Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
141 commits
Select commit Hold shift + click to select a range
671fb8a
core: add TUD_OPT_SUPER_SPEED and register WCH CH569/CH32H417 MCUs
hathach Jul 20, 2026
99d7e67
device: add USB SuperSpeed (3.2) support to the device stack
hathach Jul 20, 2026
9638f3d
class: size endpoints and buffers for SuperSpeed (cdc, hid, msc, mtp)
hathach Jul 20, 2026
a5a592a
class: size endpoints and buffers for SuperSpeed (net, printer, usbtm…
hathach Jul 20, 2026
565f02b
wch: add CH569 (CH56x) USB3 device driver
hathach Jul 20, 2026
8be902a
wch: add CH569 (CH56x) USB high-speed device driver
hathach Jul 20, 2026
ec62a1a
wch: add CH32H417 USB3 device driver
hathach Jul 20, 2026
4ceaa5a
wch: add CH32H417 USB high-speed device driver
hathach Jul 20, 2026
bf38aa5
bsp: add CH569 hydrausb3_v1 board
hathach Jul 20, 2026
3918d50
bsp: add CH32H417 nanoch32h417 board
hathach Jul 20, 2026
2bc6b76
bsp: register WCH boards in build metadata and docs
hathach Jul 20, 2026
82f5db8
usbtest: add SuperSpeed descriptors, capability tiers, and erratum qu…
hathach Jul 20, 2026
818a52b
examples/net_lwip: place lwIP memory in RAMX for WCH CH56x
hathach Jul 20, 2026
7528d30
examples: add SuperSpeed device and configuration descriptors
hathach Jul 20, 2026
f980138
examples: skip WCH USB3 MCUs where unsupported
hathach Jul 20, 2026
a8adb7f
hil: add WCH board flashing and UART firmware loader
hathach Jul 20, 2026
109097f
hil: usbtest host quirks and capability tiers
hathach Jul 20, 2026
43cfdec
hil: skip device/usbtest on lpcxpresso43s67 pending an ip3511 baseline
hathach Jul 20, 2026
5b1c69a
test/unit-test: cover SuperSpeed in usbd tests
hathach Jul 20, 2026
a9c0a29
skills: add adding-superspeed-port and update usb debug/recover/usbtest
hathach Jul 20, 2026
55bfd4d
bsp: append -w to vendor SDK targets instead of replacing COMPILE_OPT…
hathach Aug 11, 2026
9ace700
hil: add pooled SETUP drop-rate measurement
hathach Aug 14, 2026
cf06107
docs: CH32H417 high-speed SETUP-drop investigation
hathach Aug 14, 2026
949abd3
docs: design for remediating the 16 review findings
hathach Aug 14, 2026
1868d49
docs: implementation plan for the review-findings remediation
hathach Aug 14, 2026
95f09ac
hil: do not leak the capture process when a drop-rate run fails
hathach Aug 14, 2026
82d4d82
docs: drop a plan line reference invalidated by the try/finally fix
hathach Aug 14, 2026
b7110e4
docs: scope the plan's pytest runs to test_*.py
hathach Aug 14, 2026
5da24e8
hil: keep quirk-skipped usbtest cases in the reported total
hathach Aug 14, 2026
893a1ca
hil: attribute SETUP ACKs by source, not by a hardcoded address
hathach Aug 14, 2026
1fdf68b
hil: fail fast instead of prompting on the drop-rate sudo
hathach Aug 14, 2026
245a6f8
bsp: bound the CH32H417 UART loader with an inactivity reset
hathach Aug 14, 2026
04eaef8
usbtest: advertise the quirk for the live link, not the compiled dcd
hathach Aug 14, 2026
ebd5093
wch: give the CH569 fallback ladder a single state owner
hathach Aug 14, 2026
140056d
wch: do not re-arm a retired transfer on clear-stall
hathach Aug 14, 2026
a4fc765
mtp: derive the ZLP threshold from the live bulk max packet size
hathach Aug 14, 2026
80b8476
wch: clear the CH32H417 OUT completion flag after re-arming
hathach Aug 14, 2026
d7e8c63
examples/midi2: add the descriptor callbacks its HS config requires
hathach Aug 14, 2026
f8bbdc5
device: make per-function remote wake readable and resettable
hathach Aug 14, 2026
e95718f
docs: defer the two non-regression fixes with their plan
hathach Aug 14, 2026
163e86c
Revert "wch: do not re-arm a retired transfer on clear-stall"
hathach Aug 14, 2026
da84862
docs: record F3 as refuted-by-hardware and still open
hathach Aug 14, 2026
1731fa3
Revert "wch: clear the CH32H417 OUT completion flag after re-arming"
hathach Aug 15, 2026
c0fa831
wch: do not re-arm the fallback ladder on link-partner loss
hathach Aug 15, 2026
f9dcba4
device: gate the FUNCTION REMOTE WAKEUP reset on the live link and th…
hathach Aug 15, 2026
cfe5259
docs: record F1 and F4 as attempted, reverted and still open
hathach Aug 15, 2026
38fd88d
docs: correct the F4 row now that the change is reverted
hathach Aug 15, 2026
56e695e
docs: record F9 as dropped by decision
hathach Aug 15, 2026
d40f293
wch: mask and acknowledge the CH32H417 USB2 controller on deinit
hathach Aug 15, 2026
c46ea17
wch: mark the CH32H417 cross-context driver state volatile
hathach Aug 15, 2026
2118aad
wch: discard stale link flags on the inline CH569 re-inits
hathach Aug 15, 2026
b7b4992
bsp: document .DMADATA as uninitialised-only and drop its bogus load …
hathach Aug 15, 2026
c36123a
audio: treat SuperSpeed as microframed in the feedback computation
hathach Aug 15, 2026
b95d144
docs: record the two fallback findings left alone, and what got fixed
hathach Aug 15, 2026
c118fd1
wch: recover the CH569 link when the deferred re-init is dropped
hathach Aug 16, 2026
6d1fe2d
device: scope the SetInterface wake reset, and ignore DEVICE_REMOTE_W…
hathach Aug 16, 2026
c850200
test/unit-test: make the SuperSpeed control tests self-contained
hathach Aug 16, 2026
decf777
hil, bsp: check the hammer sudo, and bound the CH569 SPI-ROM waits
hathach Aug 16, 2026
324eb4d
docs: record the 2026-08-17 review findings left open
hathach Aug 16, 2026
7f53cbb
device: ignore DEVICE_REMOTE_WAKEUP at SuperSpeed instead of stalling it
hathach Aug 18, 2026
e3e3631
Revert the SetInterface wake scoping and its DEVICE_REMOTE_WAKEUP gate
hathach Aug 18, 2026
e858056
Revert "Revert the SetInterface wake scoping and its DEVICE_REMOTE_WA…
hathach Aug 18, 2026
096dbbb
docs: record the nano's harness-only usbtest failures
hathach Aug 18, 2026
2924bc1
docs: the nano's harness-only failures were stale firmware, now resolved
hathach Aug 18, 2026
5bdd22e
wch: reset the whole EP0 and link state in the CH569 dcd_init
hathach Aug 18, 2026
0b64ef0
wch, hil: bound the stall paths and never leak the capture process
hathach Aug 18, 2026
f0d5923
wch: the CH32H417 USB3 driver is hardware-verified, not pending
hathach Aug 19, 2026
a0a9f68
wch: do not demote a trained CH569 link to USB2 on disconnect
hathach Aug 19, 2026
a58d340
docs: record the CH569 demotion fix and what remains open
hathach Aug 19, 2026
160da4d
docs: F1 now has a hardware reproducer, and recovery is intact
hathach Aug 19, 2026
1ad116c
wch: close four CH569 link-teardown and EP0 hazards
hathach Aug 20, 2026
ea65c56
wch: keep the CH32H417 disconnect mask and park EP0 IN
hathach Aug 20, 2026
b790f0e
usbd: key FUNCTION REMOTE WAKEUP by function, not by interface
hathach Aug 20, 2026
06d9b40
usbtmc: bound the endpoint descriptor walk
hathach Aug 20, 2026
aa61d9f
hil: read the DUT serial through the bounded sysfs reader
hathach Aug 20, 2026
bae3d61
docs: record what the 2026-08-21 review left open
hathach Aug 20, 2026
666b07b
bsp: trap after NVIC_SystemReset in the UART loader
hathach Sep 3, 2026
84b9491
wch: NAK an unqueued CH32H417 OUT instead of ACKing isochronous
hathach Sep 3, 2026
6a7bc64
wch: shadow the CH569 EP0 OUT toggle like the IN side
hathach Sep 3, 2026
093cc0f
docs: record the validate-run outcome and the EP0 early-OUT race
hathach Sep 3, 2026
20c0c09
bsp: add the CH569 and CH32H417 boards to family.json
hathach Oct 22, 2026
aa18fa1
hil: drop the unused tinyusb-sudoer template
hathach Oct 31, 2026
7c290c0
class/mtp: check the buffer against the SuperSpeed bulk packet size
hathach Nov 1, 2026
4b52d16
hil: drop raw sudo from hs_drop_rate and the SuperSpeed port skill
hathach Nov 1, 2026
9ac987a
test/mtp: add a SuperSpeed MTP device suite
hathach Nov 1, 2026
ad123ef
docs: record the reverted F1 re-arm and the inline warm reset in the …
hathach Nov 1, 2026
395b492
usbd: keep the SuperSpeed companion walk inside desc_end
hathach Nov 1, 2026
6c1a7de
bsp: refresh the da14695_dk_usb and msp_exp430f5529lp family.json rows
hathach Nov 1, 2026
3b60927
wch: apply cycle-6 review fixes for the SuperSpeed port
hathach Nov 1, 2026
fad6bd9
hil: note the WCH UART loader stays put after an erase
hathach Nov 1, 2026
a67e0a8
cdc: keep cdcd_open's descriptor type reads inside desc_end
hathach Nov 1, 2026
b9e7260
wch: apply cycle-9 review fixes for the SuperSpeed port
hathach Nov 1, 2026
f582119
test/usbd: share the two-function configuration and remote-wake helpers
hathach Nov 1, 2026
4d7b410
test/usbd: cover function suspend clear and aggregate remote wake
hathach Nov 1, 2026
526c95d
wch: indent with spaces in dcd_init and the new linker scripts
hathach Nov 10, 2026
77447b7
wch: release USB3 bounce slots after a bus reset
hathach Nov 10, 2026
2464998
hil: bound the WCH UART park write by the reset timeout
hathach Nov 10, 2026
0a9f4e7
wch: defer xfer completion to task context on CH569 and CH32H417
hathach Nov 10, 2026
56a47f9
wch: release CH569 USB3 bounce slots at SET_ADDRESS
hathach Nov 10, 2026
1f80a45
bsp: add CH32H417QEU6-R0 EVT board ch32h417_r0
hathach Nov 11, 2026
0424dfa
docs: remove superpowers docs
hathach Nov 11, 2026
522dee0
usbtest: drop CH32H417 high-speed quirk 0x40
hathach Nov 11, 2026
f5aff72
wch: program TIM12 with full-width counter/reload and an update event
hathach Nov 11, 2026
be66305
wch: drive the CH32H417 USB2 controller with the generic HS2 driver
hathach Nov 11, 2026
d5d2143
wch: cancel the transfer and send ERDY when a CH32H417 USB3 endpoint …
hathach Nov 11, 2026
d8a81fd
wch: cancel the transfer when a CH569 USB3 endpoint halts
hathach Nov 11, 2026
055f83f
wch: move the USB3 drivers to wch_ss1/ and wch_ss2/
hathach Nov 11, 2026
57429d9
wch: publish SS2 IN progress before arming the chain
hathach Nov 11, 2026
89e628e
wch: cancel the transfer when a CH56x USB2 endpoint halts
hathach Nov 11, 2026
24ced37
usbd: build SuperSpeed endpoint descriptors from shared blocks
hathach Nov 11, 2026
4d4aa68
examples: take SuperSpeed burst and EP0 sizes from stack options
hathach Nov 11, 2026
f53756e
wch: simplify the SS2 driver and trim CH32H417 BSP comments
hathach Nov 11, 2026
dae8967
wch: simplify the SS1 and CH56x USB2 drivers
hathach Nov 11, 2026
ba73318
test: drop the obsolete hs_drop_rate tool
hathach Nov 11, 2026
10bd58c
Merge remote-tracking branch 'origin/master' into claude/wch-ch569-ch…
hathach Nov 11, 2026
85ba019
hil: resend the WCH UART loader magic until the banner shows
hathach Nov 11, 2026
ce1f5f0
ci: key the example filter by family variant legs too
hathach Nov 11, 2026
642e2e5
usbtest: define L in the value-sweep example
hathach Nov 11, 2026
dedb7c2
cdc: require full descriptor lengths before reading endpoint and data…
hathach Nov 11, 2026
47c15ce
usbd: reject a short endpoint descriptor in usbd_open_edpt_pair
hathach Nov 11, 2026
2d5d535
examples: advertise full speed in the BOS for the CH32H417 USB2 fallback
hathach Nov 11, 2026
5960ef8
bsp: drop CFG_TUD_ENDPOINT0_SIZE from the da1469x and msp430 family.j…
hathach Nov 11, 2026
84d99af
ch569: reject a CFG_TUD_WCH_USB30_MAX_BURST outside 1..4
hathach Nov 11, 2026
b088755
wch: make the SS1 and SS2 register headers self-contained
hathach Nov 11, 2026
d949d7e
wch_ss2: drop EP0 stages of a superseded SETUP and check the HS2 fall…
hathach Nov 11, 2026
a7db1e9
wch: drop superseded EP0 stages on CH569 and fix CH56x USB2 iso OUT, …
hathach Nov 11, 2026
a56ccb0
wch_ss2: rewind only the unsent DPs when clearing halt on a busy IN e…
hathach Nov 11, 2026
69512e7
examples: share the SuperSpeed BOS wSpeedsSupported value through usbd.h
hathach Nov 11, 2026
bcefe83
examples: report bcdUSB 2.10 in the USB2 descriptors of SuperSpeed bu…
hathach Nov 12, 2026
23b0913
tusb: rename TUP_RHPORT_SUPERSPEED to an overridable CFG_TUSB_SUPER_S…
hathach Nov 12, 2026
18361c5
wch_ss1: park EP0 RX with NRDY while an early control-OUT packet is held
hathach Nov 12, 2026
ae2a851
wch_ss1: share the EP0 early-OUT drain's re-arm and select the park v…
hathach Nov 12, 2026
7d55807
docs: retire the adding-superspeed-port skill into the porting guide …
hathach Nov 12, 2026
5a716e3
wch: fix SuperSpeed review findings in slot release, headers and conf…
hathach Nov 12, 2026
7ad5f40
docs: fix SuperSpeed review findings in porting and usb concepts pages
hathach Nov 12, 2026
c818aec
wch_ss1: clear the retired-pool flag only in pool_release
hathach Nov 12, 2026
479036f
docs: list the legal Full Speed EP0 packet sizes
hathach Nov 12, 2026
f3c3199
wch_ss1: clear the retired-pool flag only for a request served after …
hathach Nov 12, 2026
12dbc19
Merge remote-tracking branch 'origin/master' into claude/wch-ch569-ch…
hathach Nov 12, 2026
d9d4228
hil: look up wch_uart_loader's probe as the WCH-LinkE VCP
hathach Nov 12, 2026
dc61e89
wch_ss1: state when SET_ADDRESS releases the slots in the open-path c…
hathach Nov 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion .claude/skills/usbtest/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ whose recovery flasher is not convoy-safe or has no probe reset are refused.
without `--recover-board` leaves a HUNG device wedged. `wedged` is also set with no HUNG case
when the serial matches two devices or cannot be read after a case; stderr names which
(`reported wedged: ...`).
- **Never hand-write a bare `echo "vid pid" > usbtest/new_id`.** A dynamic id without the 5-field
ref form (`vid pid 0 0525 a4a0`, copying Gadget Zero's driver_info) probes with driver_info=NULL:
a kernel NULL-deref Oops, a D-state testusb and a forced reboot. Binding a foreign device (a
vendor demo for an A/B) uses the same 5-field form.

## Failed case

Expand Down Expand Up @@ -126,6 +130,7 @@ under a timer.
| FAIL "did not run" | testusb never reached the ioctl (open or usage error): read the case's captured `stderr` |
| HUNG | testusb not reaped 35 s after SIGKILL |
| BUDGET | never dispatched: the battery stopped first; its detail names why |
| SKIP | never dispatched: the device's bcdDevice quirk bits declare it unsupported at this speed |

| Failing case(s) | Exercises | First suspect |
|--------------------|--------------------------------------------|----------------------------------------------------------------------------|
Expand All @@ -140,7 +145,11 @@ under a timer.

Case 29 (`test_toggle_sync`: clear halt, write, clear halt, write) is the most common DCD bug here:
reset the toggle to DATA0 **and** keep the pending transfer armed (fixed that way in rp2040
ad7acc849, fsdev 046463687, ch32_usbhs d63a45509).
ad7acc849, fsdev 046463687, ch32_usbhs 99044894a).

WCH SuperSpeed silicon fails cases 13 (CH569, CH32H417) and 14, 21 (CH569) for good and quirk-skips them
(`QUIRK_SKIPS`); the errata are in `docs/reference/device_issues.rst`. The 14/21 strike rate depends on the host: an
onboard AMD xHCI ran clean and once retired the quirk by mistake, so run it on a uPD720201 before removing a quirk.

Escalate in order:
1. The case's `detail` and captured `dmesg` in the JSON verdict (`TEST n` lines bracket each case).
Expand All @@ -150,6 +159,15 @@ Escalate in order:
3. Target-side evidence: `target-debug` (`esp-target-debug` on Espressif) on the failing case.
4. The reference manual and errata (`read-doc`) before changing any register-level code: DCD
comments have been wrong about what the hardware can do.
5. **Prove or refute "it's the silicon" with a vendor-stack A/B.** Build the vendor's reference
firmware, patch in the gadget-zero 0x5b/0x5c control store (mirror its existing control-OUT
request, ~10 lines), flash it to the same board and port, bind usbtest to the foreign VID:PID
(5-field form) and run the failing case. The same failure is an erratum (document and
quirk-skip it); a clean run puts the difference in our DCD. Nothing else closes the debate.
6. **A flake may be value-gated, not random:** sweep one parameter at a time.
`L=513; testusb -A <node> -D <node> -t 14 -c 4000 -s "$L" -v "$((L-1))"` alternates lengths 1
and L; sweeping L exposed a wLength-mod-4 gate that the stock `-s 512 -v 61` (one hot length in its
9-cycle) diluted into "0.3% random".

## Isochronous rules

Expand Down Expand Up @@ -188,6 +206,11 @@ From USB 2.0 §8.5.5 (Calibre book 775, p. 229-230):
to chase, not noise.
5. Add the board to the HIL roster (`test/hil/*.json`) when roster edits are in the task's scope;
otherwise hand it to the owner. Automated PR repair never touches the rosters.
6. **A silicon-impossible case gets a quirk flag, not a dodge.** Once proven an erratum (vendor-stack
A/B above), advertise it in bcdDevice bits 4-7 (`USBTEST_QUIRKS` in `src/usb_descriptors.h`;
skip table `QUIRK_SKIPS` in `usbtest.py`, keyed by link speed) so the battery skips it visibly
("27/30 passed, 3 skipped") instead of flaking. Never mask an erratum by tuning parameters or
dropping the board. Prove an erratum on more than one host before removing its quirk.

## Wrong profile

Expand Down
2 changes: 2 additions & 0 deletions .github/ci-pinned-boards.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
{ "board": "feather_nrf52840_express", "note": "nrf5x FS" },
{ "board": "fomu", "note": "eptri FS" },
{ "board": "frdm_k64f", "note": "ci_fs FS, host" },
{ "board": "hydrausb3_v1", "note": "ch56x usb30 SS + usbhs HS fallback" },
{ "board": "lpcxpresso11u68", "note": "ip3511 FS" },
{ "board": "lpcxpresso55s69", "note": "ip3511 HS, ohci host" },
{ "board": "max32666fthr", "note": "musb HS" },
Expand All @@ -19,6 +20,7 @@
{ "board": "mimxrt1064_evk", "note": "ci_hs HS, ehci host" },
{ "board": "mm900evxb", "note": "ft9xx HS" },
{ "board": "msp_exp430f5529lp", "note": "msp430x5xx FS" },
{ "board": "nanoch32h417", "note": "ch32h417 usb30 SS + usbhs HS" },
{ "board": "nanoch32v203", "note": "ch32 usbfs + fsdev FS, host" },
{ "board": "ra6m5_ek", "note": "rusb2 HS, host" },
{ "board": "raspberry_pi_pico", "note": "rp2040 FS, host" },
Expand Down
28 changes: 26 additions & 2 deletions .github/scripts/ci_set_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
"ch32v30x": ["riscv-gcc"],
"ch32v4x7": ["riscv-gcc"],
"ch32x035": ["riscv-gcc"],
"ch32h417": ["riscv-gcc"],
"ch569": ["riscv-gcc"],
"ch583": ["riscv-gcc"],
"cxd56": ["arm-gcc"],
"da1469x": ["arm-gcc"],
Expand Down Expand Up @@ -108,6 +110,17 @@
"xmc4000": ["arm-gcc"],
}

