2010-01-15 10:18:11 +00:00
/*-
2013-03-10 16:15:23 +01:00
* Free / Libre Near Field Communication ( NFC ) library
2012-05-29 00:33:22 +00:00
*
2013-03-10 16:15:23 +01:00
* Libnfc historical contributors :
* Copyright ( C ) 2009 Roel Verdult
* Copyright ( C ) 2009 - 2013 Romuald Conty
* Copyright ( C ) 2010 - 2012 Romain Tartière
2017-04-20 01:11:28 +02:00
* Copyright ( C ) 2010 - 2017 Philippe Teuwen
2013-03-10 16:15:23 +01:00
* Copyright ( C ) 2012 - 2013 Ludovic Rousseau
2013-07-17 13:57:56 +02:00
* See AUTHORS file for a more comprehensive list of contributors .
2013-03-10 16:15:23 +01:00
* Additional contributors of this file :
2012-05-29 00:33:22 +00:00
*
2009-12-06 16:36:55 +00:00
* This program is free software : you can redistribute it and / or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation , either version 3 of the License , or ( at your
* option ) any later version .
2012-05-29 00:33:22 +00:00
*
2009-12-06 16:36:55 +00:00
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>
2010-01-15 10:18:11 +00:00
*/
/**
2009-12-06 16:36:55 +00:00
* @ file pn53x_usb . c
2011-03-09 13:37:16 +00:00
* @ brief Driver for PN53x using USB
2009-12-06 16:36:55 +00:00
*/
2010-01-15 10:18:11 +00:00
# ifdef HAVE_CONFIG_H
2010-09-07 17:51:03 +00:00
# include "config.h"
2010-01-15 10:18:11 +00:00
# endif // HAVE_CONFIG_H
2009-12-06 16:36:55 +00:00
/*
Thanks to d18c7db and Okko for example code
*/
# include <stdio.h>
2009-12-23 11:56:56 +00:00
# include <stdlib.h>
2011-10-17 13:03:56 +00:00
# include <inttypes.h>
# include <sys/select.h>
# include <errno.h>
2009-12-06 16:36:55 +00:00
# include <string.h>
2020-07-07 19:40:46 +02:00
# ifdef _MSC_VER
# include <sys/types.h>
# endif
2010-08-15 14:08:29 +00:00
# include <nfc/nfc.h>
2009-12-06 16:36:55 +00:00
2011-03-05 19:54:52 +00:00
# include "nfc-internal.h"
2013-03-02 01:08:07 +01:00
# include "buses/usbbus.h"
2011-03-05 19:54:52 +00:00
# include "chips/pn53x.h"
# include "chips/pn53x-internal.h"
# include "drivers/pn53x_usb.h"
2011-10-17 13:03:56 +00:00
# define PN53X_USB_DRIVER_NAME "pn53x_usb"
2011-09-12 14:50:01 +00:00
# define LOG_CATEGORY "libnfc.driver.pn53x_usb"
2012-11-26 21:02:03 +01:00
# define LOG_GROUP NFC_LOG_GROUP_DRIVER
2009-12-06 16:36:55 +00:00
2011-08-08 10:02:47 +00:00
# define USB_INFINITE_TIMEOUT 0
2011-03-05 19:54:52 +00:00
# define DRIVER_DATA(pnd) ((struct pn53x_usb_data*)(pnd->driver_data))
Better list of supported modulations & baud rates
* Extend supported baud rates for TypeA
* Extend supported modulations B->BI,B2SR,B2CT
* Use InPSL only on TypeA
* Add mode to nfc_get_supported_baud_rate() (API change!)
* Fix supported baud rates for BI,B2SR,B2CT
* Remove supported modulations as target for ASK LoGO
Before:
$ nfc-scan-device -v
3 NFC device(s) found:
- ACS / ACR122U PICC Interface:
acr122_usb:002:024
chip: PN532 v1.4
initator mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
- SCM Micro / SCL3711-NFC&RW:
pn53x_usb:002:028
chip: PN533 v2.7
initator mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (847 kbps, 424 kbps, 212 kbps, 106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
- ASK / LoGO:
pn53x_usb:002:023
chip: PN533 v2.7
initator mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (847 kbps, 424 kbps, 212 kbps, 106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
After:
$ nfc-scan-device -v
3 NFC device(s) found:
- ACS / ACR122U PICC Interface:
acr122_usb:002:024
chip: PN532 v1.4
initator mode modulations: ISO/IEC 14443A (424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (106 kbps), ISO/IEC 14443-4B' (106 kbps), ISO/IEC 14443-2B ST SRx (106 kbps), ISO/IEC 14443-2B ASK CTx (106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
- SCM Micro / SCL3711-NFC&RW:
pn53x_usb:002:025
chip: PN533 v2.7
initator mode modulations: ISO/IEC 14443A (847 kbps, 424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (847 kbps, 424 kbps, 212 kbps, 106 kbps), ISO/IEC 14443-4B' (106 kbps), ISO/IEC 14443-2B ST SRx (106 kbps), ISO/IEC 14443-2B ASK CTx (106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
- ASK / LoGO:
pn53x_usb:002:023
chip: PN533 v2.7
initator mode modulations: ISO/IEC 14443A (847 kbps, 424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (847 kbps, 424 kbps, 212 kbps, 106 kbps), ISO/IEC 14443-4B' (106 kbps), ISO/IEC 14443-2B ST SRx (106 kbps), ISO/IEC 14443-2B ASK CTx (106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations:
2014-03-11 23:52:47 +01:00
const nfc_modulation_type no_target_support [ ] = { 0 } ;
2011-03-05 19:54:52 +00:00
typedef enum {
UNKNOWN ,
NXP_PN531 ,
2011-04-04 14:16:36 +00:00
SONY_PN531 ,
2011-03-05 19:54:52 +00:00
NXP_PN533 ,
ASK_LOGO ,
2011-06-05 22:25:05 +00:00
SCM_SCL3711 ,
2015-11-04 20:15:56 +01:00
SCM_SCL3712 ,
2011-06-07 20:36:20 +00:00
SONY_RCS360
2011-03-05 19:54:52 +00:00
} pn53x_usb_model ;
2013-03-02 10:59:37 +01:00
// Internal data struct
2011-03-05 19:54:52 +00:00
struct pn53x_usb_data {
usb_dev_handle * pudh ;
pn53x_usb_model model ;
uint32_t uiEndPointIn ;
uint32_t uiEndPointOut ;
uint32_t uiMaxPacketSize ;
2011-05-05 09:27:17 +00:00
volatile bool abort_flag ;
2017-04-20 01:11:28 +02:00
bool possibly_corrupted_usbdesc ;
2011-03-05 19:54:52 +00:00
} ;
2013-03-02 10:59:37 +01:00
// Internal io struct
2011-03-05 19:54:52 +00:00
const struct pn53x_io pn53x_usb_io ;
2012-10-21 14:10:43 +00:00
// Prototypes
2012-05-29 15:54:36 +00:00
bool pn53x_usb_get_usb_device_name ( struct usb_device * dev , usb_dev_handle * udev , char * buffer , size_t len ) ;
int pn53x_usb_init ( nfc_device * pnd ) ;
2011-03-05 19:54:52 +00:00
2012-05-13 14:50:18 +00:00
static int
2012-05-29 15:54:36 +00:00
pn53x_usb_bulk_read ( struct pn53x_usb_data * data , uint8_t abtRx [ ] , const size_t szRx , const int timeout )
2011-03-05 19:54:52 +00:00
{
2012-05-29 15:54:36 +00:00
int res = usb_bulk_read ( data - > pudh , data - > uiEndPointIn , ( char * ) abtRx , szRx , timeout ) ;
2011-06-09 14:00:45 +00:00
if ( res > 0 ) {
2012-11-26 21:02:03 +01:00
LOG_HEX ( NFC_LOG_GROUP_COM , " RX " , abtRx , res ) ;
2011-06-09 14:00:45 +00:00
} else if ( res < 0 ) {
2011-09-22 16:21:22 +00:00
if ( res ! = - USB_TIMEDOUT )
2012-11-26 21:02:03 +01:00
log_put ( NFC_LOG_GROUP_COM , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " Unable to read from USB (%s) " , _usb_strerror ( res ) ) ;
2011-06-09 14:00:45 +00:00
}
2011-03-09 13:37:16 +00:00
return res ;
2011-03-05 19:54:52 +00:00
}
2012-05-13 14:50:18 +00:00
static int
2012-05-29 15:54:36 +00:00
pn53x_usb_bulk_write ( struct pn53x_usb_data * data , uint8_t abtTx [ ] , const size_t szTx , const int timeout )
2011-03-05 19:54:52 +00:00
{
2012-11-26 21:02:03 +01:00
LOG_HEX ( NFC_LOG_GROUP_COM , " TX " , abtTx , szTx ) ;
2012-05-29 15:54:36 +00:00
int res = usb_bulk_write ( data - > pudh , data - > uiEndPointOut , ( char * ) abtTx , szTx , timeout ) ;
2011-06-09 14:00:45 +00:00
if ( res > 0 ) {
// HACK This little hack is a well know problem of USB, see http://www.libusb.org/ticket/6 for more details
if ( ( res % data - > uiMaxPacketSize ) = = 0 ) {
2012-05-29 15:54:36 +00:00
usb_bulk_write ( data - > pudh , data - > uiEndPointOut , " \0 " , 0 , timeout ) ;
2011-06-09 14:00:45 +00:00
}
} else {
2012-11-26 21:02:03 +01:00
log_put ( NFC_LOG_GROUP_COM , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " Unable to write to USB (%s) " , _usb_strerror ( res ) ) ;
2011-05-17 10:41:26 +00:00
}
return res ;
2011-03-05 19:54:52 +00:00
}
struct pn53x_usb_supported_device {
uint16_t vendor_id ;
uint16_t product_id ;
pn53x_usb_model model ;
const char * name ;
2017-04-19 01:33:40 +02:00
/* hardcoded known values for buggy hardware whose configuration vanishes */
uint32_t uiEndPointIn ;
uint32_t uiEndPointOut ;
uint32_t uiMaxPacketSize ;
2011-03-05 19:54:52 +00:00
} ;
const struct pn53x_usb_supported_device pn53x_usb_supported_devices [ ] = {
2019-07-17 22:29:09 +02:00
{ 0x04CC , 0x0531 , NXP_PN531 , " Philips / PN531 " , 0x84 , 0x04 , 0x40 } ,
{ 0x04CC , 0x2533 , NXP_PN533 , " NXP / PN533 " , 0x84 , 0x04 , 0x40 } ,
{ 0x04E6 , 0x5591 , SCM_SCL3711 , " SCM Micro / SCL3711-NFC&RW " , 0x84 , 0x04 , 0x40 } ,
{ 0x04E6 , 0x5594 , SCM_SCL3712 , " SCM Micro / SCL3712-NFC&RW " , 0 , 0 , 0 } , // to check on real device
{ 0x054c , 0x0193 , SONY_PN531 , " Sony / PN531 " , 0x84 , 0x04 , 0x40 } ,
{ 0x1FD3 , 0x0608 , ASK_LOGO , " ASK / LoGO " , 0x84 , 0x04 , 0x40 } ,
{ 0x054C , 0x02E1 , SONY_RCS360 , " Sony / FeliCa S360 [PaSoRi] " , 0x84 , 0x04 , 0x40 }
2011-03-05 19:54:52 +00:00
} ;
2017-04-20 01:11:28 +02:00
// PN533 USB descriptors backup buffers
const uint8_t btXramUsbDesc_scl3711 [ ] = {
0x09 , 0x02 , 0x20 , 0x00 , 0x01 , 0x01 , 0x00 , 0x80 , 0x32 , 0x09 , 0x04 , 0x00 ,
0x00 , 0x02 , 0xff , 0xff , 0xff , 0x00 , 0x07 , 0x05 , 0x04 , 0x02 , 0x40 , 0x00 ,
0x04 , 0x07 , 0x05 , 0x84 , 0x02 , 0x40 , 0x00 , 0x04 , 0x1e , 0x03 , 0x53 , 0x00 ,
0x43 , 0x00 , 0x4c , 0x00 , 0x33 , 0x00 , 0x37 , 0x00 , 0x31 , 0x00 , 0x31 , 0x00 ,
0x2d , 0x00 , 0x4e , 0x00 , 0x46 , 0x00 , 0x43 , 0x00 , 0x26 , 0x00 , 0x52 , 0x00 ,
0x57 ,
} ;
const uint8_t btXramUsbDesc_nxppn533 [ ] = {
0x09 , 0x02 , 0x20 , 0x00 , 0x01 , 0x01 , 0x00 , 0x80 , 0x32 , 0x09 , 0x04 , 0x00 ,
0x00 , 0x02 , 0xff , 0xff , 0xff , 0x00 , 0x07 , 0x05 , 0x04 , 0x02 , 0x40 , 0x00 ,
0x04 , 0x07 , 0x05 , 0x84 , 0x02 , 0x40 , 0x00 , 0x04 , 0x0c , 0x03 , 0x50 , 0x00 ,
0x4e , 0x00 , 0x35 , 0x00 , 0x33 , 0x00 , 0x33 , 0x00 , 0x04 , 0x03 , 0x09 , 0x04 ,
0x08 , 0x03 , 0x4e , 0x00 , 0x58 , 0x00 , 0x50 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 ,
} ;
const uint8_t btXramUsbDesc_asklogo [ ] = {
0x09 , 0x02 , 0x20 , 0x00 , 0x01 , 0x01 , 0x00 , 0x80 , 0x96 , 0x09 , 0x04 , 0x00 ,
0x00 , 0x02 , 0xff , 0xff , 0xff , 0x00 , 0x07 , 0x05 , 0x04 , 0x02 , 0x40 , 0x00 ,
0x04 , 0x07 , 0x05 , 0x84 , 0x02 , 0x40 , 0x00 , 0x04 , 0x0a , 0x03 , 0x4c , 0x00 ,
0x6f , 0x00 , 0x47 , 0x00 , 0x4f , 0x00 , 0x04 , 0x03 , 0x09 , 0x04 , 0x08 , 0x03 ,
0x41 , 0x00 , 0x53 , 0x00 , 0x4b , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 ,
} ;
static void pn533_fix_usbdesc ( nfc_device * pnd )
{
// PN533 USB descriptors may have been corrupted by large commands/responses
// so they need to be restored before closing usb connection.
// cf PN5331B3HNC270 Release Note
uint32_t szXramUsbDesc = 0 ;
uint8_t * btXramUsbDesc = NULL ;
if ( DRIVER_DATA ( pnd ) - > model = = NXP_PN533 ) {
btXramUsbDesc = ( uint8_t * ) btXramUsbDesc_nxppn533 ;
szXramUsbDesc = sizeof ( btXramUsbDesc_nxppn533 ) ;
} else if ( DRIVER_DATA ( pnd ) - > model = = SCM_SCL3711 ) {
btXramUsbDesc = ( uint8_t * ) btXramUsbDesc_scl3711 ;
szXramUsbDesc = sizeof ( btXramUsbDesc_scl3711 ) ;
} else if ( DRIVER_DATA ( pnd ) - > model = = ASK_LOGO ) {
btXramUsbDesc = ( uint8_t * ) btXramUsbDesc_asklogo ;
szXramUsbDesc = sizeof ( btXramUsbDesc_asklogo ) ;
}
2017-04-20 08:35:13 +02:00
# define MAXSZXRAMUSBDESC 61
if ( ( szXramUsbDesc = = 0 ) | | ( MAXSZXRAMUSBDESC > 61 ) )
2017-04-20 01:11:28 +02:00
return ;
2017-04-20 09:06:41 +02:00
#if 0
// Debug routine to check if corruption occurred:
// Don't read more regs at once or it will trigger the bug and corrupt what we're busy reading!
uint8_t abtCmdRR [ ] = { ReadRegister , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ;
uint8_t nRRreg = ( ( sizeof ( abtCmdRR ) - 1 ) / 2 ) ;
uint8_t abtRxRR [ 1 + nRRreg ] ;
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_INFO , " %s " , " Checking USB descriptors corruption in XRAM " ) ;
for ( uint8_t i = 0x19 , j = 0 ; i < 0x19 + szXramUsbDesc ; ) {
for ( uint8_t k = 0 ; k < nRRreg ; k + + ) {
abtCmdRR [ ( 2 * k ) + 2 ] = i + + ;
2017-04-20 01:11:28 +02:00
}
2017-04-20 09:06:41 +02:00
if ( pn53x_transceive ( pnd , abtCmdRR , sizeof ( abtCmdRR ) , abtRxRR , sizeof ( abtRxRR ) , - 1 ) < 0 ) {
return ; // void
}
for ( int k = 0 ; ( k < nRRreg ) & & ( j < szXramUsbDesc ) ; k + + ) {
//printf("0x%02x, ", abtRxRR[1 + k]);
if ( btXramUsbDesc [ j ] ! = abtRxRR [ 1 + k ] )
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_INFO , " XRAM corruption @ addr 0x00%02X: got %02x, expected %02x " , 0x0019 + ( j - 1 ) , abtRxRR [ 1 + k ] , btXramUsbDesc [ j ] ) ;
j + + ;
}
}
# endif
2017-04-20 08:35:13 +02:00
// Abuse the overflow bug to restore USB descriptors in one go
2017-04-20 01:11:28 +02:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_INFO , " %s " , " Fixing USB descriptors corruption " ) ;
2017-04-20 08:35:13 +02:00
uint8_t abtCmdWR [ 19 + MAXSZXRAMUSBDESC ] = { GetFirmwareVersion } ;
for ( uint8_t i = 0 ; i < szXramUsbDesc ; i + + ) {
abtCmdWR [ i + 19 ] = btXramUsbDesc [ i ] ;
}
2017-04-20 01:11:28 +02:00
size_t szCmdWR = sizeof ( abtCmdWR ) ;
2017-04-20 08:35:13 +02:00
uint8_t abtRxWR [ 4 ] ;
if ( pn53x_transceive ( pnd , abtCmdWR , szCmdWR , abtRxWR , sizeof ( abtRxWR ) , - 1 ) < 0 ) {
return ; // void
2017-04-20 01:11:28 +02:00
}
DRIVER_DATA ( pnd ) - > possibly_corrupted_usbdesc = false ;
}
2012-05-13 14:50:18 +00:00
static pn53x_usb_model
2012-05-29 15:54:36 +00:00
pn53x_usb_get_device_model ( uint16_t vendor_id , uint16_t product_id )
2011-03-05 19:54:52 +00:00
{
2012-05-29 15:54:36 +00:00
for ( size_t n = 0 ; n < sizeof ( pn53x_usb_supported_devices ) / sizeof ( struct pn53x_usb_supported_device ) ; n + + ) {
2011-03-05 19:54:52 +00:00
if ( ( vendor_id = = pn53x_usb_supported_devices [ n ] . vendor_id ) & &
2012-05-29 15:52:51 +00:00
( product_id = = pn53x_usb_supported_devices [ n ] . product_id ) )
2011-03-05 19:54:52 +00:00
return pn53x_usb_supported_devices [ n ] . model ;
}
2011-09-22 13:03:47 +00:00
2011-03-05 19:54:52 +00:00
return UNKNOWN ;
}
2018-11-12 15:26:43 +00:00
static bool
2017-04-19 01:33:40 +02:00
pn53x_usb_get_end_points_default ( struct usb_device * dev , struct pn53x_usb_data * data )
{
for ( size_t n = 0 ; n < sizeof ( pn53x_usb_supported_devices ) / sizeof ( struct pn53x_usb_supported_device ) ; n + + ) {
if ( ( dev - > descriptor . idVendor = = pn53x_usb_supported_devices [ n ] . vendor_id ) & &
( dev - > descriptor . idProduct = = pn53x_usb_supported_devices [ n ] . product_id ) ) {
if ( pn53x_usb_supported_devices [ n ] . uiMaxPacketSize ! = 0 ) {
data - > uiEndPointIn = pn53x_usb_supported_devices [ n ] . uiEndPointIn ;
data - > uiEndPointOut = pn53x_usb_supported_devices [ n ] . uiEndPointOut ;
data - > uiMaxPacketSize = pn53x_usb_supported_devices [ n ] . uiMaxPacketSize ;
2018-11-12 15:26:43 +00:00
return true ;
}
2017-04-19 01:33:40 +02:00
}
}
2018-11-12 15:26:43 +00:00
return false ;
2017-04-19 01:33:40 +02:00
}
2012-05-29 15:54:36 +00:00
int pn53x_usb_ack ( nfc_device * pnd ) ;
2010-10-12 15:51:57 +00:00
2009-12-06 16:36:55 +00:00
// Find transfer endpoints for bulk transfers
2012-05-13 14:50:18 +00:00
static void
2012-05-29 15:54:36 +00:00
pn53x_usb_get_end_points ( struct usb_device * dev , struct pn53x_usb_data * data )
2009-12-06 16:36:55 +00:00
{
uint32_t uiIndex ;
uint32_t uiEndPoint ;
2010-09-07 17:51:03 +00:00
struct usb_interface_descriptor * puid = dev - > config - > interface - > altsetting ;
2009-12-06 16:36:55 +00:00
// 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
2010-09-07 17:51:03 +00:00
for ( uiIndex = 0 ; uiIndex < puid - > bNumEndpoints ; uiIndex + + ) {
2009-12-06 16:36:55 +00:00
// Only accept bulk transfer endpoints (ignore interrupt endpoints)
2010-09-07 17:51:03 +00:00
if ( puid - > endpoint [ uiIndex ] . bmAttributes ! = USB_ENDPOINT_TYPE_BULK )
continue ;
2009-12-06 16:36:55 +00:00
// Copy the endpoint to a local var, makes it more readable code
uiEndPoint = puid - > endpoint [ uiIndex ] . bEndpointAddress ;
// Test if we dealing with a bulk IN endpoint
2010-09-07 17:51:03 +00:00
if ( ( uiEndPoint & USB_ENDPOINT_DIR_MASK ) = = USB_ENDPOINT_IN ) {
2011-03-05 19:54:52 +00:00
data - > uiEndPointIn = uiEndPoint ;
data - > uiMaxPacketSize = puid - > endpoint [ uiIndex ] . wMaxPacketSize ;
2009-12-06 16:36:55 +00:00
}
// Test if we dealing with a bulk OUT endpoint
2010-09-07 17:51:03 +00:00
if ( ( uiEndPoint & USB_ENDPOINT_DIR_MASK ) = = USB_ENDPOINT_OUT ) {
2011-03-05 19:54:52 +00:00
data - > uiEndPointOut = uiEndPoint ;
data - > uiMaxPacketSize = puid - > endpoint [ uiIndex ] . wMaxPacketSize ;
2009-12-06 16:36:55 +00:00
}
}
}
2012-10-21 14:11:17 +00:00
static size_t
2012-11-26 21:02:03 +01:00
pn53x_usb_scan ( const nfc_context * context , nfc_connstring connstrings [ ] , const size_t connstrings_len )
2009-12-06 16:36:55 +00:00
{
2012-11-26 21:02:03 +01:00
( void ) context ;
2013-03-02 10:59:37 +01:00
2013-03-02 01:08:07 +01:00
usb_prepare ( ) ;
2013-03-02 10:59:37 +01:00
2012-10-21 14:11:17 +00:00
size_t device_found = 0 ;
2011-03-05 19:54:52 +00:00
uint32_t uiBusIndex = 0 ;
struct usb_bus * bus ;
2012-05-29 15:54:36 +00:00
for ( bus = usb_get_busses ( ) ; bus ; bus = bus - > next ) {
2011-03-05 19:54:52 +00:00
struct usb_device * dev ;
2011-06-09 14:00:45 +00:00
2010-09-07 17:51:03 +00:00
for ( dev = bus - > devices ; dev ; dev = dev - > next , uiBusIndex + + ) {
2012-05-29 15:54:36 +00:00
for ( size_t n = 0 ; n < sizeof ( pn53x_usb_supported_devices ) / sizeof ( struct pn53x_usb_supported_device ) ; n + + ) {
2011-03-05 19:54:52 +00:00
if ( ( pn53x_usb_supported_devices [ n ] . vendor_id = = dev - > descriptor . idVendor ) & &
( pn53x_usb_supported_devices [ n ] . product_id = = dev - > descriptor . idProduct ) ) {
2009-12-08 21:06:59 +00:00
// Make sure there are 2 endpoints available
2018-11-12 15:26:43 +00:00
// libusb-win32 may return a NULL dev->config,
2018-11-13 12:50:19 +00:00
// or the descriptors may be corrupted, hence
2018-11-12 15:26:43 +00:00
// let us assume we will use hardcoded defaults
2018-11-13 12:50:19 +00:00
// from pn53x_usb_supported_devices if available.
2018-11-12 15:26:43 +00:00
// otherwise get data from the descriptors.
if ( pn53x_usb_supported_devices [ n ] . uiMaxPacketSize = = 0 ) {
2017-04-19 01:33:40 +02:00
if ( dev - > config - > interface = = NULL | | dev - > config - > interface - > altsetting = = NULL ) {
// Nope, we maybe want the next one, let's try to find another
continue ;
}
if ( dev - > config - > interface - > altsetting - > bNumEndpoints < 2 ) {
// Nope, we maybe want the next one, let's try to find another
continue ;
}
2009-12-08 21:06:59 +00:00
}
2011-03-05 19:54:52 +00:00
2012-05-29 15:54:36 +00:00
usb_dev_handle * udev = usb_open ( dev ) ;
2013-04-05 15:42:01 +02:00
if ( udev = = NULL )
continue ;
2011-05-25 12:08:42 +00:00
// Set configuration
2013-03-02 01:08:07 +01:00
int res = usb_set_configuration ( udev , 1 ) ;
2011-05-25 12:08:42 +00:00
if ( res < 0 ) {
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " Unable to set USB configuration (%s) " , _usb_strerror ( res ) ) ;
2012-05-29 15:54:36 +00:00
usb_close ( udev ) ;
2011-05-25 12:08:42 +00:00
// we failed to use the device
continue ;
}
2012-10-21 14:11:17 +00:00
// pn53x_usb_get_usb_device_name (dev, udev, pnddDevices[device_found].acDevice, sizeof (pnddDevices[device_found].acDevice));
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_DEBUG , " device found: Bus %s Device %s " , bus - > dirname , dev - > filename ) ;
2012-05-29 15:54:36 +00:00
usb_close ( udev ) ;
2020-05-21 15:06:17 +02:00
if ( snprintf ( connstrings [ device_found ] , sizeof ( nfc_connstring ) , " %s:%s:%s " , PN53X_USB_DRIVER_NAME , bus - > dirname , dev - > filename ) > = ( int ) sizeof ( nfc_connstring ) ) {
2020-05-21 15:05:48 +02:00
// truncation occurred, skipping that one
continue ;
}
2012-10-21 14:11:17 +00:00
device_found + + ;
2009-12-08 21:06:59 +00:00
// Test if we reach the maximum "wanted" devices
2012-10-21 14:11:17 +00:00
if ( device_found = = connstrings_len ) {
return device_found ;
2009-12-08 21:06:59 +00:00
}
2009-12-06 16:36:55 +00:00
}
2009-12-07 21:13:36 +00:00
}
}
}
2011-03-09 13:49:33 +00:00
2012-10-21 14:11:17 +00:00
return device_found ;
2009-12-07 21:13:36 +00:00
}
2011-10-17 13:03:56 +00:00
struct pn53x_usb_descriptor {
2012-01-18 13:13:36 +00:00
char * dirname ;
char * filename ;
2011-10-17 13:03:56 +00:00
} ;
2011-03-05 19:54:52 +00:00
bool
2012-05-29 15:54:36 +00:00
pn53x_usb_get_usb_device_name ( struct usb_device * dev , usb_dev_handle * udev , char * buffer , size_t len )
2011-03-05 19:54:52 +00:00
{
* buffer = ' \0 ' ;
if ( dev - > descriptor . iManufacturer | | dev - > descriptor . iProduct ) {
if ( udev ) {
2012-05-29 15:54:36 +00:00
usb_get_string_simple ( udev , dev - > descriptor . iManufacturer , buffer , len ) ;
if ( strlen ( buffer ) > 0 )
strcpy ( buffer + strlen ( buffer ) , " / " ) ;
usb_get_string_simple ( udev , dev - > descriptor . iProduct , buffer + strlen ( buffer ) , len - strlen ( buffer ) ) ;
2011-03-05 19:54:52 +00:00
}
}
if ( ! * buffer ) {
2012-05-29 15:54:36 +00:00
for ( size_t n = 0 ; n < sizeof ( pn53x_usb_supported_devices ) / sizeof ( struct pn53x_usb_supported_device ) ; n + + ) {
2011-03-05 19:54:52 +00:00
if ( ( pn53x_usb_supported_devices [ n ] . vendor_id = = dev - > descriptor . idVendor ) & &
( pn53x_usb_supported_devices [ n ] . product_id = = dev - > descriptor . idProduct ) ) {
2012-05-29 15:54:36 +00:00
strncpy ( buffer , pn53x_usb_supported_devices [ n ] . name , len ) ;
2013-03-06 12:38:59 +01:00
buffer [ len - 1 ] = ' \0 ' ;
2011-03-05 19:54:52 +00:00
return true ;
}
}
}
return false ;
}
2012-10-21 14:10:43 +00:00
static nfc_device *
2012-11-26 21:02:03 +01:00
pn53x_usb_open ( const nfc_context * context , const nfc_connstring connstring )
2009-12-07 21:13:36 +00:00
{
2012-01-18 13:13:36 +00:00
nfc_device * pnd = NULL ;
2012-01-26 21:36:08 +00:00
struct pn53x_usb_descriptor desc = { NULL , NULL } ;
2013-03-10 00:20:52 +01:00
int connstring_decode_level = connstring_decode ( connstring , PN53X_USB_DRIVER_NAME , " usb " , & desc . dirname , & desc . filename ) ;
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_DEBUG , " %d element(s) have been decoded from \" %s \" " , connstring_decode_level , connstring ) ;
2011-10-17 13:03:56 +00:00
if ( connstring_decode_level < 1 ) {
2012-01-18 13:13:36 +00:00
goto free_mem ;
2011-10-17 13:03:56 +00:00
}
2011-03-05 19:54:52 +00:00
struct pn53x_usb_data data = {
. pudh = NULL ,
. uiEndPointIn = 0 ,
. uiEndPointOut = 0 ,
2017-04-20 01:11:28 +02:00
. possibly_corrupted_usbdesc = false ,
2011-03-05 19:54:52 +00:00
} ;
2009-12-07 21:13:36 +00:00
struct usb_bus * bus ;
struct usb_device * dev ;
2013-03-02 01:08:07 +01:00
usb_prepare ( ) ;
2012-01-18 13:13:36 +00:00
2012-05-29 15:54:36 +00:00
for ( bus = usb_get_busses ( ) ; bus ; bus = bus - > next ) {
2011-10-17 13:03:56 +00:00
if ( connstring_decode_level > 1 ) {
// A specific bus have been specified
2012-05-29 15:54:36 +00:00
if ( 0 ! = strcmp ( bus - > dirname , desc . dirname ) )
2011-10-17 13:03:56 +00:00
continue ;
}
for ( dev = bus - > devices ; dev ; dev = dev - > next ) {
if ( connstring_decode_level > 2 ) {
// A specific dev have been specified
2012-05-29 15:54:36 +00:00
if ( 0 ! = strcmp ( dev - > filename , desc . filename ) )
2011-10-17 13:03:56 +00:00
continue ;
}
// Open the USB device
2013-04-05 15:42:01 +02:00
if ( ( data . pudh = usb_open ( dev ) ) = = NULL )
continue ;
2019-07-17 22:29:09 +02:00
//To retrieve real USB endpoints configuration:
//pn53x_usb_get_end_points(dev, &data);
//printf("DEBUG ENDPOINTS In:0x%x Out:0x%x Size:0x%x\n", data.uiEndPointIn, data.uiEndPointOut, data.uiMaxPacketSize);
2018-11-12 15:26:43 +00:00
// Retrieve end points, using hardcoded defaults if available
// or using the descriptors otherwise.
if ( pn53x_usb_get_end_points_default ( dev , & data ) = = false ) {
2017-04-19 01:33:40 +02:00
pn53x_usb_get_end_points ( dev , & data ) ;
2017-04-20 01:11:28 +02:00
}
2011-10-17 13:03:56 +00:00
// Set configuration
2013-03-02 01:08:07 +01:00
int res = usb_set_configuration ( data . pudh , 1 ) ;
2011-10-17 13:03:56 +00:00
if ( res < 0 ) {
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " Unable to set USB configuration (%s) " , _usb_strerror ( res ) ) ;
2011-10-17 13:03:56 +00:00
if ( EPERM = = - res ) {
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_INFO , " Warning: Please double check USB permissions for device %04x:%04x " , dev - > descriptor . idVendor , dev - > descriptor . idProduct ) ;
2009-12-06 16:36:55 +00:00
}
2012-05-29 15:54:36 +00:00
usb_close ( data . pudh ) ;
2011-10-17 13:03:56 +00:00
// we failed to use the specified device
2012-01-18 13:13:36 +00:00
goto free_mem ;
2011-10-17 13:03:56 +00:00
}
2009-12-06 16:36:55 +00:00
2012-05-29 15:54:36 +00:00
res = usb_claim_interface ( data . pudh , 0 ) ;
2011-10-17 13:03:56 +00:00
if ( res < 0 ) {
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " Unable to claim USB interface (%s) " , _usb_strerror ( res ) ) ;
2012-05-29 15:54:36 +00:00
usb_close ( data . pudh ) ;
2011-10-17 13:03:56 +00:00
// we failed to use the specified device
2012-01-18 13:13:36 +00:00
goto free_mem ;
2011-10-17 13:03:56 +00:00
}
2012-05-29 15:54:36 +00:00
data . model = pn53x_usb_get_device_model ( dev - > descriptor . idVendor , dev - > descriptor . idProduct ) ;
2011-10-17 13:03:56 +00:00
// Allocate memory for the device info and specification, fill it and return the info
2012-11-26 21:02:03 +01:00
pnd = nfc_device_new ( context , connstring ) ;
2013-03-05 19:57:36 +01:00
if ( ! pnd ) {
perror ( " malloc " ) ;
goto error ;
}
2012-05-29 15:54:36 +00:00
pn53x_usb_get_usb_device_name ( dev , data . pudh , pnd - > name , sizeof ( pnd - > name ) ) ;
2011-10-17 13:03:56 +00:00
pnd - > driver_data = malloc ( sizeof ( struct pn53x_usb_data ) ) ;
2013-03-02 02:25:13 +01:00
if ( ! pnd - > driver_data ) {
perror ( " malloc " ) ;
goto error ;
}
2012-05-29 15:54:36 +00:00
* DRIVER_DATA ( pnd ) = data ;
2011-10-17 13:03:56 +00:00
// Alloc and init chip's data
2013-03-18 00:20:49 +01:00
if ( pn53x_data_new ( pnd , & pn53x_usb_io ) = = NULL ) {
perror ( " malloc " ) ;
goto error ;
}
2011-10-17 13:03:56 +00:00
2012-05-29 15:54:36 +00:00
switch ( DRIVER_DATA ( pnd ) - > model ) {
2017-02-18 13:05:59 +01:00
// empirical tuning
2011-10-17 13:03:56 +00:00
case ASK_LOGO :
2012-05-29 15:54:36 +00:00
CHIP_DATA ( pnd ) - > timer_correction = 50 ;
2017-05-17 13:38:20 +02:00
CHIP_DATA ( pnd ) - > progressive_field = true ;
2011-10-17 13:03:56 +00:00
break ;
case SCM_SCL3711 :
2015-11-04 20:15:56 +01:00
case SCM_SCL3712 :
2011-10-17 13:03:56 +00:00
case NXP_PN533 :
2012-05-29 15:54:36 +00:00
CHIP_DATA ( pnd ) - > timer_correction = 46 ;
2011-10-17 13:03:56 +00:00
break ;
case NXP_PN531 :
2012-05-29 15:54:36 +00:00
CHIP_DATA ( pnd ) - > timer_correction = 50 ;
2011-10-17 13:03:56 +00:00
break ;
case SONY_PN531 :
2012-05-29 15:54:36 +00:00
CHIP_DATA ( pnd ) - > timer_correction = 54 ;
2011-10-17 13:03:56 +00:00
break ;
2012-05-16 18:08:42 +00:00
case SONY_RCS360 :
case UNKNOWN :
2012-05-29 15:54:36 +00:00
CHIP_DATA ( pnd ) - > timer_correction = 0 ; // TODO: allow user to know if timed functions are available
2011-10-17 13:03:56 +00:00
break ;
}
pnd - > driver = & pn53x_usb_driver ;
2010-09-29 09:57:50 +00:00
2011-10-17 13:03:56 +00:00
// HACK1: Send first an ACK as Abort command, to reset chip before talking to it:
2012-05-29 15:54:36 +00:00
pn53x_usb_ack ( pnd ) ;
2010-09-29 09:57:50 +00:00
2011-10-17 13:03:56 +00:00
// HACK2: Then send a GetFirmware command to resync USB toggle bit between host & device
// in case host used set_configuration and expects the device to have reset its toggle bit, which PN53x doesn't do
2012-05-29 15:54:36 +00:00
if ( pn53x_usb_init ( pnd ) < 0 ) {
usb_close ( data . pudh ) ;
2011-10-17 13:03:56 +00:00
goto error ;
2009-12-06 16:36:55 +00:00
}
2012-05-29 15:54:36 +00:00
DRIVER_DATA ( pnd ) - > abort_flag = false ;
2012-01-18 13:13:36 +00:00
goto free_mem ;
2009-12-06 16:36:55 +00:00
}
}
2009-12-07 21:13:36 +00:00
// We ran out of devices before the index required
2012-01-18 13:13:36 +00:00
goto free_mem ;
2011-03-05 19:54:52 +00:00
error :
// Free allocated structure on error.
2012-05-29 15:54:36 +00:00
nfc_device_free ( pnd ) ;
2012-03-05 07:28:45 +00:00
pnd = NULL ;
2012-01-18 13:13:36 +00:00
free_mem :
2012-05-29 15:54:36 +00:00
free ( desc . dirname ) ;
free ( desc . filename ) ;
2012-01-18 13:13:36 +00:00
return pnd ;
2009-12-06 16:36:55 +00:00
}
2012-10-21 14:10:43 +00:00
static void
2012-05-29 15:54:36 +00:00
pn53x_usb_close ( nfc_device * pnd )
2009-12-06 16:36:55 +00:00
{
2012-05-29 15:54:36 +00:00
pn53x_usb_ack ( pnd ) ;
2010-10-12 15:51:57 +00:00
2012-05-29 15:54:36 +00:00
if ( DRIVER_DATA ( pnd ) - > model = = ASK_LOGO ) {
2011-04-08 19:27:10 +00:00
/* Set P30, P31, P32, P33, P35 to logic 1 and P34 to 0 logic */
/* ie. Switch all LEDs off and turn off progressive field */
2012-05-29 15:54:36 +00:00
pn53x_write_register ( pnd , PN53X_SFR_P3 , 0xFF , _BV ( P30 ) | _BV ( P31 ) | _BV ( P32 ) | _BV ( P33 ) | _BV ( P35 ) ) ;
2011-04-08 19:27:10 +00:00
}
2017-04-20 01:11:28 +02:00
if ( DRIVER_DATA ( pnd ) - > possibly_corrupted_usbdesc )
pn533_fix_usbdesc ( pnd ) ;
2013-01-31 01:18:23 +01:00
pn53x_idle ( pnd ) ;
2011-05-09 10:09:40 +00:00
int res ;
2012-05-29 15:54:36 +00:00
if ( ( res = usb_release_interface ( DRIVER_DATA ( pnd ) - > pudh , 0 ) ) < 0 ) {
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " Unable to release USB interface (%s) " , _usb_strerror ( res ) ) ;
2010-07-29 12:47:51 +00:00
}
2012-05-29 15:54:36 +00:00
if ( ( res = usb_close ( DRIVER_DATA ( pnd ) - > pudh ) ) < 0 ) {
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " Unable to close USB connection (%s) " , _usb_strerror ( res ) ) ;
2010-08-11 16:44:34 +00:00
}
2012-05-29 15:54:36 +00:00
pn53x_data_free ( pnd ) ;
nfc_device_free ( pnd ) ;
2009-12-06 16:36:55 +00:00
}
2011-03-05 19:54:52 +00:00
# define PN53X_USB_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
2012-10-21 14:10:43 +00:00
static int
2012-05-29 15:54:36 +00:00
pn53x_usb_send ( nfc_device * pnd , const uint8_t * pbtData , const size_t szData , const int timeout )
2009-12-06 16:36:55 +00:00
{
2011-11-24 10:54:42 +00:00
uint8_t abtFrame [ PN53X_USB_BUFFER_LEN ] = { 0x00 , 0x00 , 0xff } ; // Every packet must start with "00 00 ff"
2011-03-05 19:54:52 +00:00
size_t szFrame = 0 ;
2012-01-12 13:52:48 +00:00
int res = 0 ;
2009-12-06 16:36:55 +00:00
2013-09-22 03:31:50 +02:00
if ( ( res = pn53x_build_frame ( abtFrame , & szFrame , pbtData , szData ) ) < 0 ) {
pnd - > last_error = res ;
return pnd - > last_error ;
}
2009-12-06 16:36:55 +00:00
2017-04-20 01:11:28 +02:00
DRIVER_DATA ( pnd ) - > possibly_corrupted_usbdesc | = szData > 17 ;
2012-05-29 15:54:36 +00:00
if ( ( res = pn53x_usb_bulk_write ( DRIVER_DATA ( pnd ) , abtFrame , szFrame , timeout ) ) < 0 ) {
2012-01-12 13:52:48 +00:00
pnd - > last_error = res ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2009-12-06 16:36:55 +00:00
}
2011-11-24 10:54:42 +00:00
uint8_t abtRxBuf [ PN53X_USB_BUFFER_LEN ] ;
2012-05-29 15:54:36 +00:00
if ( ( res = pn53x_usb_bulk_read ( DRIVER_DATA ( pnd ) , abtRxBuf , sizeof ( abtRxBuf ) , timeout ) ) < 0 ) {
2010-10-12 16:04:40 +00:00
// try to interrupt current device state
pn53x_usb_ack ( pnd ) ;
2012-01-26 21:36:08 +00:00
pnd - > last_error = res ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2009-12-06 16:36:55 +00:00
}
2012-05-29 15:54:36 +00:00
if ( pn53x_check_ack_frame ( pnd , abtRxBuf , res ) = = 0 ) {
2011-04-27 13:16:36 +00:00
// The PN53x is running the sent command
2011-03-05 19:54:52 +00:00
} else {
2011-05-17 10:41:26 +00:00
// For some reasons (eg. send another command while a previous one is
// running), the PN533 sometimes directly replies the response packet
// instead of ACK frame, so we send a NACK frame to force PN533 to resend
2017-04-20 01:11:28 +02:00
// response packet. With this hack, the next executed function (ie.
// pn53x_usb_receive()) will be able to retrieve the correct response
2011-05-17 10:41:26 +00:00
// packet.
2011-10-10 00:40:34 +00:00
// FIXME Sony reader is also affected by this bug but NACK is not supported
2012-05-29 15:54:36 +00:00
if ( ( res = pn53x_usb_bulk_write ( DRIVER_DATA ( pnd ) , ( uint8_t * ) pn53x_nack_frame , sizeof ( pn53x_nack_frame ) , timeout ) ) < 0 ) {
2012-01-12 13:52:48 +00:00
pnd - > last_error = res ;
2011-05-17 10:41:26 +00:00
// try to interrupt current device state
pn53x_usb_ack ( pnd ) ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-05-17 10:41:26 +00:00
}
2011-03-05 19:54:52 +00:00
}
2012-01-05 13:24:41 +00:00
return NFC_SUCCESS ;
2011-03-05 19:54:52 +00:00
}
2011-11-25 16:13:40 +00:00
# define USB_TIMEOUT_PER_PASS 200
2012-10-21 14:10:43 +00:00
static int
2012-05-29 15:54:36 +00:00
pn53x_usb_receive ( nfc_device * pnd , uint8_t * pbtData , const size_t szDataLen , const int timeout )
2011-03-05 19:54:52 +00:00
{
size_t len ;
off_t offset = 0 ;
2010-07-31 14:20:15 +00:00
2011-11-24 10:54:42 +00:00
uint8_t abtRxBuf [ PN53X_USB_BUFFER_LEN ] ;
2011-03-09 13:37:16 +00:00
int res ;
2011-09-22 13:03:47 +00:00
/*
2011-11-25 16:13:40 +00:00
* If no timeout is specified but the command is blocking , force a 200 ms ( USB_TIMEOUT_PER_PASS )
2011-09-22 13:03:47 +00:00
* timeout to allow breaking the loop if the user wants to stop it .
*/
2011-11-25 16:13:40 +00:00
int usb_timeout ;
int remaining_time = timeout ;
2011-03-09 13:37:16 +00:00
read :
2011-11-25 16:13:40 +00:00
if ( timeout = = USB_INFINITE_TIMEOUT ) {
usb_timeout = USB_TIMEOUT_PER_PASS ;
} else {
2020-10-11 07:43:16 +11:00
// A user-provided timeout is set, we have to cut it in multiple chunk to be able to keep an nfc_abort_command() mechanism
2011-11-25 16:13:40 +00:00
remaining_time - = USB_TIMEOUT_PER_PASS ;
if ( remaining_time < = 0 ) {
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_ETIMEOUT ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-09-22 16:21:22 +00:00
} else {
2011-11-25 16:13:40 +00:00
usb_timeout = MIN ( remaining_time , USB_TIMEOUT_PER_PASS ) ;
2011-09-22 16:21:22 +00:00
}
}
2011-11-25 16:13:40 +00:00
2012-05-29 15:54:36 +00:00
res = pn53x_usb_bulk_read ( DRIVER_DATA ( pnd ) , abtRxBuf , sizeof ( abtRxBuf ) , usb_timeout ) ;
2011-05-05 09:27:17 +00:00
2011-09-29 14:53:52 +00:00
if ( res = = - USB_TIMEDOUT ) {
2012-05-29 15:54:36 +00:00
if ( DRIVER_DATA ( pnd ) - > abort_flag ) {
DRIVER_DATA ( pnd ) - > abort_flag = false ;
pn53x_usb_ack ( pnd ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EOPABORTED ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-05-05 09:27:17 +00:00
} else {
goto read ;
2011-03-09 13:37:16 +00:00
}
}
2011-03-05 19:54:52 +00:00
if ( res < 0 ) {
2010-10-12 16:04:40 +00:00
// try to interrupt current device state
pn53x_usb_ack ( pnd ) ;
2012-01-26 21:36:08 +00:00
pnd - > last_error = res ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2010-09-07 17:51:03 +00:00
}
2009-12-06 16:36:55 +00:00
2011-11-24 10:54:42 +00:00
const uint8_t pn53x_preamble [ 3 ] = { 0x00 , 0x00 , 0xff } ;
2012-05-29 15:54:36 +00:00
if ( 0 ! = ( memcmp ( abtRxBuf , pn53x_preamble , 3 ) ) ) {
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " %s " , " Frame preamble+start code mismatch " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-05 19:54:52 +00:00
}
offset + = 3 ;
if ( ( 0x01 = = abtRxBuf [ offset ] ) & & ( 0xff = = abtRxBuf [ offset + 1 ] ) ) {
// Error frame
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " %s " , " Application level error detected " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-05 19:54:52 +00:00
} else if ( ( 0xff = = abtRxBuf [ offset ] ) & & ( 0xff = = abtRxBuf [ offset + 1 ] ) ) {
// Extended frame
2011-05-06 15:03:08 +00:00
offset + = 2 ;
// (abtRxBuf[offset] << 8) + abtRxBuf[offset + 1] (LEN) include TFI + (CC+1)
len = ( abtRxBuf [ offset ] < < 8 ) + abtRxBuf [ offset + 1 ] - 2 ;
if ( ( ( abtRxBuf [ offset ] + abtRxBuf [ offset + 1 ] + abtRxBuf [ offset + 2 ] ) % 256 ) ! = 0 ) {
// TODO: Retry
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " %s " , " Length checksum mismatch " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-05-06 15:03:08 +00:00
}
2011-03-05 19:54:52 +00:00
offset + = 3 ;
} else {
// Normal frame
if ( 256 ! = ( abtRxBuf [ offset ] + abtRxBuf [ offset + 1 ] ) ) {
// TODO: Retry
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " %s " , " Length checksum mismatch " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-05 19:54:52 +00:00
}
2010-08-20 10:06:19 +00:00
2011-03-05 19:54:52 +00:00
// abtRxBuf[3] (LEN) include TFI + (CC+1)
len = abtRxBuf [ offset ] - 2 ;
offset + = 2 ;
}
2009-12-06 16:36:55 +00:00
2011-03-05 19:54:52 +00:00
if ( len > szDataLen ) {
2013-03-04 01:26:23 -05:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " Unable to receive data: buffer too small. (szDataLen: % " PRIuPTR " , len: % " PRIuPTR " ) " , szDataLen , len ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2009-12-07 21:13:36 +00:00
}
2009-12-06 16:36:55 +00:00
2011-03-05 19:54:52 +00:00
// TFI + PD0 (CC+1)
if ( abtRxBuf [ offset ] ! = 0xD5 ) {
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " %s " , " TFI Mismatch " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-05 19:54:52 +00:00
}
offset + = 1 ;
2009-12-06 16:36:55 +00:00
2012-05-29 15:54:36 +00:00
if ( abtRxBuf [ offset ] ! = CHIP_DATA ( pnd ) - > last_command + 1 ) {
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " %s " , " Command Code verification failed " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-05 19:54:52 +00:00
}
offset + = 1 ;
2012-05-29 15:54:36 +00:00
memcpy ( pbtData , abtRxBuf + offset , len ) ;
2011-03-05 19:54:52 +00:00
offset + = len ;
2011-11-24 10:54:42 +00:00
uint8_t btDCS = ( 256 - 0xD5 ) ;
2012-05-29 15:54:36 +00:00
btDCS - = CHIP_DATA ( pnd ) - > last_command + 1 ;
2011-03-05 19:54:52 +00:00
for ( size_t szPos = 0 ; szPos < len ; szPos + + ) {
btDCS - = pbtData [ szPos ] ;
}
if ( btDCS ! = abtRxBuf [ offset ] ) {
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " %s " , " Data checksum mismatch " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-05 19:54:52 +00:00
}
offset + = 1 ;
if ( 0x00 ! = abtRxBuf [ offset ] ) {
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_ERROR , " %s " , " Frame postamble mismatch " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-05 19:54:52 +00:00
}
2011-04-27 13:16:36 +00:00
// The PN53x command is done and we successfully received the reply
2011-12-15 16:02:38 +00:00
pnd - > last_error = 0 ;
2017-04-20 09:06:47 +02:00
DRIVER_DATA ( pnd ) - > possibly_corrupted_usbdesc | = len > 16 ;
2011-03-05 19:54:52 +00:00
return len ;
2009-12-06 16:36:55 +00:00
}
2010-10-12 15:51:57 +00:00
2011-03-05 19:54:52 +00:00
int
2012-05-29 15:54:36 +00:00
pn53x_usb_ack ( nfc_device * pnd )
2010-10-12 15:51:57 +00:00
{
2013-01-30 00:56:47 +01:00
return pn53x_usb_bulk_write ( DRIVER_DATA ( pnd ) , ( uint8_t * ) pn53x_ack_frame , sizeof ( pn53x_ack_frame ) , 1000 ) ;
2010-10-12 15:51:57 +00:00
}
2011-03-05 19:54:52 +00:00
2012-01-05 14:05:43 +00:00
int
2012-05-29 15:54:36 +00:00
pn53x_usb_init ( nfc_device * pnd )
2011-03-05 19:54:52 +00:00
{
2012-01-05 14:05:43 +00:00
int res = 0 ;
2011-05-05 09:27:17 +00:00
// Sometimes PN53x USB doesn't reply ACK one the first frame, so we need to send a dummy one...
2011-06-07 20:36:20 +00:00
//pn53x_check_communication (pnd); // Sony RC-S360 doesn't support this command for now so let's use a get_firmware_version instead:
2011-11-24 10:54:42 +00:00
const uint8_t abtCmd [ ] = { GetFirmwareVersion } ;
2012-05-30 23:02:34 +00:00
pn53x_transceive ( pnd , abtCmd , sizeof ( abtCmd ) , NULL , 0 , - 1 ) ;
2011-05-05 09:27:17 +00:00
// ...and we don't care about error
2011-12-15 16:02:38 +00:00
pnd - > last_error = 0 ;
2012-05-29 15:54:36 +00:00
if ( SONY_RCS360 = = DRIVER_DATA ( pnd ) - > model ) {
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_DEBUG , " %s " , " SONY RC-S360 initialization. " ) ;
2011-11-24 10:54:42 +00:00
const uint8_t abtCmd2 [ ] = { 0x18 , 0x01 } ;
2012-05-30 23:02:34 +00:00
pn53x_transceive ( pnd , abtCmd2 , sizeof ( abtCmd2 ) , NULL , 0 , - 1 ) ;
2012-05-29 15:54:36 +00:00
pn53x_usb_ack ( pnd ) ;
2011-06-07 20:36:20 +00:00
}
2011-05-05 09:27:17 +00:00
2012-05-29 15:54:36 +00:00
if ( ( res = pn53x_init ( pnd ) ) < 0 )
2012-01-05 14:05:43 +00:00
return res ;
2011-03-05 19:54:52 +00:00
2012-05-29 15:54:36 +00:00
if ( ASK_LOGO = = DRIVER_DATA ( pnd ) - > model ) {
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_DEBUG , " %s " , " ASK LoGO initialization. " ) ;
2011-03-07 02:47:21 +00:00
/* Internal registers */
/* Disable 100mA current limit, Power on Secure IC (SVDD) */
2012-05-29 15:54:36 +00:00
pn53x_write_register ( pnd , PN53X_REG_Control_switch_rng , 0xFF , SYMBOL_CURLIMOFF | SYMBOL_SIC_SWITCH_EN | SYMBOL_RANDOM_DATAREADY ) ;
2011-03-07 02:47:21 +00:00
/* Select the signal to be output on SIGOUT: Modulation signal (envelope) from the internal coder */
2012-05-29 15:54:36 +00:00
pn53x_write_register ( pnd , PN53X_REG_CIU_TxSel , 0xFF , 0x14 ) ;
2011-03-07 02:47:21 +00:00
/* SFR Registers */
/* Setup push-pulls for pins from P30 to P35 */
2012-05-29 15:54:36 +00:00
pn53x_write_register ( pnd , PN53X_SFR_P3CFGB , 0xFF , 0x37 ) ;
2011-03-07 02:47:21 +00:00
2012-05-29 15:52:51 +00:00
/*
On ASK LoGO hardware :
LEDs port bits definition :
* LED 1 : bit 2 ( P32 )
* LED 2 : bit 1 ( P31 )
* LED 3 : bit 0 or 3 ( depending of hardware revision ) ( P30 or P33 )
* LED 4 : bit 5 ( P35 )
Notes :
* Set logical 0 to switch LED on ; logical 1 to switch LED off .
* Bit 4 should be maintained at 1 to keep RF field on .
Progressive field activation :
The ASK LoGO hardware can progressively power - up the antenna .
To use this feature we have to switch on the field by switching on
the field on PN533 ( RFConfiguration ) then set P34 to ' 1 ' , and cut - off the
field by switching off the field on PN533 then set P34 to ' 0 ' .
*/
2011-03-07 02:47:21 +00:00
2011-05-05 12:45:56 +00:00
/* Set P30, P31, P33, P35 to logic 1 and P32, P34 to 0 logic */
/* ie. Switch LED1 on and turn off progressive field */
2012-05-29 15:54:36 +00:00
pn53x_write_register ( pnd , PN53X_SFR_P3 , 0xFF , _BV ( P30 ) | _BV ( P31 ) | _BV ( P33 ) | _BV ( P35 ) ) ;
2011-03-05 19:54:52 +00:00
}
2017-04-20 01:11:28 +02:00
if ( DRIVER_DATA ( pnd ) - > possibly_corrupted_usbdesc )
pn533_fix_usbdesc ( pnd ) ;
2011-03-05 19:54:52 +00:00
2012-01-05 14:05:43 +00:00
return NFC_SUCCESS ;
2011-03-05 19:54:52 +00:00
}
2012-05-13 14:50:18 +00:00
static int
2012-05-29 15:54:36 +00:00
pn53x_usb_set_property_bool ( nfc_device * pnd , const nfc_property property , const bool bEnable )
2011-04-04 09:53:33 +00:00
{
2011-12-20 11:25:33 +00:00
int res = 0 ;
2012-05-29 15:54:36 +00:00
if ( ( res = pn53x_set_property_bool ( pnd , property , bEnable ) ) < 0 )
2011-12-15 16:02:38 +00:00
return res ;
2011-04-04 09:53:33 +00:00
2012-05-29 15:54:36 +00:00
switch ( DRIVER_DATA ( pnd ) - > model ) {
2011-04-08 14:42:29 +00:00
case ASK_LOGO :
2011-12-14 16:01:00 +00:00
if ( NP_ACTIVATE_FIELD = = property ) {
2011-05-05 12:45:56 +00:00
/* Switch on/off LED2 and Progressive Field GPIO according to ACTIVATE_FIELD option */
2012-11-26 21:02:03 +01:00
log_put ( LOG_GROUP , LOG_CATEGORY , NFC_LOG_PRIORITY_DEBUG , " Switch progressive field %s " , bEnable ? " On " : " Off " ) ;
2020-07-07 19:40:46 +02:00
if ( pn53x_write_register ( pnd , PN53X_SFR_P3 , _BV ( P31 ) | _BV ( P34 ) , bEnable ? _BV ( P34 ) : _BV ( P31 ) ) < 0 )
2011-12-15 16:02:38 +00:00
return NFC_ECHIP ;
2011-04-08 14:42:29 +00:00
}
break ;
case SCM_SCL3711 :
2011-12-14 16:01:00 +00:00
if ( NP_ACTIVATE_FIELD = = property ) {
2011-04-08 19:11:42 +00:00
// Switch on/off LED according to ACTIVATE_FIELD option
2012-05-29 15:54:36 +00:00
if ( ( res = pn53x_write_register ( pnd , PN53X_SFR_P3 , _BV ( P32 ) , bEnable ? 0 : _BV ( P32 ) ) ) < 0 )
2011-12-20 11:25:33 +00:00
return res ;
2011-04-08 14:42:29 +00:00
}
break ;
2015-11-04 20:15:56 +01:00
case SCM_SCL3712 :
2017-02-18 13:05:59 +01:00
if ( NP_ACTIVATE_FIELD = = property ) {
// Switch on/off LED according to ACTIVATE_FIELD option
if ( ( res = pn53x_write_register ( pnd , PN53X_SFR_P3 , _BV ( P32 ) , bEnable ? 0 : _BV ( P32 ) ) ) < 0 )
return res ;
}
break ;
2012-05-16 18:08:42 +00:00
case NXP_PN531 :
case NXP_PN533 :
case SONY_PN531 :
case SONY_RCS360 :
case UNKNOWN :
// Nothing to do.
2011-04-08 14:42:29 +00:00
break ;
2011-04-04 09:53:33 +00:00
}
2011-12-14 16:01:00 +00:00
return NFC_SUCCESS ;
2011-04-04 09:53:33 +00:00
}
2012-05-13 14:50:18 +00:00
static int
2012-05-29 15:54:36 +00:00
pn53x_usb_abort_command ( nfc_device * pnd )
2011-05-05 09:27:17 +00:00
{
2012-05-29 15:54:36 +00:00
DRIVER_DATA ( pnd ) - > abort_flag = true ;
2012-01-05 14:49:02 +00:00
return NFC_SUCCESS ;
2011-05-05 09:27:17 +00:00
}
Better list of supported modulations & baud rates
* Extend supported baud rates for TypeA
* Extend supported modulations B->BI,B2SR,B2CT
* Use InPSL only on TypeA
* Add mode to nfc_get_supported_baud_rate() (API change!)
* Fix supported baud rates for BI,B2SR,B2CT
* Remove supported modulations as target for ASK LoGO
Before:
$ nfc-scan-device -v
3 NFC device(s) found:
- ACS / ACR122U PICC Interface:
acr122_usb:002:024
chip: PN532 v1.4
initator mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
- SCM Micro / SCL3711-NFC&RW:
pn53x_usb:002:028
chip: PN533 v2.7
initator mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (847 kbps, 424 kbps, 212 kbps, 106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
- ASK / LoGO:
pn53x_usb:002:023
chip: PN533 v2.7
initator mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (847 kbps, 424 kbps, 212 kbps, 106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
After:
$ nfc-scan-device -v
3 NFC device(s) found:
- ACS / ACR122U PICC Interface:
acr122_usb:002:024
chip: PN532 v1.4
initator mode modulations: ISO/IEC 14443A (424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (106 kbps), ISO/IEC 14443-4B' (106 kbps), ISO/IEC 14443-2B ST SRx (106 kbps), ISO/IEC 14443-2B ASK CTx (106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
- SCM Micro / SCL3711-NFC&RW:
pn53x_usb:002:025
chip: PN533 v2.7
initator mode modulations: ISO/IEC 14443A (847 kbps, 424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (847 kbps, 424 kbps, 212 kbps, 106 kbps), ISO/IEC 14443-4B' (106 kbps), ISO/IEC 14443-2B ST SRx (106 kbps), ISO/IEC 14443-2B ASK CTx (106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
- ASK / LoGO:
pn53x_usb:002:023
chip: PN533 v2.7
initator mode modulations: ISO/IEC 14443A (847 kbps, 424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (847 kbps, 424 kbps, 212 kbps, 106 kbps), ISO/IEC 14443-4B' (106 kbps), ISO/IEC 14443-2B ST SRx (106 kbps), ISO/IEC 14443-2B ASK CTx (106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations:
2014-03-11 23:52:47 +01:00
static int
pn53x_usb_get_supported_modulation ( nfc_device * pnd , const nfc_mode mode , const nfc_modulation_type * * const supported_mt )
{
if ( ( DRIVER_DATA ( pnd ) - > model ! = ASK_LOGO ) | | ( mode ! = N_TARGET ) )
return pn53x_get_supported_modulation ( pnd , mode , supported_mt ) ;
else // ASK_LOGO has no N_TARGET support
* supported_mt = no_target_support ;
return NFC_SUCCESS ;
}
2011-03-05 19:54:52 +00:00
const struct pn53x_io pn53x_usb_io = {
. send = pn53x_usb_send ,
. receive = pn53x_usb_receive ,
} ;
2012-01-17 14:17:01 +00:00
const struct nfc_driver pn53x_usb_driver = {
2011-10-17 13:03:56 +00:00
. name = PN53X_USB_DRIVER_NAME ,
2013-03-02 10:59:37 +01:00
. scan_type = NOT_INTRUSIVE ,
2012-10-21 14:11:17 +00:00
. scan = pn53x_usb_scan ,
2012-01-17 15:21:56 +00:00
. open = pn53x_usb_open ,
2012-01-17 14:52:39 +00:00
. close = pn53x_usb_close ,
2011-10-17 13:03:56 +00:00
. strerror = pn53x_strerror ,
2011-03-05 19:54:52 +00:00
2011-04-08 14:30:23 +00:00
. initiator_init = pn53x_initiator_init ,
2012-06-04 00:16:28 +00:00
. initiator_init_secure_element = NULL , // No secure-element support
2011-05-05 12:45:56 +00:00
. initiator_select_passive_target = pn53x_initiator_select_passive_target ,
2011-10-03 11:19:08 +00:00
. initiator_poll_target = pn53x_initiator_poll_target ,
2011-03-05 19:54:52 +00:00
. initiator_select_dep_target = pn53x_initiator_select_dep_target ,
. initiator_deselect_target = pn53x_initiator_deselect_target ,
. initiator_transceive_bytes = pn53x_initiator_transceive_bytes ,
. initiator_transceive_bits = pn53x_initiator_transceive_bits ,
2011-04-04 14:16:36 +00:00
. initiator_transceive_bytes_timed = pn53x_initiator_transceive_bytes_timed ,
. initiator_transceive_bits_timed = pn53x_initiator_transceive_bits_timed ,
2012-05-27 22:34:21 +00:00
. initiator_target_is_present = pn53x_initiator_target_is_present ,
2011-03-05 19:54:52 +00:00
. target_init = pn53x_target_init ,
. target_send_bytes = pn53x_target_send_bytes ,
. target_receive_bytes = pn53x_target_receive_bytes ,
. target_send_bits = pn53x_target_send_bits ,
. target_receive_bits = pn53x_target_receive_bits ,
2012-05-17 00:48:47 +00:00
. device_set_property_bool = pn53x_usb_set_property_bool ,
. device_set_property_int = pn53x_set_property_int ,
Better list of supported modulations & baud rates
* Extend supported baud rates for TypeA
* Extend supported modulations B->BI,B2SR,B2CT
* Use InPSL only on TypeA
* Add mode to nfc_get_supported_baud_rate() (API change!)
* Fix supported baud rates for BI,B2SR,B2CT
* Remove supported modulations as target for ASK LoGO
Before:
$ nfc-scan-device -v
3 NFC device(s) found:
- ACS / ACR122U PICC Interface:
acr122_usb:002:024
chip: PN532 v1.4
initator mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
- SCM Micro / SCL3711-NFC&RW:
pn53x_usb:002:028
chip: PN533 v2.7
initator mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (847 kbps, 424 kbps, 212 kbps, 106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
- ASK / LoGO:
pn53x_usb:002:023
chip: PN533 v2.7
initator mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (847 kbps, 424 kbps, 212 kbps, 106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
After:
$ nfc-scan-device -v
3 NFC device(s) found:
- ACS / ACR122U PICC Interface:
acr122_usb:002:024
chip: PN532 v1.4
initator mode modulations: ISO/IEC 14443A (424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (106 kbps), ISO/IEC 14443-4B' (106 kbps), ISO/IEC 14443-2B ST SRx (106 kbps), ISO/IEC 14443-2B ASK CTx (106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
- SCM Micro / SCL3711-NFC&RW:
pn53x_usb:002:025
chip: PN533 v2.7
initator mode modulations: ISO/IEC 14443A (847 kbps, 424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (847 kbps, 424 kbps, 212 kbps, 106 kbps), ISO/IEC 14443-4B' (106 kbps), ISO/IEC 14443-2B ST SRx (106 kbps), ISO/IEC 14443-2B ASK CTx (106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations: ISO/IEC 14443A (424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
- ASK / LoGO:
pn53x_usb:002:023
chip: PN533 v2.7
initator mode modulations: ISO/IEC 14443A (847 kbps, 424 kbps, 212 kbps, 106 kbps), FeliCa (424 kbps, 212 kbps), ISO/IEC 14443-4B (847 kbps, 424 kbps, 212 kbps, 106 kbps), ISO/IEC 14443-4B' (106 kbps), ISO/IEC 14443-2B ST SRx (106 kbps), ISO/IEC 14443-2B ASK CTx (106 kbps), Innovision Jewel (106 kbps), D.E.P. (424 kbps, 212 kbps, 106 kbps)
target mode modulations:
2014-03-11 23:52:47 +01:00
. get_supported_modulation = pn53x_usb_get_supported_modulation ,
2012-05-17 00:48:47 +00:00
. get_supported_baud_rate = pn53x_get_supported_baud_rate ,
. device_get_information_about = pn53x_get_information_about ,
2011-05-05 09:27:17 +00:00
. abort_command = pn53x_usb_abort_command ,
2013-01-31 01:15:03 +01:00
. idle = pn53x_idle ,
. powerdown = pn53x_PowerDown ,
2011-03-05 19:54:52 +00:00
} ;