2023-01-31 10:58 AM
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?
Solved! Go to Solution.
2023-02-08 01:22 AM
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
2023-02-01 11:17 PM
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
2023-02-02 06:32 AM
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.
2023-02-03 01:49 AM
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
2023-02-05 08:04 PM
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
2023-02-06 03:51 AM
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
2023-02-06 05:09 AM
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
2023-02-08 01:22 AM
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