diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2017-03-10 23:00:17 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2017-03-11 12:15:07 -0500 |
commit | e5d7e593ec8a1587983e2ca9504af6b4e9d17578 (patch) | |
tree | 35ca4517e8f043e98659ceca7720fb1b08bef776 /src/sam3x8e/timer.c | |
parent | 69b927bfe9f9fd7a6ffe664a188ae4ad9462fd75 (diff) | |
download | kutter-e5d7e593ec8a1587983e2ca9504af6b4e9d17578.tar.gz kutter-e5d7e593ec8a1587983e2ca9504af6b4e9d17578.tar.xz kutter-e5d7e593ec8a1587983e2ca9504af6b4e9d17578.zip |
generic: Move generic parts of sam3x8e timer.c to generic directory
Most of sam3x8e/timer.c is going to be platform agnostic for any board
with standard irq handling. Move the generic code into a new file
generic/timer.c.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src/sam3x8e/timer.c')
-rw-r--r-- | src/sam3x8e/timer.c | 99 |
1 files changed, 11 insertions, 88 deletions
diff --git a/src/sam3x8e/timer.c b/src/sam3x8e/timer.c index dbc7700e..e450d21e 100644 --- a/src/sam3x8e/timer.c +++ b/src/sam3x8e/timer.c @@ -4,28 +4,12 @@ // // This file may be distributed under the terms of the GNU GPLv3 license. -#include "autoconf.h" // CONFIG_CLOCK_FREQ #include "board/irq.h" // irq_disable -#include "board/misc.h" // timer_from_us -#include "command.h" // shutdown +#include "board/misc.h" // timer_read_time +#include "command.h" // DECL_SHUTDOWN #include "sam3x8e.h" // TC0 #include "sched.h" // sched_timer_kick - -/**************************************************************** - * Low level timer code - ****************************************************************/ - -DECL_CONSTANT(CLOCK_FREQ, CONFIG_CLOCK_FREQ); -DECL_CONSTANT(MCU, "sam3x8e"); - -// Return the number of clock ticks for a given number of microseconds -uint32_t -timer_from_us(uint32_t us) -{ - return us * (CONFIG_CLOCK_FREQ / 1000000); -} - // IRQ handler void __visible TC0_Handler(void) @@ -37,12 +21,20 @@ TC0_Handler(void) irq_enable(); } -static void +// Set the next irq time +void timer_set(uint32_t value) { TC0->TC_CHANNEL[0].TC_RA = value; } +// Return the current time (in absolute clock ticks). +uint32_t +timer_read_time(void) +{ + return TC0->TC_CHANNEL[0].TC_CV; +} + static void timer_init(void) { @@ -70,72 +62,3 @@ timer_shutdown(void) TC0->TC_CHANNEL[0].TC_SR; // read to clear irq pending } DECL_SHUTDOWN(timer_shutdown); - -// Called by main code once every millisecond. (IRQs disabled.) -void -timer_periodic(void) -{ -} - -// Return the current time (in absolute clock ticks). -uint32_t -timer_read_time(void) -{ - return TC0->TC_CHANNEL[0].TC_CV; -} - -static uint32_t timer_repeat_until; -#define TIMER_IDLE_REPEAT_TICKS timer_from_us(500) -#define TIMER_REPEAT_TICKS timer_from_us(100) - -#define TIMER_MIN_TRY_TICKS timer_from_us(1) -#define TIMER_DEFER_REPEAT_TICKS timer_from_us(5) - -// Set the next timer wake time (in absolute clock ticks) or return 1 -// if the next timer is too close to schedule. Caller must disable -// irqs. -uint8_t -timer_try_set_next(uint32_t next) -{ - uint32_t now = timer_read_time(); - int32_t diff = next - now; - if (diff > (int32_t)TIMER_MIN_TRY_TICKS) - // Schedule next timer normally. - 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))) { - // Can run more timers from this irq; briefly allow irqs - irq_enable(); - while (diff >= 0) { - // Next timer is in the near future - wait for time to occur - now = timer_read_time(); - diff = next - now; - } - irq_disable(); - return 0; - } - if (diff < (int32_t)(-timer_from_us(1000))) - goto fail; - - // Too many repeat timers from a single interrupt - force a pause - timer_repeat_until = now + TIMER_REPEAT_TICKS; - next = now + TIMER_DEFER_REPEAT_TICKS; - -done: - timer_set(next); - return 1; -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) -{ - irq_disable(); - timer_repeat_until = timer_read_time() + TIMER_IDLE_REPEAT_TICKS; - irq_enable(); -} -DECL_TASK(timer_task); |