ODRFID (HID Firmware)
The HID firmware acts as a USB HID Keyboard and a Vendor-Specific HID device. The device scans for new tags and types the UID (or UID+SAK, or the specified block) of the scanned tag by using virtual keystrokes.
The differences in the device revisions are described in the Hardware Revisions section.
Device modes
The RFID device can be in two modes: the scanning mode and the application controlled mode. The default mode (i.e. then device mode after POR) is selected via the device settings. Factory defaults set it to the scanning mode.
- In the scanning mode the device scans for new tags and "types" the UID, UID+SAK and/or block(s) of the scanned tag by using virtual keystrokes. One can control how the data is printed via the device settings (upper case / lower case, carriage return, etc. Starting from the v1.2F firmware the device presents full control over the data being printed). The tag presence is queried once every N ms. Factory default is 200ms. Custom HID commands (except the one switching the mode and controlling the device settings) are ignored in the scanning mode.
- When the device in the application controlled mode, the user controls the device behavior via custom HID commands.
HID Reports
This firmware has two reports
- Report
1
is used to send keyboard events when the device is in scanning mode and follows the standard HID Keyboard Report format - Report
2
is used to configure the device, switching scan modes and query/read/write tags. Both IN- and OUT reports with ID2
always consist of 63 bytes (64 including the report ID).
Custom HID commands
General Description
Custom HID commands are sent and received via HID report with ID 2
. The report always consists of 63 bytes. The report ID is always the first byte, therefore the full report length is 64 bytes. The first byte (after the report ID byte) is the command ID. Valid commands are listed below. The next bytes are command parameters. If the command parameters occupy less than 62 bytes, the remaining unused bytes should be treated as a padding - they can have any arbitrary value that has no meaning.
The device answers with a report, where the first byte (after the report ID) is the command id (the same as in the request), the next 4 bytes are the error code (32bit unsigned integer, little endian), and the following bytes are command specific. If the command parameters occupy less than the remaining 58 bytes, the unused bytes should be treated as a padding - they can have any arbitrary value that has no meaning. If the error code is not zero, the following command-specific bytes cannot be trusted and must be regarded as meaningless.
The error code has the following bit fields:
0x00000001
- Protocol error0x00000002
- Parity error0x00000004
- Checksum error0x00000008
- Collision0x00000010
- Buffer overflow0x00000020
- Tear event0x00000040
- IC overheated0x00000080
- FIFO write error0x00000100
- Operation timed out0x00000200
- Mifare NAK0x00000400
- Authentication failure0x00000800
- Generic communication error0x00001000
- The TAG returned more data than expected (v1.5+)0x00002000
- The TAG reply integrity error (v1.5+)
Bits 16-31 are reserved for internal purposes
The error code of 0
is OK
(i.e. no error). ATTENTION: the data following the error code bytes is valid only if the error code is 0.
Command list:
0x01
- Device Information0x02
- LED Control0x03
- Buzzer Control0x10
- Inventory Scan (all tags)0x11
- Inventory Scan (the first tag)0x12
- Inventory Scan (select the next tag)0x13
- Check Tag Presence0x20
- Select Tag0x21
- Tag Details0x22
- Read Data Block0x23
- Write Data Block0x24
- Increment value0x25
- Decrement value0x26
- MF Plus Write Data Block0x27
- MF Plus Security Level Switch0x28
- MF Plus Read Data Block0x29
- MF Plus Authenticate0x2F
- Change Tag UID0x30
- Settings: LED0x31
- Settings: Buzzer0x32
- Settings: Gain0x33
- Settings: Query Frequency0x34
- Settings: Mifare Key0x35
- Settings: UID Case (KBD)0x36
- Settings: UID Carriage Return (KBD)0x37
- Settings: SAK (KBD)0x38
- Settings: Scan Type0x39
- Settings: Scan Block Number0x3A
- Settings: Output Format0x3F
- Settings: Save to ROM0x40
- RFID Antenna State0x41
- RFID Mode Control0x42
- 13.56MHz transceiver control0x43
- 125kHz transceiver control0x60
- T55x7 programming control0x61
- T55x7 cloning0x62
- T55x7 programming0x63
- T55x7 password programming0x64
- Clear T55x7 password0x80
- Reboot Device0x81
- Reboot Device (DFU)- Other values are RFU
Abbreviations:
- IN - device to host
- OUT - host to device
Several commands have one 1byte parameter (bValue), that controls a device state or setting. It can be one of the following:
QUERY |
0 | query the current state/value |
ON |
1 | enable |
OFF |
2 | disable |
SWITCH |
3 | switch state |
DEFAULT |
4 | relinquish control to the firmware |
----- |
other values | treated as QUERY |
Device Information
- Command code: 0x01
- Params (OUT): none
- Params (IN):
- 4 bytes: error code
- 1 byte: firmware info length
- N bytes: firmware info
This command queries the firmware version of the device.
LED Control
- Command code: 0x02
- Params (OUT): bValue
ON
- LED onOFF
- LED offSWITCH
- blink (250ms)DEFAULT
- relinquish control to the firmware- other - query state
- Params (IN):
- 4 bytes: error code
- 1 byte: current LED state (1 - on, 0 - off)
Buzzer Control
- Command code: 0x03
- Params (OUT): bValue
ON
- buzzer onOFF
- buzzer offSWITCH
,DEFAULT
- relinquish control to the firmware- other - query state
- Params (IN):
- 4 bytes: error code
- 1 byte: current buzzer state (1 - on, 0 - off)
Inventory Scan (all tags)
Enumerates all the tags currently visible by the reader. All the tags are reset after the scan.
- Command code: 0x10
- Params(OUT): none
One or mode IN reports will be sent by the device. Params:
- 4 byte: error code
- 1 byte: L - UID length (0 for the last report)
- L bytes: UID
- 1 byte: SAK
Inventory Scan (the first tag)
Selects the first tag (according to the anti-collision procedure). The tag (if present) will be set as the current one and halted.
- Command code: 0x11
- Params (OUT): none
- Params (IN):
- 4 bytes: error code
- 1 byte: L - UID length
- L bytes: UID
- 1 byte: SAK
Inventory Scan (select the next tag)
Halts the currently selected tag (if any) and selects the next 13.56MHz tag (if any) according to the anti-collision procedure. The new tag will be set as the current one and halted.
The '-e' revision of the device does not support this command and returns an ERROR
.
- Command code: 0x12
- Params (OUT): none
- Params (IN):
- 4 bytes: error code
- 1 byte: L - UID length
- L bytes: UID
- 1 byte: SAK
Check Tag Presence
Checks whether a 13.56MHz tag with the specified UID is present. If the query succeeds, the tag will not be set as the current one. The tag will be halted.
The '-e' revision of the device does not support this command and returns an ERROR
.
- Command code: 0x13
- Params (OUT):
- 1 byte: L - UID length (4/7/10)
- L bytes: UID
- Params (IN):
- 4 bytes: error code
- 1 byte: L - UID length
- L bytes: UID
- 1 byte: SAK
Select Tag
The 13.56MHz tag with the specified UID will be set as the current one and halted.
The '-e' revision of the device does not support this command and returns an ERROR
.
- Command code: 0x20
- Params (OUT):
- 1 byte: L - UID length (0/4/7/10). If L == 0, halt the current tag.
- L bytes: UID
- Params (IN):
- 4 bytes: error code
Get Current Tag Information
ATTENTION: Prior to v1.6, if no tag is selected as the current one, the Inventory Scan (the first tag) command will be executed first. If the current tag fails to respond, the next one will be selected and queried. Starting from v1.6, current should read: 'the tag, selected by the last Inventory Scan / Next Tag / Select command' (not the first one selected by the anti-collision procedure)
- Command code: 0x21
- Params (OUT): none
-
Params (IN):
- 4 bytes: error code
- 1 byte: L - UID length (0 for the last report)
- L bytes: UID
- 1 byte: SAK
- 2 bytes: block count (16bit unsigned integer, little endian)
- 1 byte: block size
- 1 byte: tag type
Recognized tag types: ref. Tag Types
Read Data Block
(only for Classic, Plus S/X (SL1), Ultralight and NTAGs)
A tag must be selected prior to executing this command (either by calling Inventory Scan (the first tag), Inventory Scan (select the next tag), Select Tag ). The block number must be within the range supported by the tag.
The '-e' revision of the device does not support this command and returns an ERROR
.
- Command code: 0x22
- Params (OUT): 1 byte block number
- Params (IN):
- 4 bytes: error code
- 1 byte: block number
- 1 byte: N = block size (16 or 4 - equal to the value of the block size field returned by the tag info command)
- N bytes: block data
Write Data Block
(only for Classic, Plus S/X (SL1), Ultralight and NTAGs)
A tag must be selected prior to executing this command (either by calling Inventory Scan (the first tag), Inventory Scan (select the next tag), Select Tag ). The block number must be within the range supported by the tag. Data size must be equal to the block size value returned by the tag info command.
The '-e' revision of the device does not support this command and returns an ERROR
.
- Command code: 0x23
- Params (OUT):
- 1 byte: block number
- 1 byte: data size (N)
- N bytes: data
- Params (IN):
- 4 bytes: error code
- 1 byte: block number
Value Block
(supported since v1.6, only for Classic, Plus S/X (SL1), Ultralight and NTAGs)
Increment / decrement the value of a "value block" of a Mifare Classic or Plus S/X tag.
The '-e' revision of the device does not support this command and returns an ERROR
.
- Command code: 0x24 (increment) / 0x25 (decrement)
- Params (OUT):
- 1 byte: block number
- 4 bytes: integer value (32bit, little endian)
- Params (IN):
- 4 bytes: error code
- 1 byte: block number
Change Tag UID
Warning: this function is supported starting from v 1.5. Not all tags have a rewritable block 0. This is a potentially dangerous operation. The best case scenario - it just won't work. The worst case - you can brick your tag. Proceed at your own risk. UID size changing is not supported. All tags except Mifare Classic are not supported!
The '-e' revision of the device does not support this command and returns an ERROR
.
- Command code: 0x2F
- Params (OUT):
- 1 byte: UID size (it must match the size of the current UID.)
- N bytes: new UID data
- Params (IN):
- 4 bytes: error code
Mifare Plus specific commands
(supported since v1.6)
The '-e/-m' revisions of the device do not support these commands and return an ERROR
.
Authentication
Perform MF Plus authentication for the specified block.
- Command code: 0x29
- Params (OUT):
- 2 bytes: block number (16 bit, little endian)
- Params (IN):
- 4 bytes: error code
- 2 bytes: block number
Read Block
Read a block of a MF Plus tag (assumes a successful authentication procedure for the corresponding block has been performed)
- Command code: 0x28
- Params (OUT):
- 2 bytes: block number (16 bit, little endian)
- Params (IN):
- 4 bytes: error code
- 2 bytes: block number
- 1 bytes: N = data size (matches the value of the block size field returned by the tag info command)
- N bytes: block data
Write Block
Write data block to tag memory (assumes a successful authentication procedure for the corresponding block has been performed). The block number must be within the range supported by the tag. The length of the data must match the size of a data block.
- Command code: 0x26
- Params (OUT):
- 2 bytes: block number (16 bit, little endian)
- 1 byte: N = data size (must match the value of the block size field returned by the tag info command)
- N bytes: block data
- Params (IN):
- 4 bytes: error code
- 2 bytes: block number
Security Level Switch
Switch the security level of a MF Plus tag.
- Command code: 0x27
- Params (OUT):
- 1 byte: new security level
- Params (IN):
- 4 bytes: error code
- 1 byte: new security level
125kHz Tags Commands
Supported by -e/-m revisions only.
Program T55x7
The device can program T55x7 (T5557/67/... and binary-compatible) tags in Em-Marine emulation mode. The tag will be identified by Em-marine compatible readers as a EM4100 tag with the specified UID.
If biphase encoding is used, please note, that in the e5555-compatibility mode (default for the T5577 IC) biphase coding is reversed compared to the EM4100 standard (mid-bit transition is one, not zero.) The device will therefore try to program the T5577 in extended mode, where a compatible biphase coding is available. This may fail, therefore for compatibility reasons Manchester coding choice is preferable.
- Command code: 0x62
- Params (OUT):
- 5 bytes: Customer ID (1 byte) + UID (4 bytes)
- Params (IN):
- 4 bytes: error code
ATTENTION: The device will not verify by itself that the write operation succeeded (or even that a compatible tag is present). The success or failure of the write command has to be verified by a following inventory scan command.
Clone a EM41xx tag
If an inventory scan command has been performed prior to issuing this command and an EM-Marine tag has been detected, the UID to be programmed can be omitted in order to perform a tag clone operation. Please refer to the previous paragraph (code 0x62) for details.
- Command code: 0x61
- Params (OUT): None
- Params (IN):
- 4 bytes: error code
Program T55x7 with a password
The same as the previous command, but the tag is password-protected against unauthorized access.
- Command code: 0x63
- Params (OUT):
- 4 bytes: password as a 32 bit big-endian unsigned integer.
- 5 bytes: Customer ID (1 byte) + UID (4 bytes)
- Params (IN):
- 4 bytes: error code
Clear the password protection of a T55x7 tag
ATTENTION. Only the password protection bit will be lifted. The password itself will be left in the tag's memory in plain text, anyone will be able to read it.
Please note that the device has no means to verify that the password protection has been disabled, or even that the password was correct.
- Command code: 0x64
- Params (OUT):
- 4 bytes: password as a 32 bit big-endian unsigned integer.
- Params (IN):
- 4 bytes: error code
Device Settings
The following commands change various device settings. The are executed regardless of the scanning mode. Individual commands change only in-RAM settings. In order to save the current settings to ROM, execute the Settings Write command.
Enable/Disable the LED
This command enables/disables the LED. This setting only affects whether the firmware switches the LED when a tag is detected/lost. Regardless of this setting, you can switch the LED on and off using LED Control command.
- Command code: 0x30
- Params (OUT): bValue
ON
- enable LED switchingOFF
- disable LED switching- other - query the current setting
- Params (IN):
- 4 bytes: error code
- 1 byte: current LED control setting (1 - enabled, 0 - disabled)
Enable/Disable the Buzzer
This command enables/disables the buzzer. This setting only affects whether the firmware switches the buzzer on when a tag is detected or not. Regardless of this setting, you can switch the buzzer on and off using BUZZ Control command.
- Command code: 0x31
- Params (OUT): bValue
ON
- enable buzzerOFF
- mute buzzer- other - query the current setting
- Params (IN):
- 4 bytes: error code
- 1 byte: current buzzer control setting (1 - enabled, 0 - disabled)
RFID Receiver Gain
The receiver gain is measured in dBm. The valid range is [18;48]dBm
. The default value is 33dBm
.
The valid gain values are
- 18dBm
- 23dBm
- 33dBm
- 38dBm
- 43dBm
- 48dBm
If any other value is passed, it will be rounded (to the nearest available value greater than the one passed).
- Command code: 0x32
- Params (OUT): (1 byte) 0 - query the current value,
>0
- set new gain value (in dBm) - Params (IN):
- 4 bytes: error code
- 1 byte: current gain value in dBm.
Tag Presence Query Frequency
When in scanning mode, the device queries the tag presence every N ms (default value: 1000ms). This command controls the query frequency (i.e. the interval N). Valid range is [100-65535] ms. Values smaller than the minimum one will be accepted and silently increased to fit in the range. Values greater then the maximum one will result in an error.
starting from v1.4: the default value is 200ms.
- Command code: 0x33
- Params (OUT): 2 bytes - 16bit unsigned little-endian integer
- 0 - query the current value
>0
- set new interval value (in ms)
- Params (IN):
- 4 bytes: error code
- 2 bytes: the current interval value in ms (U16LE).
Mifare Authentication Key / Ultralight Password
Mifare Classic / Plus tags need an authentication key to be read/written. The following command sets the key (the key type and 6 bytes long key itself), which will be used to authenticate connected Mifare Classic tags, or the 16 bytes long Mifare Plus Key (from v1.6). The default value is all FF
s
(from v 1.5) This command is also used to set the Ultralight EV1 and NTAG's authentication password and query the current tag's PACK.
- Command code: 0x34
- Params (OUT):
- 1 byte: key type
- 'A' (ascii code 65) - set the Classic key type to A
- 'B' (ascii code 66) - set the Classic key type to A
- 'U' (ascii code 85) - set the Ultralight password (for v 1.5 and above)
- 'P' (ascii code 80) - query the current Ultralight card's PACK (for v 1.5 and above)
- 'X' (ascii code 88) - set the Mifare Plus Authentication key (for v1.6 and above)
- Any other value - query the current key, key type, password (since v1.5) and Plus key (since v1.6)
- 6 bytes: key (for Classic) or
- 4 bytes: password (32bit LE - as stored in the corresponding block of the tag) or
- no extra data for PACK query or
- 16 bytes: key (for Plus)
- 1 byte: key type
- Params (IN, for 'A', 'B')
- 4 bytes: error code
- 1 byte: the current key type - 'A' (ascii code 65) or 'B' (ascii code 66)
- 6 bytes: the current key
- Params (IN, for 'U')
- 4 bytes: error code
- 1 byte: 'U'
- 4 bytes: the current password (32bit LE)
- Params (IN, for 'P')
- 4 bytes: error code
- 1 byte: 'P'
- 2 bytes: PACK (16bit LE - as stored in the corresponding block of the tag)
- Params (IN, for 'X')
- 4 bytes: error code
- 1 bytes: 'X'
- 16 bytes: the current key
- Params (IN, for any other value):
- 4 bytes: error code
- 1 byte: the current key type - 'A' (ascii code 65) or 'B' (ascii code 66)
- 6 bytes: the current key
- 4 bytes: Ultralight password (for v 1.5 and above)
- 16 bytes: Plus key (for v1.6 and above)
UID in Uppercase/Lowercase (keyboard mode)
- Command code: 0x35
- Params (OUT): bValue
ON
- print UID in upper caseOFF
- print UID in lower case- other - query the current setting
- Params (IN):
- 4 bytes: error code
- 1 byte: current case control setting (1 - upper case, 0 - lower case)
125kHz Tag Mode Control
(for the "-M/-E" revisions only). This parameter defines how the T55x7 tags will be programmed (i.e. the coding (Manchester/BiPhase) and the speed (32 or 64 transitions per bit))
- Command code: 0x60
- Params (OUT):
- Params (IN):
- 4 bytes: error code
- 1 byte: current coding state (
0
- Manchester,1
- BiPhase) - 1 byte: current speed state (
0
- 64tpb,1
- 32tpb)
Append/Omit Carriage Return (keyboard mode)
deprecated since version 1.2, not supported since v1.6
- Command code: 0x36
- Params (OUT): bValue
ON
- print carriage return after UIDOFF
- do not print carriage return after UID- other - query the current setting
- Params (IN):
- 4 bytes: error code
- 1 byte: current CR control setting (1 - append, 0 - omit)
Append/Omit SAK (keyboard mode)
deprecated since version 1.2, not supported since v1.5
- Command code: 0x37
- Params (OUT): bValue
ON
- append SAK to UIDOFF
- do not append SAK to UID- other - query the current setting
- Params (IN):
- 4 bytes: error code
- 1 byte: current SAK control setting (1 - append, 0 - omit)
Data selection (scanning mode)
deprecated since version 1.2, not supported since v1.5
This setting controls data (UID or block) printed when a new tag is detected.
- Command code: 0x38
- Params (OUT): 1 byte value
1
- print UID2
- print the contents of a block determined by the Block Number- other - query the current setting
- Params (IN):
- 4 bytes: error code
- 1 byte: current value
Block number selection (scanning mode)
deprecated since version 1.2, not supported since v1.5
In scanning mode the device continuously scans whether an RFID tag is present and prints UID or the selected block. This setting controls the block number being printed:
If the block does not exist or cannot be read (ex. due to an authorization failure) nothing is printed.
- Command code: 0x39
- Params (OUT):
- 1 byte: 0 - query, >0 - set
- 1 byte: new block number (if
set
mode is selected)
- Params (IN):
- 4 bytes: error code
- 1 byte: current value
Set output format
supported since version 1.2
In scanning mode the device continuously scans whether an RFID tag is present and prints the data read from the discovered tag using the specified format. Refer to the format description for the details. The default mode (i.e. before the first occurrence of a
, d
, h
, or H
switch) is the hexadecimal one. The upper or lower case depends on the Uppercase/Lowercase settings (code 0x35).
Syntax:
- Command code: 0x3A
- Params (OUT):
- 1 byte: 0 - query, >0 - set
- max. 32 bytes[^c_fs_1]: format string. If the length is less than 32 bytes, the string must end with 0 (aka null-terminated string).
- Params (IN):
- 4 bytes: error code
- max 32 bytes[^c_fs_2]: the current format string (null-terminated if less than 32 bytes long)
[^c_fs_1] In some newer readers (firmware version 2.9 and greater) the length of the format string is limited to 58 bytes. It is recommended to always fill the remaining bytes in the output report with zeros to prevent unexpected results.
[^c_fs_2] It is recommended to always rely on the format string being either 58 bytes long or null-terminated (whatever comes first).
Write settings to ROM
This command saves the current in-RAM setting to ROM, i.e. makes them permanent
- Command code: 0x3F
- Params (OUT): none
- Params (IN): (4 bytes) error code
Device Control
The following commands control the RFID reader device itself:
Enable/Disable RF Field
- Command code: 0x40
- Params (OUT): bValue
ON
- enable RF fieldOFF
- disable RF field- other - query the current mode
- Params (IN):
- 4 bytes: error code
- 1 byte: current RF field state (1 - enabled, 0 - disabled)
Note 1:
-
For the multi-protocol readers (i.e. 13.56MHz + 125kHz), the command switches both fields on / off, but only if the corresponding field is enabled (ref. 13.56MHz transceiver control and 125kHz transceiver control respectively), the query command is not reliable and should not be used.
-
For the single protocol readers (only 13.56MHz, or only 125kHz), the command switches the corresponding field on / off, the multi-protocol commands are not available.
Note 2: The field state query command is not reliable while the scanning process is running (i.e. the SCAN1
mode is active) and has been disabled while this mode is active for the 13.56MHz-enabled readers in the firmwares 2.2
and above. For the multi-protocol readers the query command is meaningless and has been disabled in the firmwares 2.2
and above.
RFID Mode Control
- Command code: 0x41
- Params (OUT): bValue
ON
- enable scan modeOFF
- disable scan modeQUERY
- query the current mode- other - error (will return
INVARG
error)
- Params (IN):
- 4 bytes: error code
- 1 byte: current mode (1 - scan mode enabled, 0 - scan mode disabled)
13.56MHz frequency transceiver control
(for the "-M" revision only) Enable/Disable the high-frequency (13.56MHz) transceiver. Default: enabled.
Note: The 125kHz tags are always scanned first unless the low-frequency transceiver is disabled.
Errata: due to a bug in the firmwares 2.0 and 2.1, the disable/enable command may have to be executed twice. Always check the result of the command and issue the disable/enable command again if the result differs.
- Command code: 0x42
- Params (OUT): bValue
ON
- enable 13.56 transceiverOFF
- disable 13.56 transceiverQUERY
- query the current mode- other - error (will return
INVARG
error)
- Params (IN):
- 4 bytes: error code
- 1 byte: current mode (1 - 13.56 transceiver enabled, 0 - 13.56 transceiver disabled)
125kHz frequency transceiver control
(for the "-M" revision only) Enable/Disable the low-frequency (125kHz) transceiver. Default: enabled.
Note: The 125kHz tags are always scanned first unless the low-frequency transceiver is disabled.
- Command code: 0x43
- Params (OUT): bValue
ON
- enable 125kHz transceiverOFF
- disable 125kHz transceiverQUERY
- query the current mode- other - error (will return
INVARG
error)
- Params (IN):
- 4 bytes: error code
- 1 byte: current mode (1 - 125kHz transceiver enabled, 0 - 125kHz transceiver disabled)
Device Reboot
Reboot the device.
- Command code: 0x80
- Params (OUT): none
- Params (IN): (4 bytes) error code
Firmware Update
Reboot the device and start the bootloader (this command may not be supported by some devices. If not supported, acts as Device Reboot ).
- Command code: 0x81
- Params (OUT): none
- Params (IN): (4 bytes) error code
Other commands - RFU
*Params (IN) (4 bytes) error code 0x800
- Generic communication error.