From 61698eb5d8d04da3a85dbbb42edc86858d42036b Mon Sep 17 00:00:00 2001 From: jepler Date: Sun, 15 Sep 2019 11:30:49 -0500 Subject: [PATCH] AnalogOut / AudioOut: Copy settings from Arduino Make changes in asf4_conf even though I think in these cases the "peripherals" submodule is running the show. Arduino clocks the DAC at 12MHz but uses the CCTRL setting for clocking < 1.2MHz (100kSPS). A fresh clock (6) is allocated for the new 12MHz clock. This matches the Arduino value, though not the GCLK index. Modify other settings to more closely resemble Arduino. In AudioOut, actually clock the waveform data from the timer we set up for this purpose. This gives good waveforms when setting AnalogOut full-scale in a loop, but the rise/fall of waveforms that come from AudioOut are still erratic. Weirdly, if AudioOut limits its range even slightly (e.g., to 1000..64000) then the erratic Note that this will require https://github.com/adafruit/samd-peripherals/pull/26 to be accepted for the submodule update here to work. --- .../atmel-samd/asf4_conf/samd51/hpl_dac_config.h | 4 ++-- .../atmel-samd/asf4_conf/samd51/hpl_gclk_config.h | 15 ++++++++------- .../asf4_conf/samd51/peripheral_clk_config.h | 2 +- ports/atmel-samd/common-hal/audioio/AudioOut.c | 12 +++++------- ports/atmel-samd/peripherals | 2 +- 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h index d6f1898db8..c46f99b7db 100644 --- a/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h @@ -51,7 +51,7 @@ // This defines the current in output buffer according to conversion rate // dac0_arch_cctrl #ifndef CONF_DAC0_CCTRL -#define CONF_DAC0_CCTRL 1 +#define CONF_DAC0_CCTRL 0 #endif // Run in standby @@ -90,7 +90,7 @@ // This defines the current in output buffer according to conversion rate // dac1_arch_cctrl #ifndef CONF_DAC1_CCTRL -#define CONF_DAC1_CCTRL 1 +#define CONF_DAC1_CCTRL 0 #endif // Run in standby diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h index a0748d0fa8..6f4f01a7e6 100644 --- a/ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h @@ -1,8 +1,9 @@ // Circuit Python SAMD51 clock tree: -// DFLL48M (with USBCRM on to sync with external USB ref) -> GCLK1, GCLK5 +// DFLL48M (with USBCRM on to sync with external USB ref) -> GCLK1, GCLK5, GCLK6 // GCLK1 (48MHz) -> 48 MHz peripherals -// GCLK5 (48 MHz divided down to 2 MHz) -> DPLL0, DAC peripherals +// GCLK5 (48 MHz divided down to 2 MHz) -> DPLL0 // DPLL0 (multiplied up to 120 MHz) -> GCLK0, GCLK4 (output for monitoring) +// GCLK6 (48 MHz divided down to 12 MHz) -> DAC // We'd like to use XOSC32K as a ref for DFLL48M on boards with a 32kHz crystal, // but haven't figured that out yet. @@ -472,7 +473,7 @@ // Indicates whether generic clock 6 configuration is enabled or not // enable_gclk_gen_6 #ifndef CONF_GCLK_GENERATOR_6_CONFIG -#define CONF_GCLK_GENERATOR_6_CONFIG 0 +#define CONF_GCLK_GENERATOR_6_CONFIG 1 #endif // Generic Clock Generator Control @@ -488,7 +489,7 @@ // This defines the clock source for generic clock generator 6 // gclk_gen_6_oscillator #ifndef CONF_GCLK_GEN_6_SOURCE -#define CONF_GCLK_GEN_6_SOURCE GCLK_GENCTRL_SRC_XOSC1 +#define CONF_GCLK_GEN_6_SOURCE GCLK_GENCTRL_SRC_DFLL #endif // Run in Standby @@ -523,14 +524,14 @@ // Indicates whether Improve Duty Cycle is enabled or not // gclk_arch_gen_6_idc #ifndef CONF_GCLK_GEN_6_IDC -#define CONF_GCLK_GEN_6_IDC 0 +#define CONF_GCLK_GEN_6_IDC 1 #endif // Generic Clock Generator Enable // Indicates whether Generic Clock Generator Enable is enabled or not // gclk_arch_gen_6_enable #ifndef CONF_GCLK_GEN_6_GENEN -#define CONF_GCLK_GEN_6_GENEN 0 +#define CONF_GCLK_GEN_6_GENEN 1 #endif // @@ -538,7 +539,7 @@ // Generic clock generator 6 division <0x0000-0xFFFF> // gclk_gen_6_div #ifndef CONF_GCLK_GEN_6_DIV -#define CONF_GCLK_GEN_6_DIV 1 +#define CONF_GCLK_GEN_6_DIV 4 #endif // // diff --git a/ports/atmel-samd/asf4_conf/samd51/peripheral_clk_config.h b/ports/atmel-samd/asf4_conf/samd51/peripheral_clk_config.h index 41efca755e..030a90a7a9 100644 --- a/ports/atmel-samd/asf4_conf/samd51/peripheral_clk_config.h +++ b/ports/atmel-samd/asf4_conf/samd51/peripheral_clk_config.h @@ -73,7 +73,7 @@ // dac_gclk_selection // Select the clock source for DAC. #ifndef CONF_GCLK_DAC_SRC -#define CONF_GCLK_DAC_SRC GCLK_PCHCTRL_GEN_GCLK5_Val +#define CONF_GCLK_DAC_SRC GCLK_PCHCTRL_GEN_GCLK6_Val #endif /** diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c index bb7e76414f..36ab520067 100644 --- a/ports/atmel-samd/common-hal/audioio/AudioOut.c +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -198,7 +198,7 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, #endif #ifdef SAMD51 DAC->EVCTRL.reg |= DAC_EVCTRL_STARTEI0; - DAC->DACCTRL[0].reg = DAC_DACCTRL_CCTRL_CC1M | + DAC->DACCTRL[0].reg = DAC_DACCTRL_CCTRL_CC100K | DAC_DACCTRL_ENABLE | DAC_DACCTRL_LEFTADJ; DAC->CTRLB.reg = DAC_CTRLB_REFSEL_VREFPU; @@ -207,7 +207,7 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, #ifdef SAMD51 if (channel1_enabled) { DAC->EVCTRL.reg |= DAC_EVCTRL_STARTEI1; - DAC->DACCTRL[1].reg = DAC_DACCTRL_CCTRL_CC1M | + DAC->DACCTRL[1].reg = DAC_DACCTRL_CCTRL_CC100K | DAC_DACCTRL_ENABLE | DAC_DACCTRL_LEFTADJ; DAC->CTRLB.reg = DAC_CTRLB_REFSEL_VREFPU; @@ -385,19 +385,17 @@ void common_hal_audioio_audioout_play(audioio_audioout_obj_t* self, #ifdef SAMD51 uint32_t left_channel_reg = (uint32_t) &DAC->DATABUF[0].reg; - uint8_t left_channel_trigger = DAC_DMAC_ID_EMPTY_0; + uint8_t tc_trig_id = TC0_DMAC_ID_OVF + 3 * self->tc_index; + uint8_t left_channel_trigger = tc_trig_id; uint32_t right_channel_reg = 0; - uint8_t right_channel_trigger = 0; + uint8_t right_channel_trigger = tc_trig_id; if (self->left_channel == &pin_PA05) { left_channel_reg = (uint32_t) &DAC->DATABUF[1].reg; - left_channel_trigger = DAC_DMAC_ID_EMPTY_1; } else if (self->right_channel == &pin_PA05) { right_channel_reg = (uint32_t) &DAC->DATABUF[1].reg; - right_channel_trigger = DAC_DMAC_ID_EMPTY_1; } if (self->right_channel == &pin_PA02) { right_channel_reg = (uint32_t) &DAC->DATABUF[0].reg; - right_channel_trigger = DAC_DMAC_ID_EMPTY_0; } result = audio_dma_setup_playback(&self->left_dma, sample, loop, true, 0, false /* output unsigned */, diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals index 83a4759d18..7c1c7e3195 160000 --- a/ports/atmel-samd/peripherals +++ b/ports/atmel-samd/peripherals @@ -1 +1 @@ -Subproject commit 83a4759d186574d8034435cd2303def85e4ed793 +Subproject commit 7c1c7e3195dc75a0a7ffa66c29a85edd3d0c4687