| Age | Commit message (Collapse) | Author |
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
- 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]>
|
|
- 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]>
|
|
- 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]>
|
|
- 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]>
|
|
- 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
|
|
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]>
|
|
- 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]>
|
|
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]>
|
|
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
|
|
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
|
|
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
|
|
- 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
|
|
- 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
|
|
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
|
|
- 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
# Conflicts:
# lib/rt-thread/port/msc_device_port.c
# src/device/usbd.c
|
|
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
|
|
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
|
|
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
|
|
#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
|
|
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
|
|
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
|
|
bound rndis data packet offset in handle_incoming_packet
|
|
Signed-off-by: Javid Khan <[email protected]>
|
|
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
|
|
feat(midi2): derive function blocks from the GTB descriptor
|