Commit Graph

10754 Commits

Author SHA1 Message Date
d9f736dcf9 hil: enable nanoch32v203 in CI with fsdev + usbfs variants (#3707)
* hil: enable nanoch32v203 in CI with fsdev + usbfs variants
nanoch32v203 was parked in boards-skip; move it into the active pool now
that the board is wired to the ci.lan rig. Cover both USB device IPs as
build variants:
  - nanoch32v203-fsdev: RHPORT_DEVICE=0 (USBD / stm32 FSDev IP)
  - nanoch32v203-usbfs: RHPORT_DEVICE=1 (WCH USBFS IP)
2026-06-16 17:42:31 +07:00
7b791916a7 device: clamp EP0 OUT data copy to the control transfer buffer (#3705)
* device: clamp EP0 OUT data copy to the control transfer buffer

usbd_control_xfer_cb() copied xferred_bytes from the EP0 bounce buffer
into the requester's buffer with no bound. A non-compliant host that
sends an OUT data packet larger than the control transfer's data_len
(= min(len, wLength), the buffer capacity) would overflow that buffer
and over-count total_xferred. Clamp xferred_bytes to the remaining
buffer space before the memcpy and accounting.
2026-06-16 17:36:17 +07:00
14e20e9f6b Merge pull request #3700 from hathach/claude/size-report-collapse-minor
ci(metrics): collapse <1% size changes in Size Difference Report
2026-06-13 11:57:35 +07:00
594cd55084 ci(metrics): collapse <1% size changes in Size Difference Report
Wrap the "Changes <1% in size" section in a <details> block like the
"No changes" section, so the report comment only expands changes >1%.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 00:12:44 +07:00
5014146fef Merge pull request #3695 from hathach/claude/adoring-pasteur-kbaFa
Add pvs skill to run PVS-Studio analysis for a board
2026-06-11 23:19:17 +07:00
dd31ba4530 pvs skill: harden credentials parsing; note compile DB is exported by default
- Parse PVS_STUDIO_CREDENTIALS into two quoted fields (no glob/word-split).
- AGENTS.md: examples build sets CMAKE_EXPORT_COMPILE_COMMANDS ON already.

Addresses Copilot review on #3695.
2026-06-11 14:56:16 +00:00
65b2aeb6a9 pvs skill: mirror CI --security-related-issues flag and ignore SARIF output
- Add --security-related-issues to run_pvs.sh and AGENTS.md analyze commands
  so local runs reproduce the CI SAST classification (static_analysis.yml).
- Ignore *.sarif so a successful run leaves the worktree clean.

Addresses Codex review on #3695.
2026-06-11 14:53:24 +00:00
848216a6a2 Merge pull request #3693 from hathach/claude/review-model-opus
ci(claude-review): run auto review on Opus (claude-opus-4-8)
2026-06-11 21:18:10 +07:00
b643e81085 ci(claude-review): run auto review on Opus (claude-opus-4-8)
The review action currently runs on the default Sonnet 4.6. On PR #3643
(musb EP0 race) it posted "No issues found" while an Opus pass on the
same diff surfaced substantive questions (ISR-boundary RXRDY lifetime,
regression scope of the DATA-state split). Pin the reviewer to
claude-opus-4-8 for higher-signal reviews; subagents keep their cheaper
default models.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 21:13:32 +07:00
629e805e08 Merge pull request #3692 from hathach/claude/bump-claude-review-max-turns
ci(claude-review): raise --max-turns 20 -> 50
2026-06-11 19:47:01 +07:00
7f1ccdc22f Merge pull request #3636 from hathach/stm32c5 2026-06-11 19:42:22 +07:00
c9cfd829f6 ci(claude-review): raise --max-turns 20 -> 50
The Claude Code Review action runs /code-review:code-review with a hard
--max-turns cap. On large PRs (e.g. #3636 "add stm32c5 support", 29 files
/ +1689), the agent exhausts 20 turns exploring the diff before it can
produce and post its review, so the SDK returns an error and the
claude-review check fails red with:

  Reached maximum number of turns (20)

Raise the cap to 50 so port-sized PRs complete and post their review.
Cost scales with tokens, not the cap: a finished review pays the same
whether the ceiling is 25 or 50 — the cap only bites when the agent
would otherwise be force-stopped mid-run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 19:41:51 +07:00
5145b67f79 Merge remote-tracking branch 'origin/master' into stm32c5
# Conflicts:
#	README.rst
2026-06-11 17:20:15 +07:00
0244a4f12e README: use emoji for Supported CPUs status marks (#3691)
Replace the ✔/⚠/✖ status symbols in the Supported CPUs table and its
legend with  (Supported), 🟡 (Partial support) and  (Not supported by
hardware) for clearer at-a-glance scanning.
2026-06-11 17:06:49 +07:00
dffc571358 Fix stm32f723disco host/cdc_msc_hid HIL: UART RX starvation + DWC2 DMA split-IN NAK storm (#3677)
Fix stm32f723disco host HIL: UART RX starvation + DWC2 split bulk NAK/XactErr handling (#3677)
stm32f7 BSP — UART RX starvation
- The host console USART shared interrupt priority with the USB OTG ISR, so a long
  OTG interrupt could starve RXNE and drop received bytes. Raise the USART RX IRQ
  above OTG_FS/OTG_HS in both the bare-metal and FreeRTOS init paths, guarded by
  #ifdef UART_ID so boards without a UART console keep the default OTG priority.

dwc2 host — split NAK/XactErr handling
- Slave mode: a persistently-NAKing split bulk/control IN poll re-armed the
  start-split immediately, storming the ISR and starving task context. Throttle by
  disabling the channel and re-arming on the resulting halt (no frame deferral).
- Buffer-DMA mode: a pure split bulk-OUT NAK was unhandled, leaving the channel
  halted and stalling the transfer — the dominant cause of CDC echo truncation.
  Handle it by rewinding the buffer pointers and retrying the start-split
  (Programming Guide v4.20a 5.1.4.2).
- Buffer-DMA mode: a split bulk-OUT XactErr was retried immediately, exhausting
  HCD_XFER_ERROR_MAX before the transient cleared. Throttle via channel_disable +
  re-arm to give the hub TT a recovery gap, mirroring slave mode.
- All three are scoped to split transfers (hcsplt.split_en); non-split NAK/XactErr
  keep the core-handled / immediate-retry behavior. The OUT XactErr throttle also
  excludes periodic split, where channel_disable() is a no-op and would wedge the
  channel. The nak_disabled flag is generalized to retry_disabled and honors
  xfer->closing so an endpoint close during a throttled retry tears down cleanly.

Verified on stm32f723disco HIL (slave + CFG_TUH_DWC2_DMA_ENABLE): host/cdc_msc_hid,
msc_file_explorer, and device_info all pass on both variants; DMA CDC echo went
from ~15-25% raw failure to 10/10 clean.
2026-06-11 10:17:28 +07:00
6f35e76667 HIL: replace build.flags_on with named build variants (#3687)
* test/hil: replace build.flags_on with named variant schema

Boards declare build variants as `variant: [{name, flags}]` instead of
`build.flags_on`. The variant `name` is the build dir (cmake-build-<name>) and
the HIL report row; `flags` is the raw CFLAGS string (-D...=1) injected via
CFLAGS_CLI. No `variant` => a single build named after the board.

- build.py: --build-name <name> (dir) + --cflag=<token> (raw CFLAGS, repeatable,
  =form survives the matrix's shell word-splitting); drop -f1/CFLAGS wrapping.
- hil_ci_set_matrix.py: emit one build arg per variant.
- hil_test.py: iterate variants; report row + build dir = variant name.
- hil_ci.sh: copy all cmake-build-<board>* dirs for -b runs.
- get_deps.py: accept (ignore) --build-name/--cflag from matrix args.
- tinyusb.json: migrate all 6 flags_on boards to variant.

* board_test: park CI build with busy spin instead of wfe
2026-06-11 08:16:43 +07:00
575a8fbcd0 Merge pull request #3690 from hathach/claude/board-test-idle-park
hil: park boards with idle board_test instead of erasing flash
2026-06-10 18:04:54 +07:00
474ea5684d Merge pull request #3686 from hathach/update-hil-pool
HIL: add stm32u083nucleo and post test report as PR comment
2026-06-09 13:40:38 +07:00
d23e7cd222 Merge pull request #3681 from hathach/cdc_ctrl_buf
host/cdc: use local control buffer
2026-06-09 12:03:15 +07:00
8219efdc6c test/hil: erase MCU after tests; show throughput speeds in report
Teardown: instead of flashing device/board_test (a USB-less blink loop that
keeps the MCU busy-looping), erase the first flash sector (vector table) so the
board faults to idle after its tests — no USB, lower power, faster. Per-flasher
erase_<name>: openocd/openocd_adi `flash erase_sector 0 0 0`; stlink `--erase
0`; jlink erases the sector at the flash origin read from the ELF (pure-Python,
new elf_flash_origin); esptool `erase_region 0x0 0x4000`; lm4flash writes a 4 KB
all-0xFF blank image (lm4flash erases before programming, so the first sector
ends up blank). device/board_test flash remains a fallback for flashers with no
erase_ function. The teardown is no longer a report column (it's cleanup).

Report: cdc_msc_throughput and msc_file_explorer[_freertos] now return a compact
read/write speed shown in their report cell instead of the pass tick (e.g.
"C 652k/422k M 1.1M/783k", "rd 1.2MB/s"). test_example returns an optional
metric; render_matrix shows it verbatim. Firmware lookup factored into
find_firmware (reused by the erase teardown).

Verified on the rig (stm32f723disco, jlink): erase disables the board in 0.8 s
and it disappears from the bus; the throughput cell shows live speeds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 11:44:06 +07:00
1b3627d2b6 test/hil: use for skipped in HIL report
Neutral white circle for skipped, giving a // pass/fail/skip set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 17:49:07 +07:00
3875e9cde8 test/hil: use / emoji for HIL report pass/fail
Colored emoji render green/red in the GitHub PR comment, far more visible than
the monochrome ✔/✖ dingbats. Skip stays .

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 17:17:26 +07:00
fe273aa114 ci: demote Average Code Size Metrics title to h2
metrics.md (write_combine_markdown) is also used as the PR size comment when
there is no base-metrics baseline; use h2 for its title too so the sticky
comment heading is consistent (and not oversized) in that fallback case.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 16:30:19 +07:00
71f7ba0415 ci: demote sticky-comment report headings to h2; rename HIL report
The Size Difference Report and HIL comments rendered their titles at h1, which
is oversized inside a PR comment. Use h2 for both titles (with subsections
demoted to h3 to keep the hierarchy), and rename the HIL comment from
"HIL test results" to "Hardware-in-the-loop (HIL) Test Report" for consistency.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 16:28:53 +07:00
a70c5a626b ci: include hil-hfp-iar (IAR) results in the HIL PR comment
hil-hfp-iar runs hil_test.py on hfp.json built with IAR on its own rig. Upload
its report as the hil-report-hfp-iar artifact and add the job to the hil-report
combine job's needs, so the sticky comment shows a third table for the IAR rig
alongside tinyusb.json and hfp.json (gcc). The combine gate now runs if either
HIL job produced results.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 16:21:34 +07:00
7b60e3951e test/hil: clear HIL report up front on a fresh run
The report sidecar lives in a persistent dir (it survives the CI workspace
clean so accumulation works across run attempts). A full run is "fresh" and
must not merge prior state, but previously fresh only avoided *loading* the
json at merge time — if a fresh run crashed before writing the report, the
stale json/md from an earlier run lingered and a retry (fresh=False) could
merge it, or the always() upload could post it. Delete hil_report.json/.md at
the start of a fresh run so prior results can never leak.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 16:18:04 +07:00
fba8d25784 test/hil: accumulate HIL report across re-runs; post as sticky PR comment
hil_test.py persists results in a hil_report.json sidecar and regenerates
hil_report.md from it. A full run starts fresh; a re-run (--skip-board / -bt,
i.e. the .skip file) merges into the existing report so already-passed
boards/tests are preserved while only re-run cells update. The report dir is
configurable via HIL_REPORT_DIR.

build.yml: each HIL rig writes the report to a workspace-sibling dir that
survives the per-attempt workspace clean, and uploads it as an artifact. A new
hil-report job merges the rigs' reports into one sticky PR comment (marocchino)
with one table per rig.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 16:11:13 +07:00
46aded44af presets,hil: keep Ninja Multi-Config; make HIL find its output
Per review (HiFiPhile): Ninja Multi-Config is needed for IAR, otherwise the
optimization level can't be lowered to none for debug. Revert gen_presets.py
back to Ninja Multi-Config (keeping only the cmake-build-<board> binaryDir
change), and instead teach hil_test.py to locate <ex>.elf whether it sits
directly in the example dir (single-config) or under a per-config subdir like
RelWithDebInfo/ (multi-config).

Verified: stm32u083nucleo passes 13/13 remote HIL with a multi-config preset
build (rsync preserves the RelWithDebInfo/ subdir; the resolver finds it).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 15:42:00 +07:00
d38ba79ad4 test/hil: report board x test results as a markdown matrix
hil_test.py now writes hil_report.md and prints it to stdout: rows are
boards, columns are tests (bare example names), cells are pass/fail/skip.
test_example returns a per-test status, test_board collects a board x test
grid (one row per flags-on variant), and main() renders an aligned table.
A missing binary counts as skipped. hil_ci.sh copies the report back from
the remote after a run; hil_report.md is gitignored.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 15:17:20 +07:00
6586d94af0 gitattributes: keep shell scripts LF under core.autocrlf
With core.autocrlf=true, *.sh files were checked out / restored with CRLF
line endings, which breaks bash ($'\r': command not found; set: pipefail:
invalid option). Pin *.sh to eol=lf so shell scripts stay LF in the working
tree regardless of autocrlf.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 15:10:35 +07:00
88c0dc67bc Fix formatting in README.rst table (#3685) 2026-06-08 14:39:35 +07:00
752d0d7884 Fix formatting in README.rst table 2026-06-08 14:39:14 +07:00
d2e7bbb085 test/hil: add stm32u083nucleo to pool and expose ~/bin on remote PATH
Add stm32u083nucleo to the active boards in tinyusb.json, flashed via the
stlink flasher (onboard ST-Link + STM32CubeProgrammer); ci's openocd build
has no STM32U0 flash driver. STM32_Programmer_CLI lives in ~/bin on ci,
which the remote `bash -s` shell in hil_ci.sh did not have on PATH, so add
$HOME/bin to its PATH export (matching the GHA runner .path). Verified
remote: 13/13 device tests pass on ci.lan.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 14:35:07 +07:00
bfaa3b6c4f tools/gen_presets: build into cmake-build-<board> with single-config Ninja
Change the default configure preset binaryDir from build/<board> to
cmake-build-<board> (the dir name HIL expects) and switch the generator
from Ninja Multi-Config to single-config Ninja. Multi-Config nests
binaries under a RelWithDebInfo/ subdir, which hil_test.py does not look
in; single-config emits device/<ex>/<ex>.elf so preset-built firmware is
directly consumable by `hil_test.py -B examples`.

Regenerated BoardPresets.json (also picks up the tracked ch32v103c_bluepill
board that was missing from presets).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 14:34:57 +07:00
97480bad2c stm32u0: implement board_get_unique_id from UID_BASE
Previously stm32u0 had no board_get_unique_id(), so it fell back to the
weak default in hw/bsp/board.c and every board reported the placeholder
USB serial 0123456789ABCDEF. HIL identifies boards by USB serial, so a
non-unique serial collides on a multi-board rig. Read the 96-bit unique
ID from UID_BASE, mirroring stm32u5. Verified on stm32u083nucleo: now
enumerates as 300044000D5036394E373620.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 14:34:47 +07:00
7c68545ab6 ci: post auto-review findings to the PR (#3684)
Add --comment so the auto-review is actually posted on the PR.
2026-06-08 09:42:08 +07:00
8efcc6fbc4 host/cdc: use local control buffer 2026-06-06 15:27:56 +02:00
1009b14b02 add tm4c123x evk to hill pool (#3676)
* add ek_tm4c123gxl to the hil pool, flashing with lm4flash
2026-06-05 21:23:40 +07:00
9dea2c8f39 ci: carry metrics baseline forward on no-code-change pushes (#3678)
* ci: carry metrics baseline forward on no-code-change pushes

The code-metrics job is gated on code_changed and only uploads the
metrics-tinyusb artifact on push, so a workflow/docs-only push to master (e.g.
removing an unrelated workflow) leaves the latest master Build run without a
baseline. PRs download the baseline from the latest master run, so the size
comparison then finds nothing and silently falls back to absolute sizes.

Add a small metrics-carry-forward job that, on a non-code-change push, downloads
the previous metrics-tinyusb artifact and re-publishes it, so the latest run
always carries a usable baseline. Carry-forward runs re-upload too, so the
baseline chains across consecutive no-code pushes (bounded by artifact retention).
2026-06-05 14:34:27 +07:00
c3b4ef03aa Compact pvs skill; fix PVS-Studio -S/--dump-files docs in AGENTS.md
The AGENTS.md '-S src/foo.c' example was inaccurate: -S takes a plaintext
file listing source paths, not paths directly. Drop --dump-files from the
documented commands (it scatters .PVS-Studio.i/.cfg dumps across the tree;
FP-debugging only) and reference the new pvs skill.

https://claude.ai/code/session_015inWmFhRYSq17CxMukdoqX
2026-06-05 07:30:23 +00:00
de756315ec Add pvs skill to run PVS-Studio analysis for a board
Bundle a run_pvs.sh helper (takes BOARD as its first argument) that
follows the PVS-Studio static-analysis flow from AGENTS.md: build all
examples with an exported compile_commands.json, run pvs-studio-analyzer
against .PVS-Studio/.pvsconfig, then emit errorfile + SARIF reports.

https://claude.ai/code/session_015inWmFhRYSq17CxMukdoqX
2026-06-05 07:27:50 +00:00
ddc065dc9f Remove Sponsor Triage workflow (migrated to hathach/hathach) (#3675)
This personal automation now lives in the hathach/hathach repo alongside the
other personal project-sync workflows; it has no place in the tinyusb library.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 21:59:59 +07:00
38debe00ba Merge pull request #3666 from hathach/dwc2_postfix
dwc2 postfixes
2026-06-04 21:55:12 +07:00
a105f9d099 Merge pull request #3653 from hathach/ch32_warning
add device specific issues
2026-06-04 21:19:17 +07:00
a900ea93db dwc2: cleanup setup_packet pointer cast (review feedback)
Cast DOEPDMA0 through uintptr_t and use sizeof(tusb_control_request_t)
instead of the magic constant 8, matching project convention. Add a
reference to Programming Guide v4.20a 9.1.2.1 for the DOEPDMAn-8 rule.

Addresses Copilot review comment; no functional change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 20:46:49 +07:00
b5e080732e Update setup buffer size definition based on DMA configuration 2026-06-04 17:55:44 +07:00
0393a5eaa1 Merge branch 'master' into dwc2_postfix 2026-06-04 15:31:45 +07:00
ac32feafeb ci(labeler): auto-apply Port labels from changed driver files (#3673)
* ci(labeler): auto-apply Port labels from changed driver files

Add path-based labeling so a PR touching a dcd/hcd driver under
src/portable/ gets the matching "Port <ip>" label automatically.
2026-06-04 15:18:40 +07:00
3d0516f439 ci(labeler): match emoji-renamed labels (#3672)
Labels were renamed to add emojis (Adafruit 🌸, Sponsor 💖, Prio 🚩,
Prio Top 🚨); update the hardcoded label names in the labeler script
to match so they attach to the existing labels instead of recreating
plain ones.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 14:27:54 +07:00
709b33d848 ci: bump actions/github-script v7 -> v8 (Node.js 24) (#3671)
Node.js 20 actions are deprecated; v8 runs on Node.js 24.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 13:55:17 +07:00