raspberrypi: wake core 0 from idle when core 1 posts USB host events#11130
Merged
Conversation
Why: on rp2 the TinyUSB host task only runs when core 0 drains the background callback queue. The PIO USB host runs on core 1 and posts its events there, but port_wake_main_task() was a no-op, so core 1 could not wake core 0 out of the WFI in port_idle_until_interrupt(). While a program is in time.sleep(), core 0 stays parked in that WFI for the whole sleep, so host events never get serviced. A device plugged in while a program sleeps can fail to enumerate. What: implement port_wake_main_task() as SEV and idle with WFE instead of WFI, so core 1 can wake core 0. SEVONPEND keeps the old wake on pending interrupt behavior. Shared port.c, so it covers both rp2040 and rp2350. Testing: a program looping "find(); time.sleep(0.5)" with no other USB polling. Plug a device into the host port while it runs. On main it never enumerates (over 50 seconds). With this change it enumerates within one loop iteration. Confirmed on a Fruit Jam (RP2350) and a Feather RP2040 USB Host (RP2040).
mikeysklar
marked this pull request as ready for review
July 18, 2026 02:31
Collaborator
|
Did you try running something like Fruit Jam OS to smoke test general operation? Thanks if you can. |
Collaborator
Author
dhalbert
approved these changes
Jul 19, 2026
dhalbert
left a comment
Collaborator
There was a problem hiding this comment.
Thanks for general testing. This looks OK. I don't know how I might have come up with the this fix, though. Hurrah for LLMs.
Collaborator
Author
|
The LLM added a lot of instrumentation and at one point looked at how espressif was doing |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

On rp2, the TinyUSB host task only runs when core 0 drains the background callback queue. The PIO USB host runs on core 1 and posts its events there, but
port_wake_main_task()was a no-op, so core 1 could not wake core 0 out of the WFI inport_idle_until_interrupt(). While a program is intime.sleep(), core 0 stays parked in that WFI for the whole sleep, so host events never get serviced. A device plugged in while a program sleeps can fail to enumerate at all.Implement
port_wake_main_task()as SEV and idle with WFE instead of WFI, so core 1 can wake core 0. SEVONPEND keeps the old wake on pending interrupt behavior. It lives in sharedport.c, so it covers both rp2040 and rp2350. 12 lines of code.Start this with nothing in the host port, then hot-plug a USB device while it runs:
On the current main it never prints
enumerated, the device never shows up while the program sleeps (over 50 seconds):With this PR it enumerates within one loop iteration:
Confirmed on a Fruit Jam (RP2350) and a Feather RP2040 USB Host (RP2040).