<feed xmlns='http://www.w3.org/2005/Atom'>
<title>tinyusb.git/src, branch copilot/fix-hil-tinyusb-job</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.</subtitle>
<id>http://cgit.235523.xyz/tinyusb.git/atom/src?h=copilot%2Ffix-hil-tinyusb-job</id>
<link rel='self' href='http://cgit.235523.xyz/tinyusb.git/atom/src?h=copilot%2Ffix-hil-tinyusb-job'/>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/'/>
<updated>2026-07-18T17:33:14Z</updated>
<entry>
<title>Merge pull request #3775 from hathach/claude/add-usb-debug-sniff</title>
<updated>2026-07-18T17:33:14Z</updated>
<author>
<name>Ha Thach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-18T17:33:14Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=50f30773522d21bc599f00c18980ae651f780ff8'/>
<id>urn:sha1:50f30773522d21bc599f00c18980ae651f780ff8</id>
<content type='text'>
usb-target-debug/usb-sniffer skills</content>
</entry>
<entry>
<title>fix(ci_fs): address code-review findings in host/device drivers</title>
<updated>2026-07-17T17:18:27Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-17T17:18:27Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=4782770e7f5f4a726f9739d940c110196807f15c'/>
<id>urn:sha1:4782770e7f5f4a726f9739d940c110196807f15c</id>
<content type='text'>
Host (hcd_ci_fs.c):
- Release the speculatively-armed sibling BDT on the NAK path (IN only) as
  well as on completion, so a NAKed multi-packet IN no longer leaks a BDT
  that stays own=1 and blocks every same-direction pipe. Both paths now go
  through a single release_sibling_bd() helper (was a copy-pasted disarm).
- Clear the ENTIRE shared BDT (both directions) on bus reset; clearing only
  the IN half left a stale OUT/SETUP descriptor after a disconnect mid-OUT,
  blocking the first control transfer on re-enumeration.
- Size bda[] to span the whole BDT (2*2*4) so STAT-indexed access is within
  the declared array bounds (was out-of-declared-bounds, benign via union).

Shared (ci_fs_type.h):
- Hoist buffer_descriptor_t and the TOK_PID enum out of the device and host
  drivers into the shared header so the identical definitions cannot drift.

Board (kinetis_k):
- Drop a redundant local in board_get_unique_id.

Build-verified: host + kinetis k/kl/k32l + MCX. HIL: frdm_k64f host 2/2
(cdc_msc_hid + device_info); frdm_kl25z device core suite green with the
relocated definitions.
</content>
</entry>
<entry>
<title>dcd_lpc17_40: address review findings in the iso paths</title>
<updated>2026-07-17T17:15:53Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-17T10:58:25Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=cb224400931b7fbc3477a87a258c0602092abe6b'/>
<id>urn:sha1:cb224400931b7fbc3477a87a258c0602092abe6b</id>
<content type='text'>
From a second max-effort review of the branch:

- Drop the dead TUSB_XFER_ISOCHRONOUS case in dcd_edpt_open: iso endpoints
  are armed via dcd_edpt_iso_alloc/activate (TUP_DCD_EDPT_ISO_ALLOC is
  defined for this IP), never through dcd_edpt_open, so the case and its
  dd-&gt;isochronous assignment were unreachable and asserted a false
  invariant. Only bulk/interrupt reach the switch now.

- Extend the iso compile gate to the classes that actually arm an iso
  endpoint: DCD_ISO_ENABLED now includes CFG_TUD_BTH (bth_device.c opens
  an iso voice endpoint). Without it a BTH build would compile the iso
  machinery out and fail SET_INTERFACE at runtime.

- Un-skip LPC175X_6X in the usbtest example: it shares dcd_lpc17_40.c with
  LPC40XX verbatim, so the "DCD has no isochronous support" skip reason no
  longer holds. Build-verified for lpcxpresso1769 (previously blocked by
  the skip).

- TU_ATTR_UNUSED on the ep_id_is_iso helper: every caller is under
  #if DCD_ISO_ENABLED, so non-iso builds don't reference it and clang's
  -Wunused-function (fatal in CI) rejected the build — gcc stays quiet.
  Verified with the full lpc17 and lpc40 example sets under arm-clang.

A fifth finding — bounding control_ep_read's PACKET_READY spin with a
timeout — was implemented and REVERTED: a naive 100k-iteration bound fires
on legitimately-slow control reads and intermittently drops the device
(hardware-proven by interleaved A/B testing against the pre-fix binary).
The infinite wait is retained; the read is only reached once out_received/
out_queued signal data is present, so the theoretical IRQ-off hang is not
reachable in practice.

Re-verified on ea4088_quickstart: usbtest 30/30 (repeated) + HIL 14/14.
</content>
</entry>
<entry>
<title>fix(ci_fs host): release stale sibling BDT on multi-packet completion</title>
<updated>2026-07-17T10:26:05Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-10T02:15:22Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=7d7444bd8924fce9e60364893265bd2451e115e7'/>
<id>urn:sha1:7d7444bd8924fce9e60364893265bd2451e115e7</id>
<content type='text'>
hcd_ci_fs shares a single BDT set across all pipes. prepare_packets()
speculatively arms the sibling (odd^1) BDT of a multi-packet transfer so it
can ping-pong without NAKs. When such a transfer ends early (a short IN
packet) or fails, the still-owned sibling was never released, permanently
blocking the shared BDT for every other pipe.

