Digital Power Starter Kit 3 Firmware
dsPIC33C Boost Converter Voltage Mode Control Example
drv_push_button.c
1 /*
2  * File: switch.c
3  * Author: M91406
4  *
5  * Created on March 12, 2020, 12:10 PM
6  */
7 
8 
9 #include "push_button/app_push_button.h"
10 #include "config/hal.h"
11 
12 // PRIVATE VARIABLE DELARATIONS
13 // (none)
14 
15 /*********************************************************************************
16  * @ingroup lib-layer-push-button-functions-public
17  * @fn volatile uint16_t drv_PushButton_Initialize(volatile struct PUSH_BUTTON_OBJECT_s* pushbtn)
18  * @brief Initializes the push button device driver
19  * @param pushbtn Push button object of type struct PUSH_BUTTON_OBJECT_s*
20  * @return unsigned integer (0=failure, 1=success)
21  *
22  * @details
23  * The push button driver offers typical functions of a human-machine interface
24  * push button such as
25  *
26  * - hardware debouncing
27  * - detection of short press
28  * - detection of long press
29  * - push-button status (pressed/unpressed)
30  * - switch event indication
31  *
32  * Users of this function driver can define and tune delay to adopt
33  * detection delays and related responses to the task execution period
34  * and hardware circuit related dependencies.
35  *
36  **********************************************************************************/
37 
38 volatile uint16_t drv_PushButton_Initialize(volatile struct PUSH_BUTTON_OBJECT_s* pushbtn)
39 {
40  volatile uint16_t retval = 1;
41 
42  SW_USER_Init(); // Initialize GPIO used to read switch
43 
44  // Initializing switch object
45  pushbtn->debounce_delay = 0; // Clear debounce delay
46  pushbtn->long_press_delay = 0; // Clear 'long press" delay
47  pushbtn->status.bits.pressed = false; // Reset PRESSED status
48  pushbtn->status.bits.long_press = false; // Reset LONG_PRESS status
49  pushbtn->status.bits.enabled = false; // Turn off Switch Button
50  pushbtn->status.bits.sw_event = false; // Clear SWITCH EVENT flag
51 
52  return(retval);
53 }
54 
55 /*********************************************************************************
56  * @ingroup lib-layer-push-button-functions-public
57  * @fn volatile uint16_t drv_PushButton_Execute(volatile struct PUSH_BUTTON_OBJECT_s *pushbtn)
58  * @brief Initializes the push button device driver
59  * @param pushbtn Pointer to push button data object of type struct PUSH_BUTTON_OBJECT_s
60  * @return unsigned int (0=failure, 1=success)
61  *
62  * @details
63  * This function has to be called by a task scheduler at a constant frequency.
64  * With ever function call the state of the digital I/O is scanned and monitoring
65  * timers are updated to detect the most recent status of the push button and
66  * detect events like short press, long press and raise the respective events.
67  *
68  **********************************************************************************/
69 
70 volatile uint16_t drv_PushButton_Execute(volatile struct PUSH_BUTTON_OBJECT_s* pushbtn)
71 {
72  volatile uint16_t retval = 1; // Return value
73  static uint16_t press_cnt = 0, release_cnt = 0; // local counters of SWITCH_USER being pressed/released
74  static bool pre_pressed = false, pre_long_press = false;
75 
76  // If switch is disabled, exit here
77  if (!pushbtn->status.bits.enabled)
78  {
79  pushbtn->status.bits.pressed = false; // Mark Switch as RELEASED
80  return(1); // Exit function
81  }
82 
83  // Trigger on a PRESSED event with applied debouncing
84  if ((!SW_USER_Get()) && (!pushbtn->status.bits.pressed)) {
85 
86  // switch button PRESSED event
87  if (++press_cnt >= pushbtn->debounce_delay) {
88  pushbtn->status.bits.pressed = true; // Set PRESSED flag
89  if (pushbtn->event_btn_down != NULL) // Raise Button Event
90  pushbtn->event_btn_down();
91  }
92  }
93  // Trigger on a LONG PRESS event with applied debouncing
94  else if ((!SW_USER_Get()) && (pushbtn->status.bits.pressed)) {
95 
96  // switch button LONG PRESS event
97  if (++press_cnt >= pushbtn->long_press_delay) {
98 
99  if (!pushbtn->status.bits.long_press) // Long Press Event is triggered for the first time
100  if (pushbtn->event_long_press != NULL) // Raise Button Long Press Event
101  pushbtn->event_long_press();
102 
103  pushbtn->status.bits.long_press = true; // Set LONG_PRESS flag
104  press_cnt = pushbtn->long_press_delay; // Clamp counter to threshold
105 
106  if (pushbtn->event_pressed != NULL) // Raise Button Pressed Event
107  pushbtn->event_pressed();
108 
109  }
110 
111  }
112  // Trigger on a RELEASE event with applied debouncing
113  else if ((SW_USER_Get()) && (pushbtn->status.bits.pressed)) {
114 
115  // switch button RELEASE event
116  if (++release_cnt >= pushbtn->debounce_delay) {
117  if (pushbtn->event_btn_up != NULL) // Raise Button Event
118  pushbtn->event_btn_up();
119  pushbtn->status.bits.pressed = false; // Clear PRESSED flag
120  pushbtn->status.bits.long_press = false; // Clear LONG_PRESS flag
121  release_cnt = pushbtn->debounce_delay; // Clamp counter to threshold
122  }
123  }
124  else {
125  press_cnt = 0; // Clear switch debounce counter PRESSED
126  release_cnt = 0; // Clear switch debounce counter RELEASE
127  }
128 
129  // Trigger on switch events
130  pushbtn->status.bits.sw_event = (bool) //(pre_pressed != pushbtn->status.pressed) ;
131  ((pre_pressed != pushbtn->status.bits.pressed) || (pre_long_press != pushbtn->status.bits.long_press));
132 
133  pre_pressed = pushbtn->status.bits.pressed;
134  pre_long_press = pushbtn->status.bits.long_press;
135 
136  return(retval);
137 }
138 
139 /*********************************************************************************
140  * @ingroup lib-layer-push-button-functions-public
141  * @fn volatile uint16_t drv_PushButton_Dispose(volatile struct PUSH_BUTTON_OBJECT_s* pushbtn)
142  * @brief Initializes the push button device driver
143  * @param pushbtn Push button data object of type struct PUSH_BUTTON_OBJECT_s*
144  * @return unsigned int (0=failure, 1=success)
145  * @details
146  * This function will unload the push-button function driver and free its
147  * resources. All user settings will get reset. The PUSH_BUTTON_t data
148  * object holding all user-defined settings of the push-button object need
149  * to be re-initialized before this function driver can be used again.
150  *
151  **********************************************************************************/
152 
153 volatile uint16_t drv_PushButton_Dispose(volatile struct PUSH_BUTTON_OBJECT_s* pushbtn)
154 {
155  volatile uint16_t retval = 1;
156 
157  pushbtn->debounce_delay = 0;
158  pushbtn->status.bits.pressed = false;
159  pushbtn->status.bits.long_press = false;
160  pushbtn->status.bits.enabled = false;
161  SW_USER_Init();
162 
163  return(retval);
164 }
165 
166 // end of file
volatile uint16_t long_press_delay
Number of call cycles until a "long press" switch event is triggered.
volatile uint16_t(* event_pressed)(void)
Function pointer to user function triggering a LONG_PRESS event.
volatile uint16_t(* event_long_press)(void)
Function pointer to user function triggering a LONG_PRESS event.
volatile uint16_t debounce_delay
Number of call cycles until a switch event is triggered.
volatile struct PUSH_BUTTON_STATUS_s status
Status word of the switch object.
volatile bool long_press
Bit 13: Indicates if switch has been pressed for a longer time.
volatile bool sw_event
Bit 0: Event bit indicating a state has changed (cleared automatically)
volatile uint16_t(* event_btn_up)(void)
Function pointer to user function triggering a RELEASE event.
volatile bool pressed
Bit 14: Indicates if the button is pressed or not.
volatile bool enabled
Bit 15: Enables/disables the Switch button object.
volatile uint16_t(* event_btn_down)(void)
Function pointer to user function triggering a PRESSED event.