# family: extra build.py legs on the family's toolchains, emitted after it in every unpinned
# matrix (full or scoped) the family is in.
# The WCH SuperSpeed families default to SPEED=super, which compiles their USB2 dcd out
# entirely (dcd_ch32h417_usbhs.c) or all but its dcd_* entry points (dcd_ch56x_usbhs.c).
# One SPEED=high build per family type-checks that half; --build-name keeps its metrics.json
# out of the default build's artifact path.
family_variants = {
"ch32h417": ["-bnanoch32h417 -DSPEED=high --build-name nanoch32h417-hs"],
"ch569": ["-bhydrausb3_v1 -DSPEED=high --build-name hydrausb3_v1-hs"],
}


REPO = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# the toolchains cmake-required builds a changed board with: every one a GitHub runner
Expand Down Expand Up @@ -180,10 +193,16 @@ def required_json(select):

def example_map_json(select):
"""{family: [examples]} for build_util.yml/config2.yml's -e filter: a family that
builds every example has no entry, and an unusable selection filters nothing."""
builds every example has no entry, and an unusable selection filters nothing.
The consumers look a leg up by its whole matrix arg, so a family_variants leg is
keyed too, with its family's list."""
select = usable(select)
fams = select['build']['families'] if select else {}
print(json.dumps({f: v['examples'] for f, v in fams.items() if v['examples'] != 'all'}))
out = {}
for f, v in fams.items():
if v['examples'] != 'all':
out.update((leg, v['examples']) for leg in (f, *family_variants.get(f, ())))
print(json.dumps(out))


