This is not a boot-compatible keyboard, but it does allow full NRKO. Based on my light testing, it works on Linux (Debian 11 & Android). Presumably it does not work as a boot keyboard device.
You'll need CircuitPython 7 (including the latest alpha release).
The descriptor was designed based on one from the qmk documentation.
In boot.py, set up a custom keyboard descriptor. After putting boot.py on CIRCUITPY, reset the device and make sure that boot-out.txt contains the line "enabled HID with custom keyboard device".
import usb_hid BITMAP_KEYBOARD_DESCRIPTOR_REPORT_ID = 4 REPORT_BYTES = 16 bitmap_keyboard_descriptor = bytes(( 0x05, 0x01, # Usage Page (Generic Desktop), 0x09, 0x06, # Usage (Keyboard), 0xA1, 0x01, # Collection (Application), 0x85, 0x04, # Report ID (4), # bitmap of modifiers 0x75, 0x01, # Report Size (1), 0x95, 0x08, # Report Count (8), 0x05, 0x07, # Usage Page (Key Codes), 0x19, 0xE0, # Usage Minimum (224), 0x29, 0xE7, # Usage Maximum (231), 0x15, 0x00, # Logical Minimum (0), 0x25, 0x01, # Logical Maximum (1), 0x81, 0x02, # Input (Data, Variable, Absolute), ;Modifier byte # LED output report 0x95, 0x05, # Report Count (5), 0x75, 0x01, # Report Size (1), 0x05, 0x08, # Usage Page (LEDs), 0x19, 0x01, # Usage Minimum (1), 0x29, 0x05, # Usage Maximum (5), 0x91, 0x02, # Output (Data, Variable, Absolute), 0x95, 0x01, # Report Count (1), 0x75, 0x03, # Report Size (3), 0x91, 0x03, # Output (Constant), # bitmap of keys 0x95, (REPORT_BYTES-1)*8, # Report Count (), 0x75, 0x01, # Report Size (1), 0x15, 0x00, # Logical Minimum (0), 0x25, 0x01, # Logical Maximum(1), 0x05, 0x07, # Usage Page (Key Codes), 0x19, 0x00, # Usage Minimum (0), 0x29, (REPORT_BYTES-1)*8-1, # Usage Maximum (), 0x81, 0x02, # Input (Data, Variable, Absolute), 0xc0 # End Collection )) bitmap_keyboard = usb_hid.Device( report_descriptor = bitmap_keyboard_descriptor, usage_page = 0x1, usage = 0x6, in_report_lengths = (16,) out_report_lengths = (1,) report_ids = (BITMAP_KEYBOARD_DESCRIPTOR_REPORT_ID,) ) print(bitmap_keyboard) devices = [ bitmap_keyboard usb_hid.Device.CONSUMER_CONTROL, ] usb_hid.enable(devices) print("enabled HID with custom keyboard device")
In your code.py, use this subclass of adafruit_hid.keyboard.Keyboard:
class BitmapKeyboard(Keyboard): def __init__(self, devices): for device in devices: if device.usage == 6 and device.usage_page == 1: try: device.send_report(b'\0' * 16) except ValueError: print("found device but could not send report") continue self._keyboard_device = device break else: raise IOError("Could not find an HID keyboard device.") # report[0] modifiers # report[1:16] regular key presses bitmask self.report = bytearray(16) self.report_modifier = memoryview(self.report)[0:1] self.report_keys = memoryview(self.report)[1:] def _add_keycode_to_report(self, keycode): modifier = Keycode.modifier_bit(keycode) print (f"{keycode:02x} {modifier:02x}") if modifier: # Set bit for this modifier. self.report_modifier[0] |= modifier else: self.report_keys[keycode >> 3] |= 1 << (keycode & 0x7) def _remove_keycode_from_report(self, keycode): modifier = Keycode.modifier_bit(keycode) if modifier: # Set bit for this modifier. self.report_modifier[0] &= ~modifier else: self.report_keys[keycode >> 3] &= ~(1 << (keycode & 0x7)) def release_all(self): for i in range(len(self.report)): self.report[i] = 0 self._keyboard_device.send_report(self.report)
Entry first conceived on 10 July 2021, 19:12 UTC, last modified on 25 September 2021, 15:58 UTC
Website Copyright © 2004-2024 Jeff Epler