SAM C21 Systick Configuration

Last modified by Microchip on 2023/11/10 11:08

This section covers the basic coding steps required to configure/use the SysTick timer module found in the CPU core of SAM C21 MCUs.

SysTick timer module

SysTick Operation

The system timer consists of four registers (CTRLLOADVALCALIB) which are defined in the CMSIS-Core header file core_cm0plus.h. These registers are located in the SAM C21 System Control Space (SCS) memory region, beginning at address 0xE000E010.

These registers are accessed in C via indirect (pointer) access, using the symbol SysTick as a base address pointer to the register set, for example:

SysTick->CTRL = 0; // Disable SysTick
SysTick->LOAD = 0x0000FFFF; // Set reload value register
SysTick->VAL = 0; // Reset the counter current value register value

When enabled, the 24-bit timer counter counts down from the value in VAL. When the counter reaches zero, it reloads the value in LOAD on the next clock edge. It then decrements on subsequent clocks. This reloading when the counter reaches zero is called wrapping. When the counter transitions to zero, it sets the COUNTFLAG status bit to '1'. If the TICKINT bit is set, an exception may be generated. Reading the COUNTFLAG status bit clears it to '0'.

Therefore, the SysTick Interrupt Time Period = (LOAD + 1) * CLK Period.

SysTick Interrupt Time Period

Writing to VAL clears both the register and the COUNTFLAG status bit to zero. This causes the SysTick logic to reload VAL from LOAD on the next timer clock. A write to VAL does not trigger the SysTick exception logic.

Reading VAL returns the value of the counter at the time the register is accessed. Writing a value of zero to LOAD disables the counter on the next wrap. The SysTick counter logic maintains this counter value of zero after the wrap.

The 24-bit counter is clocked by either the CPU clock (AHB clock) or an implementation-defined Reference Clock. The clock source is set by the CLKSOURCE and NOREF flag bits.

Current SAM C21 errata indicates that the Reference Clock is un-implemented and that you should configure the SysTick clock source to be the CPU Clock (CLKSOURCE==1).

Back to Top

SysTick Registers

SysTick_CTRL

SysTick_CTRL is a control and status register that configures the SysTick clock, enables the counter, enables the SysTick interrupt, and indicates the counter status.

SysTick_CTRL control and status register

bit 16

COUNTFLAG: Indicates whether the counter has counted to 0 since the last read of this register.

1 = timer has counted to 0
0 = timer has not counted to 0

COUNTFLAG is set to '1' by a count transition from 1 to 0.
COUNTFLAG is cleared to '0' by a read of this register, and by any write to the Current Value register.

bit 2

CLKSOURCE: Indicates the SysTick clock source.

1 = SysTick uses the processor clock
0 = SysTick uses the optional external reference clock

If no reference clock is provided, this bit reads as '1' and ignores writes.

bit 1

TICKINT: Indicates whether counting to 0 causes the status of the SysTick exception to change to pending.

1 = count to 0 changes the SysTick exception status to pending
0 = count to 0 does not affect the SysTick exception status

Changing the value of the counter to '0' by writing zero to the SysTick Current Value register (SysTick_VAL) never changes the status of the SysTick exception.

bit 0

ENABLE: Indicates the enabled status of the SysTick counter.

1 = counter is operating
0 = counter is disabled

Back to Top

SysTick_LOAD

SysTick_LOAD is a counter (re)-load value register. This provides the wrap value for the counter.

bit 23:0

RELOAD: The 24-bit value to (re)load into the current value register (SysTick_VAL) when the counter reaches 0.

​Make sure to load this register with '1' less than the actual number of ticks in a desired period, for example:

SysTick->LOAD = ticks -1;

Back to Top

SysTick_VAL

SysTick_VAL is the counter current value register.

SysTick_VAL counter current value register

bit 23:0

CURRENT: Current counter value. This is the value of the counter at the time it is sampled.

SysTick_CALIB

SysTick_CALIB is the calibration value register. This indicates the preload value required for a 10 ms system clock.

SysTick_CALIB calibration value register

bit 31

NOREF: Indicates whether an IMPLEMENTATION DEFINED reference clock is provided.

1 = the reference clock is not implemented
0 = the reference clock is implemented

When this bit is '1', the CLKSOURCE bit of the SysTick_CTRL register is forced to '1' and cannot be cleared to '0'.

bit 30

SKEW: Indicates whether the 10 ms calibration value is exact.

1 = 10 ms calibration value is inexact, because of the clock frequency
0 = 10 ms calibration value is exact

bit 23:0

TENMS: Optionally, holds a reload value to be used for 10 ms (100 Hz) timing, subject to system clock skew errors. If this field is zero, the calibration value is not known.

The current SAM C21 errata indicates that the CALIB value is incorrect. Therefore, this value should not be used to initialize the Systick RELOAD value register, which should be initialized instead with a value depending on the CPU clock frequency and on the tick period required by the application.

Back to Top

SysTick Initialization

As the Reload and Current Value registers are undefined at reset, the SysTick setup code needs to be written in a certain sequence:

  1. Disable the SysTick module
  2. Program the Reload Register
  3. Clear the Current Value Register
  4. Enable the SysTick Module

The following example initializes the SysTick Module to generate interrupt requests every millisecond, given a CPU Clock of 4 MHz:

// Configure SysTick to trigger every millisecond using the CPU Clock
SysTick->CTRL = 0;                    // Disable the SysTick Module
SysTick->LOAD = 3999UL;                // Set the Reload Register for 1mS interrupts
NVIC_SetPriority(SysTick_IRQn, 3);    // Set the interrupt priority to least urgency
SysTick->VAL = 0;                    // Clear the Current Value register
SysTick->CTRL = 0x00000007;        // Enable SysTick, Enable SysTick Exceptions, Use CPU Clock
NVIC_EnableIRQ(SysTick_IRQn);        // Enable the SysTick Interrupt (Global)

Back to Top

CMSIS SysTick Functions

SysTick configuration is also supported via available CMSIS functions in the core_cm0plus.h file. The following code example uses the SysTick_Config() function, which initializes SysTick and its interrupt (priority level = 3) and starts the timer. The counter is in free running mode to generate periodic interrupts.

// Configure Systick to trigger every millisecond @ 4 MHz CPU clock
SysTick_Config(4000UL);
NVIC_EnableIRQ(SysTick_IRQn);

Back to Top

SysTick Debugging

The SysTick registers may be viewed in the Atmel Studio 7 I/O Debug window as shown. Note that the Arm®-based SysTick register names are shown:

  • SysTick_CTRL = CSR (Control and Status Register)
  • SysTick_LOAD = RVR (Reload Value Register)
  • SysTick_VAL = CVR (Current Value Register)
  • SysTick_CALIB = CALIB (Calibration Register)

SysTick registers in the Atmel Studio 7 I/O Debug window

Back to Top

Learn More

Back to Top