def leg_key(arg):
Expand Down Expand Up @@ -251,6 +270,11 @@ def set_matrix_json(select=None, pinned=False):
# family selected", not a selection to widen back to the full matrix.
keep = pinned_families()
matrix = {tc: [f for f in fams if f in keep] for tc, fams in matrix.items()}
else:
# compile checks only: the pinned (size) leg leaves them out, as membrowse_json's
# universe has no identical upload for a variant board
matrix = {tc: [leg for f in fams for leg in (f, *family_variants.get(f, ()))]
for tc, fams in matrix.items()}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
print(json.dumps(matrix))


Expand Down
45 changes: 45 additions & 0 deletions docs/porting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,51 @@ The arguments are:

Stalling is one way an endpoint can indicate failure such as when an unsupported command is transmitted. The pair of ``dcd_edpt_stall()``, ``dcd_edpt_clear_stall()`` help manage the stall state of all endpoints.

SuperSpeed
----------

To the stack, SuperSpeed is one more speed. The DCD hides the link layer (LTSSM, LMP, warm and hot reset) and
reports ordinary events; usbd only needs the operating speed to size EP0 transactions and to pick descriptors. The
reference drivers are ``src/portable/wch/wch_ss1`` (CH569, with its own USB2 driver ``dcd_ch56x_usbhs.c``) and
``src/portable/wch/wch_ss2`` (CH32H417, whose USB3 driver owns ``dcd_*`` and drives ``wch_hs2`` for the USB2
fallback).

