BLE to UART

Dependencies:   BLE_API Buffer mbed nRF51822

Fork of BLE_LoopbackUART by Bluetooth Low Energy

Committer:
yihui
Date:
Fri May 22 07:23:32 2015 +0000
Revision:
12:f86bdebbebe8
Parent:
10:633cec718bf4
basic BLE2UART function

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 0:e910d9bb040f 1 /* mbed Microcontroller Library
yihui 0:e910d9bb040f 2 * Copyright (c) 2006-2013 ARM Limited
yihui 0:e910d9bb040f 3 *
yihui 0:e910d9bb040f 4 * Licensed under the Apache License, Version 2.0 (the "License");
yihui 0:e910d9bb040f 5 * you may not use this file except in compliance with the License.
yihui 0:e910d9bb040f 6 * You may obtain a copy of the License at
yihui 0:e910d9bb040f 7 *
yihui 0:e910d9bb040f 8 * http://www.apache.org/licenses/LICENSE-2.0
yihui 0:e910d9bb040f 9 *
yihui 0:e910d9bb040f 10 * Unless required by applicable law or agreed to in writing, software
yihui 0:e910d9bb040f 11 * distributed under the License is distributed on an "AS IS" BASIS,
yihui 0:e910d9bb040f 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
yihui 0:e910d9bb040f 13 * See the License for the specific language governing permissions and
yihui 0:e910d9bb040f 14 * limitations under the License.
yihui 0:e910d9bb040f 15 */
yihui 0:e910d9bb040f 16
yihui 0:e910d9bb040f 17 #include "mbed.h"
Rohit Grover 2:e060367b9024 18 #include "BLEDevice.h"
rgrover1 6:e0fc9072e853 19 #include "UARTService.h"
yihui 12:f86bdebbebe8 20 #include "DFUService.h"
yihui 12:f86bdebbebe8 21 #include "Buffer.h"
yihui 0:e910d9bb040f 22
rgrover1 6:e0fc9072e853 23 #define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console;
Rohit Grover 2:e060367b9024 24 * it will have an impact on code-size and power consumption. */
yihui 0:e910d9bb040f 25
Rohit Grover 2:e060367b9024 26 #if NEED_CONSOLE_OUTPUT
rgrover1 6:e0fc9072e853 27 #define DEBUG(...) { printf(__VA_ARGS__); }
yihui 0:e910d9bb040f 28 #else
Rohit Grover 2:e060367b9024 29 #define DEBUG(...) /* nothing */
Rohit Grover 2:e060367b9024 30 #endif /* #if NEED_CONSOLE_OUTPUT */
yihui 0:e910d9bb040f 31
yihui 12:f86bdebbebe8 32 Buffer <char> uartRxBuffer(0x100);
yihui 12:f86bdebbebe8 33 //Serial uart(p8, p7);
yihui 12:f86bdebbebe8 34 Serial uart(USBTX, USBRX);
yihui 12:f86bdebbebe8 35
Rohit Grover 2:e060367b9024 36 BLEDevice ble;
yihui 12:f86bdebbebe8 37 DigitalOut led1(p28);
yihui 0:e910d9bb040f 38
rgrover1 6:e0fc9072e853 39 UARTService *uartServicePtr;
yihui 0:e910d9bb040f 40
yihui 12:f86bdebbebe8 41 uint8_t bleIsConnected = 0;
yihui 12:f86bdebbebe8 42 uint8_t bleTxFlag = 0;
yihui 12:f86bdebbebe8 43
yihui 12:f86bdebbebe8 44 bool rxPayloadUpdated = false;
yihui 12:f86bdebbebe8 45 uint8_t rxPayload[20 + 1] = {0,};
yihui 12:f86bdebbebe8 46 uint8_t txPayload[20 + 1] = {0,};
yihui 12:f86bdebbebe8 47
yihui 12:f86bdebbebe8 48 void uart2ble(void)
yihui 12:f86bdebbebe8 49 {
yihui 12:f86bdebbebe8 50 uint16_t bytesToWrite = 0;
yihui 12:f86bdebbebe8 51 for (int i = 0; i < 20; i++) {
yihui 12:f86bdebbebe8 52 if (uartRxBuffer.available()) {
yihui 12:f86bdebbebe8 53 txPayload[bytesToWrite] = uartRxBuffer;
yihui 12:f86bdebbebe8 54 bytesToWrite++;
yihui 12:f86bdebbebe8 55 }
yihui 12:f86bdebbebe8 56 }
yihui 12:f86bdebbebe8 57
yihui 12:f86bdebbebe8 58 if (bytesToWrite != 0) {
yihui 12:f86bdebbebe8 59 bleTxFlag = 1;
yihui 12:f86bdebbebe8 60
yihui 12:f86bdebbebe8 61 ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), txPayload, bytesToWrite);
yihui 12:f86bdebbebe8 62 } else {
yihui 12:f86bdebbebe8 63 bleTxFlag = 0;
yihui 12:f86bdebbebe8 64 }
yihui 12:f86bdebbebe8 65 }
yihui 12:f86bdebbebe8 66
yihui 12:f86bdebbebe8 67 void resetToRunBootloader()
yihui 12:f86bdebbebe8 68 {
yihui 12:f86bdebbebe8 69 DEBUG("Reset to run bootloader\r\n");
yihui 12:f86bdebbebe8 70 NRF_POWER->GPREGRET = 0x02;
yihui 12:f86bdebbebe8 71 NVIC_SystemReset();
yihui 12:f86bdebbebe8 72 }
yihui 12:f86bdebbebe8 73
yihui 12:f86bdebbebe8 74 void connectionCallback(Gap::Handle_t, Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr, const Gap::ConnectionParams_t *)
yihui 12:f86bdebbebe8 75 {
yihui 12:f86bdebbebe8 76 DEBUG("Connected\r\n");
yihui 12:f86bdebbebe8 77 bleIsConnected = 1;
yihui 12:f86bdebbebe8 78 bleTxFlag = 0;
yihui 12:f86bdebbebe8 79 }
yihui 12:f86bdebbebe8 80
rgrover1 5:4bc41267a03a 81 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
yihui 0:e910d9bb040f 82 {
Rohit Grover 2:e060367b9024 83 DEBUG("Disconnected!\n\r");
Rohit Grover 2:e060367b9024 84 DEBUG("Restarting the advertising process\n\r");
yihui 12:f86bdebbebe8 85
yihui 12:f86bdebbebe8 86 bleTxFlag = 0;
yihui 12:f86bdebbebe8 87 bleIsConnected = 0;
yihui 12:f86bdebbebe8 88
Rohit Grover 2:e060367b9024 89 ble.startAdvertising();
Rohit Grover 2:e060367b9024 90 }
yihui 0:e910d9bb040f 91
rgrover1 6:e0fc9072e853 92 void onDataWritten(const GattCharacteristicWriteCBParams *params)
yihui 0:e910d9bb040f 93 {
rgrover1 6:e0fc9072e853 94 if ((uartServicePtr != NULL) && (params->charHandle == uartServicePtr->getTXCharacteristicHandle())) {
rgrover1 5:4bc41267a03a 95 uint16_t bytesRead = params->len;
rgrover1 5:4bc41267a03a 96 DEBUG("received %u bytes\n\r", bytesRead);
yihui 12:f86bdebbebe8 97 // ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
yihui 12:f86bdebbebe8 98
yihui 12:f86bdebbebe8 99 for (int i = 0; i < bytesRead; i++) {
yihui 12:f86bdebbebe8 100 uart.putc(params->data[i]);
yihui 12:f86bdebbebe8 101 }
yihui 0:e910d9bb040f 102 }
Rohit Grover 2:e060367b9024 103 }
yihui 0:e910d9bb040f 104
yihui 12:f86bdebbebe8 105 void onDataSent(unsigned count)
yihui 12:f86bdebbebe8 106 {
yihui 12:f86bdebbebe8 107 DEBUG("onDataSent\r\n");
yihui 12:f86bdebbebe8 108
yihui 12:f86bdebbebe8 109 uart2ble();
yihui 12:f86bdebbebe8 110 }
yihui 12:f86bdebbebe8 111
Rohit Grover 2:e060367b9024 112 void periodicCallback(void)
Rohit Grover 2:e060367b9024 113 {
rgrover1 6:e0fc9072e853 114 led1 = !led1;
Rohit Grover 2:e060367b9024 115 }
yihui 0:e910d9bb040f 116
yihui 0:e910d9bb040f 117 int main(void)
yihui 0:e910d9bb040f 118 {
Rohit Grover 2:e060367b9024 119 led1 = 1;
Rohit Grover 2:e060367b9024 120 Ticker ticker;
yihui 12:f86bdebbebe8 121 ticker.attach(periodicCallback, 0.01);
yihui 0:e910d9bb040f 122
Rohit Grover 2:e060367b9024 123 DEBUG("Initialising the nRF51822\n\r");
Rohit Grover 2:e060367b9024 124 ble.init();
yihui 12:f86bdebbebe8 125 ble.onConnection(connectionCallback);
Rohit Grover 2:e060367b9024 126 ble.onDisconnection(disconnectionCallback);
Rohit Grover 2:e060367b9024 127 ble.onDataWritten(onDataWritten);
yihui 12:f86bdebbebe8 128 ble.onDataSent(onDataSent);
yihui 0:e910d9bb040f 129
Rohit Grover 2:e060367b9024 130 /* setup advertising */
Rohit Grover 2:e060367b9024 131 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
Rohit Grover 2:e060367b9024 132 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
Rohit Grover 2:e060367b9024 133 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
rgrover1 6:e0fc9072e853 134 (const uint8_t *)"BLE UART", sizeof("BLE UART") - 1);
Rohit Grover 2:e060367b9024 135 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
rgrover1 6:e0fc9072e853 136 (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
yihui 0:e910d9bb040f 137
rgrover1 10:633cec718bf4 138 ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000));
Rohit Grover 2:e060367b9024 139 ble.startAdvertising();
yihui 0:e910d9bb040f 140
yihui 12:f86bdebbebe8 141 DFUService dfuService(ble);
rgrover1 6:e0fc9072e853 142 UARTService uartService(ble);
rgrover1 6:e0fc9072e853 143 uartServicePtr = &uartService;
yihui 0:e910d9bb040f 144
Rohit Grover 2:e060367b9024 145 while (true) {
yihui 12:f86bdebbebe8 146 uint32_t timeout = 1000;
yihui 12:f86bdebbebe8 147 while (timeout) {
yihui 12:f86bdebbebe8 148 timeout--;
yihui 12:f86bdebbebe8 149 if (uart.readable()) {
yihui 12:f86bdebbebe8 150 uartRxBuffer.put((char)uart.getc());
yihui 12:f86bdebbebe8 151 timeout = 1000;
yihui 12:f86bdebbebe8 152 }
yihui 12:f86bdebbebe8 153 }
yihui 12:f86bdebbebe8 154
yihui 12:f86bdebbebe8 155 if (bleIsConnected && bleTxFlag == 0 && uartRxBuffer.available()) {
yihui 12:f86bdebbebe8 156 uart2ble();
yihui 12:f86bdebbebe8 157 bleTxFlag = 1;
yihui 12:f86bdebbebe8 158 }
yihui 0:e910d9bb040f 159 }
yihui 0:e910d9bb040f 160 }
yihui 12:f86bdebbebe8 161
yihui 12:f86bdebbebe8 162 extern "C" void HardFault_Handler()
yihui 12:f86bdebbebe8 163 {
yihui 12:f86bdebbebe8 164 NVIC_SystemReset();
yihui 12:f86bdebbebe8 165 }