raspberrypi / pico-sdk

BSD 3-Clause "New" or "Revised" License
3.25k stars 838 forks source link

TinyUSB fails silently when multiple devices are connected at the same time #1680

Open theosib opened 3 months ago

theosib commented 3 months ago

I'm getting silent failure (no console messages or anything) from TinyUSB and/or the USB hardware.

My devices:

If works if I follow this sequence:

It fails if either:

Once it fails, it fails permanently. For example, if I get them working then unplug them both and then plug them in at the same time again, it fails. After that point, I cannot get ANY USB devices to be recognized again until I power cycle.

I have considered whether or not this might be some kind of voltage droop, so I have tried powering the Pico from a desktop power supply, and I have also tried two different powered USB hubs for supplying power to the peripherals. None of these helped. This and the fact that its failure lasts until reboot suggest to me that this is a problem with TinyUSB or the USB hardware in the RP2040, rather than a power supply issue.

One other potentially relevant fact is that I have been running TinyUSB from the second core. I'm calling board_init() from core 0, but I call tuh_init(BOARD_TUH_RHPORT); and tuh_task() (in a loop) from core 1. I'm concerned that support for doing USB on core 1 might be broken since I have a timing-critical ISR on core 0 that seems to get interfered with in a way that I haven't fully investigated yet whenever I connect a USB device, so if the USB hardware is trying assert an IRQ on core 0 at a higher priority than mine, then that could cause the trouble.

That said, I tried swapping everything runs on each core so that my ISR and main application logic run on core 1 while USB runs on core 0. What I find is that my ISR is no longer interfered with, but the problem of plugging in both the keyboard and mouse at once still happens. This may support my hypothesis that the USB hardware might be asserting an IRQ on core 0 despite initialization and everything else happening on core 1.

Another thing that might be relevant is that disabling MSC support seems to help just a little. When I go back and disable MSC support, it doesn't always fail silently. Sometimes, I get the error "process_enumeration 1254: ASSERT FAILED" when I plug in a device after the failure has occurred. The USB support is dead, but at least I get something out. BTW, that's this line in usbh.c:

      TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, process_enumeration, ENUM_SET_ADDR), );

Another thing I did was to make sure tuh_task() is called often enough. After having put some timing code in my task loop, what I find is that only tuh_task() ever takes significant time (almost exactly 500000 microseconds), and that's only when I plug in a USB device. Other things take time in the hundreds of microseconds (a few thousand at absolute worst).

BTW, I've also seen this message a few times:

tuh_hid_set_report 212: ASSERT FAILED

And this:

*** PANIC ***

ep 0 in was already available

I haven't figured out how to reproduce the first one, but the second one will occur sometimes if I plug and unplug a USB device a few times after failure has occurred. (It occurs on plugging in.)

I'm going to start instrumenting some of the USB code to see if I can get some more insight into what's going on. If anyone can make suggestions about things I can probe, that would be great. For instance, how do I query the state of the USB controller? I'll see if I can figure that out myself, but if anyone can suggest something specific, that would be great.

Thanks!

P.S. If you want to see the full source to my project, you can find it here: https://github.com/theosib/pico_vga.git

theosib commented 3 months ago

I tried another experiment. There's a newer version of TinyUSB available. I made a copy of the Pico SDK and then updated the TinyUSB submodule to the latest release. Here are some observations:

Unfortunately:

lurch commented 3 months ago

ping @hathach for comments on TinyUSB, and ping @shreeve as he mentioned that he's working on an independent USB host library.

theosib commented 3 months ago

Something weird is definitely going on with the USB controller. It's detecting that I plug in the devices, but it ultimately panics, indicating that the devices are disconnected. But obviously not since it does all sorts of transfers querying those devices. You can see the log on this bug report: https://github.com/hathach/tinyusb/issues/2556