From 1d085f21c9d1a4d4545842ec7eaf2ebbea6493ce Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Thu, 6 Jan 2011 12:39:29 +0000 Subject: [PATCH] Improve PN53x frame size calculation. chips/pn53x: adjust size and defines to better handle reply size; drivers/arygon: improve attempted reply size, should speed up the connexion; drivers/pn532_uart: improve attempted reply size, should speed up the connexion; --- examples/pn53x-diagnose.c | 2 +- libnfc/chips/pn53x.c | 44 +++++++++++++++++++++++-------------- libnfc/chips/pn53x.h | 5 ++++- libnfc/drivers/arygon.c | 32 +++++++++++---------------- libnfc/drivers/pn532_uart.c | 27 ++++++++++++----------- 5 files changed, 59 insertions(+), 51 deletions(-) diff --git a/examples/pn53x-diagnose.c b/examples/pn53x-diagnose.c index 208740c..f5995aa 100644 --- a/examples/pn53x-diagnose.c +++ b/examples/pn53x-diagnose.c @@ -54,7 +54,7 @@ main (int argc, const char *argv[]) const char *acLibnfcVersion; bool result; - byte_t abtRx[MAX_FRAME_LEN]; + byte_t abtRx[PN53x_EXTENDED_FRAME_MAX_LEN]; size_t szRx; const byte_t pncmd_diagnose_communication_line_test[] = { 0xD4, 0x00, 0x00, 0x06, 'l', 'i', 'b', 'n', 'f', 'c' }; const byte_t pncmd_diagnose_rom_test[] = { 0xD4, 0x00, 0x01 }; diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index ae42c9a..d100dbd 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -42,7 +42,7 @@ # include "../../contrib/windows.h" #endif -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#include // PN53X configuration const byte_t pncmd_get_firmware_version[2] = { 0xD4, 0x02 }; @@ -121,7 +121,7 @@ pn53x_check_ack_frame_callback (nfc_device_t * pnd, const byte_t * pbtRxFrame, c { if (szRxFrameLen >= sizeof (pn53x_ack_frame)) { if (0 == memcmp (pbtRxFrame, pn53x_ack_frame, sizeof (pn53x_ack_frame))) { - DBG ("%s", "PN53x ACKed"); + // DBG ("%s", "PN53x ACKed"); return true; } else if (0 == memcmp (pbtRxFrame, pn53x_nack_frame, sizeof (pn53x_nack_frame))) { DBG ("%s", "PN53x NACKed"); @@ -154,11 +154,12 @@ pn53x_check_error_frame_callback (nfc_device_t * pnd, const byte_t * pbtRxFrame, return true; } +#define PN53x_REPLY_FRAME_MAX_LEN (PN53x_EXTENDED_FRAME_MAX_LEN + PN53x_EXTENDED_FRAME_OVERHEAD + sizeof(pn53x_ack_frame)) bool pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx) { - byte_t abtRx[MAX_FRAME_LEN]; - size_t szRx; + byte_t abtRx[PN53x_REPLY_FRAME_MAX_LEN]; + size_t szRx = PN53x_EXTENDED_FRAME_MAX_LEN; // Check if receiving buffers are available, if not, replace them if (!pszRx || !pbtRx) { @@ -166,7 +167,16 @@ pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, b pszRx = &szRx; } - *pszRx = MAX_FRAME_LEN; +#if defined(DEBUG) + if(*pszRx > PN53x_EXTENDED_FRAME_MAX_LEN) { + DBG( "Expected reply bytes count (*pszRx=%zu) is greater than MAX (PN53x_EXTENDED_FRAME_MAX_LEN=%d)", *pszRx, PN53x_EXTENDED_FRAME_MAX_LEN ); + *pszRx=MIN(*pszRx, PN53x_EXTENDED_FRAME_MAX_LEN); +// abort(); + } +#endif + + *pszRx += sizeof(pn53x_ack_frame) + PN53x_EXTENDED_FRAME_OVERHEAD; + // Call the transceive callback function of the current device if (!pnd->pdc->transceive (pnd, pbtTx, szTx, pbtRx, pszRx)) return false; @@ -207,7 +217,6 @@ pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, b bool pn53x_get_reg (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t * ui8Value) { - size_t szValueLen; byte_t abtCmd[sizeof (pncmd_get_register)]; memcpy (abtCmd, pncmd_get_register, sizeof (pncmd_get_register)); @@ -215,6 +224,7 @@ pn53x_get_reg (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t * ui8Value) abtCmd[3] = ui16Reg & 0xff; byte_t abtRegValue[2]; + size_t szValueLen = 3 + PN53x_NORMAL_FRAME_OVERHEAD; if (pn53x_transceive (pnd, abtCmd, sizeof (pncmd_get_register), abtRegValue, &szValueLen)) { if (pnd->nc == NC_PN533) { // PN533 prepends its answer by a status byte @@ -502,7 +512,7 @@ pn53x_initiator_select_passive_target (nfc_device_t * pnd, nfc_target_t * pnt) { size_t szTargetsData; - byte_t abtTargetsData[MAX_FRAME_LEN]; + byte_t abtTargetsData[PN53x_EXTENDED_FRAME_MAX_LEN]; const pn53x_modulation_t pm = pn53x_nm_to_pm(nm); if (PM_UNDEFINED == pm) { @@ -621,7 +631,7 @@ pn53x_InListPassiveTarget (nfc_device_t * pnd, memcpy (abtCmd + 4, pbtInitiatorData, szInitiatorData); // Try to find a tag, call the tranceive callback function of the current device - szRx = MAX_FRAME_LEN; + szRx = PN53x_EXTENDED_FRAME_MAX_LEN; if (pn53x_transceive (pnd, abtCmd, 4 + szInitiatorData, pbtTargetsData, &szRx)) { *pszTargetsData = szRx; return true; @@ -658,7 +668,7 @@ pn53x_InAutoPoll (nfc_device_t * pnd, size_t szTxInAutoPoll, n, szRx; - byte_t abtRx[MAX_FRAME_LEN]; + byte_t abtRx[PN53x_EXTENDED_FRAME_MAX_LEN]; bool res; byte_t *pbtTxInAutoPoll; @@ -678,7 +688,7 @@ pn53x_InAutoPoll (nfc_device_t * pnd, pbtTxInAutoPoll[4 + n] = ppttTargetTypes[n]; } - szRx = MAX_FRAME_LEN; + szRx = PN53x_EXTENDED_FRAME_MAX_LEN; res = pnd->pdc->transceive (pnd, pbtTxInAutoPoll, szTxInAutoPoll, abtRx, &szRx); if ((szRx == 0) || (res == false)) { @@ -957,7 +967,7 @@ pn53x_InJumpForDEP (nfc_device_t * pnd, const byte_t * pbtGBi, const size_t szGBi, nfc_target_t * pnt) { - byte_t abtRx[MAX_FRAME_LEN]; + byte_t abtRx[PN53x_EXTENDED_FRAME_MAX_LEN]; size_t szRx; size_t offset; byte_t abtCmd[sizeof (pncmd_initiator_jump_for_dep)]; @@ -1050,7 +1060,7 @@ bool pn53x_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar) { - byte_t abtRx[MAX_FRAME_LEN]; + byte_t abtRx[PN53x_EXTENDED_FRAME_MAX_LEN]; size_t szRx; size_t szFrameBits = 0; size_t szFrameBytes = 0; @@ -1115,7 +1125,7 @@ bool pn53x_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx) { - byte_t abtRx[MAX_FRAME_LEN]; + byte_t abtRx[PN53x_EXTENDED_FRAME_MAX_LEN]; size_t szExtraTxLen, szRx; byte_t abtCmd[sizeof (pncmd_initiator_exchange_raw_data)]; @@ -1331,7 +1341,7 @@ pn53x_TgInitAsTarget (nfc_device_t * pnd, pn53x_target_mode_t ptm, const byte_t * pbtNFCID3t, const byte_t * pbtGBt, const size_t szGBt, byte_t * pbtRx, size_t * pszRx, byte_t * pbtModeByte) { - byte_t abtRx[MAX_FRAME_LEN]; + byte_t abtRx[PN53x_EXTENDED_FRAME_MAX_LEN]; size_t szRx; byte_t abtCmd[39 + 47 + 48]; // Worst case: 39-byte base, 47 bytes max. for General Bytes, 48 bytes max. for Historical Bytes size_t szOptionalBytes = 0; @@ -1379,7 +1389,7 @@ pn53x_TgInitAsTarget (nfc_device_t * pnd, pn53x_target_mode_t ptm, } // Request the initialization as a target - szRx = MAX_FRAME_LEN; + szRx = PN53x_EXTENDED_FRAME_MAX_LEN; if (!pn53x_transceive (pnd, abtCmd, 37 + szOptionalBytes, abtRx, &szRx)) return false; @@ -1401,7 +1411,7 @@ pn53x_TgInitAsTarget (nfc_device_t * pnd, pn53x_target_mode_t ptm, bool pn53x_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar) { - byte_t abtRx[MAX_FRAME_LEN]; + byte_t abtRx[PN53x_EXTENDED_FRAME_MAX_LEN]; size_t szRx; size_t szFrameBits; uint8_t ui8rcc; @@ -1438,7 +1448,7 @@ bool pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx) { byte_t const *pbtTx; - byte_t abtRx[MAX_FRAME_LEN]; + byte_t abtRx[PN53x_EXTENDED_FRAME_MAX_LEN]; size_t szRx; if (pnd->bEasyFraming) { diff --git a/libnfc/chips/pn53x.h b/libnfc/chips/pn53x.h index 35f170b..822c4bc 100644 --- a/libnfc/chips/pn53x.h +++ b/libnfc/chips/pn53x.h @@ -27,7 +27,10 @@ # include -# define MAX_FRAME_LEN 264 +# define PN53x_NORMAL_FRAME_MAX_LEN 255 +# define PN53x_NORMAL_FRAME_OVERHEAD 7 +# define PN53x_EXTENDED_FRAME_MAX_LEN 264 +# define PN53x_EXTENDED_FRAME_OVERHEAD 10 // Registers and symbols masks used to covers parts within a register # define REG_CIU_TX_MODE 0x6302 diff --git a/libnfc/drivers/arygon.c b/libnfc/drivers/arygon.c index e1d2881..6cc5ef4 100644 --- a/libnfc/drivers/arygon.c +++ b/libnfc/drivers/arygon.c @@ -44,7 +44,7 @@ // Bus #include "uart.h" -#define BUFFER_LENGTH 256 +#include /** @def DEV_ARYGON_PROTOCOL_ARYGON_ASCII * @brief High level language in ASCII format. (Common µC commands and Mifare® commands) @@ -80,12 +80,6 @@ void arygon_firmware (const nfc_device_spec_t nds, char * str); bool arygon_check_communication (const nfc_device_spec_t nds); -/** - * @note ARYGON-ADRA (PN531): ???,n,8,1 - * @note ARYGON-ADRB (PN532): 9600,n,8,1 - * @note ARYGON-APDA (PN531): 9600,n,8,1 - * @note ARYGON-APDB2UA33 (PN532 + ARYGON µC): 9600,n,8,1 - */ nfc_device_desc_t * arygon_pick_device (void) { @@ -106,7 +100,6 @@ arygon_pick_device (void) return NULL; } } - return pndd; } @@ -209,19 +202,20 @@ arygon_disconnect (nfc_device_t * pnd) free (pnd); } +#define TX_BUFFER_LENGTH (300) +#define RX_BUFFER_LENGTH (PN53x_EXTENDED_FRAME_MAX_LEN + PN53x_EXTENDED_FRAME_OVERHEAD) bool arygon_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx) { - byte_t abtTxBuf[BUFFER_LENGTH] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff" - byte_t abtRxBuf[BUFFER_LENGTH]; - size_t szRxBufLen = BUFFER_LENGTH; + byte_t abtTxBuf[TX_BUFFER_LENGTH] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "0x32 0x00 0x00 0xff" + byte_t abtRxBuf[RX_BUFFER_LENGTH]; + size_t szRxBufLen = MIN(RX_BUFFER_LENGTH, *pszRx); size_t szPos; int res; - // Packet length = data length (len) + checksum (1) + end of stream marker (1) abtTxBuf[4] = szTx; // Packet length checksum - abtTxBuf[5] = BUFFER_LENGTH - abtTxBuf[4]; + abtTxBuf[5] = 256 - abtTxBuf[4]; // Copy the PN53X command into the packet buffer memmove (abtTxBuf + 6, pbtTx, szTx); @@ -264,7 +258,7 @@ arygon_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, memmove (abtRxBuf, abtRxBuf + sizeof (pn53x_ack_frame), szRxBufLen); if (szRxBufLen == 0) { - szRxBufLen = BUFFER_LENGTH; + szRxBufLen = RX_BUFFER_LENGTH; do { delay_ms (10); res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen); @@ -296,8 +290,8 @@ void arygon_firmware (const nfc_device_spec_t nds, char * str) { const byte_t arygon_firmware_version_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'v' }; - byte_t abtRx[BUFFER_LENGTH]; - size_t szRx = BUFFER_LENGTH; + byte_t abtRx[RX_BUFFER_LENGTH]; + size_t szRx = 16; int res; #ifdef DEBUG @@ -326,8 +320,8 @@ bool arygon_reset_tama (const nfc_device_spec_t nds) { const byte_t arygon_reset_tama_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'r' }; - byte_t abtRx[BUFFER_LENGTH]; - size_t szRx = BUFFER_LENGTH; + byte_t abtRx[RX_BUFFER_LENGTH]; + size_t szRx = 10; // Attempted response is 10 bytes long 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) @@ -392,7 +386,7 @@ arygon_ack (const nfc_device_spec_t nds) bool arygon_check_communication (const nfc_device_spec_t nds) { - byte_t abtRx[BUFFER_LENGTH]; + byte_t abtRx[RX_BUFFER_LENGTH]; size_t szRx; const byte_t attempted_result[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, // ACK 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd5, 0x01, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbc, 0x00 }; // Reply diff --git a/libnfc/drivers/pn532_uart.c b/libnfc/drivers/pn532_uart.c index f0e469b..2079d28 100644 --- a/libnfc/drivers/pn532_uart.c +++ b/libnfc/drivers/pn532_uart.c @@ -39,8 +39,6 @@ // Bus #include "uart.h" -#define BUFFER_LENGTH 256 - #define SERIAL_DEFAULT_PORT_SPEED 115200 // TODO Move this one level up for libnfc-1.6 @@ -183,20 +181,22 @@ pn532_uart_disconnect (nfc_device_t * pnd) free (pnd); } +#define TX_BUFFER_LEN (256) +#define RX_BUFFER_LEN (PN53x_EXTENDED_FRAME_MAX_LEN + PN53x_EXTENDED_FRAME_OVERHEAD) bool pn532_uart_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx) { - byte_t abtTxBuf[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff" - byte_t abtRxBuf[BUFFER_LENGTH]; - size_t szRxBufLen = BUFFER_LENGTH; + byte_t abtTxBuf[TX_BUFFER_LEN] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff" + byte_t abtRxBuf[RX_BUFFER_LEN]; + size_t szRxBufLen = MIN( RX_BUFFER_LEN, *pbtRx ); size_t szPos; int res; // Packet length = data length (len) + checksum (1) + end of stream marker (1) abtTxBuf[3] = szTx; // Packet length checksum - abtTxBuf[4] = BUFFER_LENGTH - abtTxBuf[3]; + abtTxBuf[4] = 256 - abtTxBuf[3]; // Copy the PN53X command into the packet buffer memmove (abtTxBuf + 5, pbtTx, szTx); @@ -236,7 +236,7 @@ pn532_uart_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t sz memmove (abtRxBuf, abtRxBuf + sizeof (ack_frame), szRxBufLen); if (szRxBufLen == 0) { - szRxBufLen = BUFFER_LENGTH; + szRxBufLen = RX_BUFFER_LEN; do { delay_ms (10); res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen); @@ -284,18 +284,19 @@ pn532_uart_ack (const nfc_device_spec_t nds) uart_send ((serial_port) nds, ack_frame, sizeof (ack_frame)); } +#define PN53X_RX_OVERHEAD 6 void pn532_uart_wakeup (const nfc_device_spec_t nds) { - byte_t abtRx[BUFFER_LENGTH]; - size_t szRx = BUFFER_LENGTH; + byte_t abtRx[RX_BUFFER_LEN]; + size_t szRx = PN53x_NORMAL_FRAME_OVERHEAD + 2; /** PN532C106 wakeup. */ /** High Speed Unit (HSU) wake up consist to send 0x55 and wait a "long" delay for PN532 being wakeup. */ /** After the preamble we request the PN532C106 chip to switch to "normal" mode (SAM is not used) */ const byte_t pncmd_pn532c106_wakeup_preamble[] = { 0x55, 0x55, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x03, 0xfd, 0xd4, 0x14, 0x01, 0x17, // XXX: WTF this command is sent twice? - 0x00, 0x00, 0xff, 0x03, 0xfd, 0xd4, 0x14, 0x01, 0x17, 0x00 }; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x03, 0xfd, 0xd4, 0x14, 0x01, 0x17, 0x00 }; // Here we send a SAMConfiguration command (Normal mode, the SAM is not used; this is the default mode) #ifdef DEBUG PRINT_HEX ("TX", pncmd_pn532c106_wakeup_preamble, sizeof (pncmd_pn532c106_wakeup_preamble)); #endif @@ -312,11 +313,11 @@ pn532_uart_wakeup (const nfc_device_spec_t nds) bool pn532_uart_check_communication (const nfc_device_spec_t nds, bool * success) { - byte_t abtRx[BUFFER_LENGTH]; - size_t szRx = BUFFER_LENGTH; + byte_t abtRx[RX_BUFFER_LEN]; const byte_t attempted_result[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xD5, 0x01, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbc, 0x00 }; + size_t szRx = sizeof(attempted_result); int res; /** To be sure that PN532 is alive, we have put a "Diagnose" command to execute a "Communication Line Test" */