Add K8850 4x4+3knob key binding support (native FD protocol)#174
Add K8850 4x4+3knob key binding support (native FD protocol)#174skarard wants to merge 1 commit intokriomant:masterfrom
Conversation
45ad56c to
5f3394a
Compare
The K8850 (VID 0x514C, PID 0x8850) uses a different key binding protocol (0xFD command) than the K884x family (0xFE command). Protocol details reverse-engineered via Frida HID captures of mini_keyboard.exe and verified on hardware for all binding types: keyboard, modifiers, macros, media, mouse, and knobs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5749ae4 to
1ec60b7
Compare
|
I have no issues with this being a competition for my PR :) and if this becomes a better one then I'm all for it. But I have some comments:
Like in my PR, you also don't provide any way to differentiate this keyboard from other ones with the same VID/PID. This is the main reason I've marked my PR as WIP (Work In Progress) so it won't get merged. Merging either this or my PR will break things for other already supported keyboards that reuse the same VID/PID. Making this driver a default one for this VID/PID combination doesn't make any sense. I think that this program needs to have an option to manually override the driver in a command line. It's nice that it provides the tests. And of course the addition to control LEDs is also nice. |
| match expansion { | ||
| Macro::Keyboard(KeyboardEvent(_, presses)) => { | ||
| // Single key, no modifiers: binding_mode=1 (compact format) | ||
| if presses.len() == 1 && presses[0].modifiers.is_empty() { |
There was a problem hiding this comment.
This doesn't make sense. There's no such thing as a binding_mode=1. You're just setting the key sequence length field to 1. You can remove this condition and just leave the code in else block and it'll still work (the only difference is that the 50 ms delay is going to be set after the key).
| } | ||
| Macro::Media(code) => { | ||
| // Media mode: binding_mode=2, consumer code at [9] | ||
| let [low, _high] = (*code as u16).to_le_bytes(); |
There was a problem hiding this comment.
HID consumer codes are 16-bit wide. It doesn't make sense to only use the low byte.
|
|
||
| fn create_driver(id_product: u16, buttons: u8, knobs: u8) -> Result<Box<dyn Keyboard>> { | ||
| let keyboard: Box<dyn Keyboard> = match id_product { | ||
| 0x8840 | 0x8842 | 0x8850 => { |
There was a problem hiding this comment.
Making this driver the default one for 0x8850 PID is going to break support for other 0x8850 keyboards that are already supported.
Summary
Adds a dedicated driver (
k8850.rs) for the K8850 4x4+3knob keyboard variant (VID0x514C, PID0x8850). This device uses a different key binding protocol (0xFDcommand) than the K884x family (0xFEcommand).Protocol details were reverse-engineered via Frida-based HID captures of the official mini_keyboard.exe tool and confirmed through extensive hardware testing on an XZKJ-16key_3knob device.
Relation to PR #154
This PR covers the same device as @yawor's WIP PR #154. Key differences:
[code, 0x00, 0x32]for modifiers/macros[0x00, 0x00, code]for everything[0x00, 0x02, 0x00, 0x00, low][0, 2, 0, 0, low, 0, 0, high](includes high byte)new(buttons, knobs)with validationnew()no argsBoth PRs share: FD command byte, modifier IDs (F1-F8), mouse data format, finalize packet, endpoint 0x04.
Changes
k8850.rs(new): Native FD protocol driver withbind_key, mouse support, modifier mapping, and unit testsmod.rs: Addk8850module (+1 line)consts.rs: Add0x8850to product ID list (+1 line)main.rs: Addk8850import andcreate_drivermatch arm (+5 lines)No changes to
k884x.rs, theKeyboardtrait, oropen_device.Binding formats (confirmed via Frida capture)
[03 FD key_id layer 01 00 01 00 00 keycode 00][03 FD key_id layer 01 00 N 00 00 (triplets...)]where N = total entries[03 FD key_id layer 02 00 02 00 00 consumer_code][03 FD key_id layer 03 mouse_data...](17-byte mouse_data)[03 FD FE FF]after each bind_keyNote on VID
This device uses VID
0x514C(not0x1189), so requires--vendor-id 0x514c. Automatic VID handling can be addressed separately.Note on PID conflict
As noted in #154 and #136, PID
0x8850may be shared by different keyboard variants (e.g. 4x3+4knob). This PR maps0x8850directly to the 4x4+3knob driver. Variant auto-detection can be added later if needed.Test plan
Generated with Claude Code, reviewed and hardware tested by @skarard