Nordic stack and drivers for the mbed BLE API

Fork of nRF51822 by Nordic Semiconductor

Committer:
amithy
Date:
Fri Nov 10 01:00:06 2017 +0000
Revision:
639:5aeed2c29513
Parent:
638:c90ae1400bf2
for testing export

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 "nrf_delay.h"
Vincent Coubard 638:c90ae1400bf2 28
Vincent Coubard 638:c90ae1400bf2 29 extern "C" {
Vincent Coubard 638:c90ae1400bf2 30 #include "softdevice_handler.h"
Vincent Coubard 638:c90ae1400bf2 31 }
Vincent Coubard 638:c90ae1400bf2 32
Vincent Coubard 638:c90ae1400bf2 33 /**
Vincent Coubard 638:c90ae1400bf2 34 * The singleton which represents the nRF51822 transport for the BLE.
Vincent Coubard 638:c90ae1400bf2 35 */
Vincent Coubard 638:c90ae1400bf2 36 static nRF5xn deviceInstance;
Vincent Coubard 638:c90ae1400bf2 37
Vincent Coubard 638:c90ae1400bf2 38 /**
Vincent Coubard 638:c90ae1400bf2 39 * BLE-API requires an implementation of the following function in order to
Vincent Coubard 638:c90ae1400bf2 40 * obtain its transport handle.
Vincent Coubard 638:c90ae1400bf2 41 */
Vincent Coubard 638:c90ae1400bf2 42 BLEInstanceBase *
Vincent Coubard 638:c90ae1400bf2 43 createBLEInstance(void)
Vincent Coubard 638:c90ae1400bf2 44 {
Vincent Coubard 638:c90ae1400bf2 45 return &nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
Vincent Coubard 638:c90ae1400bf2 46 }
Vincent Coubard 638:c90ae1400bf2 47
Vincent Coubard 638:c90ae1400bf2 48 nRF5xn& nRF5xn::Instance(BLE::InstanceID_t instanceId)
Vincent Coubard 638:c90ae1400bf2 49 {
Vincent Coubard 638:c90ae1400bf2 50 return deviceInstance;
Vincent Coubard 638:c90ae1400bf2 51 }
Vincent Coubard 638:c90ae1400bf2 52
Vincent Coubard 638:c90ae1400bf2 53 nRF5xn::nRF5xn(void) :
Vincent Coubard 638:c90ae1400bf2 54 initialized(false),
Vincent Coubard 638:c90ae1400bf2 55 instanceID(BLE::DEFAULT_INSTANCE),
Vincent Coubard 638:c90ae1400bf2 56 gapInstance(),
Vincent Coubard 638:c90ae1400bf2 57 gattServerInstance(NULL),
Vincent Coubard 638:c90ae1400bf2 58 gattClientInstance(NULL),
Vincent Coubard 638:c90ae1400bf2 59 securityManagerInstance(NULL)
Vincent Coubard 638:c90ae1400bf2 60 {
Vincent Coubard 638:c90ae1400bf2 61 }
Vincent Coubard 638:c90ae1400bf2 62
Vincent Coubard 638:c90ae1400bf2 63 nRF5xn::~nRF5xn(void)
Vincent Coubard 638:c90ae1400bf2 64 {
Vincent Coubard 638:c90ae1400bf2 65 }
Vincent Coubard 638:c90ae1400bf2 66
Vincent Coubard 638:c90ae1400bf2 67 const char *nRF5xn::getVersion(void)
Vincent Coubard 638:c90ae1400bf2 68 {
Vincent Coubard 638:c90ae1400bf2 69 if (!initialized) {
Vincent Coubard 638:c90ae1400bf2 70 return "INITIALIZATION_INCOMPLETE";
Vincent Coubard 638:c90ae1400bf2 71 }
Vincent Coubard 638:c90ae1400bf2 72
Vincent Coubard 638:c90ae1400bf2 73 static char versionString[32];
Vincent Coubard 638:c90ae1400bf2 74 static bool versionFetched = false;
Vincent Coubard 638:c90ae1400bf2 75
Vincent Coubard 638:c90ae1400bf2 76 if (!versionFetched) {
Vincent Coubard 638:c90ae1400bf2 77 ble_version_t version;
Vincent Coubard 638:c90ae1400bf2 78 if ((sd_ble_version_get(&version) == NRF_SUCCESS) && (version.company_id == 0x0059)) {
Vincent Coubard 638:c90ae1400bf2 79 switch (version.version_number) {
Vincent Coubard 638:c90ae1400bf2 80 case 0x07:
Vincent Coubard 638:c90ae1400bf2 81 case 0x08:
Vincent Coubard 638:c90ae1400bf2 82 snprintf(versionString, sizeof(versionString), "Nordic BLE4.1 ver:%u fw:%04x", version.version_number, version.subversion_number);
Vincent Coubard 638:c90ae1400bf2 83 break;
Vincent Coubard 638:c90ae1400bf2 84 default:
Vincent Coubard 638:c90ae1400bf2 85 snprintf(versionString, sizeof(versionString), "Nordic (spec unknown) ver:%u fw:%04x", version.version_number, version.subversion_number);
Vincent Coubard 638:c90ae1400bf2 86 break;
Vincent Coubard 638:c90ae1400bf2 87 }
Vincent Coubard 638:c90ae1400bf2 88 versionFetched = true;
Vincent Coubard 638:c90ae1400bf2 89 } else {
Vincent Coubard 638:c90ae1400bf2 90 strncpy(versionString, "unknown", sizeof(versionString));
Vincent Coubard 638:c90ae1400bf2 91 }
Vincent Coubard 638:c90ae1400bf2 92 }
Vincent Coubard 638:c90ae1400bf2 93
Vincent Coubard 638:c90ae1400bf2 94 return versionString;
Vincent Coubard 638:c90ae1400bf2 95 }
Vincent Coubard 638:c90ae1400bf2 96
Vincent Coubard 638:c90ae1400bf2 97 /**************************************************************************/
Vincent Coubard 638:c90ae1400bf2 98 /*!
Vincent Coubard 638:c90ae1400bf2 99 @brief Initialize the BLE stack.
Vincent Coubard 638:c90ae1400bf2 100
Vincent Coubard 638:c90ae1400bf2 101 @returns ble_error_t
Vincent Coubard 638:c90ae1400bf2 102
Vincent Coubard 638:c90ae1400bf2 103 @retval BLE_ERROR_NONE if everything executed properly and
Vincent Coubard 638:c90ae1400bf2 104 BLE_ERROR_ALREADY_INITIALIZED if the stack has already
Vincent Coubard 638:c90ae1400bf2 105 been initialized (possibly through a call to nRF5xn::init()).
Vincent Coubard 638:c90ae1400bf2 106 BLE_ERROR_INTERNAL_STACK_FAILURE is returned if initialization
Vincent Coubard 638:c90ae1400bf2 107 of the internal stack (SoftDevice) failed.
Vincent Coubard 638:c90ae1400bf2 108
Vincent Coubard 638:c90ae1400bf2 109 */
Vincent Coubard 638:c90ae1400bf2 110 /**************************************************************************/
Vincent Coubard 638:c90ae1400bf2 111 ble_error_t nRF5xn::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback)
Vincent Coubard 638:c90ae1400bf2 112 {
Vincent Coubard 638:c90ae1400bf2 113 if (initialized) {
Vincent Coubard 638:c90ae1400bf2 114 BLE::InitializationCompleteCallbackContext context = {
Vincent Coubard 638:c90ae1400bf2 115 BLE::Instance(instanceID),
Vincent Coubard 638:c90ae1400bf2 116 BLE_ERROR_ALREADY_INITIALIZED
Vincent Coubard 638:c90ae1400bf2 117 };
Vincent Coubard 638:c90ae1400bf2 118 callback.call(&context);
Vincent Coubard 638:c90ae1400bf2 119 return BLE_ERROR_ALREADY_INITIALIZED;
Vincent Coubard 638:c90ae1400bf2 120 }
Vincent Coubard 638:c90ae1400bf2 121
Vincent Coubard 638:c90ae1400bf2 122 instanceID = instanceID;
Vincent Coubard 638:c90ae1400bf2 123
Vincent Coubard 638:c90ae1400bf2 124 /* ToDo: Clear memory contents, reset the SD, etc. */
Vincent Coubard 638:c90ae1400bf2 125 if (btle_init() != ERROR_NONE) {
Vincent Coubard 638:c90ae1400bf2 126 return BLE_ERROR_INTERNAL_STACK_FAILURE;
Vincent Coubard 638:c90ae1400bf2 127 }
Vincent Coubard 638:c90ae1400bf2 128
Vincent Coubard 638:c90ae1400bf2 129 initialized = true;
Vincent Coubard 638:c90ae1400bf2 130 BLE::InitializationCompleteCallbackContext context = {
Vincent Coubard 638:c90ae1400bf2 131 BLE::Instance(instanceID),
Vincent Coubard 638:c90ae1400bf2 132 BLE_ERROR_NONE
Vincent Coubard 638:c90ae1400bf2 133 };
Vincent Coubard 638:c90ae1400bf2 134 callback.call(&context);
Vincent Coubard 638:c90ae1400bf2 135 return BLE_ERROR_NONE;
Vincent Coubard 638:c90ae1400bf2 136 }
Vincent Coubard 638:c90ae1400bf2 137
Vincent Coubard 638:c90ae1400bf2 138 /**************************************************************************/
Vincent Coubard 638:c90ae1400bf2 139 /*!
Vincent Coubard 638:c90ae1400bf2 140 @brief Purge the BLE stack of GATT and GAP state.
Vincent Coubard 638:c90ae1400bf2 141
Vincent Coubard 638:c90ae1400bf2 142 @returns ble_error_t
Vincent Coubard 638:c90ae1400bf2 143
Vincent Coubard 638:c90ae1400bf2 144 @retval BLE_ERROR_NONE
Vincent Coubard 638:c90ae1400bf2 145 Everything executed properly
Vincent Coubard 638:c90ae1400bf2 146
Vincent Coubard 638:c90ae1400bf2 147 @note When using S110, GattClient::shutdown() will not be called
Vincent Coubard 638:c90ae1400bf2 148 since Gatt client features are not supported.
Vincent Coubard 638:c90ae1400bf2 149 */
Vincent Coubard 638:c90ae1400bf2 150 /**************************************************************************/
Vincent Coubard 638:c90ae1400bf2 151 ble_error_t nRF5xn::shutdown(void)
Vincent Coubard 638:c90ae1400bf2 152 {
Vincent Coubard 638:c90ae1400bf2 153 if (!initialized) {
Vincent Coubard 638:c90ae1400bf2 154 return BLE_ERROR_INITIALIZATION_INCOMPLETE;
Vincent Coubard 638:c90ae1400bf2 155 }
Vincent Coubard 638:c90ae1400bf2 156
Vincent Coubard 638:c90ae1400bf2 157 /*
Vincent Coubard 638:c90ae1400bf2 158 * Shutdown the SoftDevice first. This is because we need to disable all
Vincent Coubard 638:c90ae1400bf2 159 * interrupts. Otherwise if we clear the BLE API and glue code first there
Vincent Coubard 638:c90ae1400bf2 160 * will be many NULL references and no config information which could lead
Vincent Coubard 638:c90ae1400bf2 161 * to errors if the shutdown process is interrupted.
Vincent Coubard 638:c90ae1400bf2 162 */
Vincent Coubard 638:c90ae1400bf2 163 if (softdevice_handler_sd_disable() != NRF_SUCCESS) {
Vincent Coubard 638:c90ae1400bf2 164 return BLE_STACK_BUSY;
Vincent Coubard 638:c90ae1400bf2 165 }
Vincent Coubard 638:c90ae1400bf2 166
Vincent Coubard 638:c90ae1400bf2 167
Vincent Coubard 638:c90ae1400bf2 168 /* Shutdown the BLE API and nRF51 glue code */
Vincent Coubard 638:c90ae1400bf2 169 ble_error_t error;
Vincent Coubard 638:c90ae1400bf2 170
Vincent Coubard 638:c90ae1400bf2 171 if (gattServerInstance != NULL) {
Vincent Coubard 638:c90ae1400bf2 172 error = gattServerInstance->reset();
Vincent Coubard 638:c90ae1400bf2 173 if (error != BLE_ERROR_NONE) {
Vincent Coubard 638:c90ae1400bf2 174 return error;
Vincent Coubard 638:c90ae1400bf2 175 }
Vincent Coubard 638:c90ae1400bf2 176 }
Vincent Coubard 638:c90ae1400bf2 177
Vincent Coubard 638:c90ae1400bf2 178 if (securityManagerInstance != NULL) {
Vincent Coubard 638:c90ae1400bf2 179 error = securityManagerInstance->reset();
Vincent Coubard 638:c90ae1400bf2 180 if (error != BLE_ERROR_NONE) {
Vincent Coubard 638:c90ae1400bf2 181 return error;
Vincent Coubard 638:c90ae1400bf2 182 }
Vincent Coubard 638:c90ae1400bf2 183 }
Vincent Coubard 638:c90ae1400bf2 184
Vincent Coubard 638:c90ae1400bf2 185 /* S110 does not support BLE client features, nothing to reset. */
Vincent Coubard 638:c90ae1400bf2 186 #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
Vincent Coubard 638:c90ae1400bf2 187 if (gattClientInstance != NULL) {
Vincent Coubard 638:c90ae1400bf2 188 error = gattClientInstance->reset();
Vincent Coubard 638:c90ae1400bf2 189 if (error != BLE_ERROR_NONE) {
Vincent Coubard 638:c90ae1400bf2 190 return error;
Vincent Coubard 638:c90ae1400bf2 191 }
Vincent Coubard 638:c90ae1400bf2 192 }
Vincent Coubard 638:c90ae1400bf2 193 #endif
Vincent Coubard 638:c90ae1400bf2 194
Vincent Coubard 638:c90ae1400bf2 195 /* Gap instance is always present */
Vincent Coubard 638:c90ae1400bf2 196 error = gapInstance.reset();
Vincent Coubard 638:c90ae1400bf2 197 if (error != BLE_ERROR_NONE) {
Vincent Coubard 638:c90ae1400bf2 198 return error;
Vincent Coubard 638:c90ae1400bf2 199 }
Vincent Coubard 638:c90ae1400bf2 200
Vincent Coubard 638:c90ae1400bf2 201 initialized = false;
Vincent Coubard 638:c90ae1400bf2 202 return BLE_ERROR_NONE;
Vincent Coubard 638:c90ae1400bf2 203 }
Vincent Coubard 638:c90ae1400bf2 204
Vincent Coubard 638:c90ae1400bf2 205 void
Vincent Coubard 638:c90ae1400bf2 206 nRF5xn::waitForEvent(void)
Vincent Coubard 638:c90ae1400bf2 207 {
Vincent Coubard 638:c90ae1400bf2 208 processEvents();
Vincent Coubard 638:c90ae1400bf2 209 sd_app_evt_wait();
Vincent Coubard 638:c90ae1400bf2 210 }
Vincent Coubard 638:c90ae1400bf2 211
Vincent Coubard 638:c90ae1400bf2 212 void nRF5xn::processEvents() {
Vincent Coubard 638:c90ae1400bf2 213 if (isEventsSignaled) {
Vincent Coubard 638:c90ae1400bf2 214 isEventsSignaled = false;
Vincent Coubard 638:c90ae1400bf2 215 intern_softdevice_events_execute();
Vincent Coubard 638:c90ae1400bf2 216 }
Vincent Coubard 638:c90ae1400bf2 217 }