Commit Graph

1399 Commits

Author SHA1 Message Date
741776311b ch32h417: register in CI matrix, lwIP throughput, docs and presets
Final integration for the CH32H417 port.

- .github/workflows/ci_set_matrix.py: add ch32h417 (riscv-gcc) so CI builds it.
- examples/device/net_lwip_webserver: enable LWIP_HIGH_THROUGHPUT for the H417
  (SuperSpeed iperf).
- docs/reference/{boards,dependencies}.rst + hw/bsp/BoardPresets.json: regenerated
  for the new board and dependency.

usbtest quirks intentionally left at 0 for the H417: its endpoint engine fixes the
two CH569 5 Gbps silicon limitations (RB_EP_TX/RX_HALT gives a repeatable STALL for
case 13; the reworked EP0/chain path is expected free of the wLength%4==1 ctrl_out
drop), so the H417 targets a full 30/30 at SuperSpeed rather than 27/27.

The HIL entry (test/hil/tinyusb.json) is deliberately deferred: it needs the chip's
ESIG unique id read from the board on first flash, which is pending hardware access.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QWhrtHjbSVMKcY68vxBwBm
2026-07-12 05:02:59 +07:00
fbdbcd092e ch32h417: add USB3 SuperSpeed dcd with runtime USB2 fallback
Second stage: the USBSS SuperSpeed device driver (SPEED=super now links). The
LINK layer is the same IP as the CH569 but the endpoint engine is the H417's
reworked chain-DMA design (hardware SEQ_AUTO/ERDY_AUTO, persistent RB_EP_*_HALT,
per-chain completion). The RCC/PHY/LINK bring-up and EP0 control sequences are
transcribed from the WCH EVT USBSS device demo; data endpoints arm one chain per
packet (burst 1) for correctness-first bring-up, matching the CH569 port's
initial path - raise CFG_TUD_WCH_USB30_MAX_BURST once the hardware validates.
Buffers may live anywhere in the shared SRAM (all DMA-reachable), so no bounce
machinery is needed.

- src/portable/wch/dcd_ch32h417_usb30.c (+ ch32h417_usb30_reg.h): full dcd with
  a STATE_CHG-driven LTSSM handler, LMP PORT_CAP/PORT_CFG exchange, EP0 DPH/ERDY
  flow with software sequence, chain-armed data endpoints, per-EP HALT stall, and
  a TIM12-backstopped runtime USB2 fallback that hands rhport 0 to ch32h417_usb2_*
  when SuperSpeed training fails (host has no SS port).
