/***
 *** The Example has no copyright and can be used by anyone.
 *** The following example is based on Device File Package
 *** required to compile the macro definitions used.
 *** The Device File Package is avaiblable by downloading Atmel Studio 7.
 ***/

/***
 *** In this example the DFLLULP is configured 
 *** to clock directly the MCLK.(see CKSEL)
 *** This lines are to be copied into a function
 ***/

 /*** Variable declaration ***/
 uint32_t divider;

/***
 *** Configure and Enable 
 *** Clock Generator 1 (GCLK1), 
 *** XOSC32K as source not divided 
 ***/
GCLK->GENCTRL[1].reg = GCLK_GENCTRL_DIV(1)|GCLK_GENCTRL_SRC_XOSC32K|GCLK_GENCTRL_GENEN;

/*** Enable DFLLULP 
 *** Peripheral Channel 
 *** with GCLK1 as source 
 ***/
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_DFLLULP].reg = GCLK_PCHCTRL_GEN_GCLK1|GCLK_PCHCTRL_CHEN;

/*** 
 *** We want a 4.88MHz frequency out 
 *** of the DFLLULP
 ***/
OSCCTRL->DFLLULPRATIO.reg = OSCCTRL_DFLLULPRATIO_RATIO(4880000/32768);

/*** 
 *** Get DFLLULP Division Factor 
 *** in PL0 from NVM Software Calibration Area
 *** To be written to DFLLULPCTRL register
 ***/
divider = ((*((uint32_t *)FUSES_DFLLULP_DIV_PL0_ADDR) & FUSES_DFLLULP_DIV_PL0_Msk) >> FUSES_DFLLULP_DIV_PL0_Pos);

/***
 *** Configure DFLLULP 
 *** with PL0 Division Factor 
 ***/ 
OSCCTRL->DFLLULPCTRL.reg = OSCCTRL_DFLLULPCTRL_DIV(divider)|  
                           OSCCTRL_DFLLULPCTRL_BINSE| 
                           OSCCTRL_DFLLULPCTRL_SAFE|
                           OSCCTRL_DFLLULPCTRL_ENABLE;
/*** (write synchronized) ***/
while(OSCCTRL->DFLLULPSYNCBUSY.bit.ENABLE==1);     

/*** 
 *** Switch DFLLULP clock 
 *** on Main Clock 
 *** (OSC16M = 4MHz by default after reset)
 ***/
MCLK->CTRLA.bit.CKSEL= 1;

/*** 
 *** Applying DFLLULP Clock Workaround errata 
 *** Refer to SAM L10/L11 Family Silicon 
 *** Errata and Data Sheet Clarification
 ***/
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();

while(MCLK->INTFLAG.bit.CKRDY == 0);

/*** Wait for DFLLULP lock flag ***/
while((OSCCTRL->STATUS.reg & OSCCTRL_STATUS_DFLLULPLOCK) == 0);

/*** Disable OSC16M and GCLK0 ***/
GCLK->GENCTRL[0].bit.GENEN = 0;
/*** (write synchronized) ***/
while (GCLK->SYNCBUSY.bit.GENCTRL0==1);    

/*** Disable OSC16M as it is not used ***/
OSCCTRL->OSC16MCTRL.bit.ENABLE = 0;