Summary
On the ESP32-P4, usbif's USB host installs cleanly on the high-speed controller and then never detects a connection — attaches stays 0 forever, for every device tried, with and without a hub. The same physical port, cable and PHY work in device mode, enumerating against Windows as a composite CDC+MSC device.
This reproduces the defect first recorded in docs/phase0-findings.md ("the P4's HS host detects no connection (the S3's FS host sees the same wire instantly — IDF's young P4 host support is the suspect)"), now with the confounders eliminated.
Bench
- Board: Waveshare ESP32-P4-WIFI6-Touch-LCD-4B, two USB-C ports — CH343P UART (COM4, used for the REPL) and the ESP32-P4 native
USBD_P/USBD_N HS OTG port.
- Firmware:
ESP32_GENERIC_P4 / C6_WIFI, MicroPython 1.28.0, built from the aggregator after a full erase_flash.
- Devices tried on the OTG port: a powered hub with a Logitech C920e behind it; the same hub alone; a simple bus-powered device directly on the C-to-A OTG adapter.
What the host reports
usbif_host: task up on core 0
usbif_host: install -> 0x0
usbif_host: client register -> 0x0
host_start -> ['cdc', 'hid', 'midi', 'msc', 'uac', 'uvc']
nothing enumerated in 6s with ALL classes accepted
host_stats: (True, 0, 0, 0, 0, 1)
host_stats is (running, attaches, detaches, errors, lib_devices, lib_clients). Zero attaches and zero lib_devices means the controller never reported a connection — this is upstream of enumeration entirely. usb_host_lib_set_root_port_power(false/true) (host_port_cycle()) returns 0 and changes nothing.
What device mode reports, on the same port and cable
2-1 303a:4003 USB Serial Device (COM72), USB Mass Storage Device
USB\VID_303A&PID_4003&MI_00 -> USB Serial Device (COM72)
USB\VID_303A&PID_4003&MI_02 -> USB Mass Storage Device
USB\VID_303A&PID_4003 -> USB Composite Device
So the connector, the cable, the HS PHY and the device stack's use of it are all good. Only the host role fails.
Ruled out
| Suspect |
How it was eliminated |
| External hub support |
CONFIG_USB_HOST_HUBS_SUPPORTED=y was already on the P4 board patch, and CONFIG_USB_HOST_HUB_MULTI_LEVEL=y is set in the built sdkconfig |
| Hubs generally |
A device directly on the OTG adapter, no hub, also gives zero attaches |
| Control-transfer buffer too small |
Fixed in cmods d6b5eb5 (256 -> 4096). Necessary and correct — the camera's HS descriptor is 2306 bytes — but changed nothing here. Verified present in the built sdkconfig |
| Wrong controller selected |
CONFIG_SOC_USB_OTG_PERIPH_NUM=2, so the driver's dual-controller branch compiles and passes peripheral_map = BIT1 for the HS peripheral explicitly |
| Host stack failing to install |
install -> 0x0, client register -> 0x0 |
| Bus power |
The powered hub back-feeds VBUS and was tested with its supply connected. (Note the direct-device test cannot distinguish "host broken" from "no VBUS", since this board is not documented to source 5V on the OTG port — the powered-hub test is the one that carries weight) |
| An IO-expander mux, as on the S3 |
This board has no CH422G and no documented multiplexer in the USB path. The second USB (USB_IN1_P/N, GPIO24/25) goes to header P2 through unpopulated series resistors and is not this port |
Not yet tried
- Reading the DWC host registers directly (HPRT in particular) to see whether the port is powered, whether
PrtConnDet/PrtConnSts ever assert, and what the PHY reports. host_intr_dump() currently returns None and would be the natural place to expose this.
- Whether IDF's own
usb_host_lib examples detect a device on this board — a useful upstream-vs-us discriminator before assuming the fault is ours.
- OTG ID / role signalling: whether anything on this board drives the OTG ID line, and whether the DWC is being left in device role at the register level despite the host library installing.
Impact
Blocks hosting USB devices on the P4, which is where high speed would unlock real UVC resolutions (the C920e offers 1280x720+ at HS versus 640x480 at FS). Does not block the P4 acting as a USB device — that works — so the "board becomes a USB camera" goal is unaffected by this.
Full-speed hosting on the ESP32-S3 is unaffected and proven: audio in, audio out and UVC video capture all work there.
Summary
On the ESP32-P4,
usbif's USB host installs cleanly on the high-speed controller and then never detects a connection —attachesstays 0 forever, for every device tried, with and without a hub. The same physical port, cable and PHY work in device mode, enumerating against Windows as a composite CDC+MSC device.This reproduces the defect first recorded in
docs/phase0-findings.md("the P4's HS host detects no connection (the S3's FS host sees the same wire instantly — IDF's young P4 host support is the suspect)"), now with the confounders eliminated.Bench
USBD_P/USBD_NHS OTG port.ESP32_GENERIC_P4 / C6_WIFI, MicroPython 1.28.0, built from the aggregator after a fullerase_flash.What the host reports
host_statsis(running, attaches, detaches, errors, lib_devices, lib_clients). Zero attaches and zerolib_devicesmeans the controller never reported a connection — this is upstream of enumeration entirely.usb_host_lib_set_root_port_power(false/true)(host_port_cycle()) returns 0 and changes nothing.What device mode reports, on the same port and cable
So the connector, the cable, the HS PHY and the device stack's use of it are all good. Only the host role fails.
Ruled out
CONFIG_USB_HOST_HUBS_SUPPORTED=ywas already on the P4 board patch, andCONFIG_USB_HOST_HUB_MULTI_LEVEL=yis set in the built sdkconfigd6b5eb5(256 -> 4096). Necessary and correct — the camera's HS descriptor is 2306 bytes — but changed nothing here. Verified present in the built sdkconfigCONFIG_SOC_USB_OTG_PERIPH_NUM=2, so the driver's dual-controller branch compiles and passesperipheral_map = BIT1for the HS peripheral explicitlyinstall -> 0x0,client register -> 0x0USB_IN1_P/N, GPIO24/25) goes to header P2 through unpopulated series resistors and is not this portNot yet tried
PrtConnDet/PrtConnStsever assert, and what the PHY reports.host_intr_dump()currently returnsNoneand would be the natural place to expose this.usb_host_libexamples detect a device on this board — a useful upstream-vs-us discriminator before assuming the fault is ours.Impact
Blocks hosting USB devices on the P4, which is where high speed would unlock real UVC resolutions (the C920e offers 1280x720+ at HS versus 640x480 at FS). Does not block the P4 acting as a USB device — that works — so the "board becomes a USB camera" goal is unaffected by this.
Full-speed hosting on the ESP32-S3 is unaffected and proven: audio in, audio out and UVC video capture all work there.