diff --git a/drivers/timer/cortex_m_systick.c b/drivers/timer/cortex_m_systick.c index 9a415524e0..abd60f5ad7 100644 --- a/drivers/timer/cortex_m_systick.c +++ b/drivers/timer/cortex_m_systick.c @@ -368,7 +368,7 @@ void sys_clock_idle_exit(void) if (timeout_idle) { cycle_t cycle_post_idle, systick_diff, missed_cycles; uint32_t idle_timer_diff, idle_timer_post, dcycles, dticks; - uint64_t systick_us, idle_timer_us, measurement_diff_us; + uint64_t systick_us, idle_timer_us; /* Get current values for both timers */ counter_get_value(idle_timer, &idle_timer_post); @@ -402,9 +402,20 @@ void sys_clock_idle_exit(void) /* Calculate difference in measurements to get how much time * the SysTick missed in idle state. */ - measurement_diff_us = idle_timer_us - systick_us; - missed_cycles = - (sys_clock_hw_cycles_per_sec() * measurement_diff_us) / USEC_PER_SEC; + if (idle_timer_us < systick_us) { + /* This case is possible, when the time in low power mode is + * very short or 0. SysTick usually has higher measurement + * resolution of than the IDLE timer, thus the measurement of + * passed time since the sys_clock_set_timeout call can be higher. + */ + missed_cycles = 0; + } else { + uint64_t measurement_diff_us; + + measurement_diff_us = idle_timer_us - systick_us; + missed_cycles = (sys_clock_hw_cycles_per_sec() * measurement_diff_us) / + USEC_PER_SEC; + } /* Update the cycle counter to include the cycles missed in idle */ cycle_count += missed_cycles;