Update ARYGON driver, it now support probing as PN532_UART. Communication should be faster (delays removed).

Note: ARYGON APPB2UA33 oem reader now works.
This commit is contained in:
Romuald Conty 2010-04-12 14:51:50 +00:00
parent a4d1c53ed3
commit 29fad31ee5
3 changed files with 96 additions and 56 deletions

View file

@ -53,7 +53,7 @@ static const struct driver_callbacks drivers_callbacks_list[] = {
{ PN533_USB_DRIVER_NAME, pn533_usb_pick_device, pn533_usb_list_devices, pn533_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect }, { PN533_USB_DRIVER_NAME, pn533_usb_pick_device, pn533_usb_list_devices, pn533_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect },
#endif /* HAVE_LIBUSB */ #endif /* HAVE_LIBUSB */
{ PN532_UART_DRIVER_NAME, pn532_uart_pick_device, pn532_uart_list_devices, pn532_uart_connect, pn532_uart_transceive, pn532_uart_disconnect }, { PN532_UART_DRIVER_NAME, pn532_uart_pick_device, pn532_uart_list_devices, pn532_uart_connect, pn532_uart_transceive, pn532_uart_disconnect },
{ ARYGON_DRIVER_NAME, NULL, NULL, arygon_connect, arygon_transceive, arygon_disconnect } { ARYGON_DRIVER_NAME, arygon_pick_device, arygon_list_devices, arygon_connect, arygon_transceive, arygon_disconnect }
}; };
#endif // __NFC_DRIVERS_H__ #endif // __NFC_DRIVERS_H__

View file

