TYBLE16 on os5 sample programs

Dependencies:   BME280 TextLCD nRF51_Vdd

Fork of TYBLE16_mbedlized_os5_BASE by Kenji Arai

Please refer following notebook.
/users/kenjiArai/notebook/tyble16-module-as-mbed-os-5-board-mbedlization/

Committer:
kenjiArai
Date:
Sat Apr 14 04:56:34 2018 +0000
Revision:
1:9011c83e4178
added samples

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 1:9011c83e4178 1 #if 0
kenjiArai 1:9011c83e4178 2 //-------------------------------------------------------------------------------------------------
kenjiArai 1:9011c83e4178 3 // ORIGINAL PROGRAM
kenjiArai 1:9011c83e4178 4 // S130 potential unstability case [closed] by Fabien Comte
kenjiArai 1:9011c83e4178 5 // https://devzone.nordicsemi.com/question/49705/s130-potential-unstability-case/
kenjiArai 1:9011c83e4178 6 //
kenjiArai 1:9011c83e4178 7 #include "mbed.h"
kenjiArai 1:9011c83e4178 8 #include "BLE.h"
kenjiArai 1:9011c83e4178 9 #include "UARTService.h"
kenjiArai 1:9011c83e4178 10 #include "ble/DiscoveredCharacteristic.h"
kenjiArai 1:9011c83e4178 11 #include "ble/DiscoveredService.h"
kenjiArai 1:9011c83e4178 12 #include "ble/service/UARTService.h"
kenjiArai 1:9011c83e4178 13
kenjiArai 1:9011c83e4178 14 #define SOFT_DEVICE_FATHER_HANDLE 3
kenjiArai 1:9011c83e4178 15
kenjiArai 1:9011c83e4178 16 #define BOARDS_COUNT 3
kenjiArai 1:9011c83e4178 17
kenjiArai 1:9011c83e4178 18 const Gap::Address_t mac_board_0 = {0xb8, 0xac, 0x4e, 0x8d, 0x8b, 0xeb};
kenjiArai 1:9011c83e4178 19 const Gap::Address_t mac_board_1 = {0x9c, 0x43, 0x62, 0x30, 0xaf, 0xd2};
kenjiArai 1:9011c83e4178 20 const Gap::Address_t mac_board_2 = {0x5f, 0x1a, 0x9e, 0x6a, 0x63, 0xdd};
kenjiArai 1:9011c83e4178 21
kenjiArai 1:9011c83e4178 22
kenjiArai 1:9011c83e4178 23 // tiny ble board
kenjiArai 1:9011c83e4178 24 #define LED_GREEN p21
kenjiArai 1:9011c83e4178 25 #define LED_RED p22
kenjiArai 1:9011c83e4178 26 #define LED_BLUE p23
kenjiArai 1:9011c83e4178 27 #define BUTTON_PIN p17
kenjiArai 1:9011c83e4178 28 #define BATTERY_PIN p1
kenjiArai 1:9011c83e4178 29
kenjiArai 1:9011c83e4178 30 #define MPU6050_SDA p12
kenjiArai 1:9011c83e4178 31 #define MPU6050_SCL p13
kenjiArai 1:9011c83e4178 32
kenjiArai 1:9011c83e4178 33 #define UART_TX p9
kenjiArai 1:9011c83e4178 34 #define UART_RX p11
kenjiArai 1:9011c83e4178 35 #define UART_CTS p8
kenjiArai 1:9011c83e4178 36 #define UART_RTS p10
kenjiArai 1:9011c83e4178 37
kenjiArai 1:9011c83e4178 38 DigitalOut led(LED_RED);
kenjiArai 1:9011c83e4178 39 DigitalOut alivenessLED(LED_GREEN);
kenjiArai 1:9011c83e4178 40 InterruptIn button(BUTTON_PIN);
kenjiArai 1:9011c83e4178 41 AnalogIn battery(BATTERY_PIN);
kenjiArai 1:9011c83e4178 42 Serial pc(UART_TX, UART_RX);
kenjiArai 1:9011c83e4178 43
kenjiArai 1:9011c83e4178 44 bool mac_equals(const Gap::Address_t mac_1, const Gap::Address_t mac_2)
kenjiArai 1:9011c83e4178 45 {
kenjiArai 1:9011c83e4178 46 #if 0
kenjiArai 1:9011c83e4178 47 if (mac_1[0] != mac_2[0])
kenjiArai 1:9011c83e4178 48 {
kenjiArai 1:9011c83e4178 49 return false;
kenjiArai 1:9011c83e4178 50 }
kenjiArai 1:9011c83e4178 51 if (mac_1[1] != mac_2[1])
kenjiArai 1:9011c83e4178 52 {
kenjiArai 1:9011c83e4178 53 return false;
kenjiArai 1:9011c83e4178 54 }
kenjiArai 1:9011c83e4178 55 if (mac_1[2] != mac_2[2])
kenjiArai 1:9011c83e4178 56 {
kenjiArai 1:9011c83e4178 57 return false;
kenjiArai 1:9011c83e4178 58 }
kenjiArai 1:9011c83e4178 59 if (mac_1[3] != mac_2[3])
kenjiArai 1:9011c83e4178 60 {
kenjiArai 1:9011c83e4178 61 return false;
kenjiArai 1:9011c83e4178 62 }
kenjiArai 1:9011c83e4178 63 if (mac_1[4] != mac_2[4])
kenjiArai 1:9011c83e4178 64 {
kenjiArai 1:9011c83e4178 65 return false;
kenjiArai 1:9011c83e4178 66 }
kenjiArai 1:9011c83e4178 67 if (mac_1[5] != mac_2[5])
kenjiArai 1:9011c83e4178 68 {
kenjiArai 1:9011c83e4178 69 return false;
kenjiArai 1:9011c83e4178 70 }
kenjiArai 1:9011c83e4178 71 #else
kenjiArai 1:9011c83e4178 72 for (int i = 0; i < 6; i++)
kenjiArai 1:9011c83e4178 73 {
kenjiArai 1:9011c83e4178 74 if (mac_1[i] != mac_2[i])
kenjiArai 1:9011c83e4178 75 {
kenjiArai 1:9011c83e4178 76 //pc.printf("0x%02x != 0x%02x at %d\r\n", mac_1[i], mac_2[i], i);
kenjiArai 1:9011c83e4178 77 return false;
kenjiArai 1:9011c83e4178 78 }
kenjiArai 1:9011c83e4178 79 else
kenjiArai 1:9011c83e4178 80 {
kenjiArai 1:9011c83e4178 81 //pc.printf("0x%02x == 0x%02x at %d\r\n", mac_1[i], mac_2[i], i);
kenjiArai 1:9011c83e4178 82 }
kenjiArai 1:9011c83e4178 83 }
kenjiArai 1:9011c83e4178 84 #endif
kenjiArai 1:9011c83e4178 85 return true;
kenjiArai 1:9011c83e4178 86 }
kenjiArai 1:9011c83e4178 87
kenjiArai 1:9011c83e4178 88 int get_board_index(const Gap::Address_t mac)
kenjiArai 1:9011c83e4178 89 {
kenjiArai 1:9011c83e4178 90 if (mac_equals(mac, mac_board_0))
kenjiArai 1:9011c83e4178 91 {
kenjiArai 1:9011c83e4178 92 return 0;
kenjiArai 1:9011c83e4178 93 }
kenjiArai 1:9011c83e4178 94 if (mac_equals(mac, mac_board_1))
kenjiArai 1:9011c83e4178 95 {
kenjiArai 1:9011c83e4178 96 return 1;
kenjiArai 1:9011c83e4178 97 }
kenjiArai 1:9011c83e4178 98 if (mac_equals(mac, mac_board_2))
kenjiArai 1:9011c83e4178 99 {
kenjiArai 1:9011c83e4178 100 return 2;
kenjiArai 1:9011c83e4178 101 }
kenjiArai 1:9011c83e4178 102
kenjiArai 1:9011c83e4178 103 return -1;
kenjiArai 1:9011c83e4178 104 }
kenjiArai 1:9011c83e4178 105
kenjiArai 1:9011c83e4178 106 void periodicCallback(void)
kenjiArai 1:9011c83e4178 107 {
kenjiArai 1:9011c83e4178 108 alivenessLED = !alivenessLED; /* do blinky on alivenessLED while we're waiting for BLE events */
kenjiArai 1:9011c83e4178 109 }
kenjiArai 1:9011c83e4178 110
kenjiArai 1:9011c83e4178 111
kenjiArai 1:9011c83e4178 112 // Mixed role ****************************************************
kenjiArai 1:9011c83e4178 113 BLE ble;
kenjiArai 1:9011c83e4178 114 Gap::Address_t my_mac;
kenjiArai 1:9011c83e4178 115 int my_board_index = -1;
kenjiArai 1:9011c83e4178 116
kenjiArai 1:9011c83e4178 117 // Device role ****************************************************
kenjiArai 1:9011c83e4178 118 UARTService * uartServicePtr = NULL;
kenjiArai 1:9011c83e4178 119 const static char DEVICE_NAME[] = "ChangeMe!!"; // change this
kenjiArai 1:9011c83e4178 120 static const uint16_t uuid16_list[] = {UARTServiceShortUUID};
kenjiArai 1:9011c83e4178 121 volatile int central_handle = -1;
kenjiArai 1:9011c83e4178 122
kenjiArai 1:9011c83e4178 123
kenjiArai 1:9011c83e4178 124 // Central role ****************************************************
kenjiArai 1:9011c83e4178 125 Gap::Handle_t connectionHandle = 0xFFFF;
kenjiArai 1:9011c83e4178 126 DiscoveredCharacteristic uartTXCharacteristic;
kenjiArai 1:9011c83e4178 127 DiscoveredCharacteristic uartRXCharacteristic;
kenjiArai 1:9011c83e4178 128 bool foundUartRXCharacteristic = false;
kenjiArai 1:9011c83e4178 129 volatile int device_handle = -1;
kenjiArai 1:9011c83e4178 130
kenjiArai 1:9011c83e4178 131
kenjiArai 1:9011c83e4178 132 // Device role ****************************************************
kenjiArai 1:9011c83e4178 133 void onReceivedDataFromCentralCallback(const GattWriteCallbackParams *params)
kenjiArai 1:9011c83e4178 134 {
kenjiArai 1:9011c83e4178 135 if (uartServicePtr != NULL)
kenjiArai 1:9011c83e4178 136 {
kenjiArai 1:9011c83e4178 137 if ((params->handle == uartServicePtr->getTXCharacteristicHandle()) && (params->len >= 1))
kenjiArai 1:9011c83e4178 138 {
kenjiArai 1:9011c83e4178 139 if (params->data[0] != '0')
kenjiArai 1:9011c83e4178 140 {
kenjiArai 1:9011c83e4178 141 led = 1;
kenjiArai 1:9011c83e4178 142 }
kenjiArai 1:9011c83e4178 143 else
kenjiArai 1:9011c83e4178 144 {
kenjiArai 1:9011c83e4178 145 led = 0;
kenjiArai 1:9011c83e4178 146 }
kenjiArai 1:9011c83e4178 147
kenjiArai 1:9011c83e4178 148 for(int i = 0; i < params->len; i++)
kenjiArai 1:9011c83e4178 149 {
kenjiArai 1:9011c83e4178 150 pc.printf("%c", params->data[i]);
kenjiArai 1:9011c83e4178 151 }
kenjiArai 1:9011c83e4178 152
kenjiArai 1:9011c83e4178 153 pc.printf(" (%d, %d)\r\n", params->handle, params->connHandle);
kenjiArai 1:9011c83e4178 154 }
kenjiArai 1:9011c83e4178 155 }
kenjiArai 1:9011c83e4178 156 }
kenjiArai 1:9011c83e4178 157
kenjiArai 1:9011c83e4178 158 // Central role ****************************************************
kenjiArai 1:9011c83e4178 159 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params)
kenjiArai 1:9011c83e4178 160 {
kenjiArai 1:9011c83e4178 161 // do connections like a triangle
kenjiArai 1:9011c83e4178 162 int peer_board_index = get_board_index(params->peerAddr);
kenjiArai 1:9011c83e4178 163
kenjiArai 1:9011c83e4178 164 int next_board_index = my_board_index + 1;
kenjiArai 1:9011c83e4178 165 if (next_board_index >= BOARDS_COUNT)
kenjiArai 1:9011c83e4178 166 {
kenjiArai 1:9011c83e4178 167 next_board_index = 0;
kenjiArai 1:9011c83e4178 168 }
kenjiArai 1:9011c83e4178 169
kenjiArai 1:9011c83e4178 170 //pc.printf("adv %d, %d, %d\r\n", peer_board_index, my_board_index, next_board_index);
kenjiArai 1:9011c83e4178 171
kenjiArai 1:9011c83e4178 172 // force order
kenjiArai 1:9011c83e4178 173 if ((central_handle != -1) || (peer_board_index == 0))
kenjiArai 1:9011c83e4178 174 {
kenjiArai 1:9011c83e4178 175 if (peer_board_index == next_board_index)
kenjiArai 1:9011c83e4178 176 {
kenjiArai 1:9011c83e4178 177 //pc.printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
kenjiArai 1:9011c83e4178 178 // params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
kenjiArai 1:9011c83e4178 179 // params->rssi, params->isScanResponse, params->type);
kenjiArai 1:9011c83e4178 180
kenjiArai 1:9011c83e4178 181 ble.gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL);
kenjiArai 1:9011c83e4178 182 }
kenjiArai 1:9011c83e4178 183 }
kenjiArai 1:9011c83e4178 184 }
kenjiArai 1:9011c83e4178 185
kenjiArai 1:9011c83e4178 186 void serviceDiscoveryCallback(const DiscoveredService *service)
kenjiArai 1:9011c83e4178 187 {
kenjiArai 1:9011c83e4178 188 if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT)
kenjiArai 1:9011c83e4178 189 {
kenjiArai 1:9011c83e4178 190 pc.printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle());
kenjiArai 1:9011c83e4178 191 }
kenjiArai 1:9011c83e4178 192 else
kenjiArai 1:9011c83e4178 193 {
kenjiArai 1:9011c83e4178 194 //pc.printf("S UUID-");
kenjiArai 1:9011c83e4178 195 const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
kenjiArai 1:9011c83e4178 196 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++)
kenjiArai 1:9011c83e4178 197 {
kenjiArai 1:9011c83e4178 198 pc.printf("%02x", longUUIDBytes[i]);
kenjiArai 1:9011c83e4178 199 }
kenjiArai 1:9011c83e4178 200 pc.printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle());
kenjiArai 1:9011c83e4178 201 }
kenjiArai 1:9011c83e4178 202 }
kenjiArai 1:9011c83e4178 203
kenjiArai 1:9011c83e4178 204 void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP)
kenjiArai 1:9011c83e4178 205 {
kenjiArai 1:9011c83e4178 206 //pc.printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
kenjiArai 1:9011c83e4178 207 if (characteristicP->getUUID().getShortUUID() == UARTServiceTXCharacteristicShortUUID)
kenjiArai 1:9011c83e4178 208 {
kenjiArai 1:9011c83e4178 209 pc.printf("fit TX 0x%04x\r\n", UARTServiceTXCharacteristicShortUUID);
kenjiArai 1:9011c83e4178 210 /* !ALERT! Alter this filter to suit your device. */
kenjiArai 1:9011c83e4178 211 uartTXCharacteristic = *characteristicP;
kenjiArai 1:9011c83e4178 212 }
kenjiArai 1:9011c83e4178 213 else if (characteristicP->getUUID().getShortUUID() == UARTServiceRXCharacteristicShortUUID)
kenjiArai 1:9011c83e4178 214 {
kenjiArai 1:9011c83e4178 215 pc.printf("fit RX 0x%04x\r\n", UARTServiceRXCharacteristicShortUUID);
kenjiArai 1:9011c83e4178 216 /* !ALERT! Alter this filter to suit your device. */
kenjiArai 1:9011c83e4178 217 uartRXCharacteristic = *characteristicP;
kenjiArai 1:9011c83e4178 218 foundUartRXCharacteristic = true;
kenjiArai 1:9011c83e4178 219 }
kenjiArai 1:9011c83e4178 220 }
kenjiArai 1:9011c83e4178 221
kenjiArai 1:9011c83e4178 222 void discoveryTerminationCallback(Gap::Handle_t connectionHandle)
kenjiArai 1:9011c83e4178 223 {
kenjiArai 1:9011c83e4178 224 pc.printf("terminated SD for handle %u\r\n", connectionHandle);
kenjiArai 1:9011c83e4178 225 }
kenjiArai 1:9011c83e4178 226
kenjiArai 1:9011c83e4178 227 void onReceivedDataFromDeviceCallback(const GattHVXCallbackParams *params)
kenjiArai 1:9011c83e4178 228 {
kenjiArai 1:9011c83e4178 229 //pc.printf("received HVX callback for handle %u; type %s\r\r\n", params->handle, (params->type == BLE_HVX_NOTIFICATION) ? "notification" : "indication");
kenjiArai 1:9011c83e4178 230 if (params->type == BLE_HVX_NOTIFICATION)
kenjiArai 1:9011c83e4178 231 {
kenjiArai 1:9011c83e4178 232 if ((params->handle == uartRXCharacteristic.getValueHandle()) && (params->len > 0))
kenjiArai 1:9011c83e4178 233 {
kenjiArai 1:9011c83e4178 234 for (int i = 0; i < params->len; i++)
kenjiArai 1:9011c83e4178 235 {
kenjiArai 1:9011c83e4178 236 pc.printf("%c", params->data[i]);
kenjiArai 1:9011c83e4178 237 }
kenjiArai 1:9011c83e4178 238
kenjiArai 1:9011c83e4178 239 pc.printf(" (%d, %d)\r\n", params->handle, params->connHandle);
kenjiArai 1:9011c83e4178 240 }
kenjiArai 1:9011c83e4178 241 }
kenjiArai 1:9011c83e4178 242 else
kenjiArai 1:9011c83e4178 243 {
kenjiArai 1:9011c83e4178 244 pc.printf("%d\r\n", params->type);
kenjiArai 1:9011c83e4178 245 }
kenjiArai 1:9011c83e4178 246 }
kenjiArai 1:9011c83e4178 247
kenjiArai 1:9011c83e4178 248 // Mixed role ****************************************************
kenjiArai 1:9011c83e4178 249 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
kenjiArai 1:9011c83e4178 250 {
kenjiArai 1:9011c83e4178 251 if (params->role == Gap::CENTRAL)
kenjiArai 1:9011c83e4178 252 {
kenjiArai 1:9011c83e4178 253 if (central_handle == -1)
kenjiArai 1:9011c83e4178 254 {
kenjiArai 1:9011c83e4178 255 ble.stopAdvertising(); // stop advertising during discovery, incoming connection breaks discovery
kenjiArai 1:9011c83e4178 256 }
kenjiArai 1:9011c83e4178 257
kenjiArai 1:9011c83e4178 258 device_handle = params->handle;
kenjiArai 1:9011c83e4178 259 pc.printf("connected as central (handle = %d)\r\n\r", params->handle);
kenjiArai 1:9011c83e4178 260 connectionHandle = params->handle;
kenjiArai 1:9011c83e4178 261 ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback);
kenjiArai 1:9011c83e4178 262 int ret = ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, UARTServiceShortUUID/*, 0xa001*/);
kenjiArai 1:9011c83e4178 263
kenjiArai 1:9011c83e4178 264 if (ret != BLE_ERROR_NONE)
kenjiArai 1:9011c83e4178 265 {
kenjiArai 1:9011c83e4178 266 pc.printf("launchServiceDiscovery failed error = %d\r\n\r", ret);
kenjiArai 1:9011c83e4178 267 }
kenjiArai 1:9011c83e4178 268 }
kenjiArai 1:9011c83e4178 269 else
kenjiArai 1:9011c83e4178 270 {
kenjiArai 1:9011c83e4178 271 central_handle = params->handle;
kenjiArai 1:9011c83e4178 272 pc.printf("connected as device (handle = %d)\r\n\r", params->handle);
kenjiArai 1:9011c83e4178 273
kenjiArai 1:9011c83e4178 274 //pc.printf("Conn. params => min=%d, max=%d, slave=%d, supervision=%d\r\n", params->connectionParams->minConnectionInterval, params->connectionParams->maxConnectionInterval, params->connectionParams->slaveLatency, params->connectionParams->connectionSupervisionTimeout);
kenjiArai 1:9011c83e4178 275 /*
kenjiArai 1:9011c83e4178 276 Gap::ConnectionParams_t connectionParams;
kenjiArai 1:9011c83e4178 277 connectionParams.minConnectionInterval = 6;
kenjiArai 1:9011c83e4178 278 connectionParams.maxConnectionInterval = 12;
kenjiArai 1:9011c83e4178 279 connectionParams.slaveLatency = 40;
kenjiArai 1:9011c83e4178 280 connectionParams.connectionSupervisionTimeout = 500;
kenjiArai 1:9011c83e4178 281
kenjiArai 1:9011c83e4178 282 int ret = ble.updateConnectionParams(params->handle, &connectionParams);
kenjiArai 1:9011c83e4178 283 if (ret != BLE_ERROR_NONE)
kenjiArai 1:9011c83e4178 284 {
kenjiArai 1:9011c83e4178 285 pc.printf("failed to update connection parameter\r\n");
kenjiArai 1:9011c83e4178 286 }
kenjiArai 1:9011c83e4178 287 */
kenjiArai 1:9011c83e4178 288 }
kenjiArai 1:9011c83e4178 289 pc.printf("own %02x:%02x:%02x:%02x:%02x:%02x (%s), peer %02x:%02x:%02x:%02x:%02x:%02x (%s)\r\n", params->ownAddr[5], params->ownAddr[4], params->ownAddr[3], params->ownAddr[2], params->ownAddr[1], params->ownAddr[0], (params->ownAddrType == Gap::ADDR_TYPE_PUBLIC) ? "public" : "random", params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0], (params->peerAddrType == Gap::ADDR_TYPE_PUBLIC) ? "public" : "random");
kenjiArai 1:9011c83e4178 290 }
kenjiArai 1:9011c83e4178 291
kenjiArai 1:9011c83e4178 292 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
kenjiArai 1:9011c83e4178 293 {
kenjiArai 1:9011c83e4178 294 char * ascii_reason = "?";
kenjiArai 1:9011c83e4178 295 switch (reason)
kenjiArai 1:9011c83e4178 296 {
kenjiArai 1:9011c83e4178 297 case Gap::CONNECTION_TIMEOUT:
kenjiArai 1:9011c83e4178 298 ascii_reason = "connection timeout";
kenjiArai 1:9011c83e4178 299 break;
kenjiArai 1:9011c83e4178 300 case Gap::REMOTE_USER_TERMINATED_CONNECTION:
kenjiArai 1:9011c83e4178 301 ascii_reason = "user terminated connection";
kenjiArai 1:9011c83e4178 302 break;
kenjiArai 1:9011c83e4178 303 case Gap::REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES:
kenjiArai 1:9011c83e4178 304 ascii_reason = "low resources";
kenjiArai 1:9011c83e4178 305 break;
kenjiArai 1:9011c83e4178 306 case Gap::REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF:
kenjiArai 1:9011c83e4178 307 ascii_reason = "power off";
kenjiArai 1:9011c83e4178 308 break;
kenjiArai 1:9011c83e4178 309 case Gap::LOCAL_HOST_TERMINATED_CONNECTION:
kenjiArai 1:9011c83e4178 310 ascii_reason = "host terminated connection";
kenjiArai 1:9011c83e4178 311 break;
kenjiArai 1:9011c83e4178 312 case Gap::CONN_INTERVAL_UNACCEPTABLE:
kenjiArai 1:9011c83e4178 313 ascii_reason = "interval unacceptable";
kenjiArai 1:9011c83e4178 314 break;
kenjiArai 1:9011c83e4178 315 default:
kenjiArai 1:9011c83e4178 316 ascii_reason = "unknown";
kenjiArai 1:9011c83e4178 317 break;
kenjiArai 1:9011c83e4178 318 }
kenjiArai 1:9011c83e4178 319
kenjiArai 1:9011c83e4178 320 pc.printf("disconnected (reason = %s, handle = %d)\r\n", ascii_reason, handle);
kenjiArai 1:9011c83e4178 321
kenjiArai 1:9011c83e4178 322
kenjiArai 1:9011c83e4178 323 if (handle == SOFT_DEVICE_FATHER_HANDLE)
kenjiArai 1:9011c83e4178 324 {
kenjiArai 1:9011c83e4178 325 central_handle = -1;
kenjiArai 1:9011c83e4178 326 // restart advertising
kenjiArai 1:9011c83e4178 327 ble.startAdvertising();
kenjiArai 1:9011c83e4178 328 }
kenjiArai 1:9011c83e4178 329 else
kenjiArai 1:9011c83e4178 330 {
kenjiArai 1:9011c83e4178 331 device_handle = -1;
kenjiArai 1:9011c83e4178 332 // restart scan
kenjiArai 1:9011c83e4178 333 ble.gap().startScan(advertisementCallback);
kenjiArai 1:9011c83e4178 334 }
kenjiArai 1:9011c83e4178 335 }
kenjiArai 1:9011c83e4178 336
kenjiArai 1:9011c83e4178 337
kenjiArai 1:9011c83e4178 338
kenjiArai 1:9011c83e4178 339 void serialTxCallback()
kenjiArai 1:9011c83e4178 340 {
kenjiArai 1:9011c83e4178 341
kenjiArai 1:9011c83e4178 342 }
kenjiArai 1:9011c83e4178 343
kenjiArai 1:9011c83e4178 344 int rx_char = -1;
kenjiArai 1:9011c83e4178 345 void serialRxCallback()
kenjiArai 1:9011c83e4178 346 {
kenjiArai 1:9011c83e4178 347 if (rx_char != -1)
kenjiArai 1:9011c83e4178 348 {
kenjiArai 1:9011c83e4178 349 pc.printf("overflow\r\n");
kenjiArai 1:9011c83e4178 350 }
kenjiArai 1:9011c83e4178 351
kenjiArai 1:9011c83e4178 352 //computer.putc(computer.getc());
kenjiArai 1:9011c83e4178 353 rx_char = pc.getc();
kenjiArai 1:9011c83e4178 354 }
kenjiArai 1:9011c83e4178 355
kenjiArai 1:9011c83e4178 356 /*
kenjiArai 1:9011c83e4178 357 void gattServerOnDataSent(unsigned count)
kenjiArai 1:9011c83e4178 358 {
kenjiArai 1:9011c83e4178 359
kenjiArai 1:9011c83e4178 360 }
kenjiArai 1:9011c83e4178 361 */
kenjiArai 1:9011c83e4178 362
kenjiArai 1:9011c83e4178 363
kenjiArai 1:9011c83e4178 364 int main(void)
kenjiArai 1:9011c83e4178 365 {
kenjiArai 1:9011c83e4178 366 alivenessLED = 0;
kenjiArai 1:9011c83e4178 367
kenjiArai 1:9011c83e4178 368 pc.baud(115200);
kenjiArai 1:9011c83e4178 369 //pc.attach(&serialTxCallback, Serial::TxIrq);
kenjiArai 1:9011c83e4178 370 pc.attach(&serialRxCallback, Serial::RxIrq);
kenjiArai 1:9011c83e4178 371
kenjiArai 1:9011c83e4178 372 // clear terminal output
kenjiArai 1:9011c83e4178 373 for (int k = 0; k < 32; k++)
kenjiArai 1:9011c83e4178 374 {
kenjiArai 1:9011c83e4178 375 pc.printf("\r\n");
kenjiArai 1:9011c83e4178 376 }
kenjiArai 1:9011c83e4178 377
kenjiArai 1:9011c83e4178 378 pc.printf("Central and device\r\n");
kenjiArai 1:9011c83e4178 379
kenjiArai 1:9011c83e4178 380 Ticker ticker;
kenjiArai 1:9011c83e4178 381 ticker.attach(periodicCallback, 1);
kenjiArai 1:9011c83e4178 382
kenjiArai 1:9011c83e4178 383
kenjiArai 1:9011c83e4178 384 // Mixed role ****************************************************
kenjiArai 1:9011c83e4178 385 ble.init();
kenjiArai 1:9011c83e4178 386
kenjiArai 1:9011c83e4178 387 Gap::AddressType_t my_mac_type;
kenjiArai 1:9011c83e4178 388 ble.gap().getAddress(&my_mac_type, my_mac);
kenjiArai 1:9011c83e4178 389 my_board_index = get_board_index(my_mac);
kenjiArai 1:9011c83e4178 390 pc.printf("me %02x:%02x:%02x:%02x:%02x:%02x (%s)\r\n", my_mac[5], my_mac[4], my_mac[3], my_mac[2], my_mac[1], my_mac[0], (my_mac_type == Gap::ADDR_TYPE_PUBLIC) ? "public" : "random");
kenjiArai 1:9011c83e4178 391
kenjiArai 1:9011c83e4178 392
kenjiArai 1:9011c83e4178 393 // try to speed up but looks like if it was ignored
kenjiArai 1:9011c83e4178 394 Gap::ConnectionParams_t fast;
kenjiArai 1:9011c83e4178 395 if (ble.getPreferredConnectionParams(&fast) != BLE_ERROR_NONE)
kenjiArai 1:9011c83e4178 396 {
kenjiArai 1:9011c83e4178 397 pc.printf("getPreferredConnectionParams failed\r\n");
kenjiArai 1:9011c83e4178 398 }
kenjiArai 1:9011c83e4178 399 else
kenjiArai 1:9011c83e4178 400 {
kenjiArai 1:9011c83e4178 401 fast.minConnectionInterval = 16; // 20 ms
kenjiArai 1:9011c83e4178 402 fast.maxConnectionInterval = 32; // 40 ms
kenjiArai 1:9011c83e4178 403 fast.slaveLatency = 0;
kenjiArai 1:9011c83e4178 404 if (ble.gap().setPreferredConnectionParams(&fast) != BLE_ERROR_NONE)
kenjiArai 1:9011c83e4178 405 {
kenjiArai 1:9011c83e4178 406 pc.printf("setPreferredConnectionParams failed\r\n");
kenjiArai 1:9011c83e4178 407 }
kenjiArai 1:9011c83e4178 408 }
kenjiArai 1:9011c83e4178 409 ble.gap().onConnection(connectionCallback);
kenjiArai 1:9011c83e4178 410 ble.gap().onDisconnection(disconnectionCallback);
kenjiArai 1:9011c83e4178 411
kenjiArai 1:9011c83e4178 412 // Device role ****************************************************
kenjiArai 1:9011c83e4178 413 ble.gattServer().onDataWritten(onReceivedDataFromCentralCallback);
kenjiArai 1:9011c83e4178 414 //ble.gattServer().onDataSent(gattServerOnDataSent);
kenjiArai 1:9011c83e4178 415
kenjiArai 1:9011c83e4178 416 UARTService uartService(ble);
kenjiArai 1:9011c83e4178 417 uartServicePtr = &uartService;
kenjiArai 1:9011c83e4178 418
kenjiArai 1:9011c83e4178 419 // setup advertising
kenjiArai 1:9011c83e4178 420 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); // BLE only, no classic BT
kenjiArai 1:9011c83e4178 421 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); // add name
kenjiArai 1:9011c83e4178 422 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // UUID's broadcast in advertising packet
kenjiArai 1:9011c83e4178 423 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); // advertising type
kenjiArai 1:9011c83e4178 424 ble.setAdvertisingInterval(100);
kenjiArai 1:9011c83e4178 425
kenjiArai 1:9011c83e4178 426 // Central role ****************************************************
kenjiArai 1:9011c83e4178 427 ble.gattClient().onHVX(onReceivedDataFromDeviceCallback);
kenjiArai 1:9011c83e4178 428 ble.gap().setScanParams(500, 450);
kenjiArai 1:9011c83e4178 429
kenjiArai 1:9011c83e4178 430
kenjiArai 1:9011c83e4178 431 // start advertising and scan
kenjiArai 1:9011c83e4178 432 ble.startAdvertising();
kenjiArai 1:9011c83e4178 433 ble.gap().startScan(advertisementCallback);
kenjiArai 1:9011c83e4178 434
kenjiArai 1:9011c83e4178 435 while (true)
kenjiArai 1:9011c83e4178 436 {
kenjiArai 1:9011c83e4178 437 // allow notifications from device
kenjiArai 1:9011c83e4178 438 if (foundUartRXCharacteristic && !ble.gattClient().isServiceDiscoveryActive())
kenjiArai 1:9011c83e4178 439 {
kenjiArai 1:9011c83e4178 440 foundUartRXCharacteristic = false; /* need to do the following only once */
kenjiArai 1:9011c83e4178 441
kenjiArai 1:9011c83e4178 442 uint16_t value = BLE_HVX_NOTIFICATION;
kenjiArai 1:9011c83e4178 443 int ret = ble.gattClient().write(GattClient::GATT_OP_WRITE_REQ,
kenjiArai 1:9011c83e4178 444 connectionHandle,
kenjiArai 1:9011c83e4178 445 uartRXCharacteristic.getValueHandle() + 1, /* HACK Alert. We're assuming that CCCD descriptor immediately follows the value attribute. */
kenjiArai 1:9011c83e4178 446 sizeof(uint16_t), /* HACK Alert! size should be made into a BLE_API constant. */
kenjiArai 1:9011c83e4178 447 reinterpret_cast<const uint8_t *>(&value));
kenjiArai 1:9011c83e4178 448
kenjiArai 1:9011c83e4178 449 if (ret == BLE_ERROR_NONE)
kenjiArai 1:9011c83e4178 450 {
kenjiArai 1:9011c83e4178 451 pc.printf("\r\ndevice notifications enabled\r\n");
kenjiArai 1:9011c83e4178 452 }
kenjiArai 1:9011c83e4178 453 else
kenjiArai 1:9011c83e4178 454 {
kenjiArai 1:9011c83e4178 455 switch (ret)
kenjiArai 1:9011c83e4178 456 {
kenjiArai 1:9011c83e4178 457 case BLE_STACK_BUSY:
kenjiArai 1:9011c83e4178 458 foundUartRXCharacteristic = true; // retry later
kenjiArai 1:9011c83e4178 459 break;
kenjiArai 1:9011c83e4178 460 case BLE_ERROR_NO_MEM:
kenjiArai 1:9011c83e4178 461 foundUartRXCharacteristic = true; // retry later
kenjiArai 1:9011c83e4178 462 break;
kenjiArai 1:9011c83e4178 463 case BLE_ERROR_INVALID_STATE:
kenjiArai 1:9011c83e4178 464 pc.printf("\r\ndevice notifications enable failed\r\n");
kenjiArai 1:9011c83e4178 465 break;
kenjiArai 1:9011c83e4178 466 default:
kenjiArai 1:9011c83e4178 467 break;
kenjiArai 1:9011c83e4178 468 }
kenjiArai 1:9011c83e4178 469 }
kenjiArai 1:9011c83e4178 470
kenjiArai 1:9011c83e4178 471 if (!foundUartRXCharacteristic)
kenjiArai 1:9011c83e4178 472 {
kenjiArai 1:9011c83e4178 473 if (central_handle == -1)
kenjiArai 1:9011c83e4178 474 {
kenjiArai 1:9011c83e4178 475 ble.startAdvertising();
kenjiArai 1:9011c83e4178 476 }
kenjiArai 1:9011c83e4178 477 }
kenjiArai 1:9011c83e4178 478 }
kenjiArai 1:9011c83e4178 479
kenjiArai 1:9011c83e4178 480 // while a new char from computer is available
kenjiArai 1:9011c83e4178 481 while (rx_char != -1)
kenjiArai 1:9011c83e4178 482 {
kenjiArai 1:9011c83e4178 483 uint8_t temp[20];
kenjiArai 1:9011c83e4178 484 int length = 1;
kenjiArai 1:9011c83e4178 485
kenjiArai 1:9011c83e4178 486 uint8_t command = rx_char;
kenjiArai 1:9011c83e4178 487 rx_char = -1;
kenjiArai 1:9011c83e4178 488
kenjiArai 1:9011c83e4178 489 // if special char to test a 20 bytes frame
kenjiArai 1:9011c83e4178 490 /*
kenjiArai 1:9011c83e4178 491 if (command == '*')
kenjiArai 1:9011c83e4178 492 {
kenjiArai 1:9011c83e4178 493 pc.printf("20 chars\r\n");
kenjiArai 1:9011c83e4178 494
kenjiArai 1:9011c83e4178 495 int c = 0;
kenjiArai 1:9011c83e4178 496 for (c = 0; c < 20; c++)
kenjiArai 1:9011c83e4178 497 {
kenjiArai 1:9011c83e4178 498 temp[c] = 'a' + c;
kenjiArai 1:9011c83e4178 499 }
kenjiArai 1:9011c83e4178 500 length = 20;
kenjiArai 1:9011c83e4178 501 }
kenjiArai 1:9011c83e4178 502 else
kenjiArai 1:9011c83e4178 503 {
kenjiArai 1:9011c83e4178 504 temp[0] = command;
kenjiArai 1:9011c83e4178 505 }
kenjiArai 1:9011c83e4178 506 */
kenjiArai 1:9011c83e4178 507 temp[0] = command;
kenjiArai 1:9011c83e4178 508
kenjiArai 1:9011c83e4178 509 // to central
kenjiArai 1:9011c83e4178 510 //if (command == '1')
kenjiArai 1:9011c83e4178 511 {
kenjiArai 1:9011c83e4178 512 if (central_handle != -1)
kenjiArai 1:9011c83e4178 513 {
kenjiArai 1:9011c83e4178 514 // device to central
kenjiArai 1:9011c83e4178 515 while (1)
kenjiArai 1:9011c83e4178 516 {
kenjiArai 1:9011c83e4178 517 if (central_handle == -1)
kenjiArai 1:9011c83e4178 518 {
kenjiArai 1:9011c83e4178 519 pc.printf("\r\ndisconnected 1 (to central)\r\n");
kenjiArai 1:9011c83e4178 520 break;
kenjiArai 1:9011c83e4178 521 }
kenjiArai 1:9011c83e4178 522 if (!ble.gap().getState().connected)
kenjiArai 1:9011c83e4178 523 {
kenjiArai 1:9011c83e4178 524 pc.printf("\r\ndisconnected 2 (to central)\r\n");
kenjiArai 1:9011c83e4178 525 break;
kenjiArai 1:9011c83e4178 526 }
kenjiArai 1:9011c83e4178 527 int ret = ble.gattServer().write(uartServicePtr->getRXCharacteristicHandle(), temp, length);
kenjiArai 1:9011c83e4178 528
kenjiArai 1:9011c83e4178 529 if (ret == BLE_ERROR_NONE)
kenjiArai 1:9011c83e4178 530 {
kenjiArai 1:9011c83e4178 531 //pc.printf("\r\nok (to central)\r\n");
kenjiArai 1:9011c83e4178 532 break;
kenjiArai 1:9011c83e4178 533 }
kenjiArai 1:9011c83e4178 534 else if (ret == BLE_STACK_BUSY)
kenjiArai 1:9011c83e4178 535 {
kenjiArai 1:9011c83e4178 536 //pc.printf("\r\nbusy (to central)\r\n");
kenjiArai 1:9011c83e4178 537 //break;
kenjiArai 1:9011c83e4178 538 }
kenjiArai 1:9011c83e4178 539 else if (ret == BLE_ERROR_OPERATION_NOT_PERMITTED)
kenjiArai 1:9011c83e4178 540 {
kenjiArai 1:9011c83e4178 541 pc.printf("\r\nnot permitted (to central)\r\n");
kenjiArai 1:9011c83e4178 542 break;
kenjiArai 1:9011c83e4178 543 }
kenjiArai 1:9011c83e4178 544 else if (ret == BLE_ERROR_INVALID_STATE)
kenjiArai 1:9011c83e4178 545 {
kenjiArai 1:9011c83e4178 546 pc.printf("\r\ninvalid state (to central)\r\n");
kenjiArai 1:9011c83e4178 547 break;
kenjiArai 1:9011c83e4178 548 }
kenjiArai 1:9011c83e4178 549 else
kenjiArai 1:9011c83e4178 550 {
kenjiArai 1:9011c83e4178 551 pc.printf("\r\ncode %d (to central)\r\n", ret);
kenjiArai 1:9011c83e4178 552 break;
kenjiArai 1:9011c83e4178 553 }
kenjiArai 1:9011c83e4178 554 }
kenjiArai 1:9011c83e4178 555 }
kenjiArai 1:9011c83e4178 556 else
kenjiArai 1:9011c83e4178 557 {
kenjiArai 1:9011c83e4178 558 pc.printf("\r\nnot connected with central\r\n");
kenjiArai 1:9011c83e4178 559 }
kenjiArai 1:9011c83e4178 560 }
kenjiArai 1:9011c83e4178 561
kenjiArai 1:9011c83e4178 562 // to device
kenjiArai 1:9011c83e4178 563 //if (command == '2')
kenjiArai 1:9011c83e4178 564 {
kenjiArai 1:9011c83e4178 565 if (device_handle != -1)
kenjiArai 1:9011c83e4178 566 {
kenjiArai 1:9011c83e4178 567 // central to device
kenjiArai 1:9011c83e4178 568 while (1)
kenjiArai 1:9011c83e4178 569 {
kenjiArai 1:9011c83e4178 570 if (device_handle == -1)
kenjiArai 1:9011c83e4178 571 {
kenjiArai 1:9011c83e4178 572 pc.printf("\r\ndisconnected (to device)\r\n");
kenjiArai 1:9011c83e4178 573 break;
kenjiArai 1:9011c83e4178 574 }
kenjiArai 1:9011c83e4178 575 int ret = uartTXCharacteristic.write(length, temp);
kenjiArai 1:9011c83e4178 576 if (ret == BLE_ERROR_NONE)
kenjiArai 1:9011c83e4178 577 {
kenjiArai 1:9011c83e4178 578 //pc.printf("\r\nok (to device)\r\n");
kenjiArai 1:9011c83e4178 579 break;
kenjiArai 1:9011c83e4178 580 }
kenjiArai 1:9011c83e4178 581 else if (ret == BLE_STACK_BUSY)
kenjiArai 1:9011c83e4178 582 {
kenjiArai 1:9011c83e4178 583 //pc.printf("\r\nbusy (to device)\r\n");
kenjiArai 1:9011c83e4178 584 //break;
kenjiArai 1:9011c83e4178 585 }
kenjiArai 1:9011c83e4178 586 else if (ret == BLE_ERROR_OPERATION_NOT_PERMITTED)
kenjiArai 1:9011c83e4178 587 {
kenjiArai 1:9011c83e4178 588 pc.printf("\r\nnot permitted (to device)\r\n");
kenjiArai 1:9011c83e4178 589 break;
kenjiArai 1:9011c83e4178 590 }
kenjiArai 1:9011c83e4178 591 else if (ret == BLE_ERROR_INVALID_STATE)
kenjiArai 1:9011c83e4178 592 {
kenjiArai 1:9011c83e4178 593 pc.printf("\r\ninvalid state (to device)\r\n");
kenjiArai 1:9011c83e4178 594 break;
kenjiArai 1:9011c83e4178 595 }
kenjiArai 1:9011c83e4178 596 else
kenjiArai 1:9011c83e4178 597 {
kenjiArai 1:9011c83e4178 598 pc.printf("\r\ncode %d (to device)\r\n", ret);
kenjiArai 1:9011c83e4178 599 break;
kenjiArai 1:9011c83e4178 600 }
kenjiArai 1:9011c83e4178 601 }
kenjiArai 1:9011c83e4178 602 }
kenjiArai 1:9011c83e4178 603 else
kenjiArai 1:9011c83e4178 604 {
kenjiArai 1:9011c83e4178 605 pc.printf("\r\nnot connected with device\r\n");
kenjiArai 1:9011c83e4178 606 }
kenjiArai 1:9011c83e4178 607 }
kenjiArai 1:9011c83e4178 608 }
kenjiArai 1:9011c83e4178 609
kenjiArai 1:9011c83e4178 610 ble.waitForEvent(); // save power
kenjiArai 1:9011c83e4178 611 }
kenjiArai 1:9011c83e4178 612 }
kenjiArai 1:9011c83e4178 613
kenjiArai 1:9011c83e4178 614 #endif