From 8d9c79f5c162e07d57d42c6ba5825a3327a911d5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 9 May 2014 00:05:39 -0700 Subject: [PATCH] altos: Simplify quadrature tracking Set the timer to 200Hz for a 5ms debounce interval. Then, simply look for transitions ending in both bits in the encoder being off, which indicates the the encoder is resting in a detent. If bit '2' is turning off, the encoder was rotated clockwise, otherwise the encoder was rotated counter clockwise. This is a lot more reliable, although still not perfect. Signed-off-by: Keith Packard --- src/drivers/ao_quadrature.c | 66 ++++++++++++++----------------------- src/stm/ao_fast_timer.c | 8 +++-- src/telelco-v0.2/ao_pins.h | 2 ++ 3 files changed, 33 insertions(+), 43 deletions(-) diff --git a/src/drivers/ao_quadrature.c b/src/drivers/ao_quadrature.c index d07488d0..66a77dfa 100644 --- a/src/drivers/ao_quadrature.c +++ b/src/drivers/ao_quadrature.c @@ -22,11 +22,7 @@ #include __xdata int32_t ao_quadrature_count[AO_QUADRATURE_COUNT]; -static uint8_t ao_quadrature_state[AO_QUADRATURE_COUNT]; -static int8_t ao_quadrature_raw[AO_QUADRATURE_COUNT]; - -#define BIT(a,b) ((a) | ((b) << 1)) -#define STATE(old_a, old_b, new_a, new_b) (((BIT(old_a, old_b) << 2) | BIT(new_a, new_b))) +static uint8_t ao_quadrature_state[AO_QUADRATURE_COUNT]; #define port(q) AO_QUADRATURE_ ## q ## _PORT #define bita(q) AO_QUADRATURE_ ## q ## _A @@ -54,51 +50,29 @@ _ao_quadrature_queue(uint8_t q, int8_t step) ao_wakeup(&ao_quadrature_count[q]); } -static const int8_t step[16] = { - [STATE(0,0,0,0)] = 0, - [STATE(0,0,0,1)] = -1, - [STATE(0,0,1,0)] = 1, - [STATE(0,0,1,1)] = 0, - [STATE(0,1,0,0)] = 1, - [STATE(0,1,1,0)] = 0, - [STATE(0,1,1,1)] = -1, - [STATE(1,0,0,0)] = -1, - [STATE(1,0,0,1)] = 0, - [STATE(1,0,1,0)] = 0, - [STATE(1,0,1,1)] = 1, - [STATE(1,1,0,0)] = 0, - [STATE(1,1,0,1)] = 1, - [STATE(1,1,1,0)] = -1, - [STATE(1,1,1,1)] = 0 -}; static void -_ao_quadrature_set(uint8_t q, uint8_t value) { - uint8_t v; - - v = ao_quadrature_state[q] & 3; - value = value & 3; +_ao_quadrature_set(uint8_t q, uint8_t new) { + uint8_t old = ao_quadrature_state[q]; - if (v == value) - return; - - ao_quadrature_state[q] = (v << 2) | value; - - ao_quadrature_raw[q] += step[ao_quadrature_state[q]]; - if (value == 0) { - if (ao_quadrature_raw[q] == 4) + if (old != new && new == 0) { + if (old & 2) _ao_quadrature_queue(q, 1); - else if (ao_quadrature_raw[q] == -4) + else if (old & 1) _ao_quadrature_queue(q, -1); - ao_quadrature_raw[q] = 0; } + ao_quadrature_state[q] = new; } static void ao_quadrature_isr(void) { +#if AO_QUADRATURE_COUNT > 0 _ao_quadrature_set(0, _ao_quadrature_get(0)); +#endif +#if AO_QUADRATURE_COUNT > 1 _ao_quadrature_set(1, _ao_quadrature_get(1)); +#endif } int32_t @@ -120,6 +94,8 @@ static void ao_quadrature_test(void) { uint8_t q; + int32_t c; + uint8_t s; ao_cmd_decimal(); q = ao_cmd_lex_i; @@ -127,10 +103,18 @@ ao_quadrature_test(void) ao_cmd_status = ao_cmd_syntax_error; return; } - printf ("count %d state %x raw %d\n", - ao_quadrature_count[q], - ao_quadrature_state[q], - ao_quadrature_raw[q]); + + c = -10000; + s = 0; + while (ao_quadrature_count[q] != 10) { + if (ao_quadrature_count[q] != c || + ao_quadrature_state[q] != s) { + c = ao_quadrature_count[q]; + s = ao_quadrature_state[q]; + printf ("count %3d state %2x\n", c, s); + flush(); + } + } #if 0 for (;;) { int32_t c; diff --git a/src/stm/ao_fast_timer.c b/src/stm/ao_fast_timer.c index d61b40c9..9a73eb51 100644 --- a/src/stm/ao_fast_timer.c +++ b/src/stm/ao_fast_timer.c @@ -88,7 +88,11 @@ void stm_tim6_isr(void) #define TIMER_23467_SCALER 1 #endif -#define TIMER_10kHz ((AO_PCLK1 * TIMER_23467_SCALER) / 10000) +#ifndef FAST_TIMER_FREQ +#define FAST_TIMER_FREQ 10000 +#endif + +#define TIMER_FAST ((AO_PCLK1 * TIMER_23467_SCALER) / FAST_TIMER_FREQ) void ao_fast_timer_init(void) @@ -100,7 +104,7 @@ ao_fast_timer_init(void) /* Turn on timer 6 */ stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_TIM6EN); - stm_tim6.psc = TIMER_10kHz; + stm_tim6.psc = TIMER_FAST; stm_tim6.arr = 9; stm_tim6.cnt = 0; diff --git a/src/telelco-v0.2/ao_pins.h b/src/telelco-v0.2/ao_pins.h index 62f221a1..609e5494 100644 --- a/src/telelco-v0.2/ao_pins.h +++ b/src/telelco-v0.2/ao_pins.h @@ -72,6 +72,8 @@ #define PACKET_HAS_SLAVE 0 #define PACKET_HAS_MASTER 0 +#define FAST_TIMER_FREQ 200 /* 5ms for debouncing */ + /* * Radio is a cc1120 connected via SPI */ -- 2.30.2