From 69cb10f51321a2443a3314c40fb2b8556aa804c0 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Tue, 16 Sep 2014 17:22:55 +0200 Subject: timer: Support timeouts > 8s --- timer.c | 48 +++++++++++++++++++++++++++++++++++------------- ui.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/timer.c b/timer.c index c4e5704..ce30b60 100644 --- a/timer.c +++ b/timer.c @@ -5,19 +5,36 @@ #include "timer.h" -volatile unsigned char hits, maxhits; +/* useconds per clock tick */ +#define US_PER_TICK 128 +/* max useconds with max OCRA1 */ +#define MAX_US ((uint32_t) 8388480) + +/* max/current timer hits */ +volatile uint8_t maxhits, hits; +/* compare value for n-1, last hits */ +uint16_t count, lastcount; +/* accumulated time since last timeout/call to timerHit (us) */ +uint32_t time; ISR(TIMER1_COMPA_vect) { ++hits; + time += OCR1A * US_PER_TICK; + if (hits == maxhits-1) { + OCR1A = lastcount; + } } /* Check if timer was hit, return time since last restart or 0 if not hit yet */ uint32_t timerHit () { if (hits >= maxhits) { - const uint32_t ret = TCNT1 * (uint32_t) 128 + - (uint32_t) hits * OCR1A * (uint32_t) 128; + const uint32_t ret = time; + /* reset timer, start again */ hits = 0; + time = 0; + OCR1A = count; + TCNT1 = 0; return ret; } else { return 0; @@ -27,6 +44,9 @@ uint32_t timerHit () { /* Start a timer that fires every t us */ void timerStart (const uint32_t t) { + hits = 0; + time = 0; + /* reset timer value */ TCNT1 = 0; /* set ctc (compare timer and clear) mode (part 1) */ @@ -35,24 +55,26 @@ void timerStart (const uint32_t t) { TIMSK1 = (1 << OCIE1A); /* set compare value */ #if F_CPU == 8000000 - const uint32_t tdiv = t/128; - if (tdiv > UINT16_MAX) { -#warning "fix this" - assert (0); + /* with divider 1024 each clock tick is 128us with a rounding error of 64us + * per second/4ms per minute, since it’s a 16 bit timer we support up to + * 2**16-1 ticks, which is 8388480us (8s) */ + if (t >= MAX_US) { + maxhits = t/MAX_US+1; + count = UINT16_MAX; + lastcount = (t % MAX_US) / US_PER_TICK; + OCR1A = UINT16_MAX; } else { - /* with divider 1024 each clock tick is 128us with a rounding error of - * 64us per second/4ms per minute, since its a 16 bit timer we support - * up to 2**16-1 ticks, which is 8388480us (8s) */ - OCR1A = tdiv; maxhits = 1; + const uint16_t tdiv = t / US_PER_TICK; + count = tdiv; + lastcount = tdiv; + OCR1A = tdiv; } #else #error "cpu speed not supported" #endif /* io clock with 1024 prescaler; ctc (part 2) */ TCCR1B = (1 << CS12) | (1 << CS10) | (1 << WGM12); - - hits = 0; } void timerStop () { diff --git a/ui.c b/ui.c index 3f3179f..7bd393d 100644 --- a/ui.c +++ b/ui.c @@ -298,6 +298,35 @@ void uiLoop () { } #endif +#if 0 + /* timer test mode */ + timerStart ((uint32_t) 10*1000*1000); + while (1) { + uint32_t t; + while (1) { + t = timerHit (); + if (t > 0) { + break; + } + cpuSleep (); + } + puts ("on"); + fwrite (&t, sizeof (t), 1, stdout); + pwmSet (horizonLed (0), PWM_ON); + + while (1) { + t = timerHit (); + if (t > 0) { + break; + } + cpuSleep (); + } + puts ("off"); + fwrite (&t, sizeof (t), 1, stdout); + pwmSet (horizonLed (0), PWM_OFF); + } +#endif + while (1) { processSensors (); -- cgit v1.2.3