Skip to content

dwc2: ESP32-S2/S3 activates a TX-FIFO-less IN endpoint without counting it against the five-active-IN limit #4450

Open

Description

@hathach

On ESP32-S2/S3, dcd_edpt_open() activates a TX-FIFO-less interrupt IN endpoint (arduino-esp32's CDC notification 0x85) with USBACTEP set but does not count it against ep_in_count. EP0 IN + 0x81-0x84 + 0x85 is six IN endpoints active, against the TRM's maximum of five.

Found in review of #4448 (fixes #4446): #4448 (review)

Problem

  • src/portable/synopsys/dwc2/dcd_dwc2.c:315-320: an interrupt IN with epnum >= ep_in_count (5, dwc2_esp32.h:32) returns before the counter at :323-326. EP0 IN is counted (dfifo_alloc(0x80)).
  • dcd_edpt_open then calls edpt_activate, which sets depctl.active = 1 and tx_fifo_num = epnum (:393, :399). Transfers are refused at :774 and :810, so EPENA is never set.
  • Before dwc2: reject an IN endpoint number beyond the implemented TX FIFOs #4280 (5ee2d6f6c) every IN endpoint was counted, so this six-IN layout was rejected.
  • ESP32-S3 TRM Rev 1.8 section 32.2.2 (p1227) and ESP32-S2 TRM Rev 1.3 (p745): a maximum of five IN endpoints concurrently active, including EP0 IN, each with a dedicated TX FIFO. "Active" is not defined at the USBACTEP level.
  • DWC2 databook 4.20a p632, DIEPCTLn.TxFNum: each active IN endpoint must use a separate FIFO number. The behaviour for an unimplemented FIFO number is undocumented.
  • ESP32-S3 errata Rev 1.3 lists only USBOTG-4289. The ESP32-S2 errata were not checked for this.
  • arduino-esp32 3.3.12 esp32-hal-tinyusb.c:727-741 relies on this layout (one extra IN for CDC 0x85, "not linked to FIFO and not used").

Hardware (farm espressif_s3_devkitm, 10fea46ca): cdc_dual_ports plus a never-sent HID interrupt IN 0x85, slave and DMA, 3 runs each (one after usbreset) of a concurrent 256 KiB/port bidirectional CDC loopback. Byte-exact, 74.6/75.7 KB/s per port, the same as the binary's second configuration without 0x85; no dmesg errors. Not tested: long soak, bandwidth-limited IN, ESP32-S2, wire capture.

So the layout works on the one board tried, but nothing in the TRM says it is allowed.

Remaining work

Decide between:

Then add hardware coverage: long soak, bandwidth-limited IN, ESP32-S2.

Deferred

#4448 keeps the chosen design (open without a FIFO, refuse transfers). Counting 0x85 would break the arduino-esp32 layout again, and independent FIFO allocation is a different design.

Related: #832 — requests skipping the FIFO for the CDC notification endpoint on ESP32-S2, which is the behaviour #4448 implements; it does not address the active-endpoint limit.
Related: #4283 — bounding the TX FIFO number by GHWCFG4.INEps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Prio 📌follow-upDeferred work from a PR or investigation

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions