mbed os with nrf51 internal bandgap enabled to read battery level

Dependents:   BLE_file_test BLE_Blink ExternalEncoder

Committer:
elessair
Date:
Sun Oct 23 15:10:02 2016 +0000
Revision:
0:f269e3021894
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elessair 0:f269e3021894 1 /* mbed Microcontroller Library
elessair 0:f269e3021894 2 * Copyright (c) 2006-2013 ARM Limited
elessair 0:f269e3021894 3 *
elessair 0:f269e3021894 4 * Licensed under the Apache License, Version 2.0 (the "License");
elessair 0:f269e3021894 5 * you may not use this file except in compliance with the License.
elessair 0:f269e3021894 6 * You may obtain a copy of the License at
elessair 0:f269e3021894 7 *
elessair 0:f269e3021894 8 * http://www.apache.org/licenses/LICENSE-2.0
elessair 0:f269e3021894 9 *
elessair 0:f269e3021894 10 * Unless required by applicable law or agreed to in writing, software
elessair 0:f269e3021894 11 * distributed under the License is distributed on an "AS IS" BASIS,
elessair 0:f269e3021894 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
elessair 0:f269e3021894 13 * See the License for the specific language governing permissions and
elessair 0:f269e3021894 14 * limitations under the License.
elessair 0:f269e3021894 15 */
elessair 0:f269e3021894 16
elessair 0:f269e3021894 17 #include "ble/BLE.h"
elessair 0:f269e3021894 18 #include "ble/BLEInstanceBase.h"
elessair 0:f269e3021894 19
elessair 0:f269e3021894 20 #if defined(TARGET_OTA_ENABLED)
elessair 0:f269e3021894 21 #include "ble/services/DFUService.h"
elessair 0:f269e3021894 22 #endif
elessair 0:f269e3021894 23
elessair 0:f269e3021894 24 #ifdef YOTTA_CFG_MBED_OS
elessair 0:f269e3021894 25 #include <minar/minar.h>
elessair 0:f269e3021894 26 #endif
elessair 0:f269e3021894 27
elessair 0:f269e3021894 28 #if !defined(YOTTA_CFG_MBED_OS)
elessair 0:f269e3021894 29 #include <mbed_error.h>
elessair 0:f269e3021894 30 #include <toolchain.h>
elessair 0:f269e3021894 31 #endif
elessair 0:f269e3021894 32
elessair 0:f269e3021894 33 ble_error_t
elessair 0:f269e3021894 34 BLE::initImplementation(FunctionPointerWithContext<InitializationCompleteCallbackContext*> callback)
elessair 0:f269e3021894 35 {
elessair 0:f269e3021894 36 ble_error_t err = transport->init(instanceID, callback);
elessair 0:f269e3021894 37 if (err != BLE_ERROR_NONE) {
elessair 0:f269e3021894 38 return err;
elessair 0:f269e3021894 39 }
elessair 0:f269e3021894 40
elessair 0:f269e3021894 41 /* Platforms enabled for DFU should introduce the DFU Service into
elessair 0:f269e3021894 42 * applications automatically. */
elessair 0:f269e3021894 43 #if defined(TARGET_OTA_ENABLED)
elessair 0:f269e3021894 44 static DFUService dfu(*this); // defined static so that the object remains alive
elessair 0:f269e3021894 45 #endif // TARGET_OTA_ENABLED
elessair 0:f269e3021894 46
elessair 0:f269e3021894 47 return BLE_ERROR_NONE;
elessair 0:f269e3021894 48 }
elessair 0:f269e3021894 49
elessair 0:f269e3021894 50 /**
elessair 0:f269e3021894 51 * BLE::Instance() and BLE constructor rely upon a static array of initializers
elessair 0:f269e3021894 52 * to create actual BLE transport instances. A description of these instances
elessair 0:f269e3021894 53 * and initializers is supposed to be put in some .json file contributing to
elessair 0:f269e3021894 54 * yotta's configuration (typically in the target definition described by
elessair 0:f269e3021894 55 * target.json). Here's a sample:
elessair 0:f269e3021894 56 *
elessair 0:f269e3021894 57 * "config": {
elessair 0:f269e3021894 58 * ...
elessair 0:f269e3021894 59 * "ble_instances": {
elessair 0:f269e3021894 60 * "count": 1,
elessair 0:f269e3021894 61 * "0" : {
elessair 0:f269e3021894 62 * "initializer" : "createBLEInstance"
elessair 0:f269e3021894 63 * }
elessair 0:f269e3021894 64 * }
elessair 0:f269e3021894 65 * ...
elessair 0:f269e3021894 66 * }
elessair 0:f269e3021894 67 *
elessair 0:f269e3021894 68 * The following macros result in translating the above config into a static
elessair 0:f269e3021894 69 * array: instanceConstructors.
elessair 0:f269e3021894 70 */
elessair 0:f269e3021894 71 #ifdef YOTTA_CFG_BLE_INSTANCES_COUNT
elessair 0:f269e3021894 72 #define CONCATENATE(A, B) A ## B
elessair 0:f269e3021894 73 #define EXPAND(X) X /* this adds a level of indirection needed to allow macro-expansion following a token-paste operation (see use of CONCATENATE() below). */
elessair 0:f269e3021894 74
elessair 0:f269e3021894 75 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1 YOTTA_CFG_BLE_INSTANCES_0_INITIALIZER
elessair 0:f269e3021894 76 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1, YOTTA_CFG_BLE_INSTANCES_1_INITIALIZER
elessair 0:f269e3021894 77 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2, YOTTA_CFG_BLE_INSTANCES_2_INITIALIZER
elessair 0:f269e3021894 78 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3, YOTTA_CFG_BLE_INSTANCES_3_INITIALIZER
elessair 0:f269e3021894 79 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_5 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4, YOTTA_CFG_BLE_INSTANCES_4_INITIALIZER
elessair 0:f269e3021894 80 /* ... add more of the above if ever needed */
elessair 0:f269e3021894 81
elessair 0:f269e3021894 82 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(N) EXPAND(CONCATENATE(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_, N))
elessair 0:f269e3021894 83 #elif !defined(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS)
elessair 0:f269e3021894 84 /*
elessair 0:f269e3021894 85 * The following applies when building without yotta. By default BLE_API provides
elessair 0:f269e3021894 86 * a trivial initializer list containing a single constructor: createBLEInstance.
elessair 0:f269e3021894 87 * This may be overridden.
elessair 0:f269e3021894 88 */
elessair 0:f269e3021894 89 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS createBLEInstance
elessair 0:f269e3021894 90
elessair 0:f269e3021894 91 // yotta unlike mbed-cli has proper dependency mechanisms
elessair 0:f269e3021894 92 // It is not required to defined a stub for createBLEInstance
elessair 0:f269e3021894 93 #if !defined(YOTTA_CFG_MBED_OS)
elessair 0:f269e3021894 94
elessair 0:f269e3021894 95 // this stub is required by ARMCC otherwise link will systematically fail
elessair 0:f269e3021894 96 MBED_WEAK BLEInstanceBase* createBLEInstance() {
elessair 0:f269e3021894 97 error("Please provide an implementation for mbed BLE");
elessair 0:f269e3021894 98 return NULL;
elessair 0:f269e3021894 99 }
elessair 0:f269e3021894 100
elessair 0:f269e3021894 101 #endif
elessair 0:f269e3021894 102
elessair 0:f269e3021894 103
elessair 0:f269e3021894 104 #endif /* YOTTA_CFG_BLE_INSTANCES_COUNT */
elessair 0:f269e3021894 105
elessair 0:f269e3021894 106 typedef BLEInstanceBase *(*InstanceConstructor_t)(void);
elessair 0:f269e3021894 107 static const InstanceConstructor_t instanceConstructors[BLE::NUM_INSTANCES] = {
elessair 0:f269e3021894 108 #ifndef YOTTA_CFG_BLE_INSTANCES_COUNT
elessair 0:f269e3021894 109 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS
elessair 0:f269e3021894 110 #else
elessair 0:f269e3021894 111 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(YOTTA_CFG_BLE_INSTANCES_COUNT)
elessair 0:f269e3021894 112 #endif
elessair 0:f269e3021894 113 };
elessair 0:f269e3021894 114
elessair 0:f269e3021894 115 BLE &
elessair 0:f269e3021894 116 BLE::Instance(InstanceID_t id)
elessair 0:f269e3021894 117 {
elessair 0:f269e3021894 118 static BLE *singletons[NUM_INSTANCES];
elessair 0:f269e3021894 119 if (id < NUM_INSTANCES) {
elessair 0:f269e3021894 120 if (singletons[id] == NULL) {
elessair 0:f269e3021894 121 singletons[id] = new BLE(id); /* This object will never be freed. */
elessair 0:f269e3021894 122 }
elessair 0:f269e3021894 123
elessair 0:f269e3021894 124 return *singletons[id];
elessair 0:f269e3021894 125 }
elessair 0:f269e3021894 126
elessair 0:f269e3021894 127 /* we come here only in the case of a bad interfaceID. */
elessair 0:f269e3021894 128 static BLE badSingleton(NUM_INSTANCES /* this is a bad index; and will result in a NULL transport. */);
elessair 0:f269e3021894 129 return badSingleton;
elessair 0:f269e3021894 130 }
elessair 0:f269e3021894 131
elessair 0:f269e3021894 132 #ifdef YOTTA_CFG_MBED_OS
elessair 0:f269e3021894 133 void defaultSchedulingCallback(BLE::OnEventsToProcessCallbackContext* params) {
elessair 0:f269e3021894 134 minar::Scheduler::postCallback(&params->ble, &BLE::processEvents);
elessair 0:f269e3021894 135 }
elessair 0:f269e3021894 136 #else
elessair 0:f269e3021894 137 #define defaultSchedulingCallback NULL
elessair 0:f269e3021894 138 #endif
elessair 0:f269e3021894 139
elessair 0:f269e3021894 140
elessair 0:f269e3021894 141 BLE::BLE(InstanceID_t instanceIDIn) : instanceID(instanceIDIn), transport(),
elessair 0:f269e3021894 142 whenEventsToProcess(defaultSchedulingCallback)
elessair 0:f269e3021894 143 {
elessair 0:f269e3021894 144 static BLEInstanceBase *transportInstances[NUM_INSTANCES];
elessair 0:f269e3021894 145
elessair 0:f269e3021894 146 if (instanceID < NUM_INSTANCES) {
elessair 0:f269e3021894 147 if (!transportInstances[instanceID]) {
elessair 0:f269e3021894 148 transportInstances[instanceID] = instanceConstructors[instanceID](); /* Call the stack's initializer for the transport object. */
elessair 0:f269e3021894 149 }
elessair 0:f269e3021894 150 transport = transportInstances[instanceID];
elessair 0:f269e3021894 151 } else {
elessair 0:f269e3021894 152 transport = NULL;
elessair 0:f269e3021894 153 }
elessair 0:f269e3021894 154 }
elessair 0:f269e3021894 155
elessair 0:f269e3021894 156 bool BLE::hasInitialized(void) const
elessair 0:f269e3021894 157 {
elessair 0:f269e3021894 158 if (!transport) {
elessair 0:f269e3021894 159 error("bad handle to underlying transport");
elessair 0:f269e3021894 160 }
elessair 0:f269e3021894 161
elessair 0:f269e3021894 162 return transport->hasInitialized();
elessair 0:f269e3021894 163 }
elessair 0:f269e3021894 164
elessair 0:f269e3021894 165 ble_error_t BLE::shutdown(void)
elessair 0:f269e3021894 166 {
elessair 0:f269e3021894 167 if (!transport) {
elessair 0:f269e3021894 168 error("bad handle to underlying transport");
elessair 0:f269e3021894 169 }
elessair 0:f269e3021894 170
elessair 0:f269e3021894 171 return transport->shutdown();
elessair 0:f269e3021894 172 }
elessair 0:f269e3021894 173
elessair 0:f269e3021894 174 const char *BLE::getVersion(void)
elessair 0:f269e3021894 175 {
elessair 0:f269e3021894 176 if (!transport) {
elessair 0:f269e3021894 177 error("bad handle to underlying transport");
elessair 0:f269e3021894 178 }
elessair 0:f269e3021894 179
elessair 0:f269e3021894 180 return transport->getVersion();
elessair 0:f269e3021894 181 }
elessair 0:f269e3021894 182
elessair 0:f269e3021894 183 const Gap &BLE::gap() const
elessair 0:f269e3021894 184 {
elessair 0:f269e3021894 185 if (!transport) {
elessair 0:f269e3021894 186 error("bad handle to underlying transport");
elessair 0:f269e3021894 187 }
elessair 0:f269e3021894 188
elessair 0:f269e3021894 189 return transport->getGap();
elessair 0:f269e3021894 190 }
elessair 0:f269e3021894 191
elessair 0:f269e3021894 192 Gap &BLE::gap()
elessair 0:f269e3021894 193 {
elessair 0:f269e3021894 194 if (!transport) {
elessair 0:f269e3021894 195 error("bad handle to underlying transport");
elessair 0:f269e3021894 196 }
elessair 0:f269e3021894 197
elessair 0:f269e3021894 198 return transport->getGap();
elessair 0:f269e3021894 199 }
elessair 0:f269e3021894 200
elessair 0:f269e3021894 201 const GattServer& BLE::gattServer() const
elessair 0:f269e3021894 202 {
elessair 0:f269e3021894 203 if (!transport) {
elessair 0:f269e3021894 204 error("bad handle to underlying transport");
elessair 0:f269e3021894 205 }
elessair 0:f269e3021894 206
elessair 0:f269e3021894 207 return transport->getGattServer();
elessair 0:f269e3021894 208 }
elessair 0:f269e3021894 209
elessair 0:f269e3021894 210 GattServer& BLE::gattServer()
elessair 0:f269e3021894 211 {
elessair 0:f269e3021894 212 if (!transport) {
elessair 0:f269e3021894 213 error("bad handle to underlying transport");
elessair 0:f269e3021894 214 }
elessair 0:f269e3021894 215
elessair 0:f269e3021894 216 return transport->getGattServer();
elessair 0:f269e3021894 217 }
elessair 0:f269e3021894 218
elessair 0:f269e3021894 219 const GattClient& BLE::gattClient() const
elessair 0:f269e3021894 220 {
elessair 0:f269e3021894 221 if (!transport) {
elessair 0:f269e3021894 222 error("bad handle to underlying transport");
elessair 0:f269e3021894 223 }
elessair 0:f269e3021894 224
elessair 0:f269e3021894 225 return transport->getGattClient();
elessair 0:f269e3021894 226 }
elessair 0:f269e3021894 227
elessair 0:f269e3021894 228 GattClient& BLE::gattClient()
elessair 0:f269e3021894 229 {
elessair 0:f269e3021894 230 if (!transport) {
elessair 0:f269e3021894 231 error("bad handle to underlying transport");
elessair 0:f269e3021894 232 }
elessair 0:f269e3021894 233
elessair 0:f269e3021894 234 return transport->getGattClient();
elessair 0:f269e3021894 235 }
elessair 0:f269e3021894 236
elessair 0:f269e3021894 237 const SecurityManager& BLE::securityManager() const
elessair 0:f269e3021894 238 {
elessair 0:f269e3021894 239 if (!transport) {
elessair 0:f269e3021894 240 error("bad handle to underlying transport");
elessair 0:f269e3021894 241 }
elessair 0:f269e3021894 242
elessair 0:f269e3021894 243 return transport->getSecurityManager();
elessair 0:f269e3021894 244 }
elessair 0:f269e3021894 245
elessair 0:f269e3021894 246 SecurityManager& BLE::securityManager()
elessair 0:f269e3021894 247 {
elessair 0:f269e3021894 248 if (!transport) {
elessair 0:f269e3021894 249 error("bad handle to underlying transport");
elessair 0:f269e3021894 250 }
elessair 0:f269e3021894 251
elessair 0:f269e3021894 252 return transport->getSecurityManager();
elessair 0:f269e3021894 253 }
elessair 0:f269e3021894 254
elessair 0:f269e3021894 255 void BLE::waitForEvent(void)
elessair 0:f269e3021894 256 {
elessair 0:f269e3021894 257 if (!transport) {
elessair 0:f269e3021894 258 error("bad handle to underlying transport");
elessair 0:f269e3021894 259 }
elessair 0:f269e3021894 260
elessair 0:f269e3021894 261 transport->waitForEvent();
elessair 0:f269e3021894 262 }
elessair 0:f269e3021894 263
elessair 0:f269e3021894 264 void BLE::processEvents()
elessair 0:f269e3021894 265 {
elessair 0:f269e3021894 266 if (!transport) {
elessair 0:f269e3021894 267 error("bad handle to underlying transport");
elessair 0:f269e3021894 268 }
elessair 0:f269e3021894 269
elessair 0:f269e3021894 270 transport->processEvents();
elessair 0:f269e3021894 271 }
elessair 0:f269e3021894 272
elessair 0:f269e3021894 273 void BLE::onEventsToProcess(const BLE::OnEventsToProcessCallback_t& callback)
elessair 0:f269e3021894 274 {
elessair 0:f269e3021894 275 whenEventsToProcess = callback;
elessair 0:f269e3021894 276 }
elessair 0:f269e3021894 277
elessair 0:f269e3021894 278 void BLE::signalEventsToProcess()
elessair 0:f269e3021894 279 {
elessair 0:f269e3021894 280 if (whenEventsToProcess) {
elessair 0:f269e3021894 281 OnEventsToProcessCallbackContext params = {
elessair 0:f269e3021894 282 *this
elessair 0:f269e3021894 283 };
elessair 0:f269e3021894 284 whenEventsToProcess(&params);
elessair 0:f269e3021894 285 }
elessair 0:f269e3021894 286 }