1 /*
2  * Copyright 2018-2019 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef __BUTTON_H__
10 #define __BUTTON_H__
11 
12 #include "fsl_common.h"
13 #if (defined(COMMON_TASK_ENABLE) && (COMMON_TASK_ENABLE == 0U))
14 #include "fsl_component_common_task.h"
15 #endif /* COMMON_TASK_ENABLE */
16 #include "fsl_adapter_gpio.h"
17 /*!
18  * @addtogroup Button
19  * @{
20  */
21 
22 /*******************************************************************************
23  * Definitions
24  ******************************************************************************/
25 /*! @brief Definition of feature 'one click' enable macro. */
26 #ifndef BUTTON_EVENT_ONECLICK_ENABLE
27 #define BUTTON_EVENT_ONECLICK_ENABLE (1)
28 #endif
29 /*! @brief Definition of feature 'double click' enable macro. */
30 #ifndef BUTTON_EVENT_DOUBLECLICK_ENABLE
31 #define BUTTON_EVENT_DOUBLECLICK_ENABLE (1)
32 #endif
33 /*! @brief Definition of feature 'short press' enable macro. */
34 #ifndef BUTTON_EVENT_SHORTPRESS_ENABLE
35 #define BUTTON_EVENT_SHORTPRESS_ENABLE (1)
36 #endif
37 /*! @brief Definition of feature 'long press' enable macro. */
38 #ifndef BUTTON_EVENT_LONGPRESS_ENABLE
39 #define BUTTON_EVENT_LONGPRESS_ENABLE (1)
40 #endif
41 
42 /*! @brief Definition of all buttons enter/exit lowpower handle macro. */
43 #define BUTTON_ALL_ENTER_EXIT_LOWPOWER_HANDLE ((uint32_t *)0xffffffffU) /* MISRA C-2012 Rule 11.6 */
44 
45 /*! @brief Definition of button handle size as HAL_GPIO_HANDLE_SIZE + button dedicated size. */
46 #define BUTTON_HANDLE_SIZE (16U + 24U)
47 
48 /*! @brief The handle of button */
49 typedef void *button_handle_t;
50 
51 /*!
52  * @brief Defines the button handle
53  *
54  * This macro is used to define a 4 byte aligned button handle.
55  * Then use "(button_handle_t)name" to get the button handle.
56  *
57  * The macro should be global and could be optional. You could also define button handle by yourself.
58  *
59  * This is an example,
60  * @code
61  * BUTTON_HANDLE_DEFINE(buttonHandle);
62  * @endcode
63  *
64  * @param name The name string of the button handle.
65  */
66 #define BUTTON_HANDLE_DEFINE(name) uint32_t name[((BUTTON_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
67 
68 /*!
69  * @brief Defines the button handle array
70  *
71  * This macro is used to define a 4 byte aligned button handle array.
72  * Then use "(button_handle_t)name[0]" to get the first button handle.
73  *
74  * The macro should be global and could be optional. You could also define these button handle by yourself.
75  *
76  * This is an example,
77  * @code
78  * BUTTON_HANDLE_DEFINE(buttonHandleArray, 1);
79  * @endcode
80  *
81  * @param name The name string of the button handle array.
82  * @param count The amount of button handle.
83  */
84 #define BUTTON_HANDLE_ARRAY_DEFINE(name, count) \
85     uint32_t name[count][((BUTTON_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
86 
87 /*! @brief Definition of button timer interval,unit is ms. */
88 #define BUTTON_TIMER_INTERVAL (25U)
89 
90 /*! @brief Definition of button short press threshold,unit is ms. */
91 #ifndef BUTTON_SHORT_PRESS_THRESHOLD
92 #define BUTTON_SHORT_PRESS_THRESHOLD (200U)
93 #endif
94 
95 /*! @brief Definition of button long press threshold,unit is ms. */
96 #ifndef BUTTON_LONG_PRESS_THRESHOLD
97 #define BUTTON_LONG_PRESS_THRESHOLD (500U)
98 #endif
99 
100 /*! @brief Definition of button double click threshold,unit is ms. */
101 #define BUTTON_DOUBLE_CLICK_THRESHOLD (200U)
102 
103 /*! @brief Definition to determine whether use common task. */
104 #ifndef BUTTON_USE_COMMON_TASK
105 #define BUTTON_USE_COMMON_TASK (0U)
106 #if (defined(COMMON_TASK_ENABLE) && (COMMON_TASK_ENABLE == 0U))
107 #undef BUTTON_USE_COMMON_TASK
108 #define BUTTON_USE_COMMON_TASK (0U)
109 #endif
110 #endif
111 
112 /*! @brief Definition of button task priority. */
113 #ifndef BUTTON_TASK_PRIORITY
114 #define BUTTON_TASK_PRIORITY (7U)
115 #endif
116 
117 /*! @brief Definition of button task stack size. */
118 #ifndef BUTTON_TASK_STACK_SIZE
119 #define BUTTON_TASK_STACK_SIZE (1000U)
120 #endif
121 
122 /*! @brief Definition of button event. */
123 #define BUTTON_EVENT_BUTTON (1U)
124 
125 /*! @brief The status type of button */
126 typedef enum _button_status
127 {
128     kStatus_BUTTON_Success    = kStatus_Success,                     /*!< Success */
129     kStatus_BUTTON_Error      = MAKE_STATUS(kStatusGroup_BUTTON, 1), /*!< Failed */
130     kStatus_BUTTON_LackSource = MAKE_STATUS(kStatusGroup_BUTTON, 2), /*!< Lack of sources */
131 } button_status_t;
132 
133 /*! @brief The event type of button */
134 typedef enum _button_event
135 {
136     kBUTTON_EventOneClick = 0x01U, /*!< One click with short time, the duration of key down and key up is less than
137                                       #BUTTON_SHORT_PRESS_THRESHOLD. */
138     kBUTTON_EventDoubleClick,      /*!< Double click with short time, the duration of key down and key up is less than
139                                       #BUTTON_SHORT_PRESS_THRESHOLD.      And the duration of the two button actions does not
140                                       exceed #BUTTON_DOUBLE_CLICK_THRESHOLD. */
141     kBUTTON_EventShortPress,       /*!< Press with short time, the duration of key down and key up is no less than
142                                       #BUTTON_SHORT_PRESS_THRESHOLD       and less than #BUTTON_LONG_PRESS_THRESHOLD. */
143     kBUTTON_EventLongPress,        /*!< Press with long time, the duration of key down and key up is no less than
144                                       #BUTTON_LONG_PRESS_THRESHOLD. */
145     kBUTTON_EventError,            /*!< Error event if the button actions cannot be identified. */
146 } button_event_t;
147 
148 /*! @brief The callback message struct of button */
149 typedef struct _button_callback_message_struct
150 {
151     button_event_t event;
152 } button_callback_message_t;
153 
154 /*! @brief The callback function of button */
155 typedef button_status_t (*button_callback_t)(void *buttonHandle,
156                                              button_callback_message_t *message,
157                                              void *callbackParam);
158 
159 /*! @brief The button gpio config structure */
160 typedef struct _button_gpio_config
161 {
162     hal_gpio_direction_t direction; /*!< GPIO Pin direction (0 - In, 1 - Out)*/
163     uint8_t pinStateDefault;        /*!< GPIO Pin voltage when button is not pressed (0 - low level, 1 - high level)*/
164     uint8_t port;                   /*!< GPIO Port */
165     uint8_t pin;                    /*!< GPIO Pin */
166 } button_gpio_config_t;
167 
168 /*! @brief The button config structure */
169 typedef struct _button_config
170 {
171     button_gpio_config_t gpio;
172 } button_config_t;
173 
174 /*******************************************************************************
175  * API
176  ******************************************************************************/
177 
178 #if defined(__cplusplus)
179 extern "C" {
180 #endif /* __cplusplus */
181 
182 /*!
183  * @name Initialization
184  * @{
185  */
186 
187 /*!
188  * @brief Initializes a button with the button handle and the user configuration structure.
189  *
190  * This function configures the button with user-defined settings. The user can configure the configuration
191  * structure. The parameter buttonHandle is a pointer to point to a memory space of size #BUTTON_HANDLE_SIZE allocated
192  * by the caller.
193  *
194  * Example below shows how to use this API to configure the button.
195  * For one button,
196  *  @code
197  *   static BUTTON_HANDLE_DEFINE(s_buttonHandle);
198  *   button_config_t buttonConfig;
199  *   buttonConfig.gpio.port = 0;
200  *   buttonConfig.gpio.pin = 1;
201  *   buttonConfig.gpio.pinStateDefault = 0;
202  *   BUTTON_Init((button_handle_t)s_buttonHandle, &buttonConfig);
203  *  @endcode
204  * For multiple buttons,
205  *  @code
206  *   static BUTTON_HANDLE_ARRAY_DEFINE(s_buttonArrayHandle, count);
207  *   button_config_t buttonArrayConfig[count];
208  *   for(uint8_t i = 0U; i < count; i++)
209  *   {
210  *       buttonArrayConfig[i].gpio.port = 0;
211  *       buttonArrayConfig[i].gpio.pin = 1;
212  *       buttonArrayConfig[i].gpio.pinStateDefault = 0;
213  *       BUTTON_Init((button_handle_t)s_buttonArrayHandle[i], &buttonArrayConfig[i]);
214  *   }
215  *  @endcode
216  *
217  * @param buttonHandle Pointer to point to a memory space of size #BUTTON_HANDLE_SIZE allocated by the caller.
218  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
219  * You can define one handle in the following two ways:
220  * #BUTTON_HANDLE_DEFINE(buttonHandle);
221  * or
222  * uint32_t buttonHandle[((BUTTON_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
223  * You can define multiple handles in the following way:
224  * #BUTTON_HANDLE_ARRAY_DEFINE(buttonHandleArray, count);
225  * @param buttonConfig Pointer to user-defined configuration structure.
226  * @return Indicates whether initialization was successful or not.
227  * @retval kStatus_BUTTON_Error An error occurred.
228  * @retval kStatus_BUTTON_Success Button initialization succeed.
229  */
230 button_status_t BUTTON_Init(button_handle_t buttonHandle, button_config_t *buttonConfig);
231 
232 /*! @}*/
233 
234 /*!
235  * @name Install callback
236  * @{
237  */
238 
239 /*!
240  * @brief Installs a callback and callback parameter.
241  *
242  * This function is used to install the callback and callback parameter for button module.
243  * Once the button is pressed, the button driver will identify the behavior and notify the
244  * upper layer with the button event by the installed callback function. Currently, the Button
245  * supports the three types of event, click, double click and long press. Detail information refer
246  * to #button_event_t.
247  *
248  * @param buttonHandle Button handle pointer.
249  * @param callback The callback function.
250  * @param callbackParam The parameter of the callback function.
251  * @return Indicates whether callback install was successful or not.
252  * @retval kStatus_BUTTON_Success Successfully install the callback.
253  */
254 button_status_t BUTTON_InstallCallback(button_handle_t buttonHandle, button_callback_t callback, void *callbackParam);
255 
256 /*! @}*/
257 
258 /*!
259  * @brief Deinitializes a button instance.
260  *
261  * This function deinitializes the button instance.
262  *
263  * @param buttonHandle button handle pointer.
264  * @retval kStatus_BUTTON_Success button de-initialization succeed.
265  */
266 button_status_t BUTTON_Deinit(button_handle_t buttonHandle);
267 
268 /*!
269  * @brief Get button pin input.
270  *
271  * This function is used for get the button pin input.
272  *
273  * @param buttonHandle button handle pointer.
274  * @param pinState a pointer to save the pin state.
275  * @retval kStatus_BUTTON_Error An error occurred.
276  * @retval kStatus_BUTTON_Success Set successfully.
277  */
278 button_status_t BUTTON_GetInput(button_handle_t buttonHandle, uint8_t *pinState);
279 
280 /*!
281  * @brief Enables or disables the button wake-up feature.
282  *
283  * This function enables or disables the button wake-up feature.
284  *
285  * @param buttonHandle button handle pointer.
286  * @param enable enable or disable (0 - disable, 1 - enable).
287  * @retval kStatus_BUTTON_Error An error occurred.
288  * @retval kStatus_BUTTON_Success Set successfully.
289  */
290 button_status_t BUTTON_WakeUpSetting(button_handle_t buttonHandle, uint8_t enable);
291 
292 /*!
293  * @brief Prepares to enter low power consumption.
294  *
295  * This function is used to prepare to enter low power consumption.
296  *
297  * @param buttonHandle button handle pointer.
298  * @retval kStatus_BUTTON_Success Successful operation.
299  */
300 button_status_t BUTTON_EnterLowpower(button_handle_t buttonHandle);
301 
302 /*!
303  * @brief Restores from low power consumption.
304  *
305  * This function is used to restore from low power consumption.
306  *
307  * @param buttonHandle button handle pointer.
308  * @retval kStatus_BUTTON_Success Successful operation.
309  */
310 button_status_t BUTTON_ExitLowpower(button_handle_t buttonHandle);
311 
312 #if defined(__cplusplus)
313 }
314 #endif /* __cplusplus */
315 
316 /*! @}*/
317 
318 #endif /* __BUTTON_H__ */
319