aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2014-09-16 17:22:55 +0200
committerLars-Dominik Braun <lars@6xq.net>2014-09-16 17:22:55 +0200
commit69cb10f51321a2443a3314c40fb2b8556aa804c0 (patch)
tree3db35b9833327a0b18111cec23047e706dd72436
parentb8d4400e30dc490e543018fe4de0a9d9775f18c2 (diff)
downloadhourglass-69cb10f51321a2443a3314c40fb2b8556aa804c0.tar.gz
hourglass-69cb10f51321a2443a3314c40fb2b8556aa804c0.tar.bz2
hourglass-69cb10f51321a2443a3314c40fb2b8556aa804c0.zip
timer: Support timeouts > 8s
-rw-r--r--timer.c48
-rw-r--r--ui.c29
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 ();