2025-02-28 12:33 AM - last edited on 2025-02-28 6:55 AM by Andrew Neil
I am porting the ST25R3911B NFC module library to work with the Quectel EC200U 4G module in the Helios SDK. While I have successfully achieved rfalNfcInitialize and rfalFieldOnAndStartGT, I am facing issues when running the NFC-A polling code. The execution gets stuck inside the while loop mentioned in the callback of the ISR.
while (1)
{
rfalNfcWorker();
MYLOG("Checking NFC \n");
err = rfalFieldOff(); /* Turn the Field Off */
if(err != RFAL_ERR_NONE){
MYLOG("Error in rfalFieldOff: %d\n", err);
}
platformDelay(500);
err = rfalNfcaPollerInitialize(); /* Initialize RFAL for NFC-A */
if(err != RFAL_ERR_NONE){
MYLOG("Error in rfalNfcaPollerInitialize: %d\n", err);
}
err = rfalFieldOnAndStartGT(); /* Turns the Field On and starts GT timer */
if(err != RFAL_ERR_NONE){
MYLOG("Error in rfalFieldOnAndStartGT: %d\n", err);
}
/*******************************************************************************/
/* Perform NFC-A Technology detection */
err = rfalNfcaPollerTechnologyDetection(RFAL_COMPLIANCE_MODE_NFC, &sensRes); /* Poll for nearby NFC-A devices */
if (err == RFAL_ERR_NONE) /* NFC-A type card found */
{
/*******************************************************************************/
/* Perform NFC-A Collision Resolution */
err = rfalNfcaPollerFullCollisionResolution(RFAL_COMPLIANCE_MODE_NFC, MAX_DEVICE_DISCOVERY, nfcaDevList, &devCnt); /* Perform collision avoidance */
if ((err == RFAL_ERR_NONE) && (devCnt > 0))
{
MYLOG("NFC-A device(s) found %d\r\n", devCnt);
devIt = 0; /* Use the first device on the list */
/*******************************************************************************/
/* Check if desired device is in Sleep */
if (nfcaDevList[devIt].isSleep)
{
err = rfalNfcaPollerCheckPresence(RFAL_14443A_SHORTFRAME_CMD_WUPA, &sensRes); /* Wake up all cards */
if (err != RFAL_ERR_NONE)
{
MYLOG("Error in rfalNfcaPollerCheckPresence: %d\n", err);
continue;
}
err = rfalNfcaPollerSelect(nfcaDevList[devIt].nfcId1, nfcaDevList[devIt].nfcId1Len, &selRes); /* Select specific device */
if (err != RFAL_ERR_NONE)
{
MYLOG("Error in rfalNfcaPollerSelect: %d\n", err);
continue;
}
}
/*******************************************************************************/
/* Perform protocol specific activation */
switch (nfcaDevList[devIt].type)
{
case RFAL_NFCA_T1T:
/* No further activation needed for a T1T (RID already performed)*/
MYLOG("NFC-A T1T device found \r\n"); /* NFC-A T1T device found, NFCID/UID is contained in: t1tRidRes.uid */
/* Following communications shall be performed using:
* - Non blocking: rfalStartTransceive() + rfalGetTransceiveState()
* - Blocking: rfalTransceiveBlockingTx() + rfalTransceiveBlockingRx() or rfalTransceiveBlockingTxRx() */
break;
case RFAL_NFCA_T2T:
/* No specific activation needed for a T2T */
MYLOG("NFC-A T2T device found \r\n"); /* NFC-A T2T device found, NFCID/UID is contained in: nfcaDev.nfcid */
/* Following communications shall be performed using:
* - Non blocking: rfalStartTransceive() + rfalGetTransceiveState()
* - Blocking: rfalTransceiveBlockingTx() + rfalTransceiveBlockingRx() or rfalTransceiveBlockingTxRx() */
break;
case RFAL_NFCA_T4T:
MYLOG("NFC-A T4T (ISO-DEP) device found \r\n"); /* NFC-A T4T device found, NFCID/UID is contained in: nfcaDev.nfcid */
/* Activation should continue using rfalIsoDepPollAHandleActivation(), see exampleRfalPoller.c */
break;
case RFAL_NFCA_T4T_NFCDEP: /* Device supports T4T and NFC-DEP */
case RFAL_NFCA_NFCDEP: /* Device supports NFC-DEP */
MYLOG("NFC-A P2P (NFC-DEP) device found \r\n"); /* NFC-A P2P device found, NFCID/UID is contained in: nfcaDev.nfcid */
/* Activation should continue using rfalNfcDepInitiatorHandleActivation(), see exampleRfalPoller.c */
break;
}
rfalNfcaPollerSleep(); /* Put device to sleep / HLTA (useless as the field will be turned off anyhow) */
}
else{
MYLOG("Error in rfalNfcaPollerInitialize: %d\n", err);
}
}
else{
MYLOG("Error in rfalNfcaPollerFullCollisionResolution: %d\n", err);
MYLOG("NFC-A device(s) found %d\r\n", devCnt);
}
}
Would appreciate any guidance on this!
Thanks in advance.
Post edited to apply proper source code formatting - please see How to insert source code for future reference.
Solved! Go to Solution.
2025-03-04 12:09 AM
Hi Samman,
I have named the two states, locate them and put breakpoints. The next state after RFAL_TXRX_STATE_TX_TRANSMIT should be RFAL_TXRX_STATE_TX_WAIT_TXE. Find out why it isn't.
Ulysses
2025-02-28 1:04 AM
2025-02-28 4:08 AM
Hi,
your session2 shows no 57h frame after IRQ went high again. Potentially your ISR not triggering or your SPI abstraction having an issue when IRQ rises during normal register access. Could be a there is a problem in your platformProtect...() macros.
BR, Ulysses
2025-02-28 6:48 AM
Hi Ulysses,
I found that I had not properly defined the platformProtect...() macros. After correctly defining them to enable and disable the IRQ, the module no longer gets stuck in the ISR loop. However, I am now facing a new issue:
When executing rfalNfcaPollerTechnologyDetection, as soon as I bring an NFC-A card near, the module gets stuck in another loop indefinitely. This eventually causes the watchdog timer to reset the EC200U module.
The function executes rfalNfcaPollerFullCollisionResolution, which contains:
ReturnCode ret;
RFAL_EXIT_ON_ERR( ret, rfalNfcaPollerStartFullCollisionResolution( compMode, devLimit, nfcaDevList, devCnt ) );
rfalRunBlocking( ret, rfalNfcaPollerGetFullCollisionResolutionStatus() );
return ret;
It seems like the module is stuck inside rfalRunBlocking( ret, rfalNfcaPollerGetFullCollisionResolutionStatus() ); indefinitely.
I’m not sure what could be causing this behavior. Any suggestions on debugging this further would be greatly appreciated.
2025-02-28 6:56 AM
Hi Samman,
just again do a logic analyzer trace.
BR, Ulysses
2025-02-28 11:16 PM
2025-03-03 1:06 AM
Hi Samman,
I find in this trace:
P.S.: I have enabled the SPI transaction framer which make it easier to navigate the traces. It makes it easy to see e.g. all FIFO writes which are starting with "0x80".
BR, Ulysses
2025-03-03 7:47 PM
Hi Ulysses,
I’m not sure what’s causing this issue. Could you suggest some debugging steps to identify the possible root cause? Specifically, what might cause the MCU to not wait for I_TXE to happen, and what is the expected purpose of I_TXE in this context?
Additionally, I tried using rfalNfcaPollerSingleCollisionResolution, and I noticed that in rfalGetTransceiveStatus, the gRFAL.TxRx.state ends up as RFAL_TXRX_STATE_RX_FAIL. Do you have any insights into why this might be happening?
Thanks for your help!
2025-03-04 12:09 AM
Hi Samman,
I have named the two states, locate them and put breakpoints. The next state after RFAL_TXRX_STATE_TX_TRANSMIT should be RFAL_TXRX_STATE_TX_WAIT_TXE. Find out why it isn't.
Ulysses