/* * Copyright (c) 2016 Zibin Zheng * All rights reserved */ #ifndef _MULTI_BUTTON_H_ #define _MULTI_BUTTON_H_ #include #include // Configuration constants - can be modified according to your needs #define TICKS_INTERVAL 5 // ms - timer interrupt interval #define DEBOUNCE_TICKS 3 // MAX 7 (0 ~ 7) - debounce filter depth #define SHORT_TICKS (300 / TICKS_INTERVAL) // short press threshold #define LONG_TICKS (1000 / TICKS_INTERVAL) // long press threshold #define PRESS_REPEAT_MAX_NUM 15 // maximum repeat counter value // Forward declaration typedef struct _Button Button; // Button callback function type typedef void (*BtnCallback)(Button* btn_handle); // Button event types typedef enum { BTN_PRESS_DOWN = 0, // button pressed down BTN_PRESS_UP, // button released BTN_PRESS_REPEAT, // repeated press detected BTN_SINGLE_CLICK, // single click completed BTN_DOUBLE_CLICK, // double click completed BTN_LONG_PRESS_START, // long press started BTN_LONG_PRESS_HOLD, // long press holding BTN_EVENT_COUNT, // total number of events BTN_NONE_PRESS // no event } ButtonEvent; // Button state machine states typedef enum { BTN_STATE_IDLE = 0, // idle state BTN_STATE_PRESS, // pressed state BTN_STATE_RELEASE, // released state waiting for timeout BTN_STATE_REPEAT, // repeat press state BTN_STATE_LONG_HOLD // long press hold state } ButtonState; // Button structure struct _Button { uint16_t ticks; // tick counter uint8_t repeat : 4; // repeat counter (0-15) uint8_t event : 4; // current event (0-15) uint8_t state : 3; // state machine state (0-7) uint8_t debounce_cnt : 3; // debounce counter (0-7) uint8_t active_level : 1; // active GPIO level (0 or 1) uint8_t button_level : 1; // current button level uint8_t button_id; // button identifier uint8_t (*hal_button_level)(uint8_t button_id); // HAL function to read GPIO BtnCallback cb[BTN_EVENT_COUNT]; // callback function array Button* next; // next button in linked list }; #ifdef __cplusplus extern "C" { #endif // Public API functions void button_init(Button* handle, uint8_t(*pin_level)(uint8_t), uint8_t active_level, uint8_t button_id); void button_attach(Button* handle, ButtonEvent event, BtnCallback cb); void button_detach(Button* handle, ButtonEvent event); ButtonEvent button_get_event(Button* handle); int button_start(Button* handle); void button_stop(Button* handle); void button_ticks(void); // Utility functions uint8_t button_get_repeat_count(Button* handle); void button_reset(Button* handle); int button_is_pressed(Button* handle); #ifdef __cplusplus } #endif #endif