HydraFW HydraNFC v1.x TRF7970A Tutorial - hydrabus/hydrafw GitHub Wiki

All the following commands shall be executed with firmware HydraFW_v0.5 or more with an HydraBus and an HydraNFC(which include TRF7970A chipset) plugged on top of HydraBus and using a terminal (on Virtual Serial COM port) like putty.

If you want to easily Read UID for Mifare/Vicinity NFC tags see https://github.com/bvernoux/hydrafw/wiki/HydraFW-HYDRANFC-guide as this tutorial is mainly to understand lowlevel/commands of TRF7970A using spi.

Python NFC reader (pyNFCReader) for HydraBus+HydraNFC

pyNFCReader: A little python client to use as a low level contactless smart card reader the HydraBus+HydraNFC

Initialize GPIO & SPI to communicate with TRF7970A

This step is mandatory to communicate with TRF7970A and later read Tag.

See also Python script (requires firmware v0.7-beta-20 or more) example bbio_hydranfc_init.py for HydraNFC init using Console mode + switch to bbIO mode for SPI2 Init & communication with TRF7970A (HydraNFC shield)

Configure NFC/TRF7970A in SPI mode with Chip Select

  • TRF7970A IO0 / HydraBus PA3 (To set to "0" for SPI)
  • TRF7970A IO1 / HydraBus PA2 (To set to "1" for SPI)
  • TRF7970A IO0 / HydraBus PC0 (To set to "1" for SPI)
  • TRF7970A NSS / HydraBus PC1 (To set to "1" for SPI)
  • TRF7970A EN / HydraBus PB11
    • Set to "0" wait 2ms or more then set to "1"(To set to "0" for SPI)
  • Read all GPIO states
gpio pa3 mode out off
gpio pa2 mode out on
gpio pc0 mode out on
gpio pc1 mode out on
gpio pb11 mode out off

gpio pb11 mode out on
gpio pa2-3 pc0-1 pb11 r

If all GPIOs are set correctly, last command result shall be:

PA2     1
PA3     0
PB11    1
PC0     1
PC1     1

Configure HydraBus SPI2 to communicate with TRF7970A

spi device 2 frequency 1.31m polarity 0 phase 1
  • Trf797xInitialSettings (check TRF7970A is alive)
[ 0x83 0x83 ] % [ 0x80 0x80 ] %
[ 0x49 r ]

Last command([ 0x49 r ]) shall return

/CS ENABLED
WRITE: 0x49
READ: 0x91
/CS DISABLED

Initialize & read ISO15693/Vicinity Tag

First move an ISO15693/Vicinity Tag on the TRF7970A Antenna then do following steps.

Initialize the chipset in ISO15693

  1. Reset & Wait 1ms [ 0x83 ] %
  2. Write & Read Modulator and SYS_CLK Control Register (0x09) (13.56Mhz SYS_CLK and default Clock 13.56Mhz)) [ 0x09 0x31 ] [ 0x49 r ]
  3. Configure Mode ISO Control Register (0x01) to 0x02 (ISO15693 high bit rate, one subcarrier, 1 out of 4) [ 0x01 0x02 ]
  4. Turn RF ON (Chip Status Control Register (0x00)) [ 0x40 r ] [ 0x00 0x20 ] [ 0x40 r ]

Read UID of ISO15693 Tag

  1. Tx Inventory(0x26 0x01 0x00) [ 0x8F 0x91 0x3D 0x00 0x30 0x26 0x01 0x00 ]
  2. Wait 3ms after send inventory %:3
  3. Read/Clear IRQ Status(0x0C=>0x6C)+dummy read [ 0x6C r:2 ]
  4. Wait 10ms to receive all data %:10
  5. Read FIFO Status Register(0x1C/0x5C) [ 0x5C r ]
  6. Read UID (Read Continuous FIFO from 0x1F to 0x1F+0x0A(0x1F/0x7F)) [ 0x7F r:10 ]
  • UID is only 8 bytes (2 bytes at start are 0x00 0x00) and shall be read from right to left
  1. Read/Clear IRQ Status(0x0C=>0x6C)+dummy read [ 0x6C r:2 ]
  2. Read FIFO Status Register(0x1C/0x5C) [ 0x5C r ]
  3. Reset FIFO(0x0F/0x8F) [ 0x8F ]
  4. Read RSSI levels and oscillator status(0x0F/0x4F) [ 0x4F r ]

