Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HyperX Alloy FPS Mechanical Gaming Keyboard not working #40

Open
bstrobel opened this issue May 19, 2024 · 20 comments
Open

HyperX Alloy FPS Mechanical Gaming Keyboard not working #40

bstrobel opened this issue May 19, 2024 · 20 comments
Assignees

Comments

@bstrobel
Copy link
Contributor

I mentioned it in my pull request. My HyperX Alloy FPS Mechanical Gaming Keyboard is behaving strangely.

Symptoms:

It is register correctly:

HID(2,3,KEYBOARD) mounted
 ID: 0951:16b7
 Manufacturer: Kingston
 Product:      HyperX Alloy FPS Mechanical Gaming Keyboard

But when a key is pressed all the events are recognized as mouse events although they come from the dev_addr/instance that was identified as KEYBOARD (i.e. dev_addr=2, instance=3 in the above example). The mouse cursor jumps wildly across the screen and ps2x2pico hangs eventually.

Investigation

I did some investigation and found out that the events identified as mouse events are actually keyboard events, but not from the simplified boot protocol that tinyusb uses but with a real HID event descriptor. They are 16 bytes long, not 8 and they have different but correct format. I wrote some code to decode them and could reliably identify all keypresses, except the EUROPE_1 and EUROPE_2 keys (these are the keys that are not present on US american keyboards, but on many european ones). The latter two keys were send in the 8 byte long boot protocol, but with the modifier bit field always 0.

So my assumption is that the keyboard in question does not support the old boot protocol but only the full featured HID protocol. Tinyusb is not able to cope with this. The tinyusb function tuh_hid_interface_protocol(dev_addr, instance) to identify the protocol of the event (i.e. if it is mouse or keyboard) is not compatible with the full protocol mode and falsely claims that it is a mouse event.

The lock up of ps2x2pico is probably due to concurrency issues. Could be due to calling the ms_usb_receive(report) function while the previous call is not finished or maybe due to a tinyusb problem where they are overrun by the events and ps2x2pico is not consuming them fast enough.

This little project here really ignited my interest and I want to dive deeper into this USB stuff. So I will continue to work on this. So maybe there will be another pull request in the future for this.

@No0ne
Copy link
Owner

No0ne commented May 19, 2024

Hu ha sounds complicated, but boot mode won't cut it in the long run I guess.
Would also solve this on the mouse side: #35 and #3

Thanks for future PRs!

@No0ne No0ne assigned No0ne and bstrobel and unassigned No0ne May 19, 2024
@bstrobel
Copy link
Contributor Author

I have the feeling that tinyusb is quite incomplete in this regard (USB host and boot mode vs. full), and I"m not sure this is a priority for them. They wrote somewhere in the comments that they switch each mouse and keyboard into boot mode when connecting. But I need to read more of the USB docs and tinyusb code before deciding what to do. I also plan to contact them and ask them about their plans. But only after I know enough to ask them educated questions... ;-)

@No0ne
Copy link
Owner

No0ne commented Jun 14, 2024

Did you find out anything new on this issue?
I'm nearly finished with the ps2 input feature, please pull as some files are renamed now.

@bstrobel
Copy link
Contributor Author

I investigated this some time ago and then traveled for a few weeks. I found out how to configure tinyusb to set report protocol instead of boot protocol when configuring a hid device:

tuh_hid_set_default_protocol(HID_PROTOCOL_REPORT);
tusb_init();

I implemented a rough parsing of the report that the keyboard is sending (just hardcoded, without actually parsing the report descriptor).

But I noticed that this keyboard is not sending europe_1 and europe_2 keys when I do this. And since I live in Germany I need them. I think the keyboard has weird bugs, that might be triggered when the report protocol is explicitly requested. I traced the USB communication of this kb and a few others I have on Linux to have something to compare to and Linux never sets the protocol explicitly. It just requests the report descriptors and then the keyboard sense also the events for the europe keys happily...

Anyway this is the only kb that is not working for me, which is not a big issue to me. I'm a bit fed up with the topic at the moment. ;) I suggest to leave this issue open since it is not fixed and I will come back when I have time and you haven't fixed it yourself yet by implementing proper report descriptor parsing and setting of the mode.

@0x504B0304
Copy link

0x504B0304 commented Jun 14, 2024

Have you ever noticed that there is a full hid report parser just in raspcerry pi pico-sdk?
https://github.com/bluekitchen/btstack/blob/72ef1732c954d938091467961e41f4aa9b976b34/src/btstack_hid_parser.c
It's very easy to port it into this project.

@bstrobel
Copy link
Contributor Author

No, I indeed have never noticed this parser. :D But this still doesn't solve the fundamental problem of the seemingly very buggy firmware of this keyboard. There are 2 bugs I did identify:

  1. In boot protocol mode (which it supports according to its descriptors) it sends the report not in boot format but in its own report format.
  2. If report protocol mode is set it sends the event in its report format but omits the europe_1 and europe_2 keys. (deal breaker for me)

It seems to work fine if the protocol mode is not set explicitly though. This is what I saw when I traced the communication in Linux using Wireshark.

