SAM D21 Clock System Configuration

This page provides a more detailed description of the Clock System on SAM D21 MCUs, covering key registers and basic coding steps required to configure/use the clock.

samd21-clock-system-block-diagram-detail.png


The peripherals that control the clock distribution tree of the SAM D21 are:

  • SYSCTRL - which controls the clock sources,
  • GCLK (Generic Clock Controller) - which controls the clock distribution system, and
  • Power Manager (PM) - which generates and controls the synchronous clocks in the system

Overview

The main system clock GCLK_MAIN and clocks generated from it (CPU, AHB/APB Bus Clocks) are called "synchronous" clocks, while the generic clocks are called "asynchronous" clocks (with respect to the system clock).

Peripheral access registers (the programmer’s interface) are clocked by the synchronous clock generated by the Power Manager for the peripheral; internally, the peripherals use the asynchronous clocks generated by the Generic Clock Generators (the SERCOM peripheral for example uses a generic clock to source the baud rate generator).

As the CPU and the peripherals can be in different clock domains, some peripheral accesses by the CPU need to be synchronized. In this case, the peripheral includes a SYNCBUSY status register that can be used to check if a sync operation is in progress. For a general description, see "Register Synchronization" below.

Clock Sources

The SAM D21 MCU devices have a number of master clock source modules, each of which being capable of producing a stabilized output frequency, which can then be fed into the various peripherals and modules within the device. Possible clock source modules include internal R/C oscillators (OSC8M, OSC32K, OSCULP32K), internal digital frequency-locked-loop (DFLL) modules (DFLL48M), as well as external crystal oscillators and/or clock inputs (XOSC, XOSC32K).

These clock sources are predominantly controlled via register settings in the SYSCTRL peripheral. Key registers include:

PCLKSR

  • Power and Clocks Status

OSC8M

  • 8 MHz Internal Osc. Control

XOSC32K

  • External 32 kHz Osc. Control

DFLLCTRL

  • 48 MHz Internal DFLL Osc. Control

Generic Clocks

Within the SAM D21 devices, there are a number of generic clocks; these are used to provide clocks to the various peripheral clock domains in the device in a standardized manner. One or more master source clocks can be selected as the input clock to a Generic Clock Generator, which can prescale down the input frequency to a slower rate for use in a peripheral.

Additionally, a number of individually selectable Generic Clock Channels are provided, which multiplex and gate the various generator outputs for one or more peripherals within the device. This setup allows for a single common generator to feed one or more channels, which can then be enabled or disabled individually as required.

samd21-clock-system-generic-clocks.png

Clock Generator 0 is dedicated to supplying GCLK_MAIN.

Multiplexer 0 (Peripheral Channel 0) is dedicated to supplying the DFLL48M reference clock.


The generic clocks are predominantly controlled via register settings in the GCLK peripheral. Key registers include:

CTRL

  • Perform Soft-Reset of GCLK registers

STATUS

  • SYNCBUSY Operation

GENDIV

  • Set clock generator divider

GENCTRL

  • Enable and configure clock generators

CLKCTRL

  • Connect a specific clock generator to a specific multiplexer (peripheral channel), supplying an asynchronous clock to a specific peripheral

Accessing GCLK Registers

Each GCLK Generator has its own set of configuration registers. The Generic Clock Generator Control and Division registers (GENCTRL and GENDIV) and the Generic Clock Control register (CLKCTRL) are indirectly addressed as shown in the next figure:

samd21-clock-system-gclk-register-access.png

Writing these registers is done by setting the corresponding ID bit group. To read a register, the user must write the ID of the channel, i, in the corresponding register. The value of the register for the corresponding ID is available in the user interface by a read access.

For example, the sequence to read the GENCTRL register of a specific Generic Clock Generator i is:

  1. Do an 8-bit write of the i value to GENCTRL.ID.
  2. Read the value of GENCTRL.


Refer to the clock-chain examples below to see some GCLK initialization code sequences.

Synchronous (CPU/Bus) Clocks

The CPU and AHB/APBx buses are clocked by the same physical clock source (referred in this module as GCLK_MAIN), however, the APBx buses may have additional prescaler division ratios set to give each peripheral bus a different clock speed. The general main clock tree for the CPU and associated buses is shown here:

samd21-clock-system-synchronous-clocks.png


The Synchronous clock sources are predominantly controlled via register settings in the PM peripheral. Key registers include:

CPUSEL

  • Set the prescaler of the main system clock

APBASEL, APBBSEL, APBCSEL

  • Select the prescaler of peripheral buses

AHBMASK

  • Enable clocks on the AHB bus

APBAMASK, APBBMASK, APBCMASK

  • Enable clocks on peripheral buses

Enabling a Peripheral

All peripherals need two clock signals:

  • a generic clock from GCLK (asynchronous),
  • and an interface clock from PM (synchronous).

samd21-clock-system-clock-chain-example-sercom0-labelled.png


In order to enable a peripheral that is clocked by a generic clock, the following parts of the system need to be configured:

  • A running clock source (SYSCTRL).
  • A clock from the Generic Clock Generator must be configured to use one of the running clock sources, and the generator must be enabled (GCLK).
  • A Generic Clock Multiplexer (Peripheral Channel) that provides the generic clock signal to the peripheral must be configured to use a running Generic Clock Generator, and the generic clock must be enabled (GCLK).
  • The peripheral interface clock needs to be unmasked in the PM. If this is not done, the peripheral registers will read all zeros and any writing attempts to the peripheral will be discarded.

See the SERCOM0 Clock Chain Example below for a code example.

Clock Chain Examples

Clocks After Reset

