Nordic stack and drivers for the mbed BLE API

Dependents:   BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate writable_gatt ... more

Committer:
Vincent Coubard
Date:
Wed Sep 14 14:39:43 2016 +0100
Revision:
638:c90ae1400bf2
Sync with bdab10dc0f90748b6989c8b577771bb403ca6bd8 from ARMmbed/mbed-os.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vincent Coubard 638:c90ae1400bf2 1 /* mbed Microcontroller Library
Vincent Coubard 638:c90ae1400bf2 2 * Copyright (c) 2006-2013 ARM Limited
Vincent Coubard 638:c90ae1400bf2 3 *
Vincent Coubard 638:c90ae1400bf2 4 * Licensed under the Apache License, Version 2.0 (the "License");
Vincent Coubard 638:c90ae1400bf2 5 * you may not use this file except in compliance with the License.
Vincent Coubard 638:c90ae1400bf2 6 * You may obtain a copy of the License at
Vincent Coubard 638:c90ae1400bf2 7 *
Vincent Coubard 638:c90ae1400bf2 8 * http://www.apache.org/licenses/LICENSE-2.0
Vincent Coubard 638:c90ae1400bf2 9 *
Vincent Coubard 638:c90ae1400bf2 10 * Unless required by applicable law or agreed to in writing, software
Vincent Coubard 638:c90ae1400bf2 11 * distributed under the License is distributed on an "AS IS" BASIS,
Vincent Coubard 638:c90ae1400bf2 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Vincent Coubard 638:c90ae1400bf2 13 * See the License for the specific language governing permissions and
Vincent Coubard 638:c90ae1400bf2 14 * limitations under the License.
Vincent Coubard 638:c90ae1400bf2 15 */
Vincent Coubard 638:c90ae1400bf2 16
Vincent Coubard 638:c90ae1400bf2 17 #ifdef YOTTA_CFG_MBED_OS
Vincent Coubard 638:c90ae1400bf2 18 #include "mbed-drivers/mbed.h"
Vincent Coubard 638:c90ae1400bf2 19 #else
Vincent Coubard 638:c90ae1400bf2 20 #include "mbed.h"
Vincent Coubard 638:c90ae1400bf2 21 #endif
Vincent Coubard 638:c90ae1400bf2 22 #include "nRF5xn.h"
Vincent Coubard 638:c90ae1400bf2 23 #include "ble/blecommon.h"
Vincent Coubard 638:c90ae1400bf2 24 #include "nrf_soc.h"
Vincent Coubard 638:c90ae1400bf2 25
Vincent Coubard 638:c90ae1400bf2 26 #include "btle/btle.h"
Vincent Coubard 638:c90ae1400bf2 27 #include "btle/custom/custom_helper.h"
Vincent Coubard 638:c90ae1400bf2 28 #include "nrf_delay.h"
Vincent Coubard 638:c90ae1400bf2 29
Vincent Coubard 638:c90ae1400bf2 30 extern "C" {
Vincent Coubard 638:c90ae1400bf2 31 #include "softdevice_handler.h"
Vincent Coubard 638:c90ae1400bf2 32 }
Vincent Coubard 638:c90ae1400bf2 33
Vincent Coubard 638:c90ae1400bf2 34 /**
Vincent Coubard 638:c90ae1400bf2 35 * The singleton which represents the nRF51822 transport for the BLE.
Vincent Coubard 638:c90ae1400bf2 36 */
Vincent Coubard 638:c90ae1400bf2 37 static nRF5xn deviceInstance;
Vincent Coubard 638:c90ae1400bf2 38
Vincent Coubard 638:c90ae1400bf2 39 /**
Vincent Coubard 638:c90ae1400bf2 40 * BLE-API requires an implementation of the following function in order to
Vincent Coubard 638:c90ae1400bf2 41 * obtain its transport handle.
Vincent Coubard 638:c90ae1400bf2 42 */
Vincent Coubard 638:c90ae1400bf2 43 BLEInstanceBase *
Vincent Coubard 638:c90ae1400bf2 44 createBLEInstance(void)
Vincent Coubard 638:c90ae1400bf2 45 {
Vincent Coubard 638:c90ae1400bf2 46 return &nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
Vincent Coubard 638:c90ae1400bf2 47 }
Vincent Coubard 638:c90ae1400bf2 48
Vincent Coubard 638:c90ae1400bf2 49 nRF5xn& nRF5xn::Instance(BLE::InstanceID_t instanceId)
Vincent Coubard 638:c90ae1400bf2 50 {
Vincent Coubard 638:c90ae1400bf2 51 return deviceInstance;
Vincent Coubard 638:c90ae1400bf2 52 }
Vincent Coubard 638:c90ae1400bf2 53
Vincent Coubard 638:c90ae1400bf2 54 nRF5xn::nRF5xn(void) :
Vincent Coubard 638:c90ae1400bf2 55 initialized(false),
Vincent Coubard 638:c90ae1400bf2 56 instanceID(BLE::DEFAULT_INSTANCE),
Vincent Coubard 638:c90ae1400bf2 57 gapInstance(),
Vincent Coubard 638:c90ae1400bf2 58 gattServerInstance(NULL),
Vincent Coubard 638:c90ae1400bf2 59 gattClientInstance(NULL),
Vincent Coubard 638:c90ae1400bf2 60 securityManagerInstance(NULL)
Vincent Coubard 638:c90ae1400bf2 61 {
Vincent Coubard 638:c90ae1400bf2 62 }
Vincent Coubard 638:c90ae1400bf2 63
Vincent Coubard 638:c90ae1400bf2 64 nRF5xn::~nRF5xn(void)
Vincent Coubard 638:c90ae1400bf2 65 {
Vincent Coubard 638:c90ae1400bf2 66 }
Vincent Coubard 638:c90ae1400bf2 67
Vincent Coubard 638:c90ae1400bf2 68 const char *nRF5xn::getVersion(void)
Vincent Coubard 638:c90ae1400bf2 69 {
Vincent Coubard 638:c90ae1400bf2 70 if (!initialized) {
Vincent Coubard 638:c90ae1400bf2 71 return "INITIALIZATION_INCOMPLETE";
Vincent Coubard 638:c90ae1400bf2 72 }
Vincent Coubard 638:c90ae1400bf2 73
Vincent Coubard 638:c90ae1400bf2 74 static char versionString[32];
Vincent Coubard 638:c90ae1400bf2 75 static bool versionFetched = false;
Vincent Coubard 638:c90ae1400bf2 76
Vincent Coubard 638:c90ae1400bf2 77 if (!versionFetched) {
Vincent Coubard 638:c90ae1400bf2 78 ble_version_t version;
Vincent Coubard 638:c90ae1400bf2 79 if ((sd_ble_version_get(&version) == NRF_SUCCESS) && (version.company_id == 0x0059)) {
Vincent Coubard 638:c90ae1400bf2 80 switch (version.version_number) {
Vincent Coubard 638:c90ae1400bf2 81 case 0x07:
Vincent Coubard 638:c90ae1400bf2 82 case 0x08:
Vincent Coubard 638:c90ae1400bf2 83 snprintf(versionString, sizeof(versionString), "Nordic BLE4.1 ver:%u fw:%04x", version.version_number, version.subversion_number);
Vincent Coubard 638:c90ae1400bf2 84 break;
Vincent Coubard 638:c90ae1400bf2 85 default:
Vincent Coubard 638:c90ae1400bf2 86 snprintf(versionString, sizeof(versionString), "Nordic (spec unknown) ver:%u fw:%04x", version.version_number, version.subversion_number);
Vincent Coubard 638:c90ae1400bf2 87 break;
Vincent Coubard 638:c90ae1400bf2 88 }
Vincent Coubard 638:c90ae1400bf2 89 versionFetched = true;
Vincent Coubard 638:c90ae1400bf2 90 } else {
Vincent Coubard 638:c90ae1400bf2 91 strncpy(versionString, "unknown", sizeof(versionString));
Vincent Coubard 638:c90ae1400bf2 92 }
Vincent Coubard 638:c90ae1400bf2 93 }
Vincent Coubard 638:c90ae1400bf2 94
Vincent Coubard 638:c90ae1400bf2 95 return versionString;
Vincent Coubard 638:c90ae1400bf2 96 }
Vincent Coubard 638:c90ae1400bf2 97
Vincent Coubard 638:c90ae1400bf2 98 /**************************************************************************/
Vincent Coubard 638:c90ae1400bf2 99 /*!
Vincent Coubard 638:c90ae1400bf2 100 @brief Initialize the BLE stack.
Vincent Coubard 638:c90ae1400bf2 101
Vincent Coubard 638:c90ae1400bf2 102 @returns ble_error_t
Vincent Coubard 638:c90ae1400bf2 103
Vincent Coubard 638:c90ae1400bf2 104 @retval BLE_ERROR_NONE if everything executed properly and
Vincent Coubard 638:c90ae1400bf2 105 BLE_ERROR_ALREADY_INITIALIZED if the stack has already
Vincent Coubard 638:c90ae1400bf2 106 been initialized (possibly through a call to nRF5xn::init()).
Vincent Coubard 638:c90ae1400bf2 107 BLE_ERROR_INTERNAL_STACK_FAILURE is returned if initialization
Vincent Coubard 638:c90ae1400bf2 108 of the internal stack (SoftDevice) failed.
Vincent Coubard 638:c90ae1400bf2 109
Vincent Coubard 638:c90ae1400bf2 110 */
Vincent Coubard 638:c90ae1400bf2 111 /**************************************************************************/
Vincent Coubard 638:c90ae1400bf2 112 ble_error_t nRF5xn::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback)
Vincent Coubard 638:c90ae1400bf2 113 {
Vincent Coubard 638:c90ae1400bf2 114 if (initialized) {
Vincent Coubard 638:c90ae1400bf2 115 BLE::InitializationCompleteCallbackContext context = {
Vincent Coubard 638:c90ae1400bf2 116 BLE::Instance(instanceID),
Vincent Coubard 638:c90ae1400bf2 117 BLE_ERROR_ALREADY_INITIALIZED
Vincent Coubard 638:c90ae1400bf2 118 };
Vincent Coubard 638:c90ae1400bf2 119 callback.call(&context);
Vincent Coubard 638:c90ae1400bf2 120 return BLE_ERROR_ALREADY_INITIALIZED;
Vincent Coubard 638:c90ae1400bf2 121 }
Vincent Coubard 638:c90ae1400bf2 122
Vincent Coubard 638:c90ae1400bf2 123 instanceID = instanceID;
Vincent Coubard 638:c90ae1400bf2 124
Vincent Coubard 638:c90ae1400bf2 125 /* ToDo: Clear memory contents, reset the SD, etc. */
Vincent Coubard 638:c90ae1400bf2 126 if (btle_init() != ERROR_NONE) {
Vincent Coubard 638:c90ae1400bf2 127 return BLE_ERROR_INTERNAL_STACK_FAILURE;
Vincent Coubard 638:c90ae1400bf2 128 }
Vincent Coubard 638:c90ae1400bf2 129
Vincent Coubard 638:c90ae1400bf2 130 initialized = true;
Vincent Coubard 638:c90ae1400bf2 131 BLE::InitializationCompleteCallbackContext context = {
Vincent Coubard 638:c90ae1400bf2 132 BLE::Instance(instanceID),
Vincent Coubard 638:c90ae1400bf2 133 BLE_ERROR_NONE
Vincent Coubard 638:c90ae1400bf2 134 };
Vincent Coubard 638:c90ae1400bf2 135 callback.call(&context);
Vincent Coubard 638:c90ae1400bf2 136 return BLE_ERROR_NONE;
Vincent Coubard 638:c90ae1400bf2 137 }
Vincent Coubard 638:c90ae1400bf2 138
Vincent Coubard 638:c90ae1400bf2 139 /**************************************************************************/
Vincent Coubard 638:c90ae1400bf2 140 /*!
Vincent Coubard 638:c90ae1400bf2 141 @brief Purge the BLE stack of GATT and GAP state.
Vincent Coubard 638:c90ae1400bf2 142
Vincent Coubard 638:c90ae1400bf2 143 @returns ble_error_t
Vincent Coubard 638:c90ae1400bf2 144
Vincent Coubard 638:c90ae1400bf2 145 @retval BLE_ERROR_NONE
Vincent Coubard 638:c90ae1400bf2 146 Everything executed properly
Vincent Coubard 638:c90ae1400bf2 147
Vincent Coubard 638:c90ae1400bf2 148 @note When using S110, GattClient::shutdown() will not be called
Vincent Coubard 638:c90ae1400bf2 149 since Gatt client features are not supported.
Vincent Coubard 638:c90ae1400bf2 150 */
Vincent Coubard 638:c90ae1400bf2 151 /**************************************************************************/
Vincent Coubard 638:c90ae1400bf2 152 ble_error_t nRF5xn::shutdown(void)
Vincent Coubard 638:c90ae1400bf2 153 {
Vincent Coubard 638:c90ae1400bf2 154 if (!initialized) {
Vincent Coubard 638:c90ae1400bf2 155 return BLE_ERROR_INITIALIZATION_INCOMPLETE;
Vincent Coubard 638:c90ae1400bf2 156 }
Vincent Coubard 638:c90ae1400bf2 157
Vincent Coubard 638:c90ae1400bf2 158 /*
Vincent Coubard 638:c90ae1400bf2 159 * Shutdown the SoftDevice first. This is because we need to disable all
Vincent Coubard 638:c90ae1400bf2 160 * interrupts. Otherwise if we clear the BLE API and glue code first there
Vincent Coubard 638:c90ae1400bf2 161 * will be many NULL references and no config information which could lead
Vincent Coubard 638:c90ae1400bf2 162 * to errors if the shutdown process is interrupted.
Vincent Coubard 638:c90ae1400bf2 163 */
Vincent Coubard 638:c90ae1400bf2 164 if (softdevice_handler_sd_disable() != NRF_SUCCESS) {
Vincent Coubard 638:c90ae1400bf2 165 return BLE_STACK_BUSY;
Vincent Coubard 638:c90ae1400bf2 166 }
Vincent Coubard 638:c90ae1400bf2 167
Vincent Coubard 638:c90ae1400bf2 168
Vincent Coubard 638:c90ae1400bf2 169 /* Shutdown the BLE API and nRF51 glue code */
Vincent Coubard 638:c90ae1400bf2 170 ble_error_t error;
Vincent Coubard 638:c90ae1400bf2 171
Vincent Coubard 638:c90ae1400bf2 172 if (gattServerInstance != NULL) {
Vincent Coubard 638:c90ae1400bf2 173 error = gattServerInstance->reset();
Vincent Coubard 638:c90ae1400bf2 174 if (error != BLE_ERROR_NONE) {
Vincent Coubard 638:c90ae1400bf2 175 return error;
Vincent Coubard 638:c90ae1400bf2 176 }
Vincent Coubard 638:c90ae1400bf2 177 }
Vincent Coubard 638:c90ae1400bf2 178
Vincent Coubard 638:c90ae1400bf2 179 if (securityManagerInstance != NULL) {
Vincent Coubard 638:c90ae1400bf2 180 error = securityManagerInstance->reset();
Vincent Coubard 638:c90ae1400bf2 181 if (error != BLE_ERROR_NONE) {
Vincent Coubard 638:c90ae1400bf2 182 return error;
Vincent Coubard 638:c90ae1400bf2 183 }
Vincent Coubard 638:c90ae1400bf2 184 }
Vincent Coubard 638:c90ae1400bf2 185
Vincent Coubard 638:c90ae1400bf2 186 /* S110 does not support BLE client features, nothing to reset. */
Vincent Coubard 638:c90ae1400bf2 187 #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
Vincent Coubard 638:c90ae1400bf2 188 if (gattClientInstance != NULL) {
Vincent Coubard 638:c90ae1400bf2 189 error = gattClientInstance->reset();
Vincent Coubard 638:c90ae1400bf2 190 if (error != BLE_ERROR_NONE) {
Vincent Coubard 638:c90ae1400bf2 191 return error;
Vincent Coubard 638:c90ae1400bf2 192 }
Vincent Coubard 638:c90ae1400bf2 193 }
Vincent Coubard 638:c90ae1400bf2 194 #endif
Vincent Coubard 638:c90ae1400bf2 195
Vincent Coubard 638:c90ae1400bf2 196 /* Gap instance is always present */
Vincent Coubard 638:c90ae1400bf2 197 error = gapInstance.reset();
Vincent Coubard 638:c90ae1400bf2 198 if (error != BLE_ERROR_NONE) {
Vincent Coubard 638:c90ae1400bf2 199 return error;
Vincent Coubard 638:c90ae1400bf2 200 }
Vincent Coubard 638:c90ae1400bf2 201
Vincent Coubard 638:c90ae1400bf2 202 custom_reset_128bits_uuid_table();
Vincent Coubard 638:c90ae1400bf2 203
Vincent Coubard 638:c90ae1400bf2 204 initialized = false;
Vincent Coubard 638:c90ae1400bf2 205 return BLE_ERROR_NONE;
Vincent Coubard 638:c90ae1400bf2 206 }
Vincent Coubard 638:c90ae1400bf2 207
Vincent Coubard 638:c90ae1400bf2 208 void
Vincent Coubard 638:c90ae1400bf2 209 nRF5xn::waitForEvent(void)
Vincent Coubard 638:c90ae1400bf2 210 {
Vincent Coubard 638:c90ae1400bf2 211 processEvents();
Vincent Coubard 638:c90ae1400bf2 212 sd_app_evt_wait();
Vincent Coubard 638:c90ae1400bf2 213 }
Vincent Coubard 638:c90ae1400bf2 214
Vincent Coubard 638:c90ae1400bf2 215 void nRF5xn::processEvents() {
Vincent Coubard 638:c90ae1400bf2 216 if (isEventsSignaled) {
Vincent Coubard 638:c90ae1400bf2 217 isEventsSignaled = false;
Vincent Coubard 638:c90ae1400bf2 218 intern_softdevice_events_execute();
Vincent Coubard 638:c90ae1400bf2 219 }
Vincent Coubard 638:c90ae1400bf2 220 }