test firmware for BLE Micro V1.3 1. test io, vcc and ble 2. act as a UART to BLE bridge

Dependencies:   BLE_API Buffer mbed

Fork of BLE_LEDBlinker by Bluetooth Low Energy

Committer:
arch
Date:
Tue Dec 08 08:34:22 2015 +0000
Revision:
12:c4090cb58976
Parent:
11:c8cbc4bc2c17
fix USBTX/USBRX pins config

Who changed what in which revision?

UserRevisionLine numberNew contents of line
arch 11:c8cbc4bc2c17 1 // nRF51822 lib revision 534
rgrover1 0:415d7f24cb91 2
rgrover1 0:415d7f24cb91 3 #include "mbed.h"
rgrover1 6:1730f66fb14d 4 #include "ble/BLE.h"
rgrover1 6:1730f66fb14d 5 #include "ble/DiscoveredCharacteristic.h"
rgrover1 6:1730f66fb14d 6 #include "ble/DiscoveredService.h"
arch 11:c8cbc4bc2c17 7 #include "ble/services/UARTService.h"
arch 11:c8cbc4bc2c17 8 #include "ble/services/DFUService.h"
arch 11:c8cbc4bc2c17 9 #include "Buffer.h"
arch 11:c8cbc4bc2c17 10
arch 11:c8cbc4bc2c17 11
arch 11:c8cbc4bc2c17 12 #define LOG(args...) // printf(args)
arch 11:c8cbc4bc2c17 13
rgrover1 0:415d7f24cb91 14
rgrover1 6:1730f66fb14d 15 BLE ble;
arch 11:c8cbc4bc2c17 16 UARTService *bleuart;
rgrover1 6:1730f66fb14d 17
rgrover1 1:1db45b17552e 18 bool triggerLedCharacteristic = false;
rgrover1 0:415d7f24cb91 19 DiscoveredCharacteristic ledCharacteristic;
arch 11:c8cbc4bc2c17 20 int saved_test_result = 0;
arch 11:c8cbc4bc2c17 21 volatile int current_test_status = 1;
arch 11:c8cbc4bc2c17 22 uint32_t device_scan_time = 0;
arch 11:c8cbc4bc2c17 23 uint32_t device_found_time = 0;
arch 11:c8cbc4bc2c17 24 uint32_t device_connected_time = 0;
rgrover1 0:415d7f24cb91 25
arch 11:c8cbc4bc2c17 26 int test_is_passed();
arch 11:c8cbc4bc2c17 27 int test_save_result(int result);
arch 11:c8cbc4bc2c17 28 int test_check_io();
arch 11:c8cbc4bc2c17 29 int test_check_vcc();
arch 11:c8cbc4bc2c17 30 int test_output_result(int result);
arch 11:c8cbc4bc2c17 31
arch 11:c8cbc4bc2c17 32 Serial *uart;
arch 11:c8cbc4bc2c17 33 Buffer <char> uartRxBuffer(0x100);
arch 11:c8cbc4bc2c17 34
arch 11:c8cbc4bc2c17 35 uint8_t bleIsConnected = 0;
arch 11:c8cbc4bc2c17 36 uint8_t bleTxFlag = 0;
rgrover1 0:415d7f24cb91 37
arch 11:c8cbc4bc2c17 38 bool rxPayloadUpdated = false;
arch 11:c8cbc4bc2c17 39 uint8_t rxPayload[20 + 1] = {0,};
arch 11:c8cbc4bc2c17 40 uint8_t txPayload[20 + 1] = {0,};
rgrover1 0:415d7f24cb91 41
arch 11:c8cbc4bc2c17 42 void uart2ble(void)
arch 11:c8cbc4bc2c17 43 {
arch 11:c8cbc4bc2c17 44 uint16_t bytesToWrite = 0;
arch 11:c8cbc4bc2c17 45 for (int i = 0; i < 20; i++) {
arch 11:c8cbc4bc2c17 46 if (uartRxBuffer.available()) {
arch 11:c8cbc4bc2c17 47 txPayload[bytesToWrite] = uartRxBuffer;
arch 11:c8cbc4bc2c17 48 bytesToWrite++;
arch 11:c8cbc4bc2c17 49 }
arch 11:c8cbc4bc2c17 50 }
arch 11:c8cbc4bc2c17 51
arch 11:c8cbc4bc2c17 52 if (bytesToWrite != 0) {
arch 11:c8cbc4bc2c17 53 bleTxFlag = 1;
arch 11:c8cbc4bc2c17 54
arch 11:c8cbc4bc2c17 55 ble.updateCharacteristicValue(bleuart->getRXCharacteristicHandle(), txPayload, bytesToWrite);
rgrover1 0:415d7f24cb91 56 } else {
arch 11:c8cbc4bc2c17 57 bleTxFlag = 0;
rgrover1 0:415d7f24cb91 58 }
rgrover1 0:415d7f24cb91 59 }
rgrover1 0:415d7f24cb91 60
arch 11:c8cbc4bc2c17 61 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params)
arch 11:c8cbc4bc2c17 62 {
arch 11:c8cbc4bc2c17 63 if (params->peerAddr[0] != params->peerAddr[5]) { /* !ALERT! Alter this filter to suit your device. */
arch 11:c8cbc4bc2c17 64 return;
rgrover1 0:415d7f24cb91 65 }
arch 11:c8cbc4bc2c17 66 device_found_time = us_ticker_read();
arch 11:c8cbc4bc2c17 67
arch 11:c8cbc4bc2c17 68 LOG("device found @ %d\r\n", device_found_time);
arch 11:c8cbc4bc2c17 69
arch 11:c8cbc4bc2c17 70 LOG("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
arch 11:c8cbc4bc2c17 71 params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
arch 11:c8cbc4bc2c17 72 params->rssi, params->isScanResponse, params->type);
arch 11:c8cbc4bc2c17 73
arch 11:c8cbc4bc2c17 74 ble.gap().connect(params->peerAddr, Gap::ADDR_TYPE_PUBLIC, NULL, NULL);
rgrover1 0:415d7f24cb91 75 }
rgrover1 0:415d7f24cb91 76
rgrover1 0:415d7f24cb91 77
arch 11:c8cbc4bc2c17 78 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
arch 11:c8cbc4bc2c17 79 {
rgrover1 0:415d7f24cb91 80 if (params->role == Gap::CENTRAL) {
arch 11:c8cbc4bc2c17 81 device_connected_time = us_ticker_read();
arch 11:c8cbc4bc2c17 82
arch 11:c8cbc4bc2c17 83 LOG("device connected @ %d\r\n", device_connected_time);
arch 11:c8cbc4bc2c17 84 if (current_test_status == 3)
arch 11:c8cbc4bc2c17 85 {
arch 11:c8cbc4bc2c17 86 current_test_status = 0;
arch 12:c4090cb58976 87 test_output_result(0);
arch 11:c8cbc4bc2c17 88 test_save_result(0);
arch 11:c8cbc4bc2c17 89 }
arch 11:c8cbc4bc2c17 90
arch 11:c8cbc4bc2c17 91 } else {
arch 11:c8cbc4bc2c17 92 LOG("connected\r\n");
arch 11:c8cbc4bc2c17 93
arch 11:c8cbc4bc2c17 94 bleIsConnected = 1;
arch 11:c8cbc4bc2c17 95 bleTxFlag = 0;
arch 11:c8cbc4bc2c17 96 uartRxBuffer.clear();
rgrover1 0:415d7f24cb91 97 }
rgrover1 0:415d7f24cb91 98 }
rgrover1 0:415d7f24cb91 99
arch 11:c8cbc4bc2c17 100 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
arch 11:c8cbc4bc2c17 101 {
arch 11:c8cbc4bc2c17 102 LOG("Disconnected!\n\r");
arch 11:c8cbc4bc2c17 103 LOG("Restarting the advertising process\n\r");
arch 11:c8cbc4bc2c17 104
arch 11:c8cbc4bc2c17 105 bleTxFlag = 0;
arch 11:c8cbc4bc2c17 106 bleIsConnected = 0;
arch 11:c8cbc4bc2c17 107
arch 11:c8cbc4bc2c17 108 ble.startAdvertising();
arch 11:c8cbc4bc2c17 109
arch 11:c8cbc4bc2c17 110 }
arch 11:c8cbc4bc2c17 111
arch 11:c8cbc4bc2c17 112 void onDataWritten(const GattWriteCallbackParams *params)
arch 11:c8cbc4bc2c17 113 {
arch 11:c8cbc4bc2c17 114 if ((bleuart != NULL) && (params->handle == bleuart->getTXCharacteristicHandle())) {
arch 11:c8cbc4bc2c17 115 uint16_t bytesRead = params->len;
arch 11:c8cbc4bc2c17 116 LOG("received %u bytes\n\r", bytesRead);
arch 11:c8cbc4bc2c17 117 // ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
arch 11:c8cbc4bc2c17 118
arch 11:c8cbc4bc2c17 119 for (int i = 0; i < bytesRead; i++) {
arch 11:c8cbc4bc2c17 120 uart->putc(params->data[i]);
rgrover1 0:415d7f24cb91 121 }
rgrover1 0:415d7f24cb91 122 }
rgrover1 0:415d7f24cb91 123 }
rgrover1 0:415d7f24cb91 124
arch 11:c8cbc4bc2c17 125 void onDataSent(unsigned count)
arch 11:c8cbc4bc2c17 126 {
arch 11:c8cbc4bc2c17 127 LOG("onDataSent\r\n");
arch 11:c8cbc4bc2c17 128
arch 11:c8cbc4bc2c17 129 uart2ble();
rgrover1 0:415d7f24cb91 130 }
rgrover1 0:415d7f24cb91 131
arch 11:c8cbc4bc2c17 132 int main(void)
arch 11:c8cbc4bc2c17 133 {
arch 11:c8cbc4bc2c17 134 int io_status;
arch 11:c8cbc4bc2c17 135 int vcc_status;
arch 12:c4090cb58976 136
arch 11:c8cbc4bc2c17 137 saved_test_result = test_is_passed();
arch 11:c8cbc4bc2c17 138 if (!saved_test_result) {
arch 12:c4090cb58976 139 {
arch 12:c4090cb58976 140 uart = new Serial(p20, p21); // release USBTX and USBRX
arch 12:c4090cb58976 141 uart->baud(38400);
arch 12:c4090cb58976 142 }
arch 12:c4090cb58976 143
arch 11:c8cbc4bc2c17 144 io_status = test_check_io();
arch 11:c8cbc4bc2c17 145 vcc_status = test_check_vcc();
arch 11:c8cbc4bc2c17 146
arch 11:c8cbc4bc2c17 147 if (io_status) {
arch 11:c8cbc4bc2c17 148 test_output_result(1);
arch 11:c8cbc4bc2c17 149 } else {
arch 11:c8cbc4bc2c17 150 current_test_status = 2;
arch 11:c8cbc4bc2c17 151 if (vcc_status) {
arch 11:c8cbc4bc2c17 152 test_output_result(2);
arch 11:c8cbc4bc2c17 153 } else {
arch 11:c8cbc4bc2c17 154 current_test_status = 3;
arch 11:c8cbc4bc2c17 155 }
arch 11:c8cbc4bc2c17 156 }
arch 11:c8cbc4bc2c17 157
arch 11:c8cbc4bc2c17 158 } else {
arch 12:c4090cb58976 159 test_output_result(0);
arch 12:c4090cb58976 160 uart = new Serial(p8, p7);
arch 12:c4090cb58976 161 uart->baud(38400);
arch 11:c8cbc4bc2c17 162 }
arch 11:c8cbc4bc2c17 163
rgrover1 0:415d7f24cb91 164
arch 12:c4090cb58976 165
rgrover1 0:415d7f24cb91 166
rgrover1 0:415d7f24cb91 167 ble.init();
rgrover1 5:3bbad34d1a85 168 ble.gap().onConnection(connectionCallback);
rgrover1 5:3bbad34d1a85 169 ble.gap().onDisconnection(disconnectionCallback);
arch 11:c8cbc4bc2c17 170 ble.onDataWritten(onDataWritten);
arch 11:c8cbc4bc2c17 171 ble.onDataSent(onDataSent);
rgrover1 0:415d7f24cb91 172
arch 11:c8cbc4bc2c17 173 if (!saved_test_result) {
arch 11:c8cbc4bc2c17 174 LOG("io test %s\r\n", io_status ? "failed" : "ok");
arch 11:c8cbc4bc2c17 175 LOG("vcc test %s\r\n", vcc_status ? "failed" : "ok");
arch 11:c8cbc4bc2c17 176
arch 11:c8cbc4bc2c17 177 LOG("enable ble centre role\r\n");
arch 11:c8cbc4bc2c17 178
arch 11:c8cbc4bc2c17 179 ble.gap().setScanParams(500, 400);
arch 11:c8cbc4bc2c17 180 ble.gap().startScan(advertisementCallback);
arch 11:c8cbc4bc2c17 181 device_scan_time = us_ticker_read();
arch 11:c8cbc4bc2c17 182 LOG("scan device @ %d\r\n", device_scan_time);
rgrover1 0:415d7f24cb91 183
arch 11:c8cbc4bc2c17 184 {
arch 11:c8cbc4bc2c17 185 int wait_time_us = 0;
arch 11:c8cbc4bc2c17 186 while (current_test_status == 3 && wait_time_us < 10000000) {
arch 11:c8cbc4bc2c17 187 wait_us(1);
arch 11:c8cbc4bc2c17 188 wait_time_us++;
arch 11:c8cbc4bc2c17 189 }
arch 11:c8cbc4bc2c17 190
arch 11:c8cbc4bc2c17 191 if (current_test_status == 0) {
arch 11:c8cbc4bc2c17 192 LOG("from scan to connected: %d", device_connected_time - device_scan_time);
arch 11:c8cbc4bc2c17 193 } else if (current_test_status == 3) {
arch 12:c4090cb58976 194 test_output_result(3);
arch 11:c8cbc4bc2c17 195 }
arch 11:c8cbc4bc2c17 196 }
arch 11:c8cbc4bc2c17 197 }
arch 11:c8cbc4bc2c17 198
arch 11:c8cbc4bc2c17 199 /* setup advertising */
arch 11:c8cbc4bc2c17 200 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
arch 11:c8cbc4bc2c17 201 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
arch 11:c8cbc4bc2c17 202 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
arch 11:c8cbc4bc2c17 203 (const uint8_t *)"BLE UART", sizeof("BLE UART") - 1);
arch 11:c8cbc4bc2c17 204 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
arch 11:c8cbc4bc2c17 205 (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
arch 11:c8cbc4bc2c17 206
arch 11:c8cbc4bc2c17 207 bleuart = new UARTService(ble);
arch 11:c8cbc4bc2c17 208 DFUService *dfu = new DFUService(ble);
arch 11:c8cbc4bc2c17 209
arch 11:c8cbc4bc2c17 210 ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
arch 11:c8cbc4bc2c17 211 ble.startAdvertising();
rgrover1 0:415d7f24cb91 212
rgrover1 0:415d7f24cb91 213 while (true) {
arch 11:c8cbc4bc2c17 214 if (bleIsConnected) {
arch 11:c8cbc4bc2c17 215 uint32_t timeout = 1000;
arch 11:c8cbc4bc2c17 216 while (timeout) {
arch 11:c8cbc4bc2c17 217 timeout--;
arch 11:c8cbc4bc2c17 218 if (uart->readable()) {
arch 11:c8cbc4bc2c17 219 uartRxBuffer.put((char)uart->getc());
arch 11:c8cbc4bc2c17 220 timeout = 1000;
arch 11:c8cbc4bc2c17 221 }
arch 11:c8cbc4bc2c17 222 }
arch 11:c8cbc4bc2c17 223
arch 11:c8cbc4bc2c17 224 if (bleIsConnected && bleTxFlag == 0 && uartRxBuffer.available()) {
arch 11:c8cbc4bc2c17 225 uart2ble();
arch 11:c8cbc4bc2c17 226 bleTxFlag = 1;
arch 11:c8cbc4bc2c17 227 }
arch 11:c8cbc4bc2c17 228 } else {
arch 11:c8cbc4bc2c17 229 ble.waitForEvent();
rgrover1 0:415d7f24cb91 230 }
rgrover1 0:415d7f24cb91 231 }
rgrover1 0:415d7f24cb91 232 }
arch 11:c8cbc4bc2c17 233
arch 11:c8cbc4bc2c17 234 extern "C" void HardFault_Handler()
arch 11:c8cbc4bc2c17 235 {
arch 11:c8cbc4bc2c17 236 NVIC_SystemReset();
arch 11:c8cbc4bc2c17 237 }