diff --git a/src/avr/timer.c b/src/avr/timer.c index e4d7b942..a7e832bc 100644 --- a/src/avr/timer.c +++ b/src/avr/timer.c @@ -42,6 +42,14 @@ timer_set_clear(uint16_t next) TIFR1 = 1<= 0) { // Next timer is in the near future - wait for time to occur now = timer_get(); @@ -161,13 +169,13 @@ timer_try_set_next(uint32_t target) } return 0; } - - // Too many repeat timers from a single interrupt - force a pause - timer_repeat = TIMER_MAX_NEXT_REPEAT; - next = now + TIMER_DEFER_REPEAT_TICKS; if (diff < (int16_t)(-timer_from_us(1000))) goto fail; + // Too many repeat timers - force a pause so tasks aren't starved + timer_repeat_set(now + TIMER_REPEAT_TICKS); + next = now + TIMER_DEFER_REPEAT_TICKS; + done: timer_set(next); return 1; @@ -175,9 +183,13 @@ fail: shutdown("Rescheduled timer in the past"); } +// Periodic background task that temporarily boosts priority of +// timers. This helps prioritize timers when tasks are idling. static void timer_task(void) { - timer_repeat = TIMER_MAX_REPEAT; + irq_disable(); + timer_repeat_set(timer_get() + TIMER_IDLE_REPEAT_TICKS); + irq_enable(); } DECL_TASK(timer_task);