From b24c9cf2a9d8b0d12a17ea3c7d83b133483a7024 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 24 Nov 2025 14:00:34 -0700 Subject: [PATCH] rp2/rp2_dma: Properly close DMA channels. Clears the control registers and aborts the closed channel upon a call to `.close()` and `.__del__()` (GC collect). Fixes issue #18446. Signed-off-by: Dryw Wade --- ports/rp2/rp2_dma.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ports/rp2/rp2_dma.c b/ports/rp2/rp2_dma.c index 94c61e226e..471cf24ea2 100644 --- a/ports/rp2/rp2_dma.c +++ b/ports/rp2/rp2_dma.c @@ -427,6 +427,14 @@ static mp_obj_t rp2_dma_close(mp_obj_t self_in) { uint8_t channel = self->channel; if (channel != CHANNEL_CLOSED) { + // Reset this channel's registers to their default values (zeros). + dma_channel_config config = { .ctrl = 0 }; + dma_channel_configure(channel, &config, NULL, NULL, 0, false); + + // Abort this channel. Must be done after clearing EN bit in control + // register due to errata RP2350-E5. + dma_channel_abort(channel); + // Clean up interrupt handler to ensure garbage collection mp_irq_obj_t *irq = MP_STATE_PORT(rp2_dma_irq_obj[channel]); MP_STATE_PORT(rp2_dma_irq_obj[channel]) = MP_OBJ_NULL;