diff --git a/drivers/timer/nrf_rtc_timer.c b/drivers/timer/nrf_rtc_timer.c index 2e1688a23cb..ba8dad9ebe7 100644 --- a/drivers/timer/nrf_rtc_timer.c +++ b/drivers/timer/nrf_rtc_timer.c @@ -19,6 +19,7 @@ #define CYC_PER_TICK (sys_clock_hw_cycles_per_sec() \ / CONFIG_SYS_CLOCK_TICKS_PER_SEC) #define MAX_TICKS ((COUNTER_MAX - CYC_PER_TICK) / CYC_PER_TICK) +#define MAX_CYCLES (MAX_TICKS * CYC_PER_TICK) static struct k_spinlock lock; @@ -121,10 +122,20 @@ void z_clock_set_timeout(s32_t ticks, bool idle) u32_t cyc, dt, t = counter(); bool zli_fixup = IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS); - /* Round up to next tick boundary */ + /* Get the cycles from last_count to the tick boundary after + * the requested ticks have passed starting now. + */ cyc = ticks * CYC_PER_TICK + 1 + counter_sub(t, last_count); cyc += (CYC_PER_TICK - 1); cyc = (cyc / CYC_PER_TICK) * CYC_PER_TICK; + + /* Due to elapsed time the calculation above might produce a + * duration that laps the counter. Don't let it. + */ + if (cyc > MAX_CYCLES) { + cyc = MAX_CYCLES; + } + cyc += last_count; /* Per NRF docs, the RTC is guaranteed to trigger a compare