- examples/device/*/skip.txt: add mcu:CH32H417 to the FreeRTOS + audio/video
  examples (no FreeRTOSConfig for this family yet), mirroring mcu:CH569.

Build-verified: all 20 device examples build for SPEED=super, and cdc_msc for
SPEED=high, clean under -Werror (riscv-none-elf-gcc 13.2). Hardware bring-up at
5 Gbps (usbtest battery, throughput) is pending rig availability.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QWhrtHjbSVMKcY68vxBwBm
2026-07-12 04:59:21 +07:00
62175c3e0d usbtest: skip silicon-impossible cases via bcdDevice quirk flags
The CH569 USBSS ctrl_out flakiness (cases 14/21, host -EPROTO) is a
silicon erratum, not a driver bug: EP0 OUT data stages whose wLength
% 4 == 1 are intermittently dropped at 5 Gbps. Proven by A/B against
WCH's own binary USB3 stack (SimulateCDC EVT demo patched to accept
the gadget-zero 0x5b/0x5c requests), which fails identically on the
same board — independent of host LPM (persists with U1/U2 disabled)
and sysclk (80 vs 120 MHz). Bulk OUT at the same lengths is clean.
Document the erratum in the dcd and drop the ineffective zeroed-BOS
workaround.

Rather than letting known-impossible cases flake the battery, the
firmware now advertises quirk flags in bcdDevice bits 4-7 (tier stays
in bits 0-3): 0x10 skips ctrl_out 14/21, 0x20 skips ep-halt 13 (the
previously proven single-STALL limitation). usbtest.py skips flagged
cases visibly at SuperSpeed only (explicit --tests still runs them)
and reports them in the summary/JSON.

Also fix the CH56x USB3 dcd leaving an endpoint halted across
reconfiguration: clear the stalled flag in dcd_edpt_open/close/
close_all (USB 2.0 9.4.5) so a SET_CONFIGURATION recovery of a
halted-then-reopened endpoint does not STALL forever.

Validated on hydrausb3_v1 at 5000M: tier-4 battery x3 = 27/27 passed
+ 3 skipped, full HIL device suite 12/12 green (MSC 160/134 MB/s).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-09 14:34:13 +07:00
671cb7a1e2 Add SuperSpeed isochronous support to the CH56x USB3 dcd
The register model comes from disassembling WCH's official USB30 device
blob (libCH56x_USB30_device_lib.a): USB30_ISO_Setendp reveals per-
endpoint isochronous mode bits in UEP_CFG (bit 16+ep for OUT, bit 24+ep
for IN); arming and completion then use the normal endpoint flow. The
usbtest example moves back to tier 4 at SuperSpeed with an iso pair in
the SS descriptor set - all four kernel usbtest iso cases (15/16/22/23)
pass on hardware at 5000M.

The endpoint-halt latch from the previous commit is kept (it fixes
usbtest case 29); case 13 is now documented as a silicon limitation
after exhaustive on-hardware experiments: a halted endpoint answers
exactly one probe with a STALL TP and no re-arm strategy (any NUMP,
ERDY, 30 us timer re-assertion, endpoint enable bounce) revives it -
no event fires per stall TP. The CH32H417's reworked endpoint engine
adds a persistent RB_EP_TX_HALT mode, evidently addressing exactly
this. Battery results: 30/30 at high speed, 28/30 at SuperSpeed
(case 13 = silicon halt limitation; case 14 ctrl_out is intermittent
- pre-existing EP0 OUT flakiness under investigation).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08 12:26:08 +07:00
597f27d0f4 Pass the usbtest battery on CH569 at high and SuperSpeed
Running the Linux kernel usbtest/testusb battery against the CH569 for
the first time. Results: 30/30 at high speed (4 consecutive reflash
cycles), 25/26 at SuperSpeed.

DCD fixes found by the battery:
- dcd_ch56x_usbhs: clear-halt on an armed bulk-OUT pipe reset the toggle
  but dropped the queued receive, NAKing forever (usbtest case 29 - the
  same defect previously found on rp2040/fsdev/ch32_usbhs/rusb2)
- dcd_ch56x_usb30: endpoint halt is now latched; the endpoint event
  handler used to clear the response field on every completion, wiping a
  just-set STALL while the peer streamed, and clear-halt now re-arms a
  still-armed transfer with the fresh packet sequence (cases 13/29)

usbtest example gains SuperSpeed support: tier 3 on SS builds, a
4-endpoint SS descriptor set with companions, EP0 512 config and
1024-byte receive buffers.

test/hil/usbtest.py gains SuperSpeed-aware case parameters: bulk sizes
and vary steps must be 1024-multiples at SS or the device's whole-packet
source overruns the host request (case 4 EOVERFLOW).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08 12:26:08 +07:00
4ab165639e Merge branch 'usbtest': Linux kernel usbtest battery support
Brings the usbtest device example (gadget-zero source/sink peer for the
kernel's usbtest.ko/testusb), the test/hil/usbtest.py battery runner and
the extended vendor class driver (interrupt/isochronous endpoints, alt
settings) into the CH569 SuperSpeed branch, enabling the battery to run
against both CH56x dcds.

Conflict resolution: test/hil/tinyusb.json keeps this branch's
hydrausb3_v1 fixture entry and adds the usbtest branch's
ch32v307v_r1_1v0 entry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08 12:26:08 +07:00
c54e81e9fb Reach SuperSpeed-class iperf on CH569 net_lwip_webserver
Measurements with the 9*MSS window showed iperf pinned at 51 Mbit/s with
the in-flight data exactly tracking the advertised window: the 120 MHz
core's TCP receive path is the bottleneck, not the window or the USB
link. Recover the software-checksum cost: inbound IP/UDP/TCP checksum
VERIFICATION is skipped on the SuperSpeed build (USB already CRC32
protects every payload; outbound generation stays on). iperf over
SuperSpeed improves 51 -> 74.5 Mbit/s (device RX, lwiperf).

Also from bringing this up on a marginal SS lane that takes seconds to
train (normal lanes train in <100 ms):
- CFG_TUD_WCH_USB30_FALLBACK is now overridable from the build line;
  =0 builds SuperSpeed-only, which retries training indefinitely
  instead of settling for high speed
- the fallback keeps retrying twice as long (4.4 s) when far-end RX
  terminations were seen: terminations mean an SS-capable partner
  exists, while a USB2-only host (no terminations) still falls back
  after ~2 s

Validated on HydraUSB3 behind a Renesas uPD720201 hub; 65/65 unit
tests, full example sweep, pre-commit clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08 08:49:16 +07:00
3853844311 Tune net_lwip_webserver lwIP memory for SuperSpeed on CH569
iperf on the SuperSpeed build is TCP-window-bound (51 Mbit/s with the
6*MSS window). Reclaim RAMX to widen it:

- dcd_ch56x_usbhs: new CFG_TUD_WCH_USBHS_EP_MAX limits usable endpoint
  numbers and scales the static RAMX bounce buffers accordingly
  (default unchanged at 8 endpoints)
- net_lwip_webserver: limit the (fallback) USB2 endpoints to 1-3,
  freeing 4 KB of RAMX; grow the SuperSpeed build to PBUF_POOL_SIZE 9 /
  TCP_WND 9*MSS (the high-speed build keeps 6/6). RAMX 94% of 32 KB.

High-speed fallback verified unchanged on HydraUSB3 (33 Mbit/s, full
enumeration); the SuperSpeed window measurement is pending the rig's SS
lane, which trains only intermittently (analog-marginal path - same
binaries trained and ran 51 Mbit/s earlier the same day).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08 07:55:13 +07:00
9d51270f7b Retry CH569 SuperSpeed training and fix net_lwip_webserver EP0 size
Two fixes found bringing up SuperSpeed on a Renesas uPD720201-based hub:

- dcd_ch56x_usb30: retry link training with a fresh detect cycle every
  second fallback-timer tick (4 ticks total) before switching to the
  USB2 fallback. Some hubs only complete Polling on a re-attempt; with
  a single continuous attempt the link reached U0 rarely and the port
  fell back to high speed almost every boot.

- net_lwip_webserver: CFG_TUD_ENDPOINT0_SIZE was left at plain 64, so
  usbd chunked EP0 data at 64 bytes; on a 512-mps SuperSpeed control
  endpoint the first chunk is a short packet, the host ends the data
  stage early and the status stage deadlocks until timeout ("can't
  read configurations, error -110"). Use the SuperSpeed-aware size and
  clamp the device-qualifier bMaxPacketSize0 like the other examples.

Validated on HydraUSB3: NCM enumerates at 5000M reliably across warm
reboots; lwiperf over SuperSpeed measures 51 Mbit/s device RX (TCP
window bound; 33 Mbit/s on the high-speed fallback), MSC 169/136 MB/s.
Full example sweep, 65/65 unit tests, pre-commit clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08 07:32:49 +07:00
5418b836d5 Add SuperSpeed descriptors to all bulk/interrupt class drivers and examples
Class drivers: skip and account the SS endpoint companion descriptor in
every descriptor walk (hid, midi, midi2, ecm_rndis, printer, mtp, usbtmc),
via a shared usbd_skip_ss_ep_companion() helper in usbd_pvt.h (cdc/ncm
already handled; vendor/dfu naturally tolerant). usbtmc buffer grows to
1024 at SS to satisfy its packet-multiple assert. bth/audio/video are left
FS/HS-only (ISO-centric; ISO is unsupported on the CH569 dcd).

usbd.h: new SS template macros TUD_HID_SS_DESCRIPTOR(+INOUT),
TUD_MIDI_SS_DESCRIPTOR (+ DESC_EP_SS part), TUD_MIDI2_DESC_ALT1_EP_SS,
TUD_PRINTER_SS_DESCRIPTOR, TUD_MTP_SS_DESCRIPTOR,
TUD_USBTMC_BULK_SS_DESCRIPTORS/INT_SS_DESCRIPTOR, with _SS_DESC_LEN
counterparts (bulk endpoints hardcode 1024, companion after every EP).

Examples: 17 bulk/interrupt examples gain the full SS descriptor set
(EP0 512/64 clamp, SS device descriptor bcdUSB 3.20 mps0=2^9, SS config
with companions, BOS caps, speed-switched callbacks): cdc_dual_ports,
cdc_msc_freertos, dfu, dfu_runtime, dynamic_configuration,
hid_boot_interface, hid_composite(+freertos), hid_generic_inout,
hid_multiple_interface, midi_test(+freertos), midi2_device, msc_dual_lun,
mtp, printer_to_cdc, usbtmc, webusb_serial. msc_dual_lun is un-skipped for
CH569 using read-only flash disks (16KB RAM can't hold two 8KB RAM disks,
same as ch32v10x/v20x boards).

Validation: full example sweep green for hydrausb3_v1 (SPEED=super, 19
device ELFs) and raspberry_pi_pico; wTotalLength == sizeof() verified for
every SS configuration array in the built ELFs; ceedling 65/65;
pre-commit clean; code-size delta +0.0% on rp2040 (SS code folds out on
non-SS builds).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-07 18:12:02 +07:00
149b91c066 Add SuperSpeed support to CDC-NCM and enable iperf on CH569
- TUD_CDC_NCM_SS_DESCRIPTOR template (bulk 1024 + endpoint companions)
  and companion handling in netd_open (notification endpoint skip,
  bulk pair drv_len)
- net_lwip_webserver: SS device/config/BOS descriptors for the NCM
  build, CH569 added to the LWIP_HIGH_THROUGHPUT tier (builds lwiperf).
  The 16 KB RAMS cannot hold lwIP: heap and pools go to the 32 KB RAMX
  via LWIP_DECLARE_MEMORY_ALIGNED (arch/cc.h), with a 6-pbuf pool /
  6*MSS window and a 3 KB dcd bounce pool to fit (RAMX 92%)
- CH569 dcd fixes found while bringing this up: TMR0 counts only 26
  bits, so the previous 1 s fallback CNT_END (120e6 > 2^26) silently
  never expired - use 0.55 s per phase; make link busy-waits in
  usb30_hw_init best-effort so a stuck-BUSY teardown state cannot
  abort re-initialization half way

Builds clean (full ch56x example sweep); NOT yet hardware-validated:
the rig's WCH-LinkE stopped completing flash writes mid-session (reads
and erases fine), leaving the board without firmware - iperf numbers
pending physical probe/board recovery.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:03:25 +07:00
12a507f507 Enable 4-packet bursts on CH569 SuperSpeed bulk endpoints
- Default CFG_TUD_WCH_USB30_MAX_BURST to 4 (tusb_mcu.h): matches the
  link layer's header-packet buffer count (NUM_HP_BUF). Burst 8 fails
  to configure; the TeenyUSB-reported burst corruption quirk did not
  reproduce with per-burst DMA re-arm (50x MSC write/read-back and
  256KB CDC echo integrity all clean at burst 4)
- Bounce slots stay one max packet regardless of burst (bounced
  transfers cap their burst to the slot; zero-copy uses the full burst)
  so the RAMX pool no longer scales with burst size
- cdc_msc/cdc_msc_throughput SS descriptors advertise
  bMaxBurst = CFG_TUD_WCH_USB30_MAX_BURST-1 via the
  CFG_EXAMPLE_SS_BULK_MAXBURST knob (0 for non-WCH SuperSpeed ports)

Measured on HydraUSB3 v1 at 5 Gbps (HIL cdc_msc_throughput): MSC read
147 MBps write 127 MBps - about 2x the single-packet figures (raw dd:
up to 163 MB/s read at 1M blocks).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:28:45 +07:00
1170ff6ffb Add SuperSpeed support to cdc_msc_throughput example
- SS device/config/BOS descriptors with endpoint companions, speed-aware
  EP0/CDC/MSC buffer sizes (same pattern as cdc_msc)
- Lengthen the CH569 SuperSpeed-training fallback timeout to 1 s per
  phase: training from a host port settled in another connection state
  can exceed the previous 0.5 s window

Measured on HydraUSB3 v1 at 5 Gbps (NUMP=1): MSC sequential read
70-79 MB/s, write 55 MB/s via dd direct IO - about 3.5x the USB2
high-speed fallback figures on the same setup. Burst support
(CFG_TUD_WCH_USB30_MAX_BURST > 1) remains the main headroom.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:03:15 +07:00
36756e4c43 Add CH569 USB3.0 SuperSpeed device driver - TinyUSB's first SuperSpeed port
New dcd_ch56x_usb30.c + ch56x_usb30_reg.h (both MIT, written fresh):
- Register model from the hydrausb3 project's reverse engineering
  (wch-ch56x-lib, Apache-2.0) and TeenyUSB's CH56x port (MIT), with
  LINK-layer bit names per the officially documented CH32H417 (same IP,
  CH32H417RM chapter 27); TU_VERIFY_STATIC offset asserts guard the
  vendor header layout
- Software-assisted LTSSM in the LINK interrupt: polling/TXEQ/ready
  sequencing, LMP PORT_CAPABILITY + PORT_CONFIGURATION exchange, warm
  and hot reset handling. Link-up (ready after TXEQ) is reported as
  dcd_event_bus_reset with TUSB_SPEED_SUPER
- EP0 with fixed 512-byte mps: SETUP via RX flag bit30, unified status
  stage via bit29 (SET_ADDRESS applied there), manual IN packet sequence
- Data endpoints with per-burst DMA re-arm, partial burst-drain
  accounting, ERDY flow control and NUMP=1 default (multi-packet burst
  silicon quirk); RAMX bounce slots from a small pool for transfer
  buffers outside RAMX; isochronous not supported
- Board vector forwarders unified into one handler + symbol aliases:
  gcc identical-code-folding otherwise rewrites one interrupt handler
  as a call into another whose mret skips the caller's epilogue,
  leaking a stack frame per interrupt (found the hard way)
- hydrausb3_v1 default SPEED flipped to super; skip net_lwip_webserver
  (16 KB RAMS, same as other small-RAM parts)

Verified on HydraUSB3 v1 hardware (ci rig, USB3 host port):
- cdc_msc enumerates at 5000M: bcdUSB 3.20, EP0 mps 2^9, endpoint
  companion descriptors, BOS with USB2-ext + SuperSpeed capability
- CDC echo and MSC FAT12 reads functional at SuperSpeed; 30x sustained
  read stress and 5x replug/reset cycles all re-enumerate at 5000M
- SPEED=high regression: still enumerates at 480M
- Full example sweep builds for both controllers

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 11:11:41 +07:00
c0648e0cfa Add CH569/CH565 family with HydraUSB3 v1 board and USB2 HS dcd
- OPT_MCU_CH569 (2250) + tusb_mcu.h capability block: USB3 SuperSpeed
  (USBSS) or USB2 HighSpeed (USBHS) selected at compile time via
  CFG_TUD_WCH_USBIP_USB30/USBHS, both on rhport 0
- New dcd_ch56x_usbhs.c: CH56x USB2 HS device driver ported from
  dcd_ch32_usbhs.c (same bit encoding, CH56x-specific register layout:
  R8_UEPn_MOD enables, different DMA/MAX_LEN/control offsets, 8 EPs).
  Internals exposed as ch56x_usb2_* (dcd_ch56x.h) for the upcoming USB3
  dcd's runtime fallback. USB DMA only reaches RAMX: buffers in the
  .dmadata section, non-RAMX transfer buffers bounce per-endpoint
- hw/bsp/ch56x family (SDK dep hydrausb3/wch-ch56x-bsp, Apache-2.0, no
  binary blobs) + hydrausb3_v1 board: 120 MHz clock (required for USB3),
  UART1 PA8/PA7 logging, LED PB22, button PB23, linker script with
  16-byte aligned NOLOAD .dmadata section in RAMX
- SPEED=high|super build option (default high until the USB3 dcd lands)
- CI: add ch56x to riscv-gcc matrix; skip FreeRTOS/audio/video examples
  (as CH583) and msc_dual_lun (16 KB RAMS, as SAMD11/MKL25)

Verified: cdc_msc builds via CMake and Make; full example sweep green;
.dmadata lands at 0x20020000 (RAMX) with 16-byte alignment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 10:49:55 +07:00
67818cb975 Add core SuperSpeed device support
Groundwork for TinyUSB's first SuperSpeed port (WCH CH569):
- TUSB_SPEED_SUPER, OPT_MODE_SUPER_SPEED, TUD_OPT_SUPER_SPEED and
  TUP_RHPORT_SUPERSPEED capability plumbing
- Allow CFG_TUD_ENDPOINT0_SIZE 512 on SS builds; EP0 control transfers
  chunk at the runtime link speed (512 at SS, 64 on USB2 fallback)
- Handle SET_SEL, SET_ISOCH_DELAY and U1/U2_ENABLE feature requests
- Tolerate SS endpoint companion descriptors in usbd_open_edpt_pair,
  cdcd_open and mscd_open interface parsing
- SS descriptor types/structs and template macros: endpoint companion,
  BOS USB2-extension + SuperSpeed capability, SS config and
  CDC/MSC/vendor SS variants (bulk fixed at 1024)
- cdc_msc example: SS device/config/BOS descriptors, speed-aware sizes
- Unit tests: SS endpoint validation, companion-tolerant endpoint pair
  open, SET_SEL, SET_ISOCH_DELAY

All SS paths compile out when disabled: verified 0-byte code-size delta
on stm32f407disco (MinSizeRel) vs master; 65/65 unit tests pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 09:46:25 +07:00
1922a1c3af usbtest: negotiated-speed int/iso refill + harden HIL sudoers
Copilot review:
- tud_vendor_int_tx_cb/iso_tx_cb submitted sizeof(chunk) (the HS-capacity buffer)
  instead of the negotiated-speed mps, diverging from usbtest_pump() on an
  HS-capable build enumerated at full speed. Factor the length into shared
  usbtest_int_len()/usbtest_iso_len() helpers used by the pump and both callbacks.
- Reword the usb_descriptors.h comment that still called the plain mps macro
  'live operating speed' — it is the compile-time capability maximum.

Claude review (test/hil/tinyusb-sudoer): drop the two grants that bypassed the
file's root-owned-helper boundary and gave uid 1000 passwordless root:
- /sbin/debugfs (unused; permits '!/bin/sh' shell escape + raw root-disk write).
- /home/*/actions-runner/svc.sh (user-writable script). Replace with a root-owned,
  argument-restricted 'systemctl stop/start actions.runner.*' grant. Also tighten
  the dmesg/uhubctl runas from (ALL) to (root).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-07 09:43:50 +07:00
