Author Topic: Is NKRO actually needed (emphasis on the N)?  (Read 1234 times)

0 Members and 1 Guest are viewing this topic.

Offline sheaf

  • Thread Starter
  • Posts: 6
Is NKRO actually needed (emphasis on the N)?
« on: Fri, 04 October 2024, 13:52:38 »
Consider the USB HID descriptor for (say) a QMK keyboard w/ NKRO enabled:

Code: [Select]
   0x05,0x01,           // Usage Page:          Generic Desktop Ctrls
   0x09,0x06,           // Usage:               Keyboard
   0xa1,0x01,           // Collection:          Application
      0x85,0x03,         //   REPORT ID
      // ----------------------------------------------------------------------
      0x05,0x07,         //   Usage Page:        Kbrd/Keypad
      0x19,0xe0,         //   Usage Minimum:     0xe0
      0x29,0xe7,         //   Usage Maximum:     0xe7
      0x15,0x00,         //   Logical Minimum:   0
      0x25,0x01,         //   Logical Maximum:   1
      0x95,0x08,         //   Report Count:      8
      0x75,0x01,         //   Report Size:       1
      0x81,0x02,         //   Input:             Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position
      // ----------------------------------------------------------------------
      0x05,0x07,         //   Usage Page:        Kbrd/Keypad
      0x19,0x00,         //   Usage Minimum:     0x00
      0x29,0xef,         //   Usage Maximum:     0xef
      0x15,0x00,         //   Logical Minimum:   0
      0x25,0x01,         //   Logical Maximum:   1
      0x95,0xf0,         //   Report Count:      -16
      0x75,0x01,         //   Report Size:       1
      0x81,0x02,         //   Input:             Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position
      // ----------------------------------------------------------------------
      0x05,0x08,         //   Usage Page:        LEDs
      0x19,0x01,         //   Usage Minimum:     Num Lock
      0x29,0x05,         //   Usage Maximum:     Kana
      0x95,0x05,         //   Report Count:      5
      0x75,0x01,         //   Report Size:       1
      0x91,0x02,         //   Output:            Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile
      0x95,0x01,         //   Report Count:      1
      0x75,0x03,         //   Report Size:       3
      0x91,0x01,         //   Output:            Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile
   0xc0,                // End Collection

recovered empirically on Ubuntu by running:

Code: [Select]
hexdump -e '16/1 "%02x " "\n"' /sys/bus/hid/devices/0003:FFFF:3000.001F/report_descriptor

where FFFF and 3000 are the VID/PID and the 001F part seems to change often (so you must get it before hand, eg. by running: ls -l /sys/bus/hid/devices).

Notice that (unless I'm counting wrong) this yields 256-bit (32-byte) HID reports, which is a whooping half of what a USB FS Interrupt Transfer even allows (see: https://beyondlogic.org/usbnutshell/usb4.shtml#Interrupt).
Compare that with a "boot procotol keyboard" HID report, which (I think) is only 8 bytes (ie. 4x smaller).

In my tests, every byte matters over USB Full Speed (or maybe my STM32 is too slow?).
(Eg. sending a 1-byte report can be done *way* faster than sending an 8-byte report.)
This may (or may not) be unimportant for regular typing, but it seems (unless I'm missing something) quite important for automation-oriented things like macros (sending macros as fast as possible), Unicode, emojis, and whatnot. (Imagine if copy-pasting the text inside a 10KB document too 3 seconds! But sending 10,000 HID keystrokes over USB FS at 1000Hz might take seconds.)
Eg. if you want to send the flag of England emoji (U+1F3F4 U+E0067 U+E0062 U+E0065 U+E006E U+E0067 U+E007F), that's seven 20-bit (almost the max size) Unicode codepoints, which in practice occupies 28 bytes in UTF-8, UTF-16 or UTF-32, so your (very practical) macro that spams 100 flags of England now run 7x slower.

So I'm wondering, is NKRO even needed?

Even for steno, if each finger only presses at most 2 keys at a time, that's a maximum of 20 keys? But 20-key chords should be very rare, if any even exist.
And for regular, non-steno, non-chorded typing, theoretically you'd only press 10 keys at a time at most, but in practice more like 4 or 6?

So I always thoght NKRO was this "must have feature" that all mechanical keyboards must have, but now that I'm actually working on one, I'm thinking, why not 16KRO, save 16 (or 15) bytes, and call it a day?
Am I missing something?

Offline Findecanor

  • Posts: 5080
  • Location: Koriko
Re: Is NKRO actually needed (emphasis on the N)?
« Reply #1 on: Fri, 04 October 2024, 17:29:42 »
I'd think that the important part of NKRO is having a diode per key switch at the keyboard end.
Having NKRO in the protocol is about meeting that capacity.

USB keyboards don't send Unicode. Each report represents the state of the keys on the keyboard: which ones that are pressed at the moment.
A keyboard's firmware could have its internal state represented as bit-vectors with one bit per key. Then it would be convenient for the programmer to use that bit-vector format also as report format.

I think TMK and QMK use a standardised format for the bit vector with all logical key codes. Pruning the format to the keys that are in the current keymap would be more work for the microcontroller and require more RAM. (The "4" in "ATmega32U4" stands for 4 kilobytes)
Historically there have also been problems with operating systems being picky about how these report formats have been made, so you'd might not want to mess too much with them: Keeping to a single format that you know works is probably the most practical thing to do.
« Last Edit: Fri, 04 October 2024, 17:36:32 by Findecanor »
🍉

Offline sheaf

  • Thread Starter
  • Posts: 6
Re: Is NKRO actually needed (emphasis on the N)?
« Reply #2 on: Fri, 04 October 2024, 17:51:37 »
USB keyboards don't send Unicode.

This one does!

Offline Findecanor

  • Posts: 5080
  • Location: Koriko
Re: Is NKRO actually needed (emphasis on the N)?
« Reply #3 on: Sat, 05 October 2024, 02:34:44 »
USB keyboards don't send Unicode.

This one does!
Ah, but not directly. QMK sends a key sequence simulating the way that you would have entered unicode manually, e.g. by holding down ALT and typing the numeric code on the numpad.
The sequences are different for different operating systems.
🍉

Offline sheaf

  • Thread Starter
  • Posts: 6
Re: Is NKRO actually needed (emphasis on the N)?
« Reply #4 on: Tue, 15 October 2024, 06:39:15 »
USB keyboards don't send Unicode.

This one does!
Ah, but not directly. QMK sends a key sequence simulating the way that you would have entered unicode manually, e.g. by holding down ALT and typing the numeric code on the numpad.
The sequences are different for different operating systems.

I forgot to say; I'm not using QMK; I've written firmware from scratch.
I mentioned the QMK USB Report Descriptor as a known example.