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)
|
||||
return;
|
||||
bool have_data = false;
|
||||
do {
|
||||
while (true) {
|
||||
const long flags = save_and_disable_interrupts();
|
||||
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];
|
||||
if (!have_data) {
|
||||
i2s_context.playback_active = false;
|
||||
shared_context.underruns = 0;
|
||||
restore_interrupts(flags);
|
||||
break;
|
||||
}
|
||||
__wfi();
|
||||
restore_interrupts(flags);
|
||||
if (have_data)
|
||||
__wfi();
|
||||
} while (have_data);
|
||||
const long flags = save_and_disable_interrupts();
|
||||
i2s_context.playback_active = false;
|
||||
shared_context.underruns = 0;
|
||||
restore_interrupts(flags);
|
||||
__nop(); // Ensure at least two instructions between enable interrupts and subsequent disable
|
||||
__nop();
|
||||
}
|
||||
// Workaround rp2040 E13
|
||||
dma_channel_set_irq1_enabled(i2s_context.dma_ch, false);
|
||||
dma_channel_abort(i2s_context.dma_ch);
|
||||
|
||||
Reference in New Issue
Block a user