Using the SysTick Timer in PSoC® 4 – KBA91374

Version: **

 

Question: What is the SysTick timer? How do you configure it and use it as a general-purpose timer in PSoC® 4?

 

Answer:

The SysTick timer is an integral part of the ARM® Cortex™-M0 processor that powers the PSoC 4 family. The timer is a down counter with a 24-bit reload/tick value and clocked by the system clock (SysClk) reaching the Cortex-M0 from the PSoC 4 clocking system. The timer has the capability to generate an interrupt when the set number of ticks expires and the counter reloads. This interrupt is available as part of the Nested Vectored Interrupt Controller (NVIC) for service by the CPU and can be used for general purpose timing control in the user code. Since the timer is independent of the CPU (except for the clock), it can be handy in applications requiring precise timing but not having a dedicated timer/counter available for the job.

Configuring the timer:

The SysTick registers are part of the System Control Space (SCS) registers that are common to all Cortex-M0 CPU-based devices. Refer to Section 4.4, “Optional system timer, SysTick” of the Cortex-M0 Devices Generic User Guide for complete details on the registers and their usage. A brief summary of the registers is provided in Table 1 for quick reference.

 

                                                                                                                                                         
    Table 1. SysTick Timer Registers
    Address    Name    Type   
     Reset value
  
    Description
    0xE000E010    SYST_CSR    RW    -[a]    SysTick Control and Status Register
    0xE000E014    SYST_RVR    RW    Unknown    SysTick Reload Value Register
    0xE000E018    SYST_CVR    RW    Unknown    SysTick Current Value Register
    0xE000E01C    SYST_CALIB    RO    -[a]    SysTick Calibration Value Register
    [a]See the register description for more information

 

In the PSoC 4 family, these registers can be accessed using a pointer to the structure defined in the core_cm0.h file. This file also provides an API to configure and enable the SysTick timer to generate a periodic interrupt. The details of the structure and API are provided in Table 2 and Table 3.

Table 2. SysTick Structure details

                                                                                                               
    Structure Name    Member    Function/Register mapped
    SysTick          
         SysTick->CTRL    SYST_CSR (Control & Status Register)
         SysTick->LOAD    SYST_RVR (Reload value register)
         SysTick->VAL    SYST_CVR (Current value register)
         SysTick->CALIB    SYST_CALIB (Calibration value register)

Table 3. SysTick API Details

                                               
    Function    Parameters    Return Value    Description
    uint32 SysTick_Config(uint32)    uint32 ticks –value to be written to the reload register. This defines the period of the timer.
   
    PERIOD = ticks/SYSCLK_FREQ
    uint32 status – status if the update was successful. The update fails if the passed parameter ‘ticks’ is more than 24-bits i.e. if the value cannot be written to the reload register    The function initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic nterrupts.

Before the timer is configured and initialized with the desired period, the interrupt needs to be mapped to the proper function for servicing the periodic ISR that will be generated. For that, the CyIntSetSysVector() API can be used as explained in the code snippet below. The code snippet is a sample firmware that can be used to generate a SysTick ISR every 100 Sysclk ticks. The ISR is mapped to the USER_ISR routine, which you can rename to any valid name you choose.

#include #define NUMBER_OF_TICKS   100/* ISR prototype declaration */CY_ISR_PROTO(USER_ISR); /* User ISR function definition */CY_ISR(USER_ISR) {  /* User ISR Code*/}  int main(void) { /* Map systick ISR to the user defined ISR. SysTick_IRQn is already defined in core_cm0.h file */ CyIntSetSysVector((SysTick_IRQn + 16), USER_ISR);  /* Enable Systick timer with desired period/number of ticks */ SysTick_Config(NUMBER_OF_TICKS);  /* Enable global interrupts */ CyGlobalIntEnable;  /* infinite loop */ for(;;)  {  } }

   

   Note: The SysTick timer is a CPU exception which cannot be masked in the NVIC. If enabled, it will generate an interrupt/exception and will be serviced.