diff --git a/README.rst b/README.rst index 2091ba3..10bf37c 100644 --- a/README.rst +++ b/README.rst @@ -23,12 +23,11 @@ Introduction Helpers for getting USB descriptors - Dependencies ============= This driver depends on: -* `Adafruit CircuitPython `_ +* `Adafruit CircuitPython 9+ `_ Please ensure all dependencies are available on the CircuitPython filesystem. This is easily achieved by downloading @@ -36,19 +35,8 @@ This is easily achieved by downloading or individual libraries can be installed using `circup `_. - - -.. todo:: Describe the Adafruit product this library works with. For PCBs, you can also add the -image from the assets folder in the PCB's GitHub repo. - -`Purchase one from the Adafruit shop `_ - Installing from PyPI ===================== -.. note:: This library is not available on PyPI yet. Install documentation is included - as a standard element. Stay tuned for PyPI availability! - -.. todo:: Remove the above note if PyPI version is/will be available at time of release. On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally `from PyPI `_. @@ -99,8 +87,59 @@ Or the following command to update an existing version: Usage Example ============= -.. todo:: Add a quick, simple example. It and other examples should live in the -examples folder and be included in docs/examples.rst. +Print basic information about a device and its first (and usually only) configuration. + +.. code-block:: python + + # SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries + # SPDX-FileCopyrightText: Copyright (c) 2023 Scott Shawcroft for Adafruit Industries + # + # SPDX-License-Identifier: Unlicense + + import time + import usb.core + + import adafruit_usb_host_descriptors + + DIR_IN = 0x80 + + while True: + print("searching for devices") + for device in usb.core.find(find_all=True): + print("pid", hex(device.idProduct)) + print("vid", hex(device.idVendor)) + print("man", device.manufacturer) + print("product", device.product) + print("serial", device.serial_number) + print("config[0]:") + config_descriptor = adafruit_usb_host_descriptors.get_configuration_descriptor( + device, 0 + ) + + i = 0 + while i < len(config_descriptor): + descriptor_len = config_descriptor[i] + descriptor_type = config_descriptor[i + 1] + if descriptor_type == adafruit_usb_host_descriptors.DESC_CONFIGURATION: + config_value = config_descriptor[i + 5] + print(f" value {config_value:d}") + elif descriptor_type == adafruit_usb_host_descriptors.DESC_INTERFACE: + interface_number = config_descriptor[i + 2] + interface_class = config_descriptor[i + 5] + interface_subclass = config_descriptor[i + 6] + print(f" interface[{interface_number:d}]") + print( + f" class {interface_class:02x} subclass {interface_subclass:02x}" + ) + elif descriptor_type == adafruit_usb_host_descriptors.DESC_ENDPOINT: + endpoint_address = config_descriptor[i + 2] + if endpoint_address & DIR_IN: + print(f" IN {endpoint_address:02x}") + else: + print(f" OUT {endpoint_address:02x}") + i += descriptor_len + print() + time.sleep(5) Documentation ============= diff --git a/adafruit_usb_host_descriptors.py b/adafruit_usb_host_descriptors.py index c59d21f..bcf2845 100644 --- a/adafruit_usb_host_descriptors.py +++ b/adafruit_usb_host_descriptors.py @@ -35,19 +35,35 @@ DESC_INTERFACE = 0x04 DESC_ENDPOINT = 0x05 + def get_descriptor(device, desc_type, index, buf, language_id=0): + """Fetch the descriptor from the device into buf.""" + # Allow capitalization that matches the USB spec. + # pylint: disable=invalid-name wValue = desc_type << 8 | index wIndex = language_id - device.ctrl_transfer(_REQ_RCPT_DEVICE | _REQ_TYPE_STANDARD | _DIR_IN, _REQ_GET_DESCRIPTOR, wValue, wIndex, buf) + device.ctrl_transfer( + _REQ_RCPT_DEVICE | _REQ_TYPE_STANDARD | _DIR_IN, + _REQ_GET_DESCRIPTOR, + wValue, + wIndex, + buf, + ) + def get_device_descriptor(device): + """Fetch the device descriptor and return it.""" buf = bytearray(1) get_descriptor(device, DESC_DEVICE, 0, buf) full_buf = bytearray(buf[0]) get_descriptor(device, DESC_DEVICE, 0, full_buf) return full_buf + def get_configuration_descriptor(device, index): + """Fetch the configuration descriptor, its associated descriptors and return it.""" + # Allow capitalization that matches the USB spec. + # pylint: disable=invalid-name buf = bytearray(4) get_descriptor(device, DESC_CONFIGURATION, index, buf) wTotalLength = struct.unpack(" .. toctree:: :caption: Other Links diff --git a/examples/usb_host_descriptors_simpletest.py b/examples/usb_host_descriptors_simpletest.py index ebb5a66..9d3765f 100644 --- a/examples/usb_host_descriptors_simpletest.py +++ b/examples/usb_host_descriptors_simpletest.py @@ -2,3 +2,48 @@ # SPDX-FileCopyrightText: Copyright (c) 2023 Scott Shawcroft for Adafruit Industries # # SPDX-License-Identifier: Unlicense + +import time +import usb.core + +import adafruit_usb_host_descriptors + +DIR_IN = 0x80 + +while True: + print("searching for devices") + for device in usb.core.find(find_all=True): + print("pid", hex(device.idProduct)) + print("vid", hex(device.idVendor)) + print("man", device.manufacturer) + print("product", device.product) + print("serial", device.serial_number) + print("config[0]:") + config_descriptor = adafruit_usb_host_descriptors.get_configuration_descriptor( + device, 0 + ) + + i = 0 + while i < len(config_descriptor): + descriptor_len = config_descriptor[i] + descriptor_type = config_descriptor[i + 1] + if descriptor_type == adafruit_usb_host_descriptors.DESC_CONFIGURATION: + config_value = config_descriptor[i + 5] + print(f" value {config_value:d}") + elif descriptor_type == adafruit_usb_host_descriptors.DESC_INTERFACE: + interface_number = config_descriptor[i + 2] + interface_class = config_descriptor[i + 5] + interface_subclass = config_descriptor[i + 6] + print(f" interface[{interface_number:d}]") + print( + f" class {interface_class:02x} subclass {interface_subclass:02x}" + ) + elif descriptor_type == adafruit_usb_host_descriptors.DESC_ENDPOINT: + endpoint_address = config_descriptor[i + 2] + if endpoint_address & DIR_IN: + print(f" IN {endpoint_address:02x}") + else: + print(f" OUT {endpoint_address:02x}") + i += descriptor_len + print() + time.sleep(5)