Skip to content

feat(usb_device): generic CDC + vendor + MSC reference example; ODrive USB example moves to odrive_native - #834

Merged
finger563 merged 3 commits into
mainfrom
feat/usb-device-reference-example
Oct 1, 2026
Merged

finger563 merged 3 commits into
mainfrom
feat/usb-device-reference-example

Conversation

@finger563

Copy link
Copy Markdown
Contributor

Summary

Two things, as requested:

1. The ODrive-compatible USB device example moves to components/odrive_native/usb_example (git mv, history preserved). It is the ODrive-specific composite device (ODrive ASCII over CDC, native / Fibre over the vendor interface, HID gamepad; VID/PID 0x1209/0x0d32), so it lives with the ODrive protocols now: same behaviour and descriptors, main source renamed to odrive_usb_example.cpp, paths fixed in its README / HARDWARE_TEST.md, its own doc page under the odrive_native component (doc/en/motor_control/odrive_usb_example.md, in that page's toctree), the odrive_native README mentions it, CI builds it for esp32s3 (component manager on, as before), Doxygen's example paths updated, and the usb_device header snippets now point at the new generic example.

2. components/usb_device/example is rewritten as the generic reference: one espp::UsbDevice with the three interface classes the component provides, plus the standard espp USB services and the dispatcher:

Interface Carries Host side
CDC-ACM the espp framed protocol via its own DispatcherWorker consoles over Web Serial, espp_* CLIs over the serial port
vendor / WebUSB (landing page = the system console) the same framed protocol via its own DispatcherWorker consoles over WebUSB, CLIs over libusb
MSC a wear-levelled FAT partition in flash (storage, 896K) with a README.txt the firmware writes at boot before handing the drive to the host mount / eject like any removable drive

Both framed links register SystemService (reboot + bootloader allowed, logging veto callback), MonitorService, OtaService (over espp::Ota, rollback like the ota example, RX overflow -> on_rx_overflow()) and CoreDumpService (over espp::CoreDump), one instance per link, serve_discovery("espp USB Device") on both, one send mutex per transport. VID 0x1209 / PID 0x0d38 (0x0d32/34/36/37 are taken by the ODrive, OTA, coredump and system examples). Boot logs the enumerated interfaces; a 10 s heartbeat logs free heap and who owns the drive. msc_example (SD card / T-Dongle-S3) is unchanged.

Partition table (4 MB): nvs, otadata, phy_init, ota_0 / ota_1 1536K each, coredump 64K, storage 896K. sdkconfig: custom table, coredump to flash, rollback, FreeRTOS stats / trace / core id, TinyUSB CDC + vendor + MSC, 4096-byte wear-levelling sectors with a 4096-byte MSC buffer, FAT labels, console on UART0.

Test plan

  • components/usb_device/example builds for esp32s3 with IDF_COMPONENT_MANAGER=0 (as CI); the app is 722 KB (47 % of an OTA slot); the generated sdkconfig has the custom table, coredump-to-flash, rollback, run-time stats, MSC enabled with a 4096-byte buffer and 4096-byte WL sectors.
  • components/odrive_native/usb_example builds for esp32s3 with the component manager on (as CI).
  • cppcheck with the CI arguments on the new example: nothing new; clang-format clean.
  • Hardware (S3): enumerates as CDC + vendor + MSC; the drive mounts and shows README.txt, ejecting hands it back (heartbeat log); system console over WebUSB and over Web Serial (info, heap / tasks, reboot, reboot into the bootloader); OTA from the OTA console; a crash trigger + coredump console download.
  • Hardware: the moved ODrive example still enumerates as before (HARDWARE_TEST.md).

🤖 Generated with Claude Code

https://claude.ai/code/session_01DFjjnq3XCTRAXENSxsCxJU

finger563 and others added 2 commits September 30, 2026 23:14
…e out of usb_device

The composite ODrive device (ASCII over CDC, native / Fibre over the vendor
interface, HID gamepad) is specific to the ODrive protocols, so it now lives
with them as components/odrive_native/usb_example (history preserved; same
behaviour, descriptors and VID/PID 0x1209/0x0d32). usb_device/example becomes
the generic USB device reference example (next commit). CI, docs (its own
page under the odrive_native component), Doxygen example paths and the
usb_device header snippets are updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFjjnq3XCTRAXENSxsCxJU
… with the standard USB services

One espp::UsbDevice with the three interface classes the component provides:
CDC and vendor (WebUSB) each carry the espp framed protocol through their own
DispatcherWorker, serving SystemService, MonitorService, OtaService and
CoreDumpService (discoverable, one send mutex per transport, RX overflow ->
OtaService::on_rx_overflow()); MSC exposes a wear-levelled FAT partition in
flash as a removable drive, on which the firmware writes a README before
handing it to the host. VID 0x1209 / PID 0x0d38 (unused by the other
examples); 4 MB table: otadata, ota_0 / ota_1 (1536K each; the app is 722K),
coredump 64K, storage 896K. Builds for esp32s3 (CI, manager off).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFjjnq3XCTRAXENSxsCxJU
Copilot AI balanced review requested due to automatic review settings October 1, 2026 03:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

Review effort: Lite
Findings: 2 High severity · 3 Medium severity

Open (5)
What changed in this PR

Moves the ODrive-specific composite USB example under odrive_native, and rewrites components/usb_device/example into a generic reference composite (CDC + vendor/WebUSB + MSC) showcasing the standard espp USB services.

Changes:

  • Relocates the ODrive-compatible USB composite example to components/odrive_native/usb_example and wires it into docs + CI.
  • Replaces components/usb_device/example with a generic CDC+vendor/WebUSB+MSC reference example (services + flash-backed MSC drive).
  • Updates Doxygen example paths and header snippet references to the new generic example.
File Description
doc/​en/​motor_control/​odrive_usb_example.md Adds doc page that includes the moved ODrive USB example README.
doc/​en/​motor_control/​odrive_native.rst Adds the ODrive USB example page to the odrive_native toctree.
doc/​Doxyfile Updates Doxygen example paths for the moved ODrive USB example and new generic usb_device example.
components/​usb_device/​include/​usb_device.hpp Points Doxygen snippet to the new usb_device_example.cpp.
components/​usb_device/​include/​usb_cdc.hpp Points Doxygen snippet to the new usb_device_example.cpp.
components/​usb_device/​example/​sdkconfig.defaults Updates sdkconfig defaults for generic CDC+vendor+MSC + services + partition table.
components/​usb_device/​example/​partitions.csv Adds custom 4MB OTA+coredump+storage partition table for the generic example.
components/​usb_device/​example/​main/​usb_device_example.cpp Adds the new generic composite USB device example with services and MSC drive.
components/​usb_device/​example/​main/​usb_cdc_example.cpp Renames snippet tags (file still present in generic example directory).
components/​usb_device/​example/​main/​CMakeLists.txt Updates component requirements for the new generic example.
components/​usb_device/​example/​README.md Rewrites README from ODrive-specific to generic services + MSC example.
components/​usb_device/​example/​HARDWARE_TEST.md Updates flash instructions, but currently points to the moved ODrive path.
components/​usb_device/​example/​CMakeLists.txt Updates build modes (manager on/off), EXTRA_COMPONENT_DIRS, and project name for generic example.
components/​odrive_native/​usb_example/​sdkconfig.defaults Adds sdkconfig defaults for the moved ODrive USB example.
components/​odrive_native/​usb_example/​main/​CMakeLists.txt Adds main component registration for the moved ODrive USB example.
components/​odrive_native/​usb_example/​README.md Adds README for the moved ODrive USB example.
components/​odrive_native/​usb_example/​CMakeLists.txt Adds project CMakeLists for the moved ODrive USB example.
components/​odrive_native/​README.md Mentions the new usb_example under odrive_native.
.github/​workflows/​build.yml Adds CI build for the moved ODrive USB example and forces manager-off build for generic usb_device example.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread components/usb_device/example/main/CMakeLists.txt
Comment thread components/usb_device/example/main/usb_device_example.cpp
Comment thread components/usb_device/example/main/usb_device_example.cpp Outdated
Comment thread components/usb_device/example/main/usb_device_example.cpp Outdated
Comment thread components/usb_device/include/usb_device.hpp Outdated
…itle (review)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFjjnq3XCTRAXENSxsCxJU
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

✅Static analysis result - no issues found! ✅

@finger563
finger563 merged commit 46f046f into main Oct 1, 2026
171 of 172 checks passed
@finger563
finger563 deleted the feat/usb-device-reference-example branch October 1, 2026 03:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread components/usb_device/example/main/CMakeLists.txt
Comment thread components/usb_device/example/CMakeLists.txt
Comment thread components/usb_device/example/main/usb_device_example.cpp
Comment thread components/usb_device/include/usb_cdc.hpp
finger563 added a commit that referenced this pull request Oct 1, 2026
…xplains the composite example (#835)

Post-merge review of #834: the example sets CMAKE_CXX_STANDARD after
project() like the ODrive USB example, and the UsbCdc header's example
section says the snippet is the composite device (CDC next to vendor + MSC).


Claude-Session: https://claude.ai/code/session_01DFjjnq3XCTRAXENSxsCxJU

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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.

2 participants