On a User Reset (asserting the RESET pin),

  • Synchronous clocks start in their initial state:
    • OSC8M is enabled and divided by eight.
    • Generic Clock Generator 0 uses OSC8M as source and generates GCLK_MAIN.
    • CPU and BUS clocks are undivided (divide by one).
    • SOME synchronous peripheral clocks are enabled (see the PM chapter in the datasheet for details).
  • GCLK starts in its initial state. All Generic Clock Generators are disabled except:
    • Generator 0 is using OSC8M as a source without division and generates GCLK_MAIN.
    • Generator 2 is using OSCULP32K as a source without division.
    • All Multiplexers (Peripheral Channels) are disabled except WDT Generic Clock (GCLK_WDT), which uses Generator 2 as a source.
  • Instruction Cache and Flash Read Wait States start in its initial state:
    • Instruction Cache enabled (NVMCTRL->CTRLB.CACHEDIS = 0)
    • 0 Flash Read Wait States (NVMCTRL->CTRLB.RWS = 0)

samd21-clock-system-clock-chain-example-user-reset.png

Refer to the Power Manager (PM) section in the datasheet to learn about the different device reset types on SAM D21.

SERCOM0 Configuration Example

The next figure shows an example where SERCOM0 is clocked by the OSC8M. OSC8M is enabled with 8 MHz output and fed to Generic Clock Generator 0 which provides GCLK_MAIN as source to the synchronous clock generator. The Generic Clock Generator 1 also uses the OSC8M as its clock source and feeds into Peripheral Channel 20. The Generic Clock 20, also called GCLK_SERCOM0_CORE, is connected to SERCOM0. The SERCOM0 interface, clocked by CLK_SERCOM0_APB, has been unmasked in the APBC Mask register in the PM.

samd21-clock-system-clock-chain-example-sercom0.png


Here is a code sample that creates this clock configuration:

#include "sam.h"

void clockInit(void)
{
    SYSCTRL->OSC8M.bit.PRESC = 0;                          // no prescaler (is 8 on reset)
    SYSCTRL->OSC8M.reg |= 1 << SYSCTRL_OSC8M_ENABLE_Pos;   // enable source

    GCLK->GENDIV.bit.ID = 0x01;                            // select GCLK_GEN[1]
    GCLK->GENDIV.bit.DIV = 0;                              // no prescaler

    GCLK->GENCTRL.bit.ID = 0x01;                           // select GCLK_GEN[1]
    GCLK->GENCTRL.reg |= GCLK_GENCTRL_SRC_OSC8M;           // OSC8M source
    GCLK->GENCTRL.bit.GENEN = 1;                           // enable generator

    GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_SERCOM0_CORE;      // SERCOM0 peripheral channel
    GCLK->CLKCTRL.reg |= GCLK_CLKCTRL_GEN_GCLK1;           // select source GCLK_GEN[1]
    GCLK->CLKCTRL.bit.CLKEN = 1;                           // enable generic clock

    PM->APBCSEL.bit.APBCDIV = 0;                           // no prescaler
    PM->APBCMASK.bit.SERCOM0_ = 1;                         // enable SERCOM0 interface
}

DFLL48M 48 MHz Configuration Example

The next figure shows the common configuration to clock the device to its maximum speed (48 MHz) using the DFLL48M clock source. The DFLL48M reference clock source is XOSC32K but it can be another one. The DFLL48M module has been optimized for a 32.768 kHz crystal as source clock (from the datasheet, the DFLL48 maximum reference frequency = 33 kHz).

samd21-clock-system-clock-chain-example-dfll48m.png


The code sequence is a little more complicated as we have to consider multiple clock sources, as well as the configuration of Flash memory, read wait states. Here are the steps required to switch over to the 48 MHz DFLL48M clock:

  1. Set Flash wait states for 48 MHz (per Table 37-40 in the datasheet).
  2. Enable XOSC32K clock (External on-board 32.768 Hz oscillator), will be used as DFLL48M reference.
  3. Put XOSC32K as a source of Generic Clock Generator 1,
  4. Put Generic Clock Generator 1 as a source for Generic Clock Multiplexer 0 (DFLL48M reference).
  5. Enable DFLL48M clock.
  6. Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48 MHz.


See the DFLL48M 48 MHz initialization project as an example that configures the DFLL48M for 48 MHz operation using the steps described above.

Register Synchronization

All peripherals are composed of one digital bus interface connected to the APB or AHB bus and running from a corresponding synchronous clock in the Main Clock domain, and one peripheral core interface running from the asynchronous peripheral Generic Clock (GCLK):

samd21-clock-system-clock-domains.png


Communication between these clock domains must be synchronized. This mechanism is implemented in hardware, so the synchronization process takes place even if the peripheral generic clock is running from the same clock source and on the same frequency as the bus interface.

Write Synchronization

SAM D21 implements a common synchronizer mechanism for all registers in one peripheral. Therefore, only one register per peripheral can be synchronized at a time. Here is the mechanism:

  • Registers with the "Write-Synchronized" property are synchronized when written.
  • SYNCBUSY bit is set in hardware when writing to a write-synchronized register.
  • Stall occurs if trying to write to a peripheral register when the SYNCBUSY bit is set.

For example, the GCLK GENCTRL register is specified as "Write-Synchronized" in the datasheet.

samd21-clock-system-genctrl-reg.png

The following code example inserts a delay following a write to this register before writing any more registers in the GCLK module:

GCLK->GENCTRL.reg = 0x01234567;
while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY){
    /* Wait for synchronization */
}

For more information on register synchronization, review the "Clock System" chapter in the SAM D21 device datasheet.

 Learn More

 
Clock System Overview
Learn more >
 
DFLL48M 48 MHz Initialization Example
Learn more >
© 2018 Microchip Technology, Inc.
Notice: ARM and Cortex are the registered trademarks of ARM Limited in the EU and other countries.
Information contained on this site regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer's risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.