Skip to content

Commit

Permalink
Merge pull request #8123 from jepler/issue8121-workaround
Browse files Browse the repository at this point in the history
rp2040: Avoid screeches due to audio underflow during flash writes
  • Loading branch information
tannewt authored Jun 27, 2023
2 parents 324ecc2 + 3853661 commit 5dc2b16
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
21 changes: 21 additions & 0 deletions ports/raspberrypi/audio_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions ports/raspberrypi/audio_dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 4 additions & 0 deletions ports/raspberrypi/supervisor/internal_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

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

Expand Down

0 comments on commit 5dc2b16

Please sign in to comment.