X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fdrivers%2Fao_button.c;h=c8103e884d3cd47bfacb5909a0034acafa41a325;hp=25c0cd5cea66b753813cd566102ce5ba6f7c9da9;hb=0686a7b8aec524d81bda4c572549a3a068ce0eed;hpb=01f8df088759ee7e6bc3900a013e0ea4fafaf984 diff --git a/src/drivers/ao_button.c b/src/drivers/ao_button.c index 25c0cd5c..c8103e88 100644 --- a/src/drivers/ao_button.c +++ b/src/drivers/ao_button.c @@ -3,7 +3,8 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of @@ -18,7 +19,6 @@ #include #include #include -#include #if AO_EVENT #include #define ao_button_queue(b,v) ao_event_put_isr(AO_EVENT_BUTTON, b, v) @@ -26,22 +26,32 @@ #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 pin(q) AO_BUTTON_ ## q ## _PIN +#ifndef AO_BUTTON_INVERTED +#define AO_BUTTON_INVERTED 1 +#endif + +#if AO_BUTTON_INVERTED /* pins are inverted */ -#define ao_button_value(b) !ao_gpio_get(port(b), bit(b), pin(b)) +#define ao_button_value(b) !ao_gpio_get(port(b), bit(b)) +#else +#define ao_button_value(b) ao_gpio_get(port(b), bit(b)) +#endif 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); @@ -57,27 +67,76 @@ _ao_button_get(struct ao_debounce *debounce) #endif #if AO_BUTTON_COUNT > 4 case 4: return ao_button_value(4); +#endif +#if AO_BUTTON_COUNT > 5 + case 5: return ao_button_value(5); +#endif +#if AO_BUTTON_COUNT > 6 + case 6: return ao_button_value(6); +#endif +#if AO_BUTTON_COUNT > 7 + case 7: return ao_button_value(7); +#endif +#if AO_BUTTON_COUNT > 8 + case 8: return ao_button_value(8); +#endif +#if AO_BUTTON_COUNT > 9 + case 9: return ao_button_value(9); +#endif +#if AO_BUTTON_COUNT > 10 + case 10: return ao_button_value(10); +#endif +#if AO_BUTTON_COUNT > 11 + case 11: return ao_button_value(11); +#endif +#if AO_BUTTON_COUNT > 12 + case 12: return ao_button_value(12); +#endif +#if AO_BUTTON_COUNT > 13 + case 13: return ao_button_value(13); +#endif +#if AO_BUTTON_COUNT > 14 + case 14: return ao_button_value(14); +#endif +#if AO_BUTTON_COUNT > 15 + case 15: return ao_button_value(15); #endif } + return 0; } 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; + uint8_t value = _ao_button_get(b); - ao_button_queue(b, value); + if (value != ao_button_state[b].value) { + AO_TICK_TYPE now = ao_time(); + + 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_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); -#define ao_button_update(b) ao_button_do(b, ao_gpio_get(port(b), bit(b), pin(b))) +} -static void -ao_button_debounce_init(struct ao_debounce *debounce) { - ao_debounce_config(debounce, - _ao_button_get, - _ao_button_set, - AO_BUTTON_DEBOUNCE_HOLD); +uint8_t +ao_button_get(uint8_t b) +{ + return ao_button_state[b].value; } static void @@ -86,17 +145,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 @@ -117,5 +176,40 @@ ao_button_init(void) #if AO_BUTTON_COUNT > 4 init(4); #endif - ao_debounce_init(); +#if AO_BUTTON_COUNT > 5 + init(5); +#endif +#if AO_BUTTON_COUNT > 6 + init(6); +#endif +#if AO_BUTTON_COUNT > 7 + init(7); +#endif +#if AO_BUTTON_COUNT > 8 + init(8); +#endif +#if AO_BUTTON_COUNT > 9 + init(9); +#endif +#if AO_BUTTON_COUNT > 10 + init(10); +#endif +#if AO_BUTTON_COUNT > 11 + init(11); +#endif +#if AO_BUTTON_COUNT > 12 + init(12); +#endif +#if AO_BUTTON_COUNT > 13 + init(13); +#endif +#if AO_BUTTON_COUNT > 14 + init(14); +#endif +#if AO_BUTTON_COUNT > 15 + init(15); +#endif +#if AO_BUTTON_COUNT > 16 + #error too many buttons +#endif }