Skip to content

Commit e59f312

Browse files
committed
lp ticker - fix until methods - time is in period addition
We should check if now and until are valid compare to the current time. It can happen that real_now is far in the future, we should not sleep or set interrupt, just return. K64F is using deltas for setting the interrupt, we should use real_now delta = time - real_now
1 parent 49ddebe commit e59f312

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

source/lp_ticker.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,23 @@ uint32_t lp_ticker_get_compare_match(void)
150150
return lp_compare_value;
151151
}
152152

153-
void lp_ticker_set_interrupt(uint32_t now, uint32_t time) {
153+
static bool time_is_in_period(uint32_t start, uint32_t time, uint32_t end)
154+
{
155+
if((time >= start && (time < end || start >= end)) ||
156+
(time < start && end < start && end > time)) {
157+
return true;
158+
}
159+
return false;
160+
}
161+
162+
// now is the checked-current counter value, which we use to calculate delta
163+
static void lp_ticker_set_interrupt_internal(uint32_t now, uint32_t time)
164+
{
154165
// On K64F, the compare value can be only set when the LPTMR is disabled
155166
// However, disabling the LPTMR will automatically clear the LPTMR counter
156167
// So we need to compensate for the time that already passed
157168
lp_compare_value = time;
169+
158170
uint32_t ticks = time > now ? time - now : (uint32_t)((uint64_t)time + 0xFFFFFFFFu - now);
159171
lp_lptmr_schedule_ticks = 0;
160172
lp_ticker_lptmr_scheduled_flag = 0;
@@ -180,9 +192,22 @@ void lp_ticker_set_interrupt(uint32_t now, uint32_t time) {
180192
RTC_HAL_EnableCounter(RTC_BASE, true);
181193
}
182194

195+
void lp_ticker_set_interrupt(uint32_t now, uint32_t time) {
196+
// use the latest real time
197+
uint32_t real_now = lp_ticker_read();
198+
if (!time_is_in_period(now, real_now, time)) {
199+
return;
200+
}
201+
lp_ticker_set_interrupt_internal(real_now, time);
202+
}
203+
183204
void lp_ticker_sleep_until(uint32_t now, uint32_t time)
184205
{
185-
lp_ticker_set_interrupt(now, time);
206+
uint32_t real_now = lp_ticker_read();
207+
if (!time_is_in_period(now, real_now, time)) {
208+
return;
209+
}
210+
lp_ticker_set_interrupt_internal(real_now, time);
186211
sleep_t sleep_obj;
187212
mbed_enter_sleep(&sleep_obj);
188213
// if LPTMR is running and we scheduled it, we know that RTC was fired while

0 commit comments

Comments
 (0)