diff --git a/firmware/lib/timer/device/atmega32u4.c b/firmware/lib/timer/device/atmega32u4.c index 5a91d68..75eaf77 100644 --- a/firmware/lib/timer/device/atmega32u4.c +++ b/firmware/lib/timer/device/atmega32u4.c @@ -29,10 +29,13 @@ static volatile uint16_t _milliseconds__counter; static list__list_t * _milliseconds__scheduled_events = &(list__list_t){}; +// since we won't be running scheduled events every "tick" +static uint8_t _milliseconds__last_ticked; + // ---------------------------------------------------------------------------- uint8_t timer__init(void) { - OCR0A = 250; // (ticks per millisecond) + OCR0A = 250; // (ticks per millisecond (hardware timer)) TCCR0A = 0b00000010; // (configure Timer/Counter 0) TCCR0B = 0b00000011; // (configure Timer/Counter 0) @@ -46,18 +49,23 @@ uint16_t timer__get_milliseconds(void) { } uint8_t timer__schedule_milliseconds(uint16_t ticks, void(*function)(void)) { + uint8_t elapsed = timer__get_milliseconds() - _milliseconds__last_ticked; + + // - use `ticks+elapsed` to compensate for ticks that haven't been counted + // yet, but should have (if we were ticking in real time) return event_list__append( - _milliseconds__scheduled_events, ticks, function ); + _milliseconds__scheduled_events, ticks+elapsed, function ); } void timer___tick_milliseconds(void) { - static uint8_t _milliseconds__last_ticked; uint8_t elapsed = timer__get_milliseconds() - _milliseconds__last_ticked; + // - update before ticking: if an event reschedules itself to run in 1 + // tick, it should execute on the next tick without having to wait + _milliseconds__last_ticked += elapsed; + for (uint8_t i=0; i