To get started with Seeed Tiny BLE, include detecting motion, button and battery level.

Dependencies:   BLE_API eMPL_MPU6050 mbed nRF51822

Committer:
yihui
Date:
Wed Apr 22 07:47:17 2015 +0000
Revision:
1:fc2f9d636751
update libraries; ; delete nRF51822/nordic-sdk/components/gpiote/app_gpiote.c to solve GPIOTE_IRQHandler multiply defined issue. temperarily change nRF51822 library to folder

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 1:fc2f9d636751 1 /* mbed Microcontroller Library
yihui 1:fc2f9d636751 2 * Copyright (c) 2006-2013 ARM Limited
yihui 1:fc2f9d636751 3 *
yihui 1:fc2f9d636751 4 * Licensed under the Apache License, Version 2.0 (the "License");
yihui 1:fc2f9d636751 5 * you may not use this file except in compliance with the License.
yihui 1:fc2f9d636751 6 * You may obtain a copy of the License at
yihui 1:fc2f9d636751 7 *
yihui 1:fc2f9d636751 8 * http://www.apache.org/licenses/LICENSE-2.0
yihui 1:fc2f9d636751 9 *
yihui 1:fc2f9d636751 10 * Unless required by applicable law or agreed to in writing, software
yihui 1:fc2f9d636751 11 * distributed under the License is distributed on an "AS IS" BASIS,
yihui 1:fc2f9d636751 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
yihui 1:fc2f9d636751 13 * See the License for the specific language governing permissions and
yihui 1:fc2f9d636751 14 * limitations under the License.
yihui 1:fc2f9d636751 15 */
yihui 1:fc2f9d636751 16
yihui 1:fc2f9d636751 17 #include "common/common.h"
yihui 1:fc2f9d636751 18 #include "nordic_common.h"
yihui 1:fc2f9d636751 19
yihui 1:fc2f9d636751 20 #include "btle.h"
yihui 1:fc2f9d636751 21
yihui 1:fc2f9d636751 22 #include "ble_stack_handler_types.h"
yihui 1:fc2f9d636751 23 #include "ble_flash.h"
yihui 1:fc2f9d636751 24 #if NEED_BOND_MANAGER
yihui 1:fc2f9d636751 25 #include "ble_bondmngr.h"
yihui 1:fc2f9d636751 26 #endif
yihui 1:fc2f9d636751 27 #include "ble_conn_params.h"
yihui 1:fc2f9d636751 28
yihui 1:fc2f9d636751 29 #include "btle_gap.h"
yihui 1:fc2f9d636751 30 #include "btle_advertising.h"
yihui 1:fc2f9d636751 31 #include "custom/custom_helper.h"
yihui 1:fc2f9d636751 32
yihui 1:fc2f9d636751 33 #include "softdevice_handler.h"
yihui 1:fc2f9d636751 34 #include "pstorage.h"
yihui 1:fc2f9d636751 35
yihui 1:fc2f9d636751 36 #include "GapEvents.h"
yihui 1:fc2f9d636751 37 #include "nRF51Gap.h"
yihui 1:fc2f9d636751 38 #include "nRF51GattServer.h"
yihui 1:fc2f9d636751 39
yihui 1:fc2f9d636751 40 #include "ble_hci.h"
yihui 1:fc2f9d636751 41
yihui 1:fc2f9d636751 42 #if NEED_BOND_MANAGER /* disabled by default */
yihui 1:fc2f9d636751 43 static void service_error_callback(uint32_t nrf_error);
yihui 1:fc2f9d636751 44 #endif
yihui 1:fc2f9d636751 45 extern "C" void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name);
yihui 1:fc2f9d636751 46 void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name);
yihui 1:fc2f9d636751 47
yihui 1:fc2f9d636751 48 #if NEED_BOND_MANAGER /* disabled by default */
yihui 1:fc2f9d636751 49 static error_t bond_manager_init(void);
yihui 1:fc2f9d636751 50 #endif
yihui 1:fc2f9d636751 51
yihui 1:fc2f9d636751 52 static void btle_handler(ble_evt_t *p_ble_evt);
yihui 1:fc2f9d636751 53
yihui 1:fc2f9d636751 54 static void sys_evt_dispatch(uint32_t sys_evt)
yihui 1:fc2f9d636751 55 {
yihui 1:fc2f9d636751 56 pstorage_sys_event_handler(sys_evt);
yihui 1:fc2f9d636751 57 }
yihui 1:fc2f9d636751 58
yihui 1:fc2f9d636751 59 error_t btle_init(void)
yihui 1:fc2f9d636751 60 {
yihui 1:fc2f9d636751 61 const bool useScheduler = false;
yihui 1:fc2f9d636751 62 #if defined(TARGET_DELTA_DFCM_NNN40) || defined(TARGET_HRM1017)
yihui 1:fc2f9d636751 63 SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION, useScheduler);
yihui 1:fc2f9d636751 64 #else
yihui 1:fc2f9d636751 65 SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, useScheduler);
yihui 1:fc2f9d636751 66 #endif
yihui 1:fc2f9d636751 67
yihui 1:fc2f9d636751 68 // Enable BLE stack
yihui 1:fc2f9d636751 69 /**
yihui 1:fc2f9d636751 70 * Using this call, the application can select whether to include the
yihui 1:fc2f9d636751 71 * Service Changed characteristic in the GATT Server. The default in all
yihui 1:fc2f9d636751 72 * previous releases has been to include the Service Changed characteristic,
yihui 1:fc2f9d636751 73 * but this affects how GATT clients behave. Specifically, it requires
yihui 1:fc2f9d636751 74 * clients to subscribe to this attribute and not to cache attribute handles
yihui 1:fc2f9d636751 75 * between connections unless the devices are bonded. If the application
yihui 1:fc2f9d636751 76 * does not need to change the structure of the GATT server attributes at
yihui 1:fc2f9d636751 77 * runtime this adds unnecessary complexity to the interaction with peer
yihui 1:fc2f9d636751 78 * clients. If the SoftDevice is enabled with the Service Changed
yihui 1:fc2f9d636751 79 * Characteristics turned off, then clients are allowed to cache attribute
yihui 1:fc2f9d636751 80 * handles making applications simpler on both sides.
yihui 1:fc2f9d636751 81 */
yihui 1:fc2f9d636751 82 static const bool IS_SRVC_CHANGED_CHARACT_PRESENT = true;
yihui 1:fc2f9d636751 83 ble_enable_params_t enableParams = {
yihui 1:fc2f9d636751 84 .gatts_enable_params = {
yihui 1:fc2f9d636751 85 .service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT
yihui 1:fc2f9d636751 86 }
yihui 1:fc2f9d636751 87 };
yihui 1:fc2f9d636751 88 if (sd_ble_enable(&enableParams) != NRF_SUCCESS) {
yihui 1:fc2f9d636751 89 return ERROR_INVALID_PARAM;
yihui 1:fc2f9d636751 90 }
yihui 1:fc2f9d636751 91
yihui 1:fc2f9d636751 92 ble_gap_addr_t addr;
yihui 1:fc2f9d636751 93 if (sd_ble_gap_address_get(&addr) != NRF_SUCCESS) {
yihui 1:fc2f9d636751 94 return ERROR_INVALID_PARAM;
yihui 1:fc2f9d636751 95 }
yihui 1:fc2f9d636751 96 if (sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr) != NRF_SUCCESS) {
yihui 1:fc2f9d636751 97 return ERROR_INVALID_PARAM;
yihui 1:fc2f9d636751 98 }
yihui 1:fc2f9d636751 99
yihui 1:fc2f9d636751 100 ASSERT_STATUS( softdevice_ble_evt_handler_set(btle_handler));
yihui 1:fc2f9d636751 101 ASSERT_STATUS( softdevice_sys_evt_handler_set(sys_evt_dispatch));
yihui 1:fc2f9d636751 102
yihui 1:fc2f9d636751 103 #if NEED_BOND_MANAGER /* disabled by default */
yihui 1:fc2f9d636751 104 bond_manager_init();
yihui 1:fc2f9d636751 105 #endif
yihui 1:fc2f9d636751 106 btle_gap_init();
yihui 1:fc2f9d636751 107
yihui 1:fc2f9d636751 108 return ERROR_NONE;
yihui 1:fc2f9d636751 109 }
yihui 1:fc2f9d636751 110
yihui 1:fc2f9d636751 111 static void btle_handler(ble_evt_t *p_ble_evt)
yihui 1:fc2f9d636751 112 {
yihui 1:fc2f9d636751 113 /* Library service handlers */
yihui 1:fc2f9d636751 114 #if NEED_BOND_MANAGER /* disabled by default */
yihui 1:fc2f9d636751 115 ble_bondmngr_on_ble_evt(p_ble_evt);
yihui 1:fc2f9d636751 116 #endif
yihui 1:fc2f9d636751 117 #if SDK_CONN_PARAMS_MODULE_ENABLE
yihui 1:fc2f9d636751 118 ble_conn_params_on_ble_evt(p_ble_evt);
yihui 1:fc2f9d636751 119 #endif
yihui 1:fc2f9d636751 120
yihui 1:fc2f9d636751 121 /* Custom event handler */
yihui 1:fc2f9d636751 122 switch (p_ble_evt->header.evt_id) {
yihui 1:fc2f9d636751 123 case BLE_GAP_EVT_CONNECTED: {
yihui 1:fc2f9d636751 124 Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
yihui 1:fc2f9d636751 125 nRF51Gap::getInstance().setConnectionHandle(handle);
yihui 1:fc2f9d636751 126 const Gap::ConnectionParams_t *params = reinterpret_cast<Gap::ConnectionParams_t *>(&(p_ble_evt->evt.gap_evt.params.connected.conn_params));
yihui 1:fc2f9d636751 127 const ble_gap_addr_t *peer = &p_ble_evt->evt.gap_evt.params.connected.peer_addr;
yihui 1:fc2f9d636751 128 nRF51Gap::getInstance().processConnectionEvent(handle, static_cast<Gap::addr_type_t>(peer->addr_type), peer->addr, params);
yihui 1:fc2f9d636751 129 break;
yihui 1:fc2f9d636751 130 }
yihui 1:fc2f9d636751 131
yihui 1:fc2f9d636751 132 case BLE_GAP_EVT_DISCONNECTED: {
yihui 1:fc2f9d636751 133 Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
yihui 1:fc2f9d636751 134 // Since we are not in a connection and have not started advertising,
yihui 1:fc2f9d636751 135 // store bonds
yihui 1:fc2f9d636751 136 nRF51Gap::getInstance().setConnectionHandle (BLE_CONN_HANDLE_INVALID);
yihui 1:fc2f9d636751 137 #if NEED_BOND_MANAGER /* disabled by default */
yihui 1:fc2f9d636751 138 ASSERT_STATUS_RET_VOID ( ble_bondmngr_bonded_centrals_store());
yihui 1:fc2f9d636751 139 #endif
yihui 1:fc2f9d636751 140
yihui 1:fc2f9d636751 141 Gap::DisconnectionReason_t reason;
yihui 1:fc2f9d636751 142 switch (p_ble_evt->evt.gap_evt.params.disconnected.reason) {
yihui 1:fc2f9d636751 143 case BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION:
yihui 1:fc2f9d636751 144 reason = Gap::LOCAL_HOST_TERMINATED_CONNECTION;
yihui 1:fc2f9d636751 145 break;
yihui 1:fc2f9d636751 146 case BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION:
yihui 1:fc2f9d636751 147 reason = Gap::REMOTE_USER_TERMINATED_CONNECTION;
yihui 1:fc2f9d636751 148 break;
yihui 1:fc2f9d636751 149 case BLE_HCI_CONN_INTERVAL_UNACCEPTABLE:
yihui 1:fc2f9d636751 150 reason = Gap::CONN_INTERVAL_UNACCEPTABLE;
yihui 1:fc2f9d636751 151 break;
yihui 1:fc2f9d636751 152 default:
yihui 1:fc2f9d636751 153 /* Please refer to the underlying transport library for an
yihui 1:fc2f9d636751 154 * interpretion of this reason's value. */
yihui 1:fc2f9d636751 155 reason = static_cast<Gap::DisconnectionReason_t>(p_ble_evt->evt.gap_evt.params.disconnected.reason);
yihui 1:fc2f9d636751 156 break;
yihui 1:fc2f9d636751 157 }
yihui 1:fc2f9d636751 158 nRF51Gap::getInstance().processDisconnectionEvent(handle, reason);
yihui 1:fc2f9d636751 159 break;
yihui 1:fc2f9d636751 160 }
yihui 1:fc2f9d636751 161
yihui 1:fc2f9d636751 162 case BLE_GAP_EVT_SEC_PARAMS_REQUEST: {
yihui 1:fc2f9d636751 163 ble_gap_sec_params_t sec_params = {0};
yihui 1:fc2f9d636751 164
yihui 1:fc2f9d636751 165 sec_params.timeout = 30; /*< Timeout for Pairing Request or
yihui 1:fc2f9d636751 166 * Security Request (in seconds). */
yihui 1:fc2f9d636751 167 sec_params.bond = 1; /**< Perform bonding. */
yihui 1:fc2f9d636751 168 sec_params.mitm = CFG_BLE_SEC_PARAM_MITM;
yihui 1:fc2f9d636751 169 sec_params.io_caps = CFG_BLE_SEC_PARAM_IO_CAPABILITIES;
yihui 1:fc2f9d636751 170 sec_params.oob = CFG_BLE_SEC_PARAM_OOB;
yihui 1:fc2f9d636751 171 sec_params.min_key_size = CFG_BLE_SEC_PARAM_MIN_KEY_SIZE;
yihui 1:fc2f9d636751 172 sec_params.max_key_size = CFG_BLE_SEC_PARAM_MAX_KEY_SIZE;
yihui 1:fc2f9d636751 173
yihui 1:fc2f9d636751 174 ASSERT_STATUS_RET_VOID(sd_ble_gap_sec_params_reply(nRF51Gap::getInstance().getConnectionHandle(),
yihui 1:fc2f9d636751 175 BLE_GAP_SEC_STATUS_SUCCESS, &sec_params));
yihui 1:fc2f9d636751 176 }
yihui 1:fc2f9d636751 177 break;
yihui 1:fc2f9d636751 178
yihui 1:fc2f9d636751 179 case BLE_GAP_EVT_TIMEOUT:
yihui 1:fc2f9d636751 180 if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) {
yihui 1:fc2f9d636751 181 nRF51Gap::getInstance().processEvent(GapEvents::GAP_EVENT_TIMEOUT);
yihui 1:fc2f9d636751 182 }
yihui 1:fc2f9d636751 183 break;
yihui 1:fc2f9d636751 184
yihui 1:fc2f9d636751 185 case BLE_GATTC_EVT_TIMEOUT:
yihui 1:fc2f9d636751 186 case BLE_GATTS_EVT_TIMEOUT:
yihui 1:fc2f9d636751 187 // Disconnect on GATT Server and Client timeout events.
yihui 1:fc2f9d636751 188 // ASSERT_STATUS_RET_VOID (sd_ble_gap_disconnect(m_conn_handle,
yihui 1:fc2f9d636751 189 // BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
yihui 1:fc2f9d636751 190 break;
yihui 1:fc2f9d636751 191
yihui 1:fc2f9d636751 192 default:
yihui 1:fc2f9d636751 193 break;
yihui 1:fc2f9d636751 194 }
yihui 1:fc2f9d636751 195
yihui 1:fc2f9d636751 196 nRF51GattServer::getInstance().hwCallback(p_ble_evt);
yihui 1:fc2f9d636751 197 }
yihui 1:fc2f9d636751 198
yihui 1:fc2f9d636751 199 #if NEED_BOND_MANAGER /* disabled by default */
yihui 1:fc2f9d636751 200 /**************************************************************************/
yihui 1:fc2f9d636751 201 /*!
yihui 1:fc2f9d636751 202 @brief Initialises the bond manager
yihui 1:fc2f9d636751 203
yihui 1:fc2f9d636751 204 @note Bond data will be cleared on reset if the bond delete
yihui 1:fc2f9d636751 205 button is pressed during initialisation (the button is
yihui 1:fc2f9d636751 206 defined as CFG_BLE_BOND_DELETE_BUTTON_NUM).
yihui 1:fc2f9d636751 207
yihui 1:fc2f9d636751 208 @returns
yihui 1:fc2f9d636751 209 */
yihui 1:fc2f9d636751 210 /**************************************************************************/
yihui 1:fc2f9d636751 211 static error_t bond_manager_init(void)
yihui 1:fc2f9d636751 212 {
yihui 1:fc2f9d636751 213 ble_bondmngr_init_t bond_para = {0};
yihui 1:fc2f9d636751 214
yihui 1:fc2f9d636751 215 ASSERT_STATUS ( pstorage_init());
yihui 1:fc2f9d636751 216
yihui 1:fc2f9d636751 217 bond_para.flash_page_num_bond = CFG_BLE_BOND_FLASH_PAGE_BOND;
yihui 1:fc2f9d636751 218 bond_para.flash_page_num_sys_attr = CFG_BLE_BOND_FLASH_PAGE_SYS_ATTR;
yihui 1:fc2f9d636751 219 //bond_para.bonds_delete = boardButtonCheck(CFG_BLE_BOND_DELETE_BUTTON_NUM) ;
yihui 1:fc2f9d636751 220 bond_para.evt_handler = NULL;
yihui 1:fc2f9d636751 221 bond_para.error_handler = service_error_callback;
yihui 1:fc2f9d636751 222
yihui 1:fc2f9d636751 223 ASSERT_STATUS( ble_bondmngr_init( &bond_para ));
yihui 1:fc2f9d636751 224
yihui 1:fc2f9d636751 225 /* Init radio active/inactive notification to flash (to only perform flashing when the radio is inactive) */
yihui 1:fc2f9d636751 226 // ASSERT_STATUS( ble_radio_notification_init(NRF_APP_PRIORITY_HIGH,
yihui 1:fc2f9d636751 227 // NRF_RADIO_NOTIFICATION_DISTANCE_4560US,
yihui 1:fc2f9d636751 228 // ble_flash_on_radio_active_evt) );
yihui 1:fc2f9d636751 229
yihui 1:fc2f9d636751 230 return ERROR_NONE;
yihui 1:fc2f9d636751 231 }
yihui 1:fc2f9d636751 232 #endif // #if NEED_BOND_MANAGER
yihui 1:fc2f9d636751 233
yihui 1:fc2f9d636751 234 #if NEED_BOND_MANAGER /* disabled by default */
yihui 1:fc2f9d636751 235 /**************************************************************************/
yihui 1:fc2f9d636751 236 /*!
yihui 1:fc2f9d636751 237 @brief
yihui 1:fc2f9d636751 238 @param[in] nrf_error
yihui 1:fc2f9d636751 239 @returns
yihui 1:fc2f9d636751 240 */
yihui 1:fc2f9d636751 241 /**************************************************************************/
yihui 1:fc2f9d636751 242 static void service_error_callback(uint32_t nrf_error)
yihui 1:fc2f9d636751 243 {
yihui 1:fc2f9d636751 244 ASSERT_STATUS_RET_VOID( nrf_error );
yihui 1:fc2f9d636751 245 }
yihui 1:fc2f9d636751 246 #endif // #if NEED_BOND_MANAGER
yihui 1:fc2f9d636751 247
yihui 1:fc2f9d636751 248 /**************************************************************************/
yihui 1:fc2f9d636751 249 /*!
yihui 1:fc2f9d636751 250 @brief Callback when an error occurs inside the SoftDevice
yihui 1:fc2f9d636751 251
yihui 1:fc2f9d636751 252 @param[in] line_num
yihui 1:fc2f9d636751 253 @param[in] p-file_name
yihui 1:fc2f9d636751 254
yihui 1:fc2f9d636751 255 @returns
yihui 1:fc2f9d636751 256 */
yihui 1:fc2f9d636751 257 /**************************************************************************/
yihui 1:fc2f9d636751 258 void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name)
yihui 1:fc2f9d636751 259 {
yihui 1:fc2f9d636751 260 ASSERT(false, (void) 0);
yihui 1:fc2f9d636751 261 }
yihui 1:fc2f9d636751 262
yihui 1:fc2f9d636751 263 /**************************************************************************/
yihui 1:fc2f9d636751 264 /*!
yihui 1:fc2f9d636751 265 @brief Handler for general errors above the SoftDevice layer.
yihui 1:fc2f9d636751 266 Typically we can' recover from this so we do a reset.
yihui 1:fc2f9d636751 267
yihui 1:fc2f9d636751 268 @param[in] error_code
yihui 1:fc2f9d636751 269 @param[in] line_num
yihui 1:fc2f9d636751 270 @param[in] p-file_name
yihui 1:fc2f9d636751 271
yihui 1:fc2f9d636751 272 @returns
yihui 1:fc2f9d636751 273 */
yihui 1:fc2f9d636751 274 /**************************************************************************/
yihui 1:fc2f9d636751 275 void app_error_handler(uint32_t error_code,
yihui 1:fc2f9d636751 276 uint32_t line_num,
yihui 1:fc2f9d636751 277 const uint8_t *p_file_name)
yihui 1:fc2f9d636751 278 {
yihui 1:fc2f9d636751 279 ASSERT_STATUS_RET_VOID( error_code );
yihui 1:fc2f9d636751 280 NVIC_SystemReset();
yihui 1:fc2f9d636751 281 }