Cortex-M0 Interrupt Control and System Control (Part Five)

Cortex-M0 Interrupt Control and System Control (Part Five)
Cortex-M0 Interrupt Control and System Control (Part Five)

Click the image to view the details of the conference.

The OS can support multitasking, performing context switching periodically and handling tasks in parallel architecture. A crash in a single task does not affect the entire system. Context switching requires a timer to interrupt program execution; the SysTick timer can provide the necessary clock pulses, offering a rhythmic “heartbeat” for OS task scheduling.

The SysTick timer, also known as the system tick timer or “heartbeat timer,” is a 24-bit countdown timer that automatically reloads the initial value from the reload register when it counts down to zero. It will run indefinitely as long as the enable bit in the SysTick control and status register is not cleared, even working in sleep mode.

The SysTick timer is bundled in the NVIC to generate SysTick exceptions (exception number: 15), and the priority of the SysTick interrupt can also be set.

It works based on beats, dividing the entire time period into many small time slices, where each task can only run for the length of one time slice at a time. If it times out, it exits to let other tasks run, ensuring that no single task monopolizes the various timing functions provided by the operating system, all of which relate to this tick timer.

When enabled, the timer counts down from the reload value to zero and reloads the value from SYST_RVR in the next clock cycle, then continues to count down in subsequent clock cycles. Writing a zero value to SYST_RVR will disable the counter at the next callback. When the counter reaches zero, the COUNTFLAG status bit is set to 1. Reading SYST_CSR will clear the COUNTFLAG bit to 0. Writing to SYST_CVR will clear the register and COUNTFLAG status bit to 0; writing does not trigger the SysTick exception logic, and reading this register will return its value upon access.

01

SysTick Registers

The SysTick timer mainly consists of 4 registers:

Cortex-M0 Interrupt Control and System Control (Part Five)
In CMSIS, the system control register structure is:
typedef struct
{
  __IO uint32_t CTRL; /*!< Offset: 0x00  SysTick Control and Status Register */
  __IO uint32_t LOAD; /*!< Offset: 0x04  SysTick Reload Value Register       */
  __IO uint32_t VAL;  /*!< Offset: 0x08  SysTick Current Value Register      */
  __I  uint32_t CALIB;/*!< Offset: 0x0C  SysTick Calibration Register        */
} SysTick_Type;

In Arm’s official documentation, the four registers are named SYST_CSR, SYST_RVR, SYST_CVR, and SYST_CALIB, but in CMSIS, the naming has been simplified for clarity.

1.1

SysTick Control and Status Register (SYST_CSR)

Cortex-M0 Interrupt Control and System Control (Part Five)

The CSR register uses 4 bits: bit0 is for enabling the timer, setting it to 1 enables the SysTick timer; bit1 controls whether to generate interrupts, setting it to 1 allows interrupts; and bit2 sets the timer’s clock source, setting it to 1 means the timer’s clock source is the main clock, while setting it to 0 means the timer’s clock source is one-fourth of the main clock.

The HCLK source for the SysTick of the MM32F0130 series comes from the AHB bus after hardware division by 4, while FCLK directly comes from the AHB clock bus.

Cortex-M0 Interrupt Control and System Control (Part Five)

When the SysTick timer counts down from 1 to 0, it sets the COUNTFLAG bit; the following methods can clear it:

Read the SysTick Control and Status Register (STCSR).

Write any data to the SysTick Current Value Register (STCVR).

1.2

SysTick Reload Register (SYST_RVR)

Cortex-M0 Interrupt Control and System Control (Part Five)

The RVR register uses bits 0 to 23, and this value is the initial countdown value of the timer. After enabling the timer, it counts down from the value set here to 0, and once it counts down to 0, it will start counting down again from this value.

1.3

SysTick Current Value Register (SYST_CVR)

Cortex-M0 Interrupt Control and System Control (Part Five)

The CVR register also uses bits 0 to 23. This is a status register that changes continuously when the timer starts operating, counting down to 0 after obtaining the initial value from the RVR register.

CURRENT: Reading this register returns the current value of the system timer. Writing a value to this register will reset the timer to 0 and clear the COUNTFLAG bit in CTRL.

1.4

SysTick Calibration Register (SYST_CALIB)

Cortex-M0 Interrupt Control and System Control (Part Five)

If the calibration information is unknown, the required calibration value can be calculated based on the processor clock or external clock frequency.

