cancel
Showing results for 
Search instead for 
Did you mean: 

NFC06A1_PollingTagDetect : demoTransceiveBlocking blocks forever when in CE

JChen.41
Associate II

In NFC06A1_PollingTagDetect sample project, the function demoTransceiveBlocking blocks forever when in card emulation mode.

Using the sample project NFC06A1_PollingTagDetect in X-CUBE-NFC6 Software for STM32 and try the card emulation mode. Sometimes, the demoTransceiveBlocking( ) function does not return, if an android phone (NFC reader) is removed away from the antenna. Basically, the program stays in RFAL_NFC_STATE_DATAEXCHANGE state with err = ERR_BUSY in this scenario.

Is this any better way to identify that the phone (NFC reader) is remove away from the NFC06A1? By adding a timeout etc... ? I notice that it gives ERR_LINK_LOSS when the phone gets close to the NFC06A1 again. Can we get this error message right away when the link is loss and the RF field is gone?

1 ACCEPTED SOLUTION

Accepted Solutions

Hi Jonathan,

I think changing like this should be a quick fix for you:

             /* Automatic responses allowed during TxRx only for the SENSF_REQ */
-            if( (irqs & ST25R3916_IRQ_MASK_WU_F) != 0U )
+            if( ((irqs & ST25R3916_IRQ_MASK_WU_F) != 0U) && ((irqs & ST25R3916_IRQ_MASK_EOF) == 0U) )

I think we will need to make this field handling more robust by a different approach in future.

Best Regards, Ulysses

View solution in original post

7 REPLIES 7
Ulysses HERNIOSUS
ST Employee

Hi,

having seen a similar issue and reviewing the code, could you try to apply the following patch:

diff --git a/rfal_rfst25r3916.c b/rfal_rfst25r3916.c
index 0f253e1..ac27788 100755
--- a/rfal_rfst25r3916.c
+++ b/rfal_rfst25r3916.c
@@ -2164,41 +2164,41 @@ static void rfalTransceiveTx( void )
             /*******************************************************************************/
             else
         #endif /* RFAL_FEATURE_NFCV */
             {
                 /* Load FIFO with the remaining length or maximum available */
                 tmp = MIN( (gRFAL.fifo.bytesTotal - gRFAL.fifo.bytesWritten), gRFAL.fifo.expWL);       /* tmp holds the number of bytes written on this iteration */
                 st25r3916WriteFifo( &gRFAL.TxRx.ctx.txBuf[gRFAL.fifo.bytesWritten], tmp );
             }
 
             /* Update total written bytes to FIFO */
             gRFAL.fifo.bytesWritten += tmp;
 
             /* Check if a WL level is expected or TXE should come */
             gRFAL.TxRx.state = (( gRFAL.fifo.bytesWritten < gRFAL.fifo.bytesTotal ) ? RFAL_TXRX_STATE_TX_WAIT_WL : RFAL_TXRX_STATE_TX_WAIT_TXE);
             break;
 
 
         /*******************************************************************************/
         case RFAL_TXRX_STATE_TX_WAIT_TXE:
 
-            irqs = st25r3916GetInterrupt( (ST25R3916_IRQ_MASK_FWL | ST25R3916_IRQ_MASK_TXE) );
+            irqs = st25r3916GetInterrupt( (ST25R3916_IRQ_MASK_FWL | ST25R3916_IRQ_MASK_TXE | ST25R3916_IRQ_MASK_EOF) );
             if( irqs == ST25R3916_IRQ_MASK_NONE )
             {
                break;  /* No interrupt to process */
             }
 
 
             if( (irqs & ST25R3916_IRQ_MASK_TXE) != 0U )
             {
                 gRFAL.TxRx.state = RFAL_TXRX_STATE_TX_DONE;
             }
             else if( (irqs & ST25R3916_IRQ_MASK_FWL) != 0U )
             {
                 break;  /* Ignore ST25R3916 FIFO WL if total TxLen is already on the FIFO */
             }
             else
             {
                gRFAL.TxRx.status = ERR_IO;
                gRFAL.TxRx.state  = RFAL_TXRX_STATE_TX_FAIL;
                break;
             }

Please let me know about the result.

BR, Ulysses

JChen.41
Associate II

