Repository navigation
Description
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 withepnum >= ep_in_count(5,dwc2_esp32.h:32) returns before the counter at:323-326. EP0 IN is counted (dfifo_alloc(0x80)).dcd_edpt_openthen callsedpt_activate, which setsdepctl.active = 1andtx_fifo_num = epnum(:393,:399). Transfers are refused at:774and:810, soEPENAis 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
USBACTEPlevel. - 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-741relies on this layout (one extra IN for CDC0x85, "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:
- keep the uncounted activation;
- skip
USBACTEPon a FIFO-less endpoint; - independent TX FIFO allocation, as proposed in dwc2: #4280 breaks arduino-esp32 CDC on ESP32-S2/S3 (notification EP 0x85 rejected, SET_CONFIGURATION STALLs) #4446.
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.
Activity