You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

457 lines
17 KiB
C

#include "clocks.h"
#include "conf_core.h"
#if CORE_CONF_CLK_XOSC0_FREQUENCY > 24000000
#define CORE_CONF_CLK_XOSC0_IPTAT (3)
#define CORE_CONF_CLK_XOSC0_IMULT (6)
#define CORE_CONF_CLK_XOSC0_CFDPRESC (0x0)
#elif CORE_CONF_CLK_XOSC0_FREQUENCY > 16000000
#define CORE_CONF_CLK_XOSC0_IPTAT (3)
#define CORE_CONF_CLK_XOSC0_IMULT (5)
#define CORE_CONF_CLK_XOSC0_CFDPRESC (0x1)
#elif CORE_CONF_CLK_XOSC0_FREQUENCY > 8000000
#define CORE_CONF_CLK_XOSC0_IPTAT (3)
#define CORE_CONF_CLK_XOSC0_IMULT (4)
#define CORE_CONF_CLK_XOSC0_CFDPRESC (0x2)
#else
#define CORE_CONF_CLK_XOSC0_IPTAT (2)
#define CORE_CONF_CLK_XOSC0_IMULT (3)
#define CORE_CONF_CLK_XOSC0_CFDPRESC (0x3)
#endif
#if CORE_CONF_CLK_XOSC1_FREQUENCY > 24000000
#define CORE_CONF_CLK_XOSC1_IPTAT (3)
#define CORE_CONF_CLK_XOSC1_IMULT (6)
#define CORE_CONF_CLK_XOSC1_CFDPRESC (0x0)
#elif CORE_CONF_CLK_XOSC1_FREQUENCY > 16000000
#define CORE_CONF_CLK_XOSC1_IPTAT (3)
#define CORE_CONF_CLK_XOSC1_IMULT (5)
#define CORE_CONF_CLK_XOSC1_CFDPRESC (0x1)
#elif CORE_CONF_CLK_XOSC1_FREQUENCY > 8000000
#define CORE_CONF_CLK_XOSC1_IPTAT (3)
#define CORE_CONF_CLK_XOSC1_IMULT (4)
#define CORE_CONF_CLK_XOSC1_CFDPRESC (0x2)
#else
#define CORE_CONF_CLK_XOSC1_IPTAT (2)
#define CORE_CONF_CLK_XOSC1_IMULT (3)
#define CORE_CONF_CLK_XOSC1_CFDPRESC (0x3)
#endif
void clock_osc32k_init(void)
{
#if CORE_CONF_CLK_XOSC32K_ENABLE == 1
OSC32KCTRL->XOSC32K.bit.CGM = CORE_CONF_CLK_XOSC32K_CGM;
OSC32KCTRL->XOSC32K.bit.WRTLOCK = CORE_CONF_CLK_XOSC32K_WRTLOCK;
OSC32KCTRL->XOSC32K.bit.STARTUP = CORE_CONF_CLK_XOSC32K_STARTUP_TIME;
OSC32KCTRL->XOSC32K.bit.RUNSTDBY = CORE_CONF_CLK_XOSC32K_RUNSTDBY;
OSC32KCTRL->XOSC32K.bit.ONDEMAND = CORE_CONF_CLK_XOSC32K_ONDEMAND;
OSC32KCTRL->XOSC32K.bit.EN1K = CORE_CONF_CLK_XOSC32K_EN1K;
OSC32KCTRL->XOSC32K.bit.EN32K = CORE_CONF_CLK_XOSC32K_EN32K;
OSC32KCTRL->XOSC32K.bit.XTALEN = CORE_CONF_CLK_XOSC32K_XTALEN;
OSC32KCTRL->CFDCTRL.bit.CFDPRESC = CORE_CONF_CLK_XOSC32K_CFDPRESC;
OSC32KCTRL->CFDCTRL.bit.SWBACK = CORE_CONF_CLK_XOSC32K_SWBACK;
OSC32KCTRL->CFDCTRL.bit.CFDEN = CORE_CONF_CLK_XOSC32K_CFDEN;
#if CORE_CONF_CLK_XOSC32K_ENABLE == 1 && CORE_CONF_CLK_XOSC32K_ONDEMAND == 0
while(OSC32KCTRL->STATUS.bit.XOSC32KRDY == 0);
#endif
#endif
}
void clock_osc_init(void)
{
#if CORE_CONF_CLK_XOSC0_ENABLE == 1
CRITICAL_SECTION_ENTER();
OSCCTRL->XOSCCTRL[0].bit.XTALEN = CORE_CONF_CLK_XOSC0_XTALEN;
OSCCTRL->XOSCCTRL[0].bit.RUNSTDBY = CORE_CONF_CLK_XOSC0_RUNSTDBY;
OSCCTRL->XOSCCTRL[0].bit.ONDEMAND = CORE_CONF_CLK_XOSC0_ONDEMAND;
OSCCTRL->XOSCCTRL[0].bit.LOWBUFGAIN = CORE_CONF_CLK_XOSC0_LOWBUFGAIN;
OSCCTRL->XOSCCTRL[0].bit.IPTAT = CORE_CONF_CLK_XOSC0_IPTAT;
OSCCTRL->XOSCCTRL[0].bit.IMULT = CORE_CONF_CLK_XOSC0_IMULT;
OSCCTRL->XOSCCTRL[0].bit.ENALC = CORE_CONF_CLK_XOSC0_ENALC;
OSCCTRL->XOSCCTRL[0].bit.CFDEN = CORE_CONF_CLK_XOSC0_CFDEN;
OSCCTRL->XOSCCTRL[0].bit.CFDPRESC = CORE_CONF_CLK_XOSC0_CFDPRESC;
OSCCTRL->XOSCCTRL[0].bit.SWBEN = CORE_CONF_CLK_XOSC0_SWBEN;
OSCCTRL->XOSCCTRL[0].bit.STARTUP = CORE_CONF_CLK_XOSC0_STARTUP_TIME;
OSCCTRL->XOSCCTRL[0].bit.ENABLE = CORE_CONF_CLK_XOSC0_ENABLE;
CRITICAL_SECTION_LEAVE();
while(0 == OSCCTRL->STATUS.bit.XOSCRDY0);
#endif
#if CORE_CONF_CLK_XOSC1_ENABLE == 1
CRITICAL_SECTION_ENTER();
OSCCTRL->XOSCCTRL[1].bit.XTALEN = CORE_CONF_CLK_XOSC1_XTALEN;
OSCCTRL->XOSCCTRL[1].bit.RUNSTDBY = CORE_CONF_CLK_XOSC1_RUNSTDBY;
OSCCTRL->XOSCCTRL[1].bit.LOWBUFGAIN = CORE_CONF_CLK_XOSC1_LOWBUFGAIN;
OSCCTRL->XOSCCTRL[1].bit.IPTAT = CORE_CONF_CLK_XOSC1_IPTAT;
OSCCTRL->XOSCCTRL[1].bit.IMULT = CORE_CONF_CLK_XOSC1_IMULT;
OSCCTRL->XOSCCTRL[1].bit.CFDEN = CORE_CONF_CLK_XOSC1_CFDEN;
OSCCTRL->XOSCCTRL[1].bit.CFDPRESC = CORE_CONF_CLK_XOSC1_CFDPRESC;
OSCCTRL->XOSCCTRL[1].bit.SWBEN = CORE_CONF_CLK_XOSC1_SWBEN;
OSCCTRL->XOSCCTRL[1].bit.STARTUP = CORE_CONF_CLK_XOSC1_STARTUP_TIME;
OSCCTRL->XOSCCTRL[1].bit.ENABLE = CORE_CONF_CLK_XOSC1_ENABLE;
CRITICAL_SECTION_LEAVE();
while(0 == OSCCTRL->STATUS.bit.XOSCRDY1);
#endif
#if CORE_CONF_CLK_XOSC0_ENABLE == 1
CRITICAL_SECTION_ENTER();
#if CORE_CONF_CLK_XOSC0_ENALC == 1
OSCCTRL->XOSCCTRL[0].bit.ENALC = CORE_CONF_CLK_XOSC0_ENALC;
#endif
#if CORE_CONF_CLK_XOSC0_ONDEMAND == 1
OSCCTRL->XOSCCTRL[0].bit.ONDEMAND = CORE_CONF_CLK_XOSC0_ONDEMAND;
#endif
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_CLK_XOSC1_ENABLE == 1
CRITICAL_SECTION_ENTER();
#if CORE_CONF_CLK_XOSC1_ENALC == 1
OSCCTRL->XOSCCTRL[1].bit.ENALC = CORE_CONF_CLK_XOSC1_ENALC;
#endif
#if CORE_CONF_CLK_XOSC1_ONDEMAND == 1
OSCCTRL->XOSCCTRL[1].bit.ONDEMAND = CORE_CONF_CLK_XOSC1_ONDEMAND;
#endif
CRITICAL_SECTION_LEAVE();
#endif
}
void clock_mclk_init(void)
{
CRITICAL_SECTION_ENTER();
MCLK->CPUDIV.reg = CORE_CONF_MCLK_CPUDIV;
CRITICAL_SECTION_LEAVE();
}
void clock_gclk_init(void)
{
#if CORE_CONF_GCLK_0_ENABLE == 1
CRITICAL_SECTION_ENTER();
GCLK->GENCTRL[0].bit.DIV = CORE_CONF_GCLK_0_DIV_VAL;
GCLK->GENCTRL[0].bit.DIVSEL = CORE_CONF_GCLK_0_DIVSEL;
GCLK->GENCTRL[0].bit.RUNSTDBY = CORE_CONF_GCLK_0_RUN_IN_STANDBY;
GCLK->GENCTRL[0].bit.OE = CORE_CONF_GCLK_0_OUTPUT_ENABLE;
GCLK->GENCTRL[0].bit.OOV = CORE_CONF_GCLK_0_DIVSEL;
GCLK->GENCTRL[0].bit.IDC = CORE_CONF_GCLK_0_IDC;
GCLK->GENCTRL[0].bit.GENEN = CORE_CONF_GCLK_0_ENABLE;
GCLK->GENCTRL[0].bit.SRC = CORE_CONF_GCLK_0_CLOCK_SOURCE;
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_GCLK_1_ENABLE == 1
CRITICAL_SECTION_ENTER();
GCLK->GENCTRL[1].bit.DIV = CORE_CONF_GCLK_1_DIV_VAL;
GCLK->GENCTRL[1].bit.DIVSEL = CORE_CONF_GCLK_1_DIVSEL;
GCLK->GENCTRL[1].bit.RUNSTDBY = CORE_CONF_GCLK_1_RUN_IN_STANDBY;
GCLK->GENCTRL[1].bit.OE = CORE_CONF_GCLK_1_OUTPUT_ENABLE;
GCLK->GENCTRL[1].bit.OOV = CORE_CONF_GCLK_1_DIVSEL;
GCLK->GENCTRL[1].bit.IDC = CORE_CONF_GCLK_1_IDC;
GCLK->GENCTRL[1].bit.GENEN = CORE_CONF_GCLK_1_ENABLE;
GCLK->GENCTRL[1].bit.SRC = CORE_CONF_GCLK_1_CLOCK_SOURCE;
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_GCLK_2_ENABLE == 1
CRITICAL_SECTION_ENTER();
GCLK->GENCTRL[2].bit.DIV = CORE_CONF_GCLK_2_DIV_VAL;
GCLK->GENCTRL[2].bit.DIVSEL = CORE_CONF_GCLK_2_DIVSEL;
GCLK->GENCTRL[2].bit.RUNSTDBY = CORE_CONF_GCLK_2_RUN_IN_STANDBY;
GCLK->GENCTRL[2].bit.OE = CORE_CONF_GCLK_2_OUTPUT_ENABLE;
GCLK->GENCTRL[2].bit.OOV = CORE_CONF_GCLK_2_DIVSEL;
GCLK->GENCTRL[2].bit.IDC = CORE_CONF_GCLK_2_IDC;
GCLK->GENCTRL[2].bit.GENEN = CORE_CONF_GCLK_2_ENABLE;
GCLK->GENCTRL[2].bit.SRC = CORE_CONF_GCLK_2_CLOCK_SOURCE;
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_GCLK_3_ENABLE == 1
CRITICAL_SECTION_ENTER();
GCLK->GENCTRL[3].bit.DIV = CORE_CONF_GCLK_3_DIV_VAL;
GCLK->GENCTRL[3].bit.DIVSEL = CORE_CONF_GCLK_3_DIVSEL;
GCLK->GENCTRL[3].bit.RUNSTDBY = CORE_CONF_GCLK_3_RUN_IN_STANDBY;
GCLK->GENCTRL[3].bit.OE = CORE_CONF_GCLK_3_OUTPUT_ENABLE;
GCLK->GENCTRL[3].bit.OOV = CORE_CONF_GCLK_3_DIVSEL;
GCLK->GENCTRL[3].bit.IDC = CORE_CONF_GCLK_3_IDC;
GCLK->GENCTRL[3].bit.GENEN = CORE_CONF_GCLK_3_ENABLE;
GCLK->GENCTRL[3].bit.SRC = CORE_CONF_GCLK_3_CLOCK_SOURCE;
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_GCLK_4_ENABLE == 1
CRITICAL_SECTION_ENTER();
GCLK->GENCTRL[4].bit.DIV = CORE_CONF_GCLK_4_DIV_VAL;
GCLK->GENCTRL[4].bit.DIVSEL = CORE_CONF_GCLK_4_DIVSEL;
GCLK->GENCTRL[4].bit.RUNSTDBY = CORE_CONF_GCLK_4_RUN_IN_STANDBY;
GCLK->GENCTRL[4].bit.OE = CORE_CONF_GCLK_4_OUTPUT_ENABLE;
GCLK->GENCTRL[4].bit.OOV = CORE_CONF_GCLK_4_DIVSEL;
GCLK->GENCTRL[4].bit.IDC = CORE_CONF_GCLK_4_IDC;
GCLK->GENCTRL[4].bit.GENEN = CORE_CONF_GCLK_4_ENABLE;
GCLK->GENCTRL[4].bit.SRC = CORE_CONF_GCLK_4_CLOCK_SOURCE;
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_GCLK_5_ENABLE == 1
CRITICAL_SECTION_ENTER();
GCLK->GENCTRL[5].bit.DIV = CORE_CONF_GCLK_5_DIV_VAL;
GCLK->GENCTRL[5].bit.DIVSEL = CORE_CONF_GCLK_5_DIVSEL;
GCLK->GENCTRL[5].bit.RUNSTDBY = CORE_CONF_GCLK_5_RUN_IN_STANDBY;
GCLK->GENCTRL[5].bit.OE = CORE_CONF_GCLK_5_OUTPUT_ENABLE;
GCLK->GENCTRL[5].bit.OOV = CORE_CONF_GCLK_5_DIVSEL;
GCLK->GENCTRL[5].bit.IDC = CORE_CONF_GCLK_5_IDC;
GCLK->GENCTRL[5].bit.GENEN = CORE_CONF_GCLK_5_ENABLE;
GCLK->GENCTRL[5].bit.SRC = CORE_CONF_GCLK_5_CLOCK_SOURCE;
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_GCLK_6_ENABLE == 1
CRITICAL_SECTION_ENTER();
GCLK->GENCTRL[6].bit.DIV = CORE_CONF_GCLK_6_DIV_VAL;
GCLK->GENCTRL[6].bit.DIVSEL = CORE_CONF_GCLK_6_DIVSEL;
GCLK->GENCTRL[6].bit.RUNSTDBY = CORE_CONF_GCLK_6_RUN_IN_STANDBY;
GCLK->GENCTRL[6].bit.OE = CORE_CONF_GCLK_6_OUTPUT_ENABLE;
GCLK->GENCTRL[6].bit.OOV = CORE_CONF_GCLK_6_DIVSEL;
GCLK->GENCTRL[6].bit.IDC = CORE_CONF_GCLK_6_IDC;
GCLK->GENCTRL[6].bit.GENEN = CORE_CONF_GCLK_6_ENABLE;
GCLK->GENCTRL[6].bit.SRC = CORE_CONF_GCLK_6_CLOCK_SOURCE;
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_GCLK_7_ENABLE == 1
CRITICAL_SECTION_ENTER();
GCLK->GENCTRL[7].bit.DIV = CORE_CONF_GCLK_7_DIV_VAL;
GCLK->GENCTRL[7].bit.DIVSEL = CORE_CONF_GCLK_7_DIVSEL;
GCLK->GENCTRL[7].bit.RUNSTDBY = CORE_CONF_GCLK_7_RUN_IN_STANDBY;
GCLK->GENCTRL[7].bit.OE = CORE_CONF_GCLK_7_OUTPUT_ENABLE;
GCLK->GENCTRL[7].bit.OOV = CORE_CONF_GCLK_7_DIVSEL;
GCLK->GENCTRL[7].bit.IDC = CORE_CONF_GCLK_7_IDC;
GCLK->GENCTRL[7].bit.GENEN = CORE_CONF_GCLK_7_ENABLE;
GCLK->GENCTRL[7].bit.SRC = CORE_CONF_GCLK_7_CLOCK_SOURCE;
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_GCLK_8_ENABLE == 1
CRITICAL_SECTION_ENTER();
GCLK->GENCTRL[8].bit.DIV = CORE_CONF_GCLK_8_DIV_VAL;
GCLK->GENCTRL[8].bit.DIVSEL = CORE_CONF_GCLK_8_DIVSEL;
GCLK->GENCTRL[8].bit.RUNSTDBY = CORE_CONF_GCLK_8_RUN_IN_STANDBY;
GCLK->GENCTRL[8].bit.OE = CORE_CONF_GCLK_8_OUTPUT_ENABLE;
GCLK->GENCTRL[8].bit.OOV = CORE_CONF_GCLK_8_DIVSEL;
GCLK->GENCTRL[8].bit.IDC = CORE_CONF_GCLK_8_IDC;
GCLK->GENCTRL[8].bit.GENEN = CORE_CONF_GCLK_8_ENABLE;
GCLK->GENCTRL[8].bit.SRC = CORE_CONF_GCLK_8_CLOCK_SOURCE;
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_GCLK_9_ENABLE == 1
CRITICAL_SECTION_ENTER();
GCLK->GENCTRL[9].bit.DIV = CORE_CONF_GCLK_9_DIV_VAL;
GCLK->GENCTRL[9].bit.DIVSEL = CORE_CONF_GCLK_9_DIVSEL;
GCLK->GENCTRL[9].bit.RUNSTDBY = CORE_CONF_GCLK_9_RUN_IN_STANDBY;
GCLK->GENCTRL[9].bit.OE = CORE_CONF_GCLK_9_OUTPUT_ENABLE;
GCLK->GENCTRL[9].bit.OOV = CORE_CONF_GCLK_9_DIVSEL;
GCLK->GENCTRL[9].bit.IDC = CORE_CONF_GCLK_9_IDC;
GCLK->GENCTRL[9].bit.GENEN = CORE_CONF_GCLK_9_ENABLE;
GCLK->GENCTRL[9].bit.SRC = CORE_CONF_GCLK_9_CLOCK_SOURCE;
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_GCLK_10_ENABLE == 1
CRITICAL_SECTION_ENTER();
GCLK->GENCTRL[10].bit.DIV = CORE_CONF_GCLK_10_DIV_VAL;
GCLK->GENCTRL[10].bit.DIVSEL = CORE_CONF_GCLK_10_DIVSEL;
GCLK->GENCTRL[10].bit.RUNSTDBY = CORE_CONF_GCLK_10_RUN_IN_STANDBY;
GCLK->GENCTRL[10].bit.OE = CORE_CONF_GCLK_10_OUTPUT_ENABLE;
GCLK->GENCTRL[10].bit.OOV = CORE_CONF_GCLK_10_DIVSEL;
GCLK->GENCTRL[10].bit.IDC = CORE_CONF_GCLK_10_IDC;
GCLK->GENCTRL[10].bit.GENEN = CORE_CONF_GCLK_10_ENABLE;
GCLK->GENCTRL[10].bit.SRC = CORE_CONF_GCLK_10_CLOCK_SOURCE;
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_GCLK_11_ENABLE == 1
CRITICAL_SECTION_ENTER();
GCLK->GENCTRL[11].bit.DIV = CORE_CONF_GCLK_11_DIV_VAL;
GCLK->GENCTRL[11].bit.DIVSEL = CORE_CONF_GCLK_11_DIVSEL;
GCLK->GENCTRL[11].bit.RUNSTDBY = CORE_CONF_GCLK_11_RUN_IN_STANDBY;
GCLK->GENCTRL[11].bit.OE = CORE_CONF_GCLK_11_OUTPUT_ENABLE;
GCLK->GENCTRL[11].bit.OOV = CORE_CONF_GCLK_11_DIVSEL;
GCLK->GENCTRL[11].bit.IDC = CORE_CONF_GCLK_11_IDC;
GCLK->GENCTRL[11].bit.GENEN = CORE_CONF_GCLK_11_ENABLE;
GCLK->GENCTRL[11].bit.SRC = CORE_CONF_GCLK_11_CLOCK_SOURCE;
CRITICAL_SECTION_LEAVE();
#endif
}
void clock_dpll_init(void)
{
#if CORE_CONF_CLK_DPLL0_ENABLE == 1
#if CORE_CONF_CLK_DPLL0_REFCLK == 0
CRITICAL_SECTION_ENTER();
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].bit.GEN =
GCLK_PCHCTRL_GEN(CORE_CONF_CLK_DPLL0_GCLK_SRC);
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].bit.CHEN =
CORE_CONF_CLK_DPLL0_ENABLE;
CRITICAL_SECTION_LEAVE();
#endif
CRITICAL_SECTION_ENTER();
// write dpll ratio
OSCCTRL->Dpll[0].DPLLRATIO.bit.LDRFRAC = CORE_CONF_CLK_DPLL0_LDRFRAC_VAL;
OSCCTRL->Dpll[0].DPLLRATIO.bit.LDR = CORE_CONF_CLK_DPLL0_LDR_VAL;
// write dpll ctrlb
OSCCTRL->Dpll[0].DPLLCTRLB.bit.DIV = CORE_CONF_CLK_DPLL0_DIV_VAL;
OSCCTRL->Dpll[0].DPLLCTRLB.bit.DCOEN = CORE_CONF_CLK_DPLL0_DCOEN;
OSCCTRL->Dpll[0].DPLLCTRLB.bit.DCOFILTER = CORE_CONF_CLK_DPLL0_DCOFILTER;
OSCCTRL->Dpll[0].DPLLCTRLB.bit.LBYPASS = CORE_CONF_CLK_DPLL0_LBYPASS;
OSCCTRL->Dpll[0].DPLLCTRLB.bit.LTIME = CORE_CONF_CLK_DPLL0_LTIME;
OSCCTRL->Dpll[0].DPLLCTRLB.bit.REFCLK = CORE_CONF_CLK_DPLL0_REFCLK;
OSCCTRL->Dpll[0].DPLLCTRLB.bit.WUF = CORE_CONF_CLK_DPLL0_WUF;
OSCCTRL->Dpll[0].DPLLCTRLB.bit.FILTER = CORE_CONF_CLK_DPLL0_FILTER;
CRITICAL_SECTION_LEAVE();
CRITICAL_SECTION_ENTER();
OSCCTRL->Dpll[0].DPLLCTRLA.reg = 0;
OSCCTRL->Dpll[0].DPLLCTRLA.bit.RUNSTDBY = CORE_CONF_CLK_DPLL0_RUNSTDBY;
OSCCTRL->Dpll[0].DPLLCTRLA.bit.ENABLE = CORE_CONF_CLK_DPLL0_ENABLE;
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_CLK_DPLL1_ENABLE == 1
#if CORE_CONF_CLK_DPLL0_REFCLK == 0
CRITICAL_SECTION_ENTER();
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].bit.GEN =
GCLK_PCHCTRL_GEN(CORE_CONF_CLK_DPLL1_GCLK_SRC);
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].bit.CHEN =
CORE_CONF_CLK_DPLL1_ENABLE;
CRITICAL_SECTION_LEAVE();
#endif
CRITICAL_SECTION_ENTER();
// write dpll ratio
OSCCTRL->Dpll[1].DPLLRATIO.bit.LDRFRAC = CORE_CONF_CLK_DPLL1_LDRFRAC_VAL;
OSCCTRL->Dpll[1].DPLLRATIO.bit.LDR = CORE_CONF_CLK_DPLL1_LDR_VAL;
// write dpll ctrlb
OSCCTRL->Dpll[1].DPLLCTRLB.bit.DIV = CORE_CONF_CLK_DPLL1_DIV_VAL;
OSCCTRL->Dpll[1].DPLLCTRLB.bit.DCOEN = CORE_CONF_CLK_DPLL1_DCOEN;
OSCCTRL->Dpll[1].DPLLCTRLB.bit.DCOFILTER = CORE_CONF_CLK_DPLL1_DCOFILTER;
OSCCTRL->Dpll[1].DPLLCTRLB.bit.LBYPASS = CORE_CONF_CLK_DPLL1_LBYPASS;
OSCCTRL->Dpll[1].DPLLCTRLB.bit.LTIME = CORE_CONF_CLK_DPLL1_LTIME;
OSCCTRL->Dpll[1].DPLLCTRLB.bit.REFCLK = CORE_CONF_CLK_DPLL1_REFCLK;
OSCCTRL->Dpll[1].DPLLCTRLB.bit.WUF = CORE_CONF_CLK_DPLL1_WUF;
OSCCTRL->Dpll[1].DPLLCTRLB.bit.FILTER = CORE_CONF_CLK_DPLL1_FILTER;
CRITICAL_SECTION_LEAVE();
CRITICAL_SECTION_ENTER();
OSCCTRL->Dpll[1].DPLLCTRLA.reg = 0;
OSCCTRL->Dpll[1].DPLLCTRLA.bit.RUNSTDBY = CORE_CONF_CLK_DPLL1_RUNSTDBY;
OSCCTRL->Dpll[1].DPLLCTRLA.bit.ENABLE = CORE_CONF_CLK_DPLL1_ENABLE;
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_CLK_DPLL0_ENABLE == 1
while(!(OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK || OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY));
CRITICAL_SECTION_ENTER();
#if CORE_CONF_CLK_DPLL0_ONDEMAND == 1
OSCCTRL->Dpll[0].DPLLCTRLA.bit.ONDEMAND = CORE_CONF_CLK_DPLL0_ONDEMAND;
#endif
CRITICAL_SECTION_LEAVE();
#endif
#if CORE_CONF_CLK_DPLL1_ENABLE == 1
while(!(OSCCTRL->Dpll[1].DPLLSTATUS.bit.LOCK || OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY));
CRITICAL_SECTION_ENTER();
#if CORE_CONF_CLK_DPLL1_ONDEMAND == 1
OSCCTRL->Dpll[1].DPLLCTRLA.bit.ONDEMAND = CORE_CONF_CLK_DPLL1_ONDEMAND;
#endif
CRITICAL_SECTION_LEAVE();
#endif
}
void clock_dfll_init(void)
{
#if CORE_CONF_CLK_DFLL_ENABLE
CRITICAL_SECTION_ENTER();
GCLK->GENCTRL[0].bit.SRC = GCLK_GENCTRL_SRC_OSCULP32K;
CRITICAL_SECTION_LEAVE();
while(GCLK->SYNCBUSY.bit.GENCTRL0);
CRITICAL_SECTION_ENTER();
// reset stuff
OSCCTRL->DFLLCTRLA.reg = 0;
CRITICAL_SECTION_LEAVE();
#if CORE_CONF_CLK_DFLL_USBCRM != 1 && CORE_CONF_CLK_DFLL_MODE != 0
CRITICAL_SECTION_ENTER();
// reset stuff
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_DFLL48].bit.GEN =
GCLK_PCHCTRL_GEN(CORE_CONF_CLK_DFLL_GCLK_SRC);
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_DFLL48].bit.EN = CORE_CONF_CLK_DFLL_ENABLE;
CRITICAL_SECTION_LEAVE();
#endif
CRITICAL_SECTION_ENTER();
// configure clock multiplier stuff
OSCCTRL->DFLLMUL.bit.MUL = CORE_CONF_CLK_DFLL_MUL_VAL;
OSCCTRL->DFLLMUL.bit.CSTEP = CORE_CONF_CLK_DFLL_CSTEP_VAL;
OSCCTRL->DFLLMUL.bit.FSTEP = CORE_CONF_CLK_DFLL_FSTEP_VAL;
CRITICAL_SECTION_LEAVE();
while(OSCCTRL->DFLLSYNC.bit.DFLLMUL);
CRITICAL_SECTION_ENTER();
// reset dfll ctrlb
OSCCTRL->DFLLCTRLB.reg = 0;
CRITICAL_SECTION_LEAVE();
// wait for ctrlb sync
while(OSCCTRL->DFLLSYNC.bit.DFLLCTRLB);
CRITICAL_SECTION_ENTER();
OSCCTRL->DFLLCTRLA.bit.RUNSTDBY = CORE_CONF_CLK_DFLL_RUNSTDBY;
OSCCTRL->DFLLCTRLA.bit.ENABLE = CORE_CONF_CLK_DFLL_ENABLE;
CRITICAL_SECTION_LEAVE();
while(OSCCTRL->DFLLSYNC.bit.ENABLE);
#if CORE_CONF_CLK_DFLL_OVERWRITE_CAL == 1
CRITICAL_SECTION_ENTER();
// set calib for dfll48m
OSCCTRL->DFLLVAL.bit.COARSE = CORE_CONF_CLK_DFLL_COARSE_VAL;
OSCCTRL->DFLLVAL.bit.FINE = CORE_CONF_CLK_DFLL_FINE_VAL;
OSCCTRL->DFLLVAL.bit.DIFF = CORE_CONF_CLK_DFLL_DIFF_VAL;
CRITICAL_SECTION_LEAVE();
#endif
CRITICAL_SECTION_ENTER();
// write dfll val
// rewriting this for some reason?
OSCCTRL->DFLLVAL.reg = OSCCTRL->DFLLVAL.reg;
CRITICAL_SECTION_LEAVE();
// let dfll val sync
while(OSCCTRL->DFLLSYNC.bit.DFLLVAL);
CRITICAL_SECTION_ENTER();
// write dfll ctrlb
OSCCTRL->DFLLCTRLB.bit.WAITLOCK = CORE_CONF_CLK_DFLL_WAITLOCK;
OSCCTRL->DFLLCTRLB.bit.BPLCKC = CORE_CONF_CLK_DFLL_BPLKC;
OSCCTRL->DFLLCTRLB.bit.QLDIS = CORE_CONF_CLK_DFLL_QLDIS;
OSCCTRL->DFLLCTRLB.bit.CCDIS = CORE_CONF_CLK_DFLL_CCDIS;
OSCCTRL->DFLLCTRLB.bit.USBCRM = CORE_CONF_CLK_DFLL_USBCRM;
OSCCTRL->DFLLCTRLB.bit.LLAW = CORE_CONF_CLK_DFLL_LLAW;
OSCCTRL->DFLLCTRLB.bit.STABLE = CORE_CONF_CLK_DFLL_STABLE_FCALIB;
OSCCTRL->DFLLCTRLB.bit.MODE = CORE_CONF_CLK_DFLL_MODE;
CRITICAL_SECTION_LEAVE();
while(OSCCTRL->DFLLSYNC.bit.DFLLCTRLB);
if (OSCCTRL->DFLLCTRLB.bit.MODE)
{
volatile uint32_t status_mask = OSCCTRL_STATUS_DFLLRDY | OSCCTRL_STATUS_DFLLLCKC;
while((OSCCTRL->STATUS.reg & status_mask) != status_mask);
}
else
{
while(!OSCCTRL->STATUS.bit.DFLLRDY);
}
#if CORE_CONF_CLK_DFLL_ONDEMAND == 1
CRITICAL_SECTION_ENTER();
OSCCTRL->DFLLCTRLA.bit.ONDEMAND = CORE_CONF_CLK_DFLL_ONDEMAND;
CRITICAL_SECTION_LEAVE();
#endif
while(GCLK->SYNCBUSY.reg);
CRITICAL_SECTION_ENTER();
// reset gclk 0
GCLK->GENCTRL[0].bit.SRC = CORE_CONF_GCLK_0_CLOCK_SOURCE;
CRITICAL_SECTION_LEAVE();
#endif
}