Use safe clock freqs for AnalogOut; use DAC REFRESH on SAMD51.

This commit is contained in:
Dan Halbert 2018-02-27 15:44:27 -05:00
parent 5eb3b208e8
commit 4895a9d1d8
6 changed files with 18 additions and 15 deletions

View File

@ -1,12 +1,13 @@
// Circuit Python SAMD21 clock tree: // 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 // 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, // We'd like to use XOSC32K as a ref for DFLL48M on boards with a 32kHz crystal,
// but haven't figured that out yet. // but haven't figured that out yet.
// Used in hpl/core/hpl_init.c to define which clocks should be initialized first. // 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 */ /* Auto-generated config file hpl_gclk_config.h */
@ -127,7 +128,7 @@
// <i> Indicates whether Output Enable is enabled or not // <i> Indicates whether Output Enable is enabled or not
// <id> gclk_arch_gen_1_oe // <id> gclk_arch_gen_1_oe
#ifndef CONF_GCLK_GEN_1_OE #ifndef CONF_GCLK_GEN_1_OE
#define CONF_GCLK_GEN_1_OE 0 #define CONF_GCLK_GEN_1_OE 1
#endif #endif
// <q> Output Off Value // <q> Output Off Value
@ -172,7 +173,7 @@
// <i> This defines the clock source for generic clock generator 1 // <i> This defines the clock source for generic clock generator 1
// <id> gclk_gen_1_oscillator // <id> gclk_gen_1_oscillator
#ifndef CONF_GCLK_GEN_1_SRC #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 #endif
// </h> // </h>
@ -181,7 +182,7 @@
// <i> // <i>
// <id> gclk_gen_1_div // <id> gclk_gen_1_div
#ifndef CONF_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 #endif
// </h> // </h>

View File

@ -385,7 +385,7 @@
// <i> Select the clock source for DAC. // <i> Select the clock source for DAC.
#ifndef CONF_GCLK_DAC_SRC #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 #endif
/** /**
@ -393,7 +393,7 @@
* \brief DAC's Clock frequency * \brief DAC's Clock frequency
*/ */
#ifndef CONF_GCLK_DAC_FREQUENCY #ifndef CONF_GCLK_DAC_FREQUENCY
#define CONF_GCLK_DAC_FREQUENCY 48000000 #define CONF_GCLK_DAC_FREQUENCY 320000
#endif #endif
// <y> USB Clock Source // <y> USB Clock Source

View File

@ -72,7 +72,7 @@
// <i> This defines the refresh period. If it is 0, the refresh mode is disabled, else the refresh period is: value * 500us // <i> This defines the refresh period. If it is 0, the refresh mode is disabled, else the refresh period is: value * 500us
// <id> dac0_arch_refresh // <id> dac0_arch_refresh
#ifndef CONF_DAC0_REFRESH #ifndef CONF_DAC0_REFRESH
#define CONF_DAC0_REFRESH 0 #define CONF_DAC0_REFRESH 2
#endif #endif
// </h> // </h>
// <h> Channel 1 configuration // <h> Channel 1 configuration
@ -111,7 +111,7 @@
// <i> This defines the refresh period. If it is 0, the refresh mode is disabled, else the refresh period is: value * 500us // <i> This defines the refresh period. If it is 0, the refresh mode is disabled, else the refresh period is: value * 500us
// <id> dac1_arch_refresh // <id> dac1_arch_refresh
#ifndef CONF_DAC1_REFRESH #ifndef CONF_DAC1_REFRESH
#define CONF_DAC1_REFRESH 0 #define CONF_DAC1_REFRESH 2
#endif #endif
// </h> // </h>

View File

@ -1,7 +1,7 @@
// Circuit Python SAMD51 clock tree: // 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
// GCLK1 (48MHz) -> peripherals // GCLK1 (48MHz) -> 48 MHz peripherals
// GCLK5 (divided down to 2 MHz) -> DPLL0 // GCLK5 (48 MHz divided down to 2 MHz) -> DPLL0, DAC peripherals
// DPLL0 (multiplied up to 120 MHz) -> GCLK0, GCLK4 (output for monitoring) // 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, // We'd like to use XOSC32K as a ref for DFLL48M on boards with a 32kHz crystal,

View File

@ -73,7 +73,7 @@
// <id> dac_gclk_selection // <id> dac_gclk_selection
// <i> Select the clock source for DAC. // <i> Select the clock source for DAC.
#ifndef CONF_GCLK_DAC_SRC #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 #endif
/** /**
@ -81,7 +81,7 @@
* \brief DAC's Clock frequency * \brief DAC's Clock frequency
*/ */
#ifndef CONF_GCLK_DAC_FREQUENCY #ifndef CONF_GCLK_DAC_FREQUENCY
#define CONF_GCLK_DAC_FREQUENCY 48000000 #define CONF_GCLK_DAC_FREQUENCY 2000000
#endif #endif
// <y> EVSYS Channel 0 Clock Source // <y> EVSYS Channel 0 Clock Source

View File

@ -65,12 +65,14 @@ void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self,
#ifdef SAMD51 #ifdef SAMD51
hri_mclk_set_APBDMASK_DAC_bit(MCLK); 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)); hri_gclk_write_PCHCTRL_reg(GCLK, DAC_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK5_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
#endif #endif
#ifdef SAMD21 #ifdef SAMD21
_pm_enable_bus_clock(PM_BUS_APBC, DAC); _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 #endif
// Don't double init the DAC on the SAMD51 when both outputs are in use. We use the free state // 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, void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self,
uint16_t value) { 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. // bits. This is currently done in asf4_conf/*/hpl_dac_config.h.
dac_sync_write(&self->descriptor, self->channel, &value, 1); dac_sync_write(&self->descriptor, self->channel, &value, 1);
} }