cancel
Showing results for 
Search instead for 
Did you mean: 

ST25R100 Poller tag discovery

Stef2
Associate

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

  • With the X-NUCLEO-NFC09A1 shield connected, I'm not able to discover any NFCA or NFCV tags. Communication with the ST25R100 seems to work just fine (no errors).
  • gNfcDev.state enters states: RFAL_NFC_STATE_START_DISCOVERY, RFAL_NFC_STATE_POLL_TECHDETECT and RFAL_NFC_STATE_LISTEN_TECHDETECT (which indicates that no tag has been detected)

 

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();
}

 

1 REPLY 1
Ulysses HERNIOSUS
ST Employee

Hi Stefan,

 

baseline points:

  1. How is the ST25R100 reset pin connected?
  2. Please enable ST25R_SELFTEST
  3. Can you observe if an RF field is emitted? Either LED based field detector or oscilloscope with a loop of the GND cable to the tip
  4. Please share a logic analyzer trace with SPI and INT pin.

BR, Ulysses