diff --git a/.idea/cmake.xml b/.idea/cmake.xml
index 14dbdfe66..23e8af7ea 100644
--- a/.idea/cmake.xml
+++ b/.idea/cmake.xml
@@ -5,9 +5,9 @@
-
+
-
+
diff --git a/.idea/debugServers/lpc43s67.xml b/.idea/debugServers/lpc43s67.xml
new file mode 100644
index 000000000..14af905e2
--- /dev/null
+++ b/.idea/debugServers/lpc43s67.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/debugServers/lpc55s28.xml b/.idea/debugServers/lpc55s28.xml
new file mode 100644
index 000000000..afaae7368
--- /dev/null
+++ b/.idea/debugServers/lpc55s28.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/debugServers/nrf52840.xml b/.idea/debugServers/nrf52840.xml
new file mode 100644
index 000000000..11312a551
--- /dev/null
+++ b/.idea/debugServers/nrf52840.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/debugServers/nrf54lm20.xml b/.idea/debugServers/nrf54lm20.xml
new file mode 100644
index 000000000..3a0e40eed
--- /dev/null
+++ b/.idea/debugServers/nrf54lm20.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/debugServers/sam70.xml b/.idea/debugServers/sam70.xml
new file mode 100644
index 000000000..6659a857d
--- /dev/null
+++ b/.idea/debugServers/sam70.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/debugServers/stm32f407.xml b/.idea/debugServers/stm32f407.xml
new file mode 100644
index 000000000..660c182e1
--- /dev/null
+++ b/.idea/debugServers/stm32f407.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/debugServers/stm32h7s3.xml b/.idea/debugServers/stm32h7s3.xml
new file mode 100644
index 000000000..8ba7a5b70
--- /dev/null
+++ b/.idea/debugServers/stm32h7s3.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/debugServers/stm32l476.xml b/.idea/debugServers/stm32l476.xml
new file mode 100644
index 000000000..457908d01
--- /dev/null
+++ b/.idea/debugServers/stm32l476.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/editor.xml b/.idea/editor.xml
new file mode 100644
index 000000000..07792cad7
--- /dev/null
+++ b/.idea/editor.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 000000000..7ed4f1ab9
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/runConfigurations/k64f.xml b/.idea/runConfigurations/k64f.xml
deleted file mode 100644
index 6db0dd74e..000000000
--- a/.idea/runConfigurations/k64f.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/kl25.xml b/.idea/runConfigurations/kl25.xml
deleted file mode 100644
index bb7e1707b..000000000
--- a/.idea/runConfigurations/kl25.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/lpc1857.xml b/.idea/runConfigurations/lpc1857.xml
deleted file mode 100644
index ef8178e08..000000000
--- a/.idea/runConfigurations/lpc1857.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/lpc4088.xml b/.idea/runConfigurations/lpc4088.xml
deleted file mode 100644
index 6c6886f30..000000000
--- a/.idea/runConfigurations/lpc4088.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/lpc54628.xml b/.idea/runConfigurations/lpc54628.xml
deleted file mode 100644
index 4b871d543..000000000
--- a/.idea/runConfigurations/lpc54628.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/lpc55s69.xml b/.idea/runConfigurations/lpc55s69.xml
deleted file mode 100644
index 7ab9fac66..000000000
--- a/.idea/runConfigurations/lpc55s69.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/mcx947.xml b/.idea/runConfigurations/mcx947.xml
deleted file mode 100644
index 2a9805145..000000000
--- a/.idea/runConfigurations/mcx947.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/nrf52840.xml b/.idea/runConfigurations/nrf52840.xml
deleted file mode 100644
index 5a4f4837b..000000000
--- a/.idea/runConfigurations/nrf52840.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/nrf5340.xml b/.idea/runConfigurations/nrf5340.xml
deleted file mode 100644
index bf1cb2938..000000000
--- a/.idea/runConfigurations/nrf5340.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/ra2a1.xml b/.idea/runConfigurations/ra2a1.xml
deleted file mode 100644
index d50b3d729..000000000
--- a/.idea/runConfigurations/ra2a1.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/ra4m1.xml b/.idea/runConfigurations/ra4m1.xml
deleted file mode 100644
index 0cccb60d2..000000000
--- a/.idea/runConfigurations/ra4m1.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/ra6m1.xml b/.idea/runConfigurations/ra6m1.xml
deleted file mode 100644
index 5efd47753..000000000
--- a/.idea/runConfigurations/ra6m1.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/ra6m5.xml b/.idea/runConfigurations/ra6m5.xml
deleted file mode 100644
index 713fc68cc..000000000
--- a/.idea/runConfigurations/ra6m5.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/rt1010.xml b/.idea/runConfigurations/rt1010.xml
deleted file mode 100644
index c3582512c..000000000
--- a/.idea/runConfigurations/rt1010.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/rt1060.xml b/.idea/runConfigurations/rt1060.xml
deleted file mode 100644
index 649fe6dac..000000000
--- a/.idea/runConfigurations/rt1060.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/samd21g18.xml b/.idea/runConfigurations/samd21g18.xml
deleted file mode 100644
index 2ea822493..000000000
--- a/.idea/runConfigurations/samd21g18.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/samd51j19.xml b/.idea/runConfigurations/samd51j19.xml
deleted file mode 100644
index b6cbe253a..000000000
--- a/.idea/runConfigurations/samd51j19.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/stlink.xml b/.idea/runConfigurations/stlink.xml
deleted file mode 100644
index e84445add..000000000
--- a/.idea/runConfigurations/stlink.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/stm32g474.xml b/.idea/runConfigurations/stm32g474.xml
deleted file mode 100644
index 600b1e555..000000000
--- a/.idea/runConfigurations/stm32g474.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/stm32h563.xml b/.idea/runConfigurations/stm32h563.xml
deleted file mode 100644
index 9c0ffc2ec..000000000
--- a/.idea/runConfigurations/stm32h563.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/stm32h743.xml b/.idea/runConfigurations/stm32h743.xml
deleted file mode 100644
index 1565e92cd..000000000
--- a/.idea/runConfigurations/stm32h743.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/stm32u5a5.xml b/.idea/runConfigurations/stm32u5a5.xml
deleted file mode 100644
index 92a1293be..000000000
--- a/.idea/runConfigurations/stm32u5a5.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/uno_r4.xml b/.idea/runConfigurations/uno_r4.xml
deleted file mode 100644
index c69e2939c..000000000
--- a/.idea/runConfigurations/uno_r4.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/AGENTS.md b/AGENTS.md
deleted file mode 100644
index f69083697..000000000
--- a/AGENTS.md
+++ /dev/null
@@ -1,213 +0,0 @@
-# TinyUSB Agent Instructions
-
-TinyUSB is a cross-platform USB Host/Device stack for embedded systems: memory-safe (no dynamic allocation) and thread-safe (ISR events deferred to task context).
-
-Reference these instructions first; fall back to search/bash only when reality diverges.
-
-## Behavioral Guidelines
-
-Bias toward caution over speed. For trivial tasks, use judgment.
-
-- **Think first** — state assumptions; ask if unclear; present alternatives instead of picking silently.
-- **Simplicity** — no features, abstractions, flexibility, or error handling beyond what was asked. If 200 lines could be 50, rewrite.
-- **Surgical changes** — touch only what the task requires; match existing style; don't refactor working code; mention unrelated dead code rather than deleting it. Remove only orphans *your* changes created.
-- **Goal-driven** — turn tasks into verifiable goals ("write failing test, make it pass"). For multi-step work, state a brief `step → verify` plan.
-- **Worktrees** — default to a git worktree (`git worktree add`) for any branch or multi-step work; never switch the shared primary checkout's branch. Sessions run concurrently: switching the primary checkout mid-flight disrupts other sessions and can silently point a review, build, or commit at the wrong diff. Only trivial one-shot fixes may skip this.
-
-## Ground Rules
-
-- **Language/style:** C99, 2-space indent (no tabs), snake_case helpers, `UPPER_CASE` macros. Public APIs use `tud_`/`tuh_`; macros use `TU_`. Headers self-contained with `#if CFG_TUSB_MCU` guards.
-- **Safety:** no dynamic allocation; defer ISR work to task context; use `TU_ASSERT()` for error checks; always check return values; include order: C stdlib → tusb common → drivers → classes.
-- **Layout:** `src/` core, `hw/{mcu,bsp}/` MCU+BSP, `examples/{device,host,dual}/`, `test/{unit-test,fuzz,hil}/`, `docs/`, `tools/`.
-- **Commits/PRs:** imperative mood, scoped changes, link issues, include test/build evidence. After opening a PR, monitor it and drive it to green: address automated review comments (Copilot/Codex/Claude) and fix any failing CI builds, pushing follow-up commits until checks pass and review threads are resolved. Useful: `gh pr checks --watch`, `gh pr view --comments`.
-- **Formatting/lint:** `clang-format` (`.clang-format`), `codespell` (`.codespellrc`), run `pre-commit run --all-files` before submitting.
-
-## Bootstrap
-
-```bash
-sudo apt-get install -y gcc-arm-none-eabi # ARM toolchain (2-5 min, one-time)
-python3 tools/get_deps.py [FAMILY|-b BOARD] # fetch deps into lib/, hw/mcu/ (<1 s)
-. $HOME/code/esp-idf/export.sh # Espressif only: before any build/flash/monitor
-```
-
-## Build
-
-Single example (CMake+Ninja, recommended, 1-3 s):
-```bash
-cd examples/device/cdc_msc && mkdir -p build && cd build
-cmake -DBOARD=raspberry_pi_pico -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel ..
-cmake --build .
-```
-
-All examples for a board (15-20 s; some objcopy failures are non-critical). Use `cmake-build-` as the build dir — HIL tests expect that exact name:
-```bash
-cd examples
-cmake -B cmake-build-raspberry_pi_pico -DBOARD=raspberry_pi_pico -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel .
-cmake --build cmake-build-raspberry_pi_pico
-```
-
-Single example with Make:
-```bash
-cd examples/device/cdc_msc && make BOARD=raspberry_pi_pico all
-```
-
-Espressif (only ESP-IDF examples like `cdc_msc_freertos`):
-```bash
-. $HOME/code/esp-idf/export.sh
-cd examples/device/cdc_msc_freertos
-idf.py -DBOARD=espressif_s3_devkitc build
-```
-
-**Build options** (CMake `-D…` / Make `…=…`):
-- Debug: `CMAKE_BUILD_TYPE=Debug` / `DEBUG=1`
-- Logging: `LOG=2` (add `LOGGER=rtt` for RTT)
-- Root hub port: `RHPORT_DEVICE=1`
-- Speed: `RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED`
-
-## Flash
-
-```bash
-# JLink
-ninja cdc_msc-jlink # CMake
-make BOARD= flash-jlink # Make
-
-# OpenOCD
-ninja cdc_msc-openocd # CMake
-make BOARD= flash-openocd # Make
-
-# UF2
-ninja cdc_msc-uf2 # CMake
-make BOARD= all uf2 # Make
-
-ninja -t targets # list CMake targets
-
-# Espressif (after . $HOME/code/esp-idf/export.sh)
-idf.py -DBOARD= flash
-idf.py -DBOARD= monitor
-```
-
-## GDB Debugging
-
-Look up `JLINK_DEVICE` / `OPENOCD_OPTION` in `hw/bsp/*/boards/*/board.cmake` (CMake builds) or `board.mk` (Make builds).
-
-**JLink — Terminal 1:**
-```bash
-JLinkGDBServer -device stm32h743xi -if SWD -speed 4000 -port 2331 -swoport 2332 -telnetport 2333 -nogui
-```
-
-**OpenOCD — Terminal 1:**
-```bash
-openocd -f interface/stlink.cfg -f target/stm32h7x.cfg
-# or with a J-Link interface:
-openocd -f interface/jlink.cfg -f target/stm32h7x.cfg
-# rp2040/rp2350 via CMSIS-DAP:
-openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000"
-```
-
-**Terminal 2 — connect GDB** (replace `` with `2331` for JLinkGDBServer or `3333` for OpenOCD):
-```bash
-arm-none-eabi-gdb /tmp/build/firmware.elf
-(gdb) target remote :
-(gdb) monitor reset halt
-(gdb) load
-(gdb) break main # optional, to stop at entry
-(gdb) continue
-```
-
-**RTT logging:** build with `LOG=2 LOGGER=rtt`, flash, then run JLinkGDBServer with `-RTTTelnetPort 19021`, and in another terminal `JLinkRTTClient` (pipe to `tee rtt.log` or use `timeout 20s JLinkRTTClient > rtt.log` for non-interactive capture).
-
-## Testing
-
-**Unit (Ceedling, Unity+CMock, ~4 s):**
-```bash
-sudo gem install ceedling
-cd test/unit-test && ceedling test:all # or ceedling test:test_fifo
-```
-
-**HIL (2-5 min):** invoke the `hil` skill (`.claude/skills/hil/SKILL.md`) for the full procedure (local vs remote mode, config selection, SSH copy steps, debugging tips). Requires pre-built examples — see Build → "All examples for a board".
-
-## Documentation
-
-Sphinx docs in `docs/` (reStructuredText `.rst` or Markdown `.md` via MyST). Use the `build-doc` skill (`.claude/skills/build-doc/SKILL.md`) to build/preview locally (`sphinx-build`) and to regenerate auto-generated files (`tools/gen_doc.py` + `tools/gen_presets.py`) after adding a board or dependency.
-
-## Code Size Metrics
-
-Verify size impact before committing. Invoke the `code-size` skill (`.claude/skills/code-size/SKILL.md`) — it wraps `tools/metrics_compare_base.py` to handle the base-vs-branch worktree + build + compare flow.
-
-Quick reference:
-```bash
-# Single example, one board:
-python3 tools/metrics_compare_base.py -b raspberry_pi_pico -e device/cdc_msc
-# Add --bloaty for section/symbol breakdown.
-
-# All examples, one board:
-python3 tools/metrics_compare_base.py -b raspberry_pi_pico
-
-# All arm-gcc CI families combined (pre-merge sweep, 4-8 min):
-python3 tools/metrics_compare_base.py --ci
-```
-
-Reports land in `cmake-metrics//metrics_compare.md` (per-board) and `cmake-metrics/_combined/metrics_compare.md` (with `--combined`/`--ci`).
-
-## Static Analysis (PVS-Studio)
-
-Requires `compile_commands.json`, which the examples build exports by default
-(`hw/bsp/family_support.cmake` sets `CMAKE_EXPORT_COMPILE_COMMANDS ON`). The
-`pvs` skill (`.claude/skills/pvs/SKILL.md`) wraps the build + analyze flow for a
-board; the commands below are the underlying steps.
-
-```bash
-# Whole project:
-pvs-studio-analyzer analyze \
- -f examples/cmake-build-raspberry_pi_pico/compile_commands.json \
- -R .PVS-Studio/.pvsconfig \
- -o pvs-report.log -j12 \
- --security-related-issues \
- --misra-c-version 2023 --misra-cpp-version 2008 --use-old-parser
-
-# Specific files: -S takes a plaintext list (one path per line), not paths directly:
-printf 'src/foo.c\nsrc/bar.c\n' > files.txt
-pvs-studio-analyzer analyze \
- -f examples/cmake-build-raspberry_pi_pico/compile_commands.json \
- -R .PVS-Studio/.pvsconfig \
- -S files.txt \
- -o pvs-report.log -j12 \
- --security-related-issues \
- --misra-c-version 2023 --misra-cpp-version 2008 --use-old-parser
-
-plog-converter -a GA:1,2 -t errorfile pvs-report.log # view results
-```
-
-Takes ~10-30 s. (`--dump-files` adds preprocessed `.PVS-Studio.i/.cfg` dumps next
-to every source for false-positive debugging — omit it for normal runs.)
-
-## Validation After Changes
-
-1. `pre-commit run --all-files` — format, spell, unit tests (10-15 s).
-2. Build at least one board's full example set (Build → "All examples for a board") for modules you touched.
-3. Run relevant unit tests; add fuzz/HIL coverage for parsers or protocol state machines.
-
-**Boards good for local testing:**
-- `stm32f407disco` — no external SDK
-- `raspberry_pi_pico` — Pico SDK required
-- Others: see `hw/bsp/FAMILY/boards/`
-
-Device examples need real hardware to validate runtime behavior; must at least build.
-
-## Release
-
-Cutting a release — version bump, regenerated files, the per-release changelog, validation, and the maintainer's commit/tag/GitHub-release — is handled by the `make-release` skill (`.claude/skills/make-release/SKILL.md`).
-
-## References
-
-- MCU reference manuals, datasheets, schematics: `$HOME/Documents/calibre-library`.
-- Supported MCUs/boards: `hw/bsp/` and `docs/reference/boards.rst`.
-- USB classes: `src/class/{cdc,hid,msc,audio,…}/` — each has `*_device.c` and `*_host.c`.
-- Key files: `src/tusb.h`, `src/tusb_config.h`, `tools/get_deps.py`, `tools/build.py`, `test/unit-test/project.yml`.
-
-## Common Build Issues
-
-- Missing compiler → install `gcc-arm-none-eabi`.
-- Missing deps → `python3 tools/get_deps.py FAMILY`.
-- Unknown board → check `hw/bsp/FAMILY/boards/`.
-- `objcopy` errors in full builds are often non-critical; retry the single example.
diff --git a/AGENTS.md b/AGENTS.md
new file mode 120000
index 000000000..681311eb9
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1 @@
+CLAUDE.md
\ No newline at end of file
diff --git a/CLAUDE.md b/CLAUDE.md
deleted file mode 120000
index 47dc3e3d8..000000000
--- a/CLAUDE.md
+++ /dev/null
@@ -1 +0,0 @@
-AGENTS.md
\ No newline at end of file
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 000000000..c902e2b62
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,213 @@
+# TinyUSB Agent Instructions
+
+TinyUSB is a cross-platform USB Host/Device stack for embedded systems: memory-safe (no dynamic allocation) and thread-safe (ISR events deferred to task context).
+
+Reference these instructions first; fall back to search/bash only when reality diverges.
+
+## Behavioral Guidelines
+
+Bias toward caution over speed. For trivial tasks, use judgment.
+
+- **Think first** — state assumptions; ask if unclear; present alternatives instead of picking silently.
+- **Simplicity** — no features, abstractions, flexibility, or error handling beyond what was asked. If 200 lines could be 50, rewrite.
+- **Surgical changes** — touch only what the task requires; match existing style; don't refactor working code; mention unrelated dead code rather than deleting it. Remove only orphans *your* changes created.
+- **Goal-driven** — turn tasks into verifiable goals ("write failing test, make it pass"). For multi-step work, state a brief `step → verify` plan.
+- **Worktrees** — default to a git worktree for any branch or multi-step work; never switch the shared primary checkout's branch. Sessions run concurrently: switching the primary checkout mid-flight disrupts other sessions and can silently point a review, build, or commit at the wrong diff. Only trivial one-shot fixes may skip this. Standard location: `.worktrees/` at the repo root (gitignored), e.g. `git worktree add .worktrees/my-branch -b my-branch`.
+
+## Ground Rules
+
+- **Language/style:** C99, 2-space indent (no tabs), snake_case helpers, `UPPER_CASE` macros. Public APIs use `tud_`/`tuh_`; macros use `TU_`. Headers self-contained with `#if CFG_TUSB_MCU` guards.
+- **Safety:** no dynamic allocation; defer ISR work to task context; use `TU_ASSERT()` for error checks; always check return values; include order: C stdlib → tusb common → drivers → classes.
+- **Layout:** `src/` core, `hw/{mcu,bsp}/` MCU+BSP, `examples/{device,host,dual}/`, `test/{unit-test,fuzz,hil}/`, `docs/`, `tools/`.
+- **Commits/PRs:** imperative mood, scoped changes, link issues, include test/build evidence. After opening a PR, monitor it and drive it to green: address automated review comments (Copilot/Codex/Claude) and fix any failing CI builds, pushing follow-up commits until checks pass and review threads are resolved. Useful: `gh pr checks --watch`, `gh pr view --comments`.
+- **Formatting/lint:** `clang-format` (`.clang-format`), `codespell` (`.codespellrc`), run `pre-commit run --all-files` before submitting.
+
+## Bootstrap
+
+```bash
+sudo apt-get install -y gcc-arm-none-eabi # ARM toolchain (2-5 min, one-time)
+python3 tools/get_deps.py [FAMILY|-b BOARD] # fetch deps into lib/, hw/mcu/ (<1 s)
+. $HOME/code/esp-idf/export.sh # Espressif only: before any build/flash/monitor
+```
+
+## Build
+
+Single example (CMake+Ninja, recommended, 1-3 s):
+```bash
+cd examples/device/cdc_msc && mkdir -p build && cd build
+cmake -DBOARD=raspberry_pi_pico -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel ..
+cmake --build .
+```
+
+All examples for a board (15-20 s; some objcopy failures are non-critical). Use `cmake-build-` as the build dir — HIL tests expect that exact name:
+```bash
+cd examples
+cmake -B cmake-build-raspberry_pi_pico -DBOARD=raspberry_pi_pico -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel .
+cmake --build cmake-build-raspberry_pi_pico
+```
+
+Single example with Make:
+```bash
+cd examples/device/cdc_msc && make BOARD=raspberry_pi_pico all
+```
+
+Espressif (only ESP-IDF examples like `cdc_msc_freertos`):
+```bash
+. $HOME/code/esp-idf/export.sh
+cd examples/device/cdc_msc_freertos
+idf.py -DBOARD=espressif_s3_devkitc build
+```
+
+**Build options** (CMake `-D…` / Make `…=…`):
+- Debug: `CMAKE_BUILD_TYPE=Debug` / `DEBUG=1`
+- Logging: `LOG=2` (add `LOGGER=rtt` for RTT)
+- Root hub port: `RHPORT_DEVICE=1`
+- Speed: `RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED`
+
+## Flash
+
+```bash
+# JLink
+ninja cdc_msc-jlink # CMake
+make BOARD= flash-jlink # Make
+
+# OpenOCD
+ninja cdc_msc-openocd # CMake
+make BOARD= flash-openocd # Make
+
+# UF2
+ninja cdc_msc-uf2 # CMake
+make BOARD= all uf2 # Make
+
+ninja -t targets # list CMake targets
+
+# Espressif (after . $HOME/code/esp-idf/export.sh)
+idf.py -DBOARD= flash
+idf.py -DBOARD= monitor
+```
+
+## GDB Debugging
+
+Look up `JLINK_DEVICE` / `OPENOCD_OPTION` in `hw/bsp/*/boards/*/board.cmake` (CMake builds) or `board.mk` (Make builds).
+
+**JLink — Terminal 1:**
+```bash
+JLinkGDBServer -device stm32h743xi -if SWD -speed 4000 -port 2331 -swoport 2332 -telnetport 2333 -nogui
+```
+
+**OpenOCD — Terminal 1:**
+```bash
+openocd -f interface/stlink.cfg -f target/stm32h7x.cfg
+# or with a J-Link interface:
+openocd -f interface/jlink.cfg -f target/stm32h7x.cfg
+# rp2040/rp2350 via CMSIS-DAP:
+openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000"
+```
+
+**Terminal 2 — connect GDB** (replace `` with `2331` for JLinkGDBServer or `3333` for OpenOCD):
+```bash
+arm-none-eabi-gdb /tmp/build/firmware.elf
+(gdb) target remote :
+(gdb) monitor reset halt
+(gdb) load
+(gdb) break main # optional, to stop at entry
+(gdb) continue
+```
+
+**RTT logging:** build with `LOG=2 LOGGER=rtt`, flash, then run JLinkGDBServer with `-RTTTelnetPort 19021`, and in another terminal `JLinkRTTClient` (pipe to `tee rtt.log` or use `timeout 20s JLinkRTTClient > rtt.log` for non-interactive capture).
+
+## Testing
+
+**Unit (Ceedling, Unity+CMock, ~4 s):**
+```bash
+sudo gem install ceedling
+cd test/unit-test && ceedling test:all # or ceedling test:test_fifo
+```
+
+**HIL (2-5 min):** invoke the `hil` skill (`.claude/skills/hil/SKILL.md`) for the full procedure (local vs remote mode, config selection, SSH copy steps, debugging tips). Requires pre-built examples — see Build → "All examples for a board".
+
+## Documentation
+
+Sphinx docs in `docs/` (reStructuredText `.rst` or Markdown `.md` via MyST). Use the `build-doc` skill (`.claude/skills/build-doc/SKILL.md`) to build/preview locally (`sphinx-build`) and to regenerate auto-generated files (`tools/gen_doc.py` + `tools/gen_presets.py`) after adding a board or dependency.
+
+## Code Size Metrics
+
+Verify size impact before committing. Invoke the `code-size` skill (`.claude/skills/code-size/SKILL.md`) — it wraps `tools/metrics_compare_base.py` to handle the base-vs-branch worktree + build + compare flow.
+
+Quick reference:
+```bash
+# Single example, one board:
+python3 tools/metrics_compare_base.py -b raspberry_pi_pico -e device/cdc_msc
+# Add --bloaty for section/symbol breakdown.
+
+# All examples, one board:
+python3 tools/metrics_compare_base.py -b raspberry_pi_pico
+
+# All arm-gcc CI families combined (pre-merge sweep, 4-8 min):
+python3 tools/metrics_compare_base.py --ci
+```
+
+Reports land in `cmake-metrics//metrics_compare.md` (per-board) and `cmake-metrics/_combined/metrics_compare.md` (with `--combined`/`--ci`).
+
+## Static Analysis (PVS-Studio)
+
+Requires `compile_commands.json`, which the examples build exports by default
+(`hw/bsp/family_support.cmake` sets `CMAKE_EXPORT_COMPILE_COMMANDS ON`). The
+`pvs` skill (`.claude/skills/pvs/SKILL.md`) wraps the build + analyze flow for a
+board; the commands below are the underlying steps.
+
+```bash
+# Whole project:
+pvs-studio-analyzer analyze \
+ -f examples/cmake-build-raspberry_pi_pico/compile_commands.json \
+ -R .PVS-Studio/.pvsconfig \
+ -o pvs-report.log -j12 \
+ --security-related-issues \
+ --misra-c-version 2023 --misra-cpp-version 2008 --use-old-parser
+
+# Specific files: -S takes a plaintext list (one path per line), not paths directly:
+printf 'src/foo.c\nsrc/bar.c\n' > files.txt
+pvs-studio-analyzer analyze \
+ -f examples/cmake-build-raspberry_pi_pico/compile_commands.json \
+ -R .PVS-Studio/.pvsconfig \
+ -S files.txt \
+ -o pvs-report.log -j12 \
+ --security-related-issues \
+ --misra-c-version 2023 --misra-cpp-version 2008 --use-old-parser
+
+plog-converter -a GA:1,2 -t errorfile pvs-report.log # view results
+```
+
+Takes ~10-30 s. (`--dump-files` adds preprocessed `.PVS-Studio.i/.cfg` dumps next
+to every source for false-positive debugging — omit it for normal runs.)
+
+## Validation After Changes
+
+1. `pre-commit run --all-files` — format, spell, unit tests (10-15 s).
+2. Build at least one board's full example set (Build → "All examples for a board") for modules you touched.
+3. Run relevant unit tests; add fuzz/HIL coverage for parsers or protocol state machines.
+
+**Boards good for local testing:**
+- `stm32f407disco` — no external SDK
+- `raspberry_pi_pico` — Pico SDK required
+- Others: see `hw/bsp/FAMILY/boards/`
+
+Device examples need real hardware to validate runtime behavior; must at least build.
+
+## Release
+
+Cutting a release — version bump, regenerated files, the per-release changelog, validation, and the maintainer's commit/tag/GitHub-release — is handled by the `make-release` skill (`.claude/skills/make-release/SKILL.md`).
+
+## References
+
+- MCU reference manuals, datasheets, schematics: `$HOME/Documents/calibre-library`.
+- Supported MCUs/boards: `hw/bsp/` and `docs/reference/boards.rst`.
+- USB classes: `src/class/{cdc,hid,msc,audio,…}/` — each has `*_device.c` and `*_host.c`.
+- Key files: `src/tusb.h`, `src/tusb_config.h`, `tools/get_deps.py`, `tools/build.py`, `test/unit-test/project.yml`.
+
+## Common Build Issues
+
+- Missing compiler → install `gcc-arm-none-eabi`.
+- Missing deps → `python3 tools/get_deps.py FAMILY`.
+- Unknown board → check `hw/bsp/FAMILY/boards/`.
+- `objcopy` errors in full builds are often non-critical; retry the single example.