diff --git a/ports/raspberrypi/audio_dma.c b/ports/raspberrypi/audio_dma.c index 612fbbde4c41..b5bd8c069c83 100644 --- a/ports/raspberrypi/audio_dma.c +++ b/ports/raspberrypi/audio_dma.c @@ -388,6 +388,27 @@ bool audio_dma_get_paused(audio_dma_t *dma) { return (control & DMA_CH0_CTRL_TRIG_EN_BITS) == 0; } +uint32_t audio_dma_pause_all(void) { + uint32_t result = 0; + for (size_t channel = 0; channel < NUM_DMA_CHANNELS; channel++) { + audio_dma_t *dma = MP_STATE_PORT(playing_audio)[channel]; + if (dma != NULL && !audio_dma_get_paused(dma)) { + audio_dma_pause(dma); + result |= (1 << channel); + } + } + return result; +} + +void audio_dma_unpause_mask(uint32_t channel_mask) { + for (size_t channel = 0; channel < NUM_DMA_CHANNELS; channel++) { + audio_dma_t *dma = MP_STATE_PORT(playing_audio)[channel]; + if (dma != NULL && (channel_mask & (1 << channel))) { + audio_dma_resume(dma); + } + } +} + void audio_dma_init(audio_dma_t *dma) { dma->buffer[0] = NULL; dma->buffer[1] = NULL; diff --git a/ports/raspberrypi/audio_dma.h b/ports/raspberrypi/audio_dma.h index ae9a07a60456..e84a79df26cd 100644 --- a/ports/raspberrypi/audio_dma.h +++ b/ports/raspberrypi/audio_dma.h @@ -89,4 +89,7 @@ void audio_dma_pause(audio_dma_t *dma); void audio_dma_resume(audio_dma_t *dma); bool audio_dma_get_paused(audio_dma_t *dma); +uint32_t audio_dma_pause_all(void); +void audio_dma_unpause_mask(uint32_t channel_mask); + #endif // MICROPY_INCLUDED_RASPBERRYPI_AUDIO_DMA_OUT_H diff --git a/ports/raspberrypi/supervisor/internal_flash.c b/ports/raspberrypi/supervisor/internal_flash.c index 9216f1ebe2c6..42223b29e3df 100644 --- a/ports/raspberrypi/supervisor/internal_flash.c +++ b/ports/raspberrypi/supervisor/internal_flash.c @@ -39,6 +39,7 @@ #include "lib/oofatfs/ff.h" #include "shared-bindings/microcontroller/__init__.h" +#include "audio_dma.h" #include "supervisor/flash.h" #include "supervisor/usb.h" @@ -97,9 +98,12 @@ void port_internal_flash_flush(void) { } // Make sure we don't have an interrupt while we do flash operations. common_hal_mcu_disable_interrupts(); + // and audio DMA must be paused as well + uint32_t channel_mask = audio_dma_pause_all(); flash_range_erase(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + _cache_lba, SECTOR_SIZE); flash_range_program(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + _cache_lba, _cache, SECTOR_SIZE); _cache_lba = NO_CACHE; + audio_dma_unpause_mask(channel_mask); common_hal_mcu_enable_interrupts(); }