From 655f2239165a81087c76ffa02f884ee02ff98980 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 18 Sep 2018 15:29:46 -0700 Subject: [PATCH] Clock the SAMD21 much faster so it can actually convert at its max sample rate of 350ksps. Also added an error check of sample rate. Fixes #1196 --- .../asf4_conf/samd21/peripheral_clk_config.h | 4 +-- .../atmel-samd/common-hal/audioio/AudioOut.c | 25 ++++++++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/ports/atmel-samd/asf4_conf/samd21/peripheral_clk_config.h b/ports/atmel-samd/asf4_conf/samd21/peripheral_clk_config.h index f472776028..2e1e238aab 100644 --- a/ports/atmel-samd/asf4_conf/samd21/peripheral_clk_config.h +++ b/ports/atmel-samd/asf4_conf/samd21/peripheral_clk_config.h @@ -385,7 +385,7 @@ // Select the clock source for DAC. #ifndef CONF_GCLK_DAC_SRC -#define CONF_GCLK_DAC_SRC GCLK_CLKCTRL_GEN_GCLK1_Val +#define CONF_GCLK_DAC_SRC GCLK_CLKCTRL_GEN_GCLK0_Val #endif /** @@ -393,7 +393,7 @@ * \brief DAC's Clock frequency */ #ifndef CONF_GCLK_DAC_FREQUENCY -#define CONF_GCLK_DAC_FREQUENCY 320000 +#define CONF_GCLK_DAC_FREQUENCY 48000000 #endif // USB Clock Source diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c index 4e39d3b442..45d67296ac 100644 --- a/ports/atmel-samd/common-hal/audioio/AudioOut.c +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -109,13 +109,14 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, _pm_enable_bus_clock(PM_BUS_APBC, DAC); #endif - // SAMD21: This clock should be <= 12 MHz, per datasheet section 47.6.3. - // SAMD51: This clock should be <= 350kHz, per datasheet table 37-6. + // SAMD51: This clock should be <= 12 MHz, per datasheet section 47.6.3. + // SAMD21: This clock is 48mhz despite the datasheet saying it must only be <= 350kHz, per + // datasheet table 37-6. It's incorrect because the max output rate is 350ksps and is only + // achieved when the GCLK is more than 8mhz. _gclk_enable_channel(DAC_GCLK_ID, CONF_GCLK_DAC_SRC); - - DAC->CTRLA.bit.SWRST = 1; - while (DAC->CTRLA.bit.SWRST == 1) {} + DAC->CTRLA.bit.SWRST = 1; + while (DAC->CTRLA.bit.SWRST == 1) {} bool channel0_enabled = true; #ifdef SAMD51 @@ -126,9 +127,11 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, if (channel0_enabled) { #ifdef SAMD21 DAC->EVCTRL.reg |= DAC_EVCTRL_STARTEI; + // We disable the voltage pump because we always run at 3.3v. DAC->CTRLB.reg = DAC_CTRLB_REFSEL_AVCC | DAC_CTRLB_LEFTADJ | - DAC_CTRLB_EOEN; + DAC_CTRLB_EOEN | + DAC_CTRLB_VPD; #endif #ifdef SAMD51 DAC->EVCTRL.reg |= DAC_EVCTRL_STARTEI0; @@ -278,6 +281,16 @@ void common_hal_audioio_audioout_play(audioio_audioout_obj_t* self, common_hal_audioio_audioout_stop(self); } audio_dma_result result = AUDIO_DMA_OK; + uint32_t sample_rate = audiosample_sample_rate(sample); + #ifdef SAMD21 + uint32_t max_sample_rate = 350000; + #endif + #ifdef SAMD51 + uint32_t max_sample_rate = 1000000; + #endif + if (sample_rate > max_sample_rate) { + mp_raise_ValueError_varg("Sample rate too high. It must be less than %d", max_sample_rate); + } #ifdef SAMD21 result = audio_dma_setup_playback(&self->left_dma, sample, loop, true, 0, false /* output unsigned */,