add input_handler module
This commit is contained in:
74
src/input_handler.c
Normal file
74
src/input_handler.c
Normal file
@@ -0,0 +1,74 @@
|
||||
#include <avr/io.h>
|
||||
#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,
|
||||
};
|
||||
46
src/input_handler.h
Normal file
46
src/input_handler.h
Normal file
@@ -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);
|
||||
Reference in New Issue
Block a user