Merge pull request #8123 from jepler/issue8121-workaround

rp2040: Avoid screeches due to audio underflow during flash writes
This commit is contained in:
Scott Shawcroft 2023-06-27 09:09:03 -07:00 committed by GitHub
commit 5dc2b168d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 0 deletions

View File

@ -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;

View File

@ -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

View File

@ -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();
}