cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with ST25R95 and ISO15693

mahdi-questat
Associate

Hello,

 

I have a similar problem as it was asked here

https://community.st.com/t5/st25-nfc-rfid-tags-and-readers/rfal-demo-question/m-p/157070#M2943

 

I am trying to read 15693 tags with a board I designed myself.

I adjusted the RFAL library to use my own SPI port and the GPIO I assigned for connection to the IRQ pin. The rest as I can tell was the GT timer which uses systick and is already handled.

Here are my setting

 

#define RFAL_FEATURE_LISTEN_MODE               false      /*!< Enable/Disable RFAL support for Listen Mode                               */
#define RFAL_FEATURE_WAKEUP_MODE               false       /*!< Enable/Disable RFAL support for the Wake-Up mode                          */
#define RFAL_FEATURE_LOWPOWER_MODE             false      /*!< Enable/Disable RFAL support for the Low Power mode                        */
#define RFAL_FEATURE_NFCA                      false      /*!< Enable/Disable RFAL support for NFC-A (ISO14443A)                         */
#define RFAL_FEATURE_NFCB                      false      /*!< 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                       false      /*!< Enable/Disable RFAL support for T1T (Topaz)                               */
#define RFAL_FEATURE_T2T                       false      /*!< Enable/Disable RFAL support for T2T                                       */
#define RFAL_FEATURE_T4T                       false      /*!< Enable/Disable RFAL support for T4T                                       */
#define RFAL_FEATURE_ST25TB                    false      /*!< 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                   false      /*!< Enable/Disable RFAL support for ISO-DEP (ISO14443-4)                      */
#define RFAL_FEATURE_ISO_DEP_POLL              false      /*!< 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)                      */

 

 

and in my main I have

 

void test_rfid()
{
	init_rfid();
	
	while(1)
	{
		run_rfid();
	}
}

 

 

which these two functions are the same functions as the example but simplified to only cover NFC-V

 

uint8_t init_rfid()
{
	ReturnCode err;

		err = rfalNfcInitialize();
		if( err == ERR_NONE )
		{
			rfalNfcDefaultDiscParams( &discParam );

			discParam.devLimit      = 1U;

			memcpy( &discParam.nfcid3, NFCID3, sizeof(NFCID3) );
			memcpy( &discParam.GB, GB, sizeof(GB) );
			discParam.GBLen         = sizeof(GB);
			discParam.p2pNfcaPrio   = true;

			discParam.notifyCb             = demoNotif;
			discParam.totalDuration        = 1000U;
			discParam.techs2Find           = RFAL_NFC_TECH_NONE;          /* For the demo, enable the NFC Technologies based on RFAL Feature switches */



	#if RFAL_FEATURE_NFCV
			discParam.techs2Find          |= RFAL_NFC_POLL_TECH_V;
	#endif /* RFAL_FEATURE_NFCV */


	#ifdef ST25R95
			discParam.isoDepFS           = RFAL_ISODEP_FSXI_128;          /* ST25R95 cannot support 256 bytes of data block */
	#endif /* ST25R95 */

			err = rfalNfcDiscover( &discParam );
			if( err != ERR_NONE )
			{
				return false;
			}

			state = DEMO_ST_START_DISCOVERY;
			return true;
		}
		return false;

}

 

 

 

 

void run_rfid()
{
	 static rfalNfcDevice *nfcDevice;
	     rfalNfcWorker();                                    /* Run RFAL worker periodically */

	    switch( state )
	    {
	        /*******************************************************************************/
	        case DEMO_ST_START_DISCOVERY:

	        multiSel = false;
	        state    = DEMO_ST_DISCOVERY;
	        break;

	        /*******************************************************************************/
	        case DEMO_ST_DISCOVERY:

	            if( rfalNfcIsDevActivated( rfalNfcGetState() ) )
	            {
	                rfalNfcGetActiveDevice( &nfcDevice );

	                switch( nfcDevice->type )
	                {
	                    /*******************************************************************************/
	                    case RFAL_NFC_LISTEN_TYPE_NFCV:
	                        {
	                            uint8_t devUID[RFAL_NFCV_UID_LEN];

	                            //platformLedOn(PLATFORM_LED_V_PORT, PLATFORM_LED_V_PIN);

	                            memcpy( devUID, nfcDevice->nfcid, nfcDevice->nfcidLen );   /* Copy the UID into local var */
	                            REVERSE_BYTES( devUID, RFAL_NFCV_UID_LEN );                 /* Reverse the UID for display purposes */
	                            //platformLog("ISO15693/NFC-V card found. UID: %s\r\n", hex2Str(devUID, RFAL_NFCV_UID_LEN));
	                            char buffer[50];
	                            sprintf(buffer, "ISO15693/NFC-V card found. UID: %x%x %x%x %x%x %x%x\r\n", devUID[0],devUID[1],devUID[2],devUID[3],devUID[4],devUID[5],devUID[6],devUID[7]);
	                            HAL_UART_Transmit(&huart1, buffer, strlen(buffer), 5);
	                            demoNfcv( &nfcDevice->dev.nfcv );
	                        }
	                        break;

	                        default:
	                        break;
	                }

	                rfalNfcDeactivate( RFAL_NFC_DEACTIVATE_DISCOVERY );
	                state = DEMO_ST_START_DISCOVERY;
	            }
	            break;

	        /*******************************************************************************/
	        case DEMO_ST_NOTINIT:
	        default:
	            break;
	    }
}

 

