Skip to content

Commit 78a747e

Browse files
authored
Merge pull request #9989 from eightycc/issue-9983
Handle errors during audio DMA playback setup for RP2 ports
2 parents b323ae6 + 49dd58c commit 78a747e

File tree

5 files changed

+31
-9
lines changed

5 files changed

+31
-9
lines changed

locale/circuitpython.pot

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,11 @@ msgstr ""
603603
msgid "Audio conversion not implemented"
604604
msgstr ""
605605

606+
#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c
607+
#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c
608+
msgid "Audio source error"
609+
msgstr ""
610+
606611
#: shared-bindings/wifi/Radio.c
607612
msgid "AuthMode.OPEN is not used with password"
608613
msgstr ""
@@ -2334,6 +2339,7 @@ msgstr ""
23342339

23352340
#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h
23362341
#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h
2342+
#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h
23372343
msgid "You pressed the BOOT button at start up."
23382344
msgstr ""
23392345

ports/raspberrypi/audio_dma.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ static size_t audio_dma_convert_samples(audio_dma_t *dma, uint8_t *input, uint32
118118

119119
// buffer_idx is 0 or 1.
120120
static void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) {
121+
assert(dma->channel[buffer_idx] < NUM_DMA_CHANNELS);
121122
size_t dma_channel = dma->channel[buffer_idx];
122123

123124
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) {
128129

129130
if (get_buffer_result == GET_BUFFER_ERROR) {
130131
audio_dma_stop(dma);
132+
dma->dma_result = AUDIO_DMA_SOURCE_ERROR;
131133
return;
132134
}
133135

@@ -157,10 +159,10 @@ static void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) {
157159
!dma_channel_is_busy(dma->channel[1])) {
158160
// No data has been read, and both DMA channels have now finished, so it's safe to stop.
159161
audio_dma_stop(dma);
160-
dma->playing_in_progress = false;
161162
}
162163
}
163164
}
165+
dma->dma_result = AUDIO_DMA_OK;
164166
}
165167

166168
// Playback should be shutdown before calling this.
@@ -279,8 +281,14 @@ audio_dma_result audio_dma_setup_playback(
279281

280282
// Load the first two blocks up front.
281283
audio_dma_load_next_block(dma, 0);
284+
if (dma->dma_result != AUDIO_DMA_OK) {
285+
return dma->dma_result;
286+
}
282287
if (!single_buffer) {
283288
audio_dma_load_next_block(dma, 1);
289+
if (dma->dma_result != AUDIO_DMA_OK) {
290+
return dma->dma_result;
291+
}
284292
}
285293

286294
// 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) {
464472
void __not_in_flash_func(isr_dma_0)(void) {
465473
for (size_t i = 0; i < NUM_DMA_CHANNELS; i++) {
466474
uint32_t mask = 1 << i;
467-
if ((dma_hw->intr & mask) == 0) {
475+
if ((dma_hw->ints0 & mask) == 0) {
468476
continue;
469477
}
470478
// acknowledge interrupt early. Doing so late means that you could lose an

ports/raspberrypi/audio_dma.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@
1111

1212
#include "src/rp2_common/hardware_dma/include/hardware/dma.h"
1313

14+
typedef enum {
15+
AUDIO_DMA_OK,
16+
AUDIO_DMA_DMA_BUSY,
17+
AUDIO_DMA_MEMORY_ERROR,
18+
AUDIO_DMA_SOURCE_ERROR,
19+
} audio_dma_result;
20+
1421
typedef struct {
1522
mp_obj_t sample;
1623
uint8_t *buffer[2];
@@ -24,6 +31,7 @@ typedef struct {
2431
uint8_t sample_spacing;
2532
uint8_t output_resolution; // in bits
2633
uint8_t sample_resolution; // in bits
34+
audio_dma_result dma_result;
2735
bool loop;
2836
bool single_channel_output;
2937
bool signed_to_unsigned;
@@ -33,13 +41,6 @@ typedef struct {
3341
bool swap_channel;
3442
} audio_dma_t;
3543

36-
typedef enum {
37-
AUDIO_DMA_OK,
38-
AUDIO_DMA_DMA_BUSY,
39-
AUDIO_DMA_MEMORY_ERROR,
40-
} audio_dma_result;
41-
42-
4344
void audio_dma_init(audio_dma_t *dma);
4445
void audio_dma_deinit(audio_dma_t *dma);
4546
void audio_dma_reset(void);

ports/raspberrypi/common-hal/audiobusio/I2SOut.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self,
274274
} else if (result == AUDIO_DMA_MEMORY_ERROR) {
275275
common_hal_audiobusio_i2sout_stop(self);
276276
mp_raise_RuntimeError(MP_ERROR_TEXT("Unable to allocate buffers for signed conversion"));
277+
} else if (result == AUDIO_DMA_SOURCE_ERROR) {
278+
common_hal_audiobusio_i2sout_stop(self);
279+
mp_raise_RuntimeError(MP_ERROR_TEXT("Audio source error"));
277280
}
278281

279282
self->playing = true;

ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self,
214214
common_hal_audiopwmio_pwmaudioout_stop(self);
215215
mp_raise_RuntimeError(MP_ERROR_TEXT("Unable to allocate buffers for signed conversion"));
216216
}
217+
if (result == AUDIO_DMA_SOURCE_ERROR) {
218+
common_hal_audiopwmio_pwmaudioout_stop(self);
219+
mp_raise_RuntimeError(MP_ERROR_TEXT("Audio source error"));
220+
}
217221
// OK! We got all of the resources we need and dma is ready.
218222
}
219223

0 commit comments

Comments
 (0)