9ed3bc7d48 usbtest: document what each battery case does in the README
Per-case table: direction convention, what the host verifies, and which
device/DCD path each case stresses (EP0 storms, sg queue pressure, unlink,
halt/toggle semantics, iso frame deadlines, throughput).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-07 09:26:09 +07:00
309ec49bf9 usbtest: correct the capability-vs-runtime comment on the mps macros
The plain USBTEST_*_EP_MPS macros are the compile-time capability maximum that
sizes the buffers; runtime write lengths follow tud_speed_get() in main.c.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-07 01:35:59 +07:00
abd8769781 address review round 2 (4 fixed, 1 answered)
- dcd(nrf5x): dcd_edpt_iso_activate drops a stale armed transfer (started/
  data_received/iso_in_transfer_ready) — there is no dcd close on this port, so
  a transfer armed before SET_INTERFACE would trip TU_ASSERT(!xfer->started) on
  the class's next arm after usbd reset the endpoint's claim state.
- class(vendor): tud_vendor_n_mounted() counts the interrupt endpoints, so an
  interrupt-only vendor interface (bulk absent) reports mounted.
- example(usbtest): int/iso write lengths follow the negotiated speed
  (tud_speed_get), not the compile-time capability — a high-speed build
  enumerated at full speed serves the FS descriptor (mps 64/128) and must not
  submit HS-sized packets.
