mbed OS V5 BLE UARTService to USB/UART PassThru Example
Moxon Design : mbed OS V5 BLE UartService to USBUART passthru example
This example will advertise on BLE as "BLART" and allow BLE serial echo to the USB Serial port. Open a Bluetooth terminal application, like Nordic "nRF UART" and connect to "BLART", open a terminal emulator program, like "TeraTERM", and connect to the USB COM Port (like JLink CDC UART Port), and echo characters back and forth. Set UART_LoopBack = 1 for local loopback (e.g. BLE to BLE, USB-UART to USB-UART)
main.cpp
- Committer:
- moxondesign
- Date:
- 2017-04-29
- Revision:
- 2:3e203cc2a88f
- Parent:
- 1:5b50f5283781
File content as of revision 2:3e203cc2a88f:
/* mbed BLE Library - USB/UART Serial Pass-thru Example
*
* author : Moxon Design
* date : 4/27/2017
* platforms : Rigado BLE-350/300, Nordic rRF52-DK, rRF51-DK
* requires : mBed Platform Version 5+
* Overview:
*
* Employs the mBed platform ble/services/UARTService for UART emulation,
* as well as exposing the phyical UART device connected to the USB host,
* providing a transparent bridge between the two interfaces. By default,
* Serial dev(USBTX, USBRX);
*
* Set "UART_LoopBack" to enable local loopback test instead of pass-thru.
*
* Notes :
* 1) Advertises as "BLART" for BLe-usbUART
* 2) ble/services/UARTService is 20 byte max packets or about 4800 Baud (be patient)
* 3) transparent bridge
*
* License :
*
* 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.
*/
/* mbed platform defines */
#include "mbed.h"
#include "ble/BLE.h"
#include "ble/services/UARTService.h"
/* got debug? */
/* Set this if you need debug messages on the console */
/* Negative impact on code-size and power consumption */
#define DEBUG_OUTPUT 0
#if DEBUG_OUTPUT
#define DEBUG(...) { printf(__VA_ARGS__); }
#else
#define DEBUG(...) /* no output mapped */
#endif
/* instantiate BLE services and softUART service */
BLEDevice ble;
UARTService *uartServicePtr;
int UART_LoopBack = 0;
/* instantiate hardware UART devices */
/* devicename(TXD, RXD); */
/* for "JLink CDC UART Port" use the define below : */
/* Serial dev(USBTX, USBRX); */
/* otherwise use the hardware UART on 0.12 & 0.11 */
/* (a.k.a. d1 & D1 in Arduino parlance... */
//Serial dev(P0_12, P0_11);
Serial dev(USBTX, USBRX);
static uint8_t rx_buf[32];
static uint8_t rx_len=0;
int tx_buf;
static uint8_t tx_len=0;
/* define some blinky LED fun */
DigitalOut led1(LED1);
//DigitalOut led2(LED2);
//DigitalOut led3(LED3);
//DigitalOut led4(LED4);
void theBLEdisconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
#if DEBUG_OUTPUT
DEBUG("Disconnected!\n\r");
DEBUG("Restarting the advertising process\n\r");
#endif
ble.startAdvertising();
}
void theBLEonDataWritten(const GattWriteCallbackParams *params)
{
if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
uint16_t bytesRead = params->len;
uint8_t byteCnt;
#if DEBUG_OUTPUT
DEBUG("BLART BLE received %u bytes\n\r", bytesRead);
#endif
if (UART_LoopBack == 0) {
/* pass thru BLE UART data to UART1 */
for (byteCnt = 0; byteCnt < bytesRead; byteCnt++) {
dev.putc(params->data[byteCnt]);
}
} else {
/* otherwise, loopback BLE UART data to itself */
ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
}
}
}
void theUARTonDataWritten(void) {
while(dev.readable())
{
rx_buf[rx_len++] = dev.getc();
#if DEBUG_OUTPUT
DEBUG("BLART BLE received %u \n\r", rx_buf[rx_len]);
#endif
if (UART_LoopBack == 0) {
ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), rx_buf, rx_len);
rx_len = 0;
} else {
for (tx_len = 0; tx_len < rx_len; tx_len++) {
tx_buf = rx_buf[tx_len];
dev.putc(tx_buf);
}
rx_len = 0;
}
}
}
void theTickCallback(void)
{
/* toggle the LED each timer tick (1 sec) */
led1 = !led1;
}
int main(void)
{
/* set up a 1 sec timer to toggle the LED */
led1 = 1;
Ticker ticker;
ticker.attach(theTickCallback, 1);
/* attach the hardwate UART1 data received callback */
dev.attach( &theUARTonDataWritten , dev.RxIrq);
/* initialze the BLE services */
#if DEBUG_OUTPUT
DEBUG("Initialising the nRF5x\n\r");
#endif
ble.init();
ble.onDisconnection(theBLEdisconnectionCallback);
ble.onDataWritten(theBLEonDataWritten);
/* setup the BLE advertising */
ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
/* my names "BLART", what's yours? */
#if DEBUG_OUTPUT
DEBUG("Advertising nRF5x as BLART i.e. BLe-uART\n\r");
#endif
ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
(const uint8_t *)"BLART", sizeof("BLART") - 1);
ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
(const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
/* Advertising Rate at 1000ms, a multiple of the 0.625ms base timer */
ble.setAdvertisingInterval(1000);
ble.startAdvertising();
/* start the BLE UARTServices */
UARTService uartService(ble);
uartServicePtr = &uartService;
/* start the hardware UART1 */
//uart1.printf("Hello! My name is BLART, what's yours?\n");
/* main loop */
while (true) {
/* call wait to give other threads a chance to run */
ble.waitForEvent();
}
}
Thomas Moxon