What the port provides:

* ``CFG_TUSB_SUPER_SPEED_DEFAULT 1`` in its ``tusb_mcu.h`` block. ``TUD_OPT_SUPER_SPEED`` follows it while
``CFG_TUD_MAX_SPEED`` is left at default; ``tusb_config.h`` may override it with ``CFG_TUSB_SUPER_SPEED``.
* ``TUP_DCD_SS_BULK_BURST_PACKETS``, the bulk burst (1..16 packets) the endpoint engine handles. Examples encode
``bMaxBurst`` as ``TUD_OPT_SS_BULK_BURST_PACKETS - 1``.
* The actual link speed in every ``dcd_event_bus_reset()``: ``TUSB_SPEED_SUPER`` once the link is up, the USB2 speed
after a fallback. Where in the link bring-up to report it is the controller's choice.

A USB2 fallback on a second controller stays behind the same rhport: the USB3 driver owns ``dcd_*`` and calls the USB2
driver under a private prefix. A timer bounds SuperSpeed training and then brings USB2 up, and usbd re-initializes on
its bus reset. ``dcd_int_enable()`` runs on every task-loop queue operation without an RTOS, so it must honour the
fallback state and any vector the driver masked itself, instead of unmasking every vector.

What the stack already does:

* EP0 max packet size is fixed at 512 (USB 3.2 §9.6.1): ``CFG_TUD_ENDPOINT0_SIZE`` defaults to it, and a SuperSpeed
build rejects any other value.
* With ``CFG_TUSB_DEBUG``, ``tu_edpt_validate()`` requires a bulk max packet size of exactly 1024 (512 at high
speed); without it the check only rejects a zero size, so a release build accepts a wrong one.
* The class drivers that support SuperSpeed skip the endpoint companion that follows every endpoint descriptor
(``usbd_skip_ss_ep_companion()``) and include its bytes in the length ``open()`` returns; a class driver gaining
SuperSpeed support must do both.
* SET_SEL, SET_ISOCH_DELAY, U1/U2 enable and FUNCTION_SUSPEND are handled in ``usbd.c``.

