20200716 read Status Register each second

Dependencies:   SDFileSystem mbed-os-example-ble-GattServer max32630fthr

Committer:
aureliocarella
Date:
Thu Jul 16 14:59:04 2020 +0000
Revision:
21:51e162c130a9
Parent:
0:c671a4833315
20200716

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:c671a4833315 1 /* mbed Microcontroller Library
mbed_official 0:c671a4833315 2 * Copyright (c) 2017 ARM Limited
mbed_official 0:c671a4833315 3 *
mbed_official 0:c671a4833315 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 0:c671a4833315 5 * you may not use this file except in compliance with the License.
mbed_official 0:c671a4833315 6 * You may obtain a copy of the License at
mbed_official 0:c671a4833315 7 *
mbed_official 0:c671a4833315 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 0:c671a4833315 9 *
mbed_official 0:c671a4833315 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 0:c671a4833315 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 0:c671a4833315 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 0:c671a4833315 13 * See the License for the specific language governing permissions and
mbed_official 0:c671a4833315 14 * limitations under the License.
mbed_official 0:c671a4833315 15 */
mbed_official 0:c671a4833315 16
mbed_official 0:c671a4833315 17 #include <stdio.h>
mbed_official 0:c671a4833315 18
mbed_official 0:c671a4833315 19 #include "platform/Callback.h"
mbed_official 0:c671a4833315 20 #include "events/EventQueue.h"
mbed_official 0:c671a4833315 21 #include "platform/NonCopyable.h"
mbed_official 0:c671a4833315 22
mbed_official 0:c671a4833315 23 #include "ble/BLE.h"
mbed_official 0:c671a4833315 24 #include "ble/Gap.h"
mbed_official 0:c671a4833315 25 #include "ble/GattClient.h"
mbed_official 0:c671a4833315 26 #include "ble/GapAdvertisingParams.h"
mbed_official 0:c671a4833315 27 #include "ble/GapAdvertisingData.h"
mbed_official 0:c671a4833315 28 #include "ble/GattServer.h"
mbed_official 0:c671a4833315 29 #include "BLEProcess.h"
mbed_official 0:c671a4833315 30
aureliocarella 21:51e162c130a9 31 #include "max32630fthr.h"
aureliocarella 21:51e162c130a9 32 #include "RpcServer.h"
aureliocarella 21:51e162c130a9 33 #include "StringInOut.h"
aureliocarella 21:51e162c130a9 34 #include "Peripherals.h"
aureliocarella 21:51e162c130a9 35 #include "MAX30001.h"
aureliocarella 21:51e162c130a9 36 #include "DataLoggingService.h"
aureliocarella 21:51e162c130a9 37 #include "PushButton.h"
aureliocarella 21:51e162c130a9 38 #include "Streaming.h"
aureliocarella 21:51e162c130a9 39 #include "SDFileSystem.h"
aureliocarella 21:51e162c130a9 40 #include "version.h"
aureliocarella 21:51e162c130a9 41
aureliocarella 21:51e162c130a9 42
mbed_official 0:c671a4833315 43 using mbed::callback;
mbed_official 0:c671a4833315 44
mbed_official 0:c671a4833315 45 /**
mbed_official 0:c671a4833315 46 * A Clock service that demonstrate the GattServer features.
mbed_official 0:c671a4833315 47 *
mbed_official 0:c671a4833315 48 * The clock service host three characteristics that model the current hour,
mbed_official 0:c671a4833315 49 * minute and second of the clock. The value of the second characteristic is
mbed_official 0:c671a4833315 50 * incremented automatically by the system.
mbed_official 0:c671a4833315 51 *
mbed_official 0:c671a4833315 52 * A client can subscribe to updates of the clock characteristics and get
mbed_official 0:c671a4833315 53 * notified when one of the value is changed. Clients can also change value of
mbed_official 0:c671a4833315 54 * the second, minute and hour characteristric.
mbed_official 0:c671a4833315 55 */
mbed_official 0:c671a4833315 56 class ClockService {
mbed_official 0:c671a4833315 57 typedef ClockService Self;
mbed_official 0:c671a4833315 58
mbed_official 0:c671a4833315 59 public:
aureliocarella 21:51e162c130a9 60 uint8_t second;
aureliocarella 21:51e162c130a9 61 uint8_t minute;
aureliocarella 21:51e162c130a9 62 uint8_t hour;
aureliocarella 21:51e162c130a9 63
mbed_official 0:c671a4833315 64 ClockService() :
aureliocarella 21:51e162c130a9 65 _ecg("485f4145-52b9-4644-af1f-7a6b9322490f", 0),
aureliocarella 21:51e162c130a9 66 _rr_bpm("0a924ca7-87cd-4699-a3bd-abdcd9cf126a", 0),
aureliocarella 21:51e162c130a9 67 _max30001_chr("8dd6a1b7-bc75-4741-8a26-264af75807de", 0),
aureliocarella 21:51e162c130a9 68 _ecg_service(
mbed_official 0:c671a4833315 69 /* uuid */ "51311102-030e-485f-b122-f8f381aa84ed",
aureliocarella 21:51e162c130a9 70 /* characteristics */ _ecg_characteristics,
aureliocarella 21:51e162c130a9 71 /* numCharacteristics */ sizeof(_ecg_characteristics) /
aureliocarella 21:51e162c130a9 72 sizeof(_ecg_characteristics[0])
mbed_official 0:c671a4833315 73 ),
mbed_official 0:c671a4833315 74 _server(NULL),
aureliocarella 21:51e162c130a9 75
mbed_official 0:c671a4833315 76 _event_queue(NULL)
mbed_official 0:c671a4833315 77 {
mbed_official 0:c671a4833315 78 // update internal pointers (value, descriptors and characteristics array)
aureliocarella 21:51e162c130a9 79 _ecg_characteristics[0] = &_ecg;
aureliocarella 21:51e162c130a9 80 _ecg_characteristics[1] = &_rr_bpm;
aureliocarella 21:51e162c130a9 81 _ecg_characteristics[2] = &_max30001_chr;
mbed_official 0:c671a4833315 82
mbed_official 0:c671a4833315 83 // setup authorization handlers
aureliocarella 21:51e162c130a9 84 _ecg.setWriteAuthorizationCallback(this, &Self::authorize_client_write);
aureliocarella 21:51e162c130a9 85 _rr_bpm.setWriteAuthorizationCallback(this, &Self::authorize_client_write);
aureliocarella 21:51e162c130a9 86 _max30001_chr.setWriteAuthorizationCallback(this, &Self::authorize_client_write);
mbed_official 0:c671a4833315 87 }
aureliocarella 21:51e162c130a9 88
mbed_official 0:c671a4833315 89
mbed_official 0:c671a4833315 90
mbed_official 0:c671a4833315 91
mbed_official 0:c671a4833315 92 void start(BLE &ble_interface, events::EventQueue &event_queue)
mbed_official 0:c671a4833315 93 {
mbed_official 0:c671a4833315 94 if (_event_queue) {
mbed_official 0:c671a4833315 95 return;
mbed_official 0:c671a4833315 96 }
mbed_official 0:c671a4833315 97
mbed_official 0:c671a4833315 98 _server = &ble_interface.gattServer();
mbed_official 0:c671a4833315 99 _event_queue = &event_queue;
mbed_official 0:c671a4833315 100
mbed_official 0:c671a4833315 101 // register the service
mbed_official 0:c671a4833315 102 printf("Adding demo service\r\n");
aureliocarella 21:51e162c130a9 103 ble_error_t err = _server->addService(_ecg_service);
mbed_official 0:c671a4833315 104
mbed_official 0:c671a4833315 105 if (err) {
mbed_official 0:c671a4833315 106 printf("Error %u during demo service registration.\r\n", err);
mbed_official 0:c671a4833315 107 return;
mbed_official 0:c671a4833315 108 }
mbed_official 0:c671a4833315 109
mbed_official 0:c671a4833315 110 // read write handler
mbed_official 0:c671a4833315 111 _server->onDataSent(as_cb(&Self::when_data_sent));
mbed_official 0:c671a4833315 112 _server->onDataWritten(as_cb(&Self::when_data_written));
mbed_official 0:c671a4833315 113 _server->onDataRead(as_cb(&Self::when_data_read));
mbed_official 0:c671a4833315 114
mbed_official 0:c671a4833315 115 // updates subscribtion handlers
mbed_official 0:c671a4833315 116 _server->onUpdatesEnabled(as_cb(&Self::when_update_enabled));
mbed_official 0:c671a4833315 117 _server->onUpdatesDisabled(as_cb(&Self::when_update_disabled));
mbed_official 0:c671a4833315 118 _server->onConfirmationReceived(as_cb(&Self::when_confirmation_received));
mbed_official 0:c671a4833315 119
mbed_official 0:c671a4833315 120 // print the handles
mbed_official 0:c671a4833315 121 printf("clock service registered\r\n");
aureliocarella 21:51e162c130a9 122 printf("service handle: %u\r\n", _ecg_service.getHandle());
aureliocarella 21:51e162c130a9 123 printf("\thour characteristic value handle %u\r\n", _ecg.getValueHandle());
aureliocarella 21:51e162c130a9 124 printf("\tminute characteristic value handle %u\r\n", _rr_bpm.getValueHandle());
aureliocarella 21:51e162c130a9 125 printf("\tsecond characteristic value handle %u\r\n", _max30001_chr.getValueHandle());
mbed_official 0:c671a4833315 126
aureliocarella 21:51e162c130a9 127 _event_queue->call_every(2000 /* ms */, callback(this, &Self::increment_second));
mbed_official 0:c671a4833315 128 }
mbed_official 0:c671a4833315 129
mbed_official 0:c671a4833315 130 private:
mbed_official 0:c671a4833315 131
mbed_official 0:c671a4833315 132 /**
mbed_official 0:c671a4833315 133 * Handler called when a notification or an indication has been sent.
mbed_official 0:c671a4833315 134 */
mbed_official 0:c671a4833315 135 void when_data_sent(unsigned count)
mbed_official 0:c671a4833315 136 {
mbed_official 0:c671a4833315 137 printf("sent %u updates\r\n", count);
mbed_official 0:c671a4833315 138 }
mbed_official 0:c671a4833315 139
mbed_official 0:c671a4833315 140 /**
mbed_official 0:c671a4833315 141 * Handler called after an attribute has been written.
mbed_official 0:c671a4833315 142 */
mbed_official 0:c671a4833315 143 void when_data_written(const GattWriteCallbackParams *e)
mbed_official 0:c671a4833315 144 {
mbed_official 0:c671a4833315 145 printf("data written:\r\n");
mbed_official 0:c671a4833315 146 printf("\tconnection handle: %u\r\n", e->connHandle);
mbed_official 0:c671a4833315 147 printf("\tattribute handle: %u", e->handle);
aureliocarella 21:51e162c130a9 148 if (e->handle == _ecg.getValueHandle()) {
mbed_official 0:c671a4833315 149 printf(" (hour characteristic)\r\n");
aureliocarella 21:51e162c130a9 150 hour = e->data[0];
aureliocarella 21:51e162c130a9 151 } else if (e->handle == _rr_bpm.getValueHandle()) {
mbed_official 0:c671a4833315 152 printf(" (minute characteristic)\r\n");
aureliocarella 21:51e162c130a9 153 minute = e->data[0];
aureliocarella 21:51e162c130a9 154 } else if (e->handle == _max30001_chr.getValueHandle()) {
mbed_official 0:c671a4833315 155 printf(" (second characteristic)\r\n");
aureliocarella 21:51e162c130a9 156 second = e->data[0];
mbed_official 0:c671a4833315 157 } else {
mbed_official 0:c671a4833315 158 printf("\r\n");
mbed_official 0:c671a4833315 159 }
mbed_official 0:c671a4833315 160 printf("\twrite operation: %u\r\n", e->writeOp);
mbed_official 0:c671a4833315 161 printf("\toffset: %u\r\n", e->offset);
mbed_official 0:c671a4833315 162 printf("\tlength: %u\r\n", e->len);
mbed_official 0:c671a4833315 163 printf("\t data: ");
mbed_official 0:c671a4833315 164
mbed_official 0:c671a4833315 165 for (size_t i = 0; i < e->len; ++i) {
mbed_official 0:c671a4833315 166 printf("%02X", e->data[i]);
mbed_official 0:c671a4833315 167 }
mbed_official 0:c671a4833315 168
mbed_official 0:c671a4833315 169 printf("\r\n");
mbed_official 0:c671a4833315 170 }
mbed_official 0:c671a4833315 171
mbed_official 0:c671a4833315 172 /**
mbed_official 0:c671a4833315 173 * Handler called after an attribute has been read.
mbed_official 0:c671a4833315 174 */
mbed_official 0:c671a4833315 175 void when_data_read(const GattReadCallbackParams *e)
mbed_official 0:c671a4833315 176 {
mbed_official 0:c671a4833315 177 printf("data read:\r\n");
mbed_official 0:c671a4833315 178 printf("\tconnection handle: %u\r\n", e->connHandle);
mbed_official 0:c671a4833315 179 printf("\tattribute handle: %u", e->handle);
aureliocarella 21:51e162c130a9 180 if (e->handle == _ecg.getValueHandle()) {
mbed_official 0:c671a4833315 181 printf(" (hour characteristic)\r\n");
aureliocarella 21:51e162c130a9 182 } else if (e->handle == _rr_bpm.getValueHandle()) {
mbed_official 0:c671a4833315 183 printf(" (minute characteristic)\r\n");
aureliocarella 21:51e162c130a9 184 } else if (e->handle == _max30001_chr.getValueHandle()) {
mbed_official 0:c671a4833315 185 printf(" (second characteristic)\r\n");
mbed_official 0:c671a4833315 186 } else {
mbed_official 0:c671a4833315 187 printf("\r\n");
mbed_official 0:c671a4833315 188 }
mbed_official 0:c671a4833315 189 }
mbed_official 0:c671a4833315 190
mbed_official 0:c671a4833315 191 /**
mbed_official 0:c671a4833315 192 * Handler called after a client has subscribed to notification or indication.
mbed_official 0:c671a4833315 193 *
mbed_official 0:c671a4833315 194 * @param handle Handle of the characteristic value affected by the change.
mbed_official 0:c671a4833315 195 */
mbed_official 0:c671a4833315 196 void when_update_enabled(GattAttribute::Handle_t handle)
mbed_official 0:c671a4833315 197 {
mbed_official 0:c671a4833315 198 printf("update enabled on handle %d\r\n", handle);
mbed_official 0:c671a4833315 199 }
mbed_official 0:c671a4833315 200
mbed_official 0:c671a4833315 201 /**
mbed_official 0:c671a4833315 202 * Handler called after a client has cancelled his subscription from
mbed_official 0:c671a4833315 203 * notification or indication.
mbed_official 0:c671a4833315 204 *
mbed_official 0:c671a4833315 205 * @param handle Handle of the characteristic value affected by the change.
mbed_official 0:c671a4833315 206 */
mbed_official 0:c671a4833315 207 void when_update_disabled(GattAttribute::Handle_t handle)
mbed_official 0:c671a4833315 208 {
mbed_official 0:c671a4833315 209 printf("update disabled on handle %d\r\n", handle);
mbed_official 0:c671a4833315 210 }
mbed_official 0:c671a4833315 211
mbed_official 0:c671a4833315 212 /**
mbed_official 0:c671a4833315 213 * Handler called when an indication confirmation has been received.
mbed_official 0:c671a4833315 214 *
mbed_official 0:c671a4833315 215 * @param handle Handle of the characteristic value that has emitted the
mbed_official 0:c671a4833315 216 * indication.
mbed_official 0:c671a4833315 217 */
mbed_official 0:c671a4833315 218 void when_confirmation_received(GattAttribute::Handle_t handle)
mbed_official 0:c671a4833315 219 {
mbed_official 0:c671a4833315 220 printf("confirmation received on handle %d\r\n", handle);
mbed_official 0:c671a4833315 221 }
mbed_official 0:c671a4833315 222
mbed_official 0:c671a4833315 223 /**
mbed_official 0:c671a4833315 224 * Handler called when a write request is received.
mbed_official 0:c671a4833315 225 *
mbed_official 0:c671a4833315 226 * This handler verify that the value submitted by the client is valid before
mbed_official 0:c671a4833315 227 * authorizing the operation.
mbed_official 0:c671a4833315 228 */
mbed_official 0:c671a4833315 229 void authorize_client_write(GattWriteAuthCallbackParams *e)
mbed_official 0:c671a4833315 230 {
mbed_official 0:c671a4833315 231 printf("characteristic %u write authorization\r\n", e->handle);
mbed_official 0:c671a4833315 232
mbed_official 0:c671a4833315 233 if (e->offset != 0) {
mbed_official 0:c671a4833315 234 printf("Error invalid offset\r\n");
mbed_official 0:c671a4833315 235 e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
mbed_official 0:c671a4833315 236 return;
mbed_official 0:c671a4833315 237 }
mbed_official 0:c671a4833315 238
mbed_official 0:c671a4833315 239 if (e->len != 1) {
mbed_official 0:c671a4833315 240 printf("Error invalid len\r\n");
mbed_official 0:c671a4833315 241 e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
mbed_official 0:c671a4833315 242 return;
mbed_official 0:c671a4833315 243 }
mbed_official 0:c671a4833315 244
mbed_official 0:c671a4833315 245 if ((e->data[0] >= 60) ||
aureliocarella 21:51e162c130a9 246 ((e->data[0] >= 24) && (e->handle == _ecg.getValueHandle()))) {
mbed_official 0:c671a4833315 247 printf("Error invalid data\r\n");
mbed_official 0:c671a4833315 248 e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED;
mbed_official 0:c671a4833315 249 return;
mbed_official 0:c671a4833315 250 }
mbed_official 0:c671a4833315 251
mbed_official 0:c671a4833315 252 e->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
mbed_official 0:c671a4833315 253 }
mbed_official 0:c671a4833315 254
mbed_official 0:c671a4833315 255 /**
mbed_official 0:c671a4833315 256 * Increment the second counter.
mbed_official 0:c671a4833315 257 */
mbed_official 0:c671a4833315 258 void increment_second(void)
mbed_official 0:c671a4833315 259 {
aureliocarella 21:51e162c130a9 260
aureliocarella 21:51e162c130a9 261 ble_error_t err = _max30001_chr.get(*_server, second);
mbed_official 0:c671a4833315 262 if (err) {
mbed_official 0:c671a4833315 263 printf("read of the second value returned error %u\r\n", err);
mbed_official 0:c671a4833315 264 return;
mbed_official 0:c671a4833315 265 }
mbed_official 0:c671a4833315 266
mbed_official 0:c671a4833315 267 second = (second + 1) % 60;
aureliocarella 21:51e162c130a9 268 uint32_t* mamt;
aureliocarella 21:51e162c130a9 269 //MAX30001::MAX30001_REG_map_t reg = (MAX30001_REG_map_t)0x01;
aureliocarella 21:51e162c130a9 270 uint8_t addr = 0x01; //STATUS
aureliocarella 21:51e162c130a9 271 printf("reg=%d ", addr);
aureliocarella 21:51e162c130a9 272 int res = Peripherals::max30001()->max30001_reg_read(addr, mamt);
aureliocarella 21:51e162c130a9 273 printf("MAMT=%d, %x\r\n", res, *mamt);
aureliocarella 21:51e162c130a9 274
aureliocarella 21:51e162c130a9 275 /* printf("RPC");
aureliocarella 21:51e162c130a9 276 char reply1[128];
aureliocarella 21:51e162c130a9 277 // process the RPC string
aureliocarella 21:51e162c130a9 278 RPC_call("/System/ReadVer", reply1);
aureliocarella 21:51e162c130a9 279 //Send reply to debug port
aureliocarella 21:51e162c130a9 280 printf(reply1);*/
aureliocarella 21:51e162c130a9 281 printf("%d-%d-%d\r\n",hour, minute, second);
aureliocarella 21:51e162c130a9 282 err = _max30001_chr.set(*_server, second);
mbed_official 0:c671a4833315 283 if (err) {
mbed_official 0:c671a4833315 284 printf("write of the second value returned error %u\r\n", err);
mbed_official 0:c671a4833315 285 return;
mbed_official 0:c671a4833315 286 }
mbed_official 0:c671a4833315 287
mbed_official 0:c671a4833315 288 if (second == 0) {
mbed_official 0:c671a4833315 289 increment_minute();
mbed_official 0:c671a4833315 290 }
mbed_official 0:c671a4833315 291 }
mbed_official 0:c671a4833315 292
mbed_official 0:c671a4833315 293 /**
mbed_official 0:c671a4833315 294 * Increment the minute counter.
mbed_official 0:c671a4833315 295 */
mbed_official 0:c671a4833315 296 void increment_minute(void)
mbed_official 0:c671a4833315 297 {
aureliocarella 21:51e162c130a9 298
aureliocarella 21:51e162c130a9 299 ble_error_t err = _rr_bpm.get(*_server, minute);
mbed_official 0:c671a4833315 300 if (err) {
mbed_official 0:c671a4833315 301 printf("read of the minute value returned error %u\r\n", err);
mbed_official 0:c671a4833315 302 return;
mbed_official 0:c671a4833315 303 }
mbed_official 0:c671a4833315 304
mbed_official 0:c671a4833315 305 minute = (minute + 1) % 60;
mbed_official 0:c671a4833315 306
aureliocarella 21:51e162c130a9 307 err = _rr_bpm.set(*_server, minute);
mbed_official 0:c671a4833315 308 if (err) {
mbed_official 0:c671a4833315 309 printf("write of the minute value returned error %u\r\n", err);
mbed_official 0:c671a4833315 310 return;
mbed_official 0:c671a4833315 311 }
mbed_official 0:c671a4833315 312
mbed_official 0:c671a4833315 313 if (minute == 0) {
mbed_official 0:c671a4833315 314 increment_hour();
mbed_official 0:c671a4833315 315 }
mbed_official 0:c671a4833315 316 }
mbed_official 0:c671a4833315 317
mbed_official 0:c671a4833315 318 /**
mbed_official 0:c671a4833315 319 * Increment the hour counter.
mbed_official 0:c671a4833315 320 */
mbed_official 0:c671a4833315 321 void increment_hour(void)
mbed_official 0:c671a4833315 322 {
aureliocarella 21:51e162c130a9 323
aureliocarella 21:51e162c130a9 324 ble_error_t err = _ecg.get(*_server, hour);
mbed_official 0:c671a4833315 325 if (err) {
mbed_official 0:c671a4833315 326 printf("read of the hour value returned error %u\r\n", err);
mbed_official 0:c671a4833315 327 return;
mbed_official 0:c671a4833315 328 }
mbed_official 0:c671a4833315 329
mbed_official 0:c671a4833315 330 hour = (hour + 1) % 24;
mbed_official 0:c671a4833315 331
aureliocarella 21:51e162c130a9 332 err = _ecg.set(*_server, hour);
mbed_official 0:c671a4833315 333 if (err) {
mbed_official 0:c671a4833315 334 printf("write of the hour value returned error %u\r\n", err);
mbed_official 0:c671a4833315 335 return;
mbed_official 0:c671a4833315 336 }
mbed_official 0:c671a4833315 337 }
mbed_official 0:c671a4833315 338
mbed_official 0:c671a4833315 339 private:
mbed_official 0:c671a4833315 340 /**
mbed_official 0:c671a4833315 341 * Helper that construct an event handler from a member function of this
mbed_official 0:c671a4833315 342 * instance.
mbed_official 0:c671a4833315 343 */
mbed_official 0:c671a4833315 344 template<typename Arg>
mbed_official 0:c671a4833315 345 FunctionPointerWithContext<Arg> as_cb(void (Self::*member)(Arg))
mbed_official 0:c671a4833315 346 {
mbed_official 0:c671a4833315 347 return makeFunctionPointer(this, member);
mbed_official 0:c671a4833315 348 }
mbed_official 0:c671a4833315 349
mbed_official 0:c671a4833315 350 /**
mbed_official 0:c671a4833315 351 * Read, Write, Notify, Indicate Characteristic declaration helper.
mbed_official 0:c671a4833315 352 *
mbed_official 0:c671a4833315 353 * @tparam T type of data held by the characteristic.
mbed_official 0:c671a4833315 354 */
mbed_official 0:c671a4833315 355 template<typename T>
mbed_official 0:c671a4833315 356 class ReadWriteNotifyIndicateCharacteristic : public GattCharacteristic {
mbed_official 0:c671a4833315 357 public:
mbed_official 0:c671a4833315 358 /**
mbed_official 0:c671a4833315 359 * Construct a characteristic that can be read or written and emit
mbed_official 0:c671a4833315 360 * notification or indication.
mbed_official 0:c671a4833315 361 *
mbed_official 0:c671a4833315 362 * @param[in] uuid The UUID of the characteristic.
mbed_official 0:c671a4833315 363 * @param[in] initial_value Initial value contained by the characteristic.
mbed_official 0:c671a4833315 364 */
mbed_official 0:c671a4833315 365 ReadWriteNotifyIndicateCharacteristic(const UUID & uuid, const T& initial_value) :
mbed_official 0:c671a4833315 366 GattCharacteristic(
mbed_official 0:c671a4833315 367 /* UUID */ uuid,
mbed_official 0:c671a4833315 368 /* Initial value */ &_value,
mbed_official 0:c671a4833315 369 /* Value size */ sizeof(_value),
mbed_official 0:c671a4833315 370 /* Value capacity */ sizeof(_value),
mbed_official 0:c671a4833315 371 /* Properties */ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ |
mbed_official 0:c671a4833315 372 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE |
mbed_official 0:c671a4833315 373 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY |
mbed_official 0:c671a4833315 374 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE,
mbed_official 0:c671a4833315 375 /* Descriptors */ NULL,
mbed_official 0:c671a4833315 376 /* Num descriptors */ 0,
mbed_official 0:c671a4833315 377 /* variable len */ false
mbed_official 0:c671a4833315 378 ),
mbed_official 0:c671a4833315 379 _value(initial_value) {
mbed_official 0:c671a4833315 380 }
mbed_official 0:c671a4833315 381
mbed_official 0:c671a4833315 382 /**
mbed_official 0:c671a4833315 383 * Get the value of this characteristic.
mbed_official 0:c671a4833315 384 *
mbed_official 0:c671a4833315 385 * @param[in] server GattServer instance that contain the characteristic
mbed_official 0:c671a4833315 386 * value.
mbed_official 0:c671a4833315 387 * @param[in] dst Variable that will receive the characteristic value.
mbed_official 0:c671a4833315 388 *
mbed_official 0:c671a4833315 389 * @return BLE_ERROR_NONE in case of success or an appropriate error code.
mbed_official 0:c671a4833315 390 */
mbed_official 0:c671a4833315 391 ble_error_t get(GattServer &server, T& dst) const
mbed_official 0:c671a4833315 392 {
mbed_official 0:c671a4833315 393 uint16_t value_length = sizeof(dst);
mbed_official 0:c671a4833315 394 return server.read(getValueHandle(), &dst, &value_length);
mbed_official 0:c671a4833315 395 }
mbed_official 0:c671a4833315 396
mbed_official 0:c671a4833315 397 /**
mbed_official 0:c671a4833315 398 * Assign a new value to this characteristic.
mbed_official 0:c671a4833315 399 *
mbed_official 0:c671a4833315 400 * @param[in] server GattServer instance that will receive the new value.
mbed_official 0:c671a4833315 401 * @param[in] value The new value to set.
mbed_official 0:c671a4833315 402 * @param[in] local_only Flag that determine if the change should be kept
mbed_official 0:c671a4833315 403 * locally or forwarded to subscribed clients.
mbed_official 0:c671a4833315 404 */
mbed_official 0:c671a4833315 405 ble_error_t set(
mbed_official 0:c671a4833315 406 GattServer &server, const uint8_t &value, bool local_only = false
mbed_official 0:c671a4833315 407 ) const {
mbed_official 0:c671a4833315 408 return server.write(getValueHandle(), &value, sizeof(value), local_only);
mbed_official 0:c671a4833315 409 }
mbed_official 0:c671a4833315 410
mbed_official 0:c671a4833315 411 private:
mbed_official 0:c671a4833315 412 uint8_t _value;
mbed_official 0:c671a4833315 413 };
mbed_official 0:c671a4833315 414
aureliocarella 21:51e162c130a9 415 ReadWriteNotifyIndicateCharacteristic<uint8_t> _ecg;
aureliocarella 21:51e162c130a9 416 ReadWriteNotifyIndicateCharacteristic<uint8_t> _rr_bpm;
aureliocarella 21:51e162c130a9 417 ReadWriteNotifyIndicateCharacteristic<uint8_t> _max30001_chr;
mbed_official 0:c671a4833315 418
mbed_official 0:c671a4833315 419 // list of the characteristics of the clock service
aureliocarella 21:51e162c130a9 420 GattCharacteristic* _ecg_characteristics[3];
mbed_official 0:c671a4833315 421
mbed_official 0:c671a4833315 422 // demo service
aureliocarella 21:51e162c130a9 423 GattService _ecg_service;
mbed_official 0:c671a4833315 424
mbed_official 0:c671a4833315 425 GattServer* _server;
mbed_official 0:c671a4833315 426 events::EventQueue *_event_queue;
mbed_official 0:c671a4833315 427 };
mbed_official 0:c671a4833315 428
aureliocarella 21:51e162c130a9 429
aureliocarella 21:51e162c130a9 430 //Init PMIC on FTHR board and set logic thresholds to 3.3V
aureliocarella 21:51e162c130a9 431 MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
aureliocarella 21:51e162c130a9 432
aureliocarella 21:51e162c130a9 433 SDFileSystem sd(P0_5, P0_6, P0_4, P0_7, "sd"); // mosi, miso, sclk, cs
aureliocarella 21:51e162c130a9 434
aureliocarella 21:51e162c130a9 435 //SD card insertion detection pin
aureliocarella 21:51e162c130a9 436 DigitalIn SDDetect(P2_2, PullUp);
aureliocarella 21:51e162c130a9 437
aureliocarella 21:51e162c130a9 438
aureliocarella 21:51e162c130a9 439 /// DigitalOut for CS
aureliocarella 21:51e162c130a9 440 DigitalOut cs(P5_6);
aureliocarella 21:51e162c130a9 441 /// SPI Master 2 with SPI0_SS for use with MAX30001
aureliocarella 21:51e162c130a9 442 SPI spi(SPI2_MOSI, SPI2_MISO, SPI2_SCK); // used by MAX30001
aureliocarella 21:51e162c130a9 443 /// SPI Master 1
aureliocarella 21:51e162c130a9 444 QuadSpiInterface quadSpiInterface(SPI1_MOSI, SPI1_MISO, SPI1_SCK,
aureliocarella 21:51e162c130a9 445 SPI1_SS); // used by S25FS512
aureliocarella 21:51e162c130a9 446 /// External Flash
aureliocarella 21:51e162c130a9 447 S25FS512 s25fs512(&quadSpiInterface);
aureliocarella 21:51e162c130a9 448 /// ECG device
aureliocarella 21:51e162c130a9 449 MAX30001 max30001(&spi, &cs);
aureliocarella 21:51e162c130a9 450 InterruptIn max30001_InterruptB(P5_5);
aureliocarella 21:51e162c130a9 451 InterruptIn max30001_Interrupt2B(P5_4);
aureliocarella 21:51e162c130a9 452
aureliocarella 21:51e162c130a9 453
aureliocarella 21:51e162c130a9 454 /// HSP platform LED
aureliocarella 21:51e162c130a9 455 HspLed hspLed(LED_RED);
aureliocarella 21:51e162c130a9 456 /// Packet TimeStamp Timer, set for 1uS
aureliocarella 21:51e162c130a9 457 Timer timestampTimer;
aureliocarella 21:51e162c130a9 458 /// HSP Platform push button
aureliocarella 21:51e162c130a9 459 PushButton pushButton(SW1);
aureliocarella 21:51e162c130a9 460
aureliocarella 21:51e162c130a9 461 // local input state of the RPC
aureliocarella 21:51e162c130a9 462 int inputState;
aureliocarella 21:51e162c130a9 463 // RPC request buffer
aureliocarella 21:51e162c130a9 464 char request[128];
aureliocarella 21:51e162c130a9 465 // RPC reply buffer
aureliocarella 21:51e162c130a9 466 char reply[128];
mbed_official 0:c671a4833315 467 int main() {
aureliocarella 21:51e162c130a9 468
aureliocarella 21:51e162c130a9 469
aureliocarella 21:51e162c130a9 470 // display start banner
aureliocarella 21:51e162c130a9 471 printf("Maxim Integrated mbed hSensor %d.%d.%d %02d/%02d/%02d\n",
aureliocarella 21:51e162c130a9 472 VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH,
aureliocarella 21:51e162c130a9 473 VERSION_MONTH, VERSION_DAY, VERSION_SHORT_YEAR);
aureliocarella 21:51e162c130a9 474
aureliocarella 21:51e162c130a9 475 // turn on red led
aureliocarella 21:51e162c130a9 476 printf("Init HSPLED...\n");
aureliocarella 21:51e162c130a9 477 fflush(stdout);
aureliocarella 21:51e162c130a9 478 hspLed.on();
aureliocarella 21:51e162c130a9 479
aureliocarella 21:51e162c130a9 480 // set NVIC priorities for GPIO to prevent priority inversion
aureliocarella 21:51e162c130a9 481 printf("Init NVIC Priorities...\n");
aureliocarella 21:51e162c130a9 482 fflush(stdout);
aureliocarella 21:51e162c130a9 483 NVIC_SetPriority(GPIO_P0_IRQn, 5);
aureliocarella 21:51e162c130a9 484 NVIC_SetPriority(GPIO_P1_IRQn, 5);
aureliocarella 21:51e162c130a9 485 NVIC_SetPriority(GPIO_P2_IRQn, 5);
aureliocarella 21:51e162c130a9 486 NVIC_SetPriority(GPIO_P3_IRQn, 5);
aureliocarella 21:51e162c130a9 487 NVIC_SetPriority(GPIO_P4_IRQn, 5);
aureliocarella 21:51e162c130a9 488 NVIC_SetPriority(GPIO_P5_IRQn, 5);
aureliocarella 21:51e162c130a9 489 NVIC_SetPriority(GPIO_P6_IRQn, 5);
aureliocarella 21:51e162c130a9 490 // used by the MAX30001
aureliocarella 21:51e162c130a9 491 NVIC_SetPriority(SPIM2_IRQn, 0);
aureliocarella 21:51e162c130a9 492
aureliocarella 21:51e162c130a9 493 // Be able to statically reference these devices anywhere in the application
aureliocarella 21:51e162c130a9 494 Peripherals::setS25FS512(&s25fs512);
aureliocarella 21:51e162c130a9 495 Peripherals::setTimestampTimer(&timestampTimer);
aureliocarella 21:51e162c130a9 496 Peripherals::setHspLed(&hspLed);
aureliocarella 21:51e162c130a9 497 Peripherals::setPushButton(&pushButton);
aureliocarella 21:51e162c130a9 498 Peripherals::setMAX30001(&max30001);
aureliocarella 21:51e162c130a9 499 Peripherals::setSdFS(&sd);
aureliocarella 21:51e162c130a9 500 Peripherals::setSDDetect(&SDDetect);
aureliocarella 21:51e162c130a9 501
aureliocarella 21:51e162c130a9 502 // init the S25FS256 external flash device
aureliocarella 21:51e162c130a9 503 printf("Init S25FS512...\n");
aureliocarella 21:51e162c130a9 504 fflush(stdout);
aureliocarella 21:51e162c130a9 505 s25fs512.init();
aureliocarella 21:51e162c130a9 506
aureliocarella 21:51e162c130a9 507 // start blinking led1
aureliocarella 21:51e162c130a9 508 printf("Init HSPLED Blink...\n");
aureliocarella 21:51e162c130a9 509 fflush(stdout);
aureliocarella 21:51e162c130a9 510
aureliocarella 21:51e162c130a9 511 //
aureliocarella 21:51e162c130a9 512 // MAX30001
aureliocarella 21:51e162c130a9 513 //
aureliocarella 21:51e162c130a9 514 printf("Init MAX30001 callbacks, interrupts...\n");
aureliocarella 21:51e162c130a9 515 fflush(stdout);
aureliocarella 21:51e162c130a9 516 max30001_InterruptB.disable_irq();
aureliocarella 21:51e162c130a9 517 max30001_Interrupt2B.disable_irq();
aureliocarella 21:51e162c130a9 518 max30001_InterruptB.mode(PullUp);
aureliocarella 21:51e162c130a9 519 max30001_InterruptB.fall(&MAX30001Mid_IntB_Handler);
aureliocarella 21:51e162c130a9 520 max30001_Interrupt2B.mode(PullUp);
aureliocarella 21:51e162c130a9 521 max30001_Interrupt2B.fall(&MAX30001Mid_Int2B_Handler);
aureliocarella 21:51e162c130a9 522 max30001_InterruptB.enable_irq();
aureliocarella 21:51e162c130a9 523 max30001_Interrupt2B.enable_irq();
aureliocarella 21:51e162c130a9 524 MAX30001_AllowInterrupts(1);
aureliocarella 21:51e162c130a9 525 max30001.max30001_sw_rst(); // Do a software reset of the MAX30001
aureliocarella 21:51e162c130a9 526 max30001.max30001_INT_assignment(MAX30001::MAX30001_INT_B, MAX30001::MAX30001_NO_INT, MAX30001::MAX30001_NO_INT, // en_enint_loc, en_eovf_loc, en_fstint_loc,
aureliocarella 21:51e162c130a9 527 MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_NO_INT, // en_dcloffint_loc, en_bint_loc, en_bovf_loc,
aureliocarella 21:51e162c130a9 528 MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_NO_INT, // en_bover_loc, en_bundr_loc, en_bcgmon_loc,
aureliocarella 21:51e162c130a9 529 MAX30001::MAX30001_INT_B, MAX30001::MAX30001_NO_INT, MAX30001::MAX30001_NO_INT, // en_pint_loc, en_povf_loc, en_pedge_loc,
aureliocarella 21:51e162c130a9 530 MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_INT_B, MAX30001::MAX30001_NO_INT, // en_lonint_loc, en_rrint_loc, en_samp_loc,
aureliocarella 21:51e162c130a9 531 MAX30001::MAX30001_INT_ODNR, MAX30001::MAX30001_INT_ODNR); // intb_Type, int2b_Type)
aureliocarella 21:51e162c130a9 532 max30001.onDataAvailable(&StreamPacketUint32);
aureliocarella 21:51e162c130a9 533
aureliocarella 21:51e162c130a9 534 // initialize the RPC server
aureliocarella 21:51e162c130a9 535 printf("Init RPC Server...\n");
aureliocarella 21:51e162c130a9 536 fflush(stdout);
aureliocarella 21:51e162c130a9 537 RPC_init();
aureliocarella 21:51e162c130a9 538 // initialize the logging service
aureliocarella 21:51e162c130a9 539 printf("Init LoggingService...\n");
aureliocarella 21:51e162c130a9 540 fflush(stdout);
aureliocarella 21:51e162c130a9 541 LoggingService_Init();
aureliocarella 21:51e162c130a9 542 // initialize the SD disk
aureliocarella 21:51e162c130a9 543 sd.disk_initialize();
aureliocarella 21:51e162c130a9 544
aureliocarella 21:51e162c130a9 545 // start main loop
aureliocarella 21:51e162c130a9 546 printf("Start main loop...\n");
aureliocarella 21:51e162c130a9 547 fflush(stdout);
aureliocarella 21:51e162c130a9 548
aureliocarella 21:51e162c130a9 549
mbed_official 0:c671a4833315 550 BLE &ble_interface = BLE::Instance();
aureliocarella 21:51e162c130a9 551
mbed_official 0:c671a4833315 552 events::EventQueue event_queue;
mbed_official 0:c671a4833315 553 ClockService demo_service;
mbed_official 0:c671a4833315 554 BLEProcess ble_process(event_queue, ble_interface);
mbed_official 0:c671a4833315 555
mbed_official 0:c671a4833315 556 ble_process.on_init(callback(&demo_service, &ClockService::start));
mbed_official 0:c671a4833315 557
mbed_official 0:c671a4833315 558 // bind the event queue to the ble interface, initialize the interface
mbed_official 0:c671a4833315 559 // and start advertising
mbed_official 0:c671a4833315 560 ble_process.start();
mbed_official 0:c671a4833315 561
mbed_official 0:c671a4833315 562 // Process the event queue.
aureliocarella 21:51e162c130a9 563
mbed_official 0:c671a4833315 564 event_queue.dispatch_forever();
mbed_official 0:c671a4833315 565
mbed_official 0:c671a4833315 566 return 0;
mbed_official 0:c671a4833315 567 }