But I never get past 

if( rfalNfcIsDevActivated( rfalNfcGetState() ) )

it is always in RFAL_NFC_STATE_POLL_TECHDETECT which seems like is not the correct state.

Here is my notif function

static void demoNotif( rfalNfcState st )
{
    uint8_t       devCnt;
    rfalNfcDevice *dev;

    if( st == RFAL_NFC_STATE_WAKEUP_MODE )
    {
        //platformLog("Wake Up mode started \r\n");
    }
    else if( st == RFAL_NFC_STATE_POLL_TECHDETECT )
    {
        if( discParam.wakeupEnabled )
        {
            //platformLog("Wake Up mode terminated. Polling for devices \r\n");
        }
    }
    else if( st == RFAL_NFC_STATE_POLL_SELECT )
    {
        /* Check if in case of multiple devices, selection is already attempted */
        if( (!multiSel) )
        {
            multiSel = true;
            /* Multiple devices were found, activate first of them */
            rfalNfcGetDevicesFound( &dev, &devCnt );
            rfalNfcSelect( 0 );

            //platformLog("Multiple Tags detected: %d \r\n", devCnt);
        }
        else
        {
            rfalNfcDeactivate( RFAL_NFC_DEACTIVATE_DISCOVERY );
        }
    }
    else if( st == RFAL_NFC_STATE_START_DISCOVERY )
    {
        /* Clear multiple device selection flag */
        multiSel = false;
    }
}

 

I can also tell you my worker function always goes to line 1075 rfal_nfc.c 

and never goes in 

if( rfalIsGTExpired() ) /* Wait until Guard Time is fulfilled */

even though the timer is activated a few lines before.

 

Can you tell me what am I missing?

1 ACCEPTED SOLUTION

Accepted Solutions
Brian TIDAL
ST Employee

Hi,

after investigation in private, it appears that the IRQ_OUT pin is not connected whereas the RFAL is relying in this pin to read the responses from the ST25R95. 

In that case the st25r95SPIPollRead function needs to be modified to use the SPI poll mode instead of the interrupt mode. Here is the modified function

/*******************************************************************************/
ReturnCode st25r95SPIPollRead(uint32_t timeout)
{
    uint32_t timer;
    ReturnCode retCode = ERR_NONE;
    uint8_t response;
    
    timer = platformTimerCreate(timeout); 
    do {
        platformSpiSelect();
        platformDelay(1);
        st25r95SPISendReceiveByte(ST25R95_CONTROL_POLL);
        response = st25r95SPISendReceiveByte(ST25R95_CONTROL_POLL);
        platformSpiDeselect();
    }
    while (!ST25R95_POLL_DATA_CAN_BE_READ(response) && (timeout != 0) && !platformTimerIsExpired(timer));
    
    if (!ST25R95_POLL_DATA_CAN_BE_READ(response))
    {
        retCode = ERR_TIMEOUT;
    }
    return (retCode);
}

Note that IRQ_OUT is needed for some features such as the WFE mode (see Idle command in the datasheet). Make sure not to use this WFE mode when the IRQ_OUT is not connected.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

3 REPLIES 3
Brian TIDAL
ST Employee

Hi,

can you connect a logic analyzer on SPI (CLK/MOSI/MISO/CS) + IRQ_IN + IRQ_OUT and send me the trace in private?

If you do not have logic analyzer, can you set  ST25R95_DEBUG to true in st25r95_com.c and st25r95_com_spi.c and output the trace on a serial port?

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Brian TIDAL
ST Employee

Hi,

after investigation in private, it appears that the IRQ_OUT pin is not connected whereas the RFAL is relying in this pin to read the responses from the ST25R95. 

In that case the st25r95SPIPollRead function needs to be modified to use the SPI poll mode instead of the interrupt mode. Here is the modified function

/*******************************************************************************/
ReturnCode st25r95SPIPollRead(uint32_t timeout)
{
    uint32_t timer;
    ReturnCode retCode = ERR_NONE;
    uint8_t response;
    
    timer = platformTimerCreate(timeout); 
    do {
        platformSpiSelect();
        platformDelay(1);
        st25r95SPISendReceiveByte(ST25R95_CONTROL_POLL);
        response = st25r95SPISendReceiveByte(ST25R95_CONTROL_POLL);
        platformSpiDeselect();
    }
    while (!ST25R95_POLL_DATA_CAN_BE_READ(response) && (timeout != 0) && !platformTimerIsExpired(timer));
    
    if (!ST25R95_POLL_DATA_CAN_BE_READ(response))
    {
        retCode = ERR_TIMEOUT;
    }
    return (retCode);
}

Note that IRQ_OUT is needed for some features such as the WFE mode (see Idle command in the datasheet). Make sure not to use this WFE mode when the IRQ_OUT is not connected.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
mahdi-questat
Associate

Thank you, Brian and the team for your responsiveness and support.