Near Field Communication (NFC) with ST Micro CR95HF – Part 2


Near Field Communication (NFC) with ST Micro CR95HF.  A couple of weeks back I started working on a circuit board that holds ST Micro’s CR95HF NFC communication IC.  NFC stands for near field communication, and is basically an very short-range RF data link. Several communication protocol have been adopted for use with NFC hardware.

The CR95HF operates at 13.56MHz and handles a lot of the overhead required to use NFC communication.  For example, it generates all of the amplitude-shift keying (ASK) of the RF signal, cyclical-redundancy-checking (CRC) of transferred data, and also handles the timing etc. associated with the RF various communication protocols.

For my design effort I used ST Micro’s LRIS2K NFC card, ST Micro’s M24LR64 dual interface EEPROM, and Texas Instruments’ Tag-it products to interface to the CR95HF.  All of these use the ISO 15693 hardware and communication protocols.  To control the CR95HF I connected a USB-to-serial UART module between the CR95HF’s serial port, and my PC.  I then created some Visual Basic software to perform the communication.

The board design for the CR95HF is pretty straightforward.  About the only tricky part is the RF matching for the loop antenna.  Loop antenna attached to the CR95HF is used to power the smart cards and dual interface EEPROM by energizing those components via their antennae. You’re basically energizing one coil of a transformer (the antenna on the CR95HF) and its electric field couples with the smart cards antenna across the air gap, powering the other device.  The range of communication is related to the size of the antennae.  For my design I have about a 1” range.  ST Micro has a pretty good synopsis on antenna matching for the CR95HF in this app note, and I got it right the first time, so there’s not a lot to it.



There are two communication protocols that you need to become familiar with when implementing an ISO 15693 NFC design with the CR95HF.  The first is the protocol defined in the CR95HF datasheet.  In hindsight implementing both protocols is pretty easy as one wraps around the other.  But I did spend a lot of time looking at demo project source code trying to figure out some pretty basic stuff.

CR95HF Communication:   When interfacing to NFC cards/ICs through the CR95HF you are essentially just communicating with the CR95HF and wrapping messages to the NFC devices in the CR95HF’s protocol.  There are a few commands that speak directly to the CR95HF and one that passes information to the NFC cards/ICs.  This is not a complete list of commands, but covers a few important ones.

1)  Initializing the UART:  The CR95HF has both a UART (8N1 serial data) and an SPI (serial peripheral interface).  I implemented the UART interface since that’s easy to construct using Visual Basic.  The type of interface you use is determined by the state of two “select serial interface” i/o pins on power up.  The SSI_0 and SSI_1 should be grounded to enable the UART.  There are timing requirements associated with enabling the UART. Here are the requirements and the process I used.

a.  Power up
b. wait at least 10mS for the device to initialize.
c.  provide a low pulse of at least 10uS on the /IRQ_IN pin (this is also the UART_RX or data input pin)
d. wait at least 10mS for the serial interface to be ready for use
e. send your first command

The UART defaults to a speed of 57600BPS.  You can change this, but I never tried to do that.  The CR95HF implements an “echo” command.  If you send a 0x55 it will respond with the same byte.  To initialize the CR95HF I setup a loop that sends 0x55 up to 10 times and when it receives a 0x55 back I exit the loop and assume the UART is ready.  The code waits 50mS between attempts.  At 57600BPS a 0x55 low pulse is 17uS wide, and this method worked for me.

       'wake up CR95 
        For i = 1 To 10

            SerialTXBuffer(0) = &H55
            TXByteCount = 1
            SerialWait_10mS = 5

            If RXByteCount = 1 Then
                If SerialRXBuffer(0) = &H55 Then
                    Exit For
                End If
                Label_DeviceID.Text = "No Device ID"
                Label_ROMCRC.Text = "No ROM CRC"
                Label_CR95_Detected.Text = "No CR95 Detected"
                Exit Sub
            End If

FYI, the “SerialWait_10mS = 5” tells the SerialCommunication() function to wait 50mS for a complete response to the command.

2) Identify command:  This command returns information about the CR95HF IC, including the device ID, and the revision of ROM code.  While its not a command necessary for the operation of the chip, it’s a good place to start when developing an interface. You send 0x01, 0x00, and receive back a response code 0x00, followed by the length 0x0F (unless they exceed ROM revision code 9 in the future).  This is followed by a string of ASCII data and a CRC associated with the ROM.  You can skip implementing this command if you want.


