Fix ARYGON driver:
- Does not send any ACK frame at start: my ARYGON does get happy with this frame (see code comments) - Send a TAMA reset (for PN532) instead of ACK frame - Remove bzero use: its a deprecated function
This commit is contained in:
parent
ca8c5cabe1
commit
8798f6bbcd
3 changed files with 81 additions and 26 deletions
|
@ -35,7 +35,7 @@ AC_PATH_PROG(PKG_CONFIG, pkg-config, [AC_MSG_ERROR([pkg-config not found.])])
|
||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
AC_HEADER_STDBOOL
|
AC_HEADER_STDBOOL
|
||||||
AC_CHECK_HEADERS([fcntl.h limits.h stdio.h stdlib.h stdint.h stddef.h stdbool.h sys/ioctl.h sys/param.h sys/time.h termios.h])
|
AC_CHECK_HEADERS([fcntl.h limits.h stdio.h stdlib.h stdint.h stddef.h stdbool.h sys/ioctl.h sys/param.h sys/time.h termios.h])
|
||||||
AC_CHECK_FUNCS([bzero memmove memset select strdup strerror strstr strtol usleep],
|
AC_CHECK_FUNCS([memmove memset select strdup strerror strstr strtol usleep],
|
||||||
[AC_DEFINE([_XOPEN_SOURCE], [600], [Enable POSIX extensions if present])])
|
[AC_DEFINE([_XOPEN_SOURCE], [600], [Enable POSIX extensions if present])])
|
||||||
|
|
||||||
AC_DEFINE(_NETBSD_SOURCE, 1, [Define on NetBSD to activate all library features])
|
AC_DEFINE(_NETBSD_SOURCE, 1, [Define on NetBSD to activate all library features])
|
||||||
|
|
|
@ -170,7 +170,7 @@ pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, b
|
||||||
}
|
}
|
||||||
|
|
||||||
*pszRx = MAX_FRAME_LEN;
|
*pszRx = MAX_FRAME_LEN;
|
||||||
// Call the tranceive callback function of the current device
|
// Call the transceive callback function of the current device
|
||||||
if (!pnd->pdc->transceive (pnd, pbtTx, szTx, pbtRx, pszRx))
|
if (!pnd->pdc->transceive (pnd, pbtTx, szTx, pbtRx, pszRx))
|
||||||
return false;
|
return false;
|
||||||
// TODO Put all these hex-coded command behind a human-readable #define (1.6.x)
|
// TODO Put all these hex-coded command behind a human-readable #define (1.6.x)
|
||||||
|
|
|
@ -37,10 +37,6 @@
|
||||||
# include <strings.h>
|
# include <strings.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
# define bzero(a, b) memset(a, 0x00, b)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "arygon.h"
|
#include "arygon.h"
|
||||||
|
|
||||||
#include <nfc/nfc-messages.h>
|
#include <nfc/nfc-messages.h>
|
||||||
|
@ -70,16 +66,22 @@
|
||||||
#define SERIAL_DEFAULT_PORT_SPEED 9600
|
#define SERIAL_DEFAULT_PORT_SPEED 9600
|
||||||
|
|
||||||
// TODO Move this one level up for libnfc-1.6
|
// TODO Move this one level up for libnfc-1.6
|
||||||
static const byte_t ack_frame[] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
|
static const byte_t pn53x_ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
|
||||||
|
// XXX It seems that sending arygon_ack_frame to cancel current command is not allowed by ARYGON µC (see arygon_ack())
|
||||||
|
// static const byte_t arygon_ack_frame[] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
|
||||||
|
|
||||||
void arygon_ack (const nfc_device_spec_t nds);
|
static const byte_t arygon_error_none[] = "FF000000\x0d\x0a";
|
||||||
|
static const byte_t arygon_error_incomplete_command[] = "FF0C0000\x0d\x0a";
|
||||||
|
static const byte_t arygon_error_unknown_mode[] = "FF060000\x0d\x0a";
|
||||||
|
|
||||||
|
// void arygon_ack (const nfc_device_spec_t nds);
|
||||||
|
bool arygon_reset_tama (const nfc_device_spec_t nds);
|
||||||
bool arygon_check_communication (const nfc_device_spec_t nds);
|
bool arygon_check_communication (const nfc_device_spec_t nds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @note ARYGON-ADRA (PN531): ???,n,8,1
|
* @note ARYGON-ADRA (PN531): ???,n,8,1
|
||||||
* @note ARYGON-ADRB (PN532): 9600,n,8,1
|
* @note ARYGON-ADRB (PN532): 9600,n,8,1
|
||||||
* @note ARYGON-APDA (PN531): 9600,n,8,1
|
* @note ARYGON-APDA (PN531): 9600,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 *
|
nfc_device_desc_t *
|
||||||
|
@ -131,10 +133,7 @@ arygon_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *
|
||||||
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
|
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
|
||||||
uart_set_speed (sp, SERIAL_DEFAULT_PORT_SPEED);
|
uart_set_speed (sp, SERIAL_DEFAULT_PORT_SPEED);
|
||||||
|
|
||||||
// Send ACK frame to cancel a previous command
|
if (!arygon_reset_tama((nfc_device_spec_t) sp))
|
||||||
arygon_ack ((nfc_device_spec_t) sp);
|
|
||||||
|
|
||||||
if (!arygon_check_communication ((nfc_device_spec_t) sp))
|
|
||||||
continue;
|
continue;
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
|
|
||||||
|
@ -180,9 +179,9 @@ arygon_connect (const nfc_device_desc_t * pndd)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
uart_set_speed (sp, pndd->uiSpeed);
|
uart_set_speed (sp, pndd->uiSpeed);
|
||||||
|
if (!arygon_reset_tama((nfc_device_spec_t) sp)) {
|
||||||
// Send ACK frame to cancel a previous command
|
return NULL;
|
||||||
arygon_ack ((nfc_device_spec_t) sp);
|
}
|
||||||
|
|
||||||
DBG ("Successfully connected to: %s", pndd->pcPort);
|
DBG ("Successfully connected to: %s", pndd->pcPort);
|
||||||
|
|
||||||
|
@ -240,7 +239,7 @@ arygon_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bzero (abtRxBuf, sizeof (abtRxBuf));
|
memset (abtRxBuf, 0x00, sizeof (abtRxBuf));
|
||||||
#endif
|
#endif
|
||||||
res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen);
|
res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
|
@ -256,8 +255,8 @@ arygon_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx,
|
||||||
if (!pn53x_check_ack_frame_callback (pnd, abtRxBuf, szRxBufLen))
|
if (!pn53x_check_ack_frame_callback (pnd, abtRxBuf, szRxBufLen))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
szRxBufLen -= sizeof (ack_frame);
|
szRxBufLen -= sizeof (pn53x_ack_frame);
|
||||||
memmove (abtRxBuf, abtRxBuf + sizeof (ack_frame), szRxBufLen);
|
memmove (abtRxBuf, abtRxBuf + sizeof (pn53x_ack_frame), szRxBufLen);
|
||||||
|
|
||||||
if (szRxBufLen == 0) {
|
if (szRxBufLen == 0) {
|
||||||
szRxBufLen = BUFFER_LENGTH;
|
szRxBufLen = BUFFER_LENGTH;
|
||||||
|
@ -288,29 +287,85 @@ arygon_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
arygon_reset_tama(const nfc_device_spec_t nds)
|
||||||
|
{
|
||||||
|
const byte_t arygon_reset_tama[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'r' };
|
||||||
|
byte_t abtRx[BUFFER_LENGTH];
|
||||||
|
size_t szRx;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
// Sometimes the first byte we send is not well-transmited (ie. a previously sent data on a wrong baud rate can put some junk in buffer)
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRINT_HEX ("TX", arygon_reset_tama, sizeof (arygon_reset_tama));
|
||||||
|
#endif
|
||||||
|
uart_send ((serial_port) nds, arygon_reset_tama, sizeof (arygon_reset_tama));
|
||||||
|
|
||||||
|
// Two reply are possible from ARYGON device: arygon_error_none (ie. in case the byte is well-sent)
|
||||||
|
// or arygon_error_unknown_mode (ie. in case of the first byte was bad-transmitted)
|
||||||
|
res = uart_receive ((serial_port) nds, abtRx, &szRx);
|
||||||
|
if (res != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRINT_HEX ("RX", abtRx, szRx);
|
||||||
|
#endif
|
||||||
|
if ( 0 == memcmp (abtRx, arygon_error_unknown_mode, sizeof (arygon_error_unknown_mode) - 1)) {
|
||||||
|
// HACK Here we are... the first byte wasn't sent as expected, so we resend the same command
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRINT_HEX ("TX", arygon_reset_tama, sizeof (arygon_reset_tama));
|
||||||
|
#endif
|
||||||
|
uart_send ((serial_port) nds, arygon_reset_tama, sizeof (arygon_reset_tama));
|
||||||
|
res = uart_receive ((serial_port) nds, abtRx, &szRx);
|
||||||
|
if (res != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRINT_HEX ("RX", abtRx, szRx);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (0 != memcmp (abtRx, arygon_error_none, sizeof (arygon_error_none) - 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void
|
void
|
||||||
arygon_ack (const nfc_device_spec_t nds)
|
arygon_ack (const nfc_device_spec_t nds)
|
||||||
{
|
{
|
||||||
|
byte_t abtRx[BUFFER_LENGTH];
|
||||||
|
size_t szRx;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX ("TX", ack_frame, sizeof (ack_frame));
|
PRINT_HEX ("TX", arygon_ack_frame, sizeof (arygon_ack_frame));
|
||||||
#endif
|
#endif
|
||||||
uart_send ((serial_port) nds, ack_frame, sizeof (ack_frame));
|
uart_send ((serial_port) nds, arygon_ack_frame, sizeof (arygon_ack_frame));
|
||||||
|
uart_receive ((serial_port) nds, abtRx, &szRx);
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRINT_HEX ("RX", abtRx, szRx);
|
||||||
|
#endif
|
||||||
|
// ARYGON device will send an arygon_error_incomplete_command when sending an
|
||||||
|
// ACK frame, and I (Romuald) don't know if the command is sent to PN or not
|
||||||
|
if (0 != memcmp (abtRx, arygon_error_incomplete_command, sizeof (arygon_error_incomplete_command) - 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
arygon_check_communication (const nfc_device_spec_t nds)
|
arygon_check_communication (const nfc_device_spec_t nds)
|
||||||
{
|
{
|
||||||
byte_t abtRx[BUFFER_LENGTH];
|
byte_t abtRx[BUFFER_LENGTH];
|
||||||
size_t szRx;
|
size_t szRx;
|
||||||
const byte_t attempted_result[] =
|
const byte_t attempted_result[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, // ACK
|
||||||
{ 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd5, 0x01, 0x00, 'l', 'i', 'b', 'n', 'f', 'c',
|
0x00, 0x00, 0xff, 0x09, 0xf7, 0xd5, 0x01, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbc, 0x00 }; // Reply
|
||||||
0xbc, 0x00 };
|
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
/** To be sure that PN532 is alive, we have put a "Diagnose" command to execute a "Communication Line Test" */
|
/** To be sure that PN532 is alive, we have put a "Diagnose" command to execute a "Communication Line Test" */
|
||||||
const byte_t pncmd_communication_test[] =
|
const byte_t pncmd_communication_test[] =
|
||||||
{ DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbe,
|
{ DEV_ARYGON_PROTOCOL_TAMA, // Header to passthrough front ARYGON µC (== directly talk to PN53x)
|
||||||
0x00 };
|
0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbe, 0x00 };
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX ("TX", pncmd_communication_test, sizeof (pncmd_communication_test));
|
PRINT_HEX ("TX", pncmd_communication_test, sizeof (pncmd_communication_test));
|
||||||
|
|
Loading…
Reference in a new issue