Systick Timer(SysTimer)

Click Nuclei Timer Unit to learn about Core Timer Unit in Nuclei ISA Spec.

SysTimer API

__STATIC_FORCEINLINE void SysTimer_SetLoadValue (uint64_t value)
__STATIC_FORCEINLINE uint64_t SysTimer_GetLoadValue (void)
__STATIC_FORCEINLINE void SysTimer_SetHartCompareValue (uint64_t value, unsigned long hartid)
__STATIC_FORCEINLINE void SysTimer_SetCompareValue (uint64_t value)
__STATIC_FORCEINLINE uint64_t SysTimer_GetHartCompareValue (unsigned long hartid)
__STATIC_FORCEINLINE uint64_t SysTimer_GetCompareValue (void)
__STATIC_FORCEINLINE void SysTimer_Start (void)
__STATIC_FORCEINLINE void SysTimer_Stop (void)
__STATIC_FORCEINLINE void SysTimer_SetControlValue (uint32_t mctl)
__STATIC_FORCEINLINE uint32_t SysTimer_GetControlValue (void)
__STATIC_FORCEINLINE void SysTimer_SetHartSWIRQ (unsigned long hartid)
__STATIC_FORCEINLINE void SysTimer_SetSWIRQ (void)
__STATIC_FORCEINLINE void SysTimer_ClearHartSWIRQ (unsigned long hartid)
__STATIC_FORCEINLINE void SysTimer_ClearSWIRQ (void)
__STATIC_FORCEINLINE uint32_t SysTimer_GetHartMsipValue (unsigned long hartid)
__STATIC_FORCEINLINE uint32_t SysTimer_GetMsipValue (void)
__STATIC_FORCEINLINE void SysTimer_SetHartMsipValue (uint32_t msip, unsigned long hartid)
__STATIC_FORCEINLINE void SysTimer_SetMsipValue (uint32_t msip)
__STATIC_FORCEINLINE void SysTimer_SoftwareReset (void)
__STATIC_FORCEINLINE void SysTimer_SendIPI (unsigned long hartid)
__STATIC_FORCEINLINE void SysTimer_ClearIPI (unsigned long hartid)
__STATIC_INLINE uint32_t SysTick_Config (uint64_t ticks)
__STATIC_INLINE uint32_t SysTick_HartConfig (uint64_t ticks, unsigned long hartid)
__STATIC_FORCEINLINE uint32_t SysTick_Reload (uint64_t ticks)
__STATIC_FORCEINLINE uint32_t SysTick_HartReload (uint64_t ticks, unsigned long hartid)
SysTimer_GetHartID() (__get_hart_index())
group NMSIS_Core_SysTimer

Functions that configure the Core System Timer.

Defines

SysTimer_GetHartID() (__get_hart_index())

SysTimer_GetHartID() is used to get timer hartid which might not be the same as cpu hart id, for example, cpu hartid may be 1, but timer hartid may be 0, then timer hartid offset is 1.

If defined __SYSTIMER_HARTID, it will use __SYSTIMER_HARTID as timer hartid, otherwise, it will use __get_hart_index(). The cpu hartid is get by using __get_hart_id function

Functions

__STATIC_FORCEINLINE void SysTimer_SetLoadValue (uint64_t value)

Set system timer load value.

This function set the system timer load value in MTIMER register.

Remark

  • Load value is 64bits wide.

  • SysTimer_GetLoadValue

Parameters

value[in] value to set system timer MTIMER register.

__STATIC_FORCEINLINE uint64_t SysTimer_GetLoadValue (void)

Get system timer load value.

This function get the system timer current value in MTIMER register.

Remark

  • Load value is 64bits wide.

  • SysTimer_SetLoadValue

Returns

current value(64bit) of system timer MTIMER register.

__STATIC_FORCEINLINE void SysTimer_SetHartCompareValue (uint64_t value, unsigned long hartid)

Set system timer compare value by hartid.

This function set the system Timer compare value in MTIMERCMP register.

