8000 Handle errors during audio DMA playback setup for RP2 ports by eightycc · Pull Request #9989 · adafruit/circuitpython · GitHub
[go: up one dir, main page]

Skip to content

Handle errors during audio DMA playback setup for RP2 ports #9989

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions locale/circuitpython.pot
Original file line number Diff line number Diff line change
Expand Up @@ -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 ""
Expand Down Expand Up @@ -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 ""

Expand Down
12 changes: 10 additions & 2 deletions ports/raspberrypi/audio_dma.c
8000
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
15 changes: 8 additions & 7 deletions ports/raspberrypi/audio_dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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;
Expand All @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions ports/raspberrypi/common-hal/audiobusio/I2SOut.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}

Expand Down
0