rp2: use irq_add_shared_handler() for DMA_IRQ_0 instead of fixed isr_dma_0()#11054
Merged
Merged
Conversation
…dma_0() audio_dma.c defined the DMA_IRQ_0 handler as the fixed isr_dma_0() linker symbol and dispatched to both audio and rp2pio from it. Per the Pico SDK docs this is impolite: it permanently owns the vector and prevents other code from cooperating on the IRQ at runtime. It also meant rp2pio's DMA completion was silently broken when CIRCUITPY_AUDIOCORE=0, since the dispatch lived inside that guard. Convert DMA_IRQ_0 to per-subsystem shared handlers: audiocore and rp2pio each register their own handler with irq_add_shared_handler(), add it on the first channel they enable and remove it on the last, and acknowledge only their own channels. picodvi's exclusive DMA_IRQ_1 handler is unchanged. Document the DMA IRQ allocation policy (which IRQs are shared vs. exclusive) in common-hal/microcontroller/__init__.c. Adds manual hardware regression tests under tests/circuitpython-manual/rp2pio/ that exercise audio DMA, rp2pio background write, and rp2pio background read sharing DMA_IRQ_0. They use only pre-existing public APIs and pass identically before and after this change. Closes adafruit#9992 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
FoamyGuy
approved these changes
Jun 12, 2026
FoamyGuy
left a comment
Collaborator
There was a problem hiding this comment.
Looks good to me. Thanks for the fix!
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.
This post was mostly written by Claude Code. I originally addressed this bug using Copilot, which was using ChatGPT-4.5, but Claude did a much better job. Copilot's own tests would not run. The Claude code is cleaner as well. -- @dhalbert
Addresses #9992.
Problem
ports/raspberrypi/audio_dma.cdefined the DMA_IRQ_0 handler as the fixedisr_dma_0()linker symbol and dispatched to both audio and rp2pio from it. Per the Pico SDK docs, definingisr_dma_0makes that function the permanent DMA_IRQ_0 vector and prevents other code from cooperating on the IRQ at runtime ("can cause link conflicts at runtime, and offers no runtime performance benefit"). See also the discussion in #9868.Two concrete issues:
#if CIRCUITPY_AUDIOCORE, yet rp2pio relied on it — so rp2pio background DMA was silently broken whenCIRCUITPY_AUDIOCORE=0.Change
Convert DMA_IRQ_0 to per-subsystem shared handlers:
audio_dma.c) and rp2pio (StateMachine.c) each register their own handler viairq_add_shared_handler(), add it on the first channel they enable and remove it on the last, and acknowledge only their own channels.dma_hw->inte0/irq_set_mask_enabled()manipulation is replaced withdma_irqn_set_channel_enabled()/irq_set_enabled().DMA_IRQ_1handler is unchanged.common-hal/microcontroller/__init__.c.This also fixes the
CIRCUITPY_AUDIOCORE=0case, since rp2pio now owns its own handler.Testing
Builds clean for RP2040 (
raspberry_pi_pico_w) and RP2350 (raspberry_pi_pico2).Adds manual hardware regression tests under
tests/circuitpython-manual/rp2pio/that exercise audio DMA, rp2pio background write, and rp2pio background read sharing DMA_IRQ_0. They use only pre-existing public APIs and pass identically on firmware built before and after this change (verified on hardware).I tested using the regressions tests listed above, and also tested on Fruit Jam using a hacked-up version of the Fruit Jam OS startup animation program. I made it repeat over and over, and also added some NeoPixel manipulations. It worked. -- @dhalbert
🤖 Generated with Claude Code