diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index c8d7cec4b98f..48d27d14b0be 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -603,6 +603,11 @@ msgstr "" msgid "Audio conversion not implemented" msgstr "" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -2334,6 +2339,7 @@ msgstr "" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." msgstr "" diff --git a/ports/raspberrypi/audio_dma.c b/ports/raspberrypi/audio_dma.c index a067f36287ac..ecafe60b07cd 100644 --- a/ports/raspberrypi/audio_dma.c +++ b/ports/raspberrypi/audio_dma.c @@ -118,6 +118,7 @@ static size_t audio_dma_convert_samples(audio_dma_t *dma, uint8_t *input, uint32 // buffer_idx is 0 or 1. static void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) { + assert(dma->channel[buffer_idx] < NUM_DMA_CHANNELS); size_t dma_channel = dma->channel[buffer_idx]; audioio_get_buffer_result_t get_buffer_result; @@ -128,6 +129,7 @@ static void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) { if (get_buffer_result == GET_BUFFER_ERROR) { audio_dma_stop(dma); + dma->dma_result = AUDIO_DMA_SOURCE_ERROR; return; } @@ -157,10 +159,10 @@ static void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) { !dma_channel_is_busy(dma->channel[1])) { // No data has been read, and both DMA channels have now finished, so it's safe to stop. audio_dma_stop(dma); - dma->playing_in_progress = false; } } } + dma->dma_result = AUDIO_DMA_OK; } // Playback should be shutdown before calling this. @@ -279,8 +281,14 @@ audio_dma_result audio_dma_setup_playback( // Load the first two blocks up front. audio_dma_load_next_block(dma, 0); + if (dma->dma_result != AUDIO_DMA_OK) { + return dma->dma_result; + } if (!single_buffer) { audio_dma_load_next_block(dma, 1); + if (dma->dma_result != AUDIO_DMA_OK) { + return dma->dma_result; + } } // Special case the DMA for a single buffer. It's commonly used for a single wave length of sound @@ -464,7 +472,7 @@ static void dma_callback_fun(void *arg) { void __not_in_flash_func(isr_dma_0)(void) { for (size_t i = 0; i < NUM_DMA_CHANNELS; i++) { uint32_t mask = 1 << i; - if ((dma_hw->intr & mask) == 0) { + if ((dma_hw->ints0 & mask) == 0) { continue; } // acknowledge interrupt early. Doing so late means that you could lose an diff --git a/ports/raspberrypi/audio_dma.h b/ports/raspberrypi/audio_dma.h index 7c33a9e2ac31..b48456f5a83a 100644 --- a/ports/raspberrypi/audio_dma.h +++ b/ports/raspberrypi/audio_dma.h @@ -11,6 +11,13 @@ #include "src/rp2_common/hardware_dma/include/hardware/dma.h" +typedef enum { + AUDIO_DMA_OK, + AUDIO_DMA_DMA_BUSY, + AUDIO_DMA_MEMORY_ERROR, + AUDIO_DMA_SOURCE_ERROR, +} audio_dma_result; + typedef struct { mp_obj_t sample; uint8_t *buffer[2]; @@ -24,6 +31,7 @@ typedef struct { uint8_t sample_spacing; uint8_t output_resolution; // in bits uint8_t sample_resolution; // in bits + audio_dma_result dma_result; bool loop; bool single_channel_output; bool signed_to_unsigned; @@ -33,13 +41,6 @@ typedef struct { bool swap_channel; } audio_dma_t; -typedef enum { - AUDIO_DMA_OK, - AUDIO_DMA_DMA_BUSY, - AUDIO_DMA_MEMORY_ERROR, -} audio_dma_result; - - void audio_dma_init(audio_dma_t *dma); void audio_dma_deinit(audio_dma_t *dma); void audio_dma_reset(void); diff --git a/ports/raspberrypi/common-hal/audiobusio/I2SOut.c b/ports/raspberrypi/common-hal/audiobusio/I2SOut.c index f9484f546a89..559c023836fc 100644 --- a/ports/raspberrypi/common-hal/audiobusio/I2SOut.c +++ b/ports/raspberrypi/common-hal/audiobusio/I2SOut.c @@ -274,6 +274,9 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, } else if (result == AUDIO_DMA_MEMORY_ERROR) { common_hal_audiobusio_i2sout_stop(self); mp_raise_RuntimeError(MP_ERROR_TEXT("Unable to allocate buffers for signed conversion")); + } else if (result == AUDIO_DMA_SOURCE_ERROR) { + common_hal_audiobusio_i2sout_stop(self); + mp_raise_RuntimeError(MP_ERROR_TEXT("Audio source error")); } self->playing = true; diff --git a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c index d4cf161e6197..eee9060d1324 100644 --- a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +++ b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c @@ -214,6 +214,10 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, common_hal_audiopwmio_pwmaudioout_stop(self); mp_raise_RuntimeError(MP_ERROR_TEXT("Unable to allocate buffers for signed conversion")); } + if (result == AUDIO_DMA_SOURCE_ERROR) { + common_hal_audiopwmio_pwmaudioout_stop(self); + mp_raise_RuntimeError(MP_ERROR_TEXT("Audio source error")); + } // OK! We got all of the resources we need and dma is ready. }