feat(dcd/dwc2): Add Periodic Transfer Interrupt feature - #3859
Conversation
Enable DCTL.IgnrFrmNum in Buffer DMA so ISOC endpoints can be armed without even/odd frame matching. This is required to schedule ISOC OUT on alternating 7/8 ms intervals (Bluetooth HCI 7.5 ms) while keeping bInterval = 1. Gated by CFG_TUD_DWC2_PTI_ENABLE (default off, DMA only). When on, mask IncompISOCIN and report dropped ISOC OUT (PktDrpSts) as a failed transfer.
Hardware-in-the-loop (HIL) Test Reporthfp.json✅ 56 passed · ❌ 0 failed · ⚪ 0 skipped · blank not run
tinyusb-esp.json✅ 0 passed · ❌ 24 failed · ⚪ 0 skipped · blank not run
tinyusb.json✅ 298 passed · ❌ 83 failed · ⚪ 17 skipped · blank not run
|
|
| target | .text | .rodata | .data | .bss | total | % diff |
|---|---|---|---|---|---|---|
| raspberrypi_zero/mtp | 62,612 → 62,728 (+116) | 6,239 → 6,127 (-112) | — | — | 68,851 → 68,855 (+4) | +0.0% |
|
Hi @tore-espressif , didn't know HCI does this weird stuff, I got some review: P1 — Packet-drop detection is incomplete. |
|
@HiFiPhile Thank you for the review! Ad point 1: If I understand it correctly, this problem is not PTI specific, it is valid also for mode currently implemented in DCD? Refactoring the way how transfer sizes are calculated seems too risky to me... I'd suggest users to always use MPS = 64 to workaround this problem. In case this is not acceptable to you, feel free to close this PR |
You are right I've overlooked it. I read the HCI transport spec and I think we don't need PTI. The 7.5 ms value is the cadence of non-empty mSBC HCI packets, not the USB endpoint polling interval:
From Codex:
Thus Linux maintains 1 ms USB slots while placing non-empty HCI packets every 7 or 8 slots. |
@HiFiPhile Yes, for linux platform, linux usb host core stack schedule the ISO packet every 1ms, like this sequence But for windows platform, windows usb host usb stack schedule like this Using current tinyusb stack, we always lose one fixed ISO frame packet. This is because the data does not alternate changes as odd/even frames, but instead of |
Interesting to see how Windows abuse EHCI |
There was a problem hiding this comment.
🔵 Needs a closer look
The new DMA interrupt paths lack PTI-enabled test coverage.
Pull request overview
Adds opt-in DWC2 periodic transfer interrupt support for DMA-based isochronous transfers.
Changes:
- Adds
CFG_TUD_DWC2_PTI_ENABLE. - Configures
DCTL.IgnrFrmNumand thresholding. - Handles incomplete IN and dropped OUT transfers.
File summaries
| File | Description |
|---|---|
src/tusb_option.h |
Defines the PTI configuration option. |
src/portable/synopsys/dwc2/dwc2_type.h |
Defines the ignore-frame-number register bit. |
src/portable/synopsys/dwc2/dcd_dwc2.c |
Implements PTI setup and interrupt handling; PTI-enabled DMA coverage remains absent. |
Review details
Suppressed comments (1)
src/portable/synopsys/dwc2/dcd_dwc2.c:1080
- The opt-in path is not compiled or exercised by any existing test configuration: the DWC2 DMA HIL variants only define
CFG_TUD_DWC2_DMA_ENABLE, even though they already run the isochronousaudio_test_freertosexample (for example,test/hil/tinyusb.json:90-99and:422-429). Please add a PTI-enabled DMA variant or equivalent targeted coverage so the DCTL setup, incomplete-IN masking, and dropped-OUT failure path cannot regress unnoticed.
#if CFG_TUD_DWC2_PTI_ENABLE
// PTI: XferCompl can mean a dropped ISOC OUT packet (CRC/RxFIFO), not a good payload
if (doepint_bm.iso_packet_drop) {
const dwc2_depctl_t depctl = {.value = epout->doepctl};
if (depctl.type == DEPCTL_EPTYPE_ISOCHRONOUS) {
dcd_event_xfer_complete(rhport, epnum, 0, XFER_RESULT_FAILED, true);
- Files reviewed: 3/3 changed files
- Comments generated: 0
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
DWC2 DCD: Periodic Transfer Interrupt feature
Enable
DCTL.IgnrFrmNumin Buffer DMA so ISOC endpoints can be armed without even/odd frame matching.This is required to schedule ISOC OUT on alternating 7/8 ms intervals (Bluetooth HCI 7.5 ms) while keeping bInterval = 1.
Gated by CFG_TUD_DWC2_PTI_ENABLE (default off, DMA only). When on, mask IncompISOCIN and report dropped ISOC OUT (PktDrpSts) as a failed transfer.