All commands:

Initialize chipset in ISO15693

[ 0x83 ] % [ 0x09 0x31 ] [ 0x49 r ]
[ 0x01 0x02 ] [ 0x40 r ] [ 0x00 0x20 ] [ 0x40 r ]

Read UID of ISO15693 Tag

[ 0x8F 0x91 0x3D 0x00 0x30 0x26 0x01 0x00 ] %:3 [ 0x6C r:2 0x6C r:2 ] %:10 [ 0x5C r ] [ 0x7F r:10 ] %:10
[ 0x6C r:2 ] [ 0x5C r ] [ 0x8F ] [ 0x4F r ]

If you want to read the Tag UID multiple times you can repeat only the step "Read UID of ISO15693 Tag".

For more details on ISO15693 (especially Inventory, Read/Write block ...) see ISO/IEC FCD 15693-3

Example output Init + Read UID of ISO15693 Tag:

spi2> [ 0x83 ] % [ 0x09 0x31 ] [ 0x49 r ]
/CS ENABLED
WRITE: 0x83
/CS DISABLED
/CS ENABLED
WRITE: 0x09 0x31
/CS DISABLED
/CS ENABLED
WRITE: 0x49
READ: 0x31
/CS DISABLED
spi2> [ 0x01 0x02 ] [ 0x40 r ] [ 0x00 0x20 ] [ 0x40 r ]
/CS ENABLED
WRITE: 0x01 0x02
/CS DISABLED
/CS ENABLED
WRITE: 0x40
READ: 0x01
/CS DISABLED
/CS ENABLED
WRITE: 0x00 0x20
/CS DISABLED
/CS ENABLED
WRITE: 0x40
READ: 0x20
/CS DISABLED
spi2>

spi2> [ 0x8F 0x91 0x3D 0x00 0x30 0x26 0x01 0x00 ] %:3 [ 0x6C r:2 0x6C r:2 ] %:10 [ 0x5C r ] [ 0x7F r:10 ] %:10
/CS ENABLED
WRITE: 0x8F 0x91 0x3D 0x00 0x30 0x26 0x01 0x00
/CS DISABLED
/CS ENABLED
WRITE: 0x6C
READ: 0xC0 0x3E
WRITE: 0x6C
READ: 0x5D 0x00
/CS DISABLED
/CS ENABLED
WRITE: 0x5C
READ: 0x0A
/CS DISABLED
/CS ENABLED
WRITE: 0x7F
READ: 0x00 0x00 0x6A 0x15 0x3A 0x18 0x00 0x00 0x07 0xE0
/CS DISABLED
spi2> [ 0x6C r:2 ] [ 0x5C r ] [ 0x8F ] [ 0x4F r ]
/CS ENABLED
WRITE: 0x6C
READ: 0x40 0x3E
/CS DISABLED
/CS ENABLED
WRITE: 0x5C
READ: 0x00
/CS DISABLED
/CS ENABLED
WRITE: 0x8F
/CS DISABLED
/CS ENABLED
WRITE: 0x4F
READ: 0x7E
/CS DISABLED

Initialize & read ISO14443A/Mifare Tag

First move an ISO14443A / Mifare One Tag on the TRF7970A Antenna then do following steps.

Initialize the chipset in ISO14443A (Mifare One)

  1. Reset & Wait 1ms [0x83] %
  2. Write & Read Modulator and SYS_CLK Control Register(0x09) (13.56Mhz SYS_CLK and default Clock 13.56Mhz)) [0x09 0x31] [0x49 r]
  3. Configure & Read Mode ISO Control Register (0x01) to 0x88 (ISO14443A RX bit rate, 106 kbps) and no RX CRC (CRC is not present in the response)) [0x01 0x88] [0x41 r]
  4. Turn RF ON and Read It [0x00 0x20] [0x40 r]

