/***
 *** This 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.
***/

/***
 ***Initialize the system
 ***
 *** Initialize the XOSC32K Oscillator (32 kHz On-board Crystal)
 *** Switch Performance level from PL0 (Default after reset) to PL2
 *** Configure Flash Wait States based on next Main Clock frequency (32 MHz <-> 2 WS)
 *** Initialize the DPLL to generate 64 MHz Set Main clock to DPLL/2
***/

void SystemInit(void)
{
 /***
  *** Set XOSC32K Startup time 
  *** (see "Start-Up Time for 32KHz External Crystal Oscillator" 
  *** table from datasheet)
  *** Enable 32.768kHz output
  *** Enable Crystal Oscillator mode
  *** Enable XOSC32K
  ***/

 OSC32KCTRL->XOSC32K.reg =(OSC32KCTRL_XOSC32K_STARTUP(0x3)| 
                           OSC32KCTRL_XOSC32K_EN32K       |
                           OSC32KCTRL_XOSC32K_XTALEN      | 
                           OSC32KCTRL_XOSC32K_ENABLE);

 /*** Write Synchronized ***/
 while(!(OSC32KCTRL->STATUS.bit.XOSC32KRDY));     

 /*** 
  *** Switch Performance level 
  *** from PL0 (Default after reset) to PL2 
  ***/
 PM->PLCFG.bit.PLSEL = 2;
 while(PM->INTFLAG.bit.PLRDY == 0);

 /*** 
  *** Configure Flash Wait States based 
  *** on next Main Clock frequency (32 MHz <-> 2 WS) 
  ***/
 NVMCTRL->CTRLB.bit.RWS = 2;

 /*** 
  *** Set DPLL Ratio to generate 64MHz clock 
  *** (64MHz/32.768kHz=1953.125 
  *** => LDR=1952/LDRFRAC=2 <=> 
  *** 64MHz=32.768*(LDR+1+LDRFRAC/16) 
  ***/
 OSCCTRL->DPLLRATIO.reg = (OSCCTRL_DPLLRATIO_LDR(1952)| 
 OSCCTRL_DPLLRATIO_LDRFRAC(2));

 /*** Write Synchronized ***/
 while((OSCCTRL->DPLLSYNCBUSY.bit.DPLLRATIO));

 /*** Disable On-demand ***/ 
 OSCCTRL->DPLLCTRLA.bit.ONDEMAND = 0;

 /*** 
  *** Set Lock time as automatic 
  ***and reference clock to XOSC32KHz 
  ***/ 
 OSCCTRL->DPLLCTRLB.reg = (OSCCTRL_DPLLCTRLB_LTIME(0)|
                           OSCCTRL_DPLLCTRLB_REFCLK_XOSC32K);

 /*** Enable DPLL ***/
 OSCCTRL->DPLLCTRLA.bit.ENABLE = 1;
 while(OSCCTRL->DPLLSYNCBUSY.bit.ENABLE);

 /*** Wait for DPLL lock flag ***/
 while(!OSCCTRL->DPLLSTATUS.bit.LOCK);

 /*** 
  *** Set Generic clock 0 
  ***(MAIN clock for CPU and synchronous clock) 
  ***/
 GCLK->GENCTRL[0].reg = (GCLK_GENCTRL_SRC(0x07)|
                         GCLK_GENCTRL_DIV(2)|
                         GCLK_GENCTRL_GENEN);

 /*** Write Synchronized ***/
 while((GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL0));

 /***
  *** Set Generic clock 1 (GCLK1), 
  *** XOSC32K as source not divided 
  ***/
 GCLK->GENCTRL[1].reg = (GCLK_GENCTRL_SRC_XOSC32K|
                         GCLK_GENCTRL_DIV(1)|
                         GCLK_GENCTRL_GENEN);

 /*** Write Synchronized ***/
 while((GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL1));    
}