Skip to main content
Associate II
August 3, 2026
Solved

st25r3911b Tag Detection Issue

  • August 3, 2026
  • 22 replies
  • 304 views

So our System works fine most of the time but sometimes the Reader does not detect the tag and we observe that 
rfalNfcState are just keep fluctuating between RFAL_NFC_STATE_POLL_TECHDETECT and  RFAL_NFC_STATE_LISTEN_TECHDETECT  same as when no tag present in the field of Reader and it is not able to satisfy this if condition.

“

if( rfalNfcIsDevActivated( rfalNfcGetState() ) ) // this if condition

”

We observed that even if we do controller reset it doesn’t fix the issue only when we power cycle the reader{st25r3911b} it start working again normally.

I’m attaching the code with this i want your team to review it to let us know what exactly we are doing wrong which leading to this state where our rfal state machine not switching properly, With Restart_flag we are doing reinitialization i want you to review that whatever sequence we are following is correct or not 
 

Main.c  {Rfid Reinitialization sequence}

Please help us fix this issue and could you provide or help us that through software function or any register so that can we reset the reader without need to manually power cycle the reader.

Kindly find the attachments attached of main.c and demo.c.

Best answer by Ulysses HERNIOSUS

Hi,

you would again compare all the registers to try to identify which setting may have changed. 

To your tests itself: 

  • osc_ok=1 is just a result of en=1. osc_ok=0 with en=1 would only happen if the crystal has fallen off.
  • RFO AM ON level is something which may change over runtime: different modulation depth if configures so, eg. A848 if that is used. It is not the energizing level of the tag. That would be RFO_AM_OFF_LEVEL.

 

But in the end: Try to find out what is going on. In cases where your device is not healthy any more: Record enough time in the logic analyzer and inspect/let us help you to inspect it.

 

Ulysses

BR, Ulysses

22 replies

Brian TIDAL
ST Technical Moderator
August 31, 2026

Hi,

The logic analyzer capture shows only the various SPI accesses once the system is stuck.

Could you capture what happens before the system becomes stuck and up to that point. Also include the GPIO that controls the power.

Regarding the recovery mechanism, modifications to the ST25R3911B registers can affect RFAL behavior. For example, clearing the "en" bit in ST25R3911_REG_OP_CONTROL in ST25R_OscKick() can affect that behavior.

The ST25R3911B interrupt check every 1000 ms based on rfidint must be performed only when RFAL is not suspended, that is, only when RF_Field_off is false. As soon as RF_Field_off is true, RFAL is deinitialized and is unlikely to raise any interrupt.

Rgds

BT

 

 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Explorer
September 1, 2026

Hii,
I noticed same that when RF Field is off no interrupt will be triggered so i added that condition also, but we don’t know whatever mechanism is going to work or not.
These waveforms were collected from a module where we haven’t implemented Reader power off thing, it just a polling code instead of Interrupt based but still we faced the issue.
And Problem is that we don’t know when it occurs so either we can capture data when it is working fine and when it stopped.

Could you provide any method which can be able to somehow can help us resolve it? NVIC Reset after Powering off on reader is one thing that can work but problem, we can’t allow controller to reset as it will lead slave to go to INIT which can be problematic for us.

Regards,
Akshay

Ulysses HERNIOSUS
ST Technical Moderator
September 2, 2026

Hi Akshay,

on your firmware trigger an MCU pin when you discover the state machine not advancing any more. Trigger in Saleae on it using e.g. this method: https://www.saleae.com/support/logic-software/capturing-data/how-to-trigger-the-end-of-a-capture-instead-of-the-start

 

You have not followed-up on the temperature topic above. For me this is a promising lead!

 

BR, Ulysses

Brian TIDAL
ST Technical Moderator
September 2, 2026

Hi,

In addition to Ulysses answers, could you please explain why the application suspends or resumes the RFAL when it receives instrument message 25 or 26? Is this behavior intended to enter a low-power mode?

Because the RFAL in the application has been upgraded to version 4.0.0, the low-power mode APIs rfalLowPowerModeStart and rfalLowPowerModeStop can be used. Call rfalLowPowerModeStart instead of rfalDeinitialize. Make sure that RFAL_FEATURE_LOWPOWER_MODE is defined as true in the platform header file.

The prototype of rfalNfcDeactivate has changed between v2.6.0 and v4.0.0. Replace rfalNfcDeactivate(false) with rfalNfcDeactivate(RFAL_NFC_DEACTIVATE_IDLE).

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Explorer
September 3, 2026

Hii,
 