Examples switch descriptors on ``tud_speed_get()``; ``examples/device/cdc_msc`` is the pattern: ``desc_device_ss``
(bcdUSB 0x0320, ``bMaxPacketSize0`` 9, an exponent), a USB2 device descriptor reporting bcdUSB 0x0210 in SuperSpeed
builds (USB 3.2 §9.6.1), a configuration built from the ``TUD_*_SS_DESCRIPTOR`` templates, and a BOS with the USB 2.0
extension and SuperSpeed capabilities (``TUD_BOS_SUPERSPEED_SPEEDS``).

To verify: build the examples for both the SuperSpeed and high-speed configuration; check that ``wTotalLength`` matches
the SuperSpeed configuration array (a wrong length builds and then enumerates wrong); confirm a 0-byte code-size delta on
a non-SuperSpeed board; run usbtest at 5 Gbps, and data integrity before throughput; repeat replug and suspend/resume
cycles, and the USB2 fallback on a USB2-only port. ``uhubctl -l <hub> -p <port>`` shows the link state of a hub port:
``Rx.Detect`` is receiver detection or reset, ``Polling`` is link training, ``U0`` is trained.

Validate with usbtest
---------------------

Expand Down
3 changes: 3 additions & 0 deletions docs/reference/boards.rst
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ WCH
Board Name Family URL Note
========================= ============================= ======== ===================================================================== ======
ch32f205r-r0 CH32F205r-r0 ch32f20x https://github.com/openwch/ch32f20x
ch32h417_r0 CH32H417QEU6-R0 EVT ch32h417 https://www.wch-ic.com/products/CH32H417.html
nanoch32h417 nanoCH32H417 ch32h417 https://github.com/wuxx/nanoCH32H417
ch32v103c_bluepill CH32V103C8T6-Bluepill ch32v10x https://stm32-base.org/boards/STM32F103C8T6-Blue-Pill
ch32v103r_r1_1v0 CH32V103R-R1-1v1 ch32v10x https://github.com/openwch/ch32v103/tree/main/SCHPCB/CH32V103R-R1-1v1
ch32v203c_r0_1v0 CH32V203C-R0-1v0 ch32v20x https://github.com/openwch/ch32v20x/tree/main/SCHPCB/CH32V203C-R0
Expand All @@ -391,6 +393,7 @@ ch32v307v_r1_1v0 CH32V307V-R1-1v0 ch32v30x https://gith
nanoch32v305 nanoCH32V305 ch32v30x https://github.com/wuxx/nanoCH32V305
ch32v407_r0 CH32V407VET6-EVT-R0 ch32v4x7 https://www.wch-ic.com/products/CH32V407.html
weact_ch32x035_core_board WeAct CH32X035 Core Board ch32x035 https://github.com/WeActStudio/WeActStudio.CH32X035CoreBoard
hydrausb3_v1 HydraUSB3 v1 ch569 https://github.com/hydrausb3/hydrausb3_hw
ch582m_evt CH582M-EVT evaluation board ch583 https://www.wch-ic.com/products/CH582.html
yd-ch582m yd-ch582m from vcc-gnd studio ch583 http://vcc-gnd.com/
========================= ============================= ======== ===================================================================== ======
2 changes: 2 additions & 0 deletions docs/reference/dependencies.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,13 @@ hw/mcu/st/stm32wbaxx_hal_driver https://github.com/STMicroelectronics/
hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git d60dd46996876506f1d2e9abd6b1cc110c8004cd stm32wb
hw/mcu/ti https://github.com/hathach/ti_driver.git 083944907e7d08fcb1f614b47598ce45935b8da1 msp430 msp432e4 tm4c
hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.git 77c4095087e5ed2c548ec9058e655d0b8757663b ch32f20x
hw/mcu/wch/ch32h417 https://github.com/openwch/ch32h417.git a0a56fa830b860297a64a72315a731b71c841329 ch32h417
hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git ff367d8fec5c9f40029355b2806cd059d9508e4e ch32v10x
hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git b375bbbc7dfe8642d6fb7c17e6d3207ee1c3c9c1 ch32v20x
hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 8b3699d9e4eafc3102e382b74266a1165a2bb584 ch32v30x
hw/mcu/wch/ch32v407_ch32v467 https://github.com/openwch/ch32v407_ch32v467.git 17394a1f9aa484c9b2ca0c9fdfe5730ec31c06c7 ch32v4x7
hw/mcu/wch/ch32x035 https://github.com/openwch/ch32x035.git c6253942b29ff2a3f5e2829182a874afffa45881 ch32x035
hw/mcu/wch/ch569 https://github.com/openwch/ch569.git 0424d2968d1f9802e91b9cc4b72bad75f82b342b ch569
hw/mcu/wch/ch583 https://github.com/openwch/ch583.git bd508ad7ceed48377619837051412a651952857f ch583
lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c kinetis_k kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba sam3x samd11 samd21 samd2x_l2x samd51 samd5x_e5x same5x same7x samg tm4c efm32
lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx stm32c5
Expand Down
22 changes: 22 additions & 0 deletions docs/reference/device_issues.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,28 @@ USB.5: An isochronous IN endpoint sending a 1024-byte maximum-packet-size packet
interrupt and its command/status entry is not updated. Workaround: cap the isochronous IN maximum
packet size at 1023 bytes in the descriptor.

