Skip to main content
Visitor II
July 12, 2019
Solved

SPI communication with CR95HF on ESP8266

  • July 12, 2019
  • 6 replies
  • 2403 views

I create a new thread related to this with more detailed information. First of all thanks for the response, I had seen the datasheet of BM019 not the one of CR95HF which is quite more complete. Second the logic analyzer I use is Pulseview it allows me to export the capture data, I attach 2 session data, one for Arduino and the same schedule in esp8266.

My main code is quite similar to the official code of the BM019 sensor for Arduino, I do many other things for processing data but read with the sensor is basically the same. I'm going to focus on the 3 step necessaries to read the tag.

First of all is necessary send a setProtocol command in order to get the NFC ready, this works fine on both boards.

The command I send (but I test with many other commands) is the inventory command, if NFC is in range they read the data. According to the official documentation, sending a command requires 3 steps. First step is sending via SPI a predefined bytes that represents the command in the case of inventory they are the following.

 digitalWrite(SSPin, LOW);
 
 SPI.transfer(0x00); // SPI control byte to send command to CR95HF
 SPI.transfer(0x04); // Send Receive CR95HF command
 SPI.transfer(0x03); // length of data that follows is 0
 SPI.transfer(0x26); // request Flags byte
 SPI.transfer(0x01); // Inventory Command for ISO/IEC 15693
 SPI.transfer(0x00); // mask length for inventory command
 
 digitalWrite(SSPin, HIGH);

This part works well on both Arduino and ESP8266. Then is needed a loop polling for data ready, basically is send a 0x03 until MISO 4th bit is set.

 digitalWrite(SSPin, LOW);
 while(RXBuffer[0] != 8)
 {
 RXBuffer[0] = SPI.transfer(0x03); // Write 3 until
 RXBuffer[0] = RXBuffer[0] & 0x08; // bit 3 is set
 }
 digitalWrite(SSPin, HIGH);

And the last step is get the response code sending a 0x02, 0x00 and 0x00.

 digitalWrite(SSPin, LOW);
 SPI.transfer(0x02); // SPI control byte for read 
 RXBuffer[0] = SPI.transfer(0); // response code
 RXBuffer[1] = SPI.transfer(0); // length of data
 digitalWrite(SSPin, HIGH);

In the case of setCommand the response code must be 0 for the inventoy command a good response is 128, in the code I also made Serial.print(RXBuffer[0], HEX); to print the response code.

Now the difference I see in then behaviour of both boards, the difference in the code is only the SSPin and the rest of pin for the SPI protocol that obviously are not the same in Arduino and ESP8266. What I see in the logic analyzer is for arduino in the step 2 makes a bunch of iterations sending 3 until gets an 0x0E and breaks the loop. In the esp8266 only one iteration and gets 0x0E. After that, the step 3 for and inventory command when the sensor is not in range the response code is x87, here is when the things are getting weird.

I can see and x87 as response in the logic analyzer in both boards but when I do the Serial.print(RXBuffer[0], HEX); I see and 0x0E on the esp8266, compare 0x87 with 0x0E in binary are 00001110 and 10000111, it is possible that there are an offset of 1 bit, maybe related with the flank detection of the clock that makes happen this? These maybe explains why only one iteration is made in the polling loop and the setCommands works because the response code is 0.

The frecuency is the same for arduino and esp8266, on Arduino the default speed is 16Mhz and I use SPI_CLOCK_DIV32 so the frecuency is 500Khz and on esp8266 I directly set it with SPI.setFrecuency() (also checked on the logic analyzer)

I can see that on Arduino MISO and MOSI are High by default, unlike the esp8266 but I think that I mustn't bother about these outputs when the SS is High

NOTE: in the logic analyzer inputs are the following

D4: CLK

D5: MISO

D6: MOSI

D7: CS - active low

