@@ -109,13 +109,14 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self,
109109 _pm_enable_bus_clock (PM_BUS_APBC , DAC );
110110 #endif
111111
112- // SAMD21: This clock should be <= 12 MHz, per datasheet section 47.6.3.
113- // SAMD51: This clock should be <= 350kHz, per datasheet table 37-6.
112+ // SAMD51: This clock should be <= 12 MHz, per datasheet section 47.6.3.
113+ // SAMD21: This clock is 48mhz despite the datasheet saying it must only be <= 350kHz, per
114+ // datasheet table 37-6. It's incorrect because the max output rate is 350ksps and is only
115+ // achieved when the GCLK is more than 8mhz.
114116 _gclk_enable_channel (DAC_GCLK_ID , CONF_GCLK_DAC_SRC );
115117
116-
117- DAC -> CTRLA .bit .SWRST = 1 ;
118- while (DAC -> CTRLA .bit .SWRST == 1 ) {}
118+ DAC -> CTRLA .bit .SWRST = 1 ;
119+ while (DAC -> CTRLA .bit .SWRST == 1 ) {}
119120
120121 bool channel0_enabled = true;
121122 #ifdef SAMD51
@@ -126,9 +127,11 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self,
126127 if (channel0_enabled ) {
127128 #ifdef SAMD21
128129 DAC -> EVCTRL .reg |= DAC_EVCTRL_STARTEI ;
130+ // We disable the voltage pump because we always run at 3.3v.
129131 DAC -> CTRLB .reg = DAC_CTRLB_REFSEL_AVCC |
130132 DAC_CTRLB_LEFTADJ |
131- DAC_CTRLB_EOEN ;
133+ DAC_CTRLB_EOEN |
134+ DAC_CTRLB_VPD ;
132135 #endif
133136 #ifdef SAMD51
134137 DAC -> EVCTRL .reg |= DAC_EVCTRL_STARTEI0 ;
@@ -278,6 +281,16 @@ void common_hal_audioio_audioout_play(audioio_audioout_obj_t* self,
278281 common_hal_audioio_audioout_stop (self );
279282 }
280283 audio_dma_result result = AUDIO_DMA_OK ;
284+ uint32_t sample_rate = audiosample_sample_rate (sample );
285+ #ifdef SAMD21
286+ uint32_t max_sample_rate = 350000 ;
287+ #endif
288+ #ifdef SAMD51
289+ uint32_t max_sample_rate = 1000000 ;
290+ #endif
291+ if (sample_rate > max_sample_rate ) {
292+ mp_raise_ValueError_varg ("Sample rate too high. It must be less than %d" , max_sample_rate );
293+ }
281294 #ifdef SAMD21
282295 result = audio_dma_setup_playback (& self -> left_dma , sample , loop , true, 0 ,
283296 false /* output unsigned */ ,
0 commit comments