From 942c80cbd053c863720887437b36684be4dc0b4f Mon Sep 17 00:00:00 2001 From: HLammers <62934625+HLammers@users.noreply.github.com> Date: Sat, 5 Jul 2025 11:49:36 +0200 Subject: [PATCH 1/3] Update core.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⦁ Removed `import time` (not used) ⦁ Removed unused/duplicate `_Device.config` argument `config_str` ⦁ Fixed the loop reserving other string indexes used by built-in drivers `while len(strs) < builtin_driver.str_max:` to `while len(strs) < builtin\_driver.str\_max - 1:` (row 169)because str_max equals to one more than the highest string descriptor index value used by any built-in descriptor according to the [docs](https://docs.micropython.org/en/latest/library/machine.USBDevice.html) and added a comment that this loop is probably unnecessary or even wrong ⦁ Added `bAlternateSetting` as argument to `Descriptor.interface`, because it is used for USB MIDI 2.0 ⦁ Some code optimisations --- micropython/usb/usb-device/usb/device/core.py | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/micropython/usb/usb-device/usb/device/core.py b/micropython/usb/usb-device/usb/device/core.py index 7be09ee46..3dfae98d2 100644 --- a/micropython/usb/usb-device/usb/device/core.py +++ b/micropython/usb/usb-device/usb/device/core.py @@ -3,10 +3,11 @@ # These contain the classes and utilities that are needed to # implement a USB device, not any complete USB drivers. # -# MIT license; Copyright (c) 2022-2024 Angus Gratton +# MIT license; Copyright (c) 2022-2024 Angus Gratton, 2025 Harm Lammers from micropython import const import machine import struct +import time try: from _thread import get_ident @@ -108,7 +109,6 @@ def config( # noqa: PLR0913 device_class=0, device_subclass=0, device_protocol=0, - config_str=None, max_power_ma=None, remote_wakeup=False, ): @@ -166,7 +166,9 @@ def maybe_set(value, idx): # Keep track of the interface and endpoint indexes itf_num = builtin_driver.itf_max ep_num = max(builtin_driver.ep_max, 1) # Endpoint 0 always reserved for control - while len(strs) < builtin_driver.str_max: + while len(strs) < builtin_driver.str_max - 1: # This is possibly unnecessary or wrong because + # https://docs.micropython.org/en/latest/library/machine.USBDevice.html + # states all string values except index 0 should be plain ASCII strs.append(None) # Reserve other string indexes used by builtin drivers initial_cfg = builtin_driver.desc_cfg or (b"\x00" * _STD_DESC_CONFIG_LEN) @@ -204,10 +206,11 @@ def maybe_set(value, idx): ) # Configuration string is optional but supported - iConfiguration = 0 if configuration_str: iConfiguration = len(strs) strs.append(configuration_str) + else: + iConfiguration = 0 if max_power_ma is not None: # Convert from mA to the units used in the descriptor @@ -665,6 +668,7 @@ def interface( bInterfaceSubClass=_INTERFACE_SUBCLASS_NONE, bInterfaceProtocol=_PROTOCOL_NONE, iInterface=0, + bAlternateSetting=0, ): # Utility function to append a standard Interface descriptor, with # the properties specified in the parameter list. @@ -680,7 +684,7 @@ def interface( _STD_DESC_INTERFACE_LEN, # bLength _STD_DESC_INTERFACE_TYPE, # bDescriptorType bInterfaceNumber, - 0, # bAlternateSetting, not currently supported + bAlternateSetting, bNumEndpoints, bInterfaceClass, bInterfaceSubClass, @@ -791,17 +795,18 @@ class Buffer: # approximate a Python-based single byte ringbuffer. # def __init__(self, length): + self._l = length self._b = memoryview(bytearray(length)) - # number of bytes in buffer read to read, starting at index 0. Updated + # number of bytes in buffer ready to read, starting at index 0. Updated # by both producer & consumer. self._n = 0 - # start index of a pending write into the buffer, if any. equals + # start index of a pending write into the buffer, if any. Equals # len(self._b) if no write is pending. Updated by producer only. self._w = length def writable(self): # Number of writable bytes in the buffer. Assumes no pending write is outstanding. - return len(self._b) - self._n + return self._l - self._n def readable(self): # Number of readable bytes in the buffer. Assumes no pending read is outstanding. @@ -815,16 +820,16 @@ def pend_write(self, wmax=None): # this many bytes long. # # (No critical section needed as self._w is only updated by the producer.) - self._w = self._n - end = (self._w + wmax) if wmax else len(self._b) - return self._b[self._w : end] + self._w = (_w := self._n) + end = (_w + wmax) if wmax else self._l + return self._b[_w : end] def finish_write(self, nbytes): # Called by the producer to indicate it wrote nbytes into the buffer. ist = machine.disable_irq() try: - assert nbytes <= len(self._b) - self._w # can't say we wrote more than was pended - if self._n == self._w: + assert nbytes <= self._l - (_w := self._w) # can't say we wrote more than was pended + if self._n == _w: # no data was read while the write was happening, so the buffer is already in place # (this is the fast path) self._n += nbytes @@ -834,13 +839,14 @@ def finish_write(self, nbytes): # # As this updates self._n we have to do it in the critical # section, so do it byte by byte to avoid allocating. + _b = self._b while nbytes > 0: - self._b[self._n] = self._b[self._w] + _b[self._n] = _b[self._w] self._n += 1 self._w += 1 nbytes -= 1 - self._w = len(self._b) + self._w = self._l finally: machine.enable_irq(ist) @@ -866,10 +872,11 @@ def finish_read(self, nbytes): assert nbytes <= self._n # can't say we read more than was available i = 0 self._n -= nbytes + _b = self._b while i < self._n: # consumer only read part of the buffer, so shuffle remaining # read data back towards index 0 to avoid fragmentation - self._b[i] = self._b[i + nbytes] + _b[i] = _b[i + nbytes] i += 1 finally: machine.enable_irq(ist) @@ -881,4 +888,4 @@ def readinto(self, b): if to_r: b[:to_r] = pr[:to_r] self.finish_read(to_r) - return to_r + return to_r \ No newline at end of file From befd307535c734f7127ebad861c611b5a1b36055 Mon Sep 17 00:00:00 2001 From: HLammers <62934625+HLammers@users.noreply.github.com> Date: Sat, 5 Jul 2025 14:11:19 +0200 Subject: [PATCH 2/3] Update core.py Update fromatting --- micropython/usb/usb-device/usb/device/core.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/micropython/usb/usb-device/usb/device/core.py b/micropython/usb/usb-device/usb/device/core.py index 3dfae98d2..9e1ba1742 100644 --- a/micropython/usb/usb-device/usb/device/core.py +++ b/micropython/usb/usb-device/usb/device/core.py @@ -166,7 +166,9 @@ def maybe_set(value, idx): # Keep track of the interface and endpoint indexes itf_num = builtin_driver.itf_max ep_num = max(builtin_driver.ep_max, 1) # Endpoint 0 always reserved for control - while len(strs) < builtin_driver.str_max - 1: # This is possibly unnecessary or wrong because + while ( + len(strs) < builtin_driver.str_max - 1 + ): # This is possibly unnecessary or wrong because # https://docs.micropython.org/en/latest/library/machine.USBDevice.html # states all string values except index 0 should be plain ASCII strs.append(None) # Reserve other string indexes used by builtin drivers @@ -822,7 +824,7 @@ def pend_write(self, wmax=None): # (No critical section needed as self._w is only updated by the producer.) self._w = (_w := self._n) end = (_w + wmax) if wmax else self._l - return self._b[_w : end] + return self._b[_w:end] def finish_write(self, nbytes): # Called by the producer to indicate it wrote nbytes into the buffer. @@ -888,4 +890,4 @@ def readinto(self, b): if to_r: b[:to_r] = pr[:to_r] self.finish_read(to_r) - return to_r \ No newline at end of file + return to_r From 7424b120b5092b88f6b50bd97fea6f841749071c Mon Sep 17 00:00:00 2001 From: HLammers <62934625+HLammers@users.noreply.github.com> Date: Sat, 5 Jul 2025 14:33:41 +0200 Subject: [PATCH 3/3] Moved assignment out of assert statement --- micropython/usb/usb-device/usb/device/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/micropython/usb/usb-device/usb/device/core.py b/micropython/usb/usb-device/usb/device/core.py index 9e1ba1742..a3e603d73 100644 --- a/micropython/usb/usb-device/usb/device/core.py +++ b/micropython/usb/usb-device/usb/device/core.py @@ -830,8 +830,8 @@ def finish_write(self, nbytes): # Called by the producer to indicate it wrote nbytes into the buffer. ist = machine.disable_irq() try: - assert nbytes <= self._l - (_w := self._w) # can't say we wrote more than was pended - if self._n == _w: + assert nbytes <= self._l - self._w # can't say we wrote more than was pended + if self._n == self._w: # no data was read while the write was happening, so the buffer is already in place # (this is the fast path) self._n += nbytes
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: