Skip to content

Commit 3765d04

Browse files
committed
usbd: Add hid keypad example from @turmoni .
As contributed in projectgus#1 commit 5c51a9e This version of the hidkeypad module depends on some other code changes from the linked PR that aren't included here, so it won't work here yet.
1 parent 92711ea commit 3765d04

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

micropython/usbd/hidkeypad.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# MicroPython USB keypad module
2+
# MIT license; Copyright (c) 2023 Dave Wickham
3+
4+
from .hid import HIDInterface
5+
from .keycodes import KEYPAD_KEYS_TO_KEYCODES
6+
from .utils import STAGE_SETUP, split_bmRequestType
7+
from micropython import const
8+
import micropython
9+
10+
_INTERFACE_PROTOCOL_KEYBOARD = const(0x01)
11+
_REQ_CONTROL_SET_REPORT = const(0x09)
12+
_REQ_CONTROL_SET_IDLE = const(0x0A)
13+
14+
# fmt: off
15+
_KEYPAD_REPORT_DESC = bytes(
16+
[
17+
0x05, 0x01, # Usage Page (Generic Desktop)
18+
0x09, 0x07, # Usage (Keypad)
19+
0xA1, 0x01, # Collection (Application)
20+
0x05, 0x07, # Usage Page (Keypad)
21+
0x19, 0x00, # Usage Minimum (00),
22+
0x29, 0xFF, # Usage Maximum (ff),
23+
0x15, 0x00, # Logical Minimum (0),
24+
0x25, 0xFF, # Logical Maximum (ff),
25+
0x95, 0x01, # Report Count (1),
26+
0x75, 0x08, # Report Size (8),
27+
0x81, 0x00, # Input (Data, Array, Absolute)
28+
0x05, 0x08, # Usage page (LEDs)
29+
0x19, 0x01, # Usage minimum (1)
30+
0x29, 0x05, # Usage Maximum (5),
31+
0x95, 0x05, # Report Count (5),
32+
0x75, 0x01, # Report Size (1),
33+
0x91, 0x02, # Output (Data, Variable, Absolute)
34+
0x95, 0x01, # Report Count (1),
35+
0x75, 0x03, # Report Size (3),
36+
0x91, 0x01, # Output (Constant)
37+
0xC0, # End Collection
38+
]
39+
)
40+
# fmt: on
41+
42+
43+
class KeypadInterface(HIDInterface):
44+
# Very basic synchronous USB keypad HID interface
45+
46+
def __init__(self):
47+
self.numlock = None
48+
self.capslock = None
49+
self.scrolllock = None
50+
self.compose = None
51+
self.kana = None
52+
self.set_report_initialised = False
53+
super().__init__(
54+
_KEYPAD_REPORT_DESC,
55+
protocol=_INTERFACE_PROTOCOL_KEYBOARD,
56+
interface_str="MicroPython Keypad!",
57+
use_out_ep=True,
58+
)
59+
60+
def handle_interface_control_xfer(self, stage, request):
61+
if request[1] == _REQ_CONTROL_SET_IDLE and not self.set_report_initialised:
62+
# Hacky initialisation goes here
63+
self.set_report()
64+
self.set_report_initialised = True
65+
66+
if stage == STAGE_SETUP:
67+
return super().handle_interface_control_xfer(stage, request)
68+
69+
bmRequestType, bRequest, wValue, _, _ = request
70+
recipient, req_type, _ = split_bmRequestType(bmRequestType)
71+
72+
return True
73+
74+
def set_report(self, args=None):
75+
self.out_buffer = bytearray(1)
76+
self.submit_xfer(self._out_ep, self.out_buffer, self.set_report_cb)
77+
return True
78+
79+
def set_report_cb(self, ep_addr, result, xferred_bytes):
80+
buf_result = int(self.out_buffer[0])
81+
self.numlock = buf_result & 1
82+
self.capslock = (buf_result >> 1) & 1
83+
self.scrolllock = (buf_result >> 2) & 1
84+
self.compose = (buf_result >> 3) & 1
85+
self.kana = (buf_result >> 4) & 1
86+
87+
micropython.schedule(self.set_report, None)
88+
89+
def send_report(self, key=None):
90+
if key is None:
91+
super().send_report(bytes(1))
92+
else:
93+
super().send_report(KEYPAD_KEYS_TO_KEYCODES[key].to_bytes(1, "big"))

micropython/usbd/keycodes.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Keypad keycodes for use with USB HID
2+
# MIT license; Copyright (c) 2023 Dave Wickham
3+
_KEYPAD_KEYS = [
4+
"<NumLock>",
5+
"/",
6+
"*",
7+
"-",
8+
"+",
9+
"<Enter>",
10+
"1",
11+
"2",
12+
"3",
13+
"4",
14+
"5",
15+
"6",
16+
"7",
17+
"8",
18+
"9",
19+
"0",
20+
".",
21+
]
22+
23+
KEYPAD_KEYCODES_TO_KEYS = {k + 0x53: v for k, v in enumerate(_KEYPAD_KEYS)}
24+
KEYPAD_KEYS_TO_KEYCODES = {v: k for k, v in KEYPAD_KEYCODES_TO_KEYS.items()}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy