diff options
-rw-r--r-- | src/avr/timer.c | 32 | ||||
-rw-r--r-- | src/generic/misc.h | 1 | ||||
-rw-r--r-- | src/generic/timer_irq.c | 6 | ||||
-rw-r--r-- | src/sched.c | 13 | ||||
-rw-r--r-- | src/simulator/main.c | 5 |
5 files changed, 31 insertions, 26 deletions
diff --git a/src/avr/timer.c b/src/avr/timer.c index a87ae206..1b281ec9 100644 --- a/src/avr/timer.c +++ b/src/avr/timer.c @@ -85,6 +85,15 @@ timer_kick(void) TIFR1 = 1<<OCF1A; } +static struct timer wrap_timer; + +void +timer_reset(void) +{ + sched_add_timer(&wrap_timer); +} +DECL_SHUTDOWN(timer_reset); + void timer_init(void) { @@ -96,6 +105,7 @@ timer_init(void) irqstatus_t flag = irq_save(); timer_kick(); timer_repeat_set(timer_get() + 50); + timer_reset(); TIFR1 = 1<<TOV1; // enable interrupt TIMSK1 = 1<<OCIE1A; @@ -115,25 +125,33 @@ uint32_t timer_read_time(void) { irqstatus_t flag = irq_save(); - union u32_u calc; - calc.val = timer_get(); + union u32_u calc = { .val = timer_get() }; calc.hi = timer_high; - if (TIFR1 & (1<<TOV1) && calc.lo < 0x8000) - calc.hi++; + if (unlikely(TIFR1 & (1<<TOV1))) { + irq_restore(flag); + if (calc.b1 < 0xff) + calc.hi++; + return calc.val; + } irq_restore(flag); return calc.val; } -// Called by main code once every millisecond. (IRQs disabled.) -void -timer_periodic(void) +// Timer that runs every ~2ms - allows 16bit comparison optimizations +static uint_fast8_t +timer_event(struct timer *t) { if (TIFR1 & (1<<TOV1)) { // Hardware timer has overflowed - update overflow counter TIFR1 = 1<<TOV1; timer_high++; } + wrap_timer.waketime += 0x8000; + return SF_RESCHEDULE; } +static struct timer wrap_timer = { + .func = timer_event, +}; #define TIMER_IDLE_REPEAT_TICKS 8000 #define TIMER_REPEAT_TICKS 3000 diff --git a/src/generic/misc.h b/src/generic/misc.h index f0f8e5a5..65861207 100644 --- a/src/generic/misc.h +++ b/src/generic/misc.h @@ -12,7 +12,6 @@ uint32_t timer_from_us(uint32_t us); uint8_t timer_is_before(uint32_t time1, uint32_t time2); uint32_t timer_read_time(void); void timer_kick(void); -void timer_periodic(void); void *dynmem_start(void); void *dynmem_end(void); diff --git a/src/generic/timer_irq.c b/src/generic/timer_irq.c index 127601e2..605fc129 100644 --- a/src/generic/timer_irq.c +++ b/src/generic/timer_irq.c @@ -30,12 +30,6 @@ timer_is_before(uint32_t time1, uint32_t time2) return (int32_t)(time1 - time2) < 0; } -// Called by main code once every millisecond. (IRQs disabled.) -void -timer_periodic(void) -{ -} - static uint32_t timer_repeat_until; #define TIMER_IDLE_REPEAT_TICKS timer_from_us(500) #define TIMER_REPEAT_TICKS timer_from_us(100) diff --git a/src/sched.c b/src/sched.c index 92fc5504..0aadcc75 100644 --- a/src/sched.c +++ b/src/sched.c @@ -24,12 +24,11 @@ static struct timer sentinel_timer, deleted_timer; // The periodic_timer simplifies the timer code by ensuring there is // always a timer on the timer list and that there is always a timer -// not more than 1ms in the future. +// not far in the future. static uint_fast8_t periodic_event(struct timer *t) { - timer_periodic(); - periodic_timer.waketime += timer_from_us(1000); + periodic_timer.waketime += timer_from_us(100000); sentinel_timer.waketime = periodic_timer.waketime + 0x80000000; return SF_RESCHEDULE; } @@ -162,9 +161,9 @@ sched_timer_dispatch(void) return next_waketime; } -// Shutdown all user timers on an emergency stop. -void -sched_timer_shutdown(void) +// Remove all user timers on a shutdown +static void +sched_timer_reset(void) { timer_list = &deleted_timer; deleted_timer.waketime = periodic_timer.waketime; @@ -172,7 +171,6 @@ sched_timer_shutdown(void) periodic_timer.next = &sentinel_timer; timer_kick(); } -DECL_SHUTDOWN(sched_timer_shutdown); /**************************************************************** @@ -230,6 +228,7 @@ run_shutdown(int reason) if (!shutdown_status) shutdown_reason = reason; shutdown_status = 2; + sched_timer_reset(); extern void ctr_run_shutdownfuncs(void); ctr_run_shutdownfuncs(); shutdown_status = 1; diff --git a/src/simulator/main.c b/src/simulator/main.c index 7519a35b..e0384611 100644 --- a/src/simulator/main.c +++ b/src/simulator/main.c @@ -85,11 +85,6 @@ timer_kick(void) { } -void -timer_periodic(void) -{ -} - /**************************************************************** * Turn stdin/stdout into serial console |