From 4895a9d1d83699ee273ab80aa1d4113b996bbc2c Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 27 Feb 2018 15:44:27 -0500 Subject: [PATCH] Use safe clock freqs for AnalogOut; use DAC REFRESH on SAMD51. --- ports/atmel-samd/asf4_conf/samd21/hpl_gclk_config.h | 11 ++++++----- .../asf4_conf/samd21/peripheral_clk_config.h | 4 ++-- ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h | 4 ++-- ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h | 4 ++-- .../asf4_conf/samd51/peripheral_clk_config.h | 4 ++-- ports/atmel-samd/common-hal/analogio/AnalogOut.c | 6 ++++-- 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_gclk_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_gclk_config.h index 90df195cd8..d4c9bf2abe 100644 --- a/ports/atmel-samd/asf4_conf/samd21/hpl_gclk_config.h +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_gclk_config.h @@ -1,12 +1,13 @@ // Circuit Python SAMD21 clock tree: -// DFLL48M (with USBCRM on to sync with external USB ref) -> GCLK0 +// DFLL48M (with USBCRM on to sync with external USB ref) -> GCLK0, GCLK1 // GCLK0 (48MHz) -> peripherals +// GLCK1 (48MHz divided by 150 = 320Khz) -> DAC peripheral (DAC requires 350KHz or lower) // We'd like to use XOSC32K as a ref for DFLL48M on boards with a 32kHz crystal, // but haven't figured that out yet. // Used in hpl/core/hpl_init.c to define which clocks should be initialized first. -#define CIRCUITPY_GCLK_INIT_1ST (1 << 0) +#define CIRCUITPY_GCLK_INIT_1ST (1 << 0 | 1 << 1) /* Auto-generated config file hpl_gclk_config.h */ @@ -127,7 +128,7 @@ // Indicates whether Output Enable is enabled or not // gclk_arch_gen_1_oe #ifndef CONF_GCLK_GEN_1_OE -#define CONF_GCLK_GEN_1_OE 0 +#define CONF_GCLK_GEN_1_OE 1 #endif // Output Off Value @@ -172,7 +173,7 @@ // This defines the clock source for generic clock generator 1 // gclk_gen_1_oscillator #ifndef CONF_GCLK_GEN_1_SRC -#define CONF_GCLK_GEN_1_SRC GCLK_GENCTRL_SRC_XOSC32K +#define CONF_GCLK_GEN_1_SRC GCLK_GENCTRL_SRC_DFLL48M #endif // @@ -181,7 +182,7 @@ // // gclk_gen_1_div #ifndef CONF_GCLK_GEN_1_DIV -#define CONF_GCLK_GEN_1_DIV 1 +#define CONF_GCLK_GEN_1_DIV 150 #endif // 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 84fc6b9e4a..cb7dad2041 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_GCLK0_Val +#define CONF_GCLK_DAC_SRC GCLK_CLKCTRL_GEN_GCLK1_Val #endif /** @@ -393,7 +393,7 @@ * \brief DAC's Clock frequency */ #ifndef CONF_GCLK_DAC_FREQUENCY -#define CONF_GCLK_DAC_FREQUENCY 48000000 +#define CONF_GCLK_DAC_FREQUENCY 320000 #endif // USB Clock Source 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 6e530941e7..d6f1898db8 100644 --- a/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_dac_config.h @@ -72,7 +72,7 @@ // This defines the refresh period. If it is 0, the refresh mode is disabled, else the refresh period is: value * 500us // dac0_arch_refresh #ifndef CONF_DAC0_REFRESH -#define CONF_DAC0_REFRESH 0 +#define CONF_DAC0_REFRESH 2 #endif // // Channel 1 configuration @@ -111,7 +111,7 @@ // This defines the refresh period. If it is 0, the refresh mode is disabled, else the refresh period is: value * 500us // dac1_arch_refresh #ifndef CONF_DAC1_REFRESH -#define CONF_DAC1_REFRESH 0 +#define CONF_DAC1_REFRESH 2 #endif // 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 300db2716d..77793b69a5 100644 --- a/ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_gclk_config.h @@ -1,7 +1,7 @@ // Circuit Python SAMD51 clock tree: // DFLL48M (with USBCRM on to sync with external USB ref) -> GCLK1, GCLK5 -// GCLK1 (48MHz) -> peripherals -// GCLK5 (divided down to 2 MHz) -> DPLL0 +// GCLK1 (48MHz) -> 48 MHz peripherals +// GCLK5 (48 MHz divided down to 2 MHz) -> DPLL0, DAC peripherals // DPLL0 (multiplied up to 120 MHz) -> GCLK0, GCLK4 (output for monitoring) // We'd like to use XOSC32K as a ref for DFLL48M on boards with a 32kHz crystal, 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 c1df632113..41efca755e 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_GCLK1_Val +#define CONF_GCLK_DAC_SRC GCLK_PCHCTRL_GEN_GCLK5_Val #endif /** @@ -81,7 +81,7 @@ * \brief DAC's Clock frequency */ #ifndef CONF_GCLK_DAC_FREQUENCY -#define CONF_GCLK_DAC_FREQUENCY 48000000 +#define CONF_GCLK_DAC_FREQUENCY 2000000 #endif // EVSYS Channel 0 Clock Source diff --git a/ports/atmel-samd/common-hal/analogio/AnalogOut.c b/ports/atmel-samd/common-hal/analogio/AnalogOut.c index 1d53781b16..44258c3c1d 100644 --- a/ports/atmel-samd/common-hal/analogio/AnalogOut.c +++ b/ports/atmel-samd/common-hal/analogio/AnalogOut.c @@ -65,12 +65,14 @@ void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, #ifdef SAMD51 hri_mclk_set_APBDMASK_DAC_bit(MCLK); + // This clock should be <= 12 MHz, per datasheet section 47.6.3. hri_gclk_write_PCHCTRL_reg(GCLK, DAC_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK5_Val | (1 << GCLK_PCHCTRL_CHEN_Pos)); #endif #ifdef SAMD21 _pm_enable_bus_clock(PM_BUS_APBC, DAC); - _gclk_enable_channel(DAC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val); + // This clock should be <= 350kHz, per datasheet table 37-6. + _gclk_enable_channel(DAC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK1_Val); #endif // Don't double init the DAC on the SAMD51 when both outputs are in use. We use the free state @@ -123,7 +125,7 @@ void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) { void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, uint16_t value) { - // Input is 16 bit so make sure and set LEFTADJ to 1 to it takes the top + // Input is 16 bit so make sure and set LEFTADJ to 1 so it takes the top // bits. This is currently done in asf4_conf/*/hpl_dac_config.h. dac_sync_write(&self->descriptor, self->channel, &value, 1); }