From 79e27902ecc390cb57ae3a68757f76dc3688ecb0 Mon Sep 17 00:00:00 2001 From: bartool Date: Sun, 26 Mar 2023 03:04:58 +0200 Subject: [PATCH] driver: hw_button --- firmware/func_gen_stm32f303re_nucleo/Makefile | 8 ++ .../shared_libs/drivers/hw_button/hw_button.c | 102 ++++++++++++++++++ .../shared_libs/drivers/hw_button/hw_button.h | 46 ++++++++ 3 files changed, 156 insertions(+) create mode 100644 firmware/shared_libs/drivers/hw_button/hw_button.c create mode 100644 firmware/shared_libs/drivers/hw_button/hw_button.h diff --git a/firmware/func_gen_stm32f303re_nucleo/Makefile b/firmware/func_gen_stm32f303re_nucleo/Makefile index 9ac5855..704a143 100644 --- a/firmware/func_gen_stm32f303re_nucleo/Makefile +++ b/firmware/func_gen_stm32f303re_nucleo/Makefile @@ -73,6 +73,10 @@ C_SOURCES += ../shared_libs/drivers/ad9833/ad9833.c C_SOURCES += ../shared_libs/drivers/ltc2631/ltc2631.c # mcp41x C_SOURCES += ../shared_libs/drivers/mcp41x/mcp41x.c +# st7565 +C_SOURCES += ../shared_libs/drivers/st7565/st7565.c +# hw_button +C_SOURCES += ../shared_libs/drivers/hw_button/hw_button.c # ASM sources ASM_SOURCES = \ @@ -141,6 +145,10 @@ C_INCLUDES += -I../shared_libs/drivers/ad9833 C_INCLUDES += -I../shared_libs/drivers/ltc2631 # mcp41x includes C_INCLUDES += -I../shared_libs/drivers/mcp41x +# st7565 includes +C_INCLUDES += -I../shared_libs/drivers/st7565 +# hw_button includes +C_INCLUDES += -I../shared_libs/drivers/hw_button # compile gcc flags ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections diff --git a/firmware/shared_libs/drivers/hw_button/hw_button.c b/firmware/shared_libs/drivers/hw_button/hw_button.c new file mode 100644 index 0000000..40e507a --- /dev/null +++ b/firmware/shared_libs/drivers/hw_button/hw_button.c @@ -0,0 +1,102 @@ +#include "main.h" +#include "hw_button.h" + +static void buttonIdleRoutine(ButtonKey_t *key); +static void buttonDebounceRoutine(ButtonKey_t *key); +static void buttonPressedRoutine(ButtonKey_t *key); +static void buttonLongPressedRoutine(ButtonKey_t *key); + +typedef void (*ButtonRoutine_t)(ButtonKey_t *); + +ButtonRoutine_t button_routine[MAX_STATE] = { + buttonIdleRoutine, + buttonDebounceRoutine, + buttonPressedRoutine, + buttonLongPressedRoutine, + buttonLongPressedRoutine, +}; + +void buttonHandler(ButtonKey_t *key) +{ + button_routine[key->state](key); +} + +static void buttonIdleRoutine(ButtonKey_t *key) +{ + if (key->pushed_state == HAL_GPIO_ReadPin(key->gpio_port, key->gpio_pin)) + { + key->state = DEBOUNCE; + key->last_tick = HAL_GetTick(); + } +} + +static void buttonDebounceRoutine(ButtonKey_t *key) +{ + if (HAL_GetTick() - key->last_tick < key->timer_debounce) + { + return; + } + + if (key->pushed_state != HAL_GPIO_ReadPin(key->gpio_port, key->gpio_pin)) + { + key->state = IDLE; + return; + } + + key->state = PRESSED; + key->last_tick = HAL_GetTick(); + if (key->buttonPressed) + { + key->buttonPressed(key); + } +} + +static void buttonPressedRoutine(ButtonKey_t *key) +{ + if (key->pushed_state != HAL_GPIO_ReadPin(key->gpio_port, key->gpio_pin)) + { + key->state = IDLE; + if (key->buttonReleased) + { + key->buttonReleased(key); + } + return; + } + + if (HAL_GetTick() - key->last_tick < key->timer_long_pressed) + { + return; + } + + key->state = LONGPRESSED; + key->last_tick = HAL_GetTick(); + if (key->buttonLongPressed) + { + key->buttonLongPressed(key); + } +} + +static void buttonLongPressedRoutine(ButtonKey_t *key) +{ + if (key->pushed_state != HAL_GPIO_ReadPin(key->gpio_port, key->gpio_pin)) + { + key->state = IDLE; + if (key->buttonReleased) + { + key->buttonReleased(key); + } + return; + } + + if (HAL_GetTick() - key->last_tick < key->timer_repeat_delay) + { + return; + } + + key->state = REPEAT; + key->last_tick = HAL_GetTick(); + if (key->buttonRepeat) + { + key->buttonRepeat(key); + } +} diff --git a/firmware/shared_libs/drivers/hw_button/hw_button.h b/firmware/shared_libs/drivers/hw_button/hw_button.h new file mode 100644 index 0000000..0bfcc07 --- /dev/null +++ b/firmware/shared_libs/drivers/hw_button/hw_button.h @@ -0,0 +1,46 @@ +#pragma once + +#define BTN_DEFAULT_DEBOUNCE_MS 20 +#define BTN_DEFAULT_LONGPRESSED_MS 1000 +#define BTN_DEFAULT_REPEAT_MS 200 + +// States for state machine +typedef enum +{ + IDLE = 0, + DEBOUNCE, + PRESSED, + LONGPRESSED, + REPEAT, + MAX_STATE +} ButtonState_t; + +// Struct for button +typedef struct ButtonKey ButtonKey_t; +typedef void (*buttonPressed_t)(ButtonKey_t *key); +typedef void (*buttonLongPressed_t)(ButtonKey_t *key); +typedef void (*buttonRepeat_t)(ButtonKey_t *key); + +struct ButtonKey +{ + uint8_t instance; // Button name/number + ButtonState_t state; // Button current state + + GPIO_TypeDef *gpio_port; // GPIO Port for a button + uint16_t gpio_pin; // GPIO Pin for a button + GPIO_PinState pushed_state; + + uint32_t last_tick; // Last remembered time before steps + uint32_t timer_debounce; // Fixed, settable time for debounce timer + uint32_t timer_long_pressed; // Fixed, adjustable time for long press timer + uint32_t timer_repeat_delay; // Fixed, adjustable interval time + + buttonPressed_t buttonReleased; // A callback for button released + buttonPressed_t buttonPressed; // A callback for button pressed + buttonLongPressed_t buttonLongPressed; // A callback for long pressed + buttonRepeat_t buttonRepeat; // A callback for repeat +}; + +// Public functions + +void buttonHandler(ButtonKey_t *key);