tinyusb icon indicating copy to clipboard operation
tinyusb copied to clipboard

ESP32-P4 issue with output transfers on HS phy in host mode.

Open AndyDevLat opened this issue 5 months ago • 4 comments

Operating System

Others

Commit SHA

current master branch tested on ESP-IDF 5.4

Board

ESP32-P4-Function-EV-Board

Firmware

examples/host/hid_controller

What happened ?

Output transfers on interrupt endpoint fail after several successful transfers.

How to reproduce ?

Just compile standard hid_controller example from tinyusb and attach DualShock 4 controller.

Debug Log as txt file (LOG/CFG_TUSB_DEBUG=2)

Typical log with DualShock4 (logging for IN endpoints was commented in tinyusb for clearance):

ID = 054c, PID = 09cc HID Send Report 5 (x, y, z, rz) = (125, 127, 128, 128) DPad = none [:1] on EP 03 with 32 bytes: OK HID Send Report 5 [:1] on EP 03 with 32 bytes: OK HID Send Report 5 [:1] on EP 03 with 32 bytes: OK HID Send Report 5 [:1] on EP 03 with 0 bytes: FAILED HID Send Report 5 [:1] on EP 03 with 0 bytes: FAILED HID Send Report 5 [:1] on EP 03 with 0 bytes: FAILED HID Send Report 5 [:1] on EP 03 with 0 bytes: FAILED HID Send Report 5 [:1] on EP 03 with 0 bytes: FAILED

Screenshots

I was trying to use tinyusb in host mode on HS PHY (UTMI) of ESP32-P4 (i use ESP32-P4-Function-EV-Board). Tinyusb sources were compiled from the current master branch on ESP-IDF 5.4. In CMakeList.txt of my project i have added such definitions: set(compile_definitions CFG_TUSB_MCU=OPT_MCU_ESP32P4 CFG_TUSB_OS=OPT_OS_FREERTOS CFG_TUSB_MEM_SECTION=DRAM_DMA_ALIGNED_ATTR CFG_TUSB_MEM_ALIGN=attribute((aligned(64))) )

HS PHY was explicitly initialized with the following code:

usb_phy_config_t phy_conf = {
    .controller = USB_PHY_CTRL_OTG,
    .target     = USB_PHY_TARGET_UTMI,
    .otg_mode   = USB_OTG_MODE_HOST,
    .otg_speed  = USB_PHY_SPEED_UNDEFINED
};
usb_new_phy(&phy_conf, &phy_hdl);

Root port in tusb_config.h was also selected in via: #define CFG_TUSB_RHPORT1_MODE OPT_MODE_HOST | OPT_MODE_HIGH_SPEED. I also have set the following define to enable buffer DMA mode: #define CFG_TUH_DWC2_DMA_ENABLE 1 And then standard tinyusb loop is run:

tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; tusb_init(TUH_OPT_RHPORT, &host_init);

while (1) { tuh_task(); hid_app_task(); }

When device is first connected several transactions on output interrupt EP succeed, but then at some point transfer fails. It should be noted that even unplug and replug of controller does not help - the board needs to be reset for output endpoints to start working again. I have experimented with other HID controllers but results are similar. Looks like there is some low-level problem in hcd_dwc2.c. Note that there is no problem with built-in USB host stack of Espessif, but we need to use tinyusb for our project because we'll need HS hub in future and Espessif does not support FS devices attached to it (and even not plans to according to their posts).

I have checked existing issues, dicussion and documentation

  • [x] I confirm I have checked existing issues, dicussion and documentation.

AndyDevLat avatar Jul 11 '25 04:07 AndyDevLat

Hm....could be cache-related.

Could you try to enable CFG_TUH_MEM_DCACHE_ENABLE ?

roma-jam avatar Jul 11 '25 08:07 roma-jam

Thank you for your response!

Cache flush/invalidation is working: it is set in tusb_mcu.h automatially for OPT_MCU_ESP32P4:

// Enable dcache if DMA is enabled #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 64

To make sure I have also inserted logs into hcd_dcache_... functions - the are definitely called.

But the issue seems not DMA related: it tried to comment CFG_TUH_DWC2_DMA_ENABLE to put DWC2 in slave mode - it still locks up on OUT transfers after some time and hard reset is needed. At the same time IN transfers work fine always, so some issue seems to be with TX FIFO settings.

As i side note, i see new ESP-IDF version has added usb_dwc_hal_set_fifo_config function. Does it have sense to call this function maybe from dfifo_host_init (which is called from hcd_init) for FIFO allocation? Or this function is desiged for Scatter-gather DMA only used by Espessif host?

AndyDevLat avatar Jul 11 '25 09:07 AndyDevLat

@AndyDevLat ,

right now I don't think that mixing fifo settings from esp-idf and hcd_dwc2 from tinyusb somehow can help.

But the issue could be related to the way, how we access the resisters. The one issue was on S3 (yes, not RISC-V, as P4 but stll): https://github.com/hathach/tinyusb/issues/3047#issuecomment-2759331873

Could you check the discussion from the link above and compare the description and the output with your case?

roma-jam avatar Jul 11 '25 10:07 roma-jam

In my case device enumeration is always succesful, so no problem with control transfers. Only interupt OUT transfers exhibit problems. Also it does not matter if DMA is enabled or not, so it seems issue is a bit different, but maybe it is because of different architecture. If it is related to some registers or compilation issues, as mentioned in the above post, wouldn't it always fail immediately and not after some time? To me it looks more like some FIFO overflow or whatever, maybe something is not freed properly when channel is disabled after transfer, I have no deep knowledge of DWC2 architecture. Could it also may be some race condition between tuh_hid_send_report and ISR when IN report happens to arrive at the same time? I was also thinking about disabling interrupts during tuh_hid_send_report but not so sure about this.

AndyDevLat avatar Jul 11 '25 10:07 AndyDevLat