WCH CH569/CH32H417 USBSS
------------------------
**Severity: Low**

Reference: observed during `PR #3779`_ with the Linux ``usbtest`` battery at 5 Gbps on a Renesas uPD720201 host. The
``examples/device/usbtest`` firmware declares both through its bcdDevice quirk bits, and ``test/hil/usbtest.py`` skips
the affected cases of its tier battery at 5 Gbps instead of failing them. Cases chosen with ``--tests``, and ``testusb``
run directly, still run them.

.. _PR #3779: https://github.com/hathach/tinyusb/pull/3779

**1. A halted endpoint answers a single STALL** (CH569 and CH32H417)

After ``dcd_edpt_stall()`` a SuperSpeed data endpoint answers the first transaction with a STALL TP and then nothing. A
host that retries before clearing the halt sees a transaction error instead of a second STALL. Affects usbtest case 13
(quirk 0x20).

**2. EP0 OUT data stages with wLength % 4 == 1 are intermittently dropped** (CH569)

The host sees a transaction error and the full residual. The rate depends on the host: a uPD720201 failed most runs of
usbtest cases 14 and 21 (quirk 0x10), an AMD xHCI ran clean.

WCH CH32F20x/CH32V20x/CH32V30x
---------------------------------
**Severity: High**
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Glossary
USB protocol mechanism where an endpoint responds with a STALL handshake to indicate an error condition or unsupported request. Used for error handling, not flow control.

