SAM L10/L11 Clock System
Clock Distribution Overview
The SAM L10/L11 clock system configuration is done through the Oscillator Controller (OSCCTRL), the 32 kHz Oscillator Controller (OSC32KCTRL), the Generic Clock Controller (GCLK) and the Main Clock (MCLK).
Related Peripherals
- Generic Clock Generator Controller (GCLKC)
- 32K Oscillator Controller (OSC32KCTRL)
- Oscillator Controller (OSCCTRL)
- Main Clock Controller (MCLK)
Clock Controllers and Clock Features
- The OSCCTRL controls all the clock sources which are:
- 0.4-32 MHz Crystal Oscillator (XOSC)
- Tunable gain control
- Programmable start-up time
- Crystal or external input clock on XIN pin
- Clock failure detection with safe clock switch
- Clock failure event output
- 16 MHz Internal Oscillator (OSC16M)
- Fast startup
- 4/8/12/16 MHz output frequencies available
- Ultra-Low Power Digital Frequency Locked Loop (DFLLULP)
- Operates as a frequency multiplier against a known frequency in closed-loop mode
- Optional frequency dithering
- Fractional Digital Phase Locked Loop (FDPLL96M)
- 48 MHz to 96 MHz output frequency
- 32 kHz to 2 MHz reference clock
- A selection of sources for the reference clock
- Adjustable proportional integral controller Fractional part used to achieve 1/16th of reference clock step
- 0.4-32 MHz Crystal Oscillator (XOSC)
- The OSC32KCTRL controls the 32 KHz clock sources which are:
- XOSC32K
- External 32.768 kHz oscillator
- 32.768 kHz crystal or external clock
- OSCULP32K
- Ultra-low power internal 32.768 kHz oscillator
- Always ON
- Frequency fine tuning
- XOSC32K
Generic Clock Controller (GCLK)
- The GCLK controls the clock distribution of the system by implementing the following features:
- Five GCLK Generators (GCLK0 to GCLK4) to source up to 64 Peripheral Clock Channels (GCLK_PERIPH)
- Each GCLK Generator has a prescaler to divide internal or external clock sources
- The Generic Clock Generator 0 provides the GCLKMAIN which is the clock used to generate synchronous clocks
- One GCLK_IO pin for each generator can be used as a clock source for the GCLK or outputs a clock signal to the external world
Main Clock Controller (MCLK)
- The MCLK controller generates:
- CPU, AHB, and APB system clocks
- Safe run-time clock switching from GCLK
- Module-level clock gating through maskable peripheral clocks
Clock-Tree Reset State
At reset, OSC16M is enabled and configured to run at 4 MHz.
Full Speed (32 MHz) Clock Configuration Example
This example shows the usual configuration to clock the device to its maximum speed (32 MHz) using the FDPLL96MHz. The clock source is XOSC32K but it can be another one.
Code Snippet Example: How to Configure the Device at Full Speed Using the DPLL96MHz
*** 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));
}
How to Configure Clocks for Peripherals
All peripherals need two clock signals:
- The generic clock from GCLK (asynchronous) in green
- The interface clock from MCLK (synchronous) in light blue
There is no specific order in the configuration between asynchronous and synchronous clocks.
The following figure shows the configuration of the SERCOM0, but the same process can be applied to any other peripherals such as ADC, TC, etc.
The GCLK multiplexer ID number (#11 for the GCLK_SERCOM0_CORE ) can be found in the datasheet. (Refer to the table in the GCLK_PCHCTRLm register description).
Configuring a Peripheral can be realized in four steps:
- Enable the source clock (OSCCTRL / OSC32KCTRL)
- Enable and configure a Generic Clock Generator (GCLK)
- Enable and configure the appropriate Generic Clock Multiplexer to address the targeted peripheral (GCLK)
- Unmask the peripheral interface clock (MCLK)
Asynchronous or Synchronous Clock Path
As the CPU and the peripherals can be clocked from different clock sources, possibly with widely different clock speeds, some peripheral accesses by the CPU need to be synchronized between the different clock domains.
The interest in having such flexible architecture is mainly for power consumption optimization. In low power mode, peripherals can remain clocked by an external clock signal while all system clocks are OFF.
Code Snippet: How to Configure a Write-Synchronized Peripheral (Timer Counter (TC)
*** 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.
***/
/*** GCLK TC0 Peripheral Muxing Definition ***/
#define GCLK_TC0 14
/*** Curent 32KHz Clock Source Definition ***/
#define CURRENT_32KOSC GCLK_GENCTRL_SRC_XOSC32K
void init_TC0_1KHz(void)
{
/*** Enable XOSC32K (32KHZ input clock for TC) ***/
OSC32KCTRL->XOSC32K.reg |= (OSC32KCTRL_XOSC32K_ENABLE |
OSC32KCTRL_XOSC32K_XTALEN |
OSC32KCTRL_XOSC32K_EN1K |
OSC32KCTRL_XOSC32K_EN32K |
OSC32KCTRL_XOSC32K_RUNSTDBY|
OSC32KCTRL_XOSC32K_STARTUP(5));
/*** Wait until XOSC32K is ready ***/
while(OSC32KCTRL->STATUS.bit.XOSC32KRDY==0);
/*** Enable GCLK2 with XOSC32K
*** as clock peripheral clock
*** generator for TC0
***/
GCLK->GENCTRL[2].reg = GCLK_GENCTRL_DIV(1) |
CURRENT_32KOSC|
GCLK_GENCTRL_GENEN;
/*** Wait for Clocks synchronzation(GENCTRL register is write synchronized) ***/
while((GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL2));
/*** Link the Generic Clock Generator 2 to the TC0 Peripheral ***/
GCLK->PCHCTRL[GCLK_TC0].reg = (GCLK_PCHCTRL_CHEN|GCLK_PCHCTRL_GEN_GCLK2);
/*** Disable TC0 before configuring it...
*** (COUNT8 register is Enable Protected and write synchronized)
***/
TC0->COUNT8.CTRLA.bit.ENABLE = 0;
/*** Wait for Clocks synchronzation(COUNT8 register is write synchronized) ***/
while(TC0->COUNT8.SYNCBUSY.reg & TC_SYNCBUSY_ENABLE);
/*** TC0 configuration...
*** 8-bit Timer counter mode,
*** Run in SDBY
*** On Demand enabled
*** Prescaler = 1 (32KHz Divided by 1 gives 32KHz.)
***/
TC0->COUNT8.CTRLA.reg |= (TC_CTRLA_MODE(TC_CTRLA_MODE_COUNT8_Val)|
TC_CTRLA_RUNSTDBY |
TC_CTRLA_ONDEMAND |
TC_CTRLA_PRESCALER(TC_CTRLA_PRESCALER_DIV1_Val));
/*** TC0 Wave generator is used as Match frequency generator (MFRQ) ***/
TC0->COUNT8.WAVE.reg = (TC_WAVE_WAVEGEN_MFRQ);
/*** TC0 is an event generator based on compare value
*** These bit enables the generation of an event
*** for every match or capture on channel 0.
***/
TC0->COUNT8.EVCTRL.reg = (TC_EVCTRL_MCEO0);
/*** 32 is the number to get an event @ 1KHz frequency ***/
TC0->COUNT8.CC[0].reg = 32;
/*** Wait for Clocks synchronzation(COUNT8 register is write synchronized) ***/
while(TC0->COUNT8.SYNCBUSY.reg & TC_SYNCBUSY_CC0);
/*** Ensable TC0 once it is configuring...
*** (COUNT8 register is Enable Protected and write synchronized)
***/
TC0->COUNT8.CTRLA.bit.ENABLE = 1;
/*** Wait for Clocks synchronzation(COUNT8 register is write synchronized) ***/
while(TC0->COUNT8.SYNCBUSY.reg & TC_SYNCBUSY_ENABLE);
}
On Demand and Run in StandBy Clocks
On Demand Clock Request
The ONDEMAND bit is related to clock sources only (i.e., each clock source can run in on-demand mode). Setting this bit allows the clock source to be switched off automatically if no longer required by the peripheral or switched on if a peripheral requests it again.
The clock source is in a stopped state unless a peripheral is requesting the clock source. Clock requests propagate from the peripheral, via the GCLK, to the clock source. If one or more peripheral is using a clock source, the clock source will be started/kept running. As soon as the clock source is no longer needed and no peripheral has an active request, the clock source will be stopped until requested again.
The clock request can reach the clock source only if the peripheral, the generic clock and the clock from the Generic Clock Generator in-between are enabled. The time taken between a clock request being asserted and the clock source being ready depends on the clock source startup time, clock source frequency, and the divider used in the Generic Clock Generator.
In Low Power mode, the clock request mechanism is still working if the modules are configured to run in Standby mode (RUNSTDBY bit set). Do not forget to consider the clock activation delays when using this feature.
Run in Standby Capability
The Run in Standby (RUNSTDBY) bit is related to Clock sources AND Peripherals (except EIC, TRAM, NVMCTRL, PORT, and PTC). This bit enables the capability for a clock source or a peripheral to run in STANDBY Low power mode without CPU interventions.
Here is a table that summarizes the device behaviors according to the ONDEMAND & RUNSTDBY bit configurations: