@@ -150,11 +150,14 @@ static inline app_timer_running_count_t _ticks_until_expiry(app_timer_running_co
150
150
* list is maintained (the next timer to expire must always be the head of the list).
151
151
*
152
152
* @note The #start_counts and #total_counts fields of the timer must be set before calling
153
- * this function
153
+ * this function. #start_counts should be set to the timestamp in counts when the timer
154
+ * was added via #app_timer_start, and #total_counts should be set to the timer period
155
+ * in counts.
154
156
*
155
157
* @param timer Pointer to timer instance to insert
158
+ * @param now Current timestamp in timer counts
156
159
*/
157
- static void _insert_active_timer (app_timer_t * timer )
160
+ static void _insert_active_timer (app_timer_t * timer , app_timer_running_count_t now )
158
161
{
159
162
// Set timer state to active
160
163
timer -> flags &= ~FLAGS_STATE_MASK ;
@@ -177,9 +180,6 @@ static void _insert_active_timer(app_timer_t *timer)
177
180
return ;
178
181
}
179
182
180
- // timer->start_counts is assumed to be set to the current timestamp
181
- app_timer_running_count_t now = timer -> start_counts ;
182
-
183
183
app_timer_t * curr = _active_timers .head ;
184
184
185
185
/* Pending timers are maintained as a doubly-linked list, in ascending order
@@ -313,8 +313,15 @@ void app_timer_target_count_reached(void)
313
313
app_timer_int_status_t int_status = 0u ;
314
314
_hw_model -> set_interrupts_enabled (false, & int_status );
315
315
316
+ // The tick on which the head active timer should have expired
317
+ app_timer_running_count_t expiry_count = _running_timer_count + _last_timer_period ;
318
+
319
+ // Update _running_timer_count with ticks elapsed since last update
320
+ #ifdef APP_TIMER_FREERUNNING_COUNTER
321
+ _running_timer_count += (_hw_model -> read_timer_counts () - _counts_after_last_start );
322
+ #else
316
323
_running_timer_count += (app_timer_running_count_t ) _last_timer_period ;
317
- app_timer_running_count_t now = _running_timer_count ;
324
+ #endif // APP_TIMER_FREERUNNING_COUNTER
318
325
319
326
// Stop the timer counter, re-start it to time how long it takes to handle all expired timers
320
327
#ifndef APP_TIMER_RECONFIG_WITHOUT_STOPPING
@@ -327,7 +334,7 @@ void app_timer_target_count_reached(void)
327
334
_counts_after_last_start = _hw_model -> read_timer_counts ();
328
335
329
336
// Remove all expired timers from the active list, and run their handlers
330
- while ((NULL != _active_timers .head ) && (_ticks_until_expiry (now , _active_timers .head ) == 0u ))
337
+ while ((NULL != _active_timers .head ) && (_ticks_until_expiry (expiry_count , _active_timers .head ) == 0u ))
331
338
{
332
339
app_timer_t * curr = _active_timers .head ;
333
340
@@ -367,38 +374,35 @@ void app_timer_target_count_reached(void)
367
374
{
368
375
/* Timer is repeating, and was not-restarted or stopped by the handler,
369
376
* so must be re-inserted with a new start time */
370
- curr -> start_counts = now ;
371
- _insert_active_timer (curr );
377
+ curr -> start_counts = expiry_count ;
378
+ _insert_active_timer (curr , _total_timer_counts () );
372
379
}
373
380
}
374
381
375
- // Update running timer count with time taken to run expired handlers
376
- _running_timer_count += (_hw_model -> read_timer_counts () - _counts_after_last_start );
377
- now = _running_timer_count ;
378
- #ifndef APP_TIMER_RECONFIG_WITHOUT_STOPPING
379
- _hw_model -> set_timer_running (false);
380
- #endif // APP_TIMER_RECONFIG_WITHOUT_STOPPING
381
-
382
382
if (NULL == _active_timers .head )
383
383
{
384
- // No more active timers, don't re-start the counter
384
+ // No more active timers, stop the counter
385
385
_running_timer_count = 0u ;
386
- #ifdef APP_TIMER_RECONFIG_WITHOUT_STOPPING
387
- /* If we didn't already stop the counter to set a new timer period,
388
- * and there are no more active timers, then we should stop the counter now */
389
386
_hw_model -> set_timer_running (false);
390
- #endif // APP_TIMER_RECONFIG_WITHOUT_STOPPING
391
387
}
392
388
else
393
389
{
390
+ // Update running timer count with time taken to run expired handlers
391
+ _running_timer_count += (_hw_model -> read_timer_counts () - _counts_after_last_start );
392
+
394
393
// Configure timer for the next expiration and re-start
395
- app_timer_running_count_t ticks_until_expiry = _ticks_until_expiry (now , _active_timers .head );
394
+ app_timer_running_count_t ticks_until_expiry = _ticks_until_expiry (_running_timer_count , _active_timers .head );
396
395
397
396
/* If the head timer should have already expired (it expired while we were handling
398
397
* other expired timers in the loop above), just configure the hardware for 1 tick,
399
398
* and the head timer will be handled in the next call (although it does have the downside
400
399
* that the head timer will expire at least 1 tick late) */
401
400
bool expiry_overflow = (ticks_until_expiry == 0u );
401
+
402
+ #ifndef APP_TIMER_RECONFIG_WITHOUT_STOPPING
403
+ _hw_model -> set_timer_running (false);
404
+ #endif // APP_TIMER_RECONFIG_WITHOUT_STOPPING
405
+
402
406
_configure_timer (expiry_overflow ? 1u : ticks_until_expiry );
403
407
#ifdef APP_TIMER_STATS_ENABLE
404
408
_stats .num_expiry_overflows += (uint32_t ) expiry_overflow ;
@@ -509,7 +513,7 @@ app_timer_error_e app_timer_start(app_timer_t *timer, app_timer_period_t time_fr
509
513
}
510
514
511
515
// Insert timer into list
512
- _insert_active_timer (timer );
516
+ _insert_active_timer (timer , timer -> start_counts );
513
517
514
518
/* If this is the new head of the list, we need to re-configure the hardware timer/counter */
515
519
if ((timer == _active_timers .head ) && !_inside_target_count_reached )
0 commit comments