audiocore: Fix race window in i2s_stop
All checks were successful
Build RPi Pico firmware image / Build-Firmware (push) Successful in 3m23s
Check code formatting / Check-C-Format (push) Successful in 7s
Check code formatting / Check-Python-Flake8 (push) Successful in 10s
Check code formatting / Check-Bash-Shellcheck (push) Successful in 4s
Run unit tests on host / Run-Unit-Tests (push) Successful in 8s
Run pytests / Check-Pytest (push) Successful in 10s
All checks were successful
Build RPi Pico firmware image / Build-Firmware (push) Successful in 3m23s
Check code formatting / Check-C-Format (push) Successful in 7s
Check code formatting / Check-Python-Flake8 (push) Successful in 10s
Check code formatting / Check-Bash-Shellcheck (push) Successful in 4s
Run unit tests on host / Run-Unit-Tests (push) Successful in 8s
Run pytests / Check-Pytest (push) Successful in 10s
Apply the same pattern as in6f155ebb55("audiocore: Fix small race window in get_fifo_read_value_blocking") and2a4033d3ca("rp2_sd: Fix race window in sd_spi_wait_complete") to the wait for interrupt in i2s_stop too. Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
This commit is contained in:
@@ -91,19 +91,21 @@ void i2s_stop(void)
|
|||||||
{
|
{
|
||||||
if (!i2s_context.playback_active)
|
if (!i2s_context.playback_active)
|
||||||
return;
|
return;
|
||||||
bool have_data = false;
|
while (true) {
|
||||||
do {
|
|
||||||
const long flags = save_and_disable_interrupts();
|
const long flags = save_and_disable_interrupts();
|
||||||
const int next_buf = (i2s_context.cur_playing + 1) % AUDIO_BUFS;
|
const int next_buf = (i2s_context.cur_playing + 1) % AUDIO_BUFS;
|
||||||
have_data = i2s_context.has_data[next_buf];
|
const bool have_data = i2s_context.has_data[next_buf];
|
||||||
restore_interrupts(flags);
|
if (!have_data) {
|
||||||
if (have_data)
|
|
||||||
__wfi();
|
|
||||||
} while (have_data);
|
|
||||||
const long flags = save_and_disable_interrupts();
|
|
||||||
i2s_context.playback_active = false;
|
i2s_context.playback_active = false;
|
||||||
shared_context.underruns = 0;
|
shared_context.underruns = 0;
|
||||||
restore_interrupts(flags);
|
restore_interrupts(flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
__wfi();
|
||||||
|
restore_interrupts(flags);
|
||||||
|
__nop(); // Ensure at least two instructions between enable interrupts and subsequent disable
|
||||||
|
__nop();
|
||||||
|
}
|
||||||
// Workaround rp2040 E13
|
// Workaround rp2040 E13
|
||||||
dma_channel_set_irq1_enabled(i2s_context.dma_ch, false);
|
dma_channel_set_irq1_enabled(i2s_context.dma_ch, false);
|
||||||
dma_channel_abort(i2s_context.dma_ch);
|
dma_channel_abort(i2s_context.dma_ch);
|
||||||
|
|||||||
Reference in New Issue
Block a user