altos: Use fast timer for buttons instead of edge-triggered ISR
authorKeith Packard <keithp@keithp.com>
Tue, 13 Aug 2019 00:30:48 +0000 (17:30 -0700)
committerKeith Packard <keithp@keithp.com>
Tue, 13 Aug 2019 00:30:48 +0000 (17:30 -0700)
If the button bounces between the triggering interrupt and the button
state check, we could lose the final state change of the button and
send an incorrect event to the application. In the worst case, the button
would end up in exactly the wrong state, toggling in the wrong direction.

Use the fast timer to poll all buttons instead so that there is only
one check of each button at each poll interval (instead of the
interrupt and the state check). This makes buttons reliably debounced.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/drivers/ao_button.c

index c8103e884d3cd47bfacb5909a0034acafa41a325..53728bceef47d99c26b54fe6ad58a637dc985c8c 100644 (file)
@@ -19,6 +19,7 @@
 #include <ao.h>
 #include <ao_button.h>
 #include <ao_exti.h>
 #include <ao.h>
 #include <ao_button.h>
 #include <ao_exti.h>
+#include <ao_fast_timer.h>
 #if AO_EVENT
 #include <ao_event.h>
 #define ao_button_queue(b,v)   ao_event_put_isr(AO_EVENT_BUTTON, b, v)
 #if AO_EVENT
 #include <ao_event.h>
 #define ao_button_queue(b,v)   ao_event_put_isr(AO_EVENT_BUTTON, b, v)
@@ -149,12 +150,7 @@ ao_button_isr(void)
 }
 
 #define init(b) do {                                                   \
 }
 
 #define init(b) do {                                                   \
-               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_exti_enable(port(b), bit(b));                        \
+               ao_enable_input(port(b), bit(b), AO_BUTTON_MODE);       \
                _ao_button_init(b);                                     \
        } while (0)
 
                _ao_button_init(b);                                     \
        } while (0)
 
@@ -212,4 +208,6 @@ ao_button_init(void)
 #if AO_BUTTON_COUNT > 16
        #error too many buttons
 #endif
 #if AO_BUTTON_COUNT > 16
        #error too many buttons
 #endif
+       ao_fast_timer_init();
+       ao_fast_timer_on(ao_button_isr);
 }
 }