USB NKRO example for MacroPad
This commit is contained in:
parent
2562c2c3e7
commit
cfbdf71056
2 changed files with 135 additions and 0 deletions
57
CircuitPython_MacroPad_NKRO/boot.py
Normal file
57
CircuitPython_MacroPad_NKRO/boot.py
Normal 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")
|
||||||
78
CircuitPython_MacroPad_NKRO/code.py
Normal file
78
CircuitPython_MacroPad_NKRO/code.py
Normal 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)
|
||||||
Loading…
Reference in a new issue