Exercise 6 BLE UART

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 mbed

Fork of Amaldi_6_BLE_UART_IDB0XA1 by Amaldi

Committer:
waby38
Date:
Tue Apr 25 15:58:11 2017 +0000
Revision:
9:46f0c7908f89
Parent:
7:8490fe113598
Child:
8:60033323cbcb
UART BLE implementation on X-NUCLEO-IDB0XA1
; Device is bounded when LED2 is blinking
; Com RX/TX on STLINK com @9600 baud
; Android phone can use nRF UART/UART-BLE app or appinventor UART-BLE
; Without BLE_UART_IDB0XA1 lib modif

Who changed what in which revision?

UserRevisionLine numberNew contents of line
apalmieri 0:aae2d6c2a9eb 1 /* mbed Microcontroller Library
apalmieri 0:aae2d6c2a9eb 2 * Copyright (c) 2006-2013 ARM Limited
apalmieri 0:aae2d6c2a9eb 3 *
apalmieri 0:aae2d6c2a9eb 4 * Licensed under the Apache License, Version 2.0 (the "License");
apalmieri 0:aae2d6c2a9eb 5 * you may not use this file except in compliance with the License.
apalmieri 0:aae2d6c2a9eb 6 * You may obtain a copy of the License at
apalmieri 0:aae2d6c2a9eb 7 *
apalmieri 0:aae2d6c2a9eb 8 * http://www.apache.org/licenses/LICENSE-2.0
apalmieri 0:aae2d6c2a9eb 9 *
apalmieri 0:aae2d6c2a9eb 10 * Unless required by applicable law or agreed to in writing, software
apalmieri 0:aae2d6c2a9eb 11 * distributed under the License is distributed on an "AS IS" BASIS,
apalmieri 0:aae2d6c2a9eb 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
apalmieri 0:aae2d6c2a9eb 13 * See the License for the specific language governing permissions and
apalmieri 0:aae2d6c2a9eb 14 * limitations under the License.
apalmieri 0:aae2d6c2a9eb 15 */
apalmieri 0:aae2d6c2a9eb 16
apalmieri 0:aae2d6c2a9eb 17 #include "mbed.h"
apalmieri 0:aae2d6c2a9eb 18 #include "ble/BLE.h"
waby38 7:8490fe113598 19 #include "ble/services/UARTService.h"
waby38 7:8490fe113598 20 #include "Serial.h"
waby38 7:8490fe113598 21
waby38 7:8490fe113598 22 #define UART_BUFFER (UARTService::BLE_UART_SERVICE_MAX_DATA_LEN*10)
apalmieri 0:aae2d6c2a9eb 23
waby38 7:8490fe113598 24 const static char DEVICE_NAME[] = "UART";
waby38 7:8490fe113598 25 UARTService *uartServicePtr;
waby38 7:8490fe113598 26 static uint8_t uartBuff[UART_BUFFER];
waby38 7:8490fe113598 27 static uint8_t uartBuffPos=0;
apalmieri 0:aae2d6c2a9eb 28
waby38 7:8490fe113598 29 void onBleError(ble_error_t error);
waby38 7:8490fe113598 30
waby38 7:8490fe113598 31 DigitalOut led1(LED1);
waby38 7:8490fe113598 32 Serial uart1(USBTX,USBRX);
waby38 7:8490fe113598 33 Ticker ticker;
apalmieri 0:aae2d6c2a9eb 34
waby38 7:8490fe113598 35 #define DEBUG uart1.printf
waby38 7:8490fe113598 36
waby38 7:8490fe113598 37 /* Ticker */
waby38 7:8490fe113598 38 void periodicCallback(void)
apalmieri 0:aae2d6c2a9eb 39 {
waby38 7:8490fe113598 40 led1 = !led1;
apalmieri 0:aae2d6c2a9eb 41 }
apalmieri 0:aae2d6c2a9eb 42
waby38 7:8490fe113598 43 /* UART */
waby38 7:8490fe113598 44 void uartRx(void)
waby38 7:8490fe113598 45 {
waby38 7:8490fe113598 46 if(uart1.readable()){
waby38 7:8490fe113598 47 uartBuff[uartBuffPos] = uart1.getc();
waby38 7:8490fe113598 48 if((uartBuff[uartBuffPos] == '\r') || (uartBuff[uartBuffPos] == '\n') || (uartBuffPos >= UART_BUFFER)) {
waby38 7:8490fe113598 49 uartBuff[uartBuffPos] = '\0';
waby38 7:8490fe113598 50 /* We are sending the whole string even if less than BLE_UART_SERVICE_MAX_DATA_LEN otherwise we need to wait */
waby38 7:8490fe113598 51 uartServicePtr->write(uartBuff, (uartBuffPos/UARTService::BLE_UART_SERVICE_MAX_DATA_LEN +1) * UARTService::BLE_UART_SERVICE_MAX_DATA_LEN);
waby38 7:8490fe113598 52 DEBUG("TX : %s\r\n", uartBuff);
waby38 7:8490fe113598 53 memset(uartBuff, 0, UART_BUFFER);
waby38 7:8490fe113598 54 uartBuffPos = 0;
waby38 7:8490fe113598 55 }
waby38 7:8490fe113598 56 else
waby38 7:8490fe113598 57 uartBuffPos++;
apalmieri 0:aae2d6c2a9eb 58 }
apalmieri 0:aae2d6c2a9eb 59 }
apalmieri 0:aae2d6c2a9eb 60
waby38 7:8490fe113598 61
waby38 7:8490fe113598 62 /* BLE */
waby38 7:8490fe113598 63 void BleConnectionCallback(const Gap::ConnectionCallbackParams_t *params) {
waby38 7:8490fe113598 64 DEBUG("BLE Client Connected!\n\r");
waby38 7:8490fe113598 65 DEBUG("Please type a string and press return\r\n");
waby38 7:8490fe113598 66
waby38 7:8490fe113598 67 ticker.attach(periodicCallback, 1);
waby38 7:8490fe113598 68 }
waby38 7:8490fe113598 69
waby38 7:8490fe113598 70 void BleDisconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
waby38 7:8490fe113598 71 {
waby38 7:8490fe113598 72 (void)params;
waby38 7:8490fe113598 73 DEBUG("BLE Client Disconnected!\r\n");
waby38 7:8490fe113598 74 ticker.detach();
waby38 7:8490fe113598 75 BLE::Instance().gap().startAdvertising(); // restart advertising
waby38 7:8490fe113598 76 led1=0;
waby38 7:8490fe113598 77 }
waby38 7:8490fe113598 78
waby38 7:8490fe113598 79 void BleOnDataWrittenCallback(const GattWriteCallbackParams *params) {
waby38 7:8490fe113598 80 if (params->handle == uartServicePtr->getTXCharacteristicHandle()){
waby38 7:8490fe113598 81 DEBUG("RX: %s\r\n", params->data);
waby38 7:8490fe113598 82 }
waby38 7:8490fe113598 83 }
waby38 7:8490fe113598 84
waby38 7:8490fe113598 85 void onBleError(ble_error_t error) {
waby38 7:8490fe113598 86 DEBUG("BLE Error: %d\r\n");
waby38 7:8490fe113598 87 /* Handle error now */
apalmieri 0:aae2d6c2a9eb 88 }
apalmieri 0:aae2d6c2a9eb 89
apalmieri 0:aae2d6c2a9eb 90 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
apalmieri 0:aae2d6c2a9eb 91 {
apalmieri 0:aae2d6c2a9eb 92 BLE& ble = params->ble;
apalmieri 0:aae2d6c2a9eb 93 ble_error_t error = params->error;
apalmieri 0:aae2d6c2a9eb 94
apalmieri 0:aae2d6c2a9eb 95 if (error != BLE_ERROR_NONE) {
apalmieri 0:aae2d6c2a9eb 96 /* In case of error, forward the error handling to onBleInitError */
waby38 7:8490fe113598 97 onBleError(error);
apalmieri 0:aae2d6c2a9eb 98 return;
apalmieri 0:aae2d6c2a9eb 99 }
apalmieri 0:aae2d6c2a9eb 100
apalmieri 0:aae2d6c2a9eb 101 /* Ensure that it is the default instance of BLE */
apalmieri 0:aae2d6c2a9eb 102 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
apalmieri 0:aae2d6c2a9eb 103 return;
apalmieri 0:aae2d6c2a9eb 104 }
apalmieri 0:aae2d6c2a9eb 105
waby38 7:8490fe113598 106 ble.gap().onConnection(BleConnectionCallback);
waby38 7:8490fe113598 107 ble.gap().onDisconnection(BleDisconnectionCallback);
waby38 7:8490fe113598 108 ble.gattServer().onDataWritten(BleOnDataWrittenCallback);
apalmieri 0:aae2d6c2a9eb 109
waby38 7:8490fe113598 110 DEBUG("BLE UARTService: ");
waby38 7:8490fe113598 111 /* Setup primary service. */
waby38 7:8490fe113598 112 UARTService uartService(ble);
waby38 7:8490fe113598 113 uartServicePtr = &uartService;
waby38 7:8490fe113598 114 DEBUG("Started\r\n");
apalmieri 0:aae2d6c2a9eb 115
apalmieri 0:aae2d6c2a9eb 116 /* setup advertising */
apalmieri 0:aae2d6c2a9eb 117 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
waby38 7:8490fe113598 118 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
apalmieri 0:aae2d6c2a9eb 119 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
apalmieri 0:aae2d6c2a9eb 120 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
waby38 7:8490fe113598 121 ble.gap().setAdvertisingInterval(500); /* 500ms. */
apalmieri 0:aae2d6c2a9eb 122 ble.gap().startAdvertising();
apalmieri 0:aae2d6c2a9eb 123
apalmieri 0:aae2d6c2a9eb 124 while (true) {
apalmieri 0:aae2d6c2a9eb 125 ble.waitForEvent();
apalmieri 0:aae2d6c2a9eb 126 }
apalmieri 0:aae2d6c2a9eb 127 }
apalmieri 0:aae2d6c2a9eb 128
apalmieri 0:aae2d6c2a9eb 129 int main(void)
apalmieri 0:aae2d6c2a9eb 130 {
waby38 7:8490fe113598 131 led1=0;
waby38 7:8490fe113598 132
waby38 7:8490fe113598 133 uart1.baud(9600);
waby38 7:8490fe113598 134 uart1.attach(uartRx,Serial::RxIrq);
apalmieri 0:aae2d6c2a9eb 135 BLE &ble = BLE::Instance();
apalmieri 0:aae2d6c2a9eb 136 ble.init(bleInitComplete);
apalmieri 0:aae2d6c2a9eb 137 }
apalmieri 0:aae2d6c2a9eb 138