Remark

  • Compare value is 64bits wide.

  • If compare value is larger than current value timer interrupt generate.

  • Modify the load value or compare value less to clear the interrupt.

  • In S-mode, hartid can’t be get by using __get_hart_id function, so this api suits S-mode particularly.

  • SysTimer_GetHartCompareValue

Parameters
  • value[in] compare value to set system timer MTIMERCMP register.

  • hartid[in] hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023.

__STATIC_FORCEINLINE void SysTimer_SetCompareValue (uint64_t value)

Set system timer compare value in machine mode.

This function set the system Timer compare value in MTIMERCMP register.

Remark

  • Compare value is 64bits wide.

  • If compare value is larger than current value timer interrupt generate.

  • Modify the load value or compare value less to clear the interrupt.

  • __get_hart_id function can only be accessed in machine mode, or else exception will occur.

  • SysTimer_GetCompareValue

Parameters

value[in] compare value to set system timer MTIMERCMP register.

__STATIC_FORCEINLINE uint64_t SysTimer_GetHartCompareValue (unsigned long hartid)

Get system timer compare value by hartid.

This function get the system timer compare value in MTIMERCMP register.

Remark

  • Compare value is 64bits wide.

  • In S-mode, hartid can’t be get by using __get_hart_id function, so this api suits S-mode particularly.

  • SysTimer_SetHartCompareValue

Parameters

hartid[in] hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023.

Returns

compare value of system timer MTIMERCMP register.

__STATIC_FORCEINLINE uint64_t SysTimer_GetCompareValue (void)

Get system timer compare value in machine mode.

This function get the system timer compare value in MTIMERCMP register.

Remark

  • Compare value is 64bits wide.

  • SysTimer_SetCompareValue

Returns

compare value of system timer MTIMERCMP register.

__STATIC_FORCEINLINE void SysTimer_Start (void)

Enable system timer counter running.

Enable system timer counter running by clear TIMESTOP bit in MTIMECTL register.

__STATIC_FORCEINLINE void SysTimer_Stop (void)

Stop system timer counter running.

Stop system timer counter running by set TIMESTOP bit in MTIMECTL register.

__STATIC_FORCEINLINE void SysTimer_SetControlValue (uint32_t mctl)

Set system timer control value.

This function set the system timer MTIMECTL register value.

Remark

  • Bit TIMESTOP is used to start and stop timer. Clear TIMESTOP bit to 0 to start timer, otherwise to stop timer.

  • Bit CMPCLREN is used to enable auto MTIMER clear to zero when MTIMER >= MTIMERCMP. Clear CMPCLREN bit to 0 to stop auto clear MTIMER feature, otherwise to enable it.

  • Bit CLKSRC is used to select timer clock source. Clear CLKSRC bit to 0 to use mtime_toggle_a, otherwise use core_clk_aon

  • SysTimer_GetControlValue

Parameters

mctl[in] value to set MTIMECTL register

__STATIC_FORCEINLINE uint32_t SysTimer_GetControlValue (void)

Get system timer control value.

This function get the system timer MTIMECTL register value.

Remark

  • SysTimer_SetControlValue

Returns

MTIMECTL register value

__STATIC_FORCEINLINE void SysTimer_SetHartSWIRQ (unsigned long hartid)

Trigger or set software interrupt via system timer by hartid.

This function set the system timer MSIP bit in MSIP register.

Remark

  • Set system timer MSIP bit and generate a SW interrupt.

  • In S-mode, hartid can’t be get by using __get_hart_id function, so this api suits S-mode particularly.

  • SysTimer_ClearHartSWIRQ

  • SysTimer_GetHartMsipValue

Parameters

hartid[in] hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023.

__STATIC_FORCEINLINE void SysTimer_SetSWIRQ (void)

Trigger or set software interrupt via system timer in machine mode.

This function set the system timer MSIP bit in MSIP register.

