Skip to content

Commit 5b751e8

Browse files
authored
Merge pull request #7599 from c1728p9/double_low_power_ticker_interrupt
Fix double low power ticker interrupt
2 parents f15dbf2 + c36b58a commit 5b751e8

File tree

1 file changed

+9
-12
lines changed

1 file changed

+9
-12
lines changed

hal/mbed_ticker_api.c

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,9 @@ static void update_present_time(const ticker_data_t *const ticker)
165165
}
166166

167167
/**
168-
* Given the absolute timestamp compute the hal tick timestamp.
168+
* Given the absolute timestamp compute the hal tick timestamp rounded up.
169169
*/
170-
static timestamp_t compute_tick(const ticker_data_t *const ticker, us_timestamp_t timestamp)
170+
static timestamp_t compute_tick_round_up(const ticker_data_t *const ticker, us_timestamp_t timestamp)
171171
{
172172
ticker_event_queue_t *queue = ticker->queue;
173173
us_timestamp_t delta_us = timestamp - queue->present_time;
@@ -186,14 +186,14 @@ static timestamp_t compute_tick(const ticker_data_t *const ticker, us_timestamp_
186186
} else if (0 != queue->frequency_shifts) {
187187
// Optimized frequencies divisible by 2
188188

189-
delta = (delta_us << ticker->queue->frequency_shifts) / 1000000;
189+
delta = ((delta_us << ticker->queue->frequency_shifts) + 1000000 - 1) / 1000000;
190190
if (delta > ticker->queue->max_delta) {
191191
delta = ticker->queue->max_delta;
192192
}
193193
} else {
194194
// General case
195195

196-
delta = delta_us * queue->frequency / 1000000;
196+
delta = (delta_us * queue->frequency + 1000000 - 1) / 1000000;
197197
if (delta > ticker->queue->max_delta) {
198198
delta = ticker->queue->max_delta;
199199
}
@@ -249,14 +249,11 @@ static void schedule_interrupt(const ticker_data_t *const ticker)
249249
return;
250250
}
251251

252-
timestamp_t match_tick = compute_tick(ticker, match_time);
253-
// The time has been checked to be future, but it could still round
254-
// to the last tick as a result of us to ticks conversion
255-
if (match_tick == queue->tick_last_read) {
256-
// Match time has already expired so fire immediately
257-
ticker->interface->fire_interrupt();
258-
return;
259-
}
252+
timestamp_t match_tick = compute_tick_round_up(ticker, match_time);
253+
254+
// The same tick should never occur since match_tick is rounded up.
255+
// If the same tick is returned scheduling will not work correctly.
256+
MBED_ASSERT(match_tick != queue->tick_last_read);
260257

261258
ticker->interface->set_interrupt(match_tick);
262259
timestamp_t cur_tick = ticker->interface->read();

0 commit comments

Comments
 (0)