BLE FOTA APP

Dependencies:   BLE_API mbed

It doesn't work with the default FOTA bootloader. It use NVIC_SystemReset() to enter a bootloader.

Committer:
yihui
Date:
Fri Oct 10 03:36:28 2014 +0000
Revision:
1:a607cd9655d7
use NVIC_SystemReset() to run bootloader

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 1:a607cd9655d7 1 /* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
yihui 1:a607cd9655d7 2 *
yihui 1:a607cd9655d7 3 * The information contained herein is property of Nordic Semiconductor ASA.
yihui 1:a607cd9655d7 4 * Terms and conditions of usage are described in detail in NORDIC
yihui 1:a607cd9655d7 5 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
yihui 1:a607cd9655d7 6 *
yihui 1:a607cd9655d7 7 * Licensees are granted free, non-transferable use of the information. NO
yihui 1:a607cd9655d7 8 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
yihui 1:a607cd9655d7 9 * the file.
yihui 1:a607cd9655d7 10 *
yihui 1:a607cd9655d7 11 */
yihui 1:a607cd9655d7 12
yihui 1:a607cd9655d7 13 /** @file
yihui 1:a607cd9655d7 14 *
yihui 1:a607cd9655d7 15 * @defgroup app_button Button Handler
yihui 1:a607cd9655d7 16 * @{
yihui 1:a607cd9655d7 17 * @ingroup app_common
yihui 1:a607cd9655d7 18 *
yihui 1:a607cd9655d7 19 * @brief Buttons handling module.
yihui 1:a607cd9655d7 20 *
yihui 1:a607cd9655d7 21 * @details The button handler uses the @ref app_gpiote to detect that a button has been
yihui 1:a607cd9655d7 22 * pushed. To handle debouncing, it will start a timer in the GPIOTE event handler.
yihui 1:a607cd9655d7 23 * The button will only be reported as pushed if the corresponding pin is still active when
yihui 1:a607cd9655d7 24 * the timer expires. If there is a new GPIOTE event while the timer is running, the timer
yihui 1:a607cd9655d7 25 * is restarted.
yihui 1:a607cd9655d7 26 * Use the USE_SCHEDULER parameter of the APP_BUTTON_INIT() macro to select if the
yihui 1:a607cd9655d7 27 * @ref app_scheduler is to be used or not.
yihui 1:a607cd9655d7 28 *
yihui 1:a607cd9655d7 29 * @note The app_button module uses the app_timer module. The user must ensure that the queue in
yihui 1:a607cd9655d7 30 * app_timer is large enough to hold the app_timer_stop() / app_timer_start() operations
yihui 1:a607cd9655d7 31 * which will be executed on each event from GPIOTE module (2 operations), as well as other
yihui 1:a607cd9655d7 32 * app_timer operations queued simultaneously in the application.
yihui 1:a607cd9655d7 33 *
yihui 1:a607cd9655d7 34 * @note Even if the scheduler is not used, app_button.h will include app_scheduler.h, so when
yihui 1:a607cd9655d7 35 * compiling, app_scheduler.h must be available in one of the compiler include paths.
yihui 1:a607cd9655d7 36 */
yihui 1:a607cd9655d7 37
yihui 1:a607cd9655d7 38 #ifndef APP_BUTTON_H__
yihui 1:a607cd9655d7 39 #define APP_BUTTON_H__
yihui 1:a607cd9655d7 40
yihui 1:a607cd9655d7 41 #include <stdint.h>
yihui 1:a607cd9655d7 42 #include <stdbool.h>
yihui 1:a607cd9655d7 43 #include "nrf.h"
yihui 1:a607cd9655d7 44 #include "app_error.h"
yihui 1:a607cd9655d7 45 #include "app_scheduler.h"
yihui 1:a607cd9655d7 46 #include "nrf_gpio.h"
yihui 1:a607cd9655d7 47
yihui 1:a607cd9655d7 48 #define APP_BUTTON_SCHED_EVT_SIZE sizeof(app_button_event_t) /**< Size of button events being passed through the scheduler (is to be used for computing the maximum size of scheduler events). */
yihui 1:a607cd9655d7 49 #define APP_BUTTON_PUSH 1 /**< Indicates that a button is pushed. */
yihui 1:a607cd9655d7 50 #define APP_BUTTON_RELEASE 0 /**< Indicates that a button is released. */
yihui 1:a607cd9655d7 51 #define APP_BUTTON_ACTIVE_HIGH 1 /**< Indicates that a button is active high. */
yihui 1:a607cd9655d7 52 #define APP_BUTTON_ACTIVE_LOW 0 /**< Indicates that a button is active low. */
yihui 1:a607cd9655d7 53
yihui 1:a607cd9655d7 54 /**@brief Button event handler type. */
yihui 1:a607cd9655d7 55 typedef void (*app_button_handler_t)(uint8_t pin_no, uint8_t button_action);
yihui 1:a607cd9655d7 56
yihui 1:a607cd9655d7 57 /**@brief Type of function for passing events from the Button Handler module to the scheduler. */
yihui 1:a607cd9655d7 58 typedef uint32_t (*app_button_evt_schedule_func_t) (app_button_handler_t button_handler,
yihui 1:a607cd9655d7 59 uint8_t pin_no,
yihui 1:a607cd9655d7 60 uint8_t button_action);
yihui 1:a607cd9655d7 61
yihui 1:a607cd9655d7 62 /**@brief Button configuration structure. */
yihui 1:a607cd9655d7 63 typedef struct
yihui 1:a607cd9655d7 64 {
yihui 1:a607cd9655d7 65 uint8_t pin_no; /**< Pin to be used as a button. */
yihui 1:a607cd9655d7 66 uint8_t active_state; /**< APP_BUTTON_ACTIVE_HIGH or APP_BUTTON_ACTIVE_LOW. */
yihui 1:a607cd9655d7 67 nrf_gpio_pin_pull_t pull_cfg; /**< Pull-up or -down configuration. */
yihui 1:a607cd9655d7 68 app_button_handler_t button_handler; /**< Handler to be called when button is pushed. */
yihui 1:a607cd9655d7 69 } app_button_cfg_t;
yihui 1:a607cd9655d7 70
yihui 1:a607cd9655d7 71 /**@brief Pin transition direction struct. */
yihui 1:a607cd9655d7 72 typedef struct
yihui 1:a607cd9655d7 73 {
yihui 1:a607cd9655d7 74 uint32_t high_to_low; /**Pin went from high to low */
yihui 1:a607cd9655d7 75 uint32_t low_to_high; /**Pin went from low to high */
yihui 1:a607cd9655d7 76 } pin_transition_t;
yihui 1:a607cd9655d7 77
yihui 1:a607cd9655d7 78 /**@brief Macro for initializing the Button Handler module.
yihui 1:a607cd9655d7 79 *
yihui 1:a607cd9655d7 80 * @details It will initialize the specified pins as buttons, and configure the Button Handler
yihui 1:a607cd9655d7 81 * module as a GPIOTE user (but it will not enable button detection). It will also connect
yihui 1:a607cd9655d7 82 * the Button Handler module to the scheduler (if specified).
yihui 1:a607cd9655d7 83 *
yihui 1:a607cd9655d7 84 * @param[in] BUTTONS Array of buttons to be used (type app_button_cfg_t, must be
yihui 1:a607cd9655d7 85 * static!).
yihui 1:a607cd9655d7 86 * @param[in] BUTTON_COUNT Number of buttons.
yihui 1:a607cd9655d7 87 * @param[in] DETECTION_DELAY Delay from a GPIOTE event until a button is reported as pushed.
yihui 1:a607cd9655d7 88 * @param[in] USE_SCHEDULER TRUE if the application is using the event scheduler,
yihui 1:a607cd9655d7 89 * FALSE otherwise.
yihui 1:a607cd9655d7 90 */
yihui 1:a607cd9655d7 91 /*lint -emacro(506, APP_BUTTON_INIT) */ /* Suppress "Constant value Boolean */
yihui 1:a607cd9655d7 92 #define APP_BUTTON_INIT(BUTTONS, BUTTON_COUNT, DETECTION_DELAY, USE_SCHEDULER) \
yihui 1:a607cd9655d7 93 do \
yihui 1:a607cd9655d7 94 { \
yihui 1:a607cd9655d7 95 uint32_t ERR_CODE = app_button_init((BUTTONS), \
yihui 1:a607cd9655d7 96 (BUTTON_COUNT), \
yihui 1:a607cd9655d7 97 (DETECTION_DELAY), \
yihui 1:a607cd9655d7 98 (USE_SCHEDULER) ? app_button_evt_schedule : NULL); \
yihui 1:a607cd9655d7 99 APP_ERROR_CHECK(ERR_CODE); \
yihui 1:a607cd9655d7 100 } while (0)
yihui 1:a607cd9655d7 101
yihui 1:a607cd9655d7 102 /**@brief Function for initializing the Buttons.
yihui 1:a607cd9655d7 103 *
yihui 1:a607cd9655d7 104 * @details This function will initialize the specified pins as buttons, and configure the Button
yihui 1:a607cd9655d7 105 * Handler module as a GPIOTE user (but it will not enable button detection).
yihui 1:a607cd9655d7 106 *
yihui 1:a607cd9655d7 107 * @note Normally initialization should be done using the APP_BUTTON_INIT() macro, as that will take
yihui 1:a607cd9655d7 108 * care of connecting the Buttons module to the scheduler (if specified).
yihui 1:a607cd9655d7 109 *
yihui 1:a607cd9655d7 110 * @note app_button_enable() function must be called in order to enable the button detection.
yihui 1:a607cd9655d7 111 *
yihui 1:a607cd9655d7 112 * @param[in] p_buttons Array of buttons to be used (NOTE: Must be static!).
yihui 1:a607cd9655d7 113 * @param[in] button_count Number of buttons.
yihui 1:a607cd9655d7 114 * @param[in] detection_delay Delay from a GPIOTE event until a button is reported as pushed.
yihui 1:a607cd9655d7 115 * @param[in] evt_schedule_func Function for passing button events to the scheduler. Point to
yihui 1:a607cd9655d7 116 * app_button_evt_schedule() to connect to the scheduler. Set to
yihui 1:a607cd9655d7 117 * NULL to make the Buttons module call the event handler directly
yihui 1:a607cd9655d7 118 * from the delayed button push detection timeout handler.
yihui 1:a607cd9655d7 119 *
yihui 1:a607cd9655d7 120 * @return NRF_SUCCESS on success, otherwise an error code.
yihui 1:a607cd9655d7 121 */
yihui 1:a607cd9655d7 122 uint32_t app_button_init(app_button_cfg_t * p_buttons,
yihui 1:a607cd9655d7 123 uint8_t button_count,
yihui 1:a607cd9655d7 124 uint32_t detection_delay,
yihui 1:a607cd9655d7 125 app_button_evt_schedule_func_t evt_schedule_func);
yihui 1:a607cd9655d7 126
yihui 1:a607cd9655d7 127 /**@brief Function for enabling button detection.
yihui 1:a607cd9655d7 128 *
yihui 1:a607cd9655d7 129 * @retval NRF_ERROR_INVALID_PARAM GPIOTE has to many users.
yihui 1:a607cd9655d7 130 * @retval NRF_ERROR_INVALID_STATE Button or GPIOTE not initialized.
yihui 1:a607cd9655d7 131 * @retval NRF_SUCCESS Button detection successfully enabled.
yihui 1:a607cd9655d7 132 */
yihui 1:a607cd9655d7 133 uint32_t app_button_enable(void);
yihui 1:a607cd9655d7 134
yihui 1:a607cd9655d7 135 /**@brief Function for disabling button detection.
yihui 1:a607cd9655d7 136 *
yihui 1:a607cd9655d7 137 * @retval NRF_ERROR_INVALID_PARAM GPIOTE has to many users.
yihui 1:a607cd9655d7 138 * @retval NRF_ERROR_INVALID_STATE Button or GPIOTE not initialized.
yihui 1:a607cd9655d7 139 * @retval NRF_SUCCESS Button detection successfully enabled.
yihui 1:a607cd9655d7 140 */
yihui 1:a607cd9655d7 141 uint32_t app_button_disable(void);
yihui 1:a607cd9655d7 142
yihui 1:a607cd9655d7 143 /**@brief Function for checking if a button is currently being pushed.
yihui 1:a607cd9655d7 144 *
yihui 1:a607cd9655d7 145 * @param[in] button_id Button index (in the app_button_cfg_t array given to app_button_init) to be checked.
yihui 1:a607cd9655d7 146 * @param[out] p_is_pushed Button state.
yihui 1:a607cd9655d7 147 *
yihui 1:a607cd9655d7 148 * @retval NRF_SUCCESS State successfully read.
yihui 1:a607cd9655d7 149 * @retval NRF_ERROR_INVALID_PARAM Invalid button index.
yihui 1:a607cd9655d7 150 */
yihui 1:a607cd9655d7 151 uint32_t app_button_is_pushed(uint8_t button_id, bool * p_is_pushed);
yihui 1:a607cd9655d7 152
yihui 1:a607cd9655d7 153
yihui 1:a607cd9655d7 154 // Type and functions for connecting the Buttons module to the scheduler:
yihui 1:a607cd9655d7 155
yihui 1:a607cd9655d7 156 /**@cond NO_DOXYGEN */
yihui 1:a607cd9655d7 157 typedef struct
yihui 1:a607cd9655d7 158 {
yihui 1:a607cd9655d7 159 app_button_handler_t button_handler;
yihui 1:a607cd9655d7 160 uint8_t pin_no;
yihui 1:a607cd9655d7 161 uint8_t button_action;
yihui 1:a607cd9655d7 162 } app_button_event_t;
yihui 1:a607cd9655d7 163
yihui 1:a607cd9655d7 164 static __INLINE void app_button_evt_get(void * p_event_data, uint16_t event_size)
yihui 1:a607cd9655d7 165 {
yihui 1:a607cd9655d7 166 app_button_event_t * p_buttons_event = (app_button_event_t *)p_event_data;
yihui 1:a607cd9655d7 167
yihui 1:a607cd9655d7 168 APP_ERROR_CHECK_BOOL(event_size == sizeof(app_button_event_t));
yihui 1:a607cd9655d7 169 p_buttons_event->button_handler(p_buttons_event->pin_no, p_buttons_event->button_action);
yihui 1:a607cd9655d7 170 }
yihui 1:a607cd9655d7 171
yihui 1:a607cd9655d7 172 static __INLINE uint32_t app_button_evt_schedule(app_button_handler_t button_handler,
yihui 1:a607cd9655d7 173 uint8_t pin_no,
yihui 1:a607cd9655d7 174 uint8_t button_action)
yihui 1:a607cd9655d7 175 {
yihui 1:a607cd9655d7 176 app_button_event_t buttons_event;
yihui 1:a607cd9655d7 177
yihui 1:a607cd9655d7 178 buttons_event.button_handler = button_handler;
yihui 1:a607cd9655d7 179 buttons_event.pin_no = pin_no;
yihui 1:a607cd9655d7 180 buttons_event.button_action = button_action;
yihui 1:a607cd9655d7 181
yihui 1:a607cd9655d7 182 return app_sched_event_put(&buttons_event, sizeof(buttons_event), app_button_evt_get);
yihui 1:a607cd9655d7 183 }
yihui 1:a607cd9655d7 184 /**@endcond */
yihui 1:a607cd9655d7 185
yihui 1:a607cd9655d7 186 #endif // APP_BUTTON_H__
yihui 1:a607cd9655d7 187
yihui 1:a607cd9655d7 188 /** @} */