Remark

  • Set system timer MSIP bit and generate a SW interrupt.

  • SysTimer_ClearSWIRQ

  • SysTimer_GetMsipValue

__STATIC_FORCEINLINE void SysTimer_ClearHartSWIRQ (unsigned long hartid)

Clear system timer software interrupt pending request by hartid.

This function clear the system timer MSIP bit in MSIP register.

Remark

  • Clear system timer MSIP bit in MSIP register to clear the software interrupt pending.

  • In S-mode, hartid can’t be get by using __get_hart_id function, so this api suits S-mode particularly.

  • SysTimer_SetHartSWIRQ

  • SysTimer_GetHartMsipValue

Parameters

hartid[in] hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023.

__STATIC_FORCEINLINE void SysTimer_ClearSWIRQ (void)

Clear system timer software interrupt pending request in machine mode.

This function clear the system timer MSIP bit in MSIP register.

Remark

  • Clear system timer MSIP bit in MSIP register to clear the software interrupt pending.

  • SysTimer_SetSWIRQ

  • SysTimer_GetMsipValue

__STATIC_FORCEINLINE uint32_t SysTimer_GetHartMsipValue (unsigned long hartid)

Get system timer MSIP register value by hartid.

This function get the system timer MSIP register value.

Remark

  • Bit0 is SW interrupt flag. Bit0 is 1 then SW interrupt set. Bit0 is 0 then SW interrupt clear.

  • In S-mode, hartid can’t be get by using __get_hart_id function, so this api suits S-mode particularly.

  • SysTimer_SetHartSWIRQ

  • SysTimer_ClearHartSWIRQ

  • SysTimer_SetHartMsipValue

Parameters

hartid[in] hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023.

Returns

Value of Timer MSIP register.

__STATIC_FORCEINLINE uint32_t SysTimer_GetMsipValue (void)

Get system timer MSIP register value in machine mode.

This function get the system timer MSIP register value.

Remark

  • Bit0 is SW interrupt flag. Bit0 is 1 then SW interrupt set. Bit0 is 0 then SW interrupt clear.

  • SysTimer_SetSWIRQ

  • SysTimer_ClearSWIRQ

  • SysTimer_SetMsipValue

Returns

Value of Timer MSIP register.

__STATIC_FORCEINLINE void SysTimer_SetHartMsipValue (uint32_t msip, unsigned long hartid)

Set system timer MSIP register value by hartid.

This function set the system timer MSIP register value.

Remark

  • In S-mode, hartid can’t be get using __get_hart_id function, so this api suits S-mode particularly.

  • SysTimer_GetHartMsipValue

Parameters
  • msip[in] value to set MSIP register

  • hartid[in] hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023.

__STATIC_FORCEINLINE void SysTimer_SetMsipValue (uint32_t msip)

Set system timer MSIP register value in machine mode.

This function set the system timer MSIP register value.

Parameters

msip[in] value to set MSIP register

  • SysTimer_GetMsipValue

__STATIC_FORCEINLINE void SysTimer_SoftwareReset (void)

Do software reset request.

This function will do software reset request through MTIMER

  • Software need to write SysTimer_MSFRST_KEY to generate software reset request

  • The software request flag can be cleared by reset operation to clear

    Remark

  • The software reset is sent to SoC, SoC need to generate reset signal and send back to Core

  • This function will not return, it will do while(1) to wait the Core reset happened

__STATIC_FORCEINLINE void SysTimer_SendIPI (unsigned long hartid)

send ipi to target hart using Systimer Clint

This function send ipi using clint timer.

Parameters

hart[in] target hart

__STATIC_FORCEINLINE void SysTimer_ClearIPI (unsigned long hartid)

clear ipi to target hart using Systimer Clint

This function clear ipi using Systimer clint timer.

Parameters

hart[in] target hart

__STATIC_INLINE uint32_t SysTick_Config (uint64_t ticks)

System Tick Configuration.

Initializes the System Timer and its non-vector interrupt, and starts the System Tick Timer.

