diff options
-rw-r--r-- | src/avr/timer.c | 9 | ||||
-rw-r--r-- | src/basecmd.c | 8 | ||||
-rw-r--r-- | src/generic/misc.h | 3 | ||||
-rw-r--r-- | src/generic/timer.c | 11 | ||||
-rw-r--r-- | src/gpiocmds.c | 7 | ||||
-rw-r--r-- | src/sched.c | 37 | ||||
-rw-r--r-- | src/sched.h | 3 | ||||
-rw-r--r-- | src/simulator/main.c | 6 | ||||
-rw-r--r-- | src/stepper.c | 11 |
9 files changed, 48 insertions, 47 deletions
diff --git a/src/avr/timer.c b/src/avr/timer.c index 7b5facca..e96b88bf 100644 --- a/src/avr/timer.c +++ b/src/avr/timer.c @@ -25,6 +25,15 @@ timer_from_us(uint32_t us) return us * (F_CPU / 1000000); } +// Return true if time1 is before time2. Always use this function to +// compare times as regular C comparisons can fail if the counter +// rolls over. +uint8_t +timer_is_before(uint32_t time1, uint32_t time2) +{ + return (int32_t)(time1 - time2) < 0; +} + static inline uint16_t timer_get(void) { diff --git a/src/basecmd.c b/src/basecmd.c index 8049e376..5a4dc853 100644 --- a/src/basecmd.c +++ b/src/basecmd.c @@ -228,7 +228,7 @@ DECL_COMMAND(command_end_group, "end_group"); void command_get_status(uint32_t *args) { - sendf("status clock=%u status=%c", sched_read_time(), sched_is_shutdown()); + sendf("status clock=%u status=%c", timer_read_time(), sched_is_shutdown()); } DECL_COMMAND_FLAGS(command_get_status, HF_IN_SHUTDOWN, "get_status"); @@ -237,7 +237,7 @@ static uint32_t stats_send_time, stats_send_time_high; void command_get_uptime(uint32_t *args) { - uint32_t cur = sched_read_time(); + uint32_t cur = timer_read_time(); uint32_t high = stats_send_time_high + (cur < stats_send_time); sendf("uptime high=%u clock=%u", high, cur); } @@ -250,7 +250,7 @@ static void stats_task(void) { static uint32_t last, count, sumsq; - uint32_t cur = sched_read_time(); + uint32_t cur = timer_read_time(); uint32_t diff = cur - last; last = cur; count++; @@ -267,7 +267,7 @@ stats_task(void) nextsumsq = 0xffffffff; sumsq = nextsumsq; - if (sched_is_before(cur, stats_send_time + sched_from_us(5000000))) + if (timer_is_before(cur, stats_send_time + timer_from_us(5000000))) return; sendf("stats count=%u sum=%u sumsq=%u", count, cur - stats_send_time, sumsq); if (cur < stats_send_time) diff --git a/src/generic/misc.h b/src/generic/misc.h index 92d4d145..b6d49ffd 100644 --- a/src/generic/misc.h +++ b/src/generic/misc.h @@ -10,8 +10,9 @@ char *console_get_output(uint8_t len); void console_push_output(uint8_t len); uint32_t timer_from_us(uint32_t us); -void timer_periodic(void); +uint8_t timer_is_before(uint32_t time1, uint32_t time2); uint32_t timer_read_time(void); +void timer_periodic(void); uint8_t timer_try_set_next(uint32_t next); size_t alloc_maxsize(size_t reqsize); diff --git a/src/generic/timer.c b/src/generic/timer.c index 13a8bfe5..436ecb68 100644 --- a/src/generic/timer.c +++ b/src/generic/timer.c @@ -24,6 +24,15 @@ timer_from_us(uint32_t us) return us * (CONFIG_CLOCK_FREQ / 1000000); } +// Return true if time1 is before time2. Always use this function to +// compare times as regular C comparisons can fail if the counter +// rolls over. +uint8_t +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) @@ -50,7 +59,7 @@ timer_try_set_next(uint32_t next) goto done; // Next timer is in the past or near future - can't reschedule to it - if (likely(sched_is_before(now, timer_repeat_until))) { + if (likely(timer_is_before(now, timer_repeat_until))) { // Can run more timers from this irq; briefly allow irqs irq_enable(); while (diff >= 0) { diff --git a/src/gpiocmds.c b/src/gpiocmds.c index e3351b44..6dd29059 100644 --- a/src/gpiocmds.c +++ b/src/gpiocmds.c @@ -7,6 +7,7 @@ #include "basecmd.h" // oid_alloc #include "board/gpio.h" // struct gpio_out #include "board/irq.h" // irq_disable +#include "board/misc.h" // timer_is_before #include "command.h" // DECL_COMMAND #include "sched.h" // sched_add_timer @@ -117,7 +118,7 @@ soft_pwm_toggle_event(struct timer *timer) waketime += s->on_duration; else waketime += s->off_duration; - if (s->flags & SPF_CHECK_END && !sched_is_before(waketime, s->end_time)) { + if (s->flags & SPF_CHECK_END && !timer_is_before(waketime, s->end_time)) { // End of normal pulsing - next event loads new pwm settings s->timer.func = soft_pwm_load_event; waketime = s->end_time; @@ -189,13 +190,13 @@ command_schedule_soft_pwm_out(uint32_t *args) next_flags |= SPF_NEXT_CHECK_END; } irq_disable(); - if (s->flags & SPF_CHECK_END && sched_is_before(s->end_time, time)) + if (s->flags & SPF_CHECK_END && timer_is_before(s->end_time, time)) shutdown("next soft pwm extends existing pwm"); s->end_time = time; s->next_on_duration = next_on_duration; s->next_off_duration = next_off_duration; s->flags |= next_flags; - if (s->flags & SPF_TOGGLING && sched_is_before(s->timer.waketime, time)) { + if (s->flags & SPF_TOGGLING && timer_is_before(s->timer.waketime, time)) { // soft_pwm_toggle_event() will schedule a load event when ready } else { // Schedule the loading of the pwm parameters at the requested time diff --git a/src/sched.c b/src/sched.c index 8578b2a7..7a68db86 100644 --- a/src/sched.c +++ b/src/sched.c @@ -9,7 +9,7 @@ #include "board/irq.h" // irq_save #include "board/misc.h" // timer_from_us #include "command.h" // shutdown -#include "sched.h" // sched_from_us +#include "sched.h" // sched_check_periodic #include "stepper.h" // stepper_event @@ -17,29 +17,6 @@ * Timers ****************************************************************/ -// Return the number of clock ticks for a given number of microseconds -uint32_t -sched_from_us(uint32_t us) -{ - return timer_from_us(us); -} - -// Return the current time (in clock ticks) -uint32_t -sched_read_time(void) -{ - return timer_read_time(); -} - -// Return true if time1 is before time2. Always use this function to -// compare times as regular C comparisons can fail if the counter -// rolls over. -uint8_t -sched_is_before(uint32_t time1, uint32_t time2) -{ - return (int32_t)(time1 - time2) < 0; -} - static uint16_t millis; // Check if ready for a recurring periodic event @@ -67,7 +44,7 @@ ms_event(struct timer *t) { millis++; timer_periodic(); - ms_timer.waketime += sched_from_us(1000); + ms_timer.waketime += timer_from_us(1000); sentinel_timer.waketime = ms_timer.waketime + 0x80000000; return SF_RESCHEDULE; } @@ -99,12 +76,12 @@ sched_add_timer(struct timer *add) { uint32_t waketime = add->waketime; irqstatus_t flag = irq_save(); - if (sched_is_before(waketime, timer_list->waketime)) + if (timer_is_before(waketime, timer_list->waketime)) // Timer in past (or very near future) shutdown("Timer too close"); // Find position in list and insert struct timer *pos = timer_list; - while (!sched_is_before(waketime, pos->next->waketime)) + while (!timer_is_before(waketime, pos->next->waketime)) pos = pos->next; add->next = pos->next; pos->next = add; @@ -152,7 +129,7 @@ reschedule_timer(struct timer *t) { struct timer *pos = t->next; uint32_t minwaketime = t->waketime + 1; - if (!sched_is_before(pos->waketime, minwaketime)) + if (!timer_is_before(pos->waketime, minwaketime)) // Timer is still the first - no insertion needed return t; @@ -165,7 +142,7 @@ reschedule_timer(struct timer *t) // micro optimization for AVR - reduces register pressure asm("" : "+r"(prev) : : "memory"); pos = pos->next; - if (!sched_is_before(pos->waketime, minwaketime)) + if (!timer_is_before(pos->waketime, minwaketime)) break; } t->next = pos; @@ -247,7 +224,7 @@ sched_clear_shutdown(void) static void run_shutdown(void) { - uint32_t cur = sched_read_time(); + uint32_t cur = timer_read_time(); shutdown_status = 2; struct callback_handler *p; foreachdecl(p, shutdownfuncs) { diff --git a/src/sched.h b/src/sched.h index 0c1820c3..7a98257a 100644 --- a/src/sched.h +++ b/src/sched.h @@ -23,9 +23,6 @@ enum { SF_DONE=0, SF_RESCHEDULE=1 }; // sched.c uint8_t sched_check_periodic(uint16_t time, uint16_t *pnext); -uint32_t sched_from_us(uint32_t us); -uint32_t sched_read_time(void); -uint8_t sched_is_before(uint32_t time1, uint32_t time2); void sched_add_timer(struct timer*); void sched_del_timer(struct timer *del); void sched_timer_kick(void); diff --git a/src/simulator/main.c b/src/simulator/main.c index f45b5c45..4f715ab2 100644 --- a/src/simulator/main.c +++ b/src/simulator/main.c @@ -58,6 +58,12 @@ timer_from_us(uint32_t us) return 0; // XXX } +uint8_t +timer_is_before(uint32_t time1, uint32_t time2) +{ + return (int32_t)(time1 - time2) < 0; +} + void timer_periodic(void) { diff --git a/src/stepper.c b/src/stepper.c index 0d7f490b..c1bdf275 100644 --- a/src/stepper.c +++ b/src/stepper.c @@ -8,6 +8,7 @@ #include "basecmd.h" // oid_alloc #include "board/gpio.h" // gpio_out_write #include "board/irq.h" // irq_disable +#include "board/misc.h" // timer_is_before #include "command.h" // DECL_COMMAND #include "sched.h" // struct timer #include "stepper.h" // command_config_stepper @@ -75,9 +76,9 @@ stepper_load_next(struct stepper *s, uint32_t min_next_time) // On faster mcus, it is necessary to schedule unstep events // and so there are twice as many events. Also check that the // next step event isn't too close to the last unstep. - if (unlikely(sched_is_before(s->next_step_time, min_next_time))) { + if (unlikely(timer_is_before(s->next_step_time, min_next_time))) { if ((int32_t)(s->next_step_time - min_next_time) - < (int32_t)(-sched_from_us(1000))) + < (int32_t)(-timer_from_us(1000))) shutdown("stepper too far in past"); s->time.waketime = min_next_time; } else { @@ -97,7 +98,7 @@ stepper_load_next(struct stepper *s, uint32_t min_next_time) return SF_RESCHEDULE; } -#define UNSTEP_TIME sched_from_us(1) +#define UNSTEP_TIME timer_from_us(1) // Timer callback - step the given stepper. uint_fast8_t @@ -123,7 +124,7 @@ stepper_event(struct timer *t) } // On faster mcus, it is necessary to schedule the unstep event - uint32_t min_next_time = sched_read_time() + UNSTEP_TIME; + uint32_t min_next_time = timer_read_time() + UNSTEP_TIME; gpio_out_toggle(s->step_pin); s->count--; if (likely(s->count & 1)) @@ -132,7 +133,7 @@ stepper_event(struct timer *t) if (likely(s->count)) { s->next_step_time += s->interval; s->interval += s->add; - if (unlikely(sched_is_before(s->next_step_time, min_next_time))) + if (unlikely(timer_is_before(s->next_step_time, min_next_time))) // The next step event is too close - push it back goto reschedule_min; s->time.waketime = s->next_step_time; |