SysTick and the SAMD21

The AVR-based Arduino boards use a Counter/Timer overflow interrupt to implement the system tick that is used in the micros(), millis(), and delay() functions. The SAMD21-based Arduino boards use the SysTick counter to implement the same functionality, but seeking out how it does it is a bit move involved. Looking at things top-down, this functions are in the new source file delay.c. There is an apparent interrupt handler that implements the tick counter and calls a mysterious tickReset function that we will ignore (it is used to erase the microcontroller flash ROM!).

void SysTick_DefaultHandler(void)
{
  // Increment tick count each ms
  _ulTickCount++;
  tickReset();
}

Ticks are exactly 1ms apart rather than the 1.024ms of most of the AVR-based Arduinos. That makes the millis function trivial but the micros function is complicated by it not being able to get the time atomically. We will ignore that function in this blog post, but it does reference SysTick’s counter value as the mysterious SysTick->VAL.

The actual interrupt handler is SysTick_Handler. This is defined in the new file cortex_handlers.c, which also contains the Exception (“interrupt”) Table.

/* Default Arduino systick handler */
extern void SysTick_DefaultHandler(void);

void SysTick_Handler(void)
{
  if (sysTickHook())
    return;
  SysTick_DefaultHandler();
}

But notice the call to sysTickHook. There is a default implementation that does nothing located in the new file hooks.c. But this can be overridden allowing for the first time having Arduino applications with a supplied SysTick hook. Arduino supplies this for RTOS implementation. It is important to have it return false so that the default handler will run.

/**
 * SysTick hook
 *
 * This function is called from SysTick handler, before the default
 * handler provided by Arduino.
 */
static int __false() {
	// Return false
	return 0;
}
int sysTickHook(void) __attribute__ ((weak, alias("__false")));

The only other thing I’m going to talk about is device registers for SysTick. If you look in the Microchip SAMD21 datasheet you only get this statement:

• System Timer (SysTick)

– The System Timer is a 24-bit timer clocked by CLK_CPU that extends the functionality of both the processor and the NVIC. Refer to the Cortex-M0+ Technical Reference Manual for details (www.arm.com).

If you go and find the Cortex-M0+ Technical Reference Manual you will find that it also says nothing about the device registers! You actually need to seek out the Cortex-M0+ Devices Generic User Guide, which has three pages about it in chapter 4.4. Now the funny thing (as if that weren’t funny enough) is that it refers to the registers by the names SYST_CSR, SYST_RVR, SYST_CVR, and SYST_CALIB. So where is this SysTick->VAL I’m looking for?

Well ARM has this interface called CMSIS, the  Common Microcontroller Software Interface Standard. And in there file core_cm0plus.h, which you may have to hunt around a bit to find, is this:

typedef struct
{
  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
} SysTick_Type;

#define SysTick      ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct */

(There are other useful functions hidden there like SysTick_Config which can be used to configure the SysTick counter.)

Hopefully this will give you some idea of what I have to go through to decipher the operation of these microcontrollers! And this is just a simple counter with an interrupt.