This deadlocked a 2nd device enumerating behind a hub while another device
issued descriptor reads (host/device_info with CDC+MSC): the MSC's control
transfers could never acquire the BDT, so it never got Set Address.

Release the sibling in process_tokdne()'s completion path, but ONLY for a
multi-packet transfer (length &gt; max_packet_size): a single-packet transfer
never arms a sibling, so that BDT slot may legitimately belong to another
pipe's in-flight transfer and must not be disturbed (doing so unconditionally
corrupts concurrent transfers, e.g. the CDC bulk-IN vs MSC enum in
host/cdc_msc_hid).

Mirrors the equivalent device-side fix in dcd_ci_fs.c; the host needs the
multi-packet guard because its BDT set is shared across pipes.

Verified on frdm_k64f (HIL): host/device_info now enumerates both CDC+MSC
behind a hub, host/cdc_msc_hid still mounts the MSC (no regression).

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>dcd_ci_fs: disarm sibling BDT on short-packet OUT completion</title>
<updated>2026-07-17T10:26:03Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-09T17:17:52Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=439a60a87f4039beba5a1d202b7ff6f9d93745dc'/>
<id>urn:sha1:439a60a87f4039beba5a1d202b7ff6f9d93745dc</id>
<content type='text'>
A multi-packet OUT transfer speculatively arms both even/odd BDTs to avoid
NAK. When the host ends the transfer early with a short packet, the sibling
BDT was left armed (own=1), desyncing the even/odd ping-pong so the next OUT
packet landed at buffer+max_packet_size instead of buffer and the stack read
stale data. Disarm the sibling on completion.

Fixes device/mtp on Kinetis (GetDeviceInfo command was received into the wrong
buffer half -&gt; hang). Pre-existing (MSC only arms single-packet command
receives so it never hit the double-buffer path). HIL: frdm_kl25z &amp; frdm_k64f
device 13/13.

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>migrate NXP Kinetis khci to chipidea ci_fs driver (device + host)</title>
<updated>2026-07-17T10:26:02Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-09T17:17:18Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=fa1fee0a5f82b5a78ace26ee1722c1d636c5b32a'/>
<id>urn:sha1:fa1fee0a5f82b5a78ace26ee1722c1d636c5b32a</id>
<content type='text'>
Complete the khci -&gt; chipidea ci_fs migration that was started for device
(commit d70403f1f "host is not yet"):

- device: switch kinetis_k/kl/k32l (Makefiles + k32l CMake) to dcd_ci_fs.c
- host: add hcd_ci_fs.c (port of hcd_khci.c onto ci_fs_regs_t) and switch all
  Kinetis families to it; remove src/portable/nxp/khci entirely
- enable host examples (device_info, cdc_msc_hid) for mcu:KINETIS_K
- README: merge the KL and K32L2 rows into a single "KL, K32L" ci_fs row

hcd_ci_fs.c also fixes two pre-existing host bugs found via HIL on frdm_k64f
(present in the old hcd_khci.c too):
- data toggle was flipped on a NAK in suspend_transfer; a NAK transfers no
  data so the toggle must be preserved, else the retried bulk packet is
  silently discarded by the device (MSC CBW/CSW hang). See comment in file.
- prepare_packets asserted and dropped a transfer when the single shared BDT
  was still owned by an in-flight transfer under concurrent activity; now it
  returns busy and resume_transfer defers/retries on the next SOF.

HIL verified on frdm_k64f: device 13/13, host cdc_msc_hid (CDC mount + echo +
MSC mount, through a hub).

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>dcd_lpc17_40: mask USB IRQ around non-reentrant SIE and realization sequences</title>
<updated>2026-07-17T09:48:02Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-16T07:11:04Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=a3ee0b4ff12615552de50bd2a61287fdb0b11bd9'/>
<id>urn:sha1:a3ee0b4ff12615552de50bd2a61287fdb0b11bd9</id>
<content type='text'>
The SIE command protocol (CmdCode + CCEMPTY/CDFULL handshake), the
slave-mode Ctrl/RxData/TxData window, the EpIntEn read-modify-writes, and
set_ep_size's ReEp/EP_RLZED handshake are all shared between thread-mode
API calls and dcd_int_handler, and none are reentrant: an ISR preempting a
thread-mode sequence consumes its handshake flags or, in set_ep_size's
case, a bus reset's DevIntClr = 0xFFFFFFFF eats the EP_RLZED flag the
spin waits on, hanging it forever. Guard them by masking only the USB IRQ
(nestable, ISR-safe; CMSIS NVIC_DisableIRQ already ends with DSB+ISB).
control_xact keeps the mask across its in_isr=true event push, since
osal_none skips queue locking for in_isr.

