SAM L10/L11 Main Clock (MCLK) Controller

Last modified by Microchip on 2023/11/15 17:35

Overview

The MCLK controls the synchronous clock generation of the device. Using a clock provided by the Generic Clock Module (GCLK_MAIN) or the DFLLULP (CLK_DFLLULP), the MCLK Controller provides synchronous system clocks to the CPU and the modules connected to the AHBx and the APBx bus. The synchronous system clocks are divided into a number of clock domains. Each clock domain can run at different frequencies, enabling you to save power by running peripherals at a relatively low clock frequency, while maintaining high CPU performance or vice versa. In addition, the clock can be masked for individual modules, enabling you to minimize power consumption.

The MCLK bus clock (CLK_MCLK_APB) can be enabled and disabled in the Main Clock module, and the default state of CLK_MCLK_APB can be found in the Peripheral Clock Masking section. If this clock is disabled, it can only be re-enabled by a reset. The Generic Clock GCLK_MAIN or the DFLLULP Clock CLK_DFLLULP is required to generate the Main Clocks. GCLK_MAIN is configured in the Generic Clock Controller (GCLK), and can be re-configured if needed. CLK_DFLLULP is configured in the Oscillators Controller (OSCCTRL).

​By default, the MCLK clock source is supplied by the Generic Clock Generator 0 (GCLK0).

​Refer to the "MCLK – Main Clock Controller" chapter from the "SAM L10/L11 Family Ultra Low-Power, 32-bit Cortex-M23 MCUs with TrustZone, Crypto, and Enhanced PTC" datasheet for more details.

Back to top

Block Diagram

SAM L10 Clock System Block Diagram

Code Example

/***
 *** 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;

Back to top