From f9cd3be74eb47869f7aff5f5d70813bc2230525a Mon Sep 17 00:00:00 2001 From: bartool Date: Thu, 29 May 2025 18:53:28 +0200 Subject: [PATCH] add input_handler module --- src/input_handler.c | 74 +++++++++++++++++++++++++++++++++++++++++++++ src/input_handler.h | 46 ++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 src/input_handler.c create mode 100644 src/input_handler.h diff --git a/src/input_handler.c b/src/input_handler.c new file mode 100644 index 0000000..dcff77e --- /dev/null +++ b/src/input_handler.c @@ -0,0 +1,74 @@ +#include +#include "input_handler.h" +#include "timer_counter.h" + +const ButtonRoutine_t button_routine[MAX_STATE]; + +void buttonHandler(ButtonKey_t *key) +{ + button_routine[key->state](key); +} + +static inline GPIO_PinState getPinState(ButtonKey_t *key) +{ + // Read the pin state from the register + return (*(key->instance.pin_register) & (1 << key->instance.pin_number)) ? GPIO_PIN_SET : GPIO_PIN_RESET; +} + +static void buttonIdleRoutine(ButtonKey_t *key) +{ + if (getPinState(key) == key->active_state) + { + key->state = DEBOUNCE; + key->last_tick = ticks100us(); + } +} + +static void buttonActiveRoutine(ButtonKey_t *key) +{ + if (getPinState(key) != key->active_state) + { + key->state = DEBOUNCE; + key->last_tick = ticks100us(); + } +} + +static void buttonDebounceRoutine(ButtonKey_t *key) +{ + // Read the current pin state + GPIO_PinState pin_now = getPinState(key); + ButtonState_t new_state = (pin_now == key->active_state) ? ACTIVE : IDLE; + + // Check if debounce time has passed + uint16_t debounce_time = (new_state == ACTIVE) ? key->timer_debounce_on : key->timer_debounce_off; + if ((ticks100us() - key->last_tick) < debounce_time) + { + return; // Still in debounce period, do nothing + } + + // If the new state is the same as the last state, we return to the previous state + if (new_state == key->last_state) + { + key->state = key->last_state; + return; + } + + // Update the last state and current state + key->last_state = new_state; + key->state = new_state; + + if (new_state == ACTIVE && key->buttonPressed) + { + key->buttonPressed(key); + } + else if (new_state == IDLE && key->buttonReleased) + { + key->buttonReleased(key); + } +} + +const ButtonRoutine_t button_routine[MAX_STATE] = { + buttonIdleRoutine, + buttonDebounceRoutine, + buttonActiveRoutine, +}; \ No newline at end of file diff --git a/src/input_handler.h b/src/input_handler.h new file mode 100644 index 0000000..ea1c2fd --- /dev/null +++ b/src/input_handler.h @@ -0,0 +1,46 @@ +#pragma once + +typedef enum +{ + GPIO_PIN_RESET = 0, + GPIO_PIN_SET +} GPIO_PinState; + +typedef enum +{ + IDLE = 0, + DEBOUNCE, + ACTIVE, + MAX_STATE +} ButtonState_t; + +typedef struct +{ + uint8_t id; + volatile uint8_t *const pin_register; // Pointer to the port register + const uint8_t pin_number; // Pin number +} GpioPinConfig; + +// Struct for button +typedef struct ButtonKey ButtonKey_t; +typedef void (*buttonPressed_t)(ButtonKey_t *key); + +struct ButtonKey +{ + GpioPinConfig instance; // Button GPIO pin configuration + ButtonState_t state; // Button current state (IDLE, DEBOUNCE, ACTIVE) + ButtonState_t last_state; // Button last state (IDLE, ACTIVE) + + GPIO_PinState active_state; // The state when the button is active (pressed) + + uint8_t last_tick; // Last remembered time before steps + uint8_t timer_debounce_on; // Fixed, settable time for debounce timer + uint8_t timer_debounce_off; // Fixed, settable time for debounce timer + + buttonPressed_t buttonReleased; // A callback for button released + buttonPressed_t buttonPressed; // A callback for button pressed +}; + +typedef void (*ButtonRoutine_t)(ButtonKey_t *); + +void buttonHandler(ButtonKey_t *key); \ No newline at end of file