ST25R3911B Stuck in ISR While Polling for NFC-A on Quectel EC200U (Helios SDK)
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.
Observed Behavior:
- The module sometimes gets stuck in the ISR loop, with the interrupt pin remaining high even when no NFC-A card is near.
- Occasionally, instead of getting stuck, it throws RFAL_ERR_IO.
- In rare cases, it does not throw any error but gets stuck as soon as an NFC-A card is brought near.
- ST25R_SELFTEST_TIMER and ST25R_SELFTEST pass without any errors.
Polling Code:
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);
}
}
Troubleshooting Done:
- Verified that hardware connections are correct.
- Checked interrupt behavior using a logic analyzer (attached capture file).
- Ensured correct initialization of RFAL.
- Confirmed interrupt pin remains HIGH in error cases.
Request for Help:
- What could cause the interrupt pin to stay high indefinitely?
- Why does polling sometimes result in RFAL_ERR_IO?
- Are there any timing constraints I might be missing?
- Any modifications required for running this on the EC200U (Helios SDK)?
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.
