rp2040: Avoid screeches due to audio underflow during flash writes
By pausing audio during flash writes, the worst screeching of #8121 is avoided. I don't consider this a full fix, but it greatly improves the by far most common scenario in which the problem occurs. Tested on rp2040 prop feather with a midi synth playing arpeggios. When writing to the flash e.g., with ``` dd bs=512 count=32 if=/dev/zero of=/media/jepler/CIRCUITPY/boop ``` the audio goes "tap tap tap tap" during the flash write instead of the squawking. This isn't a 100% fix; it will still glitch out, including during USB enumeration which must be taking a long time without servicing background tasks. Add a delay if not usb-connected at startup ameliorates this greatly.
This commit is contained in:
parent
7e6825daf6
commit
b4be2317cb
@ -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_cookie(uint32_t cookie) {
|
||||
for (size_t channel = 0; channel < NUM_DMA_CHANNELS; channel++) {
|
||||
audio_dma_t *dma = MP_STATE_PORT(playing_audio)[channel];
|
||||
if (dma != NULL && (cookie & (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_cookie(uint32_t cookie);
|
||||
|
||||
#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 cookie = 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_cookie(cookie);
|
||||
common_hal_mcu_enable_interrupts();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user