2023-06-28 02:09 AM - last edited on 2023-07-04 11:44 PM by Ulysses HERNIOSUS
Hi!
A while back I started writing Rust driver for st25r3911b chip. Currently, it works and can read 14443A chip. The issue is that compared to official software (Discovery GUI) the read distance is about half. So if official software reads at 8-9cm then with rust driver it would just 5-6 cm.
I feel like I have messed up some register configurations. My knowledge of RF is very limited. Could someone point me in the right direction of what I should look into?
https://github.com/xpresshd/st25r3911b/blob/master/src/lib.rs#L168
Thanks!
Solved! Go to Solution.
2023-07-07 07:56 AM
Hi,
@RMuiz.1 wrote:What confuses me is why Intr jumps back high when I start reading interrupt registers
See § "Interrupt interface" in the ST25R3911B datasheet: [...]IRQ pin transitions to low after the interrupt bit(s) that caused its transition to high has (have) been read.
It is likely that a second interrupt is signalled while reading the second interrutp register (likely I_rxe interrupt).
Make sure to configure the Salae SPI decoder with CPOL=0 and CPHA=1 to properly decode the SPI frames. The SPI CS handling seems to be erroneous (except if another devices are connected to the SPI bus):
The SPI clock seems to be quite low (300 kHz). Our demos use a SPI clock = 3Mbps.
Rgds
BT
2023-06-28 03:57 AM
Hi,
could be that this is an effect of not setting the antenna calibration and target registers the same way as in the original FW. Which trim value is being achieved, or does it return an error?
Regards, Ulysses
2023-06-29 01:48 AM - edited 2023-06-29 03:59 AM
I did a few changes with the main firmware that doesn't impact driver logic and now the read distance is fine again. I'm very confused, but it seems to work. Maybe some race condition...
What is the correct way to check the error here? Currently, my calibrate logic looks like this (It should be the same as the official soft) https://github.com/xpresshd/st25r3911b/blob/jonas/src/lib.rs#L177
One thing that still bothers me is that driver crashes ~3 times per minute with IOError (Most often), FarmingError or InterruptTimeout. Even if there are no tags around.
It happens somewhere here https://github.com/xpresshd/st25r3911b/blob/jonas/src/lib.rs#L339
One thing I suspect is - `wait_for_interrupt` will sleep minimum 1ms and could be a lot longer if RTOS prioritizes other tasks. Could it be that there is a time limit in which I must process interrupt or it will move to another state?
Update:
I have noticed that after some reqa/wupa calls they stop getting back card data until the chip errors and is restarted. Could it be that I forgot to handle some error case? What could be the reason that reqa/wupa transmit is still called in a broken state, but no error is returned?
2023-06-29 04:15 AM
Hi,
please investigate the conditions in which your code returns IOError. The chip does not have such an error. Also InterruptTimeout should be more on your driver side. The FramingErrors sounds as being signaled by the ST25R3911B but you need to describe a bit more under which exact conditions. The error means incorrect framing over the RF. Such typically only happens close to the maximum operating range.
I think it would be helpful if you look at he SPI layer (maybe using logic-analyzer with SPI+INT pin) to be able to see what is happening on the chip and what is happening within your driver.
An NFC reader typically defines the pace there are typically no situations when it might be too late when only handling anticollision. Handling the FIFO water level (>96bytes) is of course timing critical.
Best Regards, Ulysses
2023-06-29 06:51 AM
IOError is taken from Rfal I think.
```
// If dont have end of receive and start of receive, throw io error
if !intr.contains(InterruptFlags::END_OF_RECEIVE)
|| !intr.contains(InterruptFlags::START_OF_RECEIVE)
{
return Err(Error::IOError);
}
```
It throwing errors is not the biggest concern, but that it fails to read tags until then. It works for a while and then reqa/wupa requests go through, but they never read tags in range. Not previous ones and not new ones.
I logged out interrupts, but I didn't see any difference between when it works and doesn't.
I have used a digital analyzer, but nothing out of the ordinary there. It seemed as if no tags were in the area.
2023-06-29 07:24 AM
Hi,
not having START_OF_RECEIVE may be ok but then you should get a NO_RESPONSE interrupt. Original RFAL will normally not return IO_ERROR.
If you have digital analyzer, then please record SPI+IRQ and share it!
Best Regards, Ulysses
2023-07-05 01:33 AM - edited 2023-07-05 01:35 AM
Attached ErrorCapture.hex (Real extension ErrorCapture.sal) Capture made using https://www.saleae.com/downloads/
https://drive.google.com/file/d/1HP3trKfch0tgLm-TP4rdvEN691bfpKf_/view?usp=sharing
Error happens before 50 ms gap
2023-07-05 02:20 AM
Hi,
two issues seen here:
Which code base was the basis for this Rust driver? Must be quite old as the single interrupt reading is not recommended for quite some years (even before ams->ST transfer).
Best Regards, Ulysses
2023-07-05 03:43 AM
Ohh never noticed that CS behavior. That explains a lot :) Will investigate and post an update of what happened here.
I thought reading multiple registers in one attempt is just optimization and reading multiple times would be fine. What kind of problems it can cause?
I used
https://github.com/nrfconnect/sdk-nrf/tree/f18f6929e239f01125d349dc8543c940b45b2001/lib/st25r3911b https://github.com/stm32duino/ST25R3911B
2023-07-05 04:24 AM
Hi,
both codes on github are using read multiple for interrupt status. If I recall correctly when using single reads it can happen that interrupts are lost (cleared without being present on MISO).
Regards, Ulysses