Unfortunately, this patch does not solve the problem. As a matter of fact, in the function

rfalRunTransceiveWorker()

It is in Rx state and only executes function rfalTransceiveRx(). But there is no interrupt to process.

...

case RFAL_TXRX_STATE_RX_WAIT_RXS:

      irqs = st25r3916GetInterrupt( (ST25R3916_IRQ_MASK_RXS | ST25R3916_IRQ_MASK_NRE | ST25R3916_IRQ_MASK_EOF) );

      if( irqs == ST25R3916_IRQ_MASK_NONE )

      {

        break; /* No interrupt to process */

      }

So it keeps looping at this place.

Hi,

not sure how it should forever loop in there. Latest if phone gets removed the ST25R3916_IRQ_MASK_EOF will be signaled, causing the loop to be left.

Which version of X-CUBE-NFC6 are you using?

Do you have an option to provide logic analyzer traces?

Best Regards, Ulysses

JChen.41
Associate II

Hi,

I am using the X-CUBE-NFC6 Software for STM32 version 2.0.0. The program emulate a NFC-F tag. and stuck at rfalTransceiveRx() even the phone is removed and no RF field present.

I think I can simulate the problem by setting the break point at the right place in func rfalTransceiveRx().

Basically, in the case RFAL_TXRX_STATE_RX_WAIT_RXE, the program does not handle ST25R3916_IRQ_MASK_EOF. If the phone, the RF field is removed at this time. this IRQ is not handled. Because this IRQ does not happen again, in the case RFAL_TXRX_STATE_RX_WAIT_RXS. So it loop forever in the function rfalTransceiveRx().

This is how I set breakpoint and duplicate this problem.

...

    case RFAL_TXRX_STATE_RX_WAIT_RXE:  /* PRQA S 2003 # MISRA 16.3 - Intentional fall through */

       

     

      /*******************************************************************************/

      /* REMARK: Silicon workaround ST25R3916 Errata #2.1.2             */

      /* ST25R396 may indicate RXS without RXE afterwards, this happens rarely on  */

      /* corrupted frames.                              */

      /* SW timer is used to timeout upon a missing RXE               */

      if( rfalTimerisExpired( gRFAL.tmr.RXE ) )

      {

        gRFAL.TxRx.status = ERR_FRAMING;

        gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_FAIL;

      }

      /*******************************************************************************/

       

      irqs |= st25r3916GetInterrupt( ( ST25R3916_IRQ_MASK_RXE | ST25R3916_IRQ_MASK_FWL | ST25R3916_IRQ_MASK_EOF | ST25R3916_IRQ_MASK_RX_REST | ST25R3916_IRQ_MASK_WU_F ) );

      if( irqs == ST25R3916_IRQ_MASK_NONE ) //Set a breakpoint here and and remove the phone when the program break here. Run again. A EOF IRQ happens when it breaks again. Run again and the system will loop in this func rfalTransceiveRx( )

      {

        break; /* No interrupt to process */

      }

       

How can I handle the EOF IRQ in the case RFAL_TXRX_STATE_RX_WAIT_RXE?

Thanks

Jonathan

Hi Jonathan,

reviewing the code with EOF interrupt it should fall through into RFAL_TXRX_STATE_RX_ERR_CHECK where then a LINK_LOSS would be signaled.

BR, Ulysses

JChen.41
Associate II

Hi Ulysses,

The irqs=0x8000800, with EOF and WU_F interrupt. So it does not fall through into RFAL_TXRX_STATE_RX_ERR_CHECK. It breaks in here.

      /* Automatic responses allowed during TxRx only for the SENSF_REQ */

      if( (irqs & ST25R3916_IRQ_MASK_WU_F) != 0U )

      {

        gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_WAIT_RXS;

        break;

      }

BR, Jonathan

Hi Jonathan,

I think changing like this should be a quick fix for you:

             /* Automatic responses allowed during TxRx only for the SENSF_REQ */
-            if( (irqs & ST25R3916_IRQ_MASK_WU_F) != 0U )
+            if( ((irqs & ST25R3916_IRQ_MASK_WU_F) != 0U) && ((irqs & ST25R3916_IRQ_MASK_EOF) == 0U) )

I think we will need to make this field handling more robust by a different approach in future.

Best Regards, Ulysses