Super Speed
USB 3.0 speed mode operating at 5 Gbps. Not supported by TinyUSB.
USB 3.0 speed mode operating at 5 Gbps. Supported in device mode on WCH CH569 and CH32H417.

tud
TinyUSB Device. Function prefix for all device stack APIs (e.g., ``tud_task()``, ``tud_cdc_write()``).
Expand Down
6 changes: 3 additions & 3 deletions docs/reference/usb_concepts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ Used for device configuration and control commands.
**Characteristics**:
- Bidirectional (uses both IN and OUT)
- Guaranteed delivery with error detection
- Limited data size (8-64 bytes per packet)
- Limited data size per packet: 8 bytes at Low Speed, 8, 16, 32 or 64 at Full Speed, 64 at High Speed, 512 at SuperSpeed
- All devices must support control transfers on endpoint 0

**Usage**: Device enumeration, configuration changes, class-specific commands

**TinyUSB Context**: Handled automatically by the core stack for standard requests; class drivers handle class-specific requests. Endpoint 0 is managed by ``src/device/usbd.c`` and ``src/host/usbh.c``. Configure buffer size with ``CFG_TUD_ENDPOINT0_SIZE`` (typically 64 bytes).
**TinyUSB Context**: Handled automatically by the core stack for standard requests; class drivers handle class-specific requests. Endpoint 0 is managed by ``src/device/usbd.c`` and ``src/host/usbh.c``. Configure buffer size with ``CFG_TUD_ENDPOINT0_SIZE`` (defaults to 64 bytes, 512 for a SuperSpeed build).

