cancel
Showing results for 
Search instead for 
Did you mean: 

ST25R3914 Library Issue

APant.2
Associate III

Hello,

I want to apologize in advance for how long this post is. I wanted to provide as much information as I could so I can help you (the reader) get a better picture of what might be going on. Sorry.

I am currently working on a project that uses a st25r3914 nfc chip to detect and interface with an NFCa tag. Also, I am using the pre-made RFAL for ST25R3911B library so I can get the chip up and running quickly. Unfortunately, this process has not been going so well. I am running into issues interfacing with a tag.

Background Info

I have successfully merged the pre-made library with the rest of my code and have populated the platform.h header file with all that is necessary. To test if the library is setup correctly, I am using the exampleRfalNfca.c example program that came with the documentation. I have verified that the system is initializing the RFAL lib correctly given that the return of the function rfalInitialize() is 0 (ERR_NONE). As an added layer of confidence, I have also enabled the ST25R_SELFTEST and ST25R_SELFTEST_TIMER to be completely sure everything is initialized and setup correctly. With both macros enabled, the function still returns a 0.

The issue I am having then arises in the next part of the example program. When I initially power the system, and put a tag close to the antenna, the program successfully detects it. It then moves forward to running the collision resolution routine. At this point the function return a value of 4 (ERR_TIMEOUT) and does not continue with the rest of the algorithm. It then goes back and restarts the process. This time, when I bring a tag close to the antenna, the function rfalNfcaPollerTechnologyDetection() always returns a value of 4 and never detects a tag again. After debugging the library, I figure out that after the tag is detected the first time, the field does not turn on anymore, even though the program runs through the code to turn it on. This would explain why the tag isn’t being detected anymore.

Debugging

I then began to step through the code to figure out exactly why this was happening. The only thing I was able to figure out was that when the system is initially powered on and no tag has been detected, the field turns on right after ST25R3911_REG_OP_CONTROL_tx_en bit has been set in the ST25R3911_REG_OP_CONTROL register (this step in the rfalFieldOnAndStartGT routine). Once a tag has been detected and the program sets the tx_en bit, the field does not turn on. I have verified this theory using an oscilloscope. Image nfc_field shows the signal before a tag is detected, and image no_nfc_field shows after.

My next thought was that maybe it has something to do with the interrupts. I began scoping the interrupt line along with the SPI peripheral. I observed that when the library is attempting to detect a tag, 2 interrupts happen. The first one is caused by the I_txe (IRQ due to end of transmission). The second is caused by I_tim (IRQ due to timer or NFC event) and I_nre (IRQ due to No-Response Timer expuire). This makes sense. Then when I bring a tag near the antenna, 3 interrupts happen. The first one is always the same, I_txe. The second one was caused by I_rxs (IRQ due to start of receive). And the third was because I_rxe (IRQ due to end of receive). This also makes sense. After that only 2 interrupts happen, and the cause is the same as the first explanation ( I_txe and (I_tim & I_nre) ). Here is where I observed something interesting. The time between the first set of 2 interrupts (before tag) was about 162us. After the tag was found, the time between them was 81 us. This was a bit odd to me and don’t know why the chip produces the interrupts twice as fast. I have attached 3 images to show the IRQ line during all three instances - irq_beforeTag, irq_tagDetected, and irq_afterTag.

Does anyone know what might be going on? I've spend 2 days already attempting to debug this, but to no avail.

1 ACCEPTED SOLUTION

Accepted Solutions
APant.2
Associate III

Brian,

I finally got the library to work. The issue was caused by NXP's way of implementing the SPI protocol. It turns out that within the library, there are a couple of instances where Tx and Rx are done in two separate transactions. This works great when you have control over the CS line, but since the NXP SDK controls this line with each call to their transmit function, both instances were being treated as two different SPI calls.

0693W00000SwMaxQAF.png 

Given this information, when the program called st25r3911ReadFifo, the second SPI call overwrote the osc bit, which inevitably caused the chip to output the 27.2Mhz signal.

Solution

After looking through the documentation, I stumbled across the ST25R_COM_SINGLETXRX preprocessor directive, as you mentioned in your post. I enabled this and the library worked. I am able to detect tags now.

Thank you Brian for all of your help! I truly appreciate it.

For anyone else using NXP SDK with freeRTOS

  • Setup your project similar to ST25 embedded NFC Library (freeRTOS example)
  • Create a Mutex instead of taskENTERCRITICAL/EXIT for platformProtect.
  • Create a Binary semaphore for triggering between IRQ and main NFC task.
  • Enable ST25R_COM_SINGLETXRX preprocessor directive at compile time.

I believe that is all of the steps. Hope this helps.

Adan

View solution in original post

13 REPLIES 13
Brian TIDAL
ST Employee

