<feed xmlns='http://www.w3.org/2005/Atom'>
<title>tinyusb.git/test/hil, branch codex/dfu-buffer-fix</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.</subtitle>
<id>http://cgit.235523.xyz/tinyusb.git/atom/test/hil?h=codex%2Fdfu-buffer-fix</id>
<link rel='self' href='http://cgit.235523.xyz/tinyusb.git/atom/test/hil?h=codex%2Fdfu-buffer-fix'/>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/'/>
<updated>2026-07-29T10:29:59Z</updated>
<entry>
<title>hil: split hil_test.py into hil_lock/hil_flash, add pool_check, update rig probes (#3794)</title>
<updated>2026-07-29T10:29:59Z</updated>
<author>
<name>Ha Thach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-29T10:29:59Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=e88fc441ddcaaa5abd4f4673ef2bf29499522dc0'/>
<id>urn:sha1:e88fc441ddcaaa5abd4f4673ef2bf29499522dc0</id>
<content type='text'>
test/hil: add board-pool health check, split hil_test into focused modules (#3794)

Add test/hil/hil_pool_check.py: per-board rig health scan — probe presence,
light-example flash (dfu_runtime; device_info + serial check for host-only
boards), uid re-enumeration, safe recovery (probe authorized-toggle, board
reset), verified board_test re-park, USB topology report, and a markdown
summary table. Missing firmware is built on the spot (tools/build.py, idf.py
for espressif, one get_deps retry); row statuses: ok, flash-failed, failed,
locked. Board locks are always respected, never bypassed.

Refactor hil_test.py into hil_lock.py (flock protocol, controller permits,
hold/release/status CLI; replaces board_lock.py) and hil_flash.py (flashers,
find_firmware, run_cmd). Update WCH probe uids and the board roster in
tinyusb.json; add the hil-pool-check skill.</content>
</entry>
<entry>
<title>bsp, hil: flash WCH boards with the unified OpenOCD fork (#3791)</title>
<updated>2026-07-28T05:50:28Z</updated>
<author>
<name>Ha Thach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-28T05:50:28Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=1d915b6b59cb88f14344521db1f9345d8c7dc9a7'/>
<id>urn:sha1:1d915b6b59cb88f14344521db1f9345d8c7dc9a7</id>
<content type='text'>
bsp, hil: flash with the unified OpenOCD fork

https://github.com/hathach/openocd (branch tinyusb) is mainline plus every
config these boards need: RPi RP2350, ADI max32/max78, the MounRiver WCH
configs, and the wlinke adapter on mainline's riscv target. It is a superset
of the vendor forks, so one 'openocd' covers all boards; -DOPENOCD=/OPENOCD=
still select another, msdk's when MAXIM_PATH is set.

Drops family_flash_openocd_wch and the OPENOCD_WCH pair, dedups
family_flash_openocd_adi, aligns ch583's work area, and points hil at the
flasher's own config instead of generating one per probe.

Verified: HIL green on all four WCH boards and max32666fthr.</content>
</entry>
<entry>
<title>test/hil: replace PCI reset with root-port VBUS cycle for D-state recovery (#3789)</title>
<updated>2026-07-27T17:17:14Z</updated>
<author>
<name>Ha Thach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-27T17:17:14Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=72f95d7d61a5a445be267eef2d677c33baa2fec2'/>
<id>urn:sha1:72f95d7d61a5a445be267eef2d677c33baa2fec2</id>
<content type='text'>
test/hil: replace PCI reset with root-port VBUS cycle for D-state recovery

pci-reset was documented as an FLR, but no controller on either rig has FLR, so
it issued a PCIe secondary bus reset on a live, driver-bound xHCI -- halting the
card until the PVE host was power-cycled, and returning success so the caller
could not tell. It destroyed the ci controller twice.

Replace it with root-cycle, which cuts VBUS at the xHCI root port and touches
only the root hub, so it never takes the per-device lock the wedged ioctl holds.
uhubctl needs -S, or its sysfs backend disconnects the child before cutting
power and blocks on that same lock. Success is proven by the device's sysfs
directory inode changing: node existence proves nothing, and devnum is reused
once the per-bus map wraps.

usbtest.py's hang path invokes it, then confirms via /proc that nothing still
holds the device node. Skill scripts now run from the repo; the drifted
/usr/local/sbin copies are deleted.</content>
</entry>
<entry>
<title>docs(skills): rename debug skills, drop the PC-host/TinyUSB-device assumption</title>
<updated>2026-07-24T07:55:59Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-23T03:18:11Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=8918c4fec4a99b174d480c043000fd4405678282'/>
<id>urn:sha1:8918c4fec4a99b174d480c043000fd4405678282</id>
<content type='text'>
Rename usb-target-debug -&gt; target-debug, usb-debug -&gt; usb-kernel-debug,
usb-recover -&gt; usb-kernel-recover (script filenames unchanged), and make all
debug skills/agents decide tool applicability by which end of the link runs
Linux: TinyUSB may run the device or host stack, and its peer may be a Linux
PC, another TinyUSB board, or a Linux gadget (e.g. Raspberry Pi UDC).

- usbmon: exists only when a Linux PC is the link's host
- usb-kernel-debug: either Linux end; allowlist gains dwc3/libcomposite/udc_core
  for the gadget side of a Linux peer
- usb-sniffer: the only full-visibility capture when TinyUSB is the host
- target-debug: covers dcd_* and hcd_*/tuh_ debugging; channel choice by topology
- update target-debugger/hil-operator agents, pre-pr, hil-validate.js, and the
  USB_RECOVER path constant in test/hil/usbtest.py
- CLAUDE.md: fold the dcd/hcd datasheet cross-check rule into the read-doc line
</content>
</entry>
<entry>
<title>hil: add frdm_k64f host test (cdc + msc) to tinyusb.json</title>
<updated>2026-07-17T10:26:04Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-09T17:17:56Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=d155273ce44f6bcf72494cce396188c90279c6a1'/>
<id>urn:sha1:d155273ce44f6bcf72494cce396188c90279c6a1</id>
<content type='text'>
frdm_k64f as a USB host with a CH9102 CDC (TX-RX loopback) and a Lexar MSC
drive behind a hub; flasher = onboard OpenSDA J-Link. host/cdc_msc_hid passes
(CDC mount+echo, MSC mount + disk-size check). device_info remains a known
device_info/usbh limitation (its synchronous descriptor dump starves a 2nd
device's enumeration) and is not ci_fs-specific.

Co-Authored-By: Claude Opus 4.8 (1M context) &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01ExGPLP5eU43LR7o6yYLpNi
</content>
</entry>
<entry>
<title>Key HIL report dir by run id so re-runs and other PRs cannot clobber it</title>
<updated>2026-07-17T08:39:10Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-17T08:39:10Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=8a42508300e03e3ed3bf7dc3e31821adf079189e'/>
<id>urn:sha1:8a42508300e03e3ed3bf7dc3e31821adf079189e</id>
<content type='text'>
A re-run attempt merged into an empty base: another PR's HIL job ran
between attempt 1 and the retry and rewrote the shared hil_report.json,
so the run-stamp guard (correctly) refused the foreign base but the
full-fleet results were lost - the retry report contained only the
re-run cells.

Give each (run id, job) its own report dir instead:
- attempts of the same run share a dir, so the retry always finds its
  own sidecar and .failed spec intact
- interleaved runs of other PRs/jobs write elsewhere and cannot clobber
- the run-stamp mechanism (.failed.run file) becomes redundant and is
  removed
- stale per-run dirs are pruned after 2 weeks
</content>
</entry>
<entry>
<title>hil: controller-aware scheduling of flash and usbtest concurrency</title>
<updated>2026-07-17T04:54:14Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-16T13:47:19Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=9b3259e60f3bd7e2d9637b61dc07265e4a73b362'/>
<id>urn:sha1:9b3259e60f3bd7e2d9637b61dc07265e4a73b362</id>
<content type='text'>
Full-fleet profiling (HIL_PROFILE=1 instrumentation, included) showed each
uPD720201 controller's serialized usbtest battery chain dominates wall time,
and a board whose marginal device port bounces during concurrent batteries
can wedge or kill the controller ("xHCI host not responding to stop endpoint
command"). Every such death traced to mimxrt1015's port (its old "kills the
uPD720201" reputation) - it is removed from the config until recabled;
mimxrt1064's enum-retry stalls were a loose device cable (re-seated).
nrf54lm20dk moves to boards-skip until its failing J-Link probe is replugged.
With the hardware fixed both cards run width-4 batteries plus full flash
churn clean, so scheduling stays simple: two symmetric knobs, flashes and
batteries budgeted per controller.

- schedule_boards(): dispatch boards round-robin across host controllers from
  a persisted hint cache (~/.cache/tinyusb-hil/ctrl_cache.json), learned and
  merge-on-write refreshed each run (concurrent HIL jobs keep each other's
  entries). Only the cached PCI address is consumed - dispatch order and
  first-flash budgeting, never battery serialization (batteries resolve live
  or fail closed to an all-slot permit).
- HIL_FLASH_PARALLEL (8) and HIL_USBTEST_PARALLEL (4) are budgeted per
  controller via lock slots assigned on first sight.
- re-runs: a failed run writes &lt;report dir&gt;/&lt;config&gt;.failed with the exact
  re-run spec (--accumulate -b &lt;failed board&gt; -bt &lt;board&gt;:&lt;its failed
  tests&gt;) instead of the inverted --skip-board list of everything that
  passed; --skip-board is gone, --flasher/--exclude-flasher scope a config
  across CI jobs by flasher type (no board names hardcoded in workflows),
  and -a/--accumulate merges a re-run into the existing report. The spec is
  stamped with GITHUB_RUN_ID and cleared on fresh runs, so a retry can never
  consume a spec left behind by a different run's dead or skipped attempt.
- CI: esp-idf firmware builds move out of hil-build into hil-build-esp, and
  the esptool-flashed boards run in their own hil-tinyusb-esp job, so the
  main hil-tinyusb run starts as soon as the fast toolchains finish instead
  of waiting on the slow esp-idf build (an esp toolchain flake previously
  skipped the whole rig run). Artifacts are namespaced per toolchain so the
  esp job downloads only esp-idf binaries.
- HIL_PROFILE=1: timestamped log lines, per-flash durations, permit-wait
  logging, uid-&gt;controller map dump for analysis.
- hil_report: per-variant test duration as a dedicated trailing column,
  recorded only by full runs.

Validated on the ci rig (fixed seeds 20260716/777, full fleet at 8/4):
738s/780s walls with only known-flake failures and no controller deaths,
vs 1134-1211s serialized-battery baseline.
</content>
</entry>
<entry>
<title>hil: add usb_recover hub-cycle action; drop MosChip skips, gate it as incompatible</title>
<updated>2026-07-15T11:20:04Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-15T11:20:04Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=39b3c4482a8af712f4306b2d3bda3cf9b52f25db'/>
<id>urn:sha1:39b3c4482a8af712f4306b2d3bda3cf9b52f25db</id>
<content type='text'>
The MosChip MCS9990 card is physically removed from the rig: delete its
cases-11/25 SKIP workaround (and the now-orphaned SKIP accounting) from
usbtest.py and refuse to run outright if a DUT ever sits behind one again.

usb_recover.sh gains `hub-cycle &lt;busport&gt;`: uhubctl VBUS cycle of the port
feeding the device, walking upstream (parent hub -&gt; root port) until it
re-enumerates. Verified on the rig: leaf-level recovery (13-4.4 usbtest
device) and full walk to the root port on a dead branch. SKILL.md updated
for the action and the two-Renesas topology (root-port ppps is real; leaf
1a40:0201 hubs fake their "ganged" switching).

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01WxUeX4Yn26KibfjvDg2pN9
</content>
</entry>
<entry>
<title>dwc2: fix EP0 OUT dcache invalidate range; run usbtest on espressif s3/p4 and mimxrt1015</title>
<updated>2026-07-14T19:31:14Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-14T19:31:14Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=59f02a1c4c18d7e43a1bd6aaad4b50e71931c9ff'/>
<id>urn:sha1:59f02a1c4c18d7e43a1bd6aaad4b50e71931c9ff</id>
<content type='text'>
edpt_schedule_packets() advanced xfer-&gt;buffer past each armed EP0
chunk, so the OUT-complete handler invalidated the cache at the
ADVANCED pointer: one line past the received data. The CPU then read
stale cached bytes instead of the DMA'd packet, and the misplaced
invalidate discarded a dirty line of whatever variable follows the
buffer - random neighbor corruption on every control-OUT data stage.
Found by usbtest ctrl_out (cases 14/21) on espressif_p4_function_ev
with DMA enabled, the first DWC2 target combining buffer DMA with a
data cache: usbd control state wedged after the first control write
(every later request stalled), and one build layout panicked in the
usbd memcpy with a wild pointer.

Rework the EP0 chunk bookkeeping so xfer-&gt;buffer always points at the
un-consumed position: the arm no longer advances it; instead the EP0
re-arm paths advance past each completed (full) chunk, invalidating it
first on the OUT side. The final OUT completion invalidates exactly
the received bytes of its last chunk, taken from DOEPDMA ("incremented
on every AHB transaction", databook 7.1.83 - the same semantics the
SETUP path relies on) before dma_setup_prepare() re-targets it. EP0
chunking state (ep0_pending) is now also dropped on bus reset and on
a new SETUP, so a stale latched completion can no longer re-arm EP0
DMA from dead state. No behavior change for targets without dcache.

While root-causing, the FIFO layout was cross-checked against the
DWC2 databook/programming guide v4.20a: the existing GDFIFOCFG
programming (EPInfoBaseAddr = otg_dfifo_depth - 2*ep_count, one SPRAM
word per endpoint direction for buffer DMA) is conformant and needs
no change; the P4 HS instance's reset GDFIFOCFG (0x03800400) merely
reflects a scatter/gather-sized EP_LOC_CNT of 128 that buffer DMA
does not need.

With the fix in place, enable the usbtest battery on the espressif
fleet: tools/build.py allowlists device/usbtest (a plain IDF component
like board_test/video_capture) and both espressif boards' only-lists
gain device/usbtest. Also re-enable device/usbtest on mimxrt1015_evk:
its skip predated the dcd_ci_hs stale-ACTIVE-overlay fix (already on
this branch), which cured the battery that previously killed the
uPD720201 host controller twice (2026-07-11 ROM fw, 2026-07-13 case 27
on fw 2.0.2.6); rig-validated 30/30 three consecutive runs.

Validated on rig (all 30/30): espressif_p4_function_ev(-DMA) (was
22/30 under DMA), espressif_s3_devkitm(-DMA), stm32f723disco(-DMA),
mimxrt1015_evk; p4/s3 slave-mode unaffected (DMA-only code path);
compile-checked stm32h743nucleo +TUD DMA, stm32f407disco,
stm32l476disco (device ports currently on the dead hub).

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_017TQZrFfU3K4Y198aLsUpBC
</content>
</entry>
<entry>
<title>dcd(ci_hs): stale overlay fix; run usbtest on lpcxpresso43s67</title>
<updated>2026-07-14T08:23:07Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-14T08:23:07Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=ca402a0e781eb4d5580030f713377552b72eddda'/>
<id>urn:sha1:ca402a0e781eb4d5580030f713377552b72eddda</id>
<content type='text'>
- dcd_edpt_stall flushes the primed buffer (ENDPTFLUSH), but the aborted
  transfer's dQH overlay can be left ACTIVE with mid-transfer state; the
  next prime after clear-halt then resumes the stale overlay instead of
  loading the fresh qtd, so post-halt IN reads return mid-buffer data
  (usbtest case 13 'buf[32] = 56 (not 0)', with case 18 failing
  downstream of the same corruption in the full battery). qhd_start_xfer
  now clears overlay.active alongside overlay.halted before linking the
  new qtd.
- test/hil(hfp): drop lpcxpresso43s67's device/usbtest skip - the
  historical first-case wedge no longer reproduces on this branch, and
  with the overlay fix the board runs 30/30 on its Fresco xHCI host
  (previously 28/30 with deterministic case 13/18 failures).
  mimxrt1064_evk (imxrt dcache path) 30/30 regression-clean.
- docs(hil skill): document the external hifiphile rig - pool
  test/hil/hfp.json, SSH-reachable from htpc/ci with no outbound SSH,
  exercised by the CI hil-tinyusb (hfp.json) job; never run HIL against
  it during development unless the user explicitly asks.

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_017TQZrFfU3K4Y198aLsUpBC
</content>
</entry>
</feed>
