Merck / Mbed OS SmartCap_OS5

Dependencies:   nRF51822

Committer:
sgetz7908
Date:
Tue Mar 19 19:25:39 2019 +0000
Revision:
23:7ca590427f0e
Child:
24:761c30334cf4
Saving in progress work of updating code to new Merck Flow Diagram.

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 #include <ctype.h>
sgetz7908 23:7ca590427f0e 9
sgetz7908 23:7ca590427f0e 10 #include "BLE_Stuff.h"
sgetz7908 23:7ca590427f0e 11 #include "infoService.h"
sgetz7908 23:7ca590427f0e 12 #include "hw.h"
sgetz7908 23:7ca590427f0e 13 #include "log.h"
sgetz7908 23:7ca590427f0e 14 #include "main.h"
sgetz7908 23:7ca590427f0e 15 #include "log.h"
sgetz7908 23:7ca590427f0e 16 #include "nrf_soc.h"
sgetz7908 23:7ca590427f0e 17
sgetz7908 23:7ca590427f0e 18 extern EventQueue eventQueue; //(/* event count */ 16 * EVENTS_EVENT_SIZE);
sgetz7908 23:7ca590427f0e 19 UARTService *uartServicePtr = NULL;
sgetz7908 23:7ca590427f0e 20
sgetz7908 23:7ca590427f0e 21 LowPowerTimeout bleInactivity_timeout;
sgetz7908 23:7ca590427f0e 22
sgetz7908 23:7ca590427f0e 23
sgetz7908 23:7ca590427f0e 24 int adv_timeout_ID = 0;
sgetz7908 23:7ca590427f0e 25
sgetz7908 23:7ca590427f0e 26 int adv_state = false;
sgetz7908 23:7ca590427f0e 27 char dev_name[15] = "";
sgetz7908 23:7ca590427f0e 28
sgetz7908 23:7ca590427f0e 29 volatile int batt_voltage = 0; // actual battery voltage * 100
sgetz7908 23:7ca590427f0e 30
sgetz7908 23:7ca590427f0e 31 bool m_isConnected = false;
sgetz7908 23:7ca590427f0e 32
sgetz7908 23:7ca590427f0e 33 void process_cmd(char * cmd);
sgetz7908 23:7ca590427f0e 34
sgetz7908 23:7ca590427f0e 35
sgetz7908 23:7ca590427f0e 36 /// Called by bleInactivity_timeout
sgetz7908 23:7ca590427f0e 37 void disconnect(void)
sgetz7908 23:7ca590427f0e 38 {
sgetz7908 23:7ca590427f0e 39 bleInactivity_timeout.detach();
sgetz7908 23:7ca590427f0e 40 #if UART_DEBUGGING==0
sgetz7908 23:7ca590427f0e 41 BLE &ble = BLE::Instance();
sgetz7908 23:7ca590427f0e 42 ble.gap().disconnect(Gap::REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF); // force disconnect
sgetz7908 23:7ca590427f0e 43 #endif
sgetz7908 23:7ca590427f0e 44 }
sgetz7908 23:7ca590427f0e 45
sgetz7908 23:7ca590427f0e 46 void reset_ble_activity_timer(void)
sgetz7908 23:7ca590427f0e 47 {
sgetz7908 23:7ca590427f0e 48 bleInactivity_timeout.detach();
sgetz7908 23:7ca590427f0e 49 bleInactivity_timeout.attach(&disconnect, BLE_INACTIVITY_TIMEOUT);
sgetz7908 23:7ca590427f0e 50 }
sgetz7908 23:7ca590427f0e 51
sgetz7908 23:7ca590427f0e 52 /// Called when the Bluetooth connection is disconnected.
sgetz7908 23:7ca590427f0e 53 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
sgetz7908 23:7ca590427f0e 54 {
sgetz7908 23:7ca590427f0e 55 m_isConnected = false;
sgetz7908 23:7ca590427f0e 56 bleInactivity_timeout.detach();
sgetz7908 23:7ca590427f0e 57 BLE &ble = BLE::Instance();
sgetz7908 23:7ca590427f0e 58 ble.gap().setAdvertisingInterval(ADV_INTERVAL);
sgetz7908 23:7ca590427f0e 59 if(adv_state) ble.gap().startAdvertising();
sgetz7908 23:7ca590427f0e 60 }
sgetz7908 23:7ca590427f0e 61
sgetz7908 23:7ca590427f0e 62 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
sgetz7908 23:7ca590427f0e 63 {
sgetz7908 23:7ca590427f0e 64 m_isConnected = true;
sgetz7908 23:7ca590427f0e 65 BLE &ble = BLE::Instance();
sgetz7908 23:7ca590427f0e 66 ble.gap().setAdvertisingInterval(CONN_INTERVAL);
sgetz7908 23:7ca590427f0e 67 reset_ble_activity_timer();
sgetz7908 23:7ca590427f0e 68 }
sgetz7908 23:7ca590427f0e 69
sgetz7908 23:7ca590427f0e 70 bool isConnected(void)
sgetz7908 23:7ca590427f0e 71 {
sgetz7908 23:7ca590427f0e 72 return m_isConnected;
sgetz7908 23:7ca590427f0e 73 }
sgetz7908 23:7ca590427f0e 74
sgetz7908 23:7ca590427f0e 75 /// Called to write a string to the Bluetooth UART.
sgetz7908 23:7ca590427f0e 76 // used for writting to the BLE UART
sgetz7908 23:7ca590427f0e 77 void BLE_UART_xmit(const char * str)
sgetz7908 23:7ca590427f0e 78 {
sgetz7908 23:7ca590427f0e 79 if (uartServicePtr != NULL) {
sgetz7908 23:7ca590427f0e 80 uartServicePtr->writeString(str);
sgetz7908 23:7ca590427f0e 81 }
sgetz7908 23:7ca590427f0e 82 }
sgetz7908 23:7ca590427f0e 83
sgetz7908 23:7ca590427f0e 84 void BLE_UART_xmit(int i)
sgetz7908 23:7ca590427f0e 85 {
sgetz7908 23:7ca590427f0e 86 BLE_UART_xmit(uli2a(i));
sgetz7908 23:7ca590427f0e 87 }
sgetz7908 23:7ca590427f0e 88
sgetz7908 23:7ca590427f0e 89 char cmd_str[21];
sgetz7908 23:7ca590427f0e 90
sgetz7908 23:7ca590427f0e 91 /// Called when data is rcv'd from connected BLE device
sgetz7908 23:7ca590427f0e 92 void onDataWritten(const GattWriteCallbackParams *params)
sgetz7908 23:7ca590427f0e 93 {
sgetz7908 23:7ca590427f0e 94 if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
sgetz7908 23:7ca590427f0e 95 uint16_t bytesRead = params->len;
sgetz7908 23:7ca590427f0e 96 strncpy(cmd_str, (const char *)params->data, bytesRead);
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 23:7ca590427f0e 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 23:7ca590427f0e 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 }