- test/hil: test_example() return annotation matches the (err, status, metric)
  3-tuple it returns.

Verified: feather_nrf52840_express and raspberry_pi_pico 30/30 through the HIL
battery; pico/feather/ch32v307-usbhs builds clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-07 01:23:38 +07:00
f41c1827b2 address Codex/Copilot review findings (9 fixed, 3 refuted with evidence)
- dcd(rp2040): rewind IN staging before the clear-halt re-issue. Staging advances
  user_buf/remaining_len when packets are copied into DPRAM, before the host has
  consumed them; aborting and re-issuing from the advanced pointer silently
  skipped the staged-but-unsent bytes.
- dcd(ip3511): dcd_edpt_iso_activate aborts a transfer still armed from the
  previous altsetting (clear Active on both buffer slots) so the hardware can't
  keep servicing the old descriptor against the class's fresh queueing.
- dcd(rusb2): reuse an endpoint's existing pipe in dcd_edpt_open. usbd_edpt_close
  is a no-op on ISO_ALLOC ports, so a class's close/open across SET_INTERFACE
  would allocate a second pipe with the same EPNUM and leak pipes.
- class(vendor): the buffered-mode free-slot check also tests the interrupt
  endpoints, so an interrupt-only vendor interface isn't clobbered as "free".
