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