Official Sheffield ARMBand micro:bit program

Committer:
MrBedfordVan
Date:
Mon Oct 17 12:41:20 2016 +0000
Revision:
0:b9164b348919
Official Sheffield ARMBand Micro:bit program

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MrBedfordVan 0:b9164b348919 1 /* mbed Microcontroller Library
MrBedfordVan 0:b9164b348919 2 * Copyright (c) 2006-2013 ARM Limited
MrBedfordVan 0:b9164b348919 3 *
MrBedfordVan 0:b9164b348919 4 * Licensed under the Apache License, Version 2.0 (the "License");
MrBedfordVan 0:b9164b348919 5 * you may not use this file except in compliance with the License.
MrBedfordVan 0:b9164b348919 6 * You may obtain a copy of the License at
MrBedfordVan 0:b9164b348919 7 *
MrBedfordVan 0:b9164b348919 8 * http://www.apache.org/licenses/LICENSE-2.0
MrBedfordVan 0:b9164b348919 9 *
MrBedfordVan 0:b9164b348919 10 * Unless required by applicable law or agreed to in writing, software
MrBedfordVan 0:b9164b348919 11 * distributed under the License is distributed on an "AS IS" BASIS,
MrBedfordVan 0:b9164b348919 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
MrBedfordVan 0:b9164b348919 13 * See the License for the specific language governing permissions and
MrBedfordVan 0:b9164b348919 14 * limitations under the License.
MrBedfordVan 0:b9164b348919 15 */
MrBedfordVan 0:b9164b348919 16
MrBedfordVan 0:b9164b348919 17 #include "common/common.h"
MrBedfordVan 0:b9164b348919 18 #include "nordic_common.h"
MrBedfordVan 0:b9164b348919 19
MrBedfordVan 0:b9164b348919 20 #include "btle.h"
MrBedfordVan 0:b9164b348919 21
MrBedfordVan 0:b9164b348919 22 #include "ble_flash.h"
MrBedfordVan 0:b9164b348919 23 #include "ble_conn_params.h"
MrBedfordVan 0:b9164b348919 24
MrBedfordVan 0:b9164b348919 25 #include "btle_gap.h"
MrBedfordVan 0:b9164b348919 26 #include "btle_advertising.h"
MrBedfordVan 0:b9164b348919 27 #include "custom/custom_helper.h"
MrBedfordVan 0:b9164b348919 28
MrBedfordVan 0:b9164b348919 29 #include "ble/GapEvents.h"
MrBedfordVan 0:b9164b348919 30 #include "nRF5xn.h"
MrBedfordVan 0:b9164b348919 31
MrBedfordVan 0:b9164b348919 32 extern "C" {
MrBedfordVan 0:b9164b348919 33 #include "pstorage.h"
MrBedfordVan 0:b9164b348919 34 #include "device_manager.h"
MrBedfordVan 0:b9164b348919 35 #include "softdevice_handler.h"
MrBedfordVan 0:b9164b348919 36 #include "ble_stack_handler_types.h"
MrBedfordVan 0:b9164b348919 37 }
MrBedfordVan 0:b9164b348919 38
MrBedfordVan 0:b9164b348919 39 #include "ble_hci.h"
MrBedfordVan 0:b9164b348919 40 #include "btle_discovery.h"
MrBedfordVan 0:b9164b348919 41
MrBedfordVan 0:b9164b348919 42 #include "nRF5xGattClient.h"
MrBedfordVan 0:b9164b348919 43 #include "nRF5xServiceDiscovery.h"
MrBedfordVan 0:b9164b348919 44 #include "nRF5xCharacteristicDescriptorDiscoverer.h"
MrBedfordVan 0:b9164b348919 45
MrBedfordVan 0:b9164b348919 46 extern "C" void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name);
MrBedfordVan 0:b9164b348919 47 void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name);
MrBedfordVan 0:b9164b348919 48
MrBedfordVan 0:b9164b348919 49 static void btle_handler(ble_evt_t *p_ble_evt);
MrBedfordVan 0:b9164b348919 50 static uint32_t gatt_table_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT;
MrBedfordVan 0:b9164b348919 51
MrBedfordVan 0:b9164b348919 52 static void sys_evt_dispatch(uint32_t sys_evt)
MrBedfordVan 0:b9164b348919 53 {
MrBedfordVan 0:b9164b348919 54 pstorage_sys_event_handler(sys_evt);
MrBedfordVan 0:b9164b348919 55 }
MrBedfordVan 0:b9164b348919 56
MrBedfordVan 0:b9164b348919 57 /**
MrBedfordVan 0:b9164b348919 58 * This function is called in interrupt context to handle BLE events; i.e. pull
MrBedfordVan 0:b9164b348919 59 * system and user events out of the pending events-queue of the BLE stack. The
MrBedfordVan 0:b9164b348919 60 * BLE stack signals the availability of events by the triggering the SWI2
MrBedfordVan 0:b9164b348919 61 * interrupt, which forwards the handling to this function.
MrBedfordVan 0:b9164b348919 62 *
MrBedfordVan 0:b9164b348919 63 * The event processing loop is implemented in intern_softdevice_events_execute().
MrBedfordVan 0:b9164b348919 64 *
MrBedfordVan 0:b9164b348919 65 * In mbed OS, a callback for intern_softdevice_events_execute() is posted
MrBedfordVan 0:b9164b348919 66 * to the scheduler, which then executes in thread mode. In mbed-classic,
MrBedfordVan 0:b9164b348919 67 * event processing happens right-away in interrupt context (which is more
MrBedfordVan 0:b9164b348919 68 * risk-prone). In either case, the logic of event processing is identical.
MrBedfordVan 0:b9164b348919 69 */
MrBedfordVan 0:b9164b348919 70 static uint32_t eventHandler()
MrBedfordVan 0:b9164b348919 71 {
MrBedfordVan 0:b9164b348919 72 #ifdef YOTTA_CFG_MBED_OS
MrBedfordVan 0:b9164b348919 73 minar::Scheduler::postCallback(intern_softdevice_events_execute);
MrBedfordVan 0:b9164b348919 74 #else
MrBedfordVan 0:b9164b348919 75 intern_softdevice_events_execute();
MrBedfordVan 0:b9164b348919 76 #endif
MrBedfordVan 0:b9164b348919 77
MrBedfordVan 0:b9164b348919 78 return NRF_SUCCESS;
MrBedfordVan 0:b9164b348919 79 }
MrBedfordVan 0:b9164b348919 80
MrBedfordVan 0:b9164b348919 81 error_t
MrBedfordVan 0:b9164b348919 82 btle_set_gatt_table_size(uint32_t size)
MrBedfordVan 0:b9164b348919 83 {
MrBedfordVan 0:b9164b348919 84 if (size >= BLE_GATTS_ATTR_TAB_SIZE_MIN)
MrBedfordVan 0:b9164b348919 85 {
MrBedfordVan 0:b9164b348919 86 gatt_table_size = size;
MrBedfordVan 0:b9164b348919 87 return ERROR_NONE;
MrBedfordVan 0:b9164b348919 88 }
MrBedfordVan 0:b9164b348919 89
MrBedfordVan 0:b9164b348919 90 return ERROR_INVALID_PARAM;
MrBedfordVan 0:b9164b348919 91 }
MrBedfordVan 0:b9164b348919 92
MrBedfordVan 0:b9164b348919 93 error_t btle_init(void)
MrBedfordVan 0:b9164b348919 94 {
MrBedfordVan 0:b9164b348919 95 nrf_clock_lfclksrc_t clockSource;
MrBedfordVan 0:b9164b348919 96 if (NRF_CLOCK->LFCLKSRC & (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos)) {
MrBedfordVan 0:b9164b348919 97 clockSource = NRF_CLOCK_LFCLKSRC_XTAL_20_PPM;
MrBedfordVan 0:b9164b348919 98 } else {
MrBedfordVan 0:b9164b348919 99 clockSource = NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION;
MrBedfordVan 0:b9164b348919 100 }
MrBedfordVan 0:b9164b348919 101 SOFTDEVICE_HANDLER_INIT(clockSource, eventHandler);
MrBedfordVan 0:b9164b348919 102
MrBedfordVan 0:b9164b348919 103 // Enable BLE stack
MrBedfordVan 0:b9164b348919 104 /**
MrBedfordVan 0:b9164b348919 105 * Using this call, the application can select whether to include the
MrBedfordVan 0:b9164b348919 106 * Service Changed characteristic in the GATT Server. The default in all
MrBedfordVan 0:b9164b348919 107 * previous releases has been to include the Service Changed characteristic,
MrBedfordVan 0:b9164b348919 108 * but this affects how GATT clients behave. Specifically, it requires
MrBedfordVan 0:b9164b348919 109 * clients to subscribe to this attribute and not to cache attribute handles
MrBedfordVan 0:b9164b348919 110 * between connections unless the devices are bonded. If the application
MrBedfordVan 0:b9164b348919 111 * does not need to change the structure of the GATT server attributes at
MrBedfordVan 0:b9164b348919 112 * runtime this adds unnecessary complexity to the interaction with peer
MrBedfordVan 0:b9164b348919 113 * clients. If the SoftDevice is enabled with the Service Changed
MrBedfordVan 0:b9164b348919 114 * Characteristics turned off, then clients are allowed to cache attribute
MrBedfordVan 0:b9164b348919 115 * handles making applications simpler on both sides.
MrBedfordVan 0:b9164b348919 116 */
MrBedfordVan 0:b9164b348919 117 static const bool IS_SRVC_CHANGED_CHARACT_PRESENT = true;
MrBedfordVan 0:b9164b348919 118 ble_enable_params_t enableParams = {
MrBedfordVan 0:b9164b348919 119 .gatts_enable_params = {
MrBedfordVan 0:b9164b348919 120 .service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT,
MrBedfordVan 0:b9164b348919 121 .attr_tab_size = gatt_table_size
MrBedfordVan 0:b9164b348919 122 }
MrBedfordVan 0:b9164b348919 123 };
MrBedfordVan 0:b9164b348919 124 if (sd_ble_enable(&enableParams) != NRF_SUCCESS) {
MrBedfordVan 0:b9164b348919 125 return ERROR_INVALID_PARAM;
MrBedfordVan 0:b9164b348919 126 }
MrBedfordVan 0:b9164b348919 127
MrBedfordVan 0:b9164b348919 128 ble_gap_addr_t addr;
MrBedfordVan 0:b9164b348919 129 if (sd_ble_gap_address_get(&addr) != NRF_SUCCESS) {
MrBedfordVan 0:b9164b348919 130 return ERROR_INVALID_PARAM;
MrBedfordVan 0:b9164b348919 131 }
MrBedfordVan 0:b9164b348919 132 if (sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr) != NRF_SUCCESS) {
MrBedfordVan 0:b9164b348919 133 return ERROR_INVALID_PARAM;
MrBedfordVan 0:b9164b348919 134 }
MrBedfordVan 0:b9164b348919 135
MrBedfordVan 0:b9164b348919 136 ASSERT_STATUS( softdevice_ble_evt_handler_set(btle_handler));
MrBedfordVan 0:b9164b348919 137 ASSERT_STATUS( softdevice_sys_evt_handler_set(sys_evt_dispatch));
MrBedfordVan 0:b9164b348919 138
MrBedfordVan 0:b9164b348919 139 return btle_gap_init();
MrBedfordVan 0:b9164b348919 140 }
MrBedfordVan 0:b9164b348919 141
MrBedfordVan 0:b9164b348919 142 static void btle_handler(ble_evt_t *p_ble_evt)
MrBedfordVan 0:b9164b348919 143 {
MrBedfordVan 0:b9164b348919 144 /* Library service handlers */
MrBedfordVan 0:b9164b348919 145 #if SDK_CONN_PARAMS_MODULE_ENABLE
MrBedfordVan 0:b9164b348919 146 ble_conn_params_on_ble_evt(p_ble_evt);
MrBedfordVan 0:b9164b348919 147 #endif
MrBedfordVan 0:b9164b348919 148
MrBedfordVan 0:b9164b348919 149 dm_ble_evt_handler(p_ble_evt);
MrBedfordVan 0:b9164b348919 150
MrBedfordVan 0:b9164b348919 151 #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
MrBedfordVan 0:b9164b348919 152 bleGattcEventHandler(p_ble_evt);
MrBedfordVan 0:b9164b348919 153 #endif
MrBedfordVan 0:b9164b348919 154
MrBedfordVan 0:b9164b348919 155 nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
MrBedfordVan 0:b9164b348919 156 nRF5xGap &gap = (nRF5xGap &) ble.getGap();
MrBedfordVan 0:b9164b348919 157 nRF5xGattServer &gattServer = (nRF5xGattServer &) ble.getGattServer();
MrBedfordVan 0:b9164b348919 158 nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager();
MrBedfordVan 0:b9164b348919 159
MrBedfordVan 0:b9164b348919 160 /* Custom event handler */
MrBedfordVan 0:b9164b348919 161 switch (p_ble_evt->header.evt_id) {
MrBedfordVan 0:b9164b348919 162 case BLE_GAP_EVT_CONNECTED: {
MrBedfordVan 0:b9164b348919 163 Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
MrBedfordVan 0:b9164b348919 164 #if defined(TARGET_MCU_NRF51_16K_S110) || defined(TARGET_MCU_NRF51_32K_S110)
MrBedfordVan 0:b9164b348919 165 /* Only peripheral role is supported by S110 */
MrBedfordVan 0:b9164b348919 166 Gap::Role_t role = Gap::PERIPHERAL;
MrBedfordVan 0:b9164b348919 167 #else
MrBedfordVan 0:b9164b348919 168 Gap::Role_t role = static_cast<Gap::Role_t>(p_ble_evt->evt.gap_evt.params.connected.role);
MrBedfordVan 0:b9164b348919 169 #endif
MrBedfordVan 0:b9164b348919 170 gap.setConnectionHandle(handle);
MrBedfordVan 0:b9164b348919 171 const Gap::ConnectionParams_t *params = reinterpret_cast<Gap::ConnectionParams_t *>(&(p_ble_evt->evt.gap_evt.params.connected.conn_params));
MrBedfordVan 0:b9164b348919 172 const ble_gap_addr_t *peer = &p_ble_evt->evt.gap_evt.params.connected.peer_addr;
MrBedfordVan 0:b9164b348919 173 const ble_gap_addr_t *own = &p_ble_evt->evt.gap_evt.params.connected.own_addr;
MrBedfordVan 0:b9164b348919 174 gap.processConnectionEvent(handle,
MrBedfordVan 0:b9164b348919 175 role,
MrBedfordVan 0:b9164b348919 176 static_cast<BLEProtocol::AddressType_t>(peer->addr_type), peer->addr,
MrBedfordVan 0:b9164b348919 177 static_cast<BLEProtocol::AddressType_t>(own->addr_type), own->addr,
MrBedfordVan 0:b9164b348919 178 params);
MrBedfordVan 0:b9164b348919 179 break;
MrBedfordVan 0:b9164b348919 180 }
MrBedfordVan 0:b9164b348919 181
MrBedfordVan 0:b9164b348919 182 case BLE_GAP_EVT_DISCONNECTED: {
MrBedfordVan 0:b9164b348919 183 Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
MrBedfordVan 0:b9164b348919 184 // Since we are not in a connection and have not started advertising,
MrBedfordVan 0:b9164b348919 185 // store bonds
MrBedfordVan 0:b9164b348919 186 gap.setConnectionHandle (BLE_CONN_HANDLE_INVALID);
MrBedfordVan 0:b9164b348919 187
MrBedfordVan 0:b9164b348919 188 Gap::DisconnectionReason_t reason;
MrBedfordVan 0:b9164b348919 189 switch (p_ble_evt->evt.gap_evt.params.disconnected.reason) {
MrBedfordVan 0:b9164b348919 190 case BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION:
MrBedfordVan 0:b9164b348919 191 reason = Gap::LOCAL_HOST_TERMINATED_CONNECTION;
MrBedfordVan 0:b9164b348919 192 break;
MrBedfordVan 0:b9164b348919 193 case BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION:
MrBedfordVan 0:b9164b348919 194 reason = Gap::REMOTE_USER_TERMINATED_CONNECTION;
MrBedfordVan 0:b9164b348919 195 break;
MrBedfordVan 0:b9164b348919 196 case BLE_HCI_CONN_INTERVAL_UNACCEPTABLE:
MrBedfordVan 0:b9164b348919 197 reason = Gap::CONN_INTERVAL_UNACCEPTABLE;
MrBedfordVan 0:b9164b348919 198 break;
MrBedfordVan 0:b9164b348919 199 default:
MrBedfordVan 0:b9164b348919 200 /* Please refer to the underlying transport library for an
MrBedfordVan 0:b9164b348919 201 * interpretion of this reason's value. */
MrBedfordVan 0:b9164b348919 202 reason = static_cast<Gap::DisconnectionReason_t>(p_ble_evt->evt.gap_evt.params.disconnected.reason);
MrBedfordVan 0:b9164b348919 203 break;
MrBedfordVan 0:b9164b348919 204 }
MrBedfordVan 0:b9164b348919 205
MrBedfordVan 0:b9164b348919 206 // Close all pending discoveries for this connection
MrBedfordVan 0:b9164b348919 207 #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
MrBedfordVan 0:b9164b348919 208 nRF5xGattClient& gattClient = ble.getGattClient();
MrBedfordVan 0:b9164b348919 209 gattClient.characteristicDescriptorDiscoverer().terminate(handle, BLE_ERROR_INVALID_STATE);
MrBedfordVan 0:b9164b348919 210 gattClient.discovery().terminate(handle);
MrBedfordVan 0:b9164b348919 211 #endif
MrBedfordVan 0:b9164b348919 212
MrBedfordVan 0:b9164b348919 213 gap.processDisconnectionEvent(handle, reason);
MrBedfordVan 0:b9164b348919 214 break;
MrBedfordVan 0:b9164b348919 215 }
MrBedfordVan 0:b9164b348919 216
MrBedfordVan 0:b9164b348919 217 case BLE_GAP_EVT_PASSKEY_DISPLAY:
MrBedfordVan 0:b9164b348919 218 securityManager.processPasskeyDisplayEvent(p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->evt.gap_evt.params.passkey_display.passkey);
MrBedfordVan 0:b9164b348919 219 break;
MrBedfordVan 0:b9164b348919 220
MrBedfordVan 0:b9164b348919 221 case BLE_GAP_EVT_TIMEOUT:
MrBedfordVan 0:b9164b348919 222 gap.processTimeoutEvent(static_cast<Gap::TimeoutSource_t>(p_ble_evt->evt.gap_evt.params.timeout.src));
MrBedfordVan 0:b9164b348919 223 break;
MrBedfordVan 0:b9164b348919 224
MrBedfordVan 0:b9164b348919 225 case BLE_GATTC_EVT_TIMEOUT:
MrBedfordVan 0:b9164b348919 226 case BLE_GATTS_EVT_TIMEOUT:
MrBedfordVan 0:b9164b348919 227 // Disconnect on GATT Server and Client timeout events.
MrBedfordVan 0:b9164b348919 228 // ASSERT_STATUS_RET_VOID (sd_ble_gap_disconnect(m_conn_handle,
MrBedfordVan 0:b9164b348919 229 // BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
MrBedfordVan 0:b9164b348919 230 break;
MrBedfordVan 0:b9164b348919 231
MrBedfordVan 0:b9164b348919 232 case BLE_GAP_EVT_ADV_REPORT: {
MrBedfordVan 0:b9164b348919 233 const ble_gap_evt_adv_report_t *advReport = &p_ble_evt->evt.gap_evt.params.adv_report;
MrBedfordVan 0:b9164b348919 234 gap.processAdvertisementReport(advReport->peer_addr.addr,
MrBedfordVan 0:b9164b348919 235 advReport->rssi,
MrBedfordVan 0:b9164b348919 236 advReport->scan_rsp,
MrBedfordVan 0:b9164b348919 237 static_cast<GapAdvertisingParams::AdvertisingType_t>(advReport->type),
MrBedfordVan 0:b9164b348919 238 advReport->dlen,
MrBedfordVan 0:b9164b348919 239 advReport->data);
MrBedfordVan 0:b9164b348919 240 break;
MrBedfordVan 0:b9164b348919 241 }
MrBedfordVan 0:b9164b348919 242
MrBedfordVan 0:b9164b348919 243 default:
MrBedfordVan 0:b9164b348919 244 break;
MrBedfordVan 0:b9164b348919 245 }
MrBedfordVan 0:b9164b348919 246
MrBedfordVan 0:b9164b348919 247 gattServer.hwCallback(p_ble_evt);
MrBedfordVan 0:b9164b348919 248 }
MrBedfordVan 0:b9164b348919 249
MrBedfordVan 0:b9164b348919 250 /*! @brief Callback when an error occurs inside the SoftDevice */
MrBedfordVan 0:b9164b348919 251 void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name)
MrBedfordVan 0:b9164b348919 252 {
MrBedfordVan 0:b9164b348919 253 ASSERT(false, (void) 0);
MrBedfordVan 0:b9164b348919 254 }
MrBedfordVan 0:b9164b348919 255
MrBedfordVan 0:b9164b348919 256 /*!
MrBedfordVan 0:b9164b348919 257 @brief Handler for general errors above the SoftDevice layer.
MrBedfordVan 0:b9164b348919 258 Typically we can' recover from this so we do a reset.
MrBedfordVan 0:b9164b348919 259 */
MrBedfordVan 0:b9164b348919 260 void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name)
MrBedfordVan 0:b9164b348919 261 {
MrBedfordVan 0:b9164b348919 262 ASSERT_STATUS_RET_VOID( error_code );
MrBedfordVan 0:b9164b348919 263 NVIC_SystemReset();
MrBedfordVan 0:b9164b348919 264 }