Skip to content

shared/tinyusb, extmod: Add runtime USB class selection.#19103

Open
andrewleech wants to merge 9 commits into
micropython:masterfrom
andrewleech:usbd-runtime-class
Open

shared/tinyusb, extmod: Add runtime USB class selection.#19103
andrewleech wants to merge 9 commits into
micropython:masterfrom
andrewleech:usbd-runtime-class

Conversation

@andrewleech

@andrewleech andrewleech commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Depends on #16459 (NCM driver). The first 8 commits in this branch are from that PR and will drop out once it merges.

Summary

Adds BUILTIN_FLAG_CDC, BUILTIN_FLAG_MSC, and BUILTIN_FLAG_NCM constants to machine.USBDevice so boot.py can select which built-in USB classes are active at runtime. Previously the only options were BUILTIN_NONE (disable all builtins) or BUILTIN_DEFAULT (CDC only), with no way to enable NCM or MSC alongside CDC without writing a full runtime USB driver in Python.

Assigning a flag mask to builtin_driver builds a dynamic configuration descriptor containing only the selected classes, with interface/endpoint/string numbers compacted to remove gaps. The USB PID is varied per combination so the host re-enumerates correctly when classes change.

BUILTIN_DEFAULT is now CDC-only rather than all compiled-in classes. This keeps the default USB footprint minimal and lets boot.py opt into heavier classes like NCM.

Example boot.py:

import machine
usb = machine.USBDevice()
usb.builtin_driver = (
    machine.USBDevice.BUILTIN_FLAG_CDC
    | machine.USBDevice.BUILTIN_FLAG_NCM
)

Testing

Tested on NUCLEO_WB55 (stm32) with CDC+NCM and CDC-only configurations. Verified USB re-enumeration on class change, descriptor correctness with lsusb -v, and NCM data path with ping.

Generative AI

I used generative AI tools when creating this PR, but a human has checked the
code and is responsible for the code and the description above.

@github-actions

github-actions Bot commented Apr 14, 2026

Copy link
Copy Markdown

Code size report:

Reference:  tests/ports/unix: Add gc_info_fast test. [936596c]
Comparison: docs/library: Document builtin_driver flag constants. [merge of 08590ca]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
      esp32:    +0 +0.000% ESP32_GENERIC
     mimxrt:    +0 +0.000% TEENSY40
        rp2: +14264 +1.548% RPI_PICO_W[incl +10552(bss)]
       samd:  +504 +0.182% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@codecov

codecov Bot commented Apr 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.47%. Comparing base (936596c) to head (08590ca).

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #19103   +/-   ##
=======================================
  Coverage   98.47%   98.47%           
=======================================
  Files         176      176           
  Lines       22845    22845           
=======================================
  Hits        22497    22497           
  Misses        348      348           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@andrewleech andrewleech force-pushed the usbd-runtime-class branch 2 times, most recently from 82a6938 to f25a7bb Compare April 15, 2026 02:54
@dpgeorge dpgeorge added the shared Relates to shared/ directory in source label May 6, 2026
pi-anl added 9 commits May 12, 2026 15:25
When false, the DHCP server omits the Router option from DHCP
responses. This prevents point-to-point links (like USB NCM) from
advertising a default gateway that hijacks the host's internet route.

Defaults to true for backward compatibility with CYW43 AP mode.

Signed-off-by: Andrew Leech <[email protected]>
lwIP's own opt.h defaults LWIP_IPV6 to 0, so the explicit
hardcoded define here was redundant and prevented overriding
the value from elsewhere.

Signed-off-by: Andrew Leech <[email protected]>
Adds TinyUSB configuration and descriptor support for USB Network
Control Model (NCM) interface. This provides the low-level USB
infrastructure needed for USB networking.

Signed-off-by: Andrew Leech <[email protected]>
Implements a complete USB Network Control Model (NCM) driver that
provides ethernet-over-USB functionality integrated with lwIP stack.

Features:
- Link-local IP address generation from MAC using CRC32
- DHCP server integration with connect callbacks
- Full lwIP network interface with IPv6 support
- USB NCM protocol handling via TinyUSB
- Python network.USB_NET class interface

Signed-off-by: Andrew Leech <[email protected]>
Automatically enable MICROPY_HW_NETWORK_USBNET when MICROPY_PY_LWIP
is enabled, following the same pattern as WEBSOCKET and WEBREPL.

This makes USB networking available by default on boards that support
both USB device mode and LWIP networking, while still allowing boards
to explicitly disable it by setting MICROPY_HW_NETWORK_USBNET=0.

Also fixes USB NCM build issues when LWIP is enabled for ethernet by
making MICROPY_HW_NETWORK_USBNET conditional on both LWIP and TinyUSB.

Signed-off-by: Andrew Leech <[email protected]>
Add builtin_driver flag constants (BUILTIN_FLAG_CDC, BUILTIN_FLAG_MSC,
BUILTIN_FLAG_NCM) that can be OR'd together to select USB classes at
runtime from boot.py. A dynamic configuration descriptor is built
containing only the selected classes with compact interface/endpoint
numbering.

Signed-off-by: Andrew Leech <[email protected]>
@andrewleech andrewleech force-pushed the usbd-runtime-class branch from f25a7bb to 08590ca Compare May 12, 2026 05:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

shared Relates to shared/ directory in source

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants