summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-07-12ch32h417: make usbss_phy_cfg return void (unused read-back)worktree-ch569-hydrausb3hathach
PVS-Studio (V530) flagged the discarded return value of usbss_phy_cfg at every call site. The PHY back-door read-back is only a strobe; the value is never used (matching the WCH EVT demo), so return void. PVS found no other issues in either CH32H417 dcd. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01QWhrtHjbSVMKcY68vxBwBm
2026-07-12ch32h417: fix USB3 fallback storm, SET_ADDRESS deref, status-stage completionhathach
Apply correctness-review findings on the USBSS SuperSpeed dcd (still pre-hardware): - Critical: the LINK DISABLE fallback path left TIM12 running, so once the driver switched to USB2 (where the ISR routes to the USB2 handler and never clears the timer flag) the update flag stormed the CPU. Both fallback entry points now go through fallback_to_usb2(), which stops TIM12 first. - Critical: dcd_set_address in fallback mode called ch32h417_usb2_edpt0_status_complete with a NULL request (dereferenced immediately) and fell through into the USB3 path. It now arms the USB2 status ZLP and returns; the address is applied by the USB2 status-complete callback usbd invokes with the real request. - Major: the control STATUS stage (USBSS_UDIF_STATUS) never completed the queued zero-length status transfer, so usbd's status-stage callback never ran and EP0 stayed busy. The status ZLP does not raise a UIF_TRANSFER on this controller, so it is now completed in the UDIF_STATUS branch (and handle_ep0_in no longer completes a zero-length IN early). - Also: LINK_STATE_INACTIVE now counts toward the fallback attempt limit (matches the file header and the vendor), the LINK_CFG init uses LINK_TX_DEEMPH_MASK exactly like the WCH EVT literal, and a dead if/else in the EP0-OUT arm path is collapsed. Build-verified: both full example matrices (SPEED=super and =high) build 20/20. Remaining review notes (U1/U2/U3 PHY low-power reconfig, RECOVERY case, SET_ISOCH_ DELAY -> LINK_ISO_DLY, OUT-DMA clamp) are deferred to hardware bring-up. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01QWhrtHjbSVMKcY68vxBwBm
2026-07-12ch32h417: fix USBHS EP0 SETUP re-detect, EP0-OUT toggle, SOF dispatchhathach
Apply correctness-review findings on the USB2 HS dcd (still pre-hardware): - EP0 control OUT arming now writes the full UEP0_RX_CTRL byte (DATA1|ACK) instead of a read-modify-write, so RB_UEP_R_SETUP_IS is cleared - otherwise the data/ status OUT following a SETUP would be re-detected as a new SETUP and every control transfer after the first would break. The SETUP handler likewise writes full TX/RX bytes. This also fixes the missing DATA1 expected-toggle on a control-write data stage. - Add the SOF interrupt branch (USBHS_UDIF_RX_SOF is a top-level INT_FG bit on this IP, not an INT_ST token): dcd_sof_enable() armed SOF but the ISR dropped it, so dcd_event_sof() was never delivered. - Drop the extra INT_FG=USBHS_UDIF_TRANSFER write: the vendor acknowledges a transfer solely by clearing the per-endpoint DONE bit; the aggregate write could clear a second endpoint's still-pending completion (only one is serviced per IRQ). Build-verified (SPEED=high links). Hardware validation still pending. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01QWhrtHjbSVMKcY68vxBwBm
2026-07-12ch32h417: register in CI matrix, lwIP throughput, docs and presetshathach
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) <[email protected]> Claude-Session: https://claude.ai/code/session_01QWhrtHjbSVMKcY68vxBwBm
2026-07-12ch32h417: add USB3 SuperSpeed dcd with runtime USB2 fallbackhathach
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) <[email protected]> Claude-Session: https://claude.ai/code/session_01QWhrtHjbSVMKcY68vxBwBm
2026-07-12Add WCH CH32H417 family + nanoCH32H417 board (BSP + USB2 HS dcd)hathach
First stage of the CH32H417/CH32H416 SuperSpeed port (the second WCH SuperSpeed device family after CH569). This lands the family scaffolding and the USB2.0 high-speed device driver; the USB3 dcd is a stub for now (SPEED=super does not link yet). - tools/get_deps.py, src/tusb_option.h (OPT_MCU_CH32H417 2260 + CH32H416 alias): openwch/ch32h417 SDK dependency. - src/common/tusb_mcu.h: OPT_MCU_CH32H417 block with distinct USB IP tokens (TUP_USBIP_WCH_USB30_H417 / _USBHS_H417) so neither the CH569 nor the CH32V307 drivers match; SPEED=super|high selectors mirror the CH569 port; EP0 = 512 on SS. - hw/bsp/ch32h417: family runs entirely on the V3F core (core 0, boot core), single image in the 512 KB shared SRAM (the only SRAM on the bus matrix, USB-DMA reachable). family.c aliases USBSS/USBSS_LINK/USBHS(/TIM12) to one forwarder (the CH569 LTO identical-code-folding hazard applies), SysTick0 tick, USART1 PA9 debug, ESIG unique id. Linker derived from the EVT V3F script. Board nanoCH32H417 (MuseLab): green LED PC2 active-low, WCH-LinkE VCP on USART1. - src/portable/wch/dcd_ch32h417_usbhs.c (+ ch32h417_usbhs_reg.h, dcd_ch32h417.h): USB2.0 HS dcd for the H417 USBHS IP (per-EP INT_ST EP_DIR+EP_ID, SETUP_IS flag, DONE flags, split UEP_TX/RX_EN, NAK/STALL/ACK encoding, manual toggle). Core exposed as ch32h417_usb2_* internals for the upcoming USB3 runtime fallback; no RAMX bounce (all shared SRAM is DMA-capable, unlike CH56x). Build-verified: board_test and cdc_msc SPEED=high link cleanly under the full -Werror set (riscv-none-elf-gcc 13.2). Hardware bring-up pending (see next). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01QWhrtHjbSVMKcY68vxBwBm
2026-07-09hil: update hydrausb3_v1 flasher probe uid (WCH-Link swapped)hathach
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-09usbtest: skip silicon-impossible cases via bcdDevice quirk flagshathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08Harden the CH56x USB3 EP0 control flowhathach
Improvements from chasing the intermittent usbtest ctrl_out failure (cases 14/21) at SuperSpeed: - Process a latched status-stage completion before a simultaneously latched SETUP: with back-to-back control transfers both flags can arrive in one ISR pass and taking the SETUP first dropped the previous transfer's completion inside usbd - Status completion is recognized from either event side via a shared helper (_ep0_status_pending), and the status arm keeps both directions armed - hardware-verified that the RX engine must acknowledge the STATUS TP even for an IN status (RX unarmed makes SET_ADDRESS time out) - EP0 idles ACK-armed and an OUT data packet that lands before usbd arms the stage is held (_ep0_early_len) and delivered at arm time; the ERDY for a host-to-device data stage is signalled from the SETUP ISR (matching the reference flow) instead of only ~100 us later from task context - EP0-OUT data arms OR into RX_CTRL, preserving the live packet sequence bits like the reference's USB30_OUT_Set Known issue (documented for future work): ctrl_out remains flaky at SuperSpeed with a ~0.3% per-transfer failure rate (EPROTO on the host). Exhaustively characterized on hardware: the device receives the SETUP exactly once and arms correctly (post-arm RX_CTRL/DMA/LINK_STATUS identical to passing iterations, verified by ISR-time tracing), then the host's data DP never arrives; bulk OUT at identical sizes is error-free, host LPM off makes no difference, and neither NRDY holds, double ERDY, sequence preservation nor removing the iso endpoints change the rate. Root-causing needs a USB3 protocol analyzer or WCH silicon documentation. High speed is unaffected (30/30). Battery results with this commit: 30/30 high speed, 29/30 SuperSpeed (case 13 halt = documented silicon limitation, cases 14/21 pass most rounds). Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08Add SuperSpeed isochronous support to the CH56x USB3 dcdhathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08Pass the usbtest battery on CH569 at high and SuperSpeedhathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08Merge branch 'usbtest': Linux kernel usbtest battery supporthathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08Add agent skill: adding a SuperSpeed device port to TinyUSBhathach
Distills the CH569 port into a reusable reference for future SuperSpeed MCU ports (e.g. CH32H417): the core-stack contract a dcd must satisfy, the staged port recipe (plumbing -> USB2 dcd -> USB3 dcd -> runtime fallback), a table of hardware-validated gotchas (EP0-size status-stage deadlock, LMP timing, hot vs warm reset, training re-attempts, fallback IRQ hygiene, interrupt-alias ICF), class-driver/example descriptor conventions and the verification checklist. Skill tested per RED/GREEN: a fresh agent without it planned the port with critical errors (claimed OPT_MODE_SUPER_SPEED does not exist, omitted the LMP exchange and fallback timer design); with it, the same scenario produced a correct, complete plan. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08Reach SuperSpeed-class iperf on CH569 net_lwip_webserverhathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08Tune net_lwip_webserver lwIP memory for SuperSpeed on CH569hathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-08Retry CH569 SuperSpeed training and fix net_lwip_webserver EP0 sizehathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-07Switch CH569 port to the official openwch/ch569 SDKhathach
Replace the hydrausb3/wch-ch56x-bsp dependency with WCH's official EVT (openwch/ch569 @0424d2968); rename the family hw/bsp/ch56x -> hw/bsp/ch569 to match. Adaptations for the EVT layout and API: - family.cmake/mk: EVT/EXAM/SRC paths (Peripheral/src|inc, RVMSIS, Startup) - CH56xSFR.H case-wrapper (EVT includes the uppercase name, which breaks case-sensitive filesystems) - debug_uart: official UART1_BaudRateCfg + explicit TXD1/RXD1 pin setup (the EVT has no pin-configuring UART init) - family.c: .dmadata (RAMX) zeroing moved into board_init (EVT startup only clears .bss) and a self-contained SPI-ROM reader for the factory unique ID (the EVT flash API is a binary blob, not linked) - dcd_ch56x_usbhs.c: plain volatile casts instead of hydrausb3-only pointer typedefs - -Wno-comment for the EVT's nested header comments Validated: full 19-example CMake sweep + Make build green, 65/65 unit tests, pre-commit clean; on HydraUSB3 hardware cdc_msc_throughput enumerates at SuperSpeed 5000M with MSC 124/110 MB/s read/write (direct-IO dd). Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-07Make ch56x FREQ_SYS overridable from the build command linehathach
Allows -DFREQ_SYS=60000000 (CMake) / FREQ_SYS=60000000 (Make) for bring-up at reduced clock; default stays 120 MHz (required for USB3). USB2 HS was verified working on HydraUSB3 at 60 MHz while diagnosing flash-config-related instruction-fetch instability at 120 MHz. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-07Add SuperSpeed descriptors to all bulk/interrupt class drivers and exampleshathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
2026-07-07Add SuperSpeed support to CDC-NCM and enable iperf on CH569hathach
- 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 <[email protected]>
2026-07-07Enable 4-packet bursts on CH569 SuperSpeed bulk endpointshathach
- 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 <[email protected]>
2026-07-07Add SuperSpeed support to cdc_msc_throughput examplehathach
- 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 <[email protected]>
2026-07-07Add CH569 runtime USB2 fallback, HIL board entry and docshathach
- CFG_TUD_WCH_USB30_FALLBACK (on by default for SPEED=super): the USB3 dcd owns both controllers on rhport 0. TMR0 times out SuperSpeed link training (2x 0.5 s: shut USB3 down, then bring USB2 up); an LTSSM disabled event (SS rejected by the port) switches immediately. The active controller is dispatched at each dcd entry point; IRQ pendings are cleared on switch and dcd_int_enable is mode-aware (a stale LINK pending otherwise refires on every usbd queue unlock) - Bounded link busy-waits (LINK_STATUS busy can stick once the link is torn down) - board_get_unique_id from the factory ID in read-only info flash (0x77FE4), so the USB serial identifies the chip (HIL requirement) - HIL: replace ch582m_evt (probe moved) with hydrausb3_v1 - Regenerate boards.rst, dependencies.rst, BoardPresets.json Verified on HydraUSB3 v1 (ci rig): SuperSpeed still trains at 5000M with fallback armed (3x replug); with SS terminations disabled the device falls back and enumerates fully at 480M. Full HIL run passes 10/10 device tests including cdc_msc at SuperSpeed and cdc_msc_throughput (MSC 22.1/14.1 MBps read/write at NUMP=1); non-SuperSpeed-aware examples recover onto USB2 via the fallback. Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-07usbtest: address Codex re-review (5 findings)hathach
- rp2040 dcd_edpt_clear_stall: the toggle-reset re-issue rewound remaining_len only for IN, but bufctrl_prepare16() pre-subtracts it for OUT too, so an OUT re-issue was short by the still-armed buffers. Rewind both directions (user_buf only for IN, which advances at DPRAM-copy time). Validated: pico usbtest 30/30. - usb_recover.sh: refuse pci-rebind/reset/bind on a BDF that is not a USB controller (class 0x0c03xx), so a stray/mistyped address can't disturb storage or NICs on the shared HIL host. Guard tested against real BDFs. - ip3511 dcd_edpt_open: make it tolerant of reopening a still-armed endpoint instead of asserting it disabled -- retire via EPSKIP (UM11126 41.7.6/41.8.3) then force disabled. This is the correct ISO_ALLOC reopen contract, since usbd_edpt_close() is a no-op there. NOTE: audio/video streaming EPs already use usbd_edpt_iso_activate() on ISO_ALLOC, so there is no in-tree trigger; this is defensive hardening for a class that reopens a non-iso EP via usbd_edpt_open (e.g. a UVC device with a notification EP + VC SET_INTERFACE). Verified on HW: lpc11u37 usbtest 30/30 and video_capture SET_INTERFACE cycling both fine. - vendor_device set_alt: abort the outgoing altsetting's bulk/interrupt endpoints before dropping them, so an endpoint absent from the target altsetting can't stay armed and hold its usbd claim. (No in-tree trigger: usbtest uses a single non-zero altsetting; defensive robustness for multi-alt vendor devices.) - vendor_device tud_vendor_n_mounted(): count iso endpoints too, so an iso-only altsetting reports mounted. (No in-tree trigger: usbtest alt1 always has bulk.) Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-07Add CH569 USB3.0 SuperSpeed device driver - TinyUSB's first SuperSpeed porthathach
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 <[email protected]>
2026-07-07Add CH569/CH565 family with HydraUSB3 v1 board and USB2 HS dcdhathach
- 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 <[email protected]>
2026-07-07Add core SuperSpeed device supporthathach
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 <[email protected]>
2026-07-07usbtest: negotiated-speed int/iso refill + harden HIL sudoershathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-07usbtest: document what each battery case does in the READMEhathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-07usbtest: correct the capability-vs-runtime comment on the mps macroshathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-07address review round 3: bound the ZLP deselect spin, quote the HIL uidhathach
- dcd(rusb2): pipe_zlp_in()'s CURPIPE deselect wait gets the same spin bound as the other FIFO waits — it runs with the USB IRQ masked, where any stuck spin freezes the stack. - test/hil: quote the board uid interpolated into the shell=True usbtest invocation. Verified: ra4m1_ek 30/30 through the HIL battery. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-07address review round 2 (4 fixed, 1 answered)hathach
- 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 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-07test/hil: move ch582m_evt to boards-skip (fixture unplugged)hathach
Its board and WCH-Link failed to re-enumerate after the rig reboot and need a physical replug; skip so HIL runs stay green until then. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-07address Codex/Copilot review findings (9 fixed, 3 refuted with evidence)hathach
- 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 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06docs: add usbtest skill — porting/debugging playbook for the kernel batteryhathach
Distills the multi-DCD campaign into a reference: tier ladder, case-to-subsystem map, the recurring clear-halt bug class, iso contract rules, debug-tool escalation (incl. usbmon's toggle blindness), datasheet-outranks-comment rule, toolchain traps (clang/IAR unused, LTO+naked-asm, HWSTK), and reliability sign-off. Verified by baseline/with-skill retrieval probes. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06test/hil: serialize usbtest batteries across the board worker poolhathach
hil_test.py tests boards in a multiprocessing Pool, so the full-fleet run had many usbtest batteries running concurrently — each saturates the host controller with bulk-perf, iso streams and unlink storms, and together they hard-froze the CI rig mid-run (fatal PCIe error on the VFIO-passed xHCI; the machine rebooted). Single-board runs and the earlier sequential sweep never hit this. Add a pool-wide lock so only one battery runs at a time while other boards' ordinary tests keep going in parallel (the baseline load the rig has always handled), and raise the default pool timeout to 70 min for the serialized tail. Verified: 3-board pool run (lpcxpresso11u37, ra4m1_ek, ch32v307 usbhs+usbfs) all report ✅ 30/30 with batteries serialized, 160 s total. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06usbtest: single-pass pump for the non-FreeRTOS task (SonarCloud ↵hathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06fix CI: clang/IAR unused helpers, LTO-dropped ISR symbol, LPC11/13 USB RAM ↵hathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06usbd: restore branch changes lost in the master merge resolutionhathach
The merge conflict in usbd.c was resolved with `git checkout --theirs`, which takes master's whole file — silently discarding every auto-merged branch change: the vendord_control_xfer_cb driver registration (without it the vendor class's SET_INTERFACE/GET_INTERFACE alt-setting handling and iso/interrupt endpoint activation never run), the GET_STATUS direction hardening (process_get_status), the endpoint feature-request and clear-stall claim-release fixes. Redo the file merge 3-way and resolve only the real conflict (get_driver) to master's _builtin_driver_count form. Verified: 61/61 unit tests; ch32v307v_r1_1v0 usbhs+usbfs both 30/30 through the HIL usbtest battery (the iso cases require SET_INTERFACE alt 1, which exercises the restored registration). Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06Merge remote-tracking branch 'origin/master' into usbtesthathach
# Conflicts: # lib/rt-thread/port/msc_device_port.c # src/device/usbd.c
2026-07-06test/hil: integrate usbtest into the HIL suitehathach
Add device/usbtest to the device test battery. test_device_usbtest() waits for the cafe:4010 device to enumerate, runs usbtest.py --json against it, and shows the pass count in the report cell — "✅ 30/30" on a clean run or "❌ 29/30" on a partial, instead of a bare ✅/❌. To carry the count onto a failing cell, a test may raise TestFail(msg, metric=…); test_example() captures that metric on the final failed attempt. The report tally is now icon-aware so an icon-prefixed metric ("❌ 29/30") is counted as a failure (and "✅ …" as a pass), keeping the passed/failed/skipped totals correct. Verified end-to-end: ra4m1_ek reports "✅ 30/30"; the partial path renders "❌ N/M" and tallies as failed. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06usbtest: support CH32V307 on both USB ports (usbfs + usbhs), 30/30 eachhathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06test/hil: add nrf54lm20dk (NRF54, high-speed dwc2) to usbtest board listhathach
Passes usbtest tier-4 30/30 at high speed. J-Link OB S/N 1051856258. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06usbtest: address remaining review findings (rusb2 #11/#12, vendor #15)hathach
#12 dcd(rusb2): key the bulk-OUT clear-stall re-arm on a new per-pipe `queued` flag instead of `pipe.buf != NULL`. A zero-length OUT read leaves buf==NULL while still armed, so the old test skipped the re-assert and the endpoint NAKed forever after CLEAR_FEATURE(HALT). `queued` is set at submit and cleared at completion (and on pipe teardown). #11 dcd(rusb2): retry a zero-length IN packet that couldn't be queued at submit (double-buffered pipe full, host not draining). Previously the ZLP was dropped and the next BRDY reported a phantom completion for a packet the host never received; now it's deferred to BRDY via `zlp_pending` and only completes once actually queued and sent. #15 vendor: collapse the byte-identical bulk/interrupt/isochronous non-buffered write / write_available / read_xfer triples into three shared static-inline helpers keyed on (endpoint, epbuf, bufsize). Verified on ra4m1_ek: usbtest tier-4 30/30 (rusb2 + vendor refactor); pre-commit (format/codespell/unit) clean. The nRF54LM20 DK also passes 30/30 at high speed. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06usbtest: address code-review findings (EP3 iso regression + 9 more)hathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-06usbtest: support CH583 — its USBFS does isochronous (30/30)hathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-05Merge pull request #3756 from dxbjavid/rndis-data-offset-overflowZixun LI
bound rndis data packet offset in handle_incoming_packet
2026-07-05bound rndis data packet offset in handle_incoming_packetJavid Khan
Signed-off-by: Javid Khan <[email protected]>
2026-07-05usbtest: enable CH32V103, drop the CH32 usbfs EP3 iso special bufferhathach
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 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
2026-07-05Merge pull request #3738 from sauloverissimo/fix/midi2-fb-directionZixun LI
feat(midi2): derive function blocks from the GTB descriptor