To solve this I would need to patch tinyusb to never set the protocol mode and issue a PR for it. I simply do not want to do this just for one buggy keyboard. (I simply don"t use it here. I have too many keyboards anyway...) But if there are more keyboards that have similar bugs it might be worth the effort.

Another question is if we would start to use the HIDs in report mode and drop the boot protocol mode. This indeed is something to consider. But I think this decision is up to NoOne as the maintainer of this project. I suggest to open a new issue for this.

My day job is currently consuming most of my time so I can't work on this during the next few months. Still I would do this when I have more time to burn.

@0x504B0304
Copy link

Yeah, there are quite a lot of HID devices not following the standard HID specification. Many of them just never had a boot mode, even though they claimed to support it in their descriptor. However, I'm very surprised that Linux and Windows' HID drivers always make the right choice on whether to set the device into report mode. I cannot see any reason from the USB traffic; maybe it needs digging into the kernel source to understand.

@bstrobel
Copy link
Contributor Author

As I said my assumption is that at least Linux is not setting the mode and it just uses the device as is (i.e. in report protocol mode). In Linux it is quite easy to capture the USB traffic with Wireshark. Don't know about Windows. Haven't looked at this yet.

Though I'm 100% sure all manufactures test their devices with Windows and most of them with Linux. So it would be best to copy Windows or at least Linux. I also started digging into the Linux kernel sources already. I think Linux is the best source to copy you can get.

So yes in my eyes there is definitely a case to move away from boot proctol mode for this project.

@No0ne
Copy link
Owner

No0ne commented Jun 15, 2024

Yes totally agree, this would also help/fix #3 #23 and #35, but it is also too difficult for me right now.

Thanks for the research, I'll close this for now and open it when its relevant again.

@No0ne No0ne closed this as not planned Won't fix, can't repro, duplicate, stale Jun 15, 2024
@No0ne
Copy link
Owner

No0ne commented Nov 20, 2024

I'll soon get rid of boot mode. @bstrobel if you are still interested and would like to test your keyboard when I'm done this would be nice.

@No0ne No0ne reopened this Nov 20, 2024
@No0ne No0ne assigned No0ne and unassigned bstrobel Nov 20, 2024
@bstrobel
Copy link
Contributor Author

bstrobel commented Nov 21, 2024 via email

@No0ne
Copy link
Owner

No0ne commented Nov 28, 2024

There is a new 2.0 pre-release, it fixed #64.

@No0ne
Copy link
Owner

No0ne commented Dec 12, 2024

Please also try this: #66 (comment)

@No0ne
Copy link
Owner

No0ne commented Jan 10, 2025

Already found out that hid_parse_keyboard_modifiers failed in #73.

@bstrobel If you still have time for that I would really like to know what your keyboard does now.

@bstrobel
Copy link
Contributor Author

bstrobel commented Jan 10, 2025 via email

@bstrobel
Copy link
Contributor Author

I just did a quick test. Unfortunately I need to report that this b....y keyboard still doesn't work. Below is the serial debug output.

The adapter still works with an old Dell USB keyboard and a Logitech M705 mouse connected to a passive hub.

I checked out your code and updated the SDK and my dev setup. So if you want I can do code changes for you like temporarily adding more debug output or so.

HID(1,0,keyboard) mounted
 VID: 0951  PID: 16b7
 HID has 1 reports
 HID(1,0,keyboard) registered for reports

HID(1,1,mouse) mounted
 VID: 0951  PID: 16b7
 HID has 4 reports
 HID(1,1,mouse) registered for reports

HID(1,5,none) mounted
 VID: 0951  PID: 16b7
 HID has 1 reports
 HID(1,5,none) registered for reports
keyboard unknown  usage_page: ff00  usage: 00

@No0ne
Copy link
Owner

No0ne commented Jan 10, 2025

Thanks, there is no further output on keypresses? 🤔
Please try this: #73 (comment)

@bstrobel
Copy link
Contributor Author

usbhid-dump.txt

I guess you meant I should provide you with the usbhid-dump like you requested in issue #73 ? Here it is. And no, no key presses are registered and nothing is logged after the "keyboard unknown usage_page" message. Though the attached mouse still works so the pico is not hanging.

As you might remember I worked on this problem some time ago after I implemented the support for scan code set 3 for my SGI O2. At the time I used wireshark on Linux to capture the initialization of this keyboard to understand what is different to what ps2pico does. (The keyboard works flawlessly in Linux and Windows after all.) This is one that I just created. Use Wireshark to open it (after decompressing) and filter with usb.device_address==21

USB_HyperX_Alloy_FPS_dev21_Plugin.pcapng.gz

This just captures what happens when keyboard is plugged in. No key is typed.

You'll also see the GET DESCRIPTOR RESPONSE with the mysterious Vendor=0xff00. It is the 3rd packet from the bottom.

@No0ne
Copy link
Owner

No0ne commented Jan 11, 2025

Thanks for the hiddump, I'll take a look at that.
But I also meant try evenmoredebug.zip, it reports the raw bytes.

@bstrobel
Copy link
Contributor Author

Ok, here it is with your evenmoredebug firmware. Hope it helps. No key presses are registered from this keyboard. If I unplug it and plug in another keyboard the latter one works right away. The mouse works all the time.

Let me know if I can provide you with more information.

HID(1,0,keyboard) mounted
 VID: 0951  PID: 16b7
 HID has 1 reports
 HID(1,0,keyboard) registered for reports
 00  00  00  00  00  00  00  00 
mod 00

HID(1,1,mouse) mounted
 VID: 0951  PID: 16b7
 HID has 4 reports
 HID(1,1,mouse) registered for reports
 00  00  00  00  00  00  00 
report not found

HID(1,2,none) mounted
 VID: 0951  PID: 16b7
 HID has 1 reports
 HID(1,2,none) registered for reports
 00  00  00  00  00  00  00  00 
keyboard unknown  usage_page: ff00  usage: 00

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants