Skip to main content
Visitor II
April 6, 2021
Solved

ST25r3916 card emulation long time operations

  • April 6, 2021
  • 2 replies
  • 1608 views

Hi,

I have implemented a smart card in software and the ccid class to interface it via the usb, everything works correctly even for long cryptographic operations (using wtx).

Now I wanted to extend the functionality of my card by adding the NFC interface and the chip I chose is the st25r3916 for possible future use as a reader as well.

I started from the demo_ce.c example in X-CUBE-NFC6 (STM32CubeExpansion_NFC6_V1.1.0) and everything works correctly until operations that take a short time to be performed, operations such as signature or key generation all fail by disconnecting the card from the reader.

What can I do to solve this problem? is there any way to implement the sending of the wtx packet in nfc as well?

Thanks and regards.

D.

    This topic has been closed for replies.
    Best answer by Ulysses HERNIOSUS

    Hi Pagano.paganino,

    I looked in the code and indeed we don't have a fully non-blocking demo code. The underlying APIs are all meant to be used non-blocking. Looking into demoCE() you can instead of the do{}while call it multiple times. If you also transform it like this:

     do
     {
     rfalNfcWorker(); 
     switch( rfalNfcGetState() )
     {
     case RFAL_NFC_STATE_ACTIVATED:
    	 	err = rfalNfcDataExchangeStart( NULL, 0, &rxData, &rcvLen, 0 ); // First transceive without tx data to get first poller frame
     if (ERR_NONE != err) break;
    		/* Intentional Fallthrough - call GetStatus once to get out of RFAL_NFC_STATE_ACTIVATED */
     case RFAL_NFC_STATE_DATAEXCHANGE:
    		err = rfalNfcDataExchangeGetStatus();
    		break;
     case RFAL_NFC_STATE_DATAEXCHANGE_DONE:
     txLen = ( (nfcDev->type == RFAL_NFC_POLL_TYPE_NFCA) ? demoCeT4T( rxData, *rcvLen, txBuf, sizeof(txBuf) ): demoCeT3T( rxData, *rcvLen, txBuf, sizeof(txBuf) ) );
     err = rfalNfcDataExchangeStart( txBuf, txLen, &rxData, &rcvLen, 0 );
     break; 
     case RFAL_NFC_STATE_LISTEN_SLEEP:
     default:
     break;
     }
     }
     while( (err == ERR_NONE) || (err == ERR_SLEEP_REQ) || (err==ERR_BUSY) );

    You will then have it fully non-blocking. Just call it at a decent frequency. The alternative would be to use the notifyCb and only issue rfalNfcDataExchangeStart()/GetStatus() and keep the state information inside the your code.

    Regards, Ulysses

    2 replies

    Technical Moderator
    April 6, 2021

    Hi pagano.paganino,

    sending wtx packets is implemented in RFAL. However you need to make sure to give RFAL time to perform such job by calling rfalNfcWorker() before FWT times out. The other alternative would be to change the used FWT (currently RFAL_ISODEP_DEFAULT_FWI with ~77ms is used).

    Regards, Ulysses

    Visitor II
    April 7, 2021

    Hi Ulysses,

    I tried as you suggested to invoke rfalNfcWorker(), in detail I invoked it in a periodic timer every 50ms but the result does not change.

    Any other suggestions?

    Thanks

    Technical Moderator
    April 7, 2021

    Hi pagano.paganino,

    as mentioned above:

    Inside rfalNfcListenActivation() please change  atsParam.fwi    = RFAL_ISODEP_DEFAULT_FWI; and give fwi a bigger value. You can consider increasing up to ~5secs. Of course this will have an impact on reactivity. How much time does your crypto take?

    Otherwise please do Logic Analyzer traces of SPI + IRQ + trigger pin on calling rfalNfcWorker(). It could also be a timing issue or porting issue in the timer interface.

    Best Regards, Ulysses

    Visitor II
    April 10, 2021

    Hi Ulysses,

    where can i find an example of card emulation mode using non-blocking api?

    All the examples I found are in blocking mode, any suggestions on where to find it or how to implement it?

    Thanks and best Regards,

    D.

    Technical Moderator
    April 13, 2021

    Hi Pagano.paganino,

    I looked in the code and indeed we don't have a fully non-blocking demo code. The underlying APIs are all meant to be used non-blocking. Looking into demoCE() you can instead of the do{}while call it multiple times. If you also transform it like this:

     do
     {
     rfalNfcWorker(); 
     switch( rfalNfcGetState() )
     {
     case RFAL_NFC_STATE_ACTIVATED:
    	 	err = rfalNfcDataExchangeStart( NULL, 0, &rxData, &rcvLen, 0 ); // First transceive without tx data to get first poller frame
     if (ERR_NONE != err) break;
    		/* Intentional Fallthrough - call GetStatus once to get out of RFAL_NFC_STATE_ACTIVATED */
     case RFAL_NFC_STATE_DATAEXCHANGE:
    		err = rfalNfcDataExchangeGetStatus();
    		break;
     case RFAL_NFC_STATE_DATAEXCHANGE_DONE:
     txLen = ( (nfcDev->type == RFAL_NFC_POLL_TYPE_NFCA) ? demoCeT4T( rxData, *rcvLen, txBuf, sizeof(txBuf) ): demoCeT3T( rxData, *rcvLen, txBuf, sizeof(txBuf) ) );
     err = rfalNfcDataExchangeStart( txBuf, txLen, &rxData, &rcvLen, 0 );
     break; 
     case RFAL_NFC_STATE_LISTEN_SLEEP:
     default:
     break;
     }
     }
     while( (err == ERR_NONE) || (err == ERR_SLEEP_REQ) || (err==ERR_BUSY) );

    You will then have it fully non-blocking. Just call it at a decent frequency. The alternative would be to use the notifyCb and only issue rfalNfcDataExchangeStart()/GetStatus() and keep the state information inside the your code.

    Regards, Ulysses