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 a found tag by using virtual keystrokes.
Device modes
RFID device can be in two modes: scanning and application controlled mode. The default mode (i.e. then device mode after POR) is selected via the device settings. Factory defaults set it to scanning mode.
- When in scanning mode the device scans for new tags and types the UID (UID+SAk / block) of a found tag by using virtual keystrokes. One can control how the data is printed via the device settings (upper case / lower case, carriage return, etc). The tag presence is queried once every N ms. Factory default is 1000ms. 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 controlls 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
Custom HID commands are sent and received via HID report with ID 2
. The report always consists of 63 bytes. The report ID is prepended to the data, therefore the full report length is 64 bytes. The first byte (after the ID one) 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 are a padding and can have any arbitrary values that have no meaning.
The device answers with a report, where the first byte (after the report ID) is the command id (the same as 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 62 bytes, the remaining unused bytes are padding and can have any arbitrary values. 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 error
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 Block0x30
- 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 Control0x80
- Reboot Device0x81
- Reboot Device (DFU)- Other values are RFU
Abberviations:
- IN - device to host
- OUT - host to device
Several commands have one 1byte parameter (bValue), that controlls 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
- blinkDEFAULT
- 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 tag (if any) according to the anti-collision procedure. The new tag will be set as the current one and halted.
- 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 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.
- 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 tag with the specified UID will be set as the current one and halted.
- 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
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.
- 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
- 0 - Classic 1K
- 1 - Classic 4K
- 2 - Classic Mini
- 3 - Ultralight
- 4 - Ultralight C
- 5 - Ultralight C EV1 (640 bits)
- 6 - Ultralight C EV1 (1312 bits)
- 7 - Plus S 2K
- 8 - Plus S 4K
- 9 - DesFire 2K
- 10 - DesFire 4K
- 11 - DesFire 8K
- 12 - Classic 2K
- 13 - Plus X 2K
- 14 - Plus X 4K
- 15-254 RFU
- 255 - Unknown
Read Data Block
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, or Tag Info ). The block number must be within the range supported by the tag.
- 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
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, or Tag Info ). 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.
- 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
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 recevier 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 pased).
- 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 [250-65535] ms. Values smaller than the minimum one will be accepted and silently increased to fit in the range. Values greater then the aximum one will result in an error.
- 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 bytea: the current interval value in ms.
Mifare Authentication Key
Mifare Classic 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. The default value is FF
- Command code: 0x34
- Params (OUT):
- 1 byte: key type - 'A' (ascii code 65) or 'B' (ascii code 66). Any other value - query the current key and key type.
- 6 bytes: key
- Params (IN):
- 1 byte: the current key type - 'A' (ascii code 65) or 'B' (ascii code 66)
- 6 bytes: the current key
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)
Append/Omit Carriage Return (keyboard mode)
deprecated since version 1.2
- 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
- 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
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
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.
Format string syntax:
a
- switch to ascii mode: output data as ascii symbols. Skips data outside the range 8(backspace), 9(tab), 10(return) and 32(space)-126(~).d
- switch to decimal mode: output data as a decimal (0-255). No zero padding.h
- switch to hexadecimal mode (lower-case)H
- switch to hexadecimal mode (upper-case)U
- output the tag UID. The 'U' switch must be followed by one of the modifiers:*
- output the whole UID~
- output the whole UID in reversed order (the last byte first)n:m
- output bytes n, n+1, ... m (incl.) of the UID. If m<n, output bytes m, m-1, ..., n(incl.). The indices outside the current data range are silently skipped.n:
- output bytes n, n+1, ... of the UID (till the last byte)n
- output byte n. (Attention: n,m indices start at zero!)
BN
- output block N(0-255) from the tag memory. The block numbers range depends on the tag type. If the block does not exist or cannot be read (for example due to the authentication failure), it is silently skipped. TheB
switch must be followed by the block number N, then the '%' symbol and one of the modifiers:*
- output the whole block (4 or 16 bytes depending on the tag type)~
- output the whole block in reversed ordern:m
- output the block range (same format as theU
modifier)n:
- output part of the block (same format as theU
modifier)n
- output the block byte (same format as theU
modifier)
S
- output the SAK of the tag\t
sequence is converted to TAB,\n
to RETURN.- any other symbol is printed as is (no check whether is is a printable character or not is performed). In order to print reseved symbol ('a', 'd', 'h', etc) escape it with a backslash (
\
)
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: format string (if less than 32 bytes must end with 0 (aka null-terminated string)
- Params (IN):
- 4 bytes: error code
- max 32 bytes: the current format string (null-terminated if less than 32 bytes long)
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)
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)
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.