From 21dfe81d0bb4685ad4515f49fb2fa3a5a93fb9e6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 10 May 2011 23:44:27 +0000 Subject: [PATCH] Some optimisations in initialisation of registers --- examples/nfc-list.c | 8 ++--- include/nfc/nfc-types.h | 7 +++-- libnfc/chips/pn53x-internal.h | 11 +++---- libnfc/chips/pn53x.c | 24 ++++++++++----- libnfc/nfc.c | 57 ++++++++++++++++++----------------- 5 files changed, 59 insertions(+), 48 deletions(-) diff --git a/examples/nfc-list.c b/examples/nfc-list.c index 4504d1d..fefce2a 100644 --- a/examples/nfc-list.c +++ b/examples/nfc-list.c @@ -127,11 +127,11 @@ main (int argc, const char *argv[]) printf ("Connected to NFC device: %s\n", pnd->acName); + nfc_modulation_t nm; + + nm.nmt = NMT_ISO14443A; + nm.nbr = NBR_106; // List ISO14443A targets - nfc_modulation_t nm = { - .nmt = NMT_ISO14443A, - .nbr = NBR_106, - }; if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) { size_t n; if (verbose || (szTargetFound > 0)) { diff --git a/include/nfc/nfc-types.h b/include/nfc/nfc-types.h index 7bddbd4..3bc0a48 100644 --- a/include/nfc/nfc-types.h +++ b/include/nfc/nfc-types.h @@ -49,11 +49,12 @@ typedef struct { char acName[DEVICE_NAME_LENGTH]; /** Is the crc automaticly added, checked and removed from the frames */ bool bCrc; -/** Does the PN53x chip handles parity bits, all parities are handled as data */ +/** Does the chip handle parity bits, all parities are handled as data */ bool bPar; -/** Should the PN53x chip handle frames encapsulation and chaining */ +/** Should the chip handle frames encapsulation and chaining */ bool bEasyFraming; -/** Should the PN53x chip switch automatically in ISO14443-4 when ISO14443 */ +/** Should the chip switch automatically activate ISO14443-4 when + selecting tags supporting it? */ bool bAutoIso14443_4; /** Supported modulation encoded in a byte */ byte_t btSupportByte; diff --git a/libnfc/chips/pn53x-internal.h b/libnfc/chips/pn53x-internal.h index f444b62..61781e2 100644 --- a/libnfc/chips/pn53x-internal.h +++ b/libnfc/chips/pn53x-internal.h @@ -292,12 +292,11 @@ typedef struct { #define PN53X_SFR_P3 0xFFB0 -#define PN53X_SFR_P3CFGA 0xFFFC -#define PN53X_SFR_P3CFGB 0xFFFD -#define PN53X_SFR_P3 0xFFB0 -#define PN53X_SFR_P7CFGA 0xFFF4 -#define PN53X_SFR_P7CFGB 0xFFF5 -#define PN53X_SFR_P7 0xFFF7 +#define PN53X_SFR_P3CFGA 0xFFFC +#define PN53X_SFR_P3CFGB 0xFFFD +#define PN53X_SFR_P7CFGA 0xFFF4 +#define PN53X_SFR_P7CFGB 0xFFF5 +#define PN53X_SFR_P7 0xFFF7 #ifdef DEBUG diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index 705c3ff..325ac5e 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -69,10 +69,10 @@ pn53x_init(nfc_device_t * pnd) return false; } - // CRC handling is enabled by default - pnd->bCrc = true; - // Parity handling is enabled by default - pnd->bPar = true; + // CRC handling should be enabled by default as declared in nfc_device_new + // which is the case by default for pn53x, so nothing to do here + // Parity handling should be enabled by default as declared in nfc_device_new + // which is the case by default for pn53x, so nothing to do here // We can't read these parameters, so we set a default config by using the SetParameters wrapper // Note: pn53x_SetParameters() will save the sent value in pnd->ui8Parameters cache @@ -512,11 +512,11 @@ pn53x_writeback_register (nfc_device_t * pnd) BUFFER_INIT (abtReadRegisterCmd, PN53x_EXTENDED_FRAME__DATA_MAX_LEN); BUFFER_APPEND (abtReadRegisterCmd, ReadRegister); - // First step, it looks for registers to be readed before applying the requested mask + // First step, it looks for registers to be read before applying the requested mask CHIP_DATA (pnd)->wb_trigged = false; for (size_t n = 0; n < PN53X_CACHE_REGISTER_SIZE; n++) { if ((CHIP_DATA (pnd)->wb_mask[n]) && (CHIP_DATA (pnd)->wb_mask[n] != 0xff)) { - // This register needs to be readed: mask is present but does not cover full data width (ie. mask != 0xff) + // This register needs to be read: mask is present but does not cover full data width (ie. mask != 0xff) const uint16_t pn53x_register_address = PN53X_CACHE_REGISTER_MIN_ADDRESS + n; BUFFER_APPEND (abtReadRegisterCmd, pn53x_register_address >> 8); BUFFER_APPEND (abtReadRegisterCmd, pn53x_register_address & 0xff); @@ -620,10 +620,13 @@ bool pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable) { byte_t btValue; - switch (ndo) { case NDO_HANDLE_CRC: // Enable or disable automatic receiving/sending of CRC bytes + if (bEnable == pnd->bCrc) { + // Nothing to do + return true; + } // TX and RX are both represented by the symbol 0x80 btValue = (bEnable) ? 0x80 : 0x00; if (!pn53x_write_register (pnd, PN53X_REG_CIU_TxMode, SYMBOL_TX_CRC_ENABLE, btValue)) @@ -635,6 +638,9 @@ pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool b case NDO_HANDLE_PARITY: // Handle parity bit by PN53X chip or parse it as data bit + if (bEnable == pnd->bPar) + // Nothing to do + return true; btValue = (bEnable) ? 0x00 : SYMBOL_PARITY_DISABLE; if (!pn53x_write_register (pnd, PN53X_REG_CIU_ManualRCV, SYMBOL_PARITY_DISABLE, btValue)) return false; @@ -691,7 +697,9 @@ pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool b break; case NDO_AUTO_ISO14443_4: - // TODO Cache activated/disactivated options + if (bEnable == pnd->bAutoIso14443_4) + // Nothing to do + return true; pnd->bAutoIso14443_4 = bEnable; return pn53x_set_parameters (pnd, PARAM_AUTO_RATS, bEnable); break; diff --git a/libnfc/nfc.c b/libnfc/nfc.c index 3494243..aa17af7 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -74,18 +74,8 @@ const struct nfc_driver_t *nfc_drivers[] = { * When it has successfully claimed a NFC device, memory is allocated to save the device information. It will return a pointer to a \a nfc_device_t struct. * This pointer should be supplied by every next functions of libnfc that should perform an action with this device. * - * @note During this function, the device will be configured with default initiator options, cf nfc_initiator_init: - * - Crc is handled by the device (NDO_HANDLE_CRC = true) - * - Parity is handled the device (NDO_HANDLE_PARITY = true) - * - Cryto1 cipher is disabled (NDO_ACTIVATE_CRYPTO1 = false) - * - Easy framing is enabled (NDO_EASY_FRAMING = true) - * - Auto-switching in ISO14443-4 mode is enabled (NDO_AUTO_ISO14443_4 = true) - * - Invalid frames are not accepted (NDO_ACCEPT_INVALID_FRAMES = false) - * - Multiple frames are not accepted (NDO_ACCEPT_MULTIPLE_FRAMES = false) - * - 14443-A mode is activated (NDO_FORCE_ISO14443_A = true) - * - speed is set to 106 kbps (NDO_FORCE_SPEED_106 = true) - * - Let the device try forever to find a target (NDO_INFINITE_SELECT = true) - * - RF field is shortly dropped (if it was enabled) then activated again + * @note Depending on the desired operation mode, the device needs to be configured + * by using nfc_initiator_init() or nfc_target_init(), optionally followed by manual tuning of the parameters if the default parameters are not suiting your goals. */ nfc_device_t * nfc_connect (nfc_device_desc_t * pndd) @@ -113,11 +103,6 @@ nfc_connect (nfc_device_desc_t * pndd) // Test if the connection was successful if (pnd != NULL) { DBG ("[%s] has been claimed.", pnd->acName); - - // Set default configuration options - if (!nfc_initiator_init(pnd)) - return NULL; - return pnd; } else { DBG ("No device found using driver: %s", ndr->name); @@ -230,6 +215,17 @@ nfc_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEn * The NFC device is configured to function as RFID reader. * After initialization it can be used to communicate to passive RFID tags and active NFC devices. * The reader will act as initiator to communicate peer 2 peer (NFCIP) to other active NFC devices. + * - Crc is handled by the device (NDO_HANDLE_CRC = true) + * - Parity is handled the device (NDO_HANDLE_PARITY = true) + * - Cryto1 cipher is disabled (NDO_ACTIVATE_CRYPTO1 = false) + * - Easy framing is enabled (NDO_EASY_FRAMING = true) + * - Auto-switching in ISO14443-4 mode is enabled (NDO_AUTO_ISO14443_4 = true) + * - Invalid frames are not accepted (NDO_ACCEPT_INVALID_FRAMES = false) + * - Multiple frames are not accepted (NDO_ACCEPT_MULTIPLE_FRAMES = false) + * - 14443-A mode is activated (NDO_FORCE_ISO14443_A = true) + * - speed is set to 106 kbps (NDO_FORCE_SPEED_106 = true) + * - Let the device try forever to find a target (NDO_INFINITE_SELECT = true) + * - RF field is shortly dropped (if it was enabled) then activated again */ bool nfc_initiator_init (nfc_device_t * pnd) @@ -237,6 +233,15 @@ nfc_initiator_init (nfc_device_t * pnd) // Drop the field for a while if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) return false; + // Enable field so more power consuming cards can power themselves up + if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) + return false; + // Let the device try forever to find a target/tag + if (!nfc_configure (pnd, NDO_INFINITE_SELECT, true)) + return false; + // Activate auto ISO14443-4 switching by default + if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, true)) + return false; // Force 14443-A mode if (!nfc_configure (pnd, NDO_FORCE_ISO14443_A, true)) return false; @@ -257,18 +262,9 @@ nfc_initiator_init (nfc_device_t * pnd) // Activate "easy framing" feature by default if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) return false; - // Activate auto ISO14443-4 switching by default - if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, true)) - return false; // Deactivate the CRYPTO1 cipher, it may could cause problems when still active if (!nfc_configure (pnd, NDO_ACTIVATE_CRYPTO1, false)) return false; - // Let the device try forever to find a target/tag - if (!nfc_configure (pnd, NDO_INFINITE_SELECT, true)) - return false; - // Enable field so more power consuming cards can power themselves up - if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) - return false; HAL (initiator_init, pnd); } @@ -608,8 +604,15 @@ nfc_initiator_transceive_bits_timed (nfc_device_t * pnd, const byte_t * pbtTx, c * @param[out] pbtRx Rx buffer pointer * @param[out] pszRx received bytes count * - * This function initialize NFC device in \e target mode in order to emulate a + * This function initializes NFC device in \e target mode in order to emulate a * tag using the specified \a nfc_target_mode_t. + * - Crc is handled by the device (NDO_HANDLE_CRC = true) + * - Parity is handled the device (NDO_HANDLE_PARITY = true) + * - Cryto1 cipher is disabled (NDO_ACTIVATE_CRYPTO1 = false) + * - Easy framing is disabled (NDO_EASY_FRAMING = false) + * - Invalid frames are not accepted (NDO_ACCEPT_INVALID_FRAMES = false) + * - Multiple frames are not accepted (NDO_ACCEPT_MULTIPLE_FRAMES = false) + * - RF field is dropped * * @warning Be aware that this function will wait (hang) until a command is * received that is not part of the anti-collision. The RATS command for