Set write permission for 'write without response' characteristics.

Fork of nRF51822 by Nordic Semiconductor

Committer:
Rohit Grover
Date:
Tue Sep 02 15:50:05 2014 +0100
Revision:
56:a1071b629aa3
Parent:
51:63ba3bcf5cd6
Child:
65:98215c4f3a25
Release 0.1.0
=============

We've achieved significant gains in power consumption: the BLE_Beacon demo now
runs at around 35uA of average current broadcasting once a second at 0dB; when
not using the radio, this demo consumes around 7uA.

Features
~~~~~~~~

- Replace initialization of high-frequency external crystal clock-source with
the use of low-frequency clock. This brings in significant gains in power
consumption.

- Re-implement the micro-second timer on nRF51 using the app_timer module
(which internally uses RTC). This limits the precision of the us_Timer to
30uS; but brings in significant gains in power consumption.

- Reduce the number of available app_timers and the event depths for app-timer
events; this will reduce memory consumption for zero-initialized data by
around 1K.

- Remove the call to conn_params_init() at startup. This is not mandatory; and
was causing an unnecessary re-negotiation of connection parameters a few
seconds into every connection.

- Reduce default transmission power level to 0dbB (was 4dbB before).

- Reduce min connection interval to 50ms and max to 500ms (previous values
were much larger).

- Replace a few instances of use of wait() with nrf_delay_us().

- onConnection() callback now receives connection-parameters applicable to the
new connection.

- onDataSent() callback now receives a count parameter containing the number of
times notifications were sent out since the last callback.

- A 'reason' parameter has been added to Gap::disconnect() to indicate the
reason for disconnection; and also to the onDisconnection callback to
receive a reason from the remote host.

- disable the app_gpiote module by default.

Bugfixes
~~~~~~~~

- onDataWritten() callback now passes an additional parameter
(GattServer::WriteEventCallback_t) encapsulating the update. This avoids
having to re-fetch the updated characteristic's value attribute. It also
fixes a bug where multiple updates to the characteristic's value-attribute
could get clobbered if they occurred in quick succession before the
callbacks could be processed.


Compatibility
~~~~~~~~~~~~~

Compatible with revision 0.1.0 of the BLE_API.

Who changed what in which revision?

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