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
Diff: main.cpp
- Revision:
- 11:c8cbc4bc2c17
- Parent:
- 10:507318f2afda
- Child:
- 12:c4090cb58976
diff -r 507318f2afda -r c8cbc4bc2c17 main.cpp --- a/main.cpp Tue Sep 29 11:52:34 2015 +0000 +++ b/main.cpp Tue Dec 08 06:02:25 2015 +0000 @@ -1,127 +1,229 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2015 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// nRF51822 lib revision 534 #include "mbed.h" #include "ble/BLE.h" #include "ble/DiscoveredCharacteristic.h" #include "ble/DiscoveredService.h" +#include "ble/services/UARTService.h" +#include "ble/services/DFUService.h" +#include "Buffer.h" + + +#define LOG(args...) // printf(args) + BLE ble; +UARTService *bleuart; -DigitalOut alivenessLED(LED1, 1); bool triggerLedCharacteristic = false; DiscoveredCharacteristic ledCharacteristic; - -void periodicCallback(void) { - alivenessLED = !alivenessLED; /* Do blinky on LED1 while we're waiting for BLE events */ -} +int saved_test_result = 0; +volatile int current_test_status = 1; +uint32_t device_scan_time = 0; +uint32_t device_found_time = 0; +uint32_t device_connected_time = 0; -void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) { - if (params->peerAddr[0] != 0x29) { /* !ALERT! Alter this filter to suit your device. */ - return; - } - printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n", - params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0], - params->rssi, params->isScanResponse, params->type); +int test_is_passed(); +int test_save_result(int result); +int test_check_io(); +int test_check_vcc(); +int test_output_result(int result); + +Serial *uart; +Buffer <char> uartRxBuffer(0x100); + +uint8_t bleIsConnected = 0; +uint8_t bleTxFlag = 0; - ble.gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL); -} +bool rxPayloadUpdated = false; +uint8_t rxPayload[20 + 1] = {0,}; +uint8_t txPayload[20 + 1] = {0,}; -void serviceDiscoveryCallback(const DiscoveredService *service) { - if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { - printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle()); +void uart2ble(void) +{ + uint16_t bytesToWrite = 0; + for (int i = 0; i < 20; i++) { + if (uartRxBuffer.available()) { + txPayload[bytesToWrite] = uartRxBuffer; + bytesToWrite++; + } + } + + if (bytesToWrite != 0) { + bleTxFlag = 1; + + ble.updateCharacteristicValue(bleuart->getRXCharacteristicHandle(), txPayload, bytesToWrite); } else { - printf("S UUID-"); - const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); - for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { - printf("%02x", longUUIDBytes[i]); - } - printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle()); + bleTxFlag = 0; } } -void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) { - printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); - if (characteristicP->getUUID().getShortUUID() == 0xa001) { /* !ALERT! Alter this filter to suit your device. */ - ledCharacteristic = *characteristicP; - triggerLedCharacteristic = true; +void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) +{ + if (params->peerAddr[0] != params->peerAddr[5]) { /* !ALERT! Alter this filter to suit your device. */ + return; } + device_found_time = us_ticker_read(); + + LOG("device found @ %d\r\n", device_found_time); + + LOG("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n", + params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0], + params->rssi, params->isScanResponse, params->type); + + ble.gap().connect(params->peerAddr, Gap::ADDR_TYPE_PUBLIC, NULL, NULL); } -void discoveryTerminationCallback(Gap::Handle_t connectionHandle) { - printf("terminated SD for handle %u\r\n", connectionHandle); -} -void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { +void connectionCallback(const Gap::ConnectionCallbackParams_t *params) +{ if (params->role == Gap::CENTRAL) { - ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); - ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, 0xa000, 0xa001); + device_connected_time = us_ticker_read(); + + LOG("device connected @ %d\r\n", device_connected_time); + if (current_test_status == 3) + { + current_test_status = 0; + test_save_result(0); + } + + } else { + LOG("connected\r\n"); + + bleIsConnected = 1; + bleTxFlag = 0; + uartRxBuffer.clear(); } } -void triggerToggledWrite(const GattReadCallbackParams *response) { - if (response->handle == ledCharacteristic.getValueHandle()) { -#if DUMP_READ_DATA - printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len); - for (unsigned index = 0; index < response->len; index++) { - printf("%c[%02x]", response->data[index], response->data[index]); +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) +{ + LOG("Disconnected!\n\r"); + LOG("Restarting the advertising process\n\r"); + + bleTxFlag = 0; + bleIsConnected = 0; + + ble.startAdvertising(); + +} + +void onDataWritten(const GattWriteCallbackParams *params) +{ + if ((bleuart != NULL) && (params->handle == bleuart->getTXCharacteristicHandle())) { + uint16_t bytesRead = params->len; + LOG("received %u bytes\n\r", bytesRead); + // ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead); + + for (int i = 0; i < bytesRead; i++) { + uart->putc(params->data[i]); } - printf("\r\n"); -#endif - - uint8_t toggledValue = response->data[0] ^ 0x1; - ledCharacteristic.write(1, &toggledValue); } } -void triggerRead(const GattWriteCallbackParams *response) { - if (response->handle == ledCharacteristic.getValueHandle()) { - ledCharacteristic.read(); - } +void onDataSent(unsigned count) +{ + LOG("onDataSent\r\n"); + + uart2ble(); } -void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { - printf("disconnected\r\n"); -} +int main(void) +{ + int io_status; + int vcc_status; + saved_test_result = test_is_passed(); + if (!saved_test_result) { + io_status = test_check_io(); + vcc_status = test_check_vcc(); + + if (io_status) { + test_output_result(1); + } else { + current_test_status = 2; + if (vcc_status) { + test_output_result(2); + } else { + current_test_status = 3; + } + } + + } else { + //test_output_result(0); + } + -int main(void) { - Ticker ticker; - ticker.attach(periodicCallback, 1); + uart = new Serial(p8, p7); + uart->baud(38400); ble.init(); ble.gap().onConnection(connectionCallback); ble.gap().onDisconnection(disconnectionCallback); + ble.onDataWritten(onDataWritten); + ble.onDataSent(onDataSent); - ble.gattClient().onDataRead(triggerToggledWrite); - ble.gattClient().onDataWrite(triggerRead); + if (!saved_test_result) { + LOG("io test %s\r\n", io_status ? "failed" : "ok"); + LOG("vcc test %s\r\n", vcc_status ? "failed" : "ok"); + + LOG("enable ble centre role\r\n"); + + ble.gap().setScanParams(500, 400); + ble.gap().startScan(advertisementCallback); + device_scan_time = us_ticker_read(); + LOG("scan device @ %d\r\n", device_scan_time); - ble.gap().setScanParams(500, 400); - ble.gap().startScan(advertisementCallback); + { + int wait_time_us = 0; + while (current_test_status == 3 && wait_time_us < 10000000) { + wait_us(1); + wait_time_us++; + } + + if (current_test_status == 0) { + LOG("from scan to connected: %d", device_connected_time - device_scan_time); + } else if (current_test_status == 3) { + test_output_result(current_test_status); + } + } + } + + /* setup advertising */ + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, + (const uint8_t *)"BLE UART", sizeof("BLE UART") - 1); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, + (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); + + bleuart = new UARTService(ble); + DFUService *dfu = new DFUService(ble); + + ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ + ble.startAdvertising(); while (true) { - if (triggerLedCharacteristic && !ble.gattClient().isServiceDiscoveryActive()) { - triggerLedCharacteristic = false; - ledCharacteristic.read(); /* We could have issued this read just as easily from - * characteristicDiscoveryCallback(); but - * invoking it here demonstrates the use - * of isServiceDiscoveryActive() and also - * the fact that it is permitted to - * operate on application-local copies of - * DiscoveredCharacteristic. */ + if (bleIsConnected) { + uint32_t timeout = 1000; + while (timeout) { + timeout--; + if (uart->readable()) { + uartRxBuffer.put((char)uart->getc()); + timeout = 1000; + } + } + + if (bleIsConnected && bleTxFlag == 0 && uartRxBuffer.available()) { + uart2ble(); + bleTxFlag = 1; + } + } else { + ble.waitForEvent(); } - ble.waitForEvent(); } } + +extern "C" void HardFault_Handler() +{ + NVIC_SystemReset(); +}