- bsp(ch32v30x): board_get_unique_id respects max_len and copies bytes
  (alignment-safe) instead of writing 12 bytes through a uint32_t cast.
- test/hil/usbtest.py: treat same-serial multi-matches as ambiguous and retry
  until the dual-port stale node drops (nanoch32v203/ch32v307 variants); reprobe
  a binding that predates the dynamic-id re-registration so a stale capability
  profile can't survive; skip the remove_id/unbind cleanup after an unrecovered
  kernel-side hang (it would join the D-state convoy and deadlock the bus).
- usbtest skip.txt: add the families whose DCD refuses dcd_edpt_iso_alloc
  (CXD56, FT90X, LPC175X_6X, LPC40XX, NUC100/120/505, PIC32MZ, SAMG, SAMX7X,
  VALENTYUSB_EPTRI) — tier 4 cannot enumerate there.
- test/hil/tinyusb-sudoer: note that '#1000' is a sudoers UID specifier, not a
  comment (the review misread the grants as commented out).

Refuted in review threads: nrf5x ISOSPLIT keeps reserve-max per-configuration
allocation semantics (iso_alloc is per-config, not per-alt); the LPC EP-number
claim (default descriptor uses EP1-3; lpcxpresso11u37 passes 30/30 on HW); the
vendor alt-0 "abort" concern (host cannot address endpoints outside the active
altsetting; usbd_edpt_iso_activate resets state on re-entry).

Verified on hardware: raspberry_pi_pico, lpcxpresso11u37, ra4m1_ek all 30/30
through the HIL battery after the changes; builds clean incl. buffered-mode
vendor (webusb_serial).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-07 00:30:07 +07:00
6d707a1e79 usbtest: single-pass pump for the non-FreeRTOS task (SonarCloud loop-executes-once)
Extract the endpoint pump into usbtest_pump(); the FreeRTOS task loops it,
the bare-metal path calls it once per main-loop tick instead of a
while(1){...return;} whose body can only execute once.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06 17:56:52 +07:00
59f15ad44d fix CI: clang/IAR unused helpers, LTO-dropped ISR symbol, LPC11/13 USB RAM overflow
Four PR-CI failures, each with a distinct root cause:

- class/vendor: mark the shared non-buffered transfer helpers TU_ATTR_UNUSED.
  In buffered mode with the int/iso endpoint gates off none is referenced, and
  clang (-Wunused-function -Werror) and IAR (Error[Pe177]) reject an unused
  static — gcc does not, which is why only the clang/IAR matrix failed.
- bsp/ch32v20x: keep dcd_int_handler alive under LTO. The `call` sits inside
  naked asm where LTO cannot see it, so -flto make builds internalized the
  symbol and every ch32v20x device example failed to link (cmake has no LTO,
  which masked it). A TU_ATTR_USED function-pointer reference pins it.
- usbtest: LPC11/13 (ip3511 FS) keep endpoint buffers in a dedicated 2 KB USB
  RAM; the 2048 B bulk epbuf overflowed it (RamUsb2 150%) in make builds. Use
  512 B (= 8 FS packets) on those parts; lpcxpresso11u37 still passes 30/30.
- test/hil: skip device/usbtest on lpcxpresso43s67 (hfp rig) — its ip3511 HS
  port wedges from the first control case (1/30) and needs on-rig debugging.

Verified: make builds link for nanoch32v203 (dfu_runtime + usbtest),
lpcxpresso11u37 and lpcxpresso1347 (RamUsb2 75%); buffered-mode webusb_serial
builds; 61/61 unit tests; lpcxpresso11u37 usbtest 30/30 on hardware with the
smaller epbuf.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06 17:55:26 +07:00
2d73cf58de Merge remote-tracking branch 'origin/master' into usbtest
# Conflicts:
#	lib/rt-thread/port/msc_device_port.c
#	src/device/usbd.c
2026-07-06 16:17:17 +07:00
61eb4a8cf2 usbtest: support CH32V307 on both USB ports (usbfs + usbhs), 30/30 each
The CH32V307 exposes two device controllers: the full-speed USBFS (dcd_ch32_usbfs,
selected with -DSPEED=full) and the high-speed USBHS (dcd_ch32_usbhs, the default).
Both now pass the Linux testusb tier-4 battery 30/30 (3 reflash cycles each) on
ch32v307v_r1_1v0.

- dcd(ch32_usbhs): fix clear-stall on an armed OUT endpoint. It set the pipe to
  NAK unconditionally, so a receive the class still considers submitted NAKed
  forever after CLEAR_FEATURE(HALT) and usbtest toggle test 29 timed out. Re-queue
  the pending receive (ACK/NYET) instead. This is the first usbtest coverage of the
  ch32_usbhs driver.
- bsp(ch32v30x): implement board_get_unique_id from the ESIG UID (0x1FFFF7E8);
  the port previously fell back to the placeholder serial.
- usbtest: the CH32V307 usbfs port caps iso at 64 B like the other WCH USBFS parts,
  so add it to the FS iso-64 descriptor branch (its usbhs port uses the HS sizes).
- test/hil: register ch32v307v_r1_1v0 (usbhs + usbfs variants, WCH-Link BC5DA47360D0)
  and move nrf54lm20dk to boards-skip.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06 15:32:17 +07:00