Hi,

how have you implemented the platformProtectST25RComm/platformUnprotectST25RComm and platformProtectST25RIrqStatus/platformUnprotectST25RIrqStatus? How have you implemented the interrupt handling?

The ST25 embedded NFC library provides a FreeRTOS demo (for ST25R3916 but not for ST25R3911B). In this demo, there is a dedicated ISR task handling the ST25R3916 IRQ. This task has an higher priority (osPriorityHigh) than the main NFC task (osPriorityNormal). taskENTER_CRITICAL and taskEXIT_CRITICAL are used to protect access to st25r3916interrupt.status and to protect the serial communication (SPI) between the ISR task and the NFC main task.

I would suggest to have a look on this demo and try to align as much as possible in particular for the protection of st25r3911interrupt.status.

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.
APant.2
Associate III

Brian,

Thank you for your reply. I really appreciate it!

  • For both, platformProtectST25RComm/platformUnprotectST25RComm and platformProtectST25RIrqStatus/platformUnprotectST25RIrqStatus, I use a semaphore.
  • The way I handle the interrupt is as follows:
  1. I detect the interrupt and inside the ISR handler, I send a queue to the dedicated ISR task.
    1. Within the ISR task, I receive the queue message and call the st25r3911Isr() function.
    2. Go back to waiting for queue message.
  • I will take a look at the demo and let you know if I have any questions.

Thanks,

Adan

Brian TIDAL
ST Employee

Hi Adan,

in the FreeRTOS demo, the ISR Task is notified by the ISR Handler (vTaskNotifyGiveFromISR). A queue is not needed as the st25r3911Isr reads the ST25R3911IRQ registers until the IRQ pin is released. Task notification mechanism looked more adequate than queue when we developed the demo. For the protect/unprotect, we used brut force taskENTER_CRITICAL and taskEXIT_CRITICAL. The main NFC task is a "dense" loop running every 10 ms with a forced execution when an interrupt has been processed by the ISR 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.
APant.2
Associate III

Brian,

After looking at the demo, your implementation of the notifications makes sense. I was wondering if something like that could be done instead of queues and you guys hit it right on the nail. I like it.

I will also make the modification to protect/unprotect, but I am curious why you guys used the brute force way instead of a semaphore?

Is the "forced execution" you mentioned accomplished with the semaphore? After looking at the code, this makes sense, but I wanted to double check.

Thanks,

Hi,

"I will also make the modification to protect/unprotect, but I am curious why you guys used the brute force way instead of a semaphore?" Well, basically because this is simple and this is working.

"Is the "forced execution" you mentioned accomplished with the semaphore? After looking at the code, this makes sense, but I wanted to double check.". Yes, this is done thanks to the semaphore.

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.
APant.2
Associate III

Brian,

Unfortunately, I cannot use the taskENTER_CRITICAL/taskEXIT_CRITICAL due to limitation of the NXP SDK; I've kept the mutex for the protect/unprotect. Although, I have implemented everything else.

I'm also running the example program shown in the freeRTOS demo, but the chip does not seem to work still. I get the same results as before. I'm going to attempt to step through the code and see if I can figure what is going on.

Thanks,

Adan

Brian TIDAL
ST Employee

Hi,

can you enable the  ST25R_SELFTEST and ST25R_SELFTEST_TIMER as global defines at compiler level. and check the return code of the st25r3911Initialize function?

can you also connect a logic analyzer on the SPI (CLK/MOSI/MISO/CS) + ST25R3911B IRQ and send a trace from the initialization up to the issue?

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.
APant.2
Associate III

Brian,

Enabling those 2 preprocessor directives returns a 0 (ERR_NONE) from the initialization function.

I am a bit confused with your second question. Do you want me to send you a single snip showing all SPI traffic between init and the issue? or a snip of all SPI transactions between Initialization and issue?

Thanks,

Adan

Brian,

I potentially found the culprit to my issue, but still working on a solution and maybe you can help me with this.

After probing the hardware I observed the following behavior on the RFO1 pin:

  • Upon power-on, no card put into the field, the frequency was 13.56Mhz.
  • After putting the card in the field, the frequency changes to 27.2Mhz. From this point, the frequency does not change back to 13.56Mhz.

This is a problem because the hardware (antenna) was tuned to work at the 13.56Mhz.

Given this change in frequency, it led me to believe that somewhere in the library, the IO Configuration Register 1 is being changed to run at the 27.2Mhz. To verify this, I polled the register and checked what the osc bit was set to in both instances. Here is my results,

  • When signal is running at 13.56Mhz, the bit is set to 1.
  • When signal is running at 27.2Mhz, the bit is set to 0.

Is there something in the code that is inverting the signal? or how can I go about resolving this problem?

Thanks,

Adan