cancel
Showing results for 
Search instead for 
Did you mean: 

Errors in initializing ST25R3911B

vaibh_p
Associate II

Hey hi ,

Can anybody suggest why ST25R3911B is giving following errors:

  • I am using "exampleRfalNfca.c" example provided in RFAL library doc.

The ST25R3911B IC is initializing properly for some initial functions but while starting field on and timer it gives some error as described below:

  1. rfalInitialize() ; No Error
  2. rfalFieldOff() : No Error
  3. rfalNfcaPollerInitialize() : No Error
  4. rfalFieldOnAndStartGT() : Gives "ReturnCode" error as "0x0C"
    1. After debugging in this function , found out following problems:
    2. rfalSetAnalogConfig() : Gives no error
    3. st25r3911PerformCollisionAvoidance() : this returns with the error "0x0C"

And further after in main loop , the Poller fucntion "rfalNfcaPollerTechnologyDetection()" is returning with error "0x03".

Need some help to debug what causing the problem.

1 ACCEPTED SOLUTION

Accepted Solutions
Ulysses HERNIOSUS
ST Employee

Hi,

I am suspecting that either your interrupt handling or your timer implementation is damaged: The error codes you encounter are probably ERR_INTERNAL and ERR_IO (defined in st_errno.h).

st25r3911PerformCollisionAvoidance() will return ERR_INTERNAL if no interrupt (CAT or CAC) is received within ST25R3911_CA_TIMEOUT=10 ms.

Best to use a logic analyzer to observe SPI + IRQ pins and see how st25r3911PerformCollisionAvoidance() is executed.

Regards, Ulysses

View solution in original post

11 REPLIES 11
Ulysses HERNIOSUS
ST Employee

Hi,

I am suspecting that either your interrupt handling or your timer implementation is damaged: The error codes you encounter are probably ERR_INTERNAL and ERR_IO (defined in st_errno.h).

st25r3911PerformCollisionAvoidance() will return ERR_INTERNAL if no interrupt (CAT or CAC) is received within ST25R3911_CA_TIMEOUT=10 ms.

Best to use a logic analyzer to observe SPI + IRQ pins and see how st25r3911PerformCollisionAvoidance() is executed.

Regards, Ulysses

vaibh_p
Associate II

thanks Ulysses , I will recheck the same.

SDesa.1
Associate II

Hi Ulysses,

I am seeing the exact same issue. I checked the SPI signals on the logic analyzer and I do see an interrupt set on the INT pin after sending the field ON command is sent in the st25r3911PerformCollisionAvoidance() routine. See attached. However, I still get the return error as ERROR_INTERNAL or 0x0C.

Under what circumstances will CAT or CAC interrupts not occur?

0693W000000VV5EQAW.png

Ulysses HERNIOSUS
ST Employee

Hi,

the chip will always produce either I_cat odr I_cac. Seemingly in your trace it has produced one of them but the software is not reading the interrupt status register - that is why the INT line does not get cleared and software will probably run into ST25R3911_CA_TIMEOUT.

Regards, Ulysses

CDowd.1
Associate II

Hello,

I'm have a very similar problem, I'm also getting the 0x0C error returned from st25r3911PerformCollisionAvoidance. The board seems to raise an interrupt within the timeout just as shown above by SDesa, but I haven't been able to work out where the issue is in the software that's preventing it from reading the interrupt status register. Were either of you able to solve this problem and could you share what you did to fix it?

I suspect my problem is in my interrupt code (I'm working on an ESP32 and that's the only code I've done myself), but I don't know where to look for the problem.

Hi,

well I guess you need to put a breakpoint into ISR and a multimeter to observe the state of the INT pin. And then read the doc of your ESP32 / HAL of it.

Regards, Ulysses

SDesa.1
Associate II

Hi @CDowd.1​ ,

You need to call the rfal lib function st25r3911Isr() (in st25r3911_interrupt.c) in your ISR for the INT pin from ST25R3911B to your MCU. I was missing that. Your ST25R is setting the INT high correctly, your ISR for the INT pin then needs to call the function st25r3911Isr() , which will initiate a SPI trnsaction to read the three interrupt status registers starting at 0x17, once these registers are read successfully then the INT line will go low.

A point to note: When you call the function st25r3911Isr() from an ISR context, you are going to execute SPI read transactions in an interrupt context. If your SPI transactions are interrupt based, then make sure they have a higher priority than the interrupt assigned to INT pin of the ST25R or make sure that the interrupt associated with INT pin is cleared before you execute the function st25r3911Isr().

Hope this helps.

Thank you Ulysses and SDesa. So I already have an ISR that is fired when the INT pin goes high. I use it to raise a flag (using a task notification) which unblocks a high priority function that calls st25r3911Isr(). I tried calling st25r3911Isr() directly from my interrupt, but I had issues with doing an SPI transaction within an interrupt context (the ESP SPI driver can't run when called from within an ISR). This works and st25r3911Isr() gets called properly. It also seems to be called within the ST25R3911_CA_TIMEOUT. I'm using polling SPI transactions so the ST25R interrupt is the only one I have assigned, but thanks for the tip.

After rfalFieldOnAndStartGT() has finishing calling the INT pin goes back low, so I'm assuming that at least from the ST25r3911 perspective that the interrupt status registers have been read successfully. My st25r3911interrupt.status however remains 0, which gives me the 0x0C error from st25r3911PerformCollisionAvoidance().

I'm going to double check that my spiTxRx() function is properly recieving, but if I'm able to check the chip ID then it should be functional. Right now I am suspecting that my issue is something simple somehow, but I'm tearing my hair out trying to find it.

Okay I finally found the issue, it was unrelated to the interrupts but I hope it helps someone else out there.

The SPI driver I was using had an option to define the CS pin, so I had the SPI driver managing the CS during each transaction. The function st25r3911ReadMultipleRegisters() calls spiTxRx() twice, once with only the command and a second time with the command empty to receive the response. Because my SPI transmit function inside spiTxRx() was toggling the CS pin for each transaction, the two calls to spiTxRx() were done as different transactions and it never recieved a response the second time it was called. The normal st25r3911ReadRegister() function worked because it did the whole transaction in a single call to spiTxRx().

To fix it I just disabled the CS option in my SPI intialisation and toggled the CS pin using the platformSpiSelect() and platformSpiDeselect() functions, as the code was intended. Trying to change stuff without understanding why it's there to begin with is the cause of my problem here.