The calibration value register provides a solution: it allows the system to generate a constant SysTick interrupt frequency even when running on different CM0 products. The simplest approach is to directly write the value of TENMS to the reload register, ensuring that SysTick exceptions occur every 10ms, as long as the system limits are not exceeded. If other SysTick exception periods are required, they can be calculated proportionally based on the TENMS value.

Among the four registers of the system timer, SYST_CALIB is the calibration register, which is configured before leaving the factory, so we do not need to consider this register.

02

SysTick Programming

Configuring SysTick needs to follow a specific process:

1. Start

2. Disable SysTick

3. Set the reload value register

4. Clear the current value register

5. Enable SysTick

6. Complete

SysTick operation-related functions include:
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks);
void SysTick_CLKSourceConfig(u32 systick_clk_source);
void RCC_SystickDisable(void);
void RCC_SystickEnable(u32 sys_tick_period);
The following code demonstrates a basic program to enable SysTick:
; Enable SysTick timer and SysTick exception
LDR R0, =0xE000E010    ; Load the address of STCSR
MOV R1, #0
STR R1, [R0]           ; First stop SysTick to prevent accidental exception requests
LDR R1, =0x3FF         ; Let SysTick count down every 1024 cycles. Since it counts from 1023 to 0,
                       ; a total of 1024 cycles, so the loaded value is 0x3FF
STR R1, [R0,#4]        ; Write the reload value
STR R1, [R0,#8]        ; Write any number to STCVR to ensure COUNTFLAG is cleared
MOV R1, #0x7           ; Select FCLK as the clock source and enable SysTick and its exception request
STR R1, [R0]           ; Write the value to enable the timer
In the CMSIS library, the corresponding configuration function is defined as:
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
/* Reload value impossible */
    if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) {
        return (1UL);                              
    }
/* set reload register */
    SysTick->LOAD  = (uint32_t)(ticks - 1UL);   
/* set Priority for Systick Interrupt */
    NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); 
/* Load the SysTick Counter Value */
    SysTick->VAL   = 0UL;   
/* Enable SysTick IRQ and SysTick Timer */                       
    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                     SysTick_CTRL_TICKINT_Msk   |
                     SysTick_CTRL_ENABLE_Msk;   
/* Function successful */
    return (0UL);                          
}

SysTick can be operated in either polling or interrupt mode. The polling program can read the SysTick control and status register to check the COUNTFLAG. If this bit is set, it indicates that the SysTick count has reached 0.

Reference program for delay in interrupt mode:
static __IO uint32_t TimingDelay;
void Delay(__IO uint32_t nTime)
{ 
     TimingDelay = nTime;
     while(TimingDelay != 0);
}

void SysTick_Handler(void)
{
     if (TimingDelay != 0x00) 
     { 
       TimingDelay--;
     }
}

int main(void)
{ 
     // SysTick clock is HCLK, interrupt time interval is 1ms
     if (SysTick_Config(SystemCoreClock / 1000)) 
     {
         while (1);
     }
     while(1)
     { 
         Delay(200);//200ms
     }
}
Reference program for delay in polling mode:
void delay_init()
{
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div4);   // Select external clock HCLK/4
    // For system clock's 1/4, actually calculating the number of SysTick VAL decreases per 1us
    fac_us=SystemCoreClock/4000000; 
    // Represents the number of SysTick clock cycles required for each ms, i.e., the number of SysTick VAL decreases per millisecond
    fac_ms=(u16)fac_us*1000;        
} 

void delay_ms(u16 nms)
{                  
    u32 temp;          
    SysTick->LOAD=(u32)nms*fac_ms;          // Time loading (SysTick->LOAD is 24bit)
    SysTick->VAL =0x00;           // Clear the counter
    SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          // Start counting down  
    do
    {
        temp=SysTick->CTRL;
     }while((temp&0x01)&&!(temp&(1<<16)));   // Wait for the time to reach, check the 16th bit of CTRL (COUNTFLAG) is 1, check the 0th bit of STRL (ENABLE) is 1   
     SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       // Turn off the counter
     SysTick->VAL =0X00;       // Clear the counter        
}

void delay_us(u32 nus)
{        
    u32 temp;            
    SysTick->LOAD=nus*fac_us;               // Time loading           
    SysTick->VAL=0x00;        // Clear the counter
    SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;  // Start counting down      
    do
    {
        temp=SysTick->CTRL;
    }while((temp&0x01)&&!(temp&(1<<16)));        // Wait for the time to reach   
    SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;  // Turn off the counter
    SysTick->VAL =0X00;       // Clear the counter    
}

The SysTick timer can also serve other purposes, such as time measurement, timing, or alarms.

Previous Highlights

Lecture 178 | Cortex-M0 Interrupt Control and System Control (Part Four)
Lecture 177 | Cortex-M0 Interrupt Control and System Control (Part Three)
Lecture 176 | Cortex-M0 Interrupt Control and System Control (Part Two)
Lecture 175 | Cortex-M0 Interrupt Control and System Control (Part One)
Lecture 174 | Causes and Solutions for Processor Lockup
Lecture 173 | HardFault Positioning Methods and Steps
Lecture 172 | MM32F013x——IEC60730-1 Class B Certification Software Design Guide (Part Seven)
Lecture 171 | MM32F013x——IEC60730-1 Class B Certification Software Design Guide (Part Six)
Lecture 170 | MM32F013x——IEC60730-1 Class B Certification Software Design Guide (Part Five)
Lecture 169 | MM32F013x——IEC60730-1 Class B Certification Software Design Guide (Part Four)
Lecture 168 | MM32F013x——IEC60730-1 Class B Certification Software Design Guide (Part Three)
Lecture 167 | MM32F013x——IEC60730-1 Class B Certification Software Design Guide (Part Two)
Lecture 166 | MM32F013x——IEC60730-1 Class B Certification Software Design Guide (Part One)
Lecture 165 | MM32F013x——Building MM32 Development Environment under Linux
Lecture 164 | MM32F013x——Event Recorder Usage Method
Lecture 163 | MM32F013x——J-Scope Virtual Oscilloscope Functionality
Lecture 162 | MM32F013x——RTT Usage Tips
Lecture 161 | MM32F013x——Using Ozone to Debug MM32 MCU
Lecture 160 | MM32F013x——Building MM32 Development Environment based on Embedded Studio
Lecture 159 | MM32F013x——Developing and Debugging MM32 under Windows with Eclipse
Lecture 158 | MM32F013x——Building Eclipse Development Environment under Windows
Lecture 157 | MM32F013x——Porting EasyLogger Component
Lecture 156 | MM32F013x——Porting EasyFlash Component
Lecture 155 | MM32F013x——Hardware Watchdog and Option Byte Operations
Lecture 154 | MM32F013x——RTC Alarm Timing Wake-Up
Lecture 153 | MM32F013x——Perpetual Calendar
Lecture 152 | MM32F013x——TIM1 Hardware Phase Shift Function
Lecture 151 | MM32F013x——ADC Any Channel Working Mode
Lecture 150 | MM32F013x——I2C Slave Multi-Address Application
Highlights of Lingdong Micro Classroom

About Lingdong

Lingdong was established in 2011 and is a leading local supplier of general-purpose 32-bit MCU products and solutions in China. The MM32 MCU products developed based on the Arm Cortex-M series cores have four major series: F/L/SPIN/W, with over 200 models, cumulatively delivering over 300 million units, ranking among the top in local general-purpose 32-bit MCU companies. MM32 MCUs are widely used in smart industry, automotive electronics, communication infrastructure, healthcare, smart appliances, IoT, personal devices, mobile phones, and computers, with tens of millions of excellent products equipped with Lingdong MM32 MCUs delivered to customers every year.

Cortex-M0 Interrupt Control and System Control (Part Five)

To date, Lingdong is the only local MCU company that has simultaneously obtained official support from development tools such as Arm-KEIL, IAR, and SEGGER, and is one of the few general-purpose MCU companies that has established an independent and complete ecosystem, committed to providing customers with comprehensive support from chip hardware to software algorithms, from reference solutions to system design, truly providing fundamental technical drive and support for China’s electronic information industry.

Cortex-M0 Interrupt Control and System Control (Part Five)

Lingdong Microelectronics

WeChat ID: MindMotion-MMCU

Cortex-M0 Interrupt Control and System Control (Part Five)
Cortex-M0 Interrupt Control and System Control (Part Five)

Long press to recognize the QR code to follow us

Cortex-M0 Interrupt Control and System Control (Part Five)

MORE

For more information, please visit: www.mm32mcu.com

WeChat official account search: Lingdong MM32MCU

QQ Technical Discussion Group: 294016370

Taobao Store: Shanghai Lingdong Microelectronics Co., Ltd.

Lingdong MM32MCU Technical Forum: bbs.21ic.com

Leave a Comment