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>
-Subproject commit 8b1c9061fa3a8f1b30ee13b373afe5cc1ad9d382
+Subproject commit bd33f6640cf5882f8630766a9acdd1bc420a9dda
#include <ao.h>
#include <ao_button.h>
#include <ao_exti.h>
#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)
#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_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
#define port(q) AO_BUTTON_ ## q ## _PORT
#define bit(q) AO_BUTTON_ ## q
#define ao_button_value(b) !ao_gpio_get(port(b), bit(b), pin(b))
static uint8_t
#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);
switch (b) {
#if AO_BUTTON_COUNT > 0
case 0: return ao_button_value(0);
-_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;
+ }
+}
-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);
+
uint8_t b;
for (b = 0; b < AO_BUTTON_COUNT; b++)
uint8_t b;
for (b = 0; b < AO_BUTTON_COUNT; b++)
- _ao_debounce_start(&ao_button_debounce[b]);
- 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_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_exti_enable(port(b), bit(b)); \
ao_exti_enable(port(b), bit(b)); \
#if AO_BUTTON_COUNT > 4
init(4);
#endif
#if AO_BUTTON_COUNT > 4
init(4);
#endif
ao_radio_spi.h \
ao_radio_cmac.h \
ao_cc1120_CC1120.h \
ao_radio_spi.h \
ao_radio_cmac.h \
ao_cc1120_CC1120.h \
ao_fec_tx.c \
ao_fec_rx.c \
ao_seven_segment.c \
ao_fec_tx.c \
ao_fec_rx.c \
ao_seven_segment.c \
ao_quadrature.c \
ao_button.c \
ao_event.c \
ao_quadrature.c \
ao_button.c \
ao_event.c \
ao_radio_cmac.h \
ao_cc1200_CC1200.h \
ao_cc1200.h \
ao_radio_cmac.h \
ao_cc1200_CC1200.h \
ao_cc1200.h \
ao_fec_tx.c \
ao_fec_rx.c \
ao_seven_segment.c \
ao_fec_tx.c \
ao_fec_rx.c \
ao_seven_segment.c \
ao_quadrature.c \
ao_button.c \
ao_event.c \
ao_quadrature.c \
ao_button.c \
ao_event.c \
ao_radio_cmac.h \
ao_cc1200_CC1200.h \
ao_cc1200.h \
ao_radio_cmac.h \
ao_cc1200_CC1200.h \
ao_cc1200.h \
ao_aes_tables.c \
ao_fec_tx.c \
ao_fec_rx.c \
ao_aes_tables.c \
ao_fec_tx.c \
ao_fec_rx.c \
ao_button.c \
ao_event.c \
ao_lco_two.c \
ao_button.c \
ao_event.c \
ao_lco_two.c \