Here’s how I implemented this command in VB.

        ' get CR95 Device ID
        SerialTXBuffer(0) = &H1
        SerialTXBuffer(1) = &H0
        TXByteCount = 2
        SerialWait_10mS = 5

        If ((RXByteCount = 17) And (SerialRXBuffer(1) = 15)) Then
            CR95_DeviceID = ""
            CR95_ROMCRC = ""

            For i = 2 To (SerialRXBuffer(1) + 1)
                If i < SerialRXBuffer(1) Then
                    CR95_DeviceID = CR95_DeviceID & Chr(SerialRXBuffer(i))
                    CR95_ROMCRC = CR95_ROMCRC & SerialRXBuffer(i).ToString("X2")
                End If

            Label_DeviceID.Text = "ID=" & CR95_DeviceID
            Label_ROMCRC.Text = "ROM CRC=" & CR95_ROMCRC
            Label_CR95_Detected.Text = "CR95 Detected"

            Label_DeviceID.Text = "No Device ID"
            Label_ROMCRC.Text = "No ROM CRC"
            Label_CR95_Detected.Text = "No CR95 Detected"

        End If


3.  Protocol Select:  Implementing the Protocol Select command turns on/off the RF field.  The RF field must be turned on prior communicating with NFC devices.  Additionally, this command has a slew of options associated with the ISO specification you plan to implement.  Since I as using ISO 15693 devices I’ve included those options as defined in the CR95HF datasheet in the image below.

As an example, if I wanted to turn on the RF field implementing ISO 15693 at 26KBPS, 312uS delay, 10% modulation, and the CRC automatically appended by the CR95HF I would send (commas shown for clarity, not sent)…

PC –> CR95HF:  0x02,0x02,0x01,0x05

0x02 (Protocol Select command), 0x02 (length of data to follow), 0x01 (ISO 15693 option), 0x05 (10% modulation and CRC bits set)

If accepted, the CR95HF would return…

CR95HF->PC:  0x00,0x00


To turn off the RF field it would look like this…

PC –> CR95HF: 0x02,0x02,0x00,0x00

CR95HF->PC: 0x00,0x00

4.  Send/Receive Command:  The command you’ll make the most us of is the Send/Receive command.  This is the bread and butter of the CR95HF NFC interface.  All commands to and from the cards/ICs implementing NFC are wrapped in this command.

PC –> CR95HF: 0x04,length of data following,ISO 15693 protocol you are sending

CR95HF->PC: 0x80,length of data following, ISO 16593 protocol response from NFC device


Let’s say you want to send and Inventory Command as defined by the from the ISO 15693-3 (BTW if you can’t find ISO 15693-3 online the ST Micro M24LR64 datasheet has a lot of the commands described, just beware that some of the information is device specific and not all commands described are present in all ISO 15693 devices).  The Inventory Command is shown in the image down below.

You’ll have to trust me on some of this so we don’t get lost in the weeds of the ISO 15693-3 protocol too early.

The CR95HF handles a lot of the overhead for the NFC communication.  So the SOF, CRC-16, and EOF are not something we need to worry about.  If you are sending the CRC-16 though you’ll enable that in the Protocol Select command previously described.

So we need to send the Request_flags, Optional AFI (if we want to), the Mask Length, and Mask Value.  The Inventory command is used to isolate specific cards/ICs in the NFC field.  In my design I’m assuming that there is only one device in the field, and so I’m using it to determine if there is a device present.

We’ll look at the request flags in a future post, but for now we can say we’re sending 0x26 which tells the NFC device we’re inventory mode, using the high data rate, and we have one-inventory slot.  We also clear the AFI flag letting the NFC device know that we are not including the optional AFI byte.  We’ll set the mask length to 1 and the Mask Value to 0.

Hence (love that word), our Inventory Command looks like 0x26 (request flags), 0x01 (mask length), 0x00(mask value).  When wrapped in the CR95HF Send Receive comand this looks like…

PC->CR95HF: 0x04,0x03,0x26,0x01,0x00

Red is data for the CR95HF, and blue is for the NFC device.  All ISO 15693-3 commands are sent this way. The response is similar.

CR95HF->PC:  0x80, length of response, ISO 15693 response to command


5.  Other CR95HF commands:  The command set to the CR95HF is pretty small.  However, there are some other commands that can be used to change the RF field settings such as the receive gain and modulation.  These are described in the datasheet.  There is also a calibration technique that I used.  I haven’t seen much of difference in range from calibration or adjusting the RF settings.  But have a go at them if you want.

