HID Device Config (/etc/hid_devices.toml)¶
Not every USB device works. Some are never enumerated; others enumerate but report in a format the generic path reads wrongly. Verified Peripherals lists what has been tested.
This file fixes the second case: it spells out, per device, which bits of the HID report are buttons and which are axes. The symptoms it addresses are a cursor that jumps, moves on the wrong axis, or does not move while the buttons work. A device that never enumerates is a driver problem and this will not help.
How a device gets its layout¶
The system tries these in order:
- This file. If a
[[mouse]]or[[gamepad]]block matches the device's vendor and product ID, that layout wins outright - Boot protocol. With no match, a boot-capable mouse is asked to send standard 3-byte boot reports
- Auto-detection. If the reports that arrive do not look like boot reports — longer than 3 bytes and starting with the mouse report ID — the system switches itself to a Report Protocol layout with 12-bit packed axes, which covers a common family of cheap mice
So a device only needs an entry here when all three fail.
Writing an entry without a PC¶
The HID Inspector app does this interactively on the device itself. It is built into the
firmware rather than installed under /app, so it is not in the launcher — press I on
the desktop to start it:
- LIST — pick the misbehaving device from the connected list
- INSPECT — watch the raw report bytes as you move and click
- WIZARD — it walks you through moving one axis at a time and works out where each field sits
- RESULT — it shows the
[[mouse]]block it generated; pressSto append it to/etc/hid_devices.toml
The format below is for reading and hand-editing what it writes.
[[mouse]]¶
[[mouse]]
vid = 0x046D
pid = 0xC534
name = "Logitech Unifying"
report_id = 0x02
report_len = 7
buttons = { offset = 0, size = 8, min = 0, max = 1, relative = false }
x = { offset = 16, size = 12, min = -2048, max = 2047, relative = true }
y = { offset = 28, size = 12, min = -2048, max = 2047, relative = true }
| Key | Meaning |
|---|---|
vid / pid |
USB vendor and product ID, as hex |
name |
Free text, used in the log so you can tell entries apart |
report_id |
The report ID byte. Omit it, or set -1, when the device sends none |
report_len |
Report length in bytes, not counting the report ID |
skip_control_transfer |
true to skip USB control transfers for this device. A few devices stall on them |
buttons |
Where the button bits are |
x / y |
Where the axes are |
Field tables take:
| Key | Meaning |
|---|---|
offset |
Bit offset from the start of the report data (after the report ID, if any) |
size |
Field width in bits |
min / max |
Value range. Negative min means the field is signed |
relative |
true for a mouse reporting movement, false for a touchpad or tablet reporting a position |
Offsets are in bits, not bytes. A 12-bit axis starting halfway through byte 2 is
offset = 20, and that is exactly the case the generic path gets wrong.
[[gamepad]]¶
[[gamepad]]
vid = 0x0F0D
pid = 0x0009
name = "HORI PAD 3 TURBO"
report_len = 19
buttons = { offset = 0, size = 16 }
hat = { offset = 16, size = 4 }
left_x = { offset = 24, size = 8, center = 128 }
left_y = { offset = 32, size = 8, center = 128 }
right_x = { offset = 40, size = 8, center = 128 }
right_y = { offset = 48, size = 8, center = 128 }
| Key | Meaning |
|---|---|
vid / pid / name |
As above |
report_len |
Report length in bytes |
buttons |
Bitmask field: offset, size. Bit n becomes button n |
hat |
D-pad / hat switch: offset, size. Optional |
left_x, left_y, right_x, right_y, l2, r2 |
Axes: offset, size, center |
center is the resting value of the axis — 128 for a stick that reports 0-255 — so the
system knows which way is "pushed".
Button numbers reach your app as ev[:button] in a :gamepad_down / :gamepad_up event, and
the GP_* constants name them. See
Constants & System Info.
Notes¶
- Blocks are matched by
vidandpidonly. A device that reports a different pid in a different mode needs an entry per mode - The shipped file contains working entries for a Logitech Unifying receiver, a Logickeyboard TITAN touchpad, a Sipeed NanoKVM-USB and a HORI PAD 3 TURBO. They are worth reading as examples even if you own none of them
- Flashing firmware replaces this file along with the rest of
/etc, so keep a copy of entries you worked out
Related¶
- Verified Peripherals — what has been tested, and what failed
- System Configuration —
system_conf.tomlandwifi.toml - Constants & System Info — the
GP_*andKEY_*constants - Default Apps — the HID Inspector