Read UID (REQA & WUPA command (Anticollision))

  1. Disable CRC Calc [0x01 0x88]
  2. Tx Raw REQA(0x26) [ 0x8F 0x90 0x3D 0x00 0x0F 0x26 ]
  3. Wait 10ms to receive all data %:10
  4. Read/Clear IRQ Status(0x0C=>0x6C) + dummy read [ 0x6C r:2 ]
  5. Read FIFO Status Register(0x1C/0x5C) [0x5C r]
  6. Read ATQA (Read Continuous FIFO from 0x1F to 0x1F+1(0x1F/0x7F)) [ 0x7F r:2 ]
  7. Reset FIFO(0x0F/0x8F) [ 0x8F ]
  8. Read RSSI levels and oscillator status(0x0F/0x4F) [ 0x4F r ]
  9. Tx Raw AntiColl(0x93 0x20) [ 0x8F 0x90 0x3D 0x00 0x20 0x93 0x20 ]
  10. Wait 5ms %:5
  11. Read/Clear IRQ Status(0x0C=>0x6C)+dummy read [ 0x6C r:2 ]
  12. Read FIFO Status Register(0x1C/0x5C) [ 0x5C r ]
  13. Read UID (Read Continuous FIFO from 0x1F to 0x1F+0x05(0x1F/0x7F) [ 0x7F r:5 ]
  • UID is only 4 bytes and last byte is BCC
  1. Read/Clear IRQ Status(0x0C=>0x6C)+dummy read [ 0x6C r:2 ]
  2. Reset FIFO(0x0F/0x8F) [ 0x8F ]
  3. Read RSSI levels and oscillator status(0x0F/0x4F) [ 0x4F r ]

All commands:

Initialize the chipset in ISO14443A (Mifare One)

[ 0x83 ] % [ 0x09 0x31 ] [ 0x49 r ]

Read UID (REQA & WUPA command (Anticollision))

[ 0x01 0x88 ] [ 0x41 r ] [ 0x00 0x20 ] [ 0x40 r ]
[ 0x01 0x88 ] [ 0x8F 0x90 0x3D 0x00 0x0F 0x26 ] %:10 [ 0x6C r:2 ] [ 0x5C r ] [ 0x7F r:2 ]
[ 0x8F ] [ 0x4F r ] [ 0x8F 0x90 0x3D 0x00 0x20 0x93 0x20 ] %:5 [ 0x6C r:2 ]
[ 0x5C r ] [ 0x7F r:5 ] [ 0x6C r:2 ] [ 0x8F ] [ 0x4F r ]

If you want to read the Tag UID multiple times you shall repeat "All commands" because the Anticollision is not fully terminated in this example.

For more details on ISO14443 (especially Initialization and anticollision) see ISO/IEC FCD 14443-3

Example output Init + Read UID of Mifare One Tag:

spi2> [ 0x83 ] % [ 0x09 0x31 ] [ 0x49 r ]
/CS ENABLED
WRITE: 0x83
/CS DISABLED
/CS ENABLED
WRITE: 0x09 0x31
/CS DISABLED
/CS ENABLED
WRITE: 0x49
READ: 0x31
/CS DISABLED

spi2> [ 0x01 0x88 ] [ 0x41 r ] [ 0x00 0x20 ] [ 0x40 r ]
/CS ENABLED
WRITE: 0x01 0x88
/CS DISABLED
/CS ENABLED
WRITE: 0x41
READ: 0x88
/CS DISABLED
/CS ENABLED
WRITE: 0x00 0x20
/CS DISABLED
/CS ENABLED
WRITE: 0x40
READ: 0x20
/CS DISABLED
spi2> [ 0x01 0x88 ] [ 0x8F 0x90 0x3D 0x00 0x0F 0x26 ] %:10 [ 0x6C r:2 ] [ 0x5C r ] [ 0x7F r:2 ]
/CS ENABLED
WRITE: 0x01 0x88
/CS DISABLED
/CS ENABLED
WRITE: 0x8F 0x90 0x3D 0x00 0x0F 0x26
/CS DISABLED
/CS ENABLED
WRITE: 0x6C
READ: 0xC0 0x3E
/CS DISABLED
/CS ENABLED
WRITE: 0x5C
READ: 0x02
/CS DISABLED
/CS ENABLED
WRITE: 0x7F
READ: 0x04 0x00
/CS DISABLED
spi2> [ 0x8F ] [ 0x4F r ] [ 0x8F 0x90 0x3D 0x00 0x20 0x93 0x20 ] %:5 [ 0x6C r:2 ]
/CS ENABLED
WRITE: 0x8F
/CS DISABLED
/CS ENABLED
WRITE: 0x4F
READ: 0x7F
/CS DISABLED
/CS ENABLED
WRITE: 0x8F 0x90 0x3D 0x00 0x20 0x93 0x20
/CS DISABLED
/CS ENABLED
WRITE: 0x6C
READ: 0xC0 0x3E
/CS DISABLED
spi2> [ 0x5C r ] [ 0x7F r:5 ] [ 0x6C r:2 ] [ 0x8F ] [ 0x4F r ]
/CS ENABLED
WRITE: 0x5C
READ: 0x05
/CS DISABLED
/CS ENABLED
WRITE: 0x7F
READ: 0xCD 0x81 0x5F 0x76 0x65
/CS DISABLED
/CS ENABLED
WRITE: 0x6C
READ: 0x00 0x3E
/CS DISABLED
/CS ENABLED
WRITE: 0x8F
/CS DISABLED
/CS ENABLED
WRITE: 0x4F
READ: 0x7F
/CS DISABLED
  • UID: In this example line READ: 0xCD 0x81 0x5F 0x76 0x65 corresponds to NFC Tag ID (4Bytes)+BCC
  • BCC is calculated as exclusive-or over the 4 previous bytes.
  • In this example line READ: 0xCD 0x81 0x5F 0x76 0x65
  • 0xCD xor 0x81 xor 0x5F xor 0x76 = 0x65 (BCC) so UID is correct
  • The last data line READ: 0x7F correspond to RSSI levels.

TRF7970A commands (SLOS743L – August 2011 – revised March 2017)

See TRF7970A "Table 6-20 Address and Command Word Bit Distribution" for more details.

Bit Description Bit Function Address Command
B7 Command control bit 0=address 1=command 0 1
B6 Read/Write 0=write 1=read R/W 0
B5 Continuous address mode 1=Continuous mode R/W 0
B4 Address/Command bit 4 Adr 4 Cmd 4
B3 Address/Command bit 3 Adr 3 Cmd 3
B2 Address/Command bit 2 Adr 2 Cmd 2
B1 Address/Command bit 1 Adr 1 Cmd 1
B0 Address/Command bit 0 Adr 0 Cmd 0

Communication is initialized by a start condition, which is expected to be followed by an Address/Command word (Adr/Cmd). The Adr/Cmd word is 8 bits long

The MSB (bit 7) determines if the word is to be used as a command or as an address. The last two columns of Table 6-11 show the function of the separate bits if either address or command is written. Data is expected once the address word is sent. In continuous-address mode (Cont. mode = 1), the first data that follows the address is written (or read) to (from) the given address. For each additional data, the address is incremented by one. Continuous mode can be used to write to a block of control registers in a single stream without changing the address; for example, setup of the predefined standard control registers from the MCU non-volatile memory to the reader. In non-continuous address mode (simple addressed mode), only one data word is expected after the address. Address Mode is used to write or read the configuration registers or the FIFO. When writing more than 12 bytes to the FIFO, the Continuous Address Mode should be set to 1. The Command Mode is used to enter a command resulting in reader action (for example, initialize transmission, enable reader, and turn reader on or off).

Example commands:

Direct Command description

  • SpiDirectCommand:
  • 1stByte = ((0x80 | CommandCode)) & 0x9f
  • Software Initialization (0x03): 1stByte = 0x83 [ 0x83 ]
  • Reset 0x09 (Reset FIFO): [ 0x89 ]

Register description

Read/Write Test register 0x1A/0x1B

  • SpiReadSingle (Read Register Addr):

    • RegisterAddr=0x1A (TestRegister R/W)
    • 1stByte = AddressCommand (0x40|RegisterAddr) | (0x5F&RegisterAddr) = 0x5A
  • SpiWriteSingle (Write Register Addr):

  • RegisterAddr=0x1A (TestRegister R/W)

  • 1stByte = AddressCommand (0x1F&RegisterAddr) = 0x1A

  • Read Test Register 0x1A: [ 0x5A r ]

  • Write Test Register 0x1A with value 0x12:

    • 1stByte = AddressCommand (0x40|RegisterAddr) | (0x5F&RegisterAddr) = 0x5A
    • [ 0x1A 0x12 ]
  • Read Test Register 0x1B: [ 0x5B r ]

  • Write Test Register 0x1B with value 0x13:

    • 1stByte = AddressCommand (0x40|RegisterAddr) | (0x5F&RegisterAddr) = 0x5A
    • [ 0x1B 0x13 ]

Read/Write Chip Status Control register (0x00)

  • Read Chip Status Control Register (0x00)(Default Value 0x01): [ 0x40 r ]
  • Turn RF ON (Chip Status Control Register (0x00)) [ 0x00 0x20 ]
  • Turn RF OFF (Chip Status Control Register (0x00)) [ 0x00 0x00 ]

Read/Write ISO Control register (0x01)

  • Read ISO Control register (0x01)(Default Value 0x02): [ 0x41 r ]
  • Write ISO Control register (0x01) to 0x02
    • ISO15693 high bit rate, one subcarrier, 1 out of 4: [ 0x01 0x02 ]
  • Write ISO Control register (0x01) to 0x88
    • ISO14443A RX bit rate, 106 kbps and no RX CRC: [0x01 0x88]

Read/Write Modulator and SYS_CLK control register (0x09)

  • Read Modulator and SYS_CLK Control Register (0x09): [ 0x49 r ]
  • Write Modulator and SYS_CLK Control Register (0x09) (13.56Mhz SYS_CLK and default Clock 13.56Mhz)): [ 0x09 0x31 ]

Read/Write Regulator and I/O control register (0x0B)

  • Read Regulator and I/O Control Register (0x0B): [ 0x4B r ]
  • Write Regulator and I/O Control Register (0x0B): [ 0x0B 0x00 ]

Read FIFO I/O register (0x1C)

  • Read FIFO Status register (0x1C): [ 0x5C r ]

Continuous Read register

  • Continuous Read and Clear IRQ Status (0x0C) (required a dummy read) [ 0x6C r:2 ]
  • Continuous Read from Addr 0x00 to addr 0x05: [ 0x60 r:6 ]
  • Continuous Read from Fifo Addr 0x1F: [ 0x7F r:9 ]

Read RSSI levels and oscillator status register (0x0F)

  • Read RSSI levels and oscillator status (0x0F): [ 0x4F r ]

Send Data (multiple command):

ISO15693 Tag

  • Transmit Inventory(0x26 0x01 0x00)
  • [ 0x8F 0x91 0x3D 0x00 0x30 0x26 0x01 0x00 ]
  • 0x8F = Reset FIFO
  • 0x91 = RX CRC (CRC is present in the response)
  • 0x3D = Write Continuous (Start at 0x1D => TX Length Byte1 & Byte2)
  • 0x00 0x30 = Number of Bytes to be sent (0x30 = 3bytes)
  • 0x26 = Request Flags (FIFO TX 1st Data @0x1F)
  • 0x01 = Inventory Command (FIFO TX 2nd Data @0x20)
  • 0x00 = Mask (FIFO TX 3rd Data @0x21)

ISO14443A/Mifare Tag

  • Transmit Raw REQA(0x26)

  • [ 0x8F 0x90 0x3D 0x00 0x0F 0x26 ]

  • 0x8F = Reset FIFO

  • 0x90 = no RX CRC (CRC is not present in the response)

  • 0x3D = Write Continuous (Start at 0x1D => TX Length Byte1 & Byte2)

  • 0x00 0x0F = Number of Byte to be sent (0x0F = Broken byte number of bits => 7bits)

  • 0x26 = REQA 7bits (FIFO TX 1st Data @0x1F)

  • Transmit Raw AntiColl(0x93 0x20)

  • [ 0x8F 0x90 0x3D 0x00 0x20 0x93 0x20 ]

  • 0x8F = Reset FIFO

  • 0x90 = no RX CRC (CRC is not present in the response)

  • 0x3D = Write Continuous (Start at 0x1D => TX Length Byte1 & Byte2)

  • 0x00 0x20 = Number of Bytes to be sent (0x20 = 2bytes @0x1D & 0x1E)

  • 0x93 0x20 = AntiColl (FIFO TX 1st & 2nd Data @0x1F,0x20)