24be249983 usbtest: address code-review findings (EP3 iso regression + 9 more)
Cross-checking the branch against the MCU datasheets surfaced a regression and
several latent defects. Fixes (finding # from the review):

#1 dcd_ch32_usbfs: restore EP3's enlarged iso buffer. CH32V20x/V30x/F20x USBFS
   give endpoint 3 a 1023-byte iso packet (CH32FV2x_V3xRM ch23; 16-bit
   R16_UEP3_T_LEN), unlike every other 64 B endpoint. Commit c05e9313e removed
   that buffer and capped iso at 64 B, breaking >64 B FS iso (UVC/UAC) on EP3.
   Re-add it via CFG_TUD_WCH_USBFS_EP3_BUFSIZE, defaulted to 1023 on those parts
   (CH32_USBFS_EP3_1023_BUFSIZE in ch32_usbfs_reg.h) and 64 elsewhere.
#3 dcd_ch32_usbfs: make data.isochronous[] per-direction and clear it on
   endpoint (re)open, so a reused ep number can't inherit a stale iso response.
#7 dcd_ch32_usbfs: exempt iso from the PID_OUT data-toggle handling too (was
   only done for PID_IN); iso is DATA0-only in both directions.
#13 dcd_ch32_usbfs: bounds-assert ep < EP_MAX in dcd_edpt_iso_alloc.
#2/#6 usbtest descriptors: TUD_OPT_HIGH_SPEED is a compile-time capability, not
   the live speed, so the full-speed config (and OTHER_SPEED) advertised int/iso
   mps 512 on HS boards — illegal at FS / over the 1023 B/frame iso budget. Split
   into FS-legal / HS descriptor sizes; the plain macro tracks operating speed.
#10 vendor: non-alt free-slot detection also checks the int endpoints (a vendor
   interface may now be interrupt-only, no bulk ep).
#14 vendor: replace the order-coupled ITF_MEM_RESET_SIZE ladder (2 unreachable
   branches) with offsetof(vendord_interface_t, tx_stream).
#5 rp2040: clear_stall re-issue preserves the already-transferred count so a
   mid-transfer clear-halt reports the full length, not just the remainder.
#8 rp2040: force single-buffering for iso (only BULK gets a double DPRAM buffer),
   so a multi-packet iso xfer can't spill buffer 1 into the next ep's DPRAM.

Verified: CH32V203 usbfs and CH583 still pass usbtest tier-4 30/30; all board
families build; pre-commit (format/codespell/unit) clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06 11:53:40 +07:00
e7d7fda974 usbtest: support CH583 — its USBFS does isochronous (30/30)
The CH582/CH583 USBFS DCD refused isochronous outright, but the datasheet
(CH582-CH583 DS1, USB controller chapter) lists synchronous/real-time
(isochronous) alongside control/bulk/interrupt, with 64 B packets. Accept iso
like the other WCH USBFS parts (iso mps 64, capped to the 64 B endpoint buffer;
drop the CH583-only refusals in dcd_edpt_iso_alloc/activate).

That alone left iso IN dropping a deterministic ~1/8 of packets. Root cause:
CH58x drives the data toggle manually in the ISR (its hardware AUTO_TOG is
unreliable) and flipped the TX toggle after every IN packet — including
isochronous, which is DATA0-only and must never toggle. Skip the manual toggle
flip for iso endpoints. This path is CH58x-only (CH32_USBFS_EP_MANUAL_TOG),
so CH32V103/V20x/V307 (hardware AUTO_TOG) are unaffected.

Verified on ch582m_evt: Linux testusb tier-4 (30 cases) = 30/30 across 4 reflash
cycles; CH32V103 and the CH32V203 usbfs port still pass. Drop CH583 from the
usbtest skip list — all WCH USBFS parts now run the full battery.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06 10:11:30 +07:00
c05e9313ee usbtest: enable CH32V103, drop the CH32 usbfs EP3 iso special buffer
CH32V103 (ch32v103r) uses the same usbfs DCD as the CH32V203 usbfs port and
passes tier-4 30/30 with the fixes already in place (iso mps 64 + the clear-halt
re-arm) — drop it from the skip list. Verified 30/30 across 6 reflash cycles.

dcd_ch32_usbfs.c gave EP3 an enlarged 1023-byte IN buffer for full-speed iso,
but the CH32V20x/V103 USB FS controller caps every endpoint (bulk/interrupt/iso)
at a 64-byte packet (per the RM "USB Full-speed Host/Device Controller"), so no
endpoint can ever send more than 64 B and the oversized EP3 buffer was pure
waste. Treat EP3 like any other endpoint (64 B OUT + 64 B IN) and drop the
special buffer, saving ~1 KB of RAM. dcd_edpt_iso_alloc now rejects an iso mps
> 64 rather than running off the end of the buffer. usbtest (iso mps 64) still
passes 30/30 on CH32V103 and the CH32V203 usbfs port.

CH583 has no isochronous support in its USBFS IP, so it cannot run tier-4 (the
iso endpoints fail to open and SET_CONFIG times out); it stays skipped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-05 23:46:17 +07:00
536157cb98 Merge pull request #3738 from sauloverissimo/fix/midi2-fb-direction
feat(midi2): derive function blocks from the GTB descriptor
2026-07-05 17:46:14 +02:00
ae7f10b0d3 usbtest: support CH32V203 (fsdev + usbfs ports), both pass tier-4 30/30
Neither of the CH32V203's two USB device IPs could run the usbtest tier-4 battery.

usbfs (port 1):
- 128 B iso doesn't fit its fixed 64 B/ep buffers -> drop iso mps to 64 on CH32
  (usb_descriptors.h).
- dcd_ch32_usbfs.c: clear-halt on an armed OUT endpoint forced it to NAK, so a
  submitted read NAK'd forever and the host timed out. Re-assert ACK when a
  receive is still armed (usbtest toggle test 29).

fsdev (port 0, the shared stm32_fsdev driver):
- The descriptor hard-coded the interrupt mps, so USBTEST_INT_EP_MPS never took
  effect; all six tier-4 endpoints then overflowed the 512 B PMA and SET_CONFIG
  timed out. Wire the interrupt mps to the macro and use 16 on the fsdev port.
- The USBD raises three IRQ lines (LP/HP/WakeUp) into one non-reentrant handler
  and they nest (HP preempts LP) with QingKe HWSTK enabled. The mainline
  toolchain's plain __attribute__((interrupt)) emits a software prologue that
  fights the hardware context stack and corrupts the return on nesting -> wild
  jump / illegal-instruction crash. Emit naked handlers that rely on HWSTK for
  context save/restore -- the equivalent of WCH's "WCH-Interrupt-fast", which
  mainline riscv-none-elf-gcc ignores -- so nesting is safe.
- Single-buffered iso IN can't stay fed under load; double-buffer it
  (CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP in the example tusb_config.h). iso mps
  32 x2 = 64 B/ep keeps the same PMA budget. Left single for other fsdev parts
  (audio's larger iso would overflow their PMA too).

Verified on nanoch32v203 (CH32V203D6): Linux testusb tier-4 (30 cases across
bulk/control/interrupt/isochronous) = 30/30 on both the fsdev and usbfs variant,
each across 5 reflash cycles. Full CH32V20X example set builds; cdc_msc still
enumerates CDC+MSC on the fsdev port (naked-handler regression check). Drop
CH32V20X from the usbtest skip list.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-05 22:18:21 +07:00
74e9caaea3 feat(usbtest): add FreeRTOS/espressif support
Mirror the video_capture #if pattern: dual-mode tasks that vTaskDelay under
FreeRTOS and return under OS_NONE, a usb_device_task + freertos_init
(xTaskCreate blinky/usbd/app), and an ESP_PLATFORM app_main. Add the ESP-IDF
src/CMakeLists.txt and CFG_TUSB_OS_INC_PATH; replace the family:espressif skip
with per-MCU skips for parts that can't fit the tier-4 descriptor.

Verified: esp32s3 (FS) and esp32p4 (HS) both 30/30 on the usbtest battery.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-04 19:47:19 +07:00
c7d2257388 fix: pre-existing VIDEO_STACK_SZIE typo + msc inquiry field overflow
Two pre-existing bugs (present on master, unrelated to the usbtest work on this
branch) flagged by the review gate; fixed in isolation so this commit can be
dropped or cherry-picked separately:

- examples/device/video_capture{,_2ch}/src/main.c: xTaskCreate() used the
  undefined macro VIDEO_STACK_SZIE (typo for VIDEO_STACK_SIZE), breaking the
  non-static-allocation FreeRTOS build.
- lib/rt-thread/port/msc_device_port.c: tud_msc_inquiry_cb() did
  memcpy(dst, src, strlen(src)) into the fixed 8/16/4-byte SCSI inquiry fields,
  overflowing them if PKG_TINYUSB_DEVICE_MSC_VID/PID/REV exceed those sizes.
  Bound each copy to the destination field size.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-03 22:59:59 +07:00
0eb1928570 fix HID_STACK_SIZE typo
Signed-off-by: HiFiPhile <admin@hifiphile.com>
2026-07-03 16:00:29 +02:00
b2a9a5d06a fix: correct video stack macro typo in video capture examples
Corrects VIDEO_STACK_SZIE to VIDEO_STACK_SIZE.
2026-07-03 15:21:40 +02:00
f082ce0cba usbtest: put iso endpoints on EP8 for nRF5x
nRF5x fixes the isochronous endpoint number to 8 (EP_ISO_NUM) in hardware for
both ISOOUT and ISOIN. The default tier-4 descriptor used EP3 for iso, so
dcd_edpt_open() rejected it and SET_CONFIGURATION failed (can't set config,
-EPIPE) - the device enumerated but never configured, so usbtest couldn't bind.

Add an OPT_MCU_NRF5X case to the per-MCU endpoint-number block placing iso on
EP8. usbtest on feather_nrf52840_express then configures and passes 29/30
(all bulk/int/iso/ctrl_out/halt/toggle); test 10 (queued control) hangs - a
separate nRF EP0 issue tracked for follow-up.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-03 15:19:22 +07:00
556e1bf81f usbtest: FS-sized ep buffers + host runner hardening
- example: interrupt/iso endpoint buffers track the per-speed max packet
  size instead of a fixed 512, saving ~1.6 KB of USB DMA RAM on FS builds.
- test/hil/usbtest.py: re-resolve the device node after a mid-battery
  re-enumeration (stale node was misreported as NOTRUN); reject an
  out-of-range tier (a tier-0 device would run an empty battery and read
  green); validate --tests case numbers; run cleanup in a try/finally so a
  crash can't leave the dynamic id registered to hijack the next device;
  guard set_pattern and the pci-reset placeholder; report a sudo-password
  failure on the testusb fallback instead of a misleading NOTRUN.
- tinyusb-sudoer: allow the foreign-driver unbind path and the testusb
  fallback used by the runner.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-03 08:57:32 +07:00
636c7556bf example(usbtest): tier 4 - isochronous source/sink (cases 15/16/22/23)
Gadget-Zero parity: alt 0 carries no endpoints, alt 1 the full set (bulk
+ interrupt + iso IN/OUT, iso FS 128B / HS 512B). The host usbtest driver
skips pipe-less altsettings and selects alt 1 itself, so no usbtest
module parameters are needed.

The complete 30-case battery (all four tiers) passes on stm32f407disco,
stm32f723disco, stm32h743nucleo and stm32l476disco, including the ch9
case which now exercises 256 consecutive SET_INTERFACE cycles.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-02 22:58:39 +07:00
bda8f9cf9a example(usbtest): tier 3 - interrupt source/sink (cases 25/26)
The host usbtest driver collects interrupt pipes from the same altsetting
as the bulk pair, so the interface grows to 4 endpoints (hand-rolled
descriptor: bulk IN/OUT + interrupt IN/OUT, FS 64B interval 1 / HS 512B
interval 4) using the vendor class with CFG_TUD_VENDOR_EP_INT_OUT/IN. The
interrupt pumps mirror the bulk ones: poll + re-arm from callbacks,
self-healing across the halt tests.

Full tier-3 battery (26 cases, now incl. 25/26 interrupt write/read)
passes on stm32f407disco, stm32f723disco, stm32h743nucleo and
stm32l476disco.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-02 22:06:24 +07:00
a6e0710b22 example(usbtest): tier 2 - vendor control 0x5b/0x5c write/read-back
Gadget-Zero ctrl_out protocol: 0x5b stores the host's wLength bytes in a
1 KiB buffer (multi-packet EP0 data stage), 0x5c returns them for
comparison. bcdDevice now advertises tier 2 so the runner adds usbtest
cases 14/21. No descriptor change needed: ctrl_out is unlocked by the
Gadget Zero capability profile of the dynamic-id binding, not by
endpoints (interrupt/iso endpoints come with tiers 3/4).

Full tier-2 battery (24 cases) passes on stm32f407disco, stm32f723disco,
stm32h743nucleo and stm32l476disco.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-02 18:26:41 +07:00
152a169e9c example(usbtest): add device-side peer for Linux usbtest/testusb (tier 1: bulk source/sink)
Vendor interface with bulk IN source / bulk OUT sink implementing the
Gadget-Zero style protocol expected by the kernel usbtest driver.
Non-buffered vendor mode keeps every transfer an exact packet multiple so
the data-integrity cases never see an unexpected short packet, and polling
pumps self-heal after the endpoint-halt cases. Tier (bulk-only for now) is
advertised in bcdDevice for the host-side runner.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-02 14:37:23 +07:00
4b1c8d16f7 docs: add build-doc tooling and a README for every example
Documentation tooling:
- Add the `build-doc` skill and `tools/build_doc.py` wrapper for local
  Sphinx builds (clean / -W / open).
- Enable Markdown (MyST) in conf.py and auto-collect
  examples/{device,host,dual}/*/README.md into a 3-level Examples nav
  (Examples > Device/Host/Dual > example), noting each page's source
  location and normalizing headings to a single H1.
- Remove the stale `.claude/commands/build-doc.md`; point the AGENTS.md
  Documentation section at the skill.

Example docs:
- Add a README.md for every device/host/dual example: what it does, USB
  interface table, notable tusb_config.h settings, generic CMake + Make
  build steps, and how to try it.
- Fold each *_freertos variant into its base README, noting the FreeRTOS
  source path and any RTOS-specific behavior.

Generated docs/examples/ output is git-ignored. Builds clean with
`sphinx-build -W`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:16:25 +07:00
516fb063d8 example(midi2): update example to demonstrate multiple fb
Adds two Group Terminal Blocks (output and input) with names and
per-direction endpoint association, plus an explicit endpoint name.
2026-06-28 16:34:35 -03:00
706e4a5daa Merge remote-tracking branch 'origin/master' into add-ch58x-usbfs 2026-06-22 15:36:37 +07:00
eda704ca1a hw/bsp+wch: rename the CH58x family to ch583 and OPT_MCU_CH58X to OPT_MCU_CH583
The BSP family and MCU option were named "ch58x"/"CH58X", but the supported part is
the CH583/CH582 (and the SDK repo is openwch/ch583); CH585 is a separate MCU family,
so the CH58x umbrella was misleading. Rename to the specific family:

- hw/bsp/ch58x -> hw/bsp/ch583 (dir), and the BSP-local files ch58x_it.* ->
  ch583_it.*, system_ch58x.* -> system_ch583.* (include guards/refs updated). The
  vendor SDK files (CH58x_common.h, CH58x_*.c in hw/mcu/wch/ch583) keep their names.
- OPT_MCU_CH58X -> OPT_MCU_CH583 in tusb_option.h, tusb_mcu.h, and the shared WCH
  USBFS driver (ch32_usbfs_reg.h, dcd_ch32_usbfs.c). OPT_MCU_CH582 is kept as an
  alias (same value), so either name selects the same code.
- FAMILY_MCUS CH58X -> CH583, CFG_TUSB_MCU=OPT_MCU_CH583, mcu:CH58X -> mcu:CH583 in
  the example skip lists, the CI build matrix (ci_set_matrix.py), the get_deps family
  tag, and docs/reference/boards.rst.

Board names (ch582m_evt, yd-ch582m) are unchanged. Verified: make + cmake build for
ch582m_evt, and ci.lan HIL (all device examples pass).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 15:23:08 +07:00
ef63456eea examples: skip isochronous audio/UAC examples on CH58X
CH58x has no isochronous support (dcd_edpt_iso_alloc() returns false), but the
audio class ignores that result and the endpoints fall back to capped 64-byte
non-iso transfers, producing non-functional audio firmware. video_capture and the
FreeRTOS audio examples already carry mcu:CH58X; add it to the remaining iso
examples (audio_test, audio_4_channel_mic, audio_test_multi_rate, cdc_uac2,
uac2_headset, uac2_speaker_fb) so they are not built for CH58x.

Found by Codex review. Verified via build_utils.skip_example() that all six now
skip on ch582m_evt while control examples (e.g. cdc_msc) still build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 23:37:23 +07:00
36fa4b1536 Merge pull request #3704 from rhgndf/fix-one-dir-examples
Fix one direction endpoint examples
2026-06-19 13:55:22 +02:00
11b4cf61ef Merge pull request #3618 from hathach/copilot/fix-audio-bitfield-order-issues
fix: BE bitfield guards for audio structs and endian-safe wValue/wIndex extraction in UAC2 examples
2026-06-18 21:56:36 +07:00
d9dc891ee2 test/hil: fix esp32 audio_test_freertos (FreeRTOS tick), skip metro_m4
Enabling the audio test fleet-wide surfaced failures on esp32-p4/s3 and
metro_m4_express: the UAC mic enumerates but arecord fails the iso IN read
with EIO, while 18 other boards pass strict=1.000.

esp32: root cause is the FreeRTOS tick rate. ESP-IDF defaults
CONFIG_FREERTOS_HZ to 100, so the audio task wakes only every 10 ms and
can't service the 1 ms UAC iso frames -> underrun -> arecord EIO. (The same
dwc2 driver passes on STM32, whose FreeRTOSConfig is 1000 Hz.) Set
CONFIG_FREERTOS_HZ=1000 in the example sdkconfig.defaults; the example
defaults are honored in the generated sdkconfig alongside the BSP's, so this
takes effect.

metro_m4_express (samd51): not tick-rate -- its FreeRTOSConfig is already
1000 Hz like the passing boards -- so it's a separate iso-IN issue, skipped
for now.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 19:36:00 +07:00
3710e6e5a5 examples/uac2: drop redundant entity_id check in request helpers
The audio20 get/set entity dispatchers already extract entity_id from
wIndex and route to the matching clock / feature-unit helper, so each
helper's own entity_id re-derivation and TU_ASSERT(entity_id == ...) was
dead: the helper is only ever reached for its one entity. Unknown
entities are still rejected by the dispatcher's "not handled" path.

Remove the redundant local, the dead assert, and the constant "entity"
field from each helper's not-supported log (the message text already
identifies the entity). The local is dropped entirely rather than kept
for the log, since TU_LOG1 compiles out in release and would leave it
unused.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 17:42:51 +07:00
4498f65c46 Merge remote-tracking branch 'origin/master' into pr-3618 2026-06-18 15:55:55 +07:00