From c0a9e3ae09c193bf9655117fa9ad494e5b3d7f8d Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Tue, 4 May 2010 02:25:34 +0200 Subject: digital/mimot/src/dirty: poll counter more often, add shift See previous commit. --- digital/mimot/src/dirty/counter.h | 3 ++ digital/mimot/src/dirty/counter_ext.avr.c | 46 +++++++++++++++++++++++++------ digital/mimot/src/dirty/timer.avr.c | 18 ++++++++++++ 3 files changed, 58 insertions(+), 9 deletions(-) (limited to 'digital/mimot') diff --git a/digital/mimot/src/dirty/counter.h b/digital/mimot/src/dirty/counter.h index 39d596c5..b4b4979d 100644 --- a/digital/mimot/src/dirty/counter.h +++ b/digital/mimot/src/dirty/counter.h @@ -31,6 +31,9 @@ extern int16_t counter_aux_diff[AC_ASSERV_AUX_NB]; void counter_init (void); +void +counter_update_step (void); + void counter_update (void); diff --git a/digital/mimot/src/dirty/counter_ext.avr.c b/digital/mimot/src/dirty/counter_ext.avr.c index 1bbe9a38..0570ab63 100644 --- a/digital/mimot/src/dirty/counter_ext.avr.c +++ b/digital/mimot/src/dirty/counter_ext.avr.c @@ -45,12 +45,21 @@ /** Define to 1 to reverse the second auxiliary counter. */ #define COUNTER_AUX1_REVERSE 0 +/** First auxiliary counter shift. */ +#define COUNTER_AUX0_SHIFT 0 +/** Second auxiliary counter shift. */ +#define COUNTER_AUX1_SHIFT 0 + /** Define to 1 to use the AVR External Memory system, or 0 to use hand made * signals. */ #define COUNTER_USE_XMEM 0 /** Last values. */ -static uint8_t counter_aux_old[AC_ASSERV_AUX_NB]; +static uint16_t counter_aux_old[AC_ASSERV_AUX_NB]; +/** New values, being updated by step update. */ +static uint16_t counter_aux_new_step[AC_ASSERV_AUX_NB]; +/** Last raw step values */ +static uint8_t counter_aux_old_step[AC_ASSERV_AUX_NB]; /** Overall counter values. */ uint16_t counter_aux[AC_ASSERV_AUX_NB]; /** Counter differences since last update. @@ -110,31 +119,50 @@ counter_init (void) DDRB |= 0x0f; #endif /* Begin with safe values. */ - counter_aux_old[0] = counter_read (COUNTER_AUX0); - counter_aux_old[1] = counter_read (COUNTER_AUX1); + counter_aux_old_step[0] = counter_read (COUNTER_AUX0); + counter_aux_old_step[1] = counter_read (COUNTER_AUX1); } -/** Update overall counter values and compute diffs. */ +/** Update one step. If counters are not read fast enough, they could + * overflow, call this function often to update step counters. */ void -counter_update (void) +counter_update_step (void) { uint8_t aux0, aux1; + int8_t diff; /* Sample counters. */ aux0 = counter_read (COUNTER_AUX0); aux1 = counter_read (COUNTER_AUX1); + /* Update step counters. */ + diff = (int8_t) (aux0 - counter_aux_old_step[0]); + counter_aux_old_step[0] = aux0; + counter_aux_new_step[0] += diff; + diff = (int8_t) (aux1 - counter_aux_old_step[1]); + counter_aux_old_step[1] = aux1; + counter_aux_new_step[1] += diff; +} + +/** Update overall counter values and compute diffs. */ +void +counter_update (void) +{ + /* Wants fresh data. */ + counter_update_step (); /* First auxiliary counter. */ + uint16_t aux0 = counter_aux_new_step[0] >> COUNTER_AUX0_SHIFT; #if !COUNTER_AUX0_REVERSE - counter_aux_diff[0] = (int8_t) (aux0 - counter_aux_old[0]); + counter_aux_diff[0] = (int16_t) (aux0 - counter_aux_old[0]); #else - counter_aux_diff[0] = (int8_t) (counter_aux_old[0] - aux0); + counter_aux_diff[0] = (int16_t) (counter_aux_old[0] - aux0); #endif counter_aux_old[0] = aux0; counter_aux[0] += counter_aux_diff[0]; /* Second auxiliary counter. */ + uint16_t aux1 = counter_aux_new_step[1] >> COUNTER_AUX1_SHIFT; #if !COUNTER_AUX1_REVERSE - counter_aux_diff[1] = (int8_t) (aux1 - counter_aux_old[1]); + counter_aux_diff[1] = (int16_t) (aux1 - counter_aux_old[1]); #else - counter_aux_diff[1] = (int8_t) (counter_aux_old[1] - aux1); + counter_aux_diff[1] = (int16_t) (counter_aux_old[1] - aux1); #endif counter_aux_old[1] = aux1; counter_aux[1] += counter_aux_diff[1]; diff --git a/digital/mimot/src/dirty/timer.avr.c b/digital/mimot/src/dirty/timer.avr.c index eb313603..3f956137 100644 --- a/digital/mimot/src/dirty/timer.avr.c +++ b/digital/mimot/src/dirty/timer.avr.c @@ -27,6 +27,15 @@ #include "modules/utils/utils.h" #include "io.h" +#include "counter.h" + +/** Top timer value. */ +#define TIMER_TOP 255 +/** Number of steps during wait. */ +#define TIMER_STEPS 4 +/** Size of step. */ +#define TIMER_STEP ((TIMER_TOP + 1) / TIMER_STEPS) + /** Initialise the timer. */ void timer_init (void) @@ -43,6 +52,15 @@ timer_init (void) void timer_wait (void) { + uint8_t i; + /* Make small steps with counter updates. */ + for (i = 1; i < TIMER_STEPS; i++) + { + while (TCNT0 < i * TIMER_STEP) + ; + counter_update_step (); + } + /* Wait overflow. */ while (!(TIFR & _BV (TOV0))) ; /* Write 1 to clear. */ -- cgit v1.2.3