Bulk Transfers
--------------
Expand Down Expand Up @@ -252,7 +252,7 @@ USB supports multiple speed modes:

**Super Speed (5 Gbps)**:
- USB 3.0 and later
- Not supported by TinyUSB
- Supported in device mode on WCH CH569 and CH32H417 (see the SuperSpeed section of :doc:`../porting`)

**TinyUSB Speed Support**: Most TinyUSB ports support Full Speed and High Speed. Speed is typically auto-detected by hardware. Configure speed requirements in board configuration (``hw/bsp/FAMILY/boards/BOARD/board.mk``) and ensure your MCU supports the desired speed.

Expand Down
2 changes: 2 additions & 0 deletions examples/device/audio_4_channel_mic/skip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ family:espressif
mcu:CH583
mcu:CH32X035
mcu:APM32F103
mcu:CH569
mcu:CH32H417
2 changes: 2 additions & 0 deletions examples/device/audio_4_channel_mic_freertos/skip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ family:hpmicro
# same7x has no FreeRTOSConfig.h wired up in the tree (hw/bsp/same7x/FreeRTOSConfig/
# does not exist): fatal error: FreeRTOSConfig.h: No such file or directory
family:same7x
mcu:CH569
mcu:CH32H417
2 changes: 2 additions & 0 deletions examples/device/audio_test/skip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ mcu:SAMG
family:espressif
mcu:CH583
mcu:CH32X035
mcu:CH569
mcu:CH32H417
2 changes: 2 additions & 0 deletions examples/device/audio_test_freertos/skip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ family:hpmicro
# same7x has no FreeRTOSConfig.h wired up in the tree (hw/bsp/same7x/FreeRTOSConfig/
# does not exist): fatal error: FreeRTOSConfig.h: No such file or directory
family:same7x
mcu:CH569
mcu:CH32H417
2 changes: 2 additions & 0 deletions examples/device/audio_test_multi_rate/skip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ mcu:SAMG
family:espressif
mcu:CH583
mcu:CH32X035
mcu:CH569
mcu:CH32H417
board:spresense
Loading
Loading