Next time…  I mostly covered the CR95HF commands in this blog.  Next time I’ll look a little closer at the ISO 15693-3 commands you embed into the CR95HF Send/Receive command to read and write data to the NFC enabled devices.


  1. Duncan Hill says:

    Hi there, I have been looking all over for someone who is to control one of these CR95HF boards using, and you’re the closest I have found! I have written some code based on the example source code on the ST website, and it works, but only partially, and I am wondering if you know where I am going wrong:

    Public Declare Function CR95HFDLL_USBconnect Lib “CR95HF.dll” () As Long

    Public Declare Function CR95HFDll_Select Lib “CR95HF.dll” (ByVal mycmdstring As String, ByVal mystring As String) As Long

    and then in a button I have:

    Dim lngStatus As Long = 5
    Dim strAnswer As String

    lngStatus = CR95HFDLL_USBconnect()

    If (lngStatus = 0) Then
    MsgBox(“DEMO-CR95HF-A connected and ready to be used”)
    MsgBox(“Warning : DEMO-CR95HF-A not connected”)
    End If

    lngStatus = CR95HFDll_Select(“010D”, strAnswer)

    If (lngStatus = 0) Then
    MsgBox(“Select protocol ISO15693 not executed”)
    End If

    it flashes up with “”DEMO-CR95HF-A connected and ready to be used”” ok, but I can’t get it to set the protocol. I have a feeling it is linked to the string, as does not allow ‘As String*256″

    any help would be massively appreciated!

    • Good morning Duncan,

      Have you verified that “010D” converts to a valid ISO/IEC 15693 protocol value? I’ve looked through the demo code at one point a couple of months ago. In our design we were testing the CR95HF with the serial protocol so I used a USB to serial converter.

      I believe the ST demo communicated to an on-board micro that converts USB to SPI for transmission to the CR95HF. I can’t provide much help decoding the protocol they put together. However you might take a look at the datasheet for our PN: BM019 which has some sample of the CR95HF protocol select communication. Also, if you use our BM010 (USB to serial converter) we have some sample VB code that works using a serial interface.


      • Duncan Hill says:

        Hi Lon, thanks for the reply and sorry I did not get back sooner. I solved the problem in the end; it was down to the dll being a 32 bit dll, but the compiler was 64 bit. This meant that “long” byte lengths were different, and so that was confusing things. also there were a few changes between earlier versions of vb and

  2. Hello Lon,
    I’m trying to make my CR95HF module to talk with me, but I have some issues.
    I have a RFid Click module from MikroElektronika with CR95HF chip on it, and I’m also trying to communicate with my module over UART using VB6 application, but I can’t wakeup the chip!
    Using your tactics with Echo command and repeat sending to USB-to-serial (FT232), but no answer from the chip.

    Can You please send me your App source-code (or just a part for communicating with chip) to my email?

    Thanks in advance!

  3. Nuno Miguel says:

    Dear Friend,

    First off all thanks for this great information. I am develop a NFC system and your unformation help me begin with more light.

    Thanks again.

  4. Hello, your blog was helpful but I am expecting little more. I want to know how NDEF message is send from PC to CR95HF board . I studied the demo code given in .In CR95HF.h header file below given commands are available
    CR95HFDll_GetDLLrev .
    CR95HFDLL_USBhandlecheck .
    CR95HFDll_Idn . .
    CR95HFDll_SendIRQPulse . .
    CR95HFDll_SendNSSPulse . . . .
    CR95HFDll_SendReceive . .
    but there is no any command to write NDEFmessage. How can I write it with the help of above commands only. Can you please help me ?
    Also I am using M24LR04E receiver board

    • ST Micro’s CR95HF datasheet shows NDEF formatting examples around pages 63-66. They do this using the 14443-A tags (NFC Forum Tag Type 4A). It looks to me like the NDEF format is encapsulated in the CR95HFDLL_SENDRECV. Their Windows application has tabs specific to the NDEF format. You should look at their source code to find out how they parse the format and incorporate it into the communication requirements for the CR95HF.


  5. Bui Hoang Thinh says:

    This is so good. If can, Pls send me schematic PCB anten RFID. I want DIY board but can see anten PCB and can open file source PCB. Pls thanks.


  1. […] Part 1 – my first attempts to interface with the CR95HF and use NFC Part 2 –an overview of the communication protocol used with the CR95HF chip […]

Speak Your Mind


This site uses Akismet to reduce spam. Learn how your comment data is processed.