Thomas Moxon / Mbed OS MoxDes-mbed-os-BLE-USB-passthru
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed BLE Library - USB/UART Serial Pass-thru Example
00002  *
00003  * author    : Moxon Design
00004  * date      : 4/27/2017
00005  * platforms : Rigado BLE-350/300, Nordic rRF52-DK, rRF51-DK
00006  * requires  : mBed Platform Version 5+
00007  
00008  * Overview: 
00009  * 
00010  * Employs the mBed platform ble/services/UARTService for UART emulation,
00011  * as well as exposing the phyical UART device connected to the USB host,
00012  * providing a transparent bridge between the two interfaces. By default, 
00013  * Serial dev(USBTX, USBRX);
00014  *
00015  * Set "UART_LoopBack" to enable local loopback test instead of pass-thru.
00016  * 
00017  * Notes : 
00018  * 1) Advertises as "BLART" for BLe-usbUART
00019  * 2) ble/services/UARTService is 20 byte max packets or about 4800 Baud (be patient)
00020  * 3) transparent bridge
00021  *
00022  * License :
00023  *
00024  * Licensed under the Apache License, Version 2.0 (the "License");
00025  * you may not use this file except in compliance with the License.
00026  * You may obtain a copy of the License at
00027  *
00028  *     http://www.apache.org/licenses/LICENSE-2.0
00029  *
00030  * Unless required by applicable law or agreed to in writing, software
00031  * distributed under the License is distributed on an "AS IS" BASIS,
00032  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00033  * See the License for the specific language governing permissions and
00034  * limitations under the License.
00035  */
00036  
00037 /* mbed platform defines */
00038 #include "mbed.h"
00039 #include "ble/BLE.h"
00040 #include "ble/services/UARTService.h"
00041 
00042 /* got debug? */
00043 /* Set this if you need debug messages on the console */
00044 /* Negative impact on code-size and power consumption */
00045 #define DEBUG_OUTPUT 0 
00046 #if DEBUG_OUTPUT
00047 #define DEBUG(...) { printf(__VA_ARGS__); }
00048 #else
00049 #define DEBUG(...) /* no output mapped */
00050 #endif
00051 
00052 /* instantiate BLE services and softUART service */
00053 BLEDevice  ble;
00054 UARTService *uartServicePtr;
00055 int UART_LoopBack = 0;
00056  
00057 /* instantiate hardware UART devices                */
00058 /* devicename(TXD, RXD);                            */
00059 /* for "JLink CDC UART Port" use the define below : */
00060 /* Serial dev(USBTX, USBRX);                      */
00061 /* otherwise use the hardware UART on 0.12 & 0.11   */
00062 /* (a.k.a. d1 & D1 in Arduino parlance...           */
00063  //Serial dev(P0_12, P0_11);
00064  Serial dev(USBTX, USBRX);
00065  static uint8_t rx_buf[32];
00066  static uint8_t rx_len=0;
00067  int tx_buf;
00068  static uint8_t tx_len=0;
00069 
00070 /* define some blinky LED fun */
00071 DigitalOut led1(LED1);
00072 //DigitalOut led2(LED2);
00073 //DigitalOut led3(LED3);
00074 //DigitalOut led4(LED4);
00075 
00076 void theBLEdisconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
00077 {
00078     #if DEBUG_OUTPUT
00079       DEBUG("Disconnected!\n\r");
00080       DEBUG("Restarting the advertising process\n\r");
00081     #endif
00082     ble.startAdvertising();
00083 }
00084 
00085 void theBLEonDataWritten(const GattWriteCallbackParams *params)
00086 {
00087     if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
00088         uint16_t bytesRead = params->len;
00089         uint8_t byteCnt;
00090         
00091         #if DEBUG_OUTPUT
00092           DEBUG("BLART BLE received %u bytes\n\r", bytesRead);
00093         #endif
00094         
00095         if (UART_LoopBack == 0) {
00096           /* pass thru BLE UART data to UART1 */
00097           for (byteCnt = 0; byteCnt < bytesRead; byteCnt++) {
00098               dev.putc(params->data[byteCnt]);
00099           } 
00100         } else {
00101           /* otherwise, loopback BLE UART data to itself */    
00102           ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
00103         }
00104     }
00105 }
00106 
00107 void theUARTonDataWritten(void) {
00108     while(dev.readable())    
00109     {
00110         rx_buf[rx_len++] = dev.getc();
00111         #if DEBUG_OUTPUT
00112           DEBUG("BLART BLE received %u \n\r", rx_buf[rx_len]);
00113         #endif    
00114              if (UART_LoopBack == 0) {
00115               ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), rx_buf, rx_len);
00116               rx_len = 0;
00117             } else {
00118                 for (tx_len = 0; tx_len < rx_len; tx_len++) {
00119                   tx_buf = rx_buf[tx_len];  
00120                   dev.putc(tx_buf);
00121                 }
00122                 rx_len = 0;
00123             } 
00124     }            
00125 }
00126 
00127 void theTickCallback(void)
00128 {
00129     /* toggle the LED each timer tick (1 sec) */
00130     led1 = !led1;
00131 }
00132 
00133 int main(void)
00134 {
00135     /* set up a 1 sec timer to toggle the LED */ 
00136     led1 = 1;
00137     Ticker ticker;
00138     ticker.attach(theTickCallback, 1);
00139 
00140     /* attach the hardwate UART1 data received callback */
00141     dev.attach( &theUARTonDataWritten , dev.RxIrq);
00142     
00143     /* initialze the BLE services */
00144     #if DEBUG_OUTPUT
00145       DEBUG("Initialising the nRF5x\n\r");
00146     #endif
00147     ble.init();
00148     ble.onDisconnection(theBLEdisconnectionCallback);
00149     ble.onDataWritten(theBLEonDataWritten);
00150 
00151     /* setup the BLE advertising */
00152     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
00153     ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00154     /* my names "BLART", what's yours? */
00155      #if DEBUG_OUTPUT
00156       DEBUG("Advertising nRF5x as BLART i.e. BLe-uART\n\r");
00157     #endif  
00158     ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
00159                                      (const uint8_t *)"BLART", sizeof("BLART") - 1);
00160     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
00161                                      (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
00162 
00163     /* Advertising Rate at 1000ms, a multiple of the 0.625ms base timer */
00164     ble.setAdvertisingInterval(1000); 
00165     ble.startAdvertising();
00166 
00167     /* start the BLE UARTServices */
00168     UARTService uartService(ble);
00169     uartServicePtr = &uartService;
00170 
00171     /* start the hardware UART1 */
00172     //uart1.printf("Hello! My name is BLART, what's yours?\n");
00173     
00174     /* main loop */
00175     while (true) {
00176         /* call wait to give other threads a chance to run */
00177         ble.waitForEvent();
00178     }
00179 }