summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Shawcroft <scott@adafruit.com>2019-08-12 15:58:09 -0700
committerGitHub <noreply@github.com>2019-08-12 15:58:09 -0700
commitc565ea6c29aa9ce34a42069fa6a5a0875a134f45 (patch)
tree37789a624cb94a3cf085325f41a565cd1fc00f36
parent9a6e603ced70d9472413d75ec0bc4a33a3ae7ec0 (diff)
parent33b949abfa9ab798a3de9d3b9ce3d2cbdbad10d0 (diff)
Merge pull request #2043 from jepler/issue1908
Improvements to Audio DMA management
-rw-r--r--ports/atmel-samd/audio_dma.c30
-rw-r--r--ports/atmel-samd/audio_dma.h3
-rw-r--r--ports/atmel-samd/background.c2
-rw-r--r--ports/atmel-samd/common-hal/audiobusio/PDMIn.c4
4 files changed, 30 insertions, 9 deletions
diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c
index 6b5eeddcc..481a420cb 100644
--- a/ports/atmel-samd/audio_dma.c
+++ b/ports/atmel-samd/audio_dma.c
@@ -35,6 +35,8 @@
#include "py/mpstate.h"
#include "py/runtime.h"
+#if CIRCUITPY_AUDIOIO || CIRCUITPY_AUDIOBUSIO
+
static audio_dma_t* audio_dma_state[AUDIO_DMA_CHANNEL_COUNT];
// This cannot be in audio_dma_state because it's volatile.
@@ -50,6 +52,18 @@ uint8_t find_free_audio_dma_channel(void) {
return channel;
}
+void audio_dma_disable_channel(uint8_t channel) {
+ if (channel >= AUDIO_DMA_CHANNEL_COUNT)
+ return;
+ dma_disable_channel(channel);
+}
+
+void audio_dma_enable_channel(uint8_t channel) {
+ if (channel >= AUDIO_DMA_CHANNEL_COUNT)
+ return;
+ dma_enable_channel(channel);
+}
+
void audio_dma_convert_signed(audio_dma_t* dma, uint8_t* buffer, uint32_t buffer_length,
uint8_t** output_buffer, uint32_t* output_buffer_length,
uint8_t* output_spacing) {
@@ -252,16 +266,19 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t* dma,
}
dma_configure(dma_channel, dma_trigger_source, true);
- dma_enable_channel(dma_channel);
+ audio_dma_enable_channel(dma_channel);
return AUDIO_DMA_OK;
}
void audio_dma_stop(audio_dma_t* dma) {
- dma_disable_channel(dma->dma_channel);
- disable_event_channel(dma->event_channel);
- MP_STATE_PORT(playing_audio)[dma->dma_channel] = NULL;
-
+ uint8_t channel = dma->dma_channel;
+ if (channel < AUDIO_DMA_CHANNEL_COUNT) {
+ audio_dma_disable_channel(channel);
+ disable_event_channel(dma->event_channel);
+ MP_STATE_PORT(playing_audio)[channel] = NULL;
+ audio_dma_state[channel] = NULL;
+ }
dma->dma_channel = AUDIO_DMA_CHANNEL_COUNT;
}
@@ -290,7 +307,7 @@ void audio_dma_reset(void) {
for (uint8_t i = 0; i < AUDIO_DMA_CHANNEL_COUNT; i++) {
audio_dma_state[i] = NULL;
audio_dma_pending[i] = false;
- dma_disable_channel(i);
+ audio_dma_disable_channel(i);
dma_descriptor(i)->BTCTRL.bit.VALID = false;
MP_STATE_PORT(playing_audio)[i] = NULL;
}
@@ -333,3 +350,4 @@ void audio_dma_background(void) {
audio_dma_pending[i] = false;
}
}
+#endif
diff --git a/ports/atmel-samd/audio_dma.h b/ports/atmel-samd/audio_dma.h
index 53173c277..9d923c5ce 100644
--- a/ports/atmel-samd/audio_dma.h
+++ b/ports/atmel-samd/audio_dma.h
@@ -83,6 +83,9 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t* dma,
bool output_signed,
uint32_t output_register_address,
uint8_t dma_trigger_source);
+
+void audio_dma_disable_channel(uint8_t channel);
+void audio_dma_enable_channel(uint8_t channel);
void audio_dma_stop(audio_dma_t* dma);
bool audio_dma_get_playing(audio_dma_t* dma);
void audio_dma_pause(audio_dma_t* dma);
diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c
index 4e88d34e7..694238070 100644
--- a/ports/atmel-samd/background.c
+++ b/ports/atmel-samd/background.c
@@ -56,7 +56,7 @@ void run_background_tasks(void) {
assert_heap_ok();
running_background_tasks = true;
- #if (defined(SAMD21) && defined(PIN_PA02)) || defined(SAMD51)
+ #if CIRCUITPY_AUDIOIO || CIRCUITPY_AUDIOBUSIO
audio_dma_background();
#endif
#if CIRCUITPY_DISPLAYIO
diff --git a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c
index 8b308b60b..da5c220a8 100644
--- a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+++ b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c
@@ -385,7 +385,7 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se
init_event_channel_interrupt(event_channel, CORE_GCLK, EVSYS_ID_GEN_DMAC_CH_0 + dma_channel);
// Turn on serializer now to get it in sync with DMA.
i2s_set_serializer_enable(self->serializer, true);
- dma_enable_channel(dma_channel);
+ audio_dma_enable_channel(dma_channel);
// Record
uint32_t buffers_processed = 0;
@@ -466,7 +466,7 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se
}
disable_event_channel(event_channel);
- dma_disable_channel(dma_channel);
+ audio_dma_disable_channel(dma_channel);
// Turn off serializer, but leave clock on, to avoid mic startup delay.
i2s_set_serializer_enable(self->serializer, false);