driver: hw_button

This commit is contained in:
2023-03-26 03:04:58 +02:00
parent 762a4da61e
commit 79e27902ec
3 changed files with 156 additions and 0 deletions

View File

@@ -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);
}
}

View File

@@ -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);