<feed xmlns='http://www.w3.org/2005/Atom'>
<title>tinyusb.git/examples, branch claude/mtp-data-phase-fixes</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.</subtitle>
<id>http://cgit.235523.xyz/tinyusb.git/atom/examples?h=claude%2Fmtp-data-phase-fixes</id>
<link rel='self' href='http://cgit.235523.xyz/tinyusb.git/atom/examples?h=claude%2Fmtp-data-phase-fixes'/>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/'/>
<updated>2026-08-17T05:11:53Z</updated>
<entry>
<title>examples/mtp: clamp SendObject writes to the declared object size</title>
<updated>2026-08-17T05:11:53Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-08-14T05:26:36Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=7530f13031c8e316131fe6272f7905db1245cfd9'/>
<id>urn:sha1:7530f13031c8e316131fe6272f7905db1245cfd9</id>
<content type='text'>
fs_send_object() copied every received payload to f-&gt;data using only
the running offset, so a host sending more data than its SendObjectInfo
declared wrote past the object and overflowed fs_buf. Clamp each copy to
what remains of f-&gt;size.
</content>
</entry>
<entry>
<title>class/mtp: correct data phase completion and transaction recovery</title>
<updated>2026-08-17T05:11:53Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-08-13T07:34:58Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=5a9803555f362a0efeeb549093a3338c5b151e9c'/>
<id>urn:sha1:5a9803555f362a0efeeb549093a3338c5b151e9c</id>
<content type='text'>
The data-out phase ended before its terminating ZLP and before the
application had seen the final payload, and several transaction states
had no way back to idle. Reworked as one state machine:

- Add MTP_PHASE_DATA_COMPLETE, entered once the data phase has fully
  finished - for an exact buffer-multiple data-out, only after the
  host's terminating ZLP - and deliver tud_mtp_data_complete_cb() from
  there. tud_mtp_response_send() now refuses while the phase is still
  MTP_PHASE_DATA: ep_out still owes the host a read at that point and
  re-arming it for a new command would race that read.

- Arm the terminating-ZLP read before handing the final payload to the
  application, as the IN path already does. The 0-length read passes a
  NULL buffer so the payload is untouched, and claiming ep_out first
  means a late tud_mtp_data_receive() fails its own claim instead of
  breaking the driver's next step.

- Honor the documented negative return of tud_mtp_data_xfer_cb() and
  tud_mtp_data_complete_cb() by entering MTP_PHASE_ERROR, which stalls
  both endpoints. This is the application's way out of a data phase now
  that a response cannot be sent from one. Their weak stubs return 0 so
  an application that does not implement them is unaffected.

- Take total_len from the container header the host sends on the first
  OUT packet. The application can only set it up front when it knows
  the size (SendObject); SendObjectInfo cannot, so total_len kept the
  12-byte header default and the phase ended on the first packet.

- Reject a runt or misdirected container in both the command and data
  phases: a short packet was matched against stale buffer contents, and
  the failed TU_VERIFY left ep_out neither armed nor stalled. The
  first data-out packet previously underflowed payload_bytes instead.

- Restore the previous phase when tud_mtp_data_send()/_receive() cannot
  claim their endpoint, so the application's fallback response is not
  refused by a phase the driver never actually entered.

- Re-arm ep_out after MTP_REQ_CANCEL of a data phase, and defer the
  new-command read when ep_out is still busy with the ZLP read of an
  abandoned transaction: usbd_edpt_xfer() asserts on a busy endpoint,
  so MTP_REQ_RESET could not recover.

The MTP example follows the same contract: a handler error raised mid
data phase (fs_send_object_info validates the received ObjectInfo, so
STORE_FULL and INVALID_PARENT_OBJECT can only be raised there) is kept
and answered from tud_mtp_data_complete_cb() once the phase completes.
</content>
</entry>
<entry>
<title>Enable APM32F0 dependency fetching and CI</title>
<updated>2026-07-25T03:28:29Z</updated>
<author>
<name>Jie Feng</name>
<email>hjf3108@gmail.com</email>
</author>
<published>2026-07-25T03:25:05Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=7b9761f1919014152d3e9ee1aaf203d7fb0e762b'/>
<id>urn:sha1:7b9761f1919014152d3e9ee1aaf203d7fb0e762b</id>
<content type='text'>
</content>
</entry>
<entry>
<title>misc fixes</title>
<updated>2026-07-19T12:38:54Z</updated>
<author>
<name>Jie Feng</name>
<email>hjf3108@gmail.com</email>
</author>
<published>2026-06-18T09:28:49Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=9418aba918d7c4107026c894e863d9ef0ec5db81'/>
<id>urn:sha1:9418aba918d7c4107026c894e863d9ef0ec5db81</id>
<content type='text'>
</content>
</entry>
<entry>
<title>examples now build</title>
<updated>2026-07-19T11:24:40Z</updated>
<author>
<name>Jie Feng</name>
<email>hjf3108@gmail.com</email>
</author>
<published>2026-06-10T10:49:07Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=6e0f455634126e7eba315ebc279e563aefbf5815'/>
<id>urn:sha1:6e0f455634126e7eba315ebc279e563aefbf5815</id>
<content type='text'>
</content>
</entry>
<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>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>skill: add usb-sniffer — wire-level capture with the ataradov hardware tap</title>
<updated>2026-07-17T10:32:47Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-16T07:11:43Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=e5b47c9306471b41bd2d2ecbbe9ea8932028b380'/>
<id>urn:sha1:e5b47c9306471b41bd2d2ecbbe9ea8932028b380</id>
<content type='text'>
Fourth view in the USB debugging toolset (usbmon = host URBs, usb-debug =
host reasoning, usb-target-debug = device firmware, usb-sniffer = what
actually crossed D+/D-). Covers the ataradov/usb-sniffer analyzer:
headless pcapng capture (--speed ls/fs/hs, --fold, --limit self-exit),
Wireshark/tshark analysis recipes, and the wire realities that bite:
downstream broadcast, sniffer self-capture noise, xHCI devnum != wire
address, tap-point-dependent reset visibility (hub choreography anchors),
FS-behind-HS-hub splits. Every recipe hardware-validated on the rig,
including the capture-window floor (a 3 s window provably misses the
enumeration ladder; 3M packets minimum).

Two udev files with distinct audiences, not one:
- examples/device/99-tinyusb-examples.rules (renamed from 99-tinyusb.rules):
  the user-facing rules the examples need — cafe VID access, hidraw, the
  ModemManager blacklist, a couple of board probes. getting_started.rst,
  the webusb_serial README and its source comment point here.
- tools/88-tinyusb.rules: the HIL rig's private probe/analyzer allowlist,
  now with the sniffer (6666:6620 + blank FX2LP 04b4:8613). Installed on
  the rig only; the usb-sniffer skill references it.
</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: 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>
</feed>
