Skip to content

Commit ed38937

Browse files
authored
Merge pull request #7 from FoamyGuy/find_boot_keyboard
add find_boot_keyboard function and example
2 parents 71816de + e547a73 commit ed38937

File tree

2 files changed

+73
-8
lines changed

2 files changed

+73
-8
lines changed

adafruit_usb_host_descriptors.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414

1515
from micropython import const
1616

17+
try:
18+
from typing import Literal
19+
except ImportError:
20+
pass
21+
1722
__version__ = "0.0.0+auto.0"
1823
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_USB_Host_Descriptors.git"
1924

@@ -39,6 +44,7 @@
3944
INTERFACE_HID = 0x03
4045
SUBCLASS_BOOT = 0x01
4146
PROTOCOL_MOUSE = 0x02
47+
PROTOCOL_KEYBOARD = 0x01
4248

4349

4450
def get_descriptor(device, desc_type, index, buf, language_id=0):
@@ -77,13 +83,7 @@ def get_configuration_descriptor(device, index):
7783
return full_buf
7884

7985

80-
def find_boot_mouse_endpoint(device):
81-
"""
82-
Try to find a boot mouse endpoint in the device and return its
83-
interface index, and endpoint address.
84-
:param device: The device to search within
85-
:return: mouse_interface_index, mouse_endpoint_address if found, or None, None otherwise
86-
"""
86+
def _find_boot_endpoint(device, protocol_type: Literal[PROTOCOL_MOUSE, PROTOCOL_KEYBOARD]):
8787
config_descriptor = get_configuration_descriptor(device, 0)
8888
i = 0
8989
mouse_interface_index = None
@@ -99,7 +99,7 @@ def find_boot_mouse_endpoint(device):
9999
if (
100100
interface_class == INTERFACE_HID
101101
and interface_subclass == SUBCLASS_BOOT
102-
and interface_protocol == PROTOCOL_MOUSE
102+
and interface_protocol == protocol_type
103103
):
104104
found_mouse = True
105105
mouse_interface_index = interface_number
@@ -111,3 +111,23 @@ def find_boot_mouse_endpoint(device):
111111
return mouse_interface_index, endpoint_address
112112
i += descriptor_len
113113
return None, None
114+
115+
116+
def find_boot_mouse_endpoint(device):
117+
"""
118+
Try to find a boot mouse endpoint in the device and return its
119+
interface index, and endpoint address.
120+
:param device: The device to search within
121+
:return: mouse_interface_index, mouse_endpoint_address if found, or None, None otherwise
122+
"""
123+
return _find_boot_endpoint(device, PROTOCOL_MOUSE)
124+
125+
126+
def find_boot_keyboard_endpoint(device):
127+
"""
128+
Try to find a boot keyboard endpoint in the device and return its
129+
interface index, and endpoint address.
130+
:param device: The device to search within
131+
:return: keyboard_interface_index, keyboard_endpoint_address if found, or None, None otherwise
132+
"""
133+
return _find_boot_endpoint(device, PROTOCOL_KEYBOARD)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
import array
5+
6+
import usb
7+
8+
import adafruit_usb_host_descriptors
9+
10+
keyboard_interface_index = None
11+
keyboard_endpoint_address = None
12+
keyboard = None
13+
14+
# scan for connected USB devices
15+
for device in usb.core.find(find_all=True):
16+
# check for boot keyboard endpoints on this device
17+
keyboard_interface_index, keyboard_endpoint_address = (
18+
adafruit_usb_host_descriptors.find_boot_keyboard_endpoint(device)
19+
)
20+
# if a boot keyboard interface index and endpoint address were found
21+
if keyboard_interface_index is not None and keyboard_endpoint_address is not None:
22+
keyboard = device
23+
24+
# detach device from kernel if needed
25+
if keyboard.is_kernel_driver_active(0):
26+
keyboard.detach_kernel_driver(0)
27+
28+
# set the configuration so the keyboard can be used
29+
keyboard.set_configuration()
30+
31+
buf = array.array("b", [0] * 8)
32+
33+
while True:
34+
# try to read data from the keyboard
35+
try:
36+
count = keyboard.read(keyboard_endpoint_address, buf, timeout=10)
37+
38+
# if there is no data it will raise USBTimeoutError
39+
except usb.core.USBTimeoutError:
40+
# Nothing to do if there is no data for this keyboard
41+
continue
42+
43+
for b in buf:
44+
print(hex(b), end=" ")
45+
print()

0 commit comments

Comments
 (0)