2025-01-30 07:00 AM
Hi there
Starting point
I am currently working on porting our NFC implementation from the ST25R3916 to the ST25R100.
We will also replace our current library (Lib-NFC & ST_25r & RFAL) and use the current libraries (RFAL and NDEF) from ST.
For the migration I currently use a NUCLEO-U575ZI-Q board and two NFC shields (X-NUCLEO-NFC06A1 with the current ST25R3916 and X-NUCLEO-NFC09A1 with the new ST25R100).
I already successfully migrated our implementation to the new library. I'm able to poll for NFCA and NFCV tags using the X-NUCLEO-NFC06A1 shield.
Issue Description
May you have a clue why ST25R100 sees nothing?
Any support is highly appreciated.
Best,
Stefan
Files & Info
rfal_platform.h (same config for both ST25 derivates):
//===================================================================
// GLOBAL DEFINES
//===================================================================
#define ST25R_SS_PIN NULL ///< GPIO pin used for ST25R SPI SS
#define ST25R_SS_PORT NULL ///< GPIO port used for ST25R SPI SS port
#define ST25R_INT_PIN NULL ///< GPIO pin used for ST25R External Interrupt
#define ST25R_INT_PORT GpioCfg_ptNfcIrqDevice ///< GPIO port used for ST25R External Interrupt
#define PLATFORM_LED_A_PIN NULL ///< GPIO pin used for LED A
#define PLATFORM_LED_A_PORT NULL ///< GPIO port used for LED A
#define PLATFORM_LED_B_PIN NULL ///< GPIO pin used for LED B
#define PLATFORM_LED_B_PORT NULL ///< GPIO port used for LED B
#define PLATFORM_LED_F_PIN NULL ///< GPIO pin used for LED F
#define PLATFORM_LED_F_PORT NULL ///< GPIO port used for LED F
#define PLATFORM_LED_V_PIN NULL ///< GPIO pin used for LED V
#define PLATFORM_LED_V_PORT NULL ///< GPIO port used for LED V
#define PLATFORM_LED_AP2P_PIN NULL ///< GPIO pin used for LED AP2P
#define PLATFORM_LED_AP2P_PORT NULL ///< GPIO port used for LED AP2P
#define PLATFORM_USER_BUTTON_PIN NULL ///< GPIO pin user button
#define PLATFORM_USER_BUTTON_PORT NULL ///< GPIO port user button
//===================================================================
// GLOBAL MACROS
//===================================================================
#define platformProtectST25RComm() System_vEnterCriticalSection() ///< Protect unique access to ST25R communication channel
#define platformUnprotectST25RComm() System_vExitCriticalSection() ///< Unprotect unique access to ST25R communication channel
#define platformProtectST25RIrqStatus() System_vEnterCriticalSection() ///< Protect unique access to ST25R communication channel
#define platformUnprotectST25RIrqStatus() System_vExitCriticalSection() ///< Unprotect unique access to ST25R communication channel
#define platformLedOff( port, pin ) platformGpioClear(port, pin) ///< Clear the GPIO
#define platformLedOn( port, pin ) platformGpioSet(port, pin) ///< Set the GPIO
#define platformLedToggle( port, pin ) platformGpioToggle(port, pin) ///< Toggle the GPIO
#define platformGpioSet( port, pin ) HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET) ///< Turns the given GPIO High
#define platformGpioClear( port, pin ) HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET) ///< Turns the given GPIO Low
#define platformGpioToggle( port, pin ) HAL_GPIO_TogglePin(port, pin) ///< Toogles the given GPIO
#define platformGpioIsHigh( port, pin ) ((Gpio_eGetLevel(port) == Gpio_LEVEL_HIGH) ? true : false) ///< Checks if the given GPIO definition is High
#define platformGpioIsLow( port, pin ) ((Gpio_eGetLevel(port) == Gpio_LEVEL_LOW) ? true : false) ///< Checks if the given GPIO definition is Low
#define platformTimerCreate( t ) (platformGetSysTick() + t) ///< Create a timer with the given time (ms)
#define platformTimerIsExpired( timer ) ((int32_t)(timer - platformGetSysTick()) < 0) ? true : false ///< Checks if the given timer is expired
#define platformDelay( t ) System_vBusyWaitMs( t ) ///< Performs a delay for the given time (ms)
#define platformGetSysTick() SupTimer_u32GetCounter() ///< Get System Tick ( 1 tick = 1 ms)
#define platformAssert( exp ) ASSERT_TRUE( exp , "") ///< Asserts whether the given expression is true
#define platformErrorHandle() Err_HANDLE_REUSABLE_ERROR(0, "RFAL_ERR"); ///< Global error handle trap
#ifdef RFAL_USE_I2C
#define platformI2CTx( txBuf, len, last, txOnly ) i2cSequentialTx((uint16_t)0xA0, (uint8_t *)(txBuf), (len), last, txOnly ) /*!< I2C Transmit */
#define platformI2CRx( txBuf, len ) i2cSequentialRx((uint16_t)0xA0, rxBuf, len ) ///< I2C Receive
#define platformI2CStart() ///< I2C Start condition
#define platformI2CStop() ///< I2C Stop condition
#define platformI2CRepeatStart() ///< I2C Repeat Start
#define platformI2CSlaveAddrWR(add) ///< I2C Slave address for Write operation
#define platformI2CSlaveAddrRD(add) ///< I2C Slave address for Read operation
#else /* RFAL_USE_I2C */
#define platformSpiSelect() SPI_vCsEnable(SpiCfg_ptST25R3916SpiDevice) ///< Enable CS PIN
#define platformSpiDeselect() SPI_vCsDisable(SpiCfg_ptST25R3916SpiDevice) ///< Disable CS PIN
#define platformSpiTxRx( txBuf, rxBuf, len ) SPI_vTxRx(SpiCfg_ptST25R3916SpiDevice, txBuf, rxBuf, len) ///< Interface to SPI tx and rx function
#endif /* RFAL_USE_I2C */
#define platformLog(...) ///< Log method (currently not used)
//===================================================================
// GLOBAL VARIABLES
//===================================================================
extern uint8_t globalCommProtectCnt; ///< Global Protection Counter provided per platform - instantiated in main.c
//===================================================================
// RFAL FEATURES CONFIGURATION
//===================================================================
#define RFAL_FEATURE_LISTEN_MODE false /*!< Enable/Disable RFAL support for Listen Mode */
#define RFAL_FEATURE_WAKEUP_MODE true /*!< Enable/Disable RFAL support for the Wake-Up mode */
#define RFAL_FEATURE_LOWPOWER_MODE true /*!< Enable/Disable RFAL support for the Low Power mode */
#define RFAL_FEATURE_NFCA true /*!< Enable/Disable RFAL support for NFC-A (ISO14443A) */
#define RFAL_FEATURE_NFCB true /*!< Enable/Disable RFAL support for NFC-B (ISO14443B) */
#define RFAL_FEATURE_NFCF false /*!< Enable/Disable RFAL support for NFC-F (FeliCa) */
#define RFAL_FEATURE_NFCV true /*!< Enable/Disable RFAL support for NFC-V (ISO15693) */
#define RFAL_FEATURE_T1T true /*!< Enable/Disable RFAL support for T1T (Topaz) */
#define RFAL_FEATURE_T2T true /*!< Enable/Disable RFAL support for T2T */
#define RFAL_FEATURE_T4T true /*!< Enable/Disable RFAL support for T4T */
#define RFAL_FEATURE_ST25TB true /*!< Enable/Disable RFAL support for ST25TB */
#define RFAL_FEATURE_ST25xV true /*!< Enable/Disable RFAL support for ST25TV/ST25DV */
#define RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG false /*!< Enable/Disable Analog Configs to be dynamically updated (RAM) */
#define RFAL_FEATURE_DPO false /*!< Enable/Disable RFAL Dynamic Power Output support */
#define RFAL_FEATURE_ISO_DEP true /*!< Enable/Disable RFAL support for ISO-DEP (ISO14443-4) */
#define RFAL_FEATURE_ISO_DEP_POLL true /*!< Enable/Disable RFAL support for Poller mode (PCD) ISO-DEP (ISO14443-4) */
#define RFAL_FEATURE_ISO_DEP_LISTEN false /*!< Enable/Disable RFAL support for Listen mode (PICC) ISO-DEP (ISO14443-4) */
#define RFAL_FEATURE_NFC_DEP false /*!< Enable/Disable RFAL support for NFC-DEP (NFCIP1/P2P) */
#define RFAL_FEATURE_ISO_DEP_IBLOCK_MAX_LEN 256U /*!< ISO-DEP I-Block max length. Please use values as defined by rfalIsoDepFSx */
#define RFAL_FEATURE_NFC_DEP_BLOCK_MAX_LEN 254U /*!< NFC-DEP Block/Payload length. Allowed values: 64, 128, 192, 254 */
#define RFAL_FEATURE_NFC_RF_BUF_LEN 258U /*!< RF buffer length used by RFAL NFC layer */
#define RFAL_FEATURE_ISO_DEP_APDU_MAX_LEN 512U /*!< ISO-DEP APDU max length. Please use multiples of I-Block max length */
#define RFAL_FEATURE_NFC_DEP_PDU_MAX_LEN 512U /*!< NFC-DEP PDU max length. */
//===================================================================
// RFAL CUSTOM SETTINGS
//===================================================================
// Custom analog configs are used to cope with Automatic Antenna Tuning (AAT)
// that are optimized differently for each board.
#define RFAL_ANALOG_CONFIG_CUSTOM ///< Use Custom Analog Configs when defined
// Empty macros (not used)
#define platformProtectWorker() ///< Protect RFAL Worker/Task/Process from concurrent execution on multi thread platforms
#define platformUnprotectWorker() ///< Unprotect RFAL Worker/Task/Process from concurrent execution on multi thread platforms
#define platformIrqST25RPinInitialize() ///< Initializes ST25R IRQ pin
#define platformIrqST25RSetCallback( cb ) ///< Sets ST25R ISR callback
#define platformLedsInitialize() ///< Initializes the pins used as LEDs to outputs
#define platformTimerDestroy( timer ) ///< Stops and released the given timer
#endif /* SYSTEM_RFAL_PLATFORM_H_ */
The function that initializes the RFAL library (and predefines the discovery parameters):
bool_t NfcInterface_bInit(const NfcInterface_EventHandler_t pxEventHandler, const NfcInterface_GetSystemUpTime_t pxGetSystemUptime, uint8_t u8RxConfReg3Value, uint8_t u8DetectMode)
{
// register handler/Adapters
tEnv.pxEventHandler = pxEventHandler;
tEnv.pxGetSysUpTimeAdapter = pxGetSystemUptime;
tEnv.u16Rssi = 0;
// Initialize RFAL NFC discovery parameters
rfalNfcDefaultDiscParams(&tEnv.tRfalNfcDiscoverParam);
tEnv.tRfalNfcDiscoverParam.devLimit = NFC_MAX_DEVICE_COUNT; // 2 devices
tEnv.tRfalNfcDiscoverParam.totalDuration = RFAL_NFC_WORKER_DEVICE_DISCOVERY_TIMEOUT_MS; // 1000ms
tEnv.tRfalNfcDiscoverParam.techs2Find = RFAL_NFC_POLL_TECH_A | RFAL_NFC_POLL_TECH_V;
tEnv.tRfalNfcDiscoverParam.notifyCb = vRfalNfcEvHandler; // This handler is mandatory to avoid that the library autoselects the first tag (even if multiple tags have been discovered)
// Initialize RFAL library
ReturnCode eRfalErr = rfalNfcInitialize();
LOG_ERROR_IF(eRfalErr != RFAL_ERR_NONE, "NFC initialization failed: error = %u", eRfalErr);
RETURN_IF(eRfalErr != RFAL_ERR_NONE, FALSE);
#if defined(ST25R3916) || defined(ST25R3916B)
// disable AAT (automatic antenna tuning)
uint8_t u8RegValue = 0u;
st25r3916ReadRegister(ST25R3916_REG_IO_CONF2, &u8RegValue);
u8RegValue &= ~(1<<5);
st25r3916WriteRegister(ST25R3916_REG_IO_CONF2, u8RegValue);
// set gain boost based on setting
st25r3916WriteRegister(ST25R3916_REG_RX_CONF3, u8RxConfReg3Value);
#endif
NfcInterface_vSetPower(TRUE);
return true;
}
The function that runs the discovery:
(annotation: The actual discovery is performed synchronously... by calling rfalNfcWorker until the expected rfal nfc state has been reached. This is because of our legacy API that expects synchronous functions.)
bool_t NfcInterface_bRfalDiscoverTags(bool_t bForceReDiscover)
{
rfalNfcState eRfalNfcState = rfalNfcGetState();
bool_t bAlreadyDiscovered = (eRfalNfcState == RFAL_NFC_STATE_POLL_SELECT) || (eRfalNfcState == RFAL_NFC_STATE_ACTIVATED) || (eRfalNfcState == RFAL_NFC_STATE_LISTEN_TECHDETECT)? TRUE : FALSE;
LOG_ERROR_IF((bForceReDiscover != TRUE) && (bAlreadyDiscovered != TRUE), "Tag Discovery failed: eRfalNfcState %u", eRfalNfcState);
RETURN_IF((bForceReDiscover != TRUE) && (bAlreadyDiscovered != TRUE), FALSE);
if(bForceReDiscover == TRUE)
{
NfcInterface_vResetDeviceList();
// Perform Tag discovery
ReturnCode eRfalErr = rfalNfcDiscover(&tEnv.tRfalNfcDiscoverParam);
LOG_ERROR_IF(eRfalErr != RFAL_ERR_NONE, "Failed to initiate NFC Discovery: Return Code %u", eRfalErr);
RETURN_IF(eRfalErr != RFAL_ERR_NONE, 0);
// Run worker until device discovery is finished
eRfalNfcState = eRfalRunNfcWorker(RFAL_NFC_WORKER_DEVICE_DISCOVERY_TIMEOUT_MS,
RFAL_NFC_STATE_POLL_SELECT, // State entered if multiple tags have been discovered
RFAL_NFC_STATE_ACTIVATED, // State entered if one tag has been discovered
RFAL_NFC_STATE_LISTEN_TECHDETECT); // State enteren if no tag has been discovered
}
else{} // Dont initiate discovery if not already done
LOG_DEBUG("State after tag discovery: %u", eRfalNfcState);
bool_t bSuccess = (eRfalNfcState == RFAL_NFC_STATE_POLL_SELECT) || (eRfalNfcState == RFAL_NFC_STATE_ACTIVATED) || (eRfalNfcState == RFAL_NFC_STATE_LISTEN_TECHDETECT)? TRUE : FALSE;
LOG_ERROR_IF(!bSuccess, "Tag Discovery failed: eRfalNfcState %u", eRfalNfcState);
return bSuccess;
}
static rfalNfcState eRfalRunNfcWorker(uint32_t u32TimeoutMs, rfalNfcState eTargetState1, rfalNfcState eTargetState2, rfalNfcState eTargetState3)
{
const uint32_t u32TimeoutThreshold = SupTimer_u32GetCounter() + u32TimeoutMs;
do
{
rfalNfcWorker();
} while((SupTimer_u32GetCounter() < u32TimeoutThreshold) &&
(rfalNfcGetState() != eTargetState1) && (rfalNfcGetState() != eTargetState2) && (rfalNfcGetState() != eTargetState3));
return rfalNfcGetState();
}
2025-01-30 07:54 AM
Hi Stefan,
baseline points:
BR, Ulysses