@ -33,27 +33,28 @@
#include "../bitutils.h" #include "../bitutils.h"
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "arygon.h" #include "arygon.h"
#include <nfc/nfc-messages.h> #include <nfc/nfc-messages.h>
// Bus // Bus
#include "../buses/uart.h" #include "uart.h"
#ifdef _WIN32 #ifdef _WIN32
#define SERIAL_STRING "COM" #define SERIAL_STRING "COM"
#define delay_ms( X ) Sleep( X ) #define snprintf _snprintf
#define strdup _strdup
#else #else
// unistd.h is needed for usleep() fct. // unistd.h is needed for usleep() fct.
#include <unistd.h> #include <unistd.h>
#define delay_ms( X ) usleep( X * 1000 )
#ifdef __APPLE__ #ifdef __APPLE__
// MacOS // MacOS
#define SERIAL_STRING "/dev/tty.SLAB_USBtoUART" #define SERIAL_STRING "/dev/tty.SLAB_USBtoUART"
#else #else
// *BSD, Linux, other POSIX systems // *BSD, Linux and others POSIX systems
#define SERIAL_STRING "/dev/ttyUSB" #define SERIAL_STRING "/dev/ttyUSB"
#endif #endif
#endif #endif
@ -86,60 +87,111 @@
* @note ARYGON-APDB1UA33N (PN532): 115200,n,8,1 * @note ARYGON-APDB1UA33N (PN532): 115200,n,8,1
* @note ARYGON-APDB2UA33 (PN532 + ARYGON µC): 9600,n,8,1 * @note ARYGON-APDB2UA33 (PN532 + ARYGON µC): 9600,n,8,1
*/ */
nfc_device_desc_t *
arygon_pick_device (void)
{
nfc_device_desc_t *pndd;
if ((pndd = malloc (sizeof (*pndd)))) {
size_t szN;
if (!arygon_list_devices (pndd, 1, &szN)) {
DBG("%s", "arygon_list_devices failed");
return NULL;
}
if (szN == 0) {
DBG("%s", "No device found");
return NULL;
}
}
return pndd;
}
bool
arygon_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
{
/** @note: Due to UART bus we can't know if its really a pn532 without
* sending some PN53x commands. But using this way to probe devices, we can
* have serious problem with other device on this bus */
#ifndef SERIAL_AUTOPROBE_ENABLED
(void)pnddDevices;
(void)szDevices;
*pszDeviceFound = 0;
DBG("%s", "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
return false;
#else /* SERIAL_AUTOPROBE_ENABLED */
*pszDeviceFound = 0;
serial_port sp;
char acConnect[BUFFER_LENGTH];
int iDevice;
// I have no idea how MAC OS X deals with multiple devices, so a quick workaround
for (iDevice=0; iDevice<DRIVERS_MAX_DEVICES; iDevice++)
{
#ifdef __APPLE__
strcpy(acConnect,SERIAL_STRING);
#else /* __APPLE__ */
sprintf(acConnect,"%s%d",SERIAL_STRING,iDevice);
#endif /* __APPLE__ */
sp = uart_open(acConnect);
DBG("Trying to find ARYGON device on serial port: %s at %d bauds.",acConnect, SERIAL_DEFAULT_PORT_SPEED);
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT))
{
// Serial port claimed: an ARYGON may be found...
// FIXME try to send a command to PN53x to know if you really have a PN53x connected here
uart_close(sp);
snprintf(pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "ARYGON", acConnect);
pnddDevices[*pszDeviceFound].acDevice[DEVICE_NAME_LENGTH - 1] = '\0';
pnddDevices[*pszDeviceFound].pcDriver = ARYGON_DRIVER_NAME;
//pnddDevices[*pszDeviceFound].pcPort = strndup(acConnect, BUFFER_LENGTH - 1);
pnddDevices[*pszDeviceFound].pcPort = strdup(acConnect);
pnddDevices[*pszDeviceFound].pcPort[BUFFER_LENGTH] = '\0';
pnddDevices[*pszDeviceFound].uiSpeed = SERIAL_DEFAULT_PORT_SPEED;
DBG("Device found: %s.", pnddDevices[*pszDeviceFound].acDevice);
(*pszDeviceFound)++;
// Test if we reach the maximum "wanted" devices
if((*pszDeviceFound) >= szDevices) break;
}
#ifdef DEBUG
if (sp == INVALID_SERIAL_PORT) DBG("Invalid serial port: %s",acConnect);
if (sp == CLAIMED_SERIAL_PORT) DBG("Serial port already claimed: %s",acConnect);
#endif /* DEBUG */
}
#endif /* SERIAL_AUTOPROBE_ENABLED */
return true;
}
nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd) nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd)
{ {
uint32_t uiDevNr;
serial_port sp; serial_port sp;
char acConnect[BUFFER_LENGTH];
nfc_device_t* pnd = NULL; nfc_device_t* pnd = NULL;
if( pndd == NULL ) { if( pndd == NULL ) {
#ifndef SERIAL_AUTOPROBE_ENABLED DBG("%s", "arygon_connect() need an nfc_device_desc_t struct.");
INFO("%s", "Sorry, serial auto-probing have been disabled at compile time.");
return NULL; return NULL;
#else /* SERIAL_AUTOPROBE_ENABLED */
DBG("Trying to find ARYGON device on serial port: %s# at %d bauds.",SERIAL_STRING, SERIAL_DEFAULT_PORT_SPEED);
// I have no idea how MAC OS X deals with multiple devices, so a quick workaround
for (uiDevNr=0; uiDevNr<DRIVERS_MAX_DEVICES; uiDevNr++)
{
#ifdef __APPLE__
strcpy(acConnect,SERIAL_STRING);
#else
sprintf(acConnect,"%s%d",SERIAL_STRING,uiDevNr);
#endif /* __APPLE__ */
sp = uart_open(acConnect);
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT))
{
uart_set_speed(sp, SERIAL_DEFAULT_PORT_SPEED);
break;
}
#ifdef DEBUG
if (sp == INVALID_SERIAL_PORT) DBG("Invalid serial port: %s",acConnect);
if (sp == CLAIMED_SERIAL_PORT) DBG("Serial port already claimed: %s",acConnect);
#endif /* DEBUG */
}
#endif /* SERIAL_AUTOPROBE_ENABLED */
// Test if we have found a device
if (uiDevNr == DRIVERS_MAX_DEVICES) return NULL;
} else { } else {
DBG("Connecting to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed); DBG("Connecting to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed);
strcpy(acConnect,pndd->pcPort); sp = uart_open(pndd->pcPort);
sp = uart_open(acConnect);
if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",acConnect); if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",pndd->pcPort);
if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",acConnect); if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",pndd->pcPort);
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL; if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL;
uart_set_speed(sp, pndd->uiSpeed); uart_set_speed(sp, pndd->uiSpeed);
} }
DBG("Successfully connected to: %s",acConnect); DBG("Successfully connected to: %s",pndd->pcPort);
// We have a connection // We have a connection
pnd = malloc(sizeof(nfc_device_t)); pnd = malloc(sizeof(nfc_device_t));
strcpy(pnd->acName,"ARYGON"); strncpy(pnd->acName, pndd->acDevice, DEVICE_NAME_LENGTH - 1);
pnd->acName[DEVICE_NAME_LENGTH - 1] = '\0';
pnd->nc = NC_PN532; pnd->nc = NC_PN532;
pnd->nds = (nfc_device_spec_t)sp; pnd->nds = (nfc_device_spec_t)sp;
pnd->bActive = true; pnd->bActive = true;
@ -188,21 +240,6 @@ bool arygon_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const s
return false; return false;
} }
/** @note PN532 (at 115200 bauds) need 20ms between sending and receiving frame. No information regarding this in ARYGON datasheet...
* It seems to be a required delay to able to send from host to device, plus the device computation then device respond transmission
*/
delay_ms(20);
/** @note PN532 (at 115200 bauds) need 30ms more to be stable (report correctly present tag, at each try: 20ms seems to be enought for one shot...)
* PN532 seems to work correctly with 50ms at 115200 bauds.
*/
delay_ms(30);
/** @note Unfortunately, adding delay is not enought for ARYGON readers which are equipped with an ARYGON µC + PN532 running at 9600 bauds.
* There are too many timing problem to solve them by adding more and more delay.
* For more information, see Issue 23 on development site : http://code.google.com/p/libnfc/issues/detail?id=23
*/
if (!uart_receive((serial_port)nds,abtRxBuf,&szRxBufLen)) { if (!uart_receive((serial_port)nds,abtRxBuf,&szRxBufLen)) {
ERR("%s", "Unable to receive data. (RX)"); ERR("%s", "Unable to receive data. (RX)");
return false; return false;

View file

@ -29,6 +29,9 @@
#define ARYGON_DRIVER_NAME "ARYGON" #define ARYGON_DRIVER_NAME "ARYGON"
// Functions used by developer to handle connection to this device // Functions used by developer to handle connection to this device
nfc_device_desc_t * arygon_pick_device (void);
bool arygon_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd); nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd);
void arygon_disconnect(nfc_device_t* pnd); void arygon_disconnect(nfc_device_t* pnd);