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) 2013 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 #include "softdevice_handler.h"
yihui 1:a607cd9655d7 14 #include <stdlib.h>
yihui 1:a607cd9655d7 15 #include "nordic_common.h"
yihui 1:a607cd9655d7 16 #include "app_error.h"
yihui 1:a607cd9655d7 17 #include "app_util.h"
yihui 1:a607cd9655d7 18 #include "nrf_assert.h"
yihui 1:a607cd9655d7 19 #include "nrf_soc.h"
yihui 1:a607cd9655d7 20
yihui 1:a607cd9655d7 21 #if defined(ANT_STACK_SUPPORT_REQD) && defined(BLE_STACK_SUPPORT_REQD)
yihui 1:a607cd9655d7 22 #include "ant_interface.h"
yihui 1:a607cd9655d7 23 #elif defined(ANT_STACK_SUPPORT_REQD)
yihui 1:a607cd9655d7 24 #include "ant_interface.h"
yihui 1:a607cd9655d7 25 #elif defined(BLE_STACK_SUPPORT_REQD)
yihui 1:a607cd9655d7 26 #include "ble.h"
yihui 1:a607cd9655d7 27 #endif
yihui 1:a607cd9655d7 28
yihui 1:a607cd9655d7 29
yihui 1:a607cd9655d7 30 static softdevice_evt_schedule_func_t m_evt_schedule_func; /**< Pointer to function for propagating SoftDevice events to the scheduler. */
yihui 1:a607cd9655d7 31
yihui 1:a607cd9655d7 32 #if defined (BLE_STACK_SUPPORT_REQD) || defined (ANT_STACK_SUPPORT_REQD)
yihui 1:a607cd9655d7 33 // The following two definition is needed only if ANT or BLE events are needed to be pulled from the stack.
yihui 1:a607cd9655d7 34 static uint8_t * m_evt_buffer; /**< Buffer for receiving events from the SoftDevice. */
yihui 1:a607cd9655d7 35 #endif
yihui 1:a607cd9655d7 36
yihui 1:a607cd9655d7 37 #ifdef BLE_STACK_SUPPORT_REQD
yihui 1:a607cd9655d7 38 static uint16_t m_ble_evt_buffer_size; /**< Size of BLE event buffer. */
yihui 1:a607cd9655d7 39 #endif
yihui 1:a607cd9655d7 40
yihui 1:a607cd9655d7 41 static volatile bool m_softdevice_enabled = false; /**< Variable to indicate whether the SoftDevice is enabled. */
yihui 1:a607cd9655d7 42
yihui 1:a607cd9655d7 43 #ifdef BLE_STACK_SUPPORT_REQD
yihui 1:a607cd9655d7 44 static ble_evt_handler_t m_ble_evt_handler; /**< Application event handler for handling BLE events. */
yihui 1:a607cd9655d7 45 #endif
yihui 1:a607cd9655d7 46
yihui 1:a607cd9655d7 47 #ifdef ANT_STACK_SUPPORT_REQD
yihui 1:a607cd9655d7 48 static ant_evt_handler_t m_ant_evt_handler; /**< Application event handler for handling ANT events. */
yihui 1:a607cd9655d7 49 #endif
yihui 1:a607cd9655d7 50
yihui 1:a607cd9655d7 51 static sys_evt_handler_t m_sys_evt_handler; /**< Application event handler for handling System (SOC) events. */
yihui 1:a607cd9655d7 52
yihui 1:a607cd9655d7 53
yihui 1:a607cd9655d7 54 /**@brief Callback function for asserts in the SoftDevice.
yihui 1:a607cd9655d7 55 *
yihui 1:a607cd9655d7 56 * @details A pointer to this function will be passed to the SoftDevice. This function will be
yihui 1:a607cd9655d7 57 * called if an ASSERT statement in the SoftDevice fails.
yihui 1:a607cd9655d7 58 *
yihui 1:a607cd9655d7 59 * @param[in] pc The value of the program counter when the ASSERT call failed.
yihui 1:a607cd9655d7 60 * @param[in] line_num Line number of the failing ASSERT call.
yihui 1:a607cd9655d7 61 * @param[in] file_name File name of the failing ASSERT call.
yihui 1:a607cd9655d7 62 */
yihui 1:a607cd9655d7 63 void softdevice_assertion_handler(uint32_t pc, uint16_t line_num, const uint8_t * file_name)
yihui 1:a607cd9655d7 64 {
yihui 1:a607cd9655d7 65 UNUSED_PARAMETER(pc);
yihui 1:a607cd9655d7 66 assert_nrf_callback(line_num, file_name);
yihui 1:a607cd9655d7 67 }
yihui 1:a607cd9655d7 68
yihui 1:a607cd9655d7 69
yihui 1:a607cd9655d7 70 void intern_softdevice_events_execute(void)
yihui 1:a607cd9655d7 71 {
yihui 1:a607cd9655d7 72 if (!m_softdevice_enabled)
yihui 1:a607cd9655d7 73 {
yihui 1:a607cd9655d7 74 // SoftDevice not enabled. This can be possible if the SoftDevice was enabled by the
yihui 1:a607cd9655d7 75 // application without using this module's API (i.e softdevice_handler_init)
yihui 1:a607cd9655d7 76
yihui 1:a607cd9655d7 77 return;
yihui 1:a607cd9655d7 78 }
yihui 1:a607cd9655d7 79
yihui 1:a607cd9655d7 80 bool no_more_soc_evts = (m_sys_evt_handler == NULL);
yihui 1:a607cd9655d7 81 #ifdef BLE_STACK_SUPPORT_REQD
yihui 1:a607cd9655d7 82 bool no_more_ble_evts = (m_ble_evt_handler == NULL);
yihui 1:a607cd9655d7 83 #endif
yihui 1:a607cd9655d7 84 #ifdef ANT_STACK_SUPPORT_REQD
yihui 1:a607cd9655d7 85 bool no_more_ant_evts = (m_ant_evt_handler == NULL);
yihui 1:a607cd9655d7 86 #endif
yihui 1:a607cd9655d7 87
yihui 1:a607cd9655d7 88 for (;;)
yihui 1:a607cd9655d7 89 {
yihui 1:a607cd9655d7 90 uint32_t err_code;
yihui 1:a607cd9655d7 91
yihui 1:a607cd9655d7 92 if (!no_more_soc_evts)
yihui 1:a607cd9655d7 93 {
yihui 1:a607cd9655d7 94 uint32_t evt_id;
yihui 1:a607cd9655d7 95
yihui 1:a607cd9655d7 96 // Pull event from SOC.
yihui 1:a607cd9655d7 97 err_code = sd_evt_get(&evt_id);
yihui 1:a607cd9655d7 98
yihui 1:a607cd9655d7 99 if (err_code == NRF_ERROR_NOT_FOUND)
yihui 1:a607cd9655d7 100 {
yihui 1:a607cd9655d7 101 no_more_soc_evts = true;
yihui 1:a607cd9655d7 102 }
yihui 1:a607cd9655d7 103 else if (err_code != NRF_SUCCESS)
yihui 1:a607cd9655d7 104 {
yihui 1:a607cd9655d7 105 APP_ERROR_HANDLER(err_code);
yihui 1:a607cd9655d7 106 }
yihui 1:a607cd9655d7 107 else
yihui 1:a607cd9655d7 108 {
yihui 1:a607cd9655d7 109 // Call application's SOC event handler.
yihui 1:a607cd9655d7 110 m_sys_evt_handler(evt_id);
yihui 1:a607cd9655d7 111 }
yihui 1:a607cd9655d7 112 }
yihui 1:a607cd9655d7 113
yihui 1:a607cd9655d7 114 #ifdef BLE_STACK_SUPPORT_REQD
yihui 1:a607cd9655d7 115 // Fetch BLE Events.
yihui 1:a607cd9655d7 116 if (!no_more_ble_evts)
yihui 1:a607cd9655d7 117 {
yihui 1:a607cd9655d7 118 // Pull event from stack
yihui 1:a607cd9655d7 119 uint16_t evt_len = m_ble_evt_buffer_size;
yihui 1:a607cd9655d7 120
yihui 1:a607cd9655d7 121 err_code = sd_ble_evt_get(m_evt_buffer, &evt_len);
yihui 1:a607cd9655d7 122 if (err_code == NRF_ERROR_NOT_FOUND)
yihui 1:a607cd9655d7 123 {
yihui 1:a607cd9655d7 124 no_more_ble_evts = true;
yihui 1:a607cd9655d7 125 }
yihui 1:a607cd9655d7 126 else if (err_code != NRF_SUCCESS)
yihui 1:a607cd9655d7 127 {
yihui 1:a607cd9655d7 128 APP_ERROR_HANDLER(err_code);
yihui 1:a607cd9655d7 129 }
yihui 1:a607cd9655d7 130 else
yihui 1:a607cd9655d7 131 {
yihui 1:a607cd9655d7 132 // Call application's BLE stack event handler.
yihui 1:a607cd9655d7 133 m_ble_evt_handler((ble_evt_t *)m_evt_buffer);
yihui 1:a607cd9655d7 134 }
yihui 1:a607cd9655d7 135 }
yihui 1:a607cd9655d7 136 #endif
yihui 1:a607cd9655d7 137
yihui 1:a607cd9655d7 138 #ifdef ANT_STACK_SUPPORT_REQD
yihui 1:a607cd9655d7 139 // Fetch ANT Events.
yihui 1:a607cd9655d7 140 if (!no_more_ant_evts)
yihui 1:a607cd9655d7 141 {
yihui 1:a607cd9655d7 142 // Pull event from stack
yihui 1:a607cd9655d7 143 err_code = sd_ant_event_get(&((ant_evt_t *)m_evt_buffer)->channel,
yihui 1:a607cd9655d7 144 &((ant_evt_t *)m_evt_buffer)->event,
yihui 1:a607cd9655d7 145 ((ant_evt_t *)m_evt_buffer)->evt_buffer);
yihui 1:a607cd9655d7 146 if (err_code == NRF_ERROR_NOT_FOUND)
yihui 1:a607cd9655d7 147 {
yihui 1:a607cd9655d7 148 no_more_ant_evts = true;
yihui 1:a607cd9655d7 149 }
yihui 1:a607cd9655d7 150 else if (err_code != NRF_SUCCESS)
yihui 1:a607cd9655d7 151 {
yihui 1:a607cd9655d7 152 APP_ERROR_HANDLER(err_code);
yihui 1:a607cd9655d7 153 }
yihui 1:a607cd9655d7 154 else
yihui 1:a607cd9655d7 155 {
yihui 1:a607cd9655d7 156 // Call application's ANT stack event handler.
yihui 1:a607cd9655d7 157 m_ant_evt_handler((ant_evt_t *)m_evt_buffer);
yihui 1:a607cd9655d7 158 }
yihui 1:a607cd9655d7 159 }
yihui 1:a607cd9655d7 160 #endif
yihui 1:a607cd9655d7 161
yihui 1:a607cd9655d7 162 if (no_more_soc_evts)
yihui 1:a607cd9655d7 163 {
yihui 1:a607cd9655d7 164 // There are no remaining System (SOC) events to be fetched from the SoftDevice.
yihui 1:a607cd9655d7 165 #if defined(ANT_STACK_SUPPORT_REQD) && defined(BLE_STACK_SUPPORT_REQD)
yihui 1:a607cd9655d7 166 // Check if there are any remaining BLE and ANT events.
yihui 1:a607cd9655d7 167 if (no_more_ble_evts && no_more_ant_evts)
yihui 1:a607cd9655d7 168 {
yihui 1:a607cd9655d7 169 break;
yihui 1:a607cd9655d7 170 }
yihui 1:a607cd9655d7 171 #elif defined(BLE_STACK_SUPPORT_REQD)
yihui 1:a607cd9655d7 172 // Check if there are any remaining BLE events.
yihui 1:a607cd9655d7 173 if (no_more_ble_evts)
yihui 1:a607cd9655d7 174 {
yihui 1:a607cd9655d7 175 break;
yihui 1:a607cd9655d7 176 }
yihui 1:a607cd9655d7 177 #elif defined(ANT_STACK_SUPPORT_REQD)
yihui 1:a607cd9655d7 178 // Check if there are any remaining ANT events.
yihui 1:a607cd9655d7 179 if (no_more_ant_evts)
yihui 1:a607cd9655d7 180 {
yihui 1:a607cd9655d7 181 break;
yihui 1:a607cd9655d7 182 }
yihui 1:a607cd9655d7 183 #else
yihui 1:a607cd9655d7 184 // No need to check for BLE or ANT events since there is no support for BLE and ANT
yihui 1:a607cd9655d7 185 // required.
yihui 1:a607cd9655d7 186 break;
yihui 1:a607cd9655d7 187 #endif
yihui 1:a607cd9655d7 188 }
yihui 1:a607cd9655d7 189 }
yihui 1:a607cd9655d7 190 }
yihui 1:a607cd9655d7 191
yihui 1:a607cd9655d7 192
yihui 1:a607cd9655d7 193 uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t clock_source,
yihui 1:a607cd9655d7 194 void * p_evt_buffer,
yihui 1:a607cd9655d7 195 uint16_t evt_buffer_size,
yihui 1:a607cd9655d7 196 softdevice_evt_schedule_func_t evt_schedule_func)
yihui 1:a607cd9655d7 197 {
yihui 1:a607cd9655d7 198 uint32_t err_code;
yihui 1:a607cd9655d7 199
yihui 1:a607cd9655d7 200 // Save configuration.
yihui 1:a607cd9655d7 201 #if defined (BLE_STACK_SUPPORT_REQD) || defined (ANT_STACK_SUPPORT_REQD)
yihui 1:a607cd9655d7 202 // Check that buffer is not NULL.
yihui 1:a607cd9655d7 203 if (p_evt_buffer == NULL)
yihui 1:a607cd9655d7 204 {
yihui 1:a607cd9655d7 205 return NRF_ERROR_INVALID_PARAM;
yihui 1:a607cd9655d7 206 }
yihui 1:a607cd9655d7 207
yihui 1:a607cd9655d7 208 // Check that buffer is correctly aligned.
yihui 1:a607cd9655d7 209 if (!is_word_aligned(p_evt_buffer))
yihui 1:a607cd9655d7 210 {
yihui 1:a607cd9655d7 211 return NRF_ERROR_INVALID_PARAM;
yihui 1:a607cd9655d7 212 }
yihui 1:a607cd9655d7 213
yihui 1:a607cd9655d7 214 m_evt_buffer = (uint8_t *)p_evt_buffer;
yihui 1:a607cd9655d7 215 #else
yihui 1:a607cd9655d7 216 // The variable p_evt_buffer is not needed if neither BLE Stack nor ANT stack support is
yihui 1:a607cd9655d7 217 // required.
yihui 1:a607cd9655d7 218 UNUSED_PARAMETER(p_evt_buffer);
yihui 1:a607cd9655d7 219 #endif
yihui 1:a607cd9655d7 220
yihui 1:a607cd9655d7 221 #if defined (BLE_STACK_SUPPORT_REQD)
yihui 1:a607cd9655d7 222 m_ble_evt_buffer_size = evt_buffer_size;
yihui 1:a607cd9655d7 223 #else
yihui 1:a607cd9655d7 224 // The variable evt_buffer_size is not needed if BLE Stack support is NOT required.
yihui 1:a607cd9655d7 225 UNUSED_PARAMETER(evt_buffer_size);
yihui 1:a607cd9655d7 226 #endif
yihui 1:a607cd9655d7 227
yihui 1:a607cd9655d7 228 m_evt_schedule_func = evt_schedule_func;
yihui 1:a607cd9655d7 229
yihui 1:a607cd9655d7 230 // Initialize SoftDevice.
yihui 1:a607cd9655d7 231
yihui 1:a607cd9655d7 232 err_code = sd_softdevice_enable(clock_source, softdevice_assertion_handler);
yihui 1:a607cd9655d7 233 if (err_code != NRF_SUCCESS)
yihui 1:a607cd9655d7 234 {
yihui 1:a607cd9655d7 235 return err_code;
yihui 1:a607cd9655d7 236 }
yihui 1:a607cd9655d7 237
yihui 1:a607cd9655d7 238 m_softdevice_enabled = true;
yihui 1:a607cd9655d7 239
yihui 1:a607cd9655d7 240 // Enable BLE event interrupt (interrupt priority has already been set by the stack).
yihui 1:a607cd9655d7 241 return sd_nvic_EnableIRQ(SWI2_IRQn);
yihui 1:a607cd9655d7 242 }
yihui 1:a607cd9655d7 243
yihui 1:a607cd9655d7 244
yihui 1:a607cd9655d7 245 uint32_t softdevice_handler_sd_disable(void)
yihui 1:a607cd9655d7 246 {
yihui 1:a607cd9655d7 247 uint32_t err_code = sd_softdevice_disable();
yihui 1:a607cd9655d7 248
yihui 1:a607cd9655d7 249 m_softdevice_enabled = !(err_code == NRF_SUCCESS);
yihui 1:a607cd9655d7 250
yihui 1:a607cd9655d7 251 return err_code;
yihui 1:a607cd9655d7 252 }
yihui 1:a607cd9655d7 253
yihui 1:a607cd9655d7 254
yihui 1:a607cd9655d7 255 #ifdef BLE_STACK_SUPPORT_REQD
yihui 1:a607cd9655d7 256 uint32_t softdevice_ble_evt_handler_set(ble_evt_handler_t ble_evt_handler)
yihui 1:a607cd9655d7 257 {
yihui 1:a607cd9655d7 258 if (ble_evt_handler == NULL)
yihui 1:a607cd9655d7 259 {
yihui 1:a607cd9655d7 260 return NRF_ERROR_NULL;
yihui 1:a607cd9655d7 261 }
yihui 1:a607cd9655d7 262
yihui 1:a607cd9655d7 263 m_ble_evt_handler = ble_evt_handler;
yihui 1:a607cd9655d7 264
yihui 1:a607cd9655d7 265 return NRF_SUCCESS;
yihui 1:a607cd9655d7 266 }
yihui 1:a607cd9655d7 267 #endif
yihui 1:a607cd9655d7 268
yihui 1:a607cd9655d7 269
yihui 1:a607cd9655d7 270 #ifdef ANT_STACK_SUPPORT_REQD
yihui 1:a607cd9655d7 271 uint32_t softdevice_ant_evt_handler_set(ant_evt_handler_t ant_evt_handler)
yihui 1:a607cd9655d7 272 {
yihui 1:a607cd9655d7 273 if (ant_evt_handler == NULL)
yihui 1:a607cd9655d7 274 {
yihui 1:a607cd9655d7 275 return NRF_ERROR_NULL;
yihui 1:a607cd9655d7 276 }
yihui 1:a607cd9655d7 277
yihui 1:a607cd9655d7 278 m_ant_evt_handler = ant_evt_handler;
yihui 1:a607cd9655d7 279
yihui 1:a607cd9655d7 280 return NRF_SUCCESS;
yihui 1:a607cd9655d7 281 }
yihui 1:a607cd9655d7 282 #endif
yihui 1:a607cd9655d7 283
yihui 1:a607cd9655d7 284
yihui 1:a607cd9655d7 285 uint32_t softdevice_sys_evt_handler_set(sys_evt_handler_t sys_evt_handler)
yihui 1:a607cd9655d7 286 {
yihui 1:a607cd9655d7 287 if (sys_evt_handler == NULL)
yihui 1:a607cd9655d7 288 {
yihui 1:a607cd9655d7 289 return NRF_ERROR_NULL;
yihui 1:a607cd9655d7 290 }
yihui 1:a607cd9655d7 291
yihui 1:a607cd9655d7 292 m_sys_evt_handler = sys_evt_handler;
yihui 1:a607cd9655d7 293
yihui 1:a607cd9655d7 294 return NRF_SUCCESS;
yihui 1:a607cd9655d7 295 }
yihui 1:a607cd9655d7 296
yihui 1:a607cd9655d7 297
yihui 1:a607cd9655d7 298 /**@brief Function for handling the Application's BLE Stack events interrupt.
yihui 1:a607cd9655d7 299 *
yihui 1:a607cd9655d7 300 * @details This function is called whenever an event is ready to be pulled.
yihui 1:a607cd9655d7 301 */
yihui 1:a607cd9655d7 302 extern "C" void SWI2_IRQHandler(void)
yihui 1:a607cd9655d7 303 {
yihui 1:a607cd9655d7 304 if (m_evt_schedule_func != NULL)
yihui 1:a607cd9655d7 305 {
yihui 1:a607cd9655d7 306 uint32_t err_code = m_evt_schedule_func();
yihui 1:a607cd9655d7 307 APP_ERROR_CHECK(err_code);
yihui 1:a607cd9655d7 308 }
yihui 1:a607cd9655d7 309 else
yihui 1:a607cd9655d7 310 {
yihui 1:a607cd9655d7 311 intern_softdevice_events_execute();
yihui 1:a607cd9655d7 312 }
yihui 1:a607cd9655d7 313 }