Thanks in advice

    This topic has been closed for replies.
    Best answer by IFroi

    I reply myself because after a lot of struggle it finally works, I set the frequency to 1,9Mhz a bit less than the maximum supported by the sensor and replies now are corrects. The reason that at the same frequency works on Arduino but no on ESP8266 it could be that the clock for ESP8266 is less accurate than the Arduino and maybe the sensor only response correctly with certain multiples of the frequency. I don't know exactly if this is correct and the documentation for the SPI bus on the ESP8266 is poorly as well.

    6 replies

    IFroiAuthorAnswer
    Visitor II
    July 12, 2019

    I reply myself because after a lot of struggle it finally works, I set the frequency to 1,9Mhz a bit less than the maximum supported by the sensor and replies now are corrects. The reason that at the same frequency works on Arduino but no on ESP8266 it could be that the clock for ESP8266 is less accurate than the Arduino and maybe the sensor only response correctly with certain multiples of the frequency. I don't know exactly if this is correct and the documentation for the SPI bus on the ESP8266 is poorly as well.

    Technical Moderator
    July 12, 2019

    So far so good. I believe some timings may be not aligned with CR95HF SPI timings at lower frequency.

    i'll will try to dig more thanks to your traces.

    Rgds

    BT

    Technical Moderator
    July 17, 2019

    Hi,

    I had a look to the 2 traces.

    Would it be possible to do some more traces and some more tests with SPI frequency set to 500 kHz?

    1. probe IRQ_IN and IRQ_OUT signals in addition to SPI CLK/SS/MISO/MOSI. IRQ_OUT will give indication about real availability of data to be read from CR95HF buffer. I suspect the 0x0E poll answer to be be wrong
    2. provide trace including the startup sequence and possibly an echo command (echo is 0x55 which is convenient to see 1->0 and 0->1 bit transitions)
    3. replace the SPI software polling mechanism (0x03) by polling the IRQ_OUT. By the way, I would suggest to prefer IRQ_OUT polling rather than the SPI 0x03 polling. In low power consumption mode the device does not support SPI poll mechanism. Application has to rely on IRQ_OUT before reading the answer to the Idle command (see ST25R95 datasheet §5.9)

    Thanks in advance

    Rgds

    BT

    EDIT:

    IRQ_OUT is DOUT on BM019 (Pin1). I would suggest to connect it on a GPIO in input mode.

    Visitor II
    January 22, 2020

    hi, I have downloaded the above code files esp8266 and ardunio,but the files were with .sr extension Iam not able to use that same code can you upload the code in rar format ,or can you tell how to use above sample codes

    Technical Moderator
    January 23, 2020

    Hi,

    these files don't contain any source code - they are logic analyzer traces from Pulseview (Sigrok session files).

    Regards, Ulysses

    Visitor II
    January 25, 2020

    Hi.

    Not an answer but rather a question. I've been playing around for the last couple of days with CR95HF (I'm using RFID Click board from Mikroe - https://www.mikroe.com/rfid-click - and STM32F4 Dicovery board); (SPI) POLLING mode works very well and reliable but I cannot make the INTERRUPT MODE working no matter how I try.

    I tried to poll the IRQ_OUT and also to connect it on a GPIO in input mode (as you suggested) but the IRQ_OUT does not go low when I 'insert' the card...

    Do I have to set something else ? Is there something I overlooked (eg how the module gets initialized)?

    The documentation does not tell much about the INTERRUPT mode and I could not find any example code.

    Thank you in advance!

    Regards,

    Radu G.

    Technical Moderator
    January 27, 2020

    Hi Radu,

    better to create a new ticket if you see here issues. The only thing they have in common with the original posting is the reader chip. Some ideas/hints:

    • check the solder bridges on your rfid-click - especially INT_O/TX
    • remove INT_O/TX solder bridge and check with a wire resistor if you can stimulate INT_O and observe in MCU, observe UTX
    • as reference: X-CUBE-NFC3 uses IRQ_OUT
    • the ST25R95 DS is maybe a bit more clear than the CR95HF DS in this regard

    Regards, Ulysses

    Visitor II
    January 27, 2020

    Hi Ulysses,

    Thank you for your time & suggestions!

    | The only thing they have in common with the original posting is the reader chip.

    I actually read point 3) of your colleague's (Brian) answer and decided to comment on it.

    The solder bridges seem to be OK. I also placed the click board on a different mikrobus socket (in case the INT_OUT pin was already in use by the discovery board).

    Regards,

    Radu G.