From: Melissa LeBlanc-Williams Date: Mon, 7 Mar 2022 16:22:40 +0000 (-0800) Subject: Merge pull request #562 from fivetide/usb_hid X-Git-Tag: 7.1.1 X-Git-Url: https://git.ayoreis.com/Adafruit_Blinka-hackapet.git/commitdiff_plain/70b2c4be7ea920982168bb03fc55aa5b0563639c?hp=-c Merge pull request #562 from fivetide/usb_hid solve issues with multiple hid devices on one gadget --- 70b2c4be7ea920982168bb03fc55aa5b0563639c diff --combined src/usb_hid.py index 8286b55,cd225bf..113ac83 --- a/src/usb_hid.py +++ b/src/usb_hid.py @@@ -1,6 -1,3 +1,6 @@@ +# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries +# +# SPDX-License-Identifier: MIT """ `usb_hid` - support for usb hid devices via usb_gadget driver =========================================================== @@@ -18,7 -15,7 +18,7 @@@ import atexi import sys for module in ["dwc2", "libcomposite"]: - if Path("/proc/modules").read_text().find(module) == -1: + if Path("/proc/modules").read_text(encoding="utf-8").find(module) == -1: raise Exception( "%s module not present in your kernel. did you insmod it?" % module ) @@@ -60,7 -57,7 +60,7 @@@ class Device """ report_id = report_id or self.report_ids[0] device_path = self.get_device_path(report_id) - with open(device_path, "rb+") as fd: + with open(device_path, "rb+", encoding="utf-8") as fd: if report_id > 0: report = bytearray(report_id.to_bytes(1, "big")) + report fd.write(report) @@@ -82,7 -79,7 +82,7 @@@ Return `None` if nothing received. """ device_path = self.get_device_path(report_id or self.report_ids[0]) - with open(device_path, "rb+") as fd: + with open(device_path, "rb+", encoding="utf-8") as fd: os.set_blocking(fd.fileno(), False) report = fd.read(self.out_report_lengths[0]) if report is not None: @@@ -98,7 -95,7 +98,7 @@@ "%s/functions/hid.usb%s/dev" % (this.gadget_root, report_id or self.report_ids[0]) ) - .read_text() + .read_text(encoding="utf-8") .strip() .split(":")[1] ) @@@ -261,7 -258,7 +261,7 @@@ Device.MOUSE = Device ), usage_page=0x1, usage=0x02, - report_ids=[2], + report_ids=[0x02], in_report_lengths=[4], out_report_lengths=[0], ) @@@ -450,7 -447,7 +450,7 @@@ Device.BOOT_MOUSE = Device ), usage_page=0x1, usage=0x02, - report_ids=[1], + report_ids=[0], in_report_lengths=[4], out_report_lengths=[0], ) @@@ -465,7 -462,7 +465,7 @@@ def disable() -> None as `usb_cdc` or `storage` to free up endpoints for use by `usb_hid`. """ try: - Path("%s/UDC" % this.gadget_root).write_text("") + Path("%s/UDC" % this.gadget_root).write_text("", encoding="utf-8") except FileNotFoundError: pass for symlink in Path(this.gadget_root).glob("configs/**/hid.usb*"): @@@ -585,30 -582,18 +585,30 @@@ def enable(requested_devices: Sequence[ # """ Path("%s/functions" % this.gadget_root).mkdir(parents=True, exist_ok=True) Path("%s/configs" % this.gadget_root).mkdir(parents=True, exist_ok=True) - Path("%s/bcdDevice" % this.gadget_root).write_text("%s" % 1) # Version 1.0.0 - Path("%s/bcdUSB" % this.gadget_root).write_text("%s" % 0x0200) # USB 2.0 + Path("%s/bcdDevice" % this.gadget_root).write_text( + "%s" % 1, encoding="utf-8" + ) # Version 1.0.0 + Path("%s/bcdUSB" % this.gadget_root).write_text( + "%s" % 0x0200, encoding="utf-8" + ) # USB 2.0 Path("%s/bDeviceClass" % this.gadget_root).write_text( - "%s" % 0x00 + "%s" % 0x00, encoding="utf-8" ) # multipurpose i guess? - Path("%s/bDeviceProtocol" % this.gadget_root).write_text("%s" % 0x00) - Path("%s/bDeviceSubClass" % this.gadget_root).write_text("%s" % 0x00) - Path("%s/bMaxPacketSize0" % this.gadget_root).write_text("%s" % 0x08) + Path("%s/bDeviceProtocol" % this.gadget_root).write_text( + "%s" % 0x00, encoding="utf-8" + ) + Path("%s/bDeviceSubClass" % this.gadget_root).write_text( + "%s" % 0x00, encoding="utf-8" + ) + Path("%s/bMaxPacketSize0" % this.gadget_root).write_text( + "%s" % 0x08, encoding="utf-8" + ) Path("%s/idProduct" % this.gadget_root).write_text( - "%s" % 0x0104 + "%s" % 0x0104, encoding="utf-8" ) # Multifunction Composite Gadget - Path("%s/idVendor" % this.gadget_root).write_text("%s" % 0x1D6B) # Linux Foundation + Path("%s/idVendor" % this.gadget_root).write_text( + "%s" % 0x1D6B, encoding="utf-8" + ) # Linux Foundation # """ # 2. Creating the configurations # ------------------------------ @@@ -641,15 -626,15 +641,15 @@@ # $ echo 120 > configs/c.1/MaxPower # """ - for i, device in enumerate(requested_devices): - config_root = "%s/configs/device.%s" % (this.gadget_root, i + 1) + for device in requested_devices: + config_root = "%s/configs/device.1" % this.gadget_root Path("%s/" % config_root).mkdir(parents=True, exist_ok=True) Path("%s/strings/0x409" % config_root).mkdir(parents=True, exist_ok=True) Path("%s/strings/0x409/configuration" % config_root).write_text( - "my configuration" + "my configuration", encoding="utf-8" ) - Path("%s/MaxPower" % config_root).write_text("150") - Path("%s/bmAttributes" % config_root).write_text("%s" % 0x080) + Path("%s/MaxPower" % config_root).write_text("150", encoding="utf-8") + Path("%s/bmAttributes" % config_root).write_text("%s" % 0x080, encoding="utf-8") this.devices.append(device) # """ # 3. Creating the functions @@@ -679,13 -664,11 +679,13 @@@ Path("%s/" % function_root).mkdir(parents=True) except FileExistsError: continue - Path("%s/protocol" % function_root).write_text("%s" % report_id) + Path("%s/protocol" % function_root).write_text( + "%s" % report_id, encoding="utf-8" + ) Path("%s/report_length" % function_root).write_text( - "%s" % device.in_report_lengths[report_index] + "%s" % device.in_report_lengths[report_index], encoding="utf-8" ) - Path("%s/subclass" % function_root).write_text("%s" % 1) + Path("%s/subclass" % function_root).write_text("%s" % 1, encoding="utf-8") Path("%s/report_desc" % function_root).write_bytes(device.descriptor) # """ # 4. Associating the functions with their configurations @@@ -702,7 -685,12 +702,12 @@@ # e.g.:: # # $ ln -s functions/ncm.usb0 configs/c.1 """ - Path("%s/hid.usb%s" % (config_root, report_id)).symlink_to(function_root) + try: + Path("%s/hid.usb%s" % (config_root, report_id)).symlink_to( + function_root + ) + except FileNotFoundError: + pass # """ 5. Enabling the gadget # ---------------------- # Such a gadget must be finally enabled so that the USB host can enumerate it. @@@ -717,4 -705,4 +722,4 @@@ # # $ echo s3c-hsotg > UDC """ udc = next(Path("/sys/class/udc/").glob("*")) - Path("%s/UDC" % this.gadget_root).write_text("%s" % udc.name) + Path("%s/UDC" % this.gadget_root).write_text("%s" % udc.name, encoding="utf-8")