void demoCycle( void )
{
static rfalNfcDevice *nfcDevice;
static UINT32 j=0;

#if RF_Fieldoff_test

if(Instrument_write_ptr->instrument_data.Last_used_date==23)
{
uint8_t regs[ST25R3911_REG_IC_IDENTITY + 1];
uint8_t size = sizeof(regs);
if(Instrument_write_ptr->instrument_data.Used_hsptl_code==0)
{
logUsart("Instrument connected\r\n");
}
st25r3911GetRegsDump(regs, &size);
for (uint8_t i = 0; i < size; i++)
logUsart("Reg[0x%02X] = 0x%02X\r\n", i, regs[i]);
}

if ((Instrument_write_ptr->instrument_data.Used_hsptl_code==1||Instrument_write_ptr->Header == 25 ) && (RF_Field_off == 0))
{
RF_Field_off = 1;
rfalNfcDeactivate( false );
rfalDeinitialize(); /* Safely clean up RFAL state */
return;
}

if ((Instrument_write_ptr->instrument_data.Used_hsptl_code==0) && (RF_Field_off == 1))
{
static uint16_t reinitBackoff = 0;

if (reinitBackoff > 0U) { reinitBackoff--; return; }

if (demoIni())
{
RF_Field_off = 0; /* clear ONLY on success */
state = DEMO_ST_START_DISCOVERY;
platformLog("RF re-init OK\r\n");
}
else
{
reinitBackoff = 100U; /* retry in ~100 cycles, stay latched */
platformLog("RF re-init FAILED\r\n");
}
return;
}

#endif

rfalNfcWorker(); /* Run RFAL worker periodically */
if ((Instrument_write_ptr->Header == 25) && (RF_Field_off == 1))
{
return;
}

switch( state )
{
/*******************************************************************************/
case DEMO_ST_START_DISCOVERY:
rfalNfcDeactivate( RFAL_NFC_DEACTIVATE_IDLE );
rfalNfcDiscover( &discParam );
state = DEMO_ST_DISCOVERY;
break;

/*******************************************************************************/
case DEMO_ST_DISCOVERY:
if( rfalNfcIsDevActivated( rfalNfcGetState() ) )
{

The reasoning behind using headers 25/26 and the used_hsptl_code values 0 and 1 is as follows:

  • When the tag is mounted on the reader, used_hsptl_code is set to 0, which initializes the RFID reader.
  • When the tag is removed, used_hsptl_code is set to 1, which deinitializes the RFID reader.
  • While reading the header, the value is set to 26.
  • When we want to lock the data, the header is changed to 25, which allows the process to exit after rfalWorker() executes.

This is the reasoning behind the current implementation. I will also look into your suggestions and try to implement them accordingly.

Regards,
Akshay

Explorer
September 3, 2026

And I have one doubt; I kept this function to check whether Reader is healthy or not, is this enough ?
 

static bool ST25R_IsHealthy(void)

{

uint8_t op = 0, auxd = 0, rfo = 0;

st25r3911ReadRegister(ST25R3911_REG_OP_CONTROL, &op);

st25r3911ReadRegister(ST25R3911_REG_AUX_DISPLAY, &auxd);

st25r3911ReadRegister(ST25R3911_REG_RFO_AM_ON_LEVEL, &rfo);

 

return ((op & ST25R3911_REG_OP_CONTROL_en) != 0U) && /* chip enabled */

((auxd & ST25R3911_REG_AUX_DISPLAY_osc_ok) != 0U) && /* oscillator up */

( rfo != 0x00U ); /* analog cfg applied */

}

Ulysses HERNIOSUS
ST Technical Moderator
September 3, 2026

Hi,

there are two aspects to your question:

  1. Does the ST25R_IsHealthy() guarantee that tag reading can still work? → No: There are many other settings would prevent proper tag reading. Coming up with an exhaustive list will be difficult.
  2. Does ST25R_IsHealthy()  detect the non-working reader state in your case? → You need to answer this by your own experiments.

BR, Ulysses

Explorer
September 3, 2026

Hii,
Actually the reason I pick these registers is based on what we observed while comparing the registers in working state and non working state, But it seems in working condition itself
 

st25r3911ReadRegister(ST25R3911_REG_OP_CONTROL, &op); → This is coming op ->144

st25r3911ReadRegister(ST25R3911_REG_AUX_DISPLAY, &auxd); → This is coming auxd → 18

st25r3911ReadRegister(ST25R3911_REG_RFO_AM_ON_LEVEL, &rfo); but rfo this is zero and it is failing.

 so what others you would suggest to check whether it is Ready state or not based on captured Register difference in working and not working state.

Regards,
Akshay

Ulysses HERNIOSUS
ST Technical Moderator
September 3, 2026

Hi,

you would again compare all the registers to try to identify which setting may have changed. 

To your tests itself: 

  • osc_ok=1 is just a result of en=1. osc_ok=0 with en=1 would only happen if the crystal has fallen off.
  • RFO AM ON level is something which may change over runtime: different modulation depth if configures so, eg. A848 if that is used. It is not the energizing level of the tag. That would be RFO_AM_OFF_LEVEL.

 

But in the end: Try to find out what is going on. In cases where your device is not healthy any more: Record enough time in the logic analyzer and inspect/let us help you to inspect it.

 

Ulysses

BR, Ulysses