USB NKRO example for MacroPad

This commit is contained in:
Jeff Epler 2021-07-20 10:45:42 -05:00 committed by Jeff Epler
parent 2562c2c3e7
commit cfbdf71056
2 changed files with 135 additions and 0 deletions

View file

@ -0,0 +1,57 @@
import usb_hid
BITMAP_KEYBOARD_DESCRIPTOR_REPORT_ID = 7
REPORT_BYTES = 16
bitmap_keyboard_descriptor = bytes((
0x05, 0x01, # Usage Page (Generic Desktop),
0x09, 0x06, # Usage (Keyboard),
0xA1, 0x01, # Collection (Application),
0x85, 0xFF, # 6,7 Report ID [SET AT RUNTIME]
# 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_length = 16,
out_report_length = 1,
report_id_index = BITMAP_KEYBOARD_DESCRIPTOR_REPORT_ID,
)
print(bitmap_keyboard)
devices = [
bitmap_keyboard,
usb_hid.Device.CONSUMER_CONTROL,
usb_hid.Device.MOUSE,
]
usb_hid.enable(devices)
print("enabled HID with custom keyboard device")

View file

@ -0,0 +1,78 @@
import keypad
import board
import usb_hid
from adafruit_hid.keyboard import Keyboard, find_device
from adafruit_hid.keycode import Keycode
key_pins = (
board.KEY1,
board.KEY2,
board.KEY3,
board.KEY4,
board.KEY5,
board.KEY6,
board.KEY7,
board.KEY8,
board.KEY9,
board.KEY10,
board.KEY11,
board.KEY12,
)
keys = keypad.Keys(key_pins, value_when_pressed=False, pull=True)
class BitmapKeyboard(Keyboard):
def __init__(self, devices):
device = find_device(devices, usage_page=0x1, usage=0x6)
try:
device.send_report(b'\0' * 16)
except ValueError:
print("found keyboard, but it did not accept a 16-byte report. check that boot.py is installed properly")
self._keyboard_device = 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_bitmap = memoryview(self.report)[1:]
def _add_keycode_to_report(self, keycode):
modifier = Keycode.modifier_bit(keycode)
if modifier:
# Set bit for this modifier.
self.report_modifier[0] |= modifier
else:
self.report_bitmap[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_bitmap[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)
kbd = BitmapKeyboard(usb_hid.devices)
keymap = [
Keycode.ONE, Keycode.TWO, Keycode.THREE,
Keycode.Q, Keycode.W, Keycode.E,
Keycode.A, Keycode.S, Keycode.D,
Keycode.Z, Keycode.X, Keycode.C]
while True:
ev = keys.events.get()
if ev is not None:
key = keymap[ev.key_number]
if ev.pressed:
kbd.press(key)
else:
kbd.release(key)