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

main.cpp

Committer:
arch
Date:
2015-12-08
Revision:
12:c4090cb58976
Parent:
11:c8cbc4bc2c17

File content as of revision 12:c4090cb58976:

// 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;

bool triggerLedCharacteristic = false;
DiscoveredCharacteristic ledCharacteristic;
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;

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;

bool rxPayloadUpdated = false;
uint8_t rxPayload[20 + 1] = {0,};
uint8_t txPayload[20 + 1] = {0,};

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 {
        bleTxFlag = 0;
    }
}

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 connectionCallback(const Gap::ConnectionCallbackParams_t *params)
{
    if (params->role == Gap::CENTRAL) {
        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_output_result(0);
            test_save_result(0);
        }
        
    } else {
        LOG("connected\r\n");
        
        bleIsConnected = 1;
        bleTxFlag = 0;
        uartRxBuffer.clear();
    }
}

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]);
        }
    }
}

void onDataSent(unsigned count)
{
    LOG("onDataSent\r\n");

    uart2ble();
}

int main(void)
{
    int io_status;
    int vcc_status;
    
    saved_test_result = test_is_passed();
    if (!saved_test_result) {
        {
            uart = new Serial(p20, p21); // release USBTX and USBRX
            uart->baud(38400);
        }
        
        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);
        uart = new Serial(p8, p7);
        uart->baud(38400);
    }
    

    

    ble.init();
    ble.gap().onConnection(connectionCallback);
    ble.gap().onDisconnection(disconnectionCallback);
    ble.onDataWritten(onDataWritten);
    ble.onDataSent(onDataSent);

    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);

        {
            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(3);
            }
        }
    }
    
    /* 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 (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();
        }
    }
}

extern "C" void HardFault_Handler()
{
    NVIC_SystemReset();
}