In our default implementation, the timer counter will be set to zero, and it will start a timer compare non-vector interrupt when it matchs the ticks user set, during the timer interrupt user should reload the system tick using SysTick_Reload function or similar function written by user, so it can produce period timer interrupt.

Remark

  • For __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced, but we assume that the CMPCLREN bit is set to 0, so MTIMER register will not be auto cleared to 0 when MTIMER >= MTIMERCMP.

  • When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included.

  • In this case, the file <Device>.h must contain a vendor-specific implementation of this function.

  • If user need this function to start a period timer interrupt, then in timer interrupt handler routine code, user should call SysTick_Reload with ticks to reload the timer.

  • This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0

See also

  • SysTimer_SetCompareValue; SysTimer_SetLoadValue

Parameters

ticks[in] Number of ticks between two interrupts.

Returns

0 Function succeeded.

Returns

1 Function failed.

__STATIC_INLINE uint32_t SysTick_HartConfig (uint64_t ticks, unsigned long hartid)

System Tick Configuration By hartid.

Initializes the System Timer and its non-vector interrupt, and starts the System Tick Timer.

In our default implementation, the timer counter will be set to zero, and it will start a timer compare non-vector interrupt when it matchs the ticks user set, during the timer interrupt user should reload the system tick using SysTick_Reload function or similar function written by user, so it can produce period timer interrupt.

Remark

  • For __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced, but we assume that the CMPCLREN bit is set to 0, so MTIMER register will not be auto cleared to 0 when MTIMER >= MTIMERCMP.

  • When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Config is not included.

  • In this case, the file <Device>.h must contain a vendor-specific implementation of this function.

  • If user need this function to start a period timer interrupt, then in timer interrupt handler routine code, user should call SysTick_Reload with ticks to reload the timer.

  • This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0

  • In S-mode, hartid can’t be get by using __get_hart_id function, so this api suits S-mode particularly.

See also

  • SysTimer_SetCompareValue; SysTimer_SetLoadValue

Parameters
  • ticks[in] Number of ticks between two interrupts.

  • hartid[in] hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023.

Returns

0 Function succeeded.

Returns

1 Function failed.

__STATIC_FORCEINLINE uint32_t SysTick_Reload (uint64_t ticks)

System Tick Reload.

Reload the System Timer Tick when the MTIMECMP reached TIME value

Remark

  • For __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced, but for this SysTick_Config function, we assume this CMPCLREN bit is set to 0, so in interrupt handler function, user still need to set the MTIMERCMP or MTIMER to reload the system tick, if vendor want to use this timer’s auto clear feature, they can define __Vendor_SysTickConfig to 1, and implement SysTick_Config and SysTick_Reload functions.

  • When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Reload is not included.

  • In this case, the file <Device>.h must contain a vendor-specific implementation of this function.

  • This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0

  • Since the MTIMERCMP value might overflow, if overflowed, MTIMER will be set to 0, and MTIMERCMP set to ticks

See also

  • SysTimer_SetCompareValue

  • SysTimer_SetLoadValue

Parameters

ticks[in] Number of ticks between two interrupts.

Returns

0 Function succeeded.

Returns

1 Function failed.

__STATIC_FORCEINLINE uint32_t SysTick_HartReload (uint64_t ticks, unsigned long hartid)

System Tick Reload.

Reload the System Timer Tick when the MTIMECMP reached TIME value

Remark

  • For __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced, but for this SysTick_Config function, we assume this CMPCLREN bit is set to 0, so in interrupt handler function, user still need to set the MTIMERCMP or MTIMER to reload the system tick, if vendor want to use this timer’s auto clear feature, they can define __Vendor_SysTickConfig to 1, and implement SysTick_Config and SysTick_Reload functions.

  • When the variable __Vendor_SysTickConfig is set to 1, then the function SysTick_Reload is not included.

  • In this case, the file <Device>.h must contain a vendor-specific implementation of this function.

  • This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0

  • Since the MTIMERCMP value might overflow, if overflowed, MTIMER will be set to 0, and MTIMERCMP set to ticks

  • In S-mode, hartid can’t be get by using __get_hart_id function, so this api suits S-mode particularly.

