Can I Feed the Same General Clock to Multiple Timers Samd21

The SAM D21 MCU contains a sophisticated clocking system, which is designed to give the maximum flexibility to the user application. This system allows a system designer to tune the performance and power consumption of the device in a dynamic manner, to achieve the best trade-off between the two for a particular application.

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


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

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.
  • A clock from the Generic Clock Generator must be configured to use one of the running Clock Sources, and the Generator must be enabled.
  • 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.
  • The user interface of the peripheral needs to be unmasked in the PM. If this is not done the peripheral registers will read all 0's and any writing attempts to the peripheral will be discarded.

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 8.
    • Generic Clock Generator 0 uses OSC8M as source and generates GCLK_MAIN.
    • CPU and BUS clocks are undivided (divide by 1).
    • 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 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 code examples below for a project that configures the DFLL48M for 48 MHz operation.

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.

Code Examples

palmoresaws1972.blogspot.com

Source: https://microchipdeveloper.com/32arm:samd21-standard-peripherals-clock-system

0 Response to "Can I Feed the Same General Clock to Multiple Timers Samd21"

Enviar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel