Skip to content

Add support for multiple virtual keyboard devices for N-Key rollover #1439

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

Closed
MostlyCoraGrace opened this issue Jan 4, 2019 · 10 comments
Closed

Comments

@MostlyCoraGrace
Copy link

current support only allows for one keyboard device with 6 pressed keys. The gamer in me can and will press more than that on occasion. More keys = more better 😎

@dhalbert
Copy link
Collaborator

dhalbert commented Jan 4, 2019

Do you have an example of a keyboard that transmits more than 6 pressed keys at once? All the USB HID keyboard descriptors I have seen do 6 keys max. I just checked a Logitech Gaming Keyboard, and it's also 6.

@MostlyCoraGrace
Copy link
Author

MostlyCoraGrace commented Jan 4, 2019

Most of the info I have comes from open-source wikis, where they use many keyboard devices each sending 6 keys each:
https://deskthority.net/wiki/Rollover,_blocking_and_ghosting#Interface-limited_NKRO

https://github.com/qmk/qmk_firmware/blob/995c3141a674a0311786cc713ea96d39330a9b48/docs/usb_nkro.txt
My Corsair K95 RGB for instance creates many virtual devices for N-Key rollover. Here I have two screenshots, one with the K95 RGB unplugged, and one with it plugged in, and you can see more than one HID device show up:
capture1

capture

@dhalbert
Copy link
Collaborator

This missive is interesting: https://www.devever.net/~hl/usbnkro.

The 6KRO limit is if the device is recognized as a boot keyboard only. So there are a couple of ways to achieve NKRO: one is to use a >6-key report descriptor, and another is to simulate multiple keyboards.

TinyUSB allocates the number of separate HID interfaces at compile time (also true for other devices, such as CDC). Currently we allocate only one. I will make this at least two to be able to support boot keyboards. But I don't think we need NKRO on boot keyboards..

Tagging @deshipu and @Red-M for interest.

@dhalbert dhalbert self-assigned this May 16, 2021
@dhalbert dhalbert modified the milestones: Long term, 7.0.0 May 16, 2021
@Red-M
Copy link

Red-M commented May 16, 2021

It would actually be very handy to have a way to assign a 6KRO for the first USB descriptor then another descriptor as an NKRO to allow for NKRO when inside an OS but to also allow for boot time control.

My current idea to cheat for NKRO was this: https://github.com/Red-M/RedPycoKeeb/blob/master/Firmware/lib/pycokeeb/basekeeb.py#L123-L149
(there is some implementation bugs with this and its missing a keycode to hid map to allow for release key reports being handled correctly)

Another thing to note is that the boot time 6KRO descriptor needs to be the first USB descriptor because otherwise the HID won't work at boot time.

@Red-M
Copy link

Red-M commented May 16, 2021

Actually that bit at the bottom of that post is exactly what we should try to get as it solves the issue of buggy BIOS implementations and silently allows for NKRO if the host supports it, which is perfect since nothing extra has to be handled by any HID use-case to "handle" HID interaction.

@dhalbert
Copy link
Collaborator

It would actually be very handy to have a way to assign a 6KRO for the first USB descriptor then another descriptor as an NKRO to allow for NKRO when inside an OS but to also allow for boot time control.

This will be possible. You will be able designate a keyboard (or mouse) descriptor as "boot", and it will mark it as a boot device. You could have a completely different keyboard report descriptor as the actual report descriptor (which would would be ignored in boot mode). So you could use the same interface for the boot-6KRO and the non-boot NKRO. I think that is one of the points in https://www.devever.net/~hl/usbnkro.

@deshipu
Copy link

deshipu commented May 16, 2021

I thought that the host is supposed to tell the device whether it expects a boot keyboard or not when the plug is connected?

@dhalbert
Copy link
Collaborator

dhalbert commented May 16, 2021

I thought that the host is supposed to tell the device whether it expects a boot keyboard or not when the plug is connected?

The host sends a "Set_Protocol" command to switch to the boot protocol and the standard, implied descriptor. So I think you could still have an NKRO-style report descriptor, but also will need to support the standard descriptor if it's Set_Protocol to boot mode. I think this is implied by the spec and by the last few paragraphs in https://www.devever.net/~hl/usbnkro. If I am misinterpreting something let me know. I think we would need to have a CIrcuitPython keyboard driver that could query which protocol is in use and send reports appropriately if you wanted to support an NKRO report.

image

@deshipu
Copy link

deshipu commented May 16, 2021

That sounds right, thank you!

@jepler
Copy link

jepler commented Jul 15, 2021

With dynamic USB descriptors (#4689) you can do things like this. In my experimentation, I successfully created a descriptor with NKRO which also worked in the BIOS boot menu of a Dell (https://emergent.unpythonic.net/01626210345 & https://emergent.unpythonic.net/01625944378). However, functioning as a boot keyboard (particcularly on macs) is still a problem (#1136).

@jepler jepler closed this as completed Jul 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants