add find_boot_keyboard function and example

This commit is contained in:
foamyguy 2025-04-23 14:36:25 -05:00
parent 71816deb14
commit 21ab387adb
2 changed files with 75 additions and 8 deletions

View file

@ -14,6 +14,11 @@ import struct
from micropython import const
try:
from typing import Literal
except ImportError:
pass
__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_USB_Host_Descriptors.git"
@ -39,6 +44,7 @@ DESC_ENDPOINT = 0x05
INTERFACE_HID = 0x03
SUBCLASS_BOOT = 0x01
PROTOCOL_MOUSE = 0x02
PROTOCOL_KEYBOARD = 0x01
def get_descriptor(device, desc_type, index, buf, language_id=0):
@ -77,13 +83,7 @@ def get_configuration_descriptor(device, index):
return full_buf
def find_boot_mouse_endpoint(device):
"""
Try to find a boot mouse endpoint in the device and return its
interface index, and endpoint address.
:param device: The device to search within
:return: mouse_interface_index, mouse_endpoint_address if found, or None, None otherwise
"""
def _find_boot_endpoint(device, protocol_type: Literal[PROTOCOL_MOUSE, PROTOCOL_KEYBOARD]):
config_descriptor = get_configuration_descriptor(device, 0)
i = 0
mouse_interface_index = None
@ -99,7 +99,7 @@ def find_boot_mouse_endpoint(device):
if (
interface_class == INTERFACE_HID
and interface_subclass == SUBCLASS_BOOT
and interface_protocol == PROTOCOL_MOUSE
and interface_protocol == protocol_type
):
found_mouse = True
mouse_interface_index = interface_number
@ -111,3 +111,23 @@ def find_boot_mouse_endpoint(device):
return mouse_interface_index, endpoint_address
i += descriptor_len
return None, None
def find_boot_mouse_endpoint(device):
"""
Try to find a boot mouse endpoint in the device and return its
interface index, and endpoint address.
:param device: The device to search within
:return: mouse_interface_index, mouse_endpoint_address if found, or None, None otherwise
"""
return _find_boot_endpoint(device, PROTOCOL_MOUSE)
def find_boot_keyboard_endpoint(device):
"""
Try to find a boot keyboard endpoint in the device and return its
interface index, and endpoint address.
:param device: The device to search within
:return: keyboard_interface_index, keyboard_endpoint_address if found, or None, None otherwise
"""
return _find_boot_endpoint(device, PROTOCOL_KEYBOARD)

View file

@ -0,0 +1,47 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import array
import usb
import adafruit_usb_host_descriptors
# lists for mouse interface indexes, endpoint addresses, and USB Device instances
# each of these will end up with length 2 once we find both mice
mouse_interface_indexes = None
mouse_endpoint_addresses = None
keyboard = None
# scan for connected USB devices
for device in usb.core.find(find_all=True):
# check for boot mouse endpoints on this device
kbd_interface_index, kbd_endpoint_address = (
adafruit_usb_host_descriptors.find_boot_keyboard_endpoint(device)
)
# if a boot mouse interface index and endpoint address were found
if kbd_interface_index is not None and kbd_interface_index is not None:
keyboard = device
# detach device from kernel if needed
if keyboard.is_kernel_driver_active(0):
keyboard.detach_kernel_driver(0)
# set the mouse configuration so it can be used
keyboard.set_configuration()
buf = array.array("b", [0] * 8)
while True:
# try to read data from the mouse
try:
count = keyboard.read(mouse_endpoint_addresses, buf, timeout=10)
# if there is no data it will raise USBTimeoutError
except usb.core.USBTimeoutError:
# Nothing to do if there is no data for this mouse
continue
for b in buf:
print(hex(b), end=" ")
print()