Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "su_button.h"
- #define BTNS_COUNT 8
- typedef struct
- {
- GPIO_PinState button_pin_state;
- uint32_t cntr_ms;
- uint32_t down_event_tick;
- int long_press_state;
- Su_OnButtonEventCallback cbOnDown;
- Su_OnButtonEventCallback cbOnUp;
- Su_OnButtonEventCallback cbOnLongPress;
- GPIO_TypeDef *GPIOx;
- uint16_t GPIO_Pin;
- GPIO_PinState ps_down;
- GPIO_PinState ps_up;
- } Su_ButtonEnv;
- uint32_t su_btn_debounce_delay = 80;
- uint32_t su_btn_longpress_interval = 1000;
- uint32_t su_btn_count = BTNS_COUNT;
- Su_ButtonEnv su_buttons [BTNS_COUNT] = {
- // 0
- { .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
- .cntr_ms = 0,
- .down_event_tick = 0,
- .long_press_state = 0,
- .cbOnDown = 0,
- .cbOnUp = 0,
- .cbOnLongPress = 0,
- .GPIOx = 0,
- .GPIO_Pin = 0,
- .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
- .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
- },
- // 1
- { .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
- .cntr_ms = 0,
- .down_event_tick = 0,
- .long_press_state = 0,
- .cbOnDown = 0,
- .cbOnUp = 0,
- .cbOnLongPress = 0,
- .GPIOx = 0,
- .GPIO_Pin = 0,
- .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
- .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
- },
- // 2
- { .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
- .cntr_ms = 0,
- .down_event_tick = 0,
- .long_press_state = 0,
- .cbOnDown = 0,
- .cbOnUp = 0,
- .cbOnLongPress = 0,
- .GPIOx = 0,
- .GPIO_Pin = 0,
- .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
- .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
- },
- // 3
- { .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
- .cntr_ms = 0,
- .down_event_tick = 0,
- .long_press_state = 0,
- .cbOnDown = 0,
- .cbOnUp = 0,
- .cbOnLongPress = 0,
- .GPIOx = 0,
- .GPIO_Pin = 0,
- .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
- .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
- },
- // 4
- { .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
- .cntr_ms = 0,
- .down_event_tick = 0,
- .long_press_state = 0,
- .cbOnDown = 0,
- .cbOnUp = 0,
- .cbOnLongPress = 0,
- .GPIOx = 0,
- .GPIO_Pin = 0,
- .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
- .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
- },
- // 5
- { .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
- .cntr_ms = 0,
- .down_event_tick = 0,
- .long_press_state = 0,
- .cbOnDown = 0,
- .cbOnUp = 0,
- .cbOnLongPress = 0,
- .GPIOx = 0,
- .GPIO_Pin = 0,
- .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
- .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
- },
- // 6
- { .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
- .cntr_ms = 0,
- .down_event_tick = 0,
- .long_press_state = 0,
- .cbOnDown = 0,
- .cbOnUp = 0,
- .cbOnLongPress = 0,
- .GPIOx = 0,
- .GPIO_Pin = 0,
- .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
- .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
- },
- // 7
- { .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
- .cntr_ms = 0,
- .down_event_tick = 0,
- .long_press_state = 0,
- .cbOnDown = 0,
- .cbOnUp = 0,
- .cbOnLongPress = 0,
- .GPIOx = 0,
- .GPIO_Pin = 0,
- .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
- .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
- }
- //check out BTNS_COUNT
- };
- uint32_t su_btnGetTickDelta(uint32_t now, uint32_t last)
- {
- if (now >= last)
- return now - last;
- return (0xffffffff - last) + now;
- }
- uint32_t su_btnGetDebounceTimeoutMs(void)
- {
- return su_btn_debounce_delay;
- }
- void su_btnSetDebounceTimeout(uint32_t ms)
- {
- su_btn_debounce_delay = ms;
- }
- uint32_t su_btnGetLongPressIntervalMs(void)
- {
- return su_btn_longpress_interval;
- }
- void su_btnSetLongPressIntervalMs(uint32_t ms)
- {
- su_btn_longpress_interval = ms;
- }
- uint32_t su_btnGetMaxButtonsCount(void)
- {
- return BTNS_COUNT;
- }
- uint32_t su_btnGetButtonsCount(void)
- {
- return su_btn_count;
- }
- void su_btnSetButtonsCount(uint32_t count)
- {
- su_btn_count = (count > BTNS_COUNT ) ? BTNS_COUNT : count;
- }
- void su_btnSetupPin(uint32_t button_index, GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
- {
- if (button_index >= BTNS_COUNT)
- return;
- Su_ButtonEnv *benv = su_buttons + button_index;
- benv->GPIOx = GPIOx;
- benv->GPIO_Pin = GPIO_Pin;
- }
- void su_btnSetEventCallback(uint32_t button_index, Su_ButtonEvent be, Su_OnButtonEventCallback ecb)
- {
- if (button_index >= BTNS_COUNT)
- return;
- Su_ButtonEnv *benv = su_buttons + button_index;
- switch (be) {
- case BE_DOWN:
- benv->cbOnDown = ecb;
- break;
- case BE_UP:
- benv->cbOnUp = ecb;
- break;
- case BE_LONG_PRESS:
- benv->cbOnLongPress = ecb;
- break;
- };
- }
- void su_btnSetAllEventsCallback(uint32_t button_index, Su_OnButtonEventCallback ecb)
- {
- if (button_index >= BTNS_COUNT)
- return;
- Su_ButtonEnv *benv = su_buttons + button_index;
- benv->cbOnDown = ecb;
- benv->cbOnUp = ecb;
- benv->cbOnLongPress = ecb;
- }
- void su_btnSetupPinStates(int button_index, GPIO_PinState ps_down, GPIO_PinState ps_up)
- {
- if (button_index >= BTNS_COUNT)
- return;
- if (ps_down == ps_up)
- return;
- Su_ButtonEnv *benv = su_buttons + button_index;
- benv->ps_down = ps_down;
- benv->ps_up = ps_up;
- }
- void su_btnProcessEvent(int button_index, Su_ButtonEnv *benv, uint32_t now_tick)
- {
- if (benv->button_pin_state == benv->ps_down) {
- benv->down_event_tick = now_tick;
- if (benv->cbOnDown != 0)
- benv->cbOnDown(button_index, BE_DOWN);
- } else {
- benv->long_press_state = 0;
- if (benv->cbOnUp != 0)
- benv->cbOnUp(button_index, BE_UP);
- }
- }
- void su_btnDoPollingAtIndex(int button_index, uint32_t now_tick, uint32_t delta_tick)
- {
- Su_ButtonEnv *benv = su_buttons + button_index;
- GPIO_PinState ps = (benv->GPIOx->IDR & benv->GPIO_Pin)?GPIO_PIN_SET:GPIO_PIN_RESET;
- if (ps == benv->button_pin_state) {
- benv->cntr_ms = 0;
- if (ps == benv->ps_down) {
- if (!benv->long_press_state && benv->cbOnLongPress != 0) {
- uint32_t delta = su_btnGetTickDelta(now_tick, benv->down_event_tick);
- if (delta >= su_btn_longpress_interval) {
- benv->long_press_state = 1;
- benv->cbOnLongPress(button_index, BE_LONG_PRESS);
- }
- }
- }
- return;
- }
- benv->cntr_ms += delta_tick;
- if (benv->cntr_ms < su_btn_debounce_delay)
- return;
- benv->cntr_ms = 0;
- benv->button_pin_state = ps;
- su_btnProcessEvent(button_index, benv, now_tick);
- }
- void su_btnDoPolling(void)
- {
- static uint32_t last_tick = 0;
- uint32_t now_tick = HAL_GetTick();
- uint32_t delta_tick = su_btnGetTickDelta(now_tick, last_tick);
- if (delta_tick == 0)
- return;
- last_tick = now_tick;
- for(int i = 0; i < su_btn_count; i++)
- su_btnDoPollingAtIndex(i, now_tick, delta_tick);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement