-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
I'm getting silent failure (no console messages or anything) from TinyUSB and/or the USB hardware.
My devices:
- Mac USB keyboard
- Genetic optical mouse (tried two different ones)
If works if I follow this sequence:
- Turn power on with no devices
- Plug in the keyboard
- Then plug in the mouse
It fails if either:
- They're already plugged in at power-up
- They plugged in later both at the same time (mouse plugged into keyboard or both into USB hub, powered or not)
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