Merck / Mbed OS SmartCap_OS5

Dependencies:   nRF51822

Committer:
sgetz7908
Date:
Thu Mar 21 19:28:22 2019 +0000
Revision:
24:761c30334cf4
Parent:
23:7ca590427f0e
Child:
27:bb7247a1704e
Test mode added; needs testing and DATA flag; Needs EOL stuff

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sgetz7908 23:7ca590427f0e 1
sgetz7908 23:7ca590427f0e 2 /// @file BLE_Stuff.cpp
sgetz7908 23:7ca590427f0e 3 #include <events/mbed_events.h>
sgetz7908 23:7ca590427f0e 4 #include <mbed.h>
sgetz7908 23:7ca590427f0e 5 #include "ble/BLE.h"
sgetz7908 23:7ca590427f0e 6 #include "ble/Gap.h"
sgetz7908 23:7ca590427f0e 7 #include "ble/services/UARTService.h"
sgetz7908 23:7ca590427f0e 8
sgetz7908 23:7ca590427f0e 9 #include "BLE_Stuff.h"
sgetz7908 23:7ca590427f0e 10 #include "infoService.h"
sgetz7908 23:7ca590427f0e 11 #include "hw.h"
sgetz7908 23:7ca590427f0e 12 #include "log.h"
sgetz7908 23:7ca590427f0e 13 #include "main.h"
sgetz7908 23:7ca590427f0e 14 #include "log.h"
sgetz7908 23:7ca590427f0e 15 #include "nrf_soc.h"
sgetz7908 23:7ca590427f0e 16
sgetz7908 23:7ca590427f0e 17 extern EventQueue eventQueue; //(/* event count */ 16 * EVENTS_EVENT_SIZE);
sgetz7908 23:7ca590427f0e 18 UARTService *uartServicePtr = NULL;
sgetz7908 23:7ca590427f0e 19
sgetz7908 23:7ca590427f0e 20 LowPowerTimeout bleInactivity_timeout;
sgetz7908 23:7ca590427f0e 21
sgetz7908 23:7ca590427f0e 22
sgetz7908 23:7ca590427f0e 23 int adv_timeout_ID = 0;
sgetz7908 23:7ca590427f0e 24
sgetz7908 23:7ca590427f0e 25 int adv_state = false;
sgetz7908 23:7ca590427f0e 26 char dev_name[15] = "";
sgetz7908 23:7ca590427f0e 27
sgetz7908 23:7ca590427f0e 28 volatile int batt_voltage = 0; // actual battery voltage * 100
sgetz7908 23:7ca590427f0e 29
sgetz7908 23:7ca590427f0e 30 bool m_isConnected = false;
sgetz7908 23:7ca590427f0e 31
sgetz7908 23:7ca590427f0e 32 void process_cmd(char * cmd);
sgetz7908 23:7ca590427f0e 33
sgetz7908 23:7ca590427f0e 34
sgetz7908 23:7ca590427f0e 35 /// Called by bleInactivity_timeout
sgetz7908 23:7ca590427f0e 36 void disconnect(void)
sgetz7908 23:7ca590427f0e 37 {
sgetz7908 23:7ca590427f0e 38 bleInactivity_timeout.detach();
sgetz7908 23:7ca590427f0e 39 #if UART_DEBUGGING==0
sgetz7908 23:7ca590427f0e 40 BLE &ble = BLE::Instance();
sgetz7908 23:7ca590427f0e 41 ble.gap().disconnect(Gap::REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF); // force disconnect
sgetz7908 23:7ca590427f0e 42 #endif
sgetz7908 23:7ca590427f0e 43 }
sgetz7908 23:7ca590427f0e 44
sgetz7908 23:7ca590427f0e 45 void reset_ble_activity_timer(void)
sgetz7908 23:7ca590427f0e 46 {
sgetz7908 23:7ca590427f0e 47 bleInactivity_timeout.detach();
sgetz7908 23:7ca590427f0e 48 bleInactivity_timeout.attach(&disconnect, BLE_INACTIVITY_TIMEOUT);
sgetz7908 23:7ca590427f0e 49 }
sgetz7908 23:7ca590427f0e 50
sgetz7908 23:7ca590427f0e 51 /// Called when the Bluetooth connection is disconnected.
sgetz7908 23:7ca590427f0e 52 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
sgetz7908 23:7ca590427f0e 53 {
sgetz7908 23:7ca590427f0e 54 m_isConnected = false;
sgetz7908 23:7ca590427f0e 55 bleInactivity_timeout.detach();
sgetz7908 23:7ca590427f0e 56 BLE &ble = BLE::Instance();
sgetz7908 23:7ca590427f0e 57 ble.gap().setAdvertisingInterval(ADV_INTERVAL);
sgetz7908 23:7ca590427f0e 58 if(adv_state) ble.gap().startAdvertising();
sgetz7908 23:7ca590427f0e 59 }
sgetz7908 23:7ca590427f0e 60
sgetz7908 23:7ca590427f0e 61 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
sgetz7908 23:7ca590427f0e 62 {
sgetz7908 23:7ca590427f0e 63 m_isConnected = true;
sgetz7908 23:7ca590427f0e 64 BLE &ble = BLE::Instance();
sgetz7908 23:7ca590427f0e 65 ble.gap().setAdvertisingInterval(CONN_INTERVAL);
sgetz7908 23:7ca590427f0e 66 reset_ble_activity_timer();
sgetz7908 23:7ca590427f0e 67 }
sgetz7908 23:7ca590427f0e 68
sgetz7908 23:7ca590427f0e 69 bool isConnected(void)
sgetz7908 23:7ca590427f0e 70 {
sgetz7908 23:7ca590427f0e 71 return m_isConnected;
sgetz7908 23:7ca590427f0e 72 }
sgetz7908 23:7ca590427f0e 73
sgetz7908 23:7ca590427f0e 74 /// Called to write a string to the Bluetooth UART.
sgetz7908 23:7ca590427f0e 75 // used for writting to the BLE UART
sgetz7908 23:7ca590427f0e 76 void BLE_UART_xmit(const char * str)
sgetz7908 23:7ca590427f0e 77 {
sgetz7908 23:7ca590427f0e 78 if (uartServicePtr != NULL) {
sgetz7908 23:7ca590427f0e 79 uartServicePtr->writeString(str);
sgetz7908 23:7ca590427f0e 80 }
sgetz7908 23:7ca590427f0e 81 }
sgetz7908 23:7ca590427f0e 82
sgetz7908 23:7ca590427f0e 83 void BLE_UART_xmit(int i)
sgetz7908 23:7ca590427f0e 84 {
sgetz7908 23:7ca590427f0e 85 BLE_UART_xmit(uli2a(i));
sgetz7908 23:7ca590427f0e 86 }
sgetz7908 23:7ca590427f0e 87
sgetz7908 23:7ca590427f0e 88 char cmd_str[21];
sgetz7908 23:7ca590427f0e 89
sgetz7908 23:7ca590427f0e 90 /// Called when data is rcv'd from connected BLE device
sgetz7908 23:7ca590427f0e 91 void onDataWritten(const GattWriteCallbackParams *params)
sgetz7908 23:7ca590427f0e 92 {
sgetz7908 23:7ca590427f0e 93 if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
sgetz7908 23:7ca590427f0e 94 uint16_t bytesRead = params->len;
sgetz7908 23:7ca590427f0e 95 strncpy(cmd_str, (const char *)params->data, bytesRead);
sgetz7908 24:761c30334cf4 96 cmd_str[bytesRead] = 0; // add end of string char
sgetz7908 23:7ca590427f0e 97
sgetz7908 23:7ca590427f0e 98 // Start process: process_cmd(cmd_str) as regular non-irq routine
sgetz7908 23:7ca590427f0e 99 eventQueue.call(process_cmd, cmd_str);
sgetz7908 23:7ca590427f0e 100 // the dispatch method executes events
sgetz7908 23:7ca590427f0e 101 //queue.dispatch();
sgetz7908 23:7ca590427f0e 102
sgetz7908 23:7ca590427f0e 103 //ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead); // send back whatever is sent to us
sgetz7908 23:7ca590427f0e 104 reset_ble_activity_timer();
sgetz7908 23:7ca590427f0e 105 }
sgetz7908 23:7ca590427f0e 106 }
sgetz7908 23:7ca590427f0e 107
sgetz7908 23:7ca590427f0e 108 /// Turn on or off advertising
sgetz7908 23:7ca590427f0e 109 // When turned on, it will only advertise for a limited time, or until turned off.
sgetz7908 23:7ca590427f0e 110 void set_radio(int state)
sgetz7908 23:7ca590427f0e 111 {
sgetz7908 23:7ca590427f0e 112 BLE &ble = BLE::Instance();
sgetz7908 23:7ca590427f0e 113 adv_state = state;
sgetz7908 23:7ca590427f0e 114
sgetz7908 23:7ca590427f0e 115 if(state) {
sgetz7908 24:761c30334cf4 116 //adv_state = true;
sgetz7908 23:7ca590427f0e 117 ble.gap().setAdvertisingInterval(ADV_INTERVAL);
sgetz7908 23:7ca590427f0e 118 ble.gap().startAdvertising();
sgetz7908 23:7ca590427f0e 119 } else {
sgetz7908 24:761c30334cf4 120 //adv_state = false;
sgetz7908 23:7ca590427f0e 121 ble.gap().stopAdvertising();
sgetz7908 23:7ca590427f0e 122 disconnect();
sgetz7908 23:7ca590427f0e 123 }
sgetz7908 23:7ca590427f0e 124 }
sgetz7908 23:7ca590427f0e 125
sgetz7908 23:7ca590427f0e 126 #if 0
sgetz7908 23:7ca590427f0e 127 void stop_radio_and_wait(void)
sgetz7908 23:7ca590427f0e 128 {
sgetz7908 23:7ca590427f0e 129 set_radio(false);
sgetz7908 23:7ca590427f0e 130
sgetz7908 23:7ca590427f0e 131 // If radio is active, wait for it to become inactive.
sgetz7908 23:7ca590427f0e 132 //wait(0.5);
sgetz7908 23:7ca590427f0e 133 while (isConnected())// || isRadioActive())
sgetz7908 23:7ca590427f0e 134 {
sgetz7908 23:7ca590427f0e 135 // Do nothing (just wait for radio to become inactive).
sgetz7908 23:7ca590427f0e 136 sd_app_evt_wait();
sgetz7908 23:7ca590427f0e 137 }
sgetz7908 23:7ca590427f0e 138 }
sgetz7908 23:7ca590427f0e 139 #endif
sgetz7908 23:7ca590427f0e 140
sgetz7908 23:7ca590427f0e 141 ble_init_status_t ble_init_status = BLE_INIT_IN_PROGRESS;
sgetz7908 23:7ca590427f0e 142
sgetz7908 23:7ca590427f0e 143 /// Called to setup the Bluetooth link.
sgetz7908 23:7ca590427f0e 144 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
sgetz7908 23:7ca590427f0e 145 {
sgetz7908 23:7ca590427f0e 146 BLE& ble = params->ble;
sgetz7908 23:7ca590427f0e 147 ble_error_t error = params->error;
sgetz7908 23:7ca590427f0e 148
sgetz7908 23:7ca590427f0e 149 if (error != BLE_ERROR_NONE) {
sgetz7908 23:7ca590427f0e 150 ble_init_status = BLE_INIT_ERROR;
sgetz7908 23:7ca590427f0e 151 return;
sgetz7908 23:7ca590427f0e 152 }
sgetz7908 23:7ca590427f0e 153
sgetz7908 23:7ca590427f0e 154 /* Ensure that it is the default instance of BLE */
sgetz7908 23:7ca590427f0e 155 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
sgetz7908 23:7ca590427f0e 156 return;
sgetz7908 23:7ca590427f0e 157 }
sgetz7908 23:7ca590427f0e 158
sgetz7908 23:7ca590427f0e 159 ble.gap().onDisconnection(disconnectionCallback);
sgetz7908 23:7ca590427f0e 160 ble.gap().onConnection(connectionCallback);
sgetz7908 23:7ca590427f0e 161 ble.gattServer().onDataWritten(onDataWritten);
sgetz7908 23:7ca590427f0e 162
sgetz7908 23:7ca590427f0e 163 //ble.gattServer().onDataRead( dataReadCallback ); //const DataReadCallback_t & callback)
sgetz7908 23:7ca590427f0e 164 //ble.onDataRead( dataReadCallback);
sgetz7908 23:7ca590427f0e 165
sgetz7908 23:7ca590427f0e 166 strcpy(dev_name, DEV_NAME);
sgetz7908 23:7ca590427f0e 167 strcat(dev_name, char2hex(NRF_FICR->DEVICEADDR[0] & 0xff));
sgetz7908 23:7ca590427f0e 168 int len = strlen(dev_name);
sgetz7908 23:7ca590427f0e 169
sgetz7908 23:7ca590427f0e 170 ble.gap().setDeviceName((std::uint8_t *)dev_name);
sgetz7908 23:7ca590427f0e 171
sgetz7908 23:7ca590427f0e 172 /* Setup primary service */
sgetz7908 23:7ca590427f0e 173 uartServicePtr = new UARTService(ble);
sgetz7908 23:7ca590427f0e 174
sgetz7908 23:7ca590427f0e 175 /* setup advertising */
sgetz7908 23:7ca590427f0e 176 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
sgetz7908 23:7ca590427f0e 177 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
sgetz7908 23:7ca590427f0e 178 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
sgetz7908 23:7ca590427f0e 179 (const uint8_t *)dev_name, len);
sgetz7908 23:7ca590427f0e 180 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
sgetz7908 23:7ca590427f0e 181 (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
sgetz7908 23:7ca590427f0e 182
sgetz7908 23:7ca590427f0e 183
sgetz7908 23:7ca590427f0e 184 ble.gap().setAdvertisingInterval(ADV_INTERVAL);
sgetz7908 23:7ca590427f0e 185 ble.gap().setAdvertisingTimeout(BLE_ADVERTISING_DURATION);
sgetz7908 23:7ca590427f0e 186 ble.gap().setTxPower(-20); // -30, -20, -16, -12, -8, -4, 0, and 4 dBm
sgetz7908 23:7ca590427f0e 187
sgetz7908 23:7ca590427f0e 188 ble_init_status = BLE_INIT_OK;
sgetz7908 23:7ca590427f0e 189
sgetz7908 23:7ca590427f0e 190 set_radio(true);
sgetz7908 23:7ca590427f0e 191 }
sgetz7908 23:7ca590427f0e 192
sgetz7908 23:7ca590427f0e 193 /// Process BLE Events
sgetz7908 23:7ca590427f0e 194 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
sgetz7908 23:7ca590427f0e 195 BLE &ble = BLE::Instance();
sgetz7908 23:7ca590427f0e 196 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
sgetz7908 23:7ca590427f0e 197 }
sgetz7908 23:7ca590427f0e 198
sgetz7908 23:7ca590427f0e 199 /// Initialize the BLE Stack
sgetz7908 23:7ca590427f0e 200 // Returns 0 if OK
sgetz7908 23:7ca590427f0e 201 ble_init_status_t Init_BLE_Stuff(void)
sgetz7908 23:7ca590427f0e 202 {
sgetz7908 23:7ca590427f0e 203 ble_init_status = BLE_INIT_IN_PROGRESS;
sgetz7908 23:7ca590427f0e 204 BLE &ble = BLE::Instance();
sgetz7908 23:7ca590427f0e 205 ble.onEventsToProcess(scheduleBleEventsProcessing);
sgetz7908 23:7ca590427f0e 206 ble.init(bleInitComplete);
sgetz7908 23:7ca590427f0e 207
sgetz7908 23:7ca590427f0e 208 // Wait for initialization to complete. This is necessary because the
sgetz7908 23:7ca590427f0e 209 // BLE object is used after this.
sgetz7908 23:7ca590427f0e 210 while(ble_init_status == BLE_INIT_IN_PROGRESS) { wait(0.05);}
sgetz7908 23:7ca590427f0e 211 // set up BLE Information services in infoService.cpp
sgetz7908 23:7ca590427f0e 212 //ble.gattServer().addService(infoServicePtr);
sgetz7908 23:7ca590427f0e 213 return ble_init_status;
sgetz7908 23:7ca590427f0e 214 }