Hardening, not a fix for an observed failure: the ea4088 usbtest 30/30 +
HIL 14/14 results were reproduced with and without it. The windows are a
few instructions wide and most exposed on RTOS builds where class drivers
queue transfers from tasks concurrent with the USB IRQ.
</content>
</entry>
<entry>
<title>dcd_lpc17_40: fix stale EP0 out_received, add isochronous support</title>
<updated>2026-07-17T09:48:01Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-16T07:11:01Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=36cd9f9f46ca20be907ed57b874d9d1dc7b3bf64'/>
<id>urn:sha1:36cd9f9f46ca20be907ed57b874d9d1dc7b3bf64</id>
<content type='text'>
EP0 control-OUT fix (usbtest 14/21, errno 110/-74): usbd queues the
status-stage OUT ZLP of every control read with buffer=NULL, so the ISR's
`if (out_buffer)` check missed it and marked the arriving ZLP as
out_received instead. The stale flag poisoned the next control-OUT with
data: its first chunk "completed" instantly from an empty EP0 buffer and
the host's real DATA NAKed forever. Track queued transfers with an
explicit out_queued flag and void half-finished control state on a new
SETUP.

Isochronous support (UM10562 12.15.6): 5-word DMA descriptors with
per-packet size memory, buflen/present_count in packets, one packet per
FRAME (no DMARSet/EpIntEn involvement), completion at EOT for both
directions. Details that matter:
- the iso machinery (5th DD word + packet-size memory) is compiled only
  when an iso-capable class is enabled (CFG_TUD_AUDIO/VIDEO/VENDOR), so
  non-iso builds pay nothing: _dcd stays 648 B vs 1032 B with iso
- ISR dispatch keys on the hardware's fixed ep-number/type map
  (ep_id_is_iso), never on dd fields that thread mode rebuilds
- iso OUT honors Packet_valid (bit 16) and prefills the hardware
  writeback slots with 0, so a missed frame counts as 0 bytes instead of
  reading back stale buffer contents as data
- packet count is validated (tu_div_ceil &lt;= ISO_MAX_PACKETS) before the
  DD is touched, so an oversized transfer is refused without leaving a
  serviceable half-built descriptor armed for the frame engine
- dcd_edpt_iso_alloc and iso_activate both enforce the fixed iso endpoint
  numbers (3/6/9/12); classes ignore alloc's return value, so activate
  must not trust it

Un-skip LPC40XX in the usbtest example; tier 4 now enumerates and passes
iso cases 15/16/22/23. cdc_msc_throughput and printer_to_cdc had bulk on
iso-only EP3 (SET_CONFIGURATION failed with -32); add the LPC17/40 EPNUM
block (bulk on EP2/EP5) like other fixed-EP examples.

Verified on ea4088_quickstart: usbtest tier-4 battery 30/30 repeatedly
and the full device HIL suite 14/14 (incl. audio_test iso).
</content>
</entry>
<entry>
<title>vendor: deactivate de-selected altsetting's isochronous endpoints</title>
<updated>2026-07-17T05:07:50Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-17T05:07:50Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=a68d776ac072725266ab53b64b29d4405090281f'/>
<id>urn:sha1:a68d776ac072725266ab53b64b29d4405090281f</id>
<content type='text'>
vendord_set_alt() aborted bulk/interrupt endpoints of the outgoing
altsetting (stall/clear-stall) but only dropped the iso endpoints'
tracking: an armed iso transfer stayed live in the dcd with its usbd
claim held and no tracked handle to stop it, and its completion fired
into an endpoint the class no longer recognizes. Reachable through the
usbtest example's alt0 (bulk) &lt;-&gt; alt1 (iso) SET_INTERFACE switching.

Track each selected iso endpoint's descriptor (points into the app's
static descriptor set) and deactivate on de-selection: with the
iso-alloc API re-activation is the abort/scrub primitive (resets
ep_status, aborts the stale transfer); without it usbd_edpt_close does,
and the next selection re-opens. Iso cannot be stalled like
bulk/interrupt, hence the separate path.

Build-verified: usbtest for stm32f072disco, ra4m1_ek, raspberry_pi_pico
(iso-alloc) and ch32v307v_r1_1v0 (close API).
</content>
</entry>
<entry>
<title>rusb2: restore speed-conditional hwfifo stride mask</title>
<updated>2026-07-17T04:54:14Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-17T04:40:15Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=a2f0c3c1baea4f0129d14d1a85c7fe8b307a2405'/>
<id>urn:sha1:a2f0c3c1baea4f0129d14d1a85c7fe8b307a2405</id>
<content type='text'>
FS-forced builds on the HS module are not a supported configuration, so
the 32-bit access path does not need to exist in full-speed builds:
CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE returns to (2 | (TUD_OPT_HIGH_SPEED ? 4 : 0)).
Saves 28 bytes of text on FS-only parts (measured on ra4m1_ek cdc_msc);
high-speed builds keep both widths for the dual-module (FS+HS ports) case.

Build-verified: ra4m1_ek and ra6m5_ek cdc_msc.
</content>
</entry>
</feed>
