cancel
Showing results for 
Search instead for 
Did you mean: 

ST25R3911B RFAL Library - i_err bit remains high - infinite loop

fredj0207
Associate III

Hello,

I'm using RFAL v2.6.0 and ST25R3911B and I get an issue with the IRQ management.

Using ISO14443 Type-A tag,  the IRQ remains high causing the while loop not to exit. 

In this condition, the i_err bit of the main interrupt register is '1' while the two  interrupt registers (Timer and NFC interrupt register and Error and wake-up interrupt register) have all of their bits to '0'. 

 

Reading these register in a loop cannot clear the i_err bit. 

 

The last content prior the lock state is:

- Main interrupt register: 0x33 -> i_rxs, i_rxe, i_tim, i_err

- Timer and NFC interrupt register: 0x20 

 - Error and wake-up interrupt register: 00  (Should be different from 0)

16 REPLIES 16
Brian TIDAL
ST Employee

Hi Frederic,

what is your hardware setup:

  • X-NUCLEO-NFC05A1 + NUCLEO MCU board (which one?)
  • or a custom board? Feel free to share details (MCU, etc.)

Do you use the X-CUBE-NFC5 package or the RFAL for ST25R3911B package? Do you use a bare metal implementation or running inside and RTOS?

" the IRQ remains high causing the while loop not to exit". Do you refer to the while loop inside st25r3911CheckForReceivedInterrupts:

BrianTIDAL_0-1702650048745.png

Can you connect a logic analyzer on the SPI (CLK/MISO/MOSI/CS) + ST25R3911B_IRQ and provide the trace  from the analyzer?

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.

Hi Brian,

This is a custom board using an ESP32-WROOM-32E as MCU (OS is ESP-IDF based)
SPI communication is 5MHz.

Yes I refer to the while loop inside st25r3911CheckForReceivedInterrupts.

In our implementation, the function is called from a high priority task which is notified by the GPIO ISR as it is not possible to execute the full st25r3911CheckForReceivedInterrupts in an IRQ routine (too long for a multi-task, multi-core OS).

Please also note, that I have absolutely no problem using ISO15693 tag.  The problem occurs only with ISO 14443-A configuration. It looks like the i_err is raising without having other bits set and so in this condition it is not possible to clear it just by reading the registers as they are already cleared.

And the RFAL is working well if I remove the while condition.

Unfortunately for now, I do not have the material to scope any signals.

Regards,

 

Hi, 

 

are you reading all three interrupt registers in one frame (DS: in one attempt)? We are no aware of this specific issue. 

You might try to detect this condition and then issue a Clear command in this case - maybe it helps.

 

BR, Ulysses

Hi,

Yes I'm using the RFAL library code. 

I will try your suggestion but as this case happens very often I am afraid that this will significantly reduce the performance of our system. 

For information, in our product (you can have a look at centiloc.com if you want), we often try to communicate with a tag which is not really in the operating volume of the antenna. As a result we could have a lot of communication issues (framing, wrong collision) but it shall not lock the ST25R chip.  

Regards

 

Brian TIDAL
ST Employee

Hi Frederic,

can you elaborate on how platformProtectST25RComm and platformUnprotectST25RComm has been implemented in your application?

See for example the FreeRTOS_polling demo inside the ST25 embedded NFC library for ST25R3916 for an example of the RFAL running inside an RTOS. The software architecture is probably similar to yours i.e. the ST25R39xx ISR runs inside a critical task triggered by the interrupt and the NFC loop runs in the main task.

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.

Hi Brian,

Our software is not using critical section as it is too restrictive. We only use binary mutexes to protect SPI communication and status register accesses. 

However, I do not think the problem is about OS our SPI communication. 

I log the contents of the three interrupt registers in the function and the status is clear:

Every thing is working as expected until we get i_err=1 in main register with a null register 19 h (that should be impossible). After this I read in an infinite loop the three registers to:  0x01 0x00 0x00 

If it was something about SPI communication, reading again and again should clear all the bits at one time.  Am I wrong ?

 

Regards

Fred

Brian TIDAL
ST Employee

Hi Frederic,

as explained by @Ulysses HERNIOSUS, we are not aware of this specific issue in spite of a lot of testing in different environments (bare metal, RTOS, Linux, ...). I've prepared a setup with tags being at the limit of the operating volume to create communication errors but so far I do not see any issues. Having a logic analyzer trace would help to analyze this issue. You can contact @Ulysses HERNIOSUS and me in private as soon as you can connect a logic analyzer and provide a trace file.

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.

Hi Brian,

I have test the solution propose by Ulysses and it works. 

No I have the following code:

    while( platformGpioIsHigh( ST25R_INT_PORT, ST25R_INT_PIN ) )
    {
        st25r3911ReadMultipleRegisters(ST25R3911_REG_IRQ_MAIN, iregs, sizeof(iregs));

        irqStatus |= (uint32_t)iregs[0];
        irqStatus |= (uint32_t)iregs[1]<<8;
        irqStatus |= (uint32_t)iregs[2]<<16;

        if( iregs[0] & 0x01 )
        {
               st25r3911ExecuteCommand(ST25R3911_CMD_CLEAR_FIFO);
        }
    }

This is the only way to clear i_err bit in main interrupt register (whatever other registers values are).

 

Hi,

we are still puzzled why this would be happening. We have seen weird issues also when the SPI driver was not doing what it was supposed to be. So I would really like to see a logic analyzer trace of the communication in this case.

Also for your workaround implementation: I would likely make it more specific by moving to 

 if( (iregs[0] & 0x01) && (0 == iregs[2]) )

 

 BR, Ulysses