Usb host unstable

Flatland
Posts: 4
Joined: Fri Nov 11, 2022 3:59 pm

Usb host unstable

Postby Flatland » Fri Nov 11, 2022 4:10 pm

I'm working on a project that uses the usb host capability of the ESP32 S3. For the first 5-45 minutes or so, everything works fine. After this I get ESP_ERR_INVALID_STATE when calling usb_host_transfer_submit().

Stepping through the code I can see that ep_obj->dynamic.num_urb_inflight=1 when entering usb_host_transfer_submit() and things are failing on this line in hcd_urb_enqueue:
HCD_CHECK(urb->hcd_ptr == NULL && urb->hcd_var == URB_HCD_STATE_IDLE, ESP_ERR_INVALID_STATE);

Once the first failure occurs it is permanent, the only way I have found to clear the problem is to replug the USB device or power it down with vbus control. Setting some breakpoints I can see that none of the interupt handlers in hcd.c ever get hit when in the problem state. I tried to use usb_host_endpoint_halt(), but this just blocks, probably because of the no interrupt thing.

I have tried version 4.4.1, 4.4.2 and 5 of the esp-idf, but this made no difference.

Any idea what might be causing this problem, or at least a fast and more elegant way to recover?

ESP_Dazz
Posts: 308
Joined: Fri Jun 02, 2017 6:50 am

Re: Usb host unstable

Postby ESP_Dazz » Sat Nov 12, 2022 8:44 am

Are you submitting a transfer again before it has completed (i.e., before the transfer's callback has been called). Each transfer (i.e., URB) internally keeps a state variable "hcd_var", that check is checking that the URB is indeed idle (i.e., has not be submitted yet) before trying to enqueue it for transfer.

Flatland
Posts: 4
Joined: Fri Nov 11, 2022 3:59 pm

Re: Usb host unstable

Postby Flatland » Sat Nov 12, 2022 3:05 pm

No. I've even tried putting an explicit check in my code to prevent this scenario, but it didn't help.

ESP_Dazz
Posts: 308
Joined: Fri Jun 02, 2017 6:50 am

Re: Usb host unstable

Postby ESP_Dazz » Tue Nov 15, 2022 6:05 am

@Flatland. Could you automatically launch GDB stub when crashing (via the CONFIG_ESP_SYSTEM_PANIC_GDBSTUB menuconfig option). Once the assertion fails inside hcd_urb_enqueue(), could you use GDB to dump the current values of the "urb" object? Those values could give use some clues as to what's currently going on with the transfer.

Flatland
Posts: 4
Joined: Fri Nov 11, 2022 3:59 pm

Re: Usb host unstable

Postby Flatland » Wed Nov 16, 2022 4:06 am

This is what I see in urb when hcd_urb_enqueue fails.

I also added a hook to the intr_hdlr_main() in hcd.c. My hook never gets called once the failure happens, but I do still see some activity on the D+/D- lines.
Attachments
urb.png
urb.png (16.51 KiB) Viewed 3174 times

ESP_Dazz
Posts: 308
Joined: Fri Jun 02, 2017 6:50 am

Re: Usb host unstable

Postby ESP_Dazz » Thu Nov 17, 2022 8:18 am

From what I can see, the "hcd_var == 2" means that it's currently set to the value of "URB_HCD_STATE_INFLIGHT". The "URB_HCD_STATE_INFLIGHT" state means that the URB has already been filled into one of the HCD's DMA lists. So the URB could either be:
  • Already transmitting on the USB bus, but can get stuck if the device is always NAKing. Why this could happen depends on the EP type and the device class
  • Waiting for the URB in front to complete. In other words, if I enqueue "URB A" and then "URB B" to the same pipe, and URB A is currently being transferred on the bus, the URB B will still be marked as "URB_HCD_STATE_INFLIGHT" (as it's been filled into the DMA list) but is still waiting for URB A to complete.

chegewara
Posts: 2371
Joined: Wed Jun 14, 2017 9:00 pm

Re: Usb host unstable

Postby chegewara » Thu Nov 17, 2022 8:31 am

Im not entirely sure, but is it possible you are trying to send the same xfer again?
Please check transfer status, it says completed.

Flatland
Posts: 4
Joined: Fri Nov 11, 2022 3:59 pm

Re: Usb host unstable

Postby Flatland » Sat Nov 19, 2022 2:26 am

In this case the device is a USB game controller. I've tried 3 different controllers and they all do the same thing. Two of them are HID controllers and one is an XBOX 360 controller.

Is there anything I can do to try to recover from this failure?

Who is online

Users browsing this forum: danpf1, MicroController and 132 guests