SAM D21 Clock System Configuration

Last modified by Microchip on 2023/11/09 09:01

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

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 an SYNCBUSY status register that can be used to check if a sync operation is in progress. For a general description, see Register Synchronization below.

Back to top

Clock Sources

The SAM D21 MCU devices have a number of master clock source modules, each of which is 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

Back to top

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

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

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.

Back to top

Synchronous (CPU/Bus) Clocks

The CPU and AHB/APBx buses are clocked by the same physical clock source (referred to 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 in the accompanying image.

samd21 clock system synchronous clocks

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
  • APBASELAPBBSELAPBCSEL
    • Select the prescaler of peripheral buses
  • AHBMASK
    • Enable clocks on the AHB bus
  • APBAMASKAPBBMASKAPBCMASK
    • Enable clocks on peripheral buses

Back to top

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

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.

Back to top

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

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

Back to top

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

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 the source clock (from the datasheet, the DFLL48 maximum reference frequency = 33 kHz).

samd21 clock system clock chain example dfll48m

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), which 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 the 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.

Back to top

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

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.

Back to top

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

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

Back to top