Skip to content

Conversation

@dlech
Copy link
Member

@dlech dlech commented Jul 21, 2025

While working on USB, I finally figured out some of the things that were making Chromium not happy about the WebUSB BOS descriptor that we couldn't figure out before.

In addition to that, we were using BOS descriptors for Pybricks Profile characteristics, but that wasn't really a good fit. So I changed how we handle those. Now, characteristics can be read individually by requesting class data from the Pybricks interface. This allows them to be read one at a time and would allow for values to change dynamically at runtime if needed in the future.

Also, I've reworked the NxOS USB descriptors to the Pybricks ones so that it matches what was done for SPIKE hubs. This driver then gets moved to pbiod/drv/usb. But Pybricks interface endpoint reads and writes aren't handled yet, so no download and run on NXT yet.

I didn't touch the EV3 stuff since that is a work in progress in #340. After that is done, we should be able to pull out a common pbsys_usb and descriptor definitions that can be shared by all 3 drivers.

The main change here is switching from using BOS descriptors to using
interface/class-specific descriptors for the equivalent of reading BLE
GATT characteristics over USB. BOS are really meant for operating system
capabilities, not application-level protocols.

Instead, we now have interface/class-specific responses to control
requests that allow reading each characteristic individually. Since the
wValue parameter is 16 bits, it is natural to use the BLE 16-bit UUIDs
for this purpose. To avoid potential clashes, we also use bRequest to
sort these by groups. For now, there is one for standard BLE 16-bit
UUIDs and one for Pybricks-defined 16-bit UUIDs.

Now, all remaining BOS descriptor info is known at compile time, so we
no longer need to fill it in at runtime.

There are also some fixes to make the BOS descriptors work correctly
with Chromium-based browsers. Chromium seems to be a bugging and expects
the WebUSB descriptor to be the first device capability and the Microsoft
OS 2.0 descriptor to be the last device capability. Otherwise, it doesn't
seem to parse them correctly.

Also, we had the bcdUSB incorrectly set to 2.0.1 instead of 2.1.0.
@coveralls
Copy link

coveralls commented Jul 21, 2025

Coverage Status

coverage: 57.466%. remained the same
when pulling 334d08d on dlech:nxt-usb
into fdb0e68 on pybricks:master.

dlech added 4 commits July 20, 2025 20:21
Replace use of MIN macro with explicit comparisons. We are removing
the defines for these, so we can't depend on them anymore.
Drop the MIN/MAX macros from the contiki includes. These can conflict
with other definitions, and are not used in the code.
NxOS had it's own USB configuration. Replace it with the Pybricks USB
configuration so that we can use the Pybricks USB protocol.

This also fixes not setting bit 7 of bmAttributes.
We have adapted the NxOS USB driver for Pybricks, so now we can move it
to the common pbio/drv/usb directory.

While moving, the code style is automatically formatted and pbio naming
conventions are applied.
@dlech dlech merged commit 259b1c8 into pybricks:master Jul 22, 2025
17 checks passed
@dlech dlech deleted the nxt-usb branch July 22, 2025 20:20
@laurensvalk
Copy link
Member

Amazing, great work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants