Introduction
A tag reader can both read and write to the tag. During production, the NFC controller of every NHS31xx IC is configured such that access to the communication interface of the firmware is never blocked. To ensure correct bi-directional communication, the tag reader needs to adhere to several standards and protocols:
- ISO/IEC 14443 - Identification cards – Contactless integrated circuit cards – Proximity cards and specifically part 4: Transmission protocol.
- the NFC Data Exchange Format (NDEF) Technical Specification from NFC Forum
- the msg protocol.
Specific information to enable communication to any NHS31xx IC is detailed out below. Sufficient knowledge of the NFC-forum standards and the msg protocol is assumed.
- Note
- This page describes low-level information to get you started, so you can implement every layer yourself. Depending on the library and API at your disposal on your host platform, this may already have been done for you. For example, on an Android platform, high level API is already present so you can just focus on the msg protocol only.
Writing to and reading from the NFC memory
The NFC controller in the NHS31xx ICs is fully compatible with a MIFARE UltraLight EV1 IC. It thus adheres to the ISO/IEC 14443 Type A standard for contactless smart cards.
All available MIFARE Ultralight EV1 commands can be found in the datasheet MF0ULX1 MIFARE Ultralight EV1 - Contactless ticket IC, Rev. 3.3 - 9 April 2019, chapter 9, table 9. Once a tag has been selected, an application can perform full communication with only a limited set of them:
GET_VERSION
is a MIFARE family specific command, and is used to identify the type of the IC.
Name | Code | Description | Length |
Cmd | 60 | Get product version | 1 byte |
CRC | xx | See ISO/IEC 14443-3 | 2 bytes |
Data | | Response | 8 bytes |
NAK | 0A | Upon success | 4 bits |
- See also UM10876 NHS31xx User manual, Rev. 2.07 - 2 May 2019, subsection 11.6.2.1 Device specific GET_VERSION command, Table 105 GET_VERSION response for NHS devices.
- The CRC is automatically added by mobile platforms Android and iOS.
- A list of all possible NAK values can be found in the MF0ULX1 datasheet: 9.3 MIFARE Ultralight ACK and NAK, Table 10. ACK and NAK values
READ
returns the bytes of 4 pages.
Name | Code | Description | Length |
Cmd | 30 | Read 4 pages | 1 byte |
Addr | xx | Start page address | 1 byte |
CRC | yy | See ISO/IEC 14443-3 | 2 bytes |
Data | | Response | 16 bytes |
NAK | 0A | Upon success | 4 bits |
For example, when Addr equals 03h
, the bytes of pages 03h
, 04h
, 05h
, 06h
are returned.
FAST_READ
returns the bytes of any number of pages.
Name | Code | Description | Length |
Cmd | 3A | Read multiple pages | 1 byte |
StartAddr | xx | Start page address | 1 byte |
EndAddr | yy | End page address | 1 byte |
CRC | zz | See ISO/IEC 14443-3 | 2 bytes |
Data | | Response | (yy-xx+1)*4 bytes |
NAK | 0A | Upon success | 4 bits |
For example, when StartAddr equals 03h
and EndAddr equals 07h
, the bytes of pages 03h
, 04h
, 05h
, 06h
, 07h
are returned.
WRITE
stores 4 bytes of data into a single page.
Name | Code | Description | Length |
Cmd | A2 | Write 1 page | 1 byte |
Addr | xx | Page address | 1 byte |
CRC | yy | See ISO/IEC 14443-3 | 2 bytes |
Data | | Data | 4 bytes |
NAK | 0A | Upon success | 4 bits |
- Note
- As part of the selection procedure before a tag is selected, the NFC ID is exchanged with the tag reader. To explicitly re-retrieve the same information as APDU command
GET UID
, use the tag-specific READ
command to read the first 4 pages. The 7-byte NFC ID is stored in the first two pages, with byte 3 of page 00h
the first check byte (and byte 0 of page 02h
the second check byte).
Using USB NFC readers
USB NFC readers implement the Personal Computer/Smart Card PC/SC specification to allow access to a tag. The specification is called the The Interoperability Specification for ICCs and Personal Computer Systems and is available at https://www.pcscworkgroup.com. The driver for a USB NFC reader allows communication to a tag by means of smart card application protocol data units or APDU's. An applications sends a command APDU and receives back a response APDU. The USB NFC reader will translate the APDU's to the tag specific commands and responses, regardless of NFC type and manufacturer. Always check the User Manual of your USB NFC reader.
Once connected, an application can perform full communication with a limited set of commands:
GET UID
command APDU will retrieve the NFC ID, which is a random 7-byte sequence determined during production of the IC.
CLA | INS | P1 | P2 | Lc | Data | Le |
FF | CA | 00 | 00 | absent | absent | 07 |
Upon success, the response APDU will be:
Data | SW1 | SW2 |
7 bytes | 90 | 00 |
READ BINARY
reads data from a MIFARE card. Data is read per 4 pages.
CLA | INS | P1 | P2 | Lc | Data | Le |
FF | B0 | MSB | LSB | absent | absent | 10 |
P1 and P2 combined represent the starting page number to be read.
Upon success, the response APDU will be:
Data | SW1 | SW2 |
16 bytes | 90 | 00 |
- Depending on the driver implementation on your host platform, it may be that only 4 bytes are returned, even though 16 bytes have been fetched.
- If Le is set to
00h
, the tag reader will repeatedly read data from the tag up to a maximum of 256 and return all bytes at once.
- A list of all possible NAK values can be found in Part 3 of the specification, subsection 3.2.2.1.8 Read Binary Command, Table 3-19: Read Binary Command Error Codes.
UPDATE BINARY
writes a single page.
CLA | INS | P1 | P2 | Lc | Data | Le |
FF | D6 | MSB | LSB | 04 | 4 bytes | absent |
P1 and P2 combined represent the page number to be written.
When writing more than 4 bytes, multiple pages need to be written. This command will then need to be repeated for every page.
The response APDU only contains the status bytes. Upon success these will be:
Data | SW1 | SW2 |
absent | 90 | 00 |
- A list of all possible NAK values can be found in Part 3 of the specification, subsection 3.2.2.1.9 Update Binary Command, Table 3-21: Update Binary Command Error Codes .
More information about APDUs can be found:
- with the documentation of your USB NFC reader.
- in the specification, specifically Part 3. Requirements for PC-Connected Interface Devices
- in ISO/IEC 7816 and specifically part 4: Organization, security and commands for interchange.
- Note
- It is not possible to retrieve the same information as the tag-specific
GET_VERSION
MIFARE command using an APDU command.
NDEF
- Write location
- The NFC memory is organized in pages with 4 bytes per page. The writable portion of the type2 tag NFC memory starts at page
04h
. It is the task of the embedded firmware to initialize the NFC contents. This must be done before the tag reader starts reading the NFC contents. Failure to do so in time will result in the tag being reported as an NDEF formattable tag, which carries some restrictions when the tag reader wants to use the high level API, available on platforms as Android and iOS.
The SDK supports you with this through the ndeft2t module. Initialize the module at startup in your firmware and the NFC contents will be populated with:
- a lock TLV:
01 03 E8 0E 46
,
- a proprietary TLV:
FD 01 00
and
- an empty NDEF TLV:
03 00
.
The tag reader must know which pages are locked and thus read-only. The read-only third page 02h
contains locking bits, covering the pages up to 0Fh
. Similar information for higher pages can be retrieved using the extra lock TLV starting at page 04h
.
The proprietary TLV is present for padding purposes: with it, the next TLV - the NDEF message - will start on a page boundary. This allows the ndeft2t module to correctly detect when new messages arrive, and when outgoing messages have been consumed by the tag reader.
When the tag reader reads the NFC contents, the NDEF message will be present on page 6 onwards.
- All new NDEF messages written by the ARM firmware application will overwrite the contents on page 6 onwards;
- all NDEF messages written by the tag reader must also overwrite the contents on page 6 onwards.
- The lock TLV and proprietary TLV on page 4 and 5 must be kept intact.
- Write sequence
- To be compliant with the NFC forum specification, an NDEF message must be written in a 4-step process:
- Write an NDEF message with length 0
- Write the payload
- Update the length
- Write the end demarcation: the terminator TLV
FE
Step 4 may be omitted or combined with step 2 (in practice, not according to a strict interpretation of the NFC forum specification). The ndeft2t module will also follow this process when writing an NDEF message for the tag reader to consume, writing the end demarcation together with the rest of the payload (combining step 2 and 4). The end demarcation is always written by the ndeft2t module, but not looked at when parsing. Steps 1 through 3 must be adhered to or the ndeft2t module will fail to detect new messages, or fail to parse them correctly - for example as it may be too fast and start parsing before all contents are already available.
- Compatibility
- Compatibility with the NDEF messaging format is provided again by the ndeft2t module in the SDK. There are a few limitations in the implementation:
- Only a single NDEF message is supported.
- Only TEXT, URL, MIME and AAR records are supported.
- Only UTF-8 TEXT is supported.
- Only the most probable URI prefixes are supported when using the shortened format.
The firmware may write and can parse multi-record NDEF messages, with any of its supported record types in any order.
The most used container to convey information is the MIME record. Currently, the mime type is not used by the firmware when interpreting the different payloads, but your custom application can. The minimum length of a mime type is 3 and must include a slash "/"
. All host demo apps use therefore the mimetype "n/p"
, while the demo firmware applications use a custom mimetype which identifies the demo at hand. This can be used by the host app to help determining whether the correct tag was tapped.
Example
- To retrieve firmware version information, the msg protocol provides MSG_ID_GETVERSION.
The command does not contain any parameters, so the full command to write is 02 00
- A MIME record contains these fields:
MB|ME|CF|SR|IL|TNF type_length payload_length type payload
When only a simple single NDEF record is to be created, this can translate to: 1 |1 |0 |1 |0 |2 3 payload_length "n/p" payload
In hexadecimal format, this equals: D2 03 payload_length 6E 2F 70 payload
And when trying to retrieve version information, this then becomes:
- An NDEF message is a
TLV
with
Type
equal to 03
. The type is always a single byte.
Length
equal to the number of bytes that will follow. If that number is strict less than 0xFF
, Length
is just a single byte; else, the length is encoded as
Value
equal to the bytes of all the record payloads, placed right after each other.
In this example, the full TLV byte sequence is then T L V
T L D2 03 02 6E 2F 70 02 00
03 08 D2 03 02 6E 2F 70 02 00
- With the end demarcation
FE
appended this will occupy three pages. After writing these, the contents of the NFC memory must become: page 06h: 03 08 D2 03
page 07h: 02 6E 2F 70
page 08h: 02 00 FE xx
The last byte of page 8 xx
can contain anything and will never be looked at.
- To write this, per the NFC forum specification, these 5 write commands must be carried out in this order:
page 06h: 03 00 xx xx
page 07h: 02 6E 2F 70
page 08h: 02 00 xx xx
page 06h: 03 08 D2 03
page 08h: 02 00 FE xx
The bytes denoting xx
can have any value.
Usually, the end demarcation FE
is written together with the payload (combining step 4 with step 2): page 06h: 03 00 00 00
page 07h: 02 6E 2F 70
page 08h: 02 00 FE 00
page 06h: 03 08 D2 03
A total of 4 page write commands then need to be executed.