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?
Usb host unstable
Re: Usb host unstable
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.
Re: Usb host unstable
No. I've even tried putting an explicit check in my code to prevent this scenario, but it didn't help.
Re: Usb host unstable
@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.
Re: Usb host unstable
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.
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 (16.51 KiB) Viewed 3173 times
Re: Usb host unstable
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.
Re: Usb host unstable
Im not entirely sure, but is it possible you are trying to send the same xfer again?
Please check transfer status, it says completed.
Please check transfer status, it says completed.
Re: Usb host unstable
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?
Is there anything I can do to try to recover from this failure?
Who is online
Users browsing this forum: Bing [Bot], danpf1, pineapple678 and 118 guests