1 /* 2 * Copyright (c) 2016-2019, Texas Instruments Incorporated 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of Texas Instruments Incorporated nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /*!*************************************************************************** 34 * @file Button.h 35 * 36 * @brief Button driver 37 * 38 * @anchor ti_drivers_Button_Synopsis 39 * # Synopsis # 40 * 41 * @code 42 * #include <ti/drivers/apps/Button.h> 43 * 44 * int main(void) 45 * { 46 * Button_Params params; 47 * Button_Handle handle; 48 * 49 * Button_Params_init(¶ms); 50 * 51 * handle = Button_open(CONFIG_BUTTON0, buttonCallbackFxn, ¶ms); 52 * 53 * ... 54 * } 55 * 56 * void buttonCallbackFxn(Button_Handle handle, Button_EventMask events) 57 * { 58 * if (events & Button_EV_CLICK) 59 * { 60 * // Received a click, handle app condition 0 etc 61 * handleAppCond(0); 62 * } 63 * if (events & Button_EV_LONGCLICKED) 64 * { 65 * // Long press, handle app condition 1 etc 66 * handleAppCond(1); 67 * } 68 * ... 69 * } 70 * @endcode 71 * 72 * @anchor ti_drivers_Button_Examples 73 * ## Examples # 74 * 75 * * @ref ti_drivers_Button_Examples_config "Generic Configuration" 76 * 77 * ## Overview # 78 * 79 * The Button driver simplifies interfacing push buttons. For example, push 80 * buttons on LaunchPads, BoosterPacks, or custom boards may easily be managed 81 * via the Button API. A given button instance may subscribe to one or several 82 * #Button_Events. When a subscribed event occurs, the user will receive a 83 * callback with the handle of the button and the event(s) that occured. 84 * 85 * ## User requirements # 86 * Buttons use the @ref GPIO.h interface for interfacing with hardware, so a 87 * #GPIO_PinConfig array must exist and contain a config for the button pin. 88 * The user must statically allocate a #Button_Config array called 89 * Button_config. Each physical button should map to an index in 90 * Button_config. 91 * 92 * ## Defining #Button_Config, #Button_Object and #Button_HWAttrs # 93 * Each structure must be defined by the application. The following 94 * example is for a MSP432 in which two buttons are setup. 95 * The following declarations are placed in "ti_drivers_config.h" 96 * and "ti_drivers_config.c" respectively. How the GPIO configs are defined 97 * are detailed in the next example. 98 * 99 * @anchor ti_drivers_Button_Examples_config 100 * 101 * "ti_drivers_config.h" 102 * @code 103 * #define CONFIG_BUTTON_0 0 //Button number 1 104 * #define CONFIG_BUTTON_1 1 //Button number 2 105 * @endcode 106 * 107 * "ti_drivers_config.c" 108 * @code 109 * #include <Button.h> 110 * 111 * Button_Object Button_object[2]; 112 * 113 * const Button_HWAttrs Button_hwAttrs[2] = { 114 * { 115 * .gpioIndex = CONFIG_S1, 116 * }, 117 * { 118 * .gpioIndex = CONFIG_S2, 119 * } 120 * }; 121 * 122 * const Button_Config Button_config[2] = { 123 * { 124 * .hwAttrs = &Button_hwAttrs[0], 125 * .object = &Button_object[0], 126 * }, 127 * { 128 * .hwAttrs = &Button_hwAttrs[1], 129 * .object = &Button_object[1], 130 * }, 131 * }; 132 * @endcode 133 * 134 * ##Setting up GPIO configurations # 135 * 136 * The following example is for a MSP432. 137 * We are showing interfacing of two push buttons. Each need a GPIO pin. The 138 * following definitions are in "ti_drivers_config.h" and 139 * "ti_drivers_config.c" respectively. This example uses GPIO pins 1.1 and 140 * 1.4. The other GPIO configuration structures must exist, see @ref GPIO.h. 141 * 142 * "ti_drivers_config.h" 143 * @code 144 * #define CONFIG_S1 0 145 * #define CONFIG_S2 1 146 * @endcode 147 * 148 * "ti_drivers_config.c" 149 * @code 150 * #include <gpio.h> 151 * GPIO_PinConfig gpioPinConfigs[] = { 152 * GPIOMSP432_P1_1 | GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING, 153 * GPIOMSP432_P1_4 | GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING, 154 * } 155 * 156 * @endcode 157 ****************************************************************************** 158 */ 159 #ifndef ti_drivers_Button__include 160 #define ti_drivers_Button__include 161 162 #include <stdint.h> 163 #include <stdbool.h> 164 165 /* Driver Header files */ 166 #include <ti/drivers/GPIO.h> 167 #include <ti/drivers/dpl/ClockP.h> 168 169 #ifdef __cplusplus 170 extern "C" { 171 #endif 172 173 /* Number of user defined Button configurations */ 174 extern const uint_least8_t Button_count; 175 176 /*! 177 * @brief Button configuration 178 * 179 * Each #Button_Config represents a single physical button. It contains 180 * pointers to the button's #Button_HWAttrs and #Button_Object. The user must 181 * statically allocate all of these structures. 182 */ 183 typedef struct Button_Config 184 { 185 /*! Pointer to a #Button_Object struct */ 186 void *object; 187 188 /*! Pointer to a #Button_HWAttrs structure */ 189 void const *hwAttrs; 190 }Button_Config; 191 192 /*! 193 * @brief A handle that is returned from a Button_open() call. 194 * 195 * User will use this handle to interact with a given button instance. 196 */ 197 typedef struct Button_Config* Button_Handle; 198 199 /*! 200 * @brief Button State 201 * @private 202 * 203 * This enumeration describes whether the button is pressed or released etc. 204 * This is for internal state machine handling. 205 */ 206 typedef enum Button_State 207 { 208 /*! Edge detected, debouncing */ 209 Button_PRESSING = 1, 210 /*! Press verified, not detecting longpress */ 211 Button_PRESSED = 2, 212 /*! Press verified, waiting for longpress timeout. */ 213 Button_LONGPRESSING = 3, 214 /*! Longpress verified, waiting for neg-edge */ 215 Button_LONGPRESSED = 4, 216 /*! Neg-edge received, debouncing */ 217 Button_RELEASING = 5, 218 /*! Neg-edge received after long-press, debouncing. */ 219 Button_RELEASING_LONG = 6, 220 /*! Button release verified. */ 221 Button_RELEASED = 7, 222 /*! EDGE detected doublepress */ 223 Button_DBLPRESS_DETECTION = 8, 224 /*! EDGE detected doublepress */ 225 Button_DBLPRESSING = 9, 226 /*! DOUBLE PRESS verified, waiting for neg edge */ 227 Button_DBLPRESSED = 10, 228 /*! DOUBLE PRESS verified, waiting for neg edge k*/ 229 Button_RELEASING_DBLPRESSED = 11 230 } Button_State; 231 232 /*! 233 * @brief Button event flags 234 * 235 * The event flags can be used by the user to subscribe to specific kinds of 236 * button actions and by the driver to signal which event caused a callback. 237 */ 238 typedef enum Button_Events 239 { 240 /*! Button pressed down, may or may not subsequently have been released */ 241 Button_EV_PRESSED = 0x01, 242 /*! Button held down for more than tLongpress (ms) */ 243 Button_EV_LONGPRESSED = 0x02, 244 /*! Button released after press or longpress */ 245 Button_EV_RELEASED = 0x04, 246 /*! Button was pressed and released, but was not a long press */ 247 Button_EV_CLICKED = 0x08, 248 /*! 249 * Button was pressed and released, and held for longer than 250 * longPressDuration (ms) 251 */ 252 Button_EV_LONGCLICKED = 0x10, 253 /*! Button was pressed when double click detection was active */ 254 Button_EV_DOUBLECLICKED = 0x20, 255 } Button_Events; 256 257 /*! @brief Event subscription and notification mask type */ 258 typedef uint8_t Button_EventMask; 259 260 /*! 261 * @brief A handler to receive button callbacks. 262 */ 263 typedef void (*Button_Callback)(Button_Handle buttonHandle, 264 Button_EventMask buttonEvents); 265 266 /*! 267 * @brief Button Pull settings 268 * 269 * This enumeration defines whether the GPIO connected to the button 270 * is PULL UP or PULL DOWN 271 */ 272 typedef enum Button_Pull 273 { 274 /* NOTE: DO NOT change the values of DOWN/UP from (0,1) */ 275 Button_PULL_DOWN = 0, /*!< Button is PULLED DOWN. */ 276 Button_PULL_UP = 1, /*!< Button is PULLED UP. */ 277 Button_PULL_NOTSET = 2 /*!< Button pull not set */ 278 } Button_Pull; 279 280 /*! 281 * @brief Hardware specific settings for a button 282 * 283 * This structure should be defined and provided by the application. 284 * The index provided should correspond to a gpio pin in a #GPIO_PinConfig 285 * array. This gpio pin should be the pin connected to the button and must 286 * be configured as #GPIO_CFG_INPUT and #GPIO_CFG_IN_INT_FALLING. 287 */ 288 typedef struct Button_HWAttrs 289 { 290 uint_least8_t gpioIndex; /*!< GPIO configuration index. */ 291 } Button_HWAttrs; 292 293 /*! 294 * @brief Button State Variables 295 * @private 296 * 297 * Each button instance needs set of variables to monitor its state. 298 * We group these variables under the structure Button_State. 299 * 300 * @sa Button_Params_init() 301 */ 302 typedef struct Button_StateVariables 303 { 304 /*! Button state */ 305 Button_State state; 306 /*! Button pressed start time in milliseconds(ms) */ 307 uint32_t pressedStartTime; 308 /*! Button pressed duration (ms) */ 309 uint32_t lastPressedDuration; 310 }Button_StateVariables; 311 312 /*! 313 * @brief Internal to Button module. Members should not be accessed 314 * by the application. 315 */ 316 typedef struct Button_Object 317 { 318 /*! Handle to clock used for timing */ 319 ClockP_Handle clockHandle; 320 321 /*! State variables for handling the debounce state machine */ 322 Button_StateVariables buttonStateVariables; 323 324 /*! Event subscription mask for the button */ 325 Button_EventMask buttonEventMask; 326 327 /*! Callback function for the button */ 328 Button_Callback buttonCallback; 329 330 /*! Debounce duration for the button in milliseconds(ms) */ 331 uint32_t debounceDuration; 332 333 /*! Long press duration is milliseconds(ms) */ 334 uint32_t longPressDuration; 335 336 /*! Double press detection timeout is milliseconds(ms) */ 337 uint32_t doublePressDetectiontimeout; 338 339 /*! Button pull(stored after reading from GPIO module) */ 340 Button_Pull buttonPull; 341 } Button_Object; 342 343 /*! 344 * @brief Button Parameters 345 * 346 * Button parameters are used with the Button_open() call. Default values for 347 * these parameters are set using Button_Params_init(). 348 * 349 * @sa Button_Params_init() 350 */ 351 typedef struct Button_Params 352 { 353 /*! Debounce duration for the button in milliseconds(ms) */ 354 uint32_t debounceDuration; 355 356 /*! Long press duration is milliseconds(ms) */ 357 uint32_t longPressDuration; 358 359 /*! Double press detection timeout is milliseconds(ms) */ 360 uint32_t doublePressDetectiontimeout; 361 362 /*! Event subscription mask for the button */ 363 Button_EventMask buttonEventMask; 364 } Button_Params; 365 366 /*! 367 * @brief Function to close a Button specified by the #Button_Handle 368 * 369 * @pre Button_open() had to be called first. 370 * 371 * @param[in] handle A #Button_Handle returned from Button_open() call 372 * 373 * @return True on success or false upon failure. 374 */ 375 extern bool Button_close(Button_Handle handle); 376 377 /*! 378 * @brief Function to initialize Button driver. 379 */ 380 extern void Button_init(); 381 382 /*! 383 * @brief Function to open a given Button 384 * 385 * Function to open a button instance corresponding to a #Button_Config in the 386 * Button_config array. The GPIO configurations must exist prior to calling 387 * this function. The #Button_Params may be used to specify runtime parameters. 388 * 389 * @pre Button_init() has to be called first 390 * 391 * @param[in] buttonIndex Logical button number indexed into 392 * the Button_config table 393 * 394 * @param[in] buttonCallback A #Button_Callback that is called when a desired 395 * event occurs. 396 * 397 * @param[in] *params A pointer to #Button_Params structure. If NULL, 398 * it will use default values. 399 * 400 * @return A #Button_Handle on success, or a NULL on failure. 401 * 402 * @sa Button_init() 403 * @sa Button_Params_init() 404 * @sa Button_close() 405 */ 406 extern Button_Handle Button_open(uint_least8_t buttonIndex, 407 Button_Callback buttonCallback, 408 Button_Params *params); 409 410 /*! 411 * @brief Function to initialize a #Button_Params struct to its defaults 412 * 413 * @param[in] params A pointer to a #Button_Params structure that will be 414 * initialized. 415 * 416 * Default values 417 * ------------------------------------------------------------------ 418 * parameter | value | description | unit 419 * -----------------|--------------|--------------------------|------------ 420 * debounceDuration | 10 | debounce duration | ms 421 * longPressDuration| 2000 | long press duration | ms 422 * buttonEventMask | 0xFF | subscribed to all events | NA 423 */ 424 extern void Button_Params_init(Button_Params *params); 425 426 /*! 427 * @brief Function to return the lastPressedDuration (valid only for short 428 * press, long press) 429 * 430 * The API returns last pressed duration and it is valid only for shortpress, 431 * longpress. If this API is called after receiving an event click or long 432 * click then the API returns the press duration which is time delta between 433 * the press and release of the button. 434 * @note This API call is only valid after a click or long click and not after 435 * a double click. 436 * 437 * @param[in] handle Pointer to the #Button_Handle of the desired button. 438 * 439 * @return time duration in milliseconds. 440 * 441 */ 442 extern uint32_t Button_getLastPressedDuration(Button_Handle handle); 443 444 /*! 445 * @brief Function to set callback function for the button instance 446 * 447 * @param[in] handle A #Button_Handle returned from Button_open() 448 * 449 * @param[in] buttonCallback button callback function 450 * 451 */ 452 extern void Button_setCallback(Button_Handle handle, 453 Button_Callback buttonCallback); 454 455 /*! 456 * @brief This is the GPIO interrupt callback function which is called on a 457 * button press or release. This is internally used by button module. 458 * 459 * This function is internally used by button module for receiving the GPIO 460 * interrupt callbacks. This is exposed to the application for wake up cases. 461 * In some of the MCUs, when in LPDS(Low power deep sleep) the GPIO interrupt 462 * is consumed for wake up, and in order to make the button module work the 463 * the application has to call this API with the index of the GPIO pin which 464 * actually was the reason for the wake up. 465 * 466 * @param[in] index Index of the GPIO for which the button press has to be 467 * detected. This is an index in #GPIO_PinConfig array. 468 */ 469 void Button_gpioCallbackFxn(uint_least8_t index); 470 471 #ifdef __cplusplus 472 } 473 #endif 474 475 #endif /* ti_drivers_Button__include */ 476