See also

  • SysTimer_SetCompareValue

  • SysTimer_SetLoadValue

Parameters
  • ticks[in] Number of ticks between two interrupts.

  • hartid[in] hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023.

Returns

0 Function succeeded.

Returns

1 Function failed.

SysTick Code Example

The code below shows the usage of the function SysTick_Config() and SysTick_Reload() with an GD32VF103 SoC.

gd32vf103_systick_example.c
 1#include "gd32vf103.h"
 2
 3volatile uint32_t msTicks = 0;                              /* Variable to store millisecond ticks */
 4
 5#define CONFIG_TICKS        (SOC_TIMER_FREQ / 1000)
 6#define SysTick_Handler     eclic_mtip_handler
 7
 8void SysTick_Handler(void) {                                /* SysTick interrupt Handler. */
 9  SysTimer_Reload(CONFIG_TICKS);                            /* Call SysTick_Reload to reload timer. */
10  msTicks++;                                                /* See startup file startup_gd32vf103.S for SysTick vector */
11}
12
13int main (void) {
14  uint32_t returnCode;
15
16  returnCode = SysTick_Config(CONFIG_TICKS);                /* Configure SysTick to generate an interrupt every millisecond */
17
18  if (returnCode != 0) {                                    /* Check return code for errors */
19    // Error Handling
20  }
21
22  while(1);
23}

SysTimer Interrupt Code Example

The code below shows the usage of various NMSIS Timer Interrupt functions with an GD32VF103 device.

gd32vf103_timer_example1.c
 1#include "gd32vf103.h"
 2
 3void eclic_mtip_handler(void)
 4{
 5    uint64_t now =  SysTimer_GetLoadValue();
 6    SysTimer_SetCompareValue(now + SOC_TIMER_FREQ/100);
 7}
 8
 9static uint32_t int_cnt = 0;
10void eclic_msip_handler(void)
11{
12    SysTimer_ClearSWIRQ();
13    int_cnt++;
14}
15
16void eclic_global_initialize(void)
17{
18    ECLIC_SetMth(0);
19    ECLIC_SetCfgNlbits(3);
20}
21
22int eclic_register_interrupt(IRQn_Type IRQn, uint8_t shv, uint32_t trig_mode, uint32 lvl, uint32_t priority, void * handler)
23{
24    ECLIC_SetShvIRQ(IRQn, shv);
25    ECLIC_SetTrigIRQ(IRQn, trig_mode);
26    ECLIC_SetLevelIRQ(IRQn, lvl);
27    ECLIC_SetPriorityIRQ(IRQn, priority);
28    ECLIC_SetVector(IRQn, (rv_csr_t)(handler));
29    ECLIC_EnableIRQ(IRQn);
30    return 0;
31}
32
33void setup_timer(void)
34{
35    SysTimer_SetLoadValue(0);
36    SysTimer_SetCompareValue(SOC_TIMER_FREQ/100);
37}
38
39int main (void)
40{
41    uint32_t returnCode;
42
43    eclic_global_initialize();                                /* initialize ECLIC */
44
45    setup_timer();                                            /* initialize timer */
46
47    returnCode = eclic_register_interrupt(SysTimer_IRQn,1,2,8,0,eclic_mtip_handler);  /* register system timer interrupt */
48
49    returnCode = eclic_register_interrupt(SysTimerSW_IRQn,1,2,8,0,eclic_msip_handler);  /* register system timer SW interrupt */
50
51    __enable_irq();                                           /* enable global interrupt */
52
53    SysTimer_SetSWIRQ();                                      /* trigger timer SW interrupt */
54
55    if (returnCode != 0) {                                    /* Check return code for errors */
56      // Error Handling
57    }
58
59    while(1);
60}