Level 1
Level 1

# SysTick for timing measurement

Hello everyone,

I am currently studying the effect of different reload intervals on the SysTick Timer running at different frequencies using interrupts. The code is very basic and simple, estimating the time to execute  CyDelay(1000) on the CM0+ and CM4. Ideally the output value should be (1000 ms +/- clock accuracy  of 1%) but I am seeing a deviation of approx. -ve 7.15% in the result (928-929) for both CM0+ and CM4 running at 100KHz with reload interval of '10'. This means I read the time values in 100microsecond steps.  I have also tested the code with multiple delay values (50,250,500,2000,etc), the result however is still a negative deviation. eg.) a delay of 1000ms is executed in 929ms which is weird.

The deviation increases to approx -45% when the reload interval is changed to '1' with the same clock frequency of 100KHz.

Can't seem to figure out what exactly is wrong with these specific configurations of clock and reload interval that it is giving erroneous result.

1 Solution
Employee
Employee

# Re: SysTick for timing measurement

A proper timing measurement scheme shouldn't add too much overhead in your system. In your case, you are basically generating an interrupt on every 1 ms.

A better way is to obtain the current system stick time, then add to a counter, where the counter is incremented, let's say every 1 second or when the SystTick timeouts.

Here is an example how to implement the SysTick handler and a function to read it.

``````void systick_callback(void)
{
systick_ov++;
}

uint32_t get_tick()
{
return ((0xFFFFFF - Cy_SysTick_GetValue()) + (systick_ov * 0x1000000));
}``````

In this case, it only increments the systick_ov when the SysTick timeouts, which has a 24-bit counter.

The example will be the least invasive scheme (less interrupt handling overhead).

4 Replies
Moderator
Moderator

# Re: SysTick for timing measurement

I went through the attached documents and your code. I am presently not certain if we can use an external clock as you have used a CLOCK, TIMER as Systick source. However, I will confirm on that with some workaround and get back to you. As you can find CAT2 Peripheral Driver Library: Functions  , the clock sources for Cy_SysTick_Init() are as below -

 CY_SYSTICK_CLOCK_SOURCE_CLK_LF The low frequency clock clk_lf is selected. CY_SYSTICK_CLOCK_SOURCE_CLK_CPU The System clock is selected.

Also, we have a similar code example Systick_example for PSoC 4 which uses the similar APIs and the implementation is also similar. In this code example, the onboard blue LED should toggle each second and the red LED should toggle each minute. HyperTerminal displays the current system time since startup in format MM:SS . Hence, here you can see the seconds value changing in the terminal every second. I will check for the precision of internal system clocks that could be used and get back to you.

Please go through above or add in case of any further query.

Best Regards,

Aashita

Level 1
Level 1

# Re: SysTick for timing measurement

Hello Aashita,

The attached code runs perfectly for other combinations of Timer and CPU frequencies(used as SysTick clock) and reload values.

e.g. 100KHz (Timer) with 100 as reload value or 100MHz (CPU) with reload value 100000

As mentioned earlier, its just these specific configurations of clock frequency, reload value (table below)  that are giving me weird values.

Regards,

Maitriya

 Clock Frequency Reload Value Deviation Observed 100KHz (Timer) 10 approx. -6.7% 100KHz (Timer) 1 approx. -45.6%
Level 1
Level 1

# Re: SysTick for timing measurement

Hello Aashita,

Just to follow up on the problem I am facing with the SysTick timer, were you able to find something that could possibly help me with my issue ?

As previously mentioned, the issue only occurs for certain sets of clock frequency and reload value for both CM0p and CM4.

Regards,

Maitriya

Employee
Employee

# Re: SysTick for timing measurement

A proper timing measurement scheme shouldn't add too much overhead in your system. In your case, you are basically generating an interrupt on every 1 ms.

A better way is to obtain the current system stick time, then add to a counter, where the counter is incremented, let's say every 1 second or when the SystTick timeouts.

Here is an example how to implement the SysTick handler and a function to read it.

``````void systick_callback(void)
{
systick_ov++;
}

uint32_t get_tick()
{
return ((0xFFFFFF - Cy_SysTick_GetValue()) + (systick_ov * 0x1000000));
}``````

In this case, it only increments the systick_ov when the SysTick timeouts, which has a 24-bit counter.

The example will be the least invasive scheme (less interrupt handling overhead).