Merge pull request #8123 from jepler/issue8121-workaround
rp2040: Avoid screeches due to audio underflow during flash writes
This commit is contained in:
commit
5dc2b168d7
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user