altos: Use simpler debounce logic for buttons
authorKeith Packard <keithp@keithp.com>
Sat, 26 Dec 2015 04:46:40 +0000 (20:46 -0800)
committerKeith Packard <keithp@keithp.com>
Wed, 20 Apr 2016 03:21:30 +0000 (23:21 -0400)
Instead of waiting for a while after the transition to decide if it
has stuck, signal the event right away and then ignore other
transitions for the debounce interval.

This seems to work just as reliably, but has the benefit of
eliminating button latency at press time.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/drivers/ao_button.c
src/telelco-v0.2/Makefile
src/telelco-v0.3/Makefile
src/telelcotwo-v0.1/Makefile

index cdf073524e1e8f4ffb5f232f255c5ef854de28fe..8e7dead71df6d075014a233c0d43c77f973a59a9 100644 (file)
@@ -18,7 +18,6 @@
 #include <ao.h>
 #include <ao_button.h>
 #include <ao_exti.h>
-#include <ao_debounce.h>
 #if AO_EVENT
 #include <ao_event.h>
 #define ao_button_queue(b,v)   ao_event_put_isr(AO_EVENT_BUTTON, b, v)
 #define ao_button_queue(b,v)
 #endif
 
-#define AO_BUTTON_DEBOUNCE_HOLD        10
+#define AO_BUTTON_DEBOUNCE_INTERVAL    AO_MS_TO_TICKS(50)
 
-static struct ao_debounce      ao_button_debounce[AO_BUTTON_COUNT];
+struct ao_button_state {
+       AO_TICK_TYPE    time;
+       uint8_t         value;
+};
+
+static struct ao_button_state  ao_button_state[AO_BUTTON_COUNT];
 
 #define port(q)        AO_BUTTON_ ## q ## _PORT
 #define bit(q) AO_BUTTON_ ## q
@@ -38,10 +42,8 @@ static struct ao_debounce    ao_button_debounce[AO_BUTTON_COUNT];
 #define ao_button_value(b)     !ao_gpio_get(port(b), bit(b), pin(b))
 
 static uint8_t
-_ao_button_get(struct ao_debounce *debounce)
+_ao_button_get(uint8_t b)
 {
-       uint8_t b = debounce - ao_button_debounce;
-
        switch (b) {
 #if AO_BUTTON_COUNT > 0
        case 0: return ao_button_value(0);
@@ -63,22 +65,31 @@ _ao_button_get(struct ao_debounce *debounce)
 }
 
 static void
-_ao_button_set(struct ao_debounce *debounce, uint8_t value)
+_ao_button_check(uint8_t b)
 {
-       uint8_t b = debounce - ao_button_debounce;
-
-       ao_button_queue(b, value);
-}
+       uint8_t value = _ao_button_get(b);
 
+       if (value != ao_button_state[b].value) {
+               AO_TICK_TYPE    now = ao_time();
 
-#define ao_button_update(b)    ao_button_do(b, ao_gpio_get(port(b), bit(b), pin(b)))
+               if ((now - ao_button_state[b].time) >= AO_BUTTON_DEBOUNCE_INTERVAL) {
+                       ao_button_state[b].value = value;
+                       ao_button_queue(b, value);
+               }
+               ao_button_state[b].time = now;
+       }
+}
 
 static void
-ao_button_debounce_init(struct ao_debounce *debounce) {
-       ao_debounce_config(debounce,
-                          _ao_button_get,
-                          _ao_button_set,
-                          AO_BUTTON_DEBOUNCE_HOLD);
+_ao_button_init(uint8_t b)
+{
+       uint8_t m = ao_arch_irqsave();
+       uint8_t value = _ao_button_get(b);
+       ao_button_state[b].value = value;
+       ao_button_state[b].time = ao_time();
+       ao_button_queue(b, value);
+       ao_arch_irqrestore(m);
+
 }
 
 static void
@@ -87,17 +98,17 @@ ao_button_isr(void)
        uint8_t b;
 
        for (b = 0; b < AO_BUTTON_COUNT; b++)
-               _ao_debounce_start(&ao_button_debounce[b]);
+               _ao_button_check(b);
 }
 
 #define init(b) do {                                                   \
-               ao_button_debounce_init(&ao_button_debounce[b]);        \
                ao_enable_port(port(b));                                \
                                                                        \
                ao_exti_setup(port(b), bit(b),                          \
                              AO_BUTTON_MODE|AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_MED, \
-                             ao_button_isr);                   \
+                             ao_button_isr);                           \
                ao_exti_enable(port(b), bit(b));                        \
+               _ao_button_init(b);                                     \
        } while (0)
 
 void
@@ -118,5 +129,4 @@ ao_button_init(void)
 #if AO_BUTTON_COUNT > 4
        init(4);
 #endif
-       ao_debounce_init();
 }
index 7a21f099c742ebd3440081f90b9427ed1629a491..8c1ced6c035d44a75db7e9b293f03d194adf4b59 100644 (file)
@@ -22,7 +22,6 @@ INC = \
        ao_radio_spi.h \
        ao_radio_cmac.h \
        ao_cc1120_CC1120.h \
-       ao_debounce.h \
        stm32l.h
 
 #
@@ -61,7 +60,6 @@ ALTOS_SRC = \
        ao_fec_tx.c \
        ao_fec_rx.c \
        ao_seven_segment.c \
-       ao_debounce.c \
        ao_quadrature.c \
        ao_button.c \
        ao_event.c \
index 83d3fc43aa803fa92f17554fef1e0e348d566856..0bb0f9dc94816bb2878586bd970085eb3b5415dc 100644 (file)
@@ -23,7 +23,6 @@ INC = \
        ao_radio_cmac.h \
        ao_cc1200_CC1200.h \
        ao_cc1200.h \
-       ao_debounce.h \
        stm32l.h
 
 #
@@ -62,7 +61,6 @@ ALTOS_SRC = \
        ao_fec_tx.c \
        ao_fec_rx.c \
        ao_seven_segment.c \
-       ao_debounce.c \
        ao_quadrature.c \
        ao_button.c \
        ao_event.c \
index 8ceb7d2ce89ee6d52312596dba4426f27712c582..42188bb2632d5017cc1d4bbeee263102bff37489 100644 (file)
@@ -19,7 +19,6 @@ INC = \
        ao_radio_cmac.h \
        ao_cc1200_CC1200.h \
        ao_cc1200.h \
-       ao_debounce.h \
        stm32l.h
 
 #
@@ -56,7 +55,6 @@ ALTOS_SRC = \
        ao_aes_tables.c \
        ao_fec_tx.c \
        ao_fec_rx.c \
-       ao_debounce.c \
        ao_button.c \
        ao_event.c \
        ao_lco_two.c \