Advertisement
alexander_seredinov

su_button.c

Jun 25th, 2019
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.52 KB | None | 0 0
  1. #include "su_button.h"
  2.  
  3. #define BTNS_COUNT  8
  4.  
  5. typedef struct  
  6. {
  7.     GPIO_PinState  button_pin_state;
  8.     uint32_t cntr_ms;
  9.    
  10.     uint32_t down_event_tick;
  11.     int long_press_state;
  12.    
  13.     Su_OnButtonEventCallback cbOnDown;
  14.     Su_OnButtonEventCallback cbOnUp;
  15.     Su_OnButtonEventCallback cbOnLongPress;
  16.    
  17.     GPIO_TypeDef *GPIOx;
  18.     uint16_t GPIO_Pin;
  19.    
  20.     GPIO_PinState ps_down;
  21.     GPIO_PinState ps_up;
  22. } Su_ButtonEnv;
  23.  
  24.  
  25. uint32_t su_btn_debounce_delay = 80;
  26. uint32_t su_btn_longpress_interval = 1000;
  27. uint32_t su_btn_count = BTNS_COUNT;
  28.  
  29. Su_ButtonEnv su_buttons [BTNS_COUNT] = {
  30.     // 0
  31.     {   .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
  32.         .cntr_ms = 0,
  33.         .down_event_tick = 0,
  34.         .long_press_state = 0,
  35.         .cbOnDown = 0,
  36.         .cbOnUp = 0,
  37.         .cbOnLongPress = 0,
  38.         .GPIOx = 0,
  39.         .GPIO_Pin = 0,
  40.         .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
  41.         .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
  42.     },
  43.    
  44.     // 1
  45.     {   .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
  46.         .cntr_ms = 0,
  47.         .down_event_tick = 0,
  48.         .long_press_state = 0,
  49.         .cbOnDown = 0,
  50.         .cbOnUp = 0,
  51.         .cbOnLongPress = 0,
  52.         .GPIOx = 0,
  53.         .GPIO_Pin = 0,
  54.         .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
  55.         .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
  56.     },
  57.    
  58.     // 2
  59.     {   .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
  60.         .cntr_ms = 0,
  61.         .down_event_tick = 0,
  62.         .long_press_state = 0,
  63.         .cbOnDown = 0,
  64.         .cbOnUp = 0,
  65.         .cbOnLongPress = 0,
  66.         .GPIOx = 0,
  67.         .GPIO_Pin = 0,
  68.         .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
  69.         .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
  70.     },
  71.    
  72.     // 3
  73.     {   .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
  74.         .cntr_ms = 0,
  75.         .down_event_tick = 0,
  76.         .long_press_state = 0,
  77.         .cbOnDown = 0,
  78.         .cbOnUp = 0,
  79.         .cbOnLongPress = 0,
  80.         .GPIOx = 0,
  81.         .GPIO_Pin = 0,
  82.         .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
  83.         .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
  84.     },
  85.    
  86.     // 4
  87.     {   .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
  88.         .cntr_ms = 0,
  89.         .down_event_tick = 0,
  90.         .long_press_state = 0,
  91.         .cbOnDown = 0,
  92.         .cbOnUp = 0,
  93.         .cbOnLongPress = 0,
  94.         .GPIOx = 0,
  95.         .GPIO_Pin = 0,
  96.         .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
  97.         .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
  98.     },
  99.    
  100.     // 5
  101.     {   .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
  102.         .cntr_ms = 0,
  103.         .down_event_tick = 0,
  104.         .long_press_state = 0,
  105.         .cbOnDown = 0,
  106.         .cbOnUp = 0,
  107.         .cbOnLongPress = 0,
  108.         .GPIOx = 0,
  109.         .GPIO_Pin = 0,
  110.         .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
  111.         .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
  112.     },
  113.    
  114.     // 6
  115.     {   .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
  116.         .cntr_ms = 0,
  117.         .down_event_tick = 0,
  118.         .long_press_state = 0,
  119.         .cbOnDown = 0,
  120.         .cbOnUp = 0,
  121.         .cbOnLongPress = 0,
  122.         .GPIOx = 0,
  123.         .GPIO_Pin = 0,
  124.         .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
  125.         .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
  126.     },
  127.    
  128.     // 7
  129.     {   .button_pin_state = BUTTON_UP_DEFAULT_PIN_STATE,
  130.         .cntr_ms = 0,
  131.         .down_event_tick = 0,
  132.         .long_press_state = 0,
  133.         .cbOnDown = 0,
  134.         .cbOnUp = 0,
  135.         .cbOnLongPress = 0,
  136.         .GPIOx = 0,
  137.         .GPIO_Pin = 0,
  138.         .ps_down = BUTTON_DOWN_DEFAULT_PIN_STATE,
  139.         .ps_up = BUTTON_UP_DEFAULT_PIN_STATE
  140.     }
  141.    
  142.     //check out BTNS_COUNT
  143. };
  144.  
  145.  
  146. uint32_t su_btnGetTickDelta(uint32_t now, uint32_t last)
  147. {
  148.     if (now >= last)
  149.         return now - last;
  150.  
  151.     return (0xffffffff - last) + now;
  152. }
  153.  
  154.  
  155. uint32_t su_btnGetDebounceTimeoutMs(void)
  156. {
  157.     return su_btn_debounce_delay;
  158. }
  159.  
  160. void        su_btnSetDebounceTimeout(uint32_t ms)
  161. {
  162.     su_btn_debounce_delay = ms;
  163. }
  164.  
  165. uint32_t su_btnGetLongPressIntervalMs(void)
  166. {
  167.     return su_btn_longpress_interval;
  168. }
  169.  
  170. void            su_btnSetLongPressIntervalMs(uint32_t ms)
  171. {
  172.     su_btn_longpress_interval = ms;
  173. }
  174.  
  175. uint32_t    su_btnGetMaxButtonsCount(void)
  176. {
  177.     return BTNS_COUNT;
  178. }
  179.  
  180. uint32_t    su_btnGetButtonsCount(void)
  181. {
  182.     return su_btn_count;
  183. }
  184.  
  185. void        su_btnSetButtonsCount(uint32_t count)
  186. {
  187.     su_btn_count = (count > BTNS_COUNT ) ? BTNS_COUNT : count;
  188. }
  189.  
  190.  
  191. void su_btnSetupPin(uint32_t button_index, GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
  192. {
  193.     if (button_index >= BTNS_COUNT)
  194.         return;
  195.    
  196.     Su_ButtonEnv *benv = su_buttons + button_index;
  197.        
  198.     benv->GPIOx = GPIOx;
  199.     benv->GPIO_Pin = GPIO_Pin;
  200. }
  201.  
  202. void su_btnSetEventCallback(uint32_t button_index, Su_ButtonEvent be, Su_OnButtonEventCallback ecb)
  203. {
  204.     if (button_index >= BTNS_COUNT)
  205.         return;
  206.    
  207.     Su_ButtonEnv *benv = su_buttons + button_index;
  208.    
  209.     switch (be) {
  210.     case BE_DOWN:
  211.         benv->cbOnDown = ecb;
  212.         break;
  213.     case BE_UP:
  214.         benv->cbOnUp = ecb;
  215.         break;
  216.     case BE_LONG_PRESS:
  217.         benv->cbOnLongPress = ecb;
  218.         break;
  219.     };
  220.    
  221. }
  222.  
  223. void su_btnSetAllEventsCallback(uint32_t button_index, Su_OnButtonEventCallback ecb)
  224. {
  225.         if (button_index >= BTNS_COUNT)
  226.         return;
  227.    
  228.         Su_ButtonEnv *benv = su_buttons + button_index;
  229.  
  230.         benv->cbOnDown = ecb;
  231.         benv->cbOnUp = ecb;
  232.         benv->cbOnLongPress = ecb;
  233. }
  234.  
  235. void su_btnSetupPinStates(int button_index, GPIO_PinState ps_down, GPIO_PinState ps_up)
  236. {
  237.     if (button_index >= BTNS_COUNT)
  238.         return;
  239.    
  240.     if (ps_down == ps_up)
  241.         return;
  242.    
  243.     Su_ButtonEnv *benv = su_buttons + button_index;
  244.    
  245.     benv->ps_down = ps_down;
  246.     benv->ps_up = ps_up;
  247. }
  248.  
  249.  
  250. void su_btnProcessEvent(int button_index, Su_ButtonEnv *benv, uint32_t now_tick)
  251. {
  252.     if (benv->button_pin_state == benv->ps_down) {
  253.         benv->down_event_tick = now_tick;
  254.         if (benv->cbOnDown != 0)
  255.             benv->cbOnDown(button_index, BE_DOWN);
  256.        
  257.     } else {
  258.         benv->long_press_state = 0;
  259.         if (benv->cbOnUp != 0)
  260.             benv->cbOnUp(button_index, BE_UP);
  261.     }
  262. }
  263.  
  264.  
  265. void su_btnDoPollingAtIndex(int button_index, uint32_t now_tick, uint32_t delta_tick)
  266. {
  267.     Su_ButtonEnv *benv = su_buttons + button_index;
  268.    
  269.     GPIO_PinState ps = (benv->GPIOx->IDR & benv->GPIO_Pin)?GPIO_PIN_SET:GPIO_PIN_RESET;
  270.    
  271.     if (ps == benv->button_pin_state) {
  272.         benv->cntr_ms = 0;
  273.        
  274.         if (ps == benv->ps_down) {
  275.             if (!benv->long_press_state && benv->cbOnLongPress != 0) {
  276.            
  277.                 uint32_t delta = su_btnGetTickDelta(now_tick, benv->down_event_tick);
  278.            
  279.                 if (delta >= su_btn_longpress_interval) {
  280.                     benv->long_press_state = 1;
  281.                     benv->cbOnLongPress(button_index, BE_LONG_PRESS);
  282.                 }
  283.             }
  284.         }
  285.        
  286.         return;
  287.     }
  288.    
  289.     benv->cntr_ms += delta_tick;
  290.    
  291.     if (benv->cntr_ms < su_btn_debounce_delay)
  292.         return;
  293.    
  294.     benv->cntr_ms = 0;
  295.     benv->button_pin_state = ps;
  296.    
  297.     su_btnProcessEvent(button_index, benv, now_tick);
  298. }
  299.  
  300. void su_btnDoPolling(void)
  301. {
  302.    
  303.     static uint32_t last_tick = 0;
  304.    
  305.     uint32_t now_tick = HAL_GetTick();
  306.    
  307.     uint32_t delta_tick = su_btnGetTickDelta(now_tick, last_tick);
  308.    
  309.     if (delta_tick == 0)
  310.         return;
  311.    
  312.     last_tick = now_tick;
  313.    
  314.     for(int i = 0; i < su_btn_count; i++)
  315.         su_btnDoPollingAtIndex(i, now_tick, delta_tick);
  316. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement