summaryrefslogtreecommitdiffhomepage
path: root/digital/mimot
diff options
context:
space:
mode:
Diffstat (limited to 'digital/mimot')
-rw-r--r--digital/mimot/src/dirty/counter.h3
-rw-r--r--digital/mimot/src/dirty/counter_ext.avr.c46
-rw-r--r--digital/mimot/src/dirty/timer.avr.c18
3 files changed, 58 insertions, 9 deletions
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
@@ -32,6 +32,9 @@ void
counter_init (void);
void
+counter_update_step (void);
+
+void
counter_update (void);
#endif /* counter_h */
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. */