2021-12-23 09:01 AM
Hello all,
I am developing a small reader with ST25R3912 and I can't use the RFAL library because I want to control it in the final application MCU STM8L. I was inspired by this discussion (https://community.st.com/s/question/0D50X00009XkWIfSAN/register-settings-for-st25r3911b-for-iso-15693) and based on it I wrote a short test program that will try to read the UID from Tag (I only use tag 15693 - inside the ICODE SLIX chip). RF IC using 3.3V power supply and antenna is single sided (components recommended by STM25 Antenna Matching Tools)
My ST25R3912 initialization looks like:
WriteToSPI (0x00,0x8B); //IO configuration register 1 - address 0x00
// single side antenna, use RFO1, RFI1, 64 water level for recieve, 32 water level for transmit, 27.12 MHz Xtal, MCU CLK set 6.78MHz, no MCU CLK if Xtal not running
WriteToSPI (0x01,80); //IO configuration register 2 - address 0x01
//3.3V supply in range: 2.4 V to 3.6 V, Enable VSP_D regulator, MISO pull down disabled when SS low, MISO pull down disabled when SS high, Increase MISO driving disabled, slow ramp at Tx on disabled
WriteToSPI (0x02,0xC8); //Operation control register - address 0x02
// Enables oscilator and regulator (ready mode), Enables Rx operation, Both AM and PM channels enabled, Automatic channel selection, Enable Tx operation, Wake-up mode disable
WriteDirectCmdToSPI (DCMDAdjustRegulators); //direct command Adjust Regulators 0xD6
WriteToSPI (0x03,0x70); //Mode definition register - address 0x03
// target: initiator, 1110 means Sub-carrier stream mode, no automatic start response RF collision
WriteToSPI (0x04,0x22); //Bit rate definition register - address 0x04
// 0010 means Tx bit rate fc/32, 0010 means Rx bit rate fc/32
WriteToSPI (0x08,0x30); //Stream mode definition register - address 0x08
// 01 means subcarier frequency fc/32 (424kHz), 10 means sub carrier pulses 4, 000 means time period fc/128
WiteToSPI (0x09,0x10); //Auxillary definition register - address 0x09
// recieve without CRC, make CRC check, OOK, Enable external field detector, RFO driver tristate disable, BPSK more tolerant disable
WriteToSPI (0x24,0x2C); //AM modulation depth control register - address 0x24
//AM modulated level is defined by bits mod5 to mod0, 010110 means 14.7% (also tested with 01110000 30%)
WriteDirectCmdToSPI (DCMDAnalogPreset); // 0xCC
//direct command Analog preset based on Mode definition register and Bit rate definition register
WriteDirectCmdToSPI (DCMDCalModulationDepth); //direct command RFID calibrate modulation depth 0xD7
When I try read some register it looks that my configuration is inside cerrectly.
I'm not entirely sure which registries need to be configured and which don't. is this configuration correct for the 15693 chip and ICODE SLIX inside the label?
Solved! Go to Solution.
2022-01-03 03:08 AM
Hi Lukas,
please use MRT/NRT from our existing software. NRT needs to be extended when you are doing write(-alike) commands without option flag.
What you receive seems to be ok - you just need to remove SOF/EOF, then Manchester-decode it and check the CRC.
B7 : SOF (5 bits: 0x17) + 01->0 + carry over 1
AA : 01->0, 01->0, 01->0, 01->0 + carry over 1
AA : 01->0, 01->0, 01->0, 01->0 + carry over 1
AA : 01->0, 01->0, 01->0, 01->0 + carry over 1
CA: 01->0, 01->0, 01->0, 10->1 + carry over 1
4C: 01->0, 10->1, 01->0, 10->1 + carry over 0
35: 10->1, 10->1 10->1, ....
giving bits 0000 0000 0000 0000 1010 1111 = bytes 00 00 f5.... The two first zero bytes are flags and DSFID.
BR, Ulysses
2021-12-23 09:09 AM
After that I coded request
Flag = 0x26 One slot, AFI not set, Inventory command selected, High datarate
CMD = 0x01 Inventory request
My Inventory request looks like like SOF Flag CMD AFI Mask_length Mask_value CRC EOF
0x26 0x01 - 0x00 - 0xF6 0x0A
SOF = 0x21
EOF = 0x04
I coded it into format, f.e 0x26
0x26
into binary 00 10 01 10
change MSB to LSB 10 01 10 00
code to 1_4 0x20 0x08 0x20 0x02 where 00~0x02, 01~0x08, 10~0x20, 11~0x80
I got the complete message:
21.20.08.20.02.08.02.02.02.02.02.02.02.20.08.80.80.20.20.02.02.04
and I try to read Tag:
static uint8_t TXReadUID[22]={0x21, 0x20,0x08,0x20,0x02, 0x08,0x02,0x02,0x02, 0x02,0x02,0x02,0x02, 0x20,0x08,0x80,0x80, 0x20,0x20,0x02,0x02, 0x04};
uint8_t message_length = 22;
WriteDirectCMD (DCMDclearFIFO); // direct command clear FIFO
WriteToFIFO(TXReadUID, message_length); // write data to FIFO
//WriteDirectCMD (DCMDTransmitNoCRC); // direct command Transmit without CRC
WriteDirectCMD (DCMDTransmitWithCRC); // I have tried both
wait_ms(200);
ReadFromFIFO(23);
But when the tag is in range I got some random data
20.08.00.00.08.00.02.02.00.02.00.02.00.00.00.00.00.20.02.02.00
When tag is not in range I got data very similar like request
Do you have any idea, what I am doing wrong?
which registers give me more information about where the error is and whether the antenna is properly tuned and working?
Thank you very much for your help !!
2022-01-03 01:11 AM
Hi LBier.1,
most of what you have done looks plausible but you may miss some steps:
I only detailed what immediately caught my eye - there may be more...
In general I can only advise you to not open too many development areas at once: New board with your own new software but rather employ some Divide&Conquer:
Best Regards, Ulysses
2022-01-03 01:55 AM
Dear Ulysses,
thank you very much for your feedback.
I've made some progress since the last post.
I met point 2,3,4 of your post:
static uint8_t TXReadUID[22]={0x21,0x20,0x08,0x20,0x02,0x08,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x20,0x08,0x80,0x80,0x20,0x20,0x02,0x02,0x04};
uint8_t message_length = 22;
WriteToFIFO(TXReadUID, message_length); // write my command to FIFO
WriteSPIregister(0x1D,0x00);
WriteSPIregister(0x1E,0xB0); // sending 22 bytes
//WriteDirectCMD (DCMDTransmitNoCRC); // direct command Transmit without CRC
WriteDirectCMD (DCMDTransmitWithCRC);
and also I am checking the I_txe, I_rxs, I_rxe and I_nre
When I read the FIFO I have got these answers:
1. Tag is not in range
FIFO is empty (read it for checking only)
2. My Tag1 in range
I always get the answer: B7.AA.AA.AA.CA.4C.35.2D.35.AB.D2.AC.B4.CA.CC.AA.2B.B3.03
The answer is the same with direct command Transmit without CRC / Transmith with CRC
The original UID of this tag is E0.04.01.50.C5.82.E6.F5
3. My Tag2 in range
I always get the answer: B7.AA.AA.AA.4A.4B.4B.53.B3.CC.CC.D2.CA.AA.AA.2C.B4.B4.03
The answer is the same with direct command Transmit without CRC / Transmith with CRC
The original UID of this tag is E0.16.24.01.19.54.BB.33
The antenna seems to be tuned in (the first good news after a few long nights) and I'm detecting Tag and I'm reading something :)
However, the data received does not look like the expected response.
I think I still have some initialization error and I'm getting some RAW data that roughly matches the UID tag, but hasn't the correct format,right?
Or do I not know how to correctly interpret this data and convert it to a UID?
Regarding MRT and NRT I am not sure of right settings for 15693 :( (most things in the datasheet are about ISO14443)
Best regards Lukas
2022-01-03 03:08 AM
Hi Lukas,
please use MRT/NRT from our existing software. NRT needs to be extended when you are doing write(-alike) commands without option flag.
What you receive seems to be ok - you just need to remove SOF/EOF, then Manchester-decode it and check the CRC.
B7 : SOF (5 bits: 0x17) + 01->0 + carry over 1
AA : 01->0, 01->0, 01->0, 01->0 + carry over 1
AA : 01->0, 01->0, 01->0, 01->0 + carry over 1
AA : 01->0, 01->0, 01->0, 01->0 + carry over 1
CA: 01->0, 01->0, 01->0, 10->1 + carry over 1
4C: 01->0, 10->1, 01->0, 10->1 + carry over 0
35: 10->1, 10->1 10->1, ....
giving bits 0000 0000 0000 0000 1010 1111 = bytes 00 00 f5.... The two first zero bytes are flags and DSFID.
BR, Ulysses
2022-01-03 04:14 AM
Dear Ulysses,
thank you very much.
This is the best news in the new year :) I'm going to write a decoding function ...
I believe that this thread will help others who solve a similar problem and are not completely clear in encoding and decoding messages.
Best regards Lukas
2022-01-03 06:00 AM
Hi Lukas,
inside our RFAL you will find a function rfalIso15693VICCDecode() which just does that. Although no rocket-science to implement such function it still takes considerable effort to implement with all corner cases bein correct.
BR, Ulysses
2023-01-01 01:35 PM
Dear Ulysses,
First of all I would like to wish you good health and all the best for the New Year.
During Christmas time I decided to upgrade my project and start using memory in my tag as well. Up until now, I was only using the read UID, which we addressed in this thread some time ago. For the sake of completeness, I still use the ST25R3912 in combination with a small MCU from ST and ICODE SLIX tags (15693). I am able to read the UID without any problems using the Inventory command.
Unfortunately I am unable to read the contents of the memory. (I checked the data on SPI and it is fine, of course)
What I am proceeded:
After successfully reading and decoding the UID (with Inventory cmd), I proceed:
1. WriteDirectCMD (DCMDclearFIFO); - delete the FIFO (just to be sure, but the FIFO status of register 1A is 0 - FIFO is empty )
2. WriteSPIregister (0x02,0xC8); - in Operation control register 1 I re-enable tx_en after the previous transfer
3. write my prepared command Raed single block 0 to the FIFO
(The broken down coding of the commands I tried is in attached file)
4. save the length of message in FIFO to registers 0x1D and 0x1E
(if I read the register value I get a message length of 22 bytes - is OK)
5. writeDirectCMD (DCMDTransmitWithCRC); - command to transmit
6 wait 1 second
look in the registers:
[0x14] MainMaskInteruptReg =0
[0x15] NFCInteruptReg =0
[0x16] MaskErrorReg =0
[0x17] MainInteruptReg =8
[0x18] NFCIntReg =0
[0x19] ErrorReg =0
[0x1A] FIFOstatusReg1 =0
[0x1B] FIFOstatusReg2 =0
FIFO register is empty
If I try DCMDTransmitNoCRC the result is the same.
If I leave DCMDTransmitWithCRC and disable the direct command Clear FIFO at the beginning I get:
[0x14] MainMaskInteruptReg =0
[0x15] NFCInteruptReg =0
[0x16] MaskErrorReg =0
[0x17] MainInteruptReg =39
[0x18] NFCIntReg =0
[0x19] ErrorReg =80 which means CRC error
[0x1A] FIFOstatusReg1 =0
[0x1B] FIFOstatusReg2 =0
FIFO register is empty
I get a similar result when I try to use my cmd Read Multiple Block. What am I doing wrong? Is the mistake realy in CRC? I'm using crccalc.com to calculate the CRC because I'll be using a fixed immutable read length so I don't need to use the algorithm for the CRC, and I'll save MCU time. Or is some mistake in reinicialisation after first Invertory command?
Thank you very much for your advise.
2023-01-10 01:39 AM
Hi,
not sure why your Read command should not work the same way as your inventory command.
The I_crc gets triggered as 3912 wants to check the CRC which it cannot as it does not perform bit decoding. Please set no_crc_rx bit.
If suspect some old data in the interrupt registers in the first case as the ClearFIFO will also clear interrupts.
I think your flag byte 0x00 is incorrect. You always need to set for high data rate.
Again my advice: Use our working code at least as reference for the SPI sequences!
BR, Ulysses
2023-01-12 12:52 AM
Dear Ulysses,
thank you for your tips. I spent yesterday trying different settings. I edited the 0x02 registry configuration, where I disabled the no_crc_rx bit and focused on the Read Multiple block command (which I want to use), where I configured the flag byte.
My main program structure is:
InitST25R3912();
if (ReadTagID()) // try read UID by Inventory command
{
DecodeManchesterUID();
ShowTagUID(); //all is OK
WriteDirectCMD (DCMDclearFIFO);
WriteSPIregister (0x02,0xC8);
// registers checking Nr.1
if (ReadTagMem()) // try read memory by Read Multiple Block command
{ // not OK
DecodeTagMem();
And I check the registers at three times
Nr.1. Before attempting to read memory
[0x14] MainMaskInteruptReg =0
[0x15] NFCInteruptReg =0
[0x16] MaskErrorReg =0
[0x17] MainInteruptReg =0
[0x18] NFCIntReg =0
[0x19] ErrorReg =0
[0x1A] FIFOstatusReg1 =0
[0x1B] FIFOstatusReg2 =0
[0x30] AuxiliaryReg = 0x10 means Xtal oscillation is stable
Nr.2. after writing my Read Multiple Command to the FIFO, check the FIFO status
[0x1A] FIFOstatusReg1 =1A means 26 bytes request is in FIFO
[0x1B] FIFOstatusReg2 =0
Nr.3. 1 second after Direct Command - TransmitWithCRC
[0x14] MainMaskInteruptReg =0
[0x15] NFCInteruptReg =0
[0x16] MaskErrorReg =0
[0x17] MainInteruptReg = 0x08 means IRQ due to end of transmission
[0x18] NFCIntReg =0
[0x19] ErrorReg =0
[0x1A] FIFOstatusReg1 =0
[0x1B] FIFOstatusReg2 =0
[0x30] AuxiliaryReg = 0x18 means Xtal oscillation is stable, recieve coder enabled
FIFO is still empty - no answer.
What's bad is that I don't see any other error flag that could point me to what I'm doing wrong. As far as I understand, according to the register, TX completes successfully, but RX doesn't start at all. The causes could be:
(a) that my Read Multiple Block command is wrong
But I would expect the tag to at least respond with an error and see it in the registers or FIFO?
b) that ST25R3912 is not able to receive anything at all and so I don't see any flag in the Main interupt register (l_rxs and l_rxe). The question is why?
I tried to study the ST sources and went through the RFAL library. I didn't find anything where you need to re-initialize anything after the previous Inventory command (except register 0x02 where tx_en and rx_en are triggered), but I admit that there are some parts of the RFAL code that I'm not sure I understand 100% correctly.
In the attached file I send the actual initialization and composition of the Read Multiple Block command.
During today I want to try ReadMultiple Block with Address mode to see if anything changes, but I guess there will be no problem here.