this is a new program based on BLE_Uart_Peripheral. Change program name due to relation Client&Peripheral to Client&Server

Dependencies:   RingBuffer nRF51_Vdd nRF51_WakeUp

This is a BLE Server (Device) program for nRF51.
You can communicate with mbed BLE using "BLE_Uart_Client" program as follows.
/users/kenjiArai/code/BLE_Uart_Client/
Please refer following my notebook.
/users/kenjiArai/notebook/ble-client-and-peripheral-using-switch-sience-ty51/#

Committer:
kenjiArai
Date:
Sun Feb 11 02:04:59 2018 +0000
Revision:
8:dd23c6d67b58
Parent:
7:0d94f4cf2a69
use Mbed-os5 dedicated class "CircularBuffer"

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 1:9b27a9710d94 1 /* mbed Microcontroller Library
kenjiArai 1:9b27a9710d94 2 * Copyright (c) 2006-2013 ARM Limited
kenjiArai 1:9b27a9710d94 3 *
kenjiArai 1:9b27a9710d94 4 * Licensed under the Apache License, Version 2.0 (the "License");
kenjiArai 1:9b27a9710d94 5 * you may not use this file except in compliance with the License.
kenjiArai 1:9b27a9710d94 6 * You may obtain a copy of the License at
kenjiArai 1:9b27a9710d94 7 *
kenjiArai 1:9b27a9710d94 8 * http://www.apache.org/licenses/LICENSE-2.0
kenjiArai 1:9b27a9710d94 9 *
kenjiArai 1:9b27a9710d94 10 * Unless required by applicable law or agreed to in writing, software
kenjiArai 1:9b27a9710d94 11 * distributed under the License is distributed on an "AS IS" BASIS,
kenjiArai 1:9b27a9710d94 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kenjiArai 1:9b27a9710d94 13 * See the License for the specific language governing permissions and
kenjiArai 1:9b27a9710d94 14 * limitations under the License.
kenjiArai 1:9b27a9710d94 15 */
kenjiArai 1:9b27a9710d94 16
kenjiArai 1:9b27a9710d94 17 /*
kenjiArai 6:16e1f9d065a3 18 * ------- BLE Peripheral/Server UART function --------------------------------
kenjiArai 6:16e1f9d065a3 19 * communicate with BLE_UART_Client program
kenjiArai 1:9b27a9710d94 20 * --- Tested on Switch Science mbed TY51822r3 ---
kenjiArai 1:9b27a9710d94 21 *
kenjiArai 1:9b27a9710d94 22 * http://www.page.sannet.ne.jp/kenjia/index.html
kenjiArai 7:0d94f4cf2a69 23 * https://os.mbed.com/users/kenjiArai/
kenjiArai 1:9b27a9710d94 24 *
kenjiArai 1:9b27a9710d94 25 * Started: March 7th, 2016
kenjiArai 5:394920d6a82f 26 * Revised: June 13th, 2016
kenjiArai 7:0d94f4cf2a69 27 * Revised: Feburary 10th, 2018 Not set mac addr but use device name
kenjiArai 8:dd23c6d67b58 28 * Revised: Feburary 11th, 2018 use mbed-os5.7.4 with CircularBuffer
kenjiArai 1:9b27a9710d94 29 *
kenjiArai 1:9b27a9710d94 30 * Original program:
kenjiArai 1:9b27a9710d94 31 * BLE_LoopbackUART
kenjiArai 6:16e1f9d065a3 32 * https://developer.mbed.org/teams/Bluetooth-Low-Energy/
kenjiArai 6:16e1f9d065a3 33 * code/BLE_LoopbackUART/
kenjiArai 7:0d94f4cf2a69 34 * Reference program:
kenjiArai 7:0d94f4cf2a69 35 * BLE_Peripheral_test by noboru koshinaka
kenjiArai 7:0d94f4cf2a69 36 * https://os.mbed.com/users/noboruk/code/BLE_Peripheral_test/
kenjiArai 7:0d94f4cf2a69 37 * Tested Client Device:
kenjiArai 1:9b27a9710d94 38 * BLE_Uart_Client
kenjiArai 7:0d94f4cf2a69 39 * https://os.mbed.com/users/kenjiArai/code/BLE_Uart_Client/
kenjiArai 1:9b27a9710d94 40 */
kenjiArai 0:6b0eca2bcb7a 41
kenjiArai 6:16e1f9d065a3 42 // Include --------------------------------------------------------------------
kenjiArai 1:9b27a9710d94 43 #include "mbed.h"
kenjiArai 1:9b27a9710d94 44 #include "BLE.h"
kenjiArai 1:9b27a9710d94 45 #include "UARTService.h"
kenjiArai 1:9b27a9710d94 46 #include "nRF51_Vdd.h"
kenjiArai 1:9b27a9710d94 47 #include "nRF51_WakeUp.h"
kenjiArai 8:dd23c6d67b58 48 #include "CircularBuffer.h"
kenjiArai 6:16e1f9d065a3 49
kenjiArai 6:16e1f9d065a3 50 // Definition -----------------------------------------------------------------
kenjiArai 7:0d94f4cf2a69 51 //#define USE_MAC // if you use mac address, please define it
kenjiArai 7:0d94f4cf2a69 52
kenjiArai 6:16e1f9d065a3 53 #define NUM_ONCE 20
kenjiArai 6:16e1f9d065a3 54 #define BFSIZE (NUM_ONCE+4)
kenjiArai 1:9b27a9710d94 55
kenjiArai 6:16e1f9d065a3 56 // Please refer nRF51_WakeUP library
kenjiArai 7:0d94f4cf2a69 57 #define GOTO_SLEEP_MODE 0
kenjiArai 8:dd23c6d67b58 58 #if GOTO_SLEEP_MODE
kenjiArai 8:dd23c6d67b58 59 #warning "Make sure!! -> You need to connected P0_21(LED1) and P0_0"
kenjiArai 8:dd23c6d67b58 60 #endif
kenjiArai 7:0d94f4cf2a69 61
kenjiArai 6:16e1f9d065a3 62 //#define USE_DEBUG_MODE
kenjiArai 6:16e1f9d065a3 63 #ifdef USE_DEBUG_MODE
kenjiArai 1:9b27a9710d94 64 #define DEBUG(...) { printf(__VA_ARGS__); }
kenjiArai 1:9b27a9710d94 65 #else
kenjiArai 1:9b27a9710d94 66 #define DEBUG(...)
kenjiArai 1:9b27a9710d94 67 #endif
kenjiArai 1:9b27a9710d94 68
kenjiArai 6:16e1f9d065a3 69 // Object ---------------------------------------------------------------------
kenjiArai 7:0d94f4cf2a69 70 BLE& ble_uart = BLE::Instance();
kenjiArai 1:9b27a9710d94 71 DigitalOut connectedLED(LED2);
kenjiArai 1:9b27a9710d94 72 InterruptIn wake_up_sw(P0_1);
kenjiArai 8:dd23c6d67b58 73 nRF51_WakeUp wakeup(P0_21, P0_0);
kenjiArai 1:9b27a9710d94 74 nRF51_Vdd vdd(3.0f, 2.2f);
kenjiArai 6:16e1f9d065a3 75 Serial pc(USBTX, USBRX, 115200);
kenjiArai 7:0d94f4cf2a69 76 //Serial pc(P0_3, P0_1, 115200); // for another board
kenjiArai 1:9b27a9710d94 77 UARTService *uartServicePtr;
kenjiArai 1:9b27a9710d94 78 Ticker ticker;
kenjiArai 8:dd23c6d67b58 79 CircularBuffer<char, 1536> ser_bf;
kenjiArai 6:16e1f9d065a3 80 Thread tsk;
kenjiArai 6:16e1f9d065a3 81 Mutex bletx_mutex;
kenjiArai 1:9b27a9710d94 82
kenjiArai 6:16e1f9d065a3 83 // ROM / Constant data --------------------------------------------------------
kenjiArai 1:9b27a9710d94 84 #warning "You need to confirm your device name."
kenjiArai 7:0d94f4cf2a69 85 const static char DEVICE_NAME[] = "UART_PJL";
kenjiArai 1:9b27a9710d94 86
kenjiArai 6:16e1f9d065a3 87 // RAM ------------------------------------------------------------------------
kenjiArai 6:16e1f9d065a3 88 Gap::Address_t my_mac;
kenjiArai 6:16e1f9d065a3 89 uint8_t tx_buf[BFSIZE];
kenjiArai 6:16e1f9d065a3 90 uint8_t tx_len = 0;
kenjiArai 6:16e1f9d065a3 91 uint8_t rx_buf[BFSIZE];
kenjiArai 6:16e1f9d065a3 92 volatile bool trigger_transmit = false;
kenjiArai 6:16e1f9d065a3 93 volatile bool trigger_receive = false;
kenjiArai 6:16e1f9d065a3 94 volatile uint8_t command_continue = 0;
kenjiArai 6:16e1f9d065a3 95 uint16_t time_out_cntr = 3600;
kenjiArai 6:16e1f9d065a3 96 volatile bool time_out = false;
kenjiArai 6:16e1f9d065a3 97 uint32_t sleep_time = 30; // unit:second
kenjiArai 6:16e1f9d065a3 98 volatile bool rx_isr_busy = false;
kenjiArai 0:6b0eca2bcb7a 99
kenjiArai 6:16e1f9d065a3 100 // Function prototypes --------------------------------------------------------
kenjiArai 1:9b27a9710d94 101 // BLE
kenjiArai 6:16e1f9d065a3 102 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *);
kenjiArai 6:16e1f9d065a3 103 void onDataWritten_action(const GattWriteCallbackParams *);
kenjiArai 6:16e1f9d065a3 104 // Tasks
kenjiArai 6:16e1f9d065a3 105 void pc_ser_rx(void);
kenjiArai 6:16e1f9d065a3 106 void data_from_ble(void);
kenjiArai 6:16e1f9d065a3 107 void Update_Values(void);
kenjiArai 1:9b27a9710d94 108 // Application related
kenjiArai 6:16e1f9d065a3 109 void command(uint8_t *cmd);
kenjiArai 1:9b27a9710d94 110 void action_tx_help(void);
kenjiArai 1:9b27a9710d94 111 void action_tx_vdd(void);
kenjiArai 1:9b27a9710d94 112 void action_tx_temperature(void);
kenjiArai 6:16e1f9d065a3 113 void action_tx_wait_time(uint8_t *);
kenjiArai 6:16e1f9d065a3 114 void action_tx_quit(void);
kenjiArai 6:16e1f9d065a3 115 int xatoi (char **, int32_t *);
kenjiArai 6:16e1f9d065a3 116 void adjust_line(uint8_t *);
kenjiArai 1:9b27a9710d94 117 // Interrupt related
kenjiArai 1:9b27a9710d94 118 void interrupt_by_sw(void);
kenjiArai 1:9b27a9710d94 119 void serialRxCallback(void);
kenjiArai 6:16e1f9d065a3 120 void periodicCallback(void);
kenjiArai 1:9b27a9710d94 121
kenjiArai 6:16e1f9d065a3 122 //------------------------------------------------------------------------------
kenjiArai 1:9b27a9710d94 123 // Control Program
kenjiArai 6:16e1f9d065a3 124 //------------------------------------------------------------------------------
kenjiArai 6:16e1f9d065a3 125 int main(void)
kenjiArai 6:16e1f9d065a3 126 {
kenjiArai 1:9b27a9710d94 127 connectedLED = 0;
kenjiArai 1:9b27a9710d94 128 pc.attach(&serialRxCallback, Serial::RxIrq);
kenjiArai 1:9b27a9710d94 129 ticker.attach(periodicCallback, 1);
kenjiArai 6:16e1f9d065a3 130 tsk.start(pc_ser_rx);
kenjiArai 6:16e1f9d065a3 131 // clear terminal output
kenjiArai 7:0d94f4cf2a69 132 for (int k = 0; k < 3; k++) {
kenjiArai 7:0d94f4cf2a69 133 pc.printf("\r\n");
kenjiArai 7:0d94f4cf2a69 134 }
kenjiArai 7:0d94f4cf2a69 135 // opening message
kenjiArai 6:16e1f9d065a3 136 pc.printf("UART Communication / Server(Peripheral) side\r\n");
kenjiArai 6:16e1f9d065a3 137 pc.printf(" need Client module (run BLE_Uart_Client program)\r\n");
kenjiArai 1:9b27a9710d94 138 // Interrupt by switch
kenjiArai 1:9b27a9710d94 139 wake_up_sw.fall(&interrupt_by_sw);
kenjiArai 7:0d94f4cf2a69 140 ble_uart.init();
kenjiArai 2:2322afea6ecf 141 Gap::AddressType_t my_mac_type;
kenjiArai 7:0d94f4cf2a69 142 ble_uart.gap().getAddress(&my_mac_type, my_mac);
kenjiArai 6:16e1f9d065a3 143 DEBUG(
kenjiArai 2:2322afea6ecf 144 " my_MAC %02x:%02x:%02x:%02x:%02x:%02x (%s)\r\n",
kenjiArai 2:2322afea6ecf 145 my_mac[5], my_mac[4], my_mac[3], my_mac[2], my_mac[1], my_mac[0],
kenjiArai 2:2322afea6ecf 146 (my_mac_type == Gap::ADDR_TYPE_PUBLIC) ? "public" : "random"
kenjiArai 2:2322afea6ecf 147 );
kenjiArai 2:2322afea6ecf 148 pc.printf(
kenjiArai 7:0d94f4cf2a69 149 " My device name : %s\r\n", DEVICE_NAME);
kenjiArai 7:0d94f4cf2a69 150 pc.printf(
kenjiArai 7:0d94f4cf2a69 151 " My mac data %02x:%02x:%02x:%02x:%02x:%02x\r\n",
kenjiArai 7:0d94f4cf2a69 152 my_mac[5], my_mac[4], my_mac[3], my_mac[2], my_mac[1], my_mac[0]
kenjiArai 7:0d94f4cf2a69 153 );
kenjiArai 7:0d94f4cf2a69 154 #ifdef USE_MAC
kenjiArai 7:0d94f4cf2a69 155 pc.printf(
kenjiArai 7:0d94f4cf2a69 156 " mac_board_x = {0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x};\r\n",
kenjiArai 2:2322afea6ecf 157 my_mac[0], my_mac[1], my_mac[2], my_mac[3], my_mac[4], my_mac[5]
kenjiArai 2:2322afea6ecf 158 );
kenjiArai 6:16e1f9d065a3 159 pc.printf(
kenjiArai 7:0d94f4cf2a69 160 " Please write above data(mac_board_x line (x=0,1,2,...))\r\n");
kenjiArai 6:16e1f9d065a3 161 pc.printf(
kenjiArai 7:0d94f4cf2a69 162 " into Client/main.cpp [ROM / Constant data] area\r\n");
kenjiArai 7:0d94f4cf2a69 163 #endif
kenjiArai 7:0d94f4cf2a69 164 ble_uart.onDisconnection(disconnectionCallback);
kenjiArai 7:0d94f4cf2a69 165 ble_uart.onDataWritten(onDataWritten_action);
kenjiArai 1:9b27a9710d94 166 /* setup advertising */
kenjiArai 7:0d94f4cf2a69 167 ble_uart.accumulateAdvertisingPayload(
kenjiArai 7:0d94f4cf2a69 168 GapAdvertisingData::BREDR_NOT_SUPPORTED);
kenjiArai 7:0d94f4cf2a69 169 ble_uart.setAdvertisingType(
kenjiArai 7:0d94f4cf2a69 170 GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
kenjiArai 7:0d94f4cf2a69 171 ble_uart.accumulateAdvertisingPayload(
kenjiArai 3:fd5273a70b21 172 GapAdvertisingData::COMPLETE_LOCAL_NAME,
kenjiArai 3:fd5273a70b21 173 (const uint8_t *)DEVICE_NAME,
kenjiArai 3:fd5273a70b21 174 sizeof(DEVICE_NAME)
kenjiArai 3:fd5273a70b21 175 );
kenjiArai 7:0d94f4cf2a69 176 ble_uart.accumulateAdvertisingPayload(
kenjiArai 3:fd5273a70b21 177 GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
kenjiArai 3:fd5273a70b21 178 (const uint8_t *)UARTServiceUUID_reversed,
kenjiArai 7:0d94f4cf2a69 179 sizeof(UARTServiceUUID_reversed)
kenjiArai 3:fd5273a70b21 180 );
kenjiArai 1:9b27a9710d94 181 // Advertize Interval
kenjiArai 7:0d94f4cf2a69 182 ble_uart.setAdvertisingInterval(1000); /* 1000ms;in multiples of 0.625ms.*/
kenjiArai 1:9b27a9710d94 183 // Start
kenjiArai 7:0d94f4cf2a69 184 ble_uart.startAdvertising();
kenjiArai 7:0d94f4cf2a69 185 UARTService uartService(ble_uart);
kenjiArai 1:9b27a9710d94 186 uartServicePtr = &uartService;
kenjiArai 7:0d94f4cf2a69 187 while(true) {
kenjiArai 7:0d94f4cf2a69 188 if (time_out) {
kenjiArai 1:9b27a9710d94 189 #if GOTO_SLEEP_MODE
kenjiArai 5:394920d6a82f 190 wakeup.set_and_wait(sleep_time);
kenjiArai 7:0d94f4cf2a69 191 while(true) { // never come here but just in case
kenjiArai 1:9b27a9710d94 192 deepsleep();
kenjiArai 1:9b27a9710d94 193 }
kenjiArai 1:9b27a9710d94 194 #endif
kenjiArai 1:9b27a9710d94 195 }
kenjiArai 7:0d94f4cf2a69 196 if (trigger_transmit) {
kenjiArai 6:16e1f9d065a3 197 static uint8_t cmd_buf[BFSIZE];
kenjiArai 6:16e1f9d065a3 198 static volatile bool flag_continue = 0;
kenjiArai 1:9b27a9710d94 199 trigger_transmit = false;
kenjiArai 6:16e1f9d065a3 200 pc.printf((const char*)rx_buf);
kenjiArai 7:0d94f4cf2a69 201 if (flag_continue == true) {
kenjiArai 6:16e1f9d065a3 202 strcat((char *)cmd_buf, (char *)rx_buf);
kenjiArai 7:0d94f4cf2a69 203 if (strchr((const char*)cmd_buf,(int)'\r') == 0) {
kenjiArai 6:16e1f9d065a3 204 flag_continue = true;
kenjiArai 6:16e1f9d065a3 205 } else {
kenjiArai 6:16e1f9d065a3 206 command(cmd_buf);
kenjiArai 7:0d94f4cf2a69 207 for(uint8_t i = 0; i < BFSIZE; i++) {
kenjiArai 7:0d94f4cf2a69 208 cmd_buf[i] = 0;
kenjiArai 7:0d94f4cf2a69 209 }
kenjiArai 6:16e1f9d065a3 210 flag_continue = false;
kenjiArai 6:16e1f9d065a3 211 }
kenjiArai 6:16e1f9d065a3 212 }
kenjiArai 7:0d94f4cf2a69 213 if ((rx_buf[0] == '~')) {
kenjiArai 6:16e1f9d065a3 214 strcpy((char *)cmd_buf, (char *)rx_buf);
kenjiArai 7:0d94f4cf2a69 215 if (strchr((const char*)cmd_buf,(int)'\r') == 0) {
kenjiArai 6:16e1f9d065a3 216 flag_continue = true;
kenjiArai 6:16e1f9d065a3 217 } else {
kenjiArai 6:16e1f9d065a3 218 command(cmd_buf);
kenjiArai 7:0d94f4cf2a69 219 for(uint8_t i = 0; i < BFSIZE; i++) {
kenjiArai 7:0d94f4cf2a69 220 cmd_buf[i] = 0;
kenjiArai 7:0d94f4cf2a69 221 }
kenjiArai 7:0d94f4cf2a69 222 flag_continue = false;
kenjiArai 1:9b27a9710d94 223 }
kenjiArai 1:9b27a9710d94 224 }
kenjiArai 1:9b27a9710d94 225 }
kenjiArai 7:0d94f4cf2a69 226 ble_uart.waitForEvent();
kenjiArai 0:6b0eca2bcb7a 227 }
kenjiArai 0:6b0eca2bcb7a 228 }
kenjiArai 1:9b27a9710d94 229
kenjiArai 6:16e1f9d065a3 230 void command(uint8_t *cmd)
kenjiArai 6:16e1f9d065a3 231 {
kenjiArai 6:16e1f9d065a3 232 uint8_t *p = cmd;
kenjiArai 6:16e1f9d065a3 233
kenjiArai 7:0d94f4cf2a69 234 while(*p == ' ') {
kenjiArai 7:0d94f4cf2a69 235 ++p; // skip space
kenjiArai 7:0d94f4cf2a69 236 }
kenjiArai 7:0d94f4cf2a69 237 if (*p++ == '~') {
kenjiArai 7:0d94f4cf2a69 238 while(*p < '!') {
kenjiArai 7:0d94f4cf2a69 239 ++p; // skip space
kenjiArai 7:0d94f4cf2a69 240 }
kenjiArai 6:16e1f9d065a3 241 uint8_t c = *p;
kenjiArai 6:16e1f9d065a3 242 //pc.printf("c=%c\r\n", c);
kenjiArai 7:0d94f4cf2a69 243 switch (c) {
kenjiArai 6:16e1f9d065a3 244 case 'v':
kenjiArai 6:16e1f9d065a3 245 action_tx_vdd();
kenjiArai 6:16e1f9d065a3 246 break;
kenjiArai 6:16e1f9d065a3 247 case 't':
kenjiArai 6:16e1f9d065a3 248 action_tx_temperature();
kenjiArai 6:16e1f9d065a3 249 break;
kenjiArai 6:16e1f9d065a3 250 case 'q':
kenjiArai 6:16e1f9d065a3 251 action_tx_quit();
kenjiArai 6:16e1f9d065a3 252 break;
kenjiArai 6:16e1f9d065a3 253 case 'w':
kenjiArai 6:16e1f9d065a3 254 action_tx_wait_time(cmd);
kenjiArai 6:16e1f9d065a3 255 break;
kenjiArai 6:16e1f9d065a3 256 case 'h':
kenjiArai 6:16e1f9d065a3 257 case '?':
kenjiArai 6:16e1f9d065a3 258 action_tx_help();
kenjiArai 6:16e1f9d065a3 259 break;
kenjiArai 6:16e1f9d065a3 260 default:
kenjiArai 6:16e1f9d065a3 261 //pc.printf("\r\nStep(%u)\r\n", __LINE__);
kenjiArai 6:16e1f9d065a3 262 break;
kenjiArai 6:16e1f9d065a3 263 }
kenjiArai 1:9b27a9710d94 264 }
kenjiArai 6:16e1f9d065a3 265 }
kenjiArai 6:16e1f9d065a3 266
kenjiArai 6:16e1f9d065a3 267 void periodicCallback(void)
kenjiArai 6:16e1f9d065a3 268 {
kenjiArai 6:16e1f9d065a3 269 #if GOTO_SLEEP_MODE
kenjiArai 7:0d94f4cf2a69 270 if (--time_out_cntr == 0) {
kenjiArai 6:16e1f9d065a3 271 time_out = true;
kenjiArai 6:16e1f9d065a3 272 }
kenjiArai 6:16e1f9d065a3 273 #endif
kenjiArai 7:0d94f4cf2a69 274 if (rx_isr_busy == true) {
kenjiArai 6:16e1f9d065a3 275 rx_isr_busy = false;
kenjiArai 6:16e1f9d065a3 276 } else {
kenjiArai 6:16e1f9d065a3 277 tsk.signal_set(0x01);
kenjiArai 6:16e1f9d065a3 278 }
kenjiArai 6:16e1f9d065a3 279 }
kenjiArai 6:16e1f9d065a3 280
kenjiArai 6:16e1f9d065a3 281 void serialRxCallback()
kenjiArai 6:16e1f9d065a3 282 {
kenjiArai 8:dd23c6d67b58 283 ser_bf.push(pc.getc());
kenjiArai 6:16e1f9d065a3 284 rx_isr_busy = true;
kenjiArai 6:16e1f9d065a3 285 tsk.signal_set(0x01);
kenjiArai 1:9b27a9710d94 286 }
kenjiArai 1:9b27a9710d94 287
kenjiArai 6:16e1f9d065a3 288 void pc_ser_rx()
kenjiArai 6:16e1f9d065a3 289 {
kenjiArai 6:16e1f9d065a3 290 static uint8_t linebf_irq[BFSIZE];
kenjiArai 6:16e1f9d065a3 291 static volatile uint8_t linebf_irq_len = 0;
kenjiArai 6:16e1f9d065a3 292
kenjiArai 7:0d94f4cf2a69 293 while(true) {
kenjiArai 6:16e1f9d065a3 294 Thread::signal_wait(0x01);
kenjiArai 8:dd23c6d67b58 295 if (ser_bf.empty()) {
kenjiArai 7:0d94f4cf2a69 296 if (linebf_irq_len != 0) {
kenjiArai 6:16e1f9d065a3 297 linebf_irq[linebf_irq_len] = 0;
kenjiArai 6:16e1f9d065a3 298 adjust_line(linebf_irq);
kenjiArai 6:16e1f9d065a3 299 linebf_irq_len = 0;
kenjiArai 6:16e1f9d065a3 300 bletx_mutex.lock();
kenjiArai 7:0d94f4cf2a69 301 ble_uart.updateCharacteristicValue(
kenjiArai 6:16e1f9d065a3 302 uartServicePtr->getRXCharacteristicHandle(),
kenjiArai 6:16e1f9d065a3 303 linebf_irq,
kenjiArai 6:16e1f9d065a3 304 NUM_ONCE
kenjiArai 6:16e1f9d065a3 305 );
kenjiArai 6:16e1f9d065a3 306 bletx_mutex.unlock();
kenjiArai 6:16e1f9d065a3 307 }
kenjiArai 6:16e1f9d065a3 308 }
kenjiArai 8:dd23c6d67b58 309 while(!ser_bf.empty()) {
kenjiArai 8:dd23c6d67b58 310 char c;
kenjiArai 8:dd23c6d67b58 311 ser_bf.pop(c);
kenjiArai 7:0d94f4cf2a69 312 if (c == '\b') {
kenjiArai 6:16e1f9d065a3 313 linebf_irq_len--;
kenjiArai 6:16e1f9d065a3 314 pc.putc(c);
kenjiArai 6:16e1f9d065a3 315 pc.putc(' ');
kenjiArai 6:16e1f9d065a3 316 pc.putc(c);
kenjiArai 7:0d94f4cf2a69 317 } else if ((c >= ' ') || (c == '\r') || (c == '\n')) {
kenjiArai 6:16e1f9d065a3 318 bool overflow = false;
kenjiArai 6:16e1f9d065a3 319 if ((c == '\r') || (c == '\n')) {
kenjiArai 7:0d94f4cf2a69 320 if (linebf_irq_len == NUM_ONCE - 1) { // remain only 1 buffer
kenjiArai 6:16e1f9d065a3 321 overflow = true;
kenjiArai 6:16e1f9d065a3 322 linebf_irq[linebf_irq_len++] = '\r';
kenjiArai 6:16e1f9d065a3 323 pc.putc('\r');
kenjiArai 6:16e1f9d065a3 324 } else {
kenjiArai 6:16e1f9d065a3 325 overflow = false;
kenjiArai 6:16e1f9d065a3 326 linebf_irq[linebf_irq_len++] = '\r';
kenjiArai 6:16e1f9d065a3 327 linebf_irq[linebf_irq_len++] = '\n';
kenjiArai 6:16e1f9d065a3 328 pc.printf("\r\n");
kenjiArai 6:16e1f9d065a3 329 }
kenjiArai 6:16e1f9d065a3 330 } else {
kenjiArai 6:16e1f9d065a3 331 linebf_irq[linebf_irq_len++] = c;
kenjiArai 6:16e1f9d065a3 332 pc.putc(c);
kenjiArai 6:16e1f9d065a3 333 }
kenjiArai 7:0d94f4cf2a69 334 if (linebf_irq_len >= NUM_ONCE ) {
kenjiArai 6:16e1f9d065a3 335 linebf_irq[linebf_irq_len] = 0;
kenjiArai 6:16e1f9d065a3 336 adjust_line(linebf_irq);
kenjiArai 6:16e1f9d065a3 337 linebf_irq_len = 0;
kenjiArai 6:16e1f9d065a3 338 bletx_mutex.lock();
kenjiArai 7:0d94f4cf2a69 339 ble_uart.updateCharacteristicValue(
kenjiArai 6:16e1f9d065a3 340 uartServicePtr->getRXCharacteristicHandle(),
kenjiArai 6:16e1f9d065a3 341 linebf_irq,
kenjiArai 6:16e1f9d065a3 342 NUM_ONCE
kenjiArai 6:16e1f9d065a3 343 );
kenjiArai 6:16e1f9d065a3 344 bletx_mutex.unlock();
kenjiArai 7:0d94f4cf2a69 345 if (overflow == true) {
kenjiArai 6:16e1f9d065a3 346 overflow = false;
kenjiArai 6:16e1f9d065a3 347 linebf_irq[linebf_irq_len++] = '\n';
kenjiArai 6:16e1f9d065a3 348 pc.putc('\n');
kenjiArai 6:16e1f9d065a3 349 }
kenjiArai 6:16e1f9d065a3 350 }
kenjiArai 6:16e1f9d065a3 351 }
kenjiArai 6:16e1f9d065a3 352 }
kenjiArai 6:16e1f9d065a3 353 }
kenjiArai 6:16e1f9d065a3 354 }
kenjiArai 6:16e1f9d065a3 355
kenjiArai 6:16e1f9d065a3 356 void adjust_line(uint8_t *bf)
kenjiArai 6:16e1f9d065a3 357 {
kenjiArai 2:2322afea6ecf 358 uint8_t i, c;
kenjiArai 1:9b27a9710d94 359
kenjiArai 7:0d94f4cf2a69 360 for (i = 0; i <NUM_ONCE; bf++, i++) {
kenjiArai 1:9b27a9710d94 361 c = *bf;
kenjiArai 7:0d94f4cf2a69 362 if (c == 0) {
kenjiArai 7:0d94f4cf2a69 363 break;
kenjiArai 7:0d94f4cf2a69 364 }
kenjiArai 1:9b27a9710d94 365 }
kenjiArai 7:0d94f4cf2a69 366 for (; i < NUM_ONCE; bf++, i++) {
kenjiArai 7:0d94f4cf2a69 367 *bf = 0x11;
kenjiArai 7:0d94f4cf2a69 368 }
kenjiArai 1:9b27a9710d94 369 *(bf + 1) = 0;
kenjiArai 1:9b27a9710d94 370 }
kenjiArai 1:9b27a9710d94 371
kenjiArai 6:16e1f9d065a3 372 void onDataWritten_action(const GattWriteCallbackParams *params)
kenjiArai 6:16e1f9d065a3 373 {
kenjiArai 7:0d94f4cf2a69 374 if ((uartServicePtr != NULL) &&
kenjiArai 7:0d94f4cf2a69 375 (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
kenjiArai 1:9b27a9710d94 376 strcpy((char *)rx_buf, (const char *)params->data);
kenjiArai 1:9b27a9710d94 377 trigger_transmit = true;
kenjiArai 1:9b27a9710d94 378 }
kenjiArai 1:9b27a9710d94 379 }
kenjiArai 1:9b27a9710d94 380
kenjiArai 6:16e1f9d065a3 381 void action_tx_help()
kenjiArai 6:16e1f9d065a3 382 {
kenjiArai 7:0d94f4cf2a69 383 // 12345678901234567890
kenjiArai 6:16e1f9d065a3 384 sprintf((char *)tx_buf," ~?:help\r\n");
kenjiArai 7:0d94f4cf2a69 385 tx_len = strlen((const char *)tx_buf);
kenjiArai 1:9b27a9710d94 386 Update_Values();
kenjiArai 8:dd23c6d67b58 387 Thread::wait(200);
kenjiArai 7:0d94f4cf2a69 388 // 12345678901234567890
kenjiArai 6:16e1f9d065a3 389 sprintf((char *)tx_buf," ~v:vdd\r\n");
kenjiArai 7:0d94f4cf2a69 390 tx_len = strlen((const char *)tx_buf);
kenjiArai 1:9b27a9710d94 391 Update_Values();
kenjiArai 8:dd23c6d67b58 392 Thread::wait(200);
kenjiArai 7:0d94f4cf2a69 393 // 12345678901234567890
kenjiArai 6:16e1f9d065a3 394 sprintf((char *)tx_buf," ~t:temperature\r\n");
kenjiArai 7:0d94f4cf2a69 395 tx_len = strlen((const char *)tx_buf);
kenjiArai 1:9b27a9710d94 396 Update_Values();
kenjiArai 8:dd23c6d67b58 397 Thread::wait(200);
kenjiArai 7:0d94f4cf2a69 398 // 12345678901234567890
kenjiArai 6:16e1f9d065a3 399 sprintf((char *)tx_buf," ~w:wait, w 120\r\n");
kenjiArai 7:0d94f4cf2a69 400 tx_len = strlen((const char *)tx_buf);
kenjiArai 5:394920d6a82f 401 Update_Values();
kenjiArai 8:dd23c6d67b58 402 Thread::wait(200);
kenjiArai 7:0d94f4cf2a69 403 // 12345678901234567890
kenjiArai 6:16e1f9d065a3 404 sprintf((char *)tx_buf," ~q:quit/sleep\r\n");
kenjiArai 7:0d94f4cf2a69 405 tx_len = strlen((const char *)tx_buf);
kenjiArai 1:9b27a9710d94 406 Update_Values();
kenjiArai 8:dd23c6d67b58 407 Thread::wait(200);
kenjiArai 1:9b27a9710d94 408 }
kenjiArai 1:9b27a9710d94 409
kenjiArai 6:16e1f9d065a3 410 void action_tx_vdd()
kenjiArai 6:16e1f9d065a3 411 {
kenjiArai 6:16e1f9d065a3 412 sprintf((char *)tx_buf,"Vdd: %3.2f V\r\n", vdd.read_real_value());
kenjiArai 6:16e1f9d065a3 413 tx_len = strlen((const char *)tx_buf);
kenjiArai 6:16e1f9d065a3 414 Update_Values();
kenjiArai 6:16e1f9d065a3 415 }
kenjiArai 6:16e1f9d065a3 416
kenjiArai 6:16e1f9d065a3 417 void action_tx_temperature()
kenjiArai 6:16e1f9d065a3 418 {
kenjiArai 6:16e1f9d065a3 419 int32_t p_temp;
kenjiArai 6:16e1f9d065a3 420 float temperature;
kenjiArai 6:16e1f9d065a3 421
kenjiArai 6:16e1f9d065a3 422 // Update a temperature (inside nRF51822 chip)
kenjiArai 6:16e1f9d065a3 423 sd_temp_get(&p_temp);
kenjiArai 6:16e1f9d065a3 424 // -16.0f is offset vale for chip die temp
kenjiArai 6:16e1f9d065a3 425 // to ambient temp (depend on your board)
kenjiArai 6:16e1f9d065a3 426 temperature = float(p_temp) / 4; // Original = float(p_temp)/4.0f - 16.0f;
kenjiArai 6:16e1f9d065a3 427 sprintf((char *)tx_buf,"T: %+4.1f dC\r\n", temperature);
kenjiArai 1:9b27a9710d94 428 tx_len = strlen((const char *)tx_buf);
kenjiArai 1:9b27a9710d94 429 Update_Values();
kenjiArai 1:9b27a9710d94 430 }
kenjiArai 1:9b27a9710d94 431
kenjiArai 6:16e1f9d065a3 432 void action_tx_wait_time(uint8_t *cmd)
kenjiArai 6:16e1f9d065a3 433 {
kenjiArai 6:16e1f9d065a3 434 int32_t dt;
kenjiArai 6:16e1f9d065a3 435 char *p;
kenjiArai 6:16e1f9d065a3 436
kenjiArai 6:16e1f9d065a3 437 p = (char *)(cmd);
kenjiArai 6:16e1f9d065a3 438 p += 2; // point to time value
kenjiArai 7:0d94f4cf2a69 439 if (xatoi(&p, &dt)) {
kenjiArai 7:0d94f4cf2a69 440 if (dt <= 5) {
kenjiArai 7:0d94f4cf2a69 441 dt = 5;
kenjiArai 7:0d94f4cf2a69 442 }
kenjiArai 6:16e1f9d065a3 443 sleep_time = dt; // set next wake-up period
kenjiArai 6:16e1f9d065a3 444 } else {
kenjiArai 6:16e1f9d065a3 445 DEBUG("data is unknown!\r\n");
kenjiArai 6:16e1f9d065a3 446 sleep_time = 30;
kenjiArai 6:16e1f9d065a3 447 }
kenjiArai 6:16e1f9d065a3 448 DEBUG("slp_t:%d\r\n", sleep_time);
kenjiArai 6:16e1f9d065a3 449 //pc.printf("slp_t:%d\r\n", sleep_time);
kenjiArai 7:0d94f4cf2a69 450 // 12345678901234567890
kenjiArai 6:16e1f9d065a3 451 sprintf((char *)tx_buf, "W: %d sec\r\n", sleep_time);
kenjiArai 1:9b27a9710d94 452 tx_len = strlen((const char *)tx_buf);
kenjiArai 1:9b27a9710d94 453 Update_Values();
kenjiArai 1:9b27a9710d94 454 }
kenjiArai 1:9b27a9710d94 455
kenjiArai 6:16e1f9d065a3 456 void action_tx_quit()
kenjiArai 6:16e1f9d065a3 457 {
kenjiArai 7:0d94f4cf2a69 458 #if GOTO_SLEEP_MODE
kenjiArai 6:16e1f9d065a3 459 ticker.detach();
kenjiArai 7:0d94f4cf2a69 460 // 12345678901234567890
kenjiArai 6:16e1f9d065a3 461 sprintf((char *)tx_buf,"Terminated the BLE");
kenjiArai 7:0d94f4cf2a69 462 tx_len = strlen((const char *)tx_buf);
kenjiArai 6:16e1f9d065a3 463 Update_Values();
kenjiArai 8:dd23c6d67b58 464 Thread::wait(1000);
kenjiArai 6:16e1f9d065a3 465 wakeup.set_and_wait(sleep_time);
kenjiArai 7:0d94f4cf2a69 466 while(true) { // never come here but just in case
kenjiArai 6:16e1f9d065a3 467 deepsleep();
kenjiArai 6:16e1f9d065a3 468 }
kenjiArai 6:16e1f9d065a3 469 #else
kenjiArai 6:16e1f9d065a3 470 SCB->AIRCR = 0x05fa0004; // System RESET!!
kenjiArai 6:16e1f9d065a3 471 #endif
kenjiArai 6:16e1f9d065a3 472 }
kenjiArai 5:394920d6a82f 473
kenjiArai 5:394920d6a82f 474 // Change string -> integer
kenjiArai 6:16e1f9d065a3 475 int xatoi (char **str, int32_t *res)
kenjiArai 6:16e1f9d065a3 476 {
kenjiArai 5:394920d6a82f 477 unsigned long val;
kenjiArai 5:394920d6a82f 478 unsigned char c, radix, s = 0;
kenjiArai 5:394920d6a82f 479
kenjiArai 7:0d94f4cf2a69 480 for (;;) {
kenjiArai 5:394920d6a82f 481 c = **str;
kenjiArai 7:0d94f4cf2a69 482 if (c == 0) {
kenjiArai 7:0d94f4cf2a69 483 return 0;
kenjiArai 7:0d94f4cf2a69 484 }
kenjiArai 7:0d94f4cf2a69 485 if (c == '-') {
kenjiArai 7:0d94f4cf2a69 486 break;
kenjiArai 7:0d94f4cf2a69 487 }
kenjiArai 7:0d94f4cf2a69 488 if (c == '+') {
kenjiArai 5:394920d6a82f 489 (*str)++;
kenjiArai 5:394920d6a82f 490 c = **str;
kenjiArai 5:394920d6a82f 491 }
kenjiArai 7:0d94f4cf2a69 492 if (c>='0'&& c<='9') {
kenjiArai 5:394920d6a82f 493 break;
kenjiArai 5:394920d6a82f 494 } else {
kenjiArai 5:394920d6a82f 495 (*str)++;
kenjiArai 5:394920d6a82f 496 c = **str;
kenjiArai 5:394920d6a82f 497 }
kenjiArai 5:394920d6a82f 498 }
kenjiArai 5:394920d6a82f 499 if (c == '-') {
kenjiArai 5:394920d6a82f 500 s = 1;
kenjiArai 5:394920d6a82f 501 c = *(++(*str));
kenjiArai 5:394920d6a82f 502 }
kenjiArai 5:394920d6a82f 503 if (c == '0') {
kenjiArai 5:394920d6a82f 504 c = *(++(*str));
kenjiArai 5:394920d6a82f 505 if (c <= ' ') {
kenjiArai 5:394920d6a82f 506 *res = 0;
kenjiArai 5:394920d6a82f 507 return 1;
kenjiArai 5:394920d6a82f 508 }
kenjiArai 5:394920d6a82f 509 if (c == 'x') {
kenjiArai 5:394920d6a82f 510 radix = 16;
kenjiArai 5:394920d6a82f 511 c = *(++(*str));
kenjiArai 5:394920d6a82f 512 } else {
kenjiArai 5:394920d6a82f 513 if (c == 'b') {
kenjiArai 5:394920d6a82f 514 radix = 2;
kenjiArai 5:394920d6a82f 515 c = *(++(*str));
kenjiArai 5:394920d6a82f 516 } else {
kenjiArai 5:394920d6a82f 517 if ((c >= '0')&&(c <= '9')) {
kenjiArai 5:394920d6a82f 518 radix = 8;
kenjiArai 5:394920d6a82f 519 } else {
kenjiArai 5:394920d6a82f 520 return 0;
kenjiArai 5:394920d6a82f 521 }
kenjiArai 5:394920d6a82f 522 }
kenjiArai 5:394920d6a82f 523 }
kenjiArai 5:394920d6a82f 524 } else {
kenjiArai 5:394920d6a82f 525 if ((c < '1')||(c > '9')) {
kenjiArai 5:394920d6a82f 526 return 0;
kenjiArai 5:394920d6a82f 527 }
kenjiArai 5:394920d6a82f 528 radix = 10;
kenjiArai 5:394920d6a82f 529 }
kenjiArai 5:394920d6a82f 530 val = 0;
kenjiArai 5:394920d6a82f 531 while (c > ' ') {
kenjiArai 5:394920d6a82f 532 if (c >= 'a') c -= 0x20;
kenjiArai 5:394920d6a82f 533 c -= '0';
kenjiArai 5:394920d6a82f 534 if (c >= 17) {
kenjiArai 5:394920d6a82f 535 c -= 7;
kenjiArai 5:394920d6a82f 536 if (c <= 9) return 0;
kenjiArai 5:394920d6a82f 537 }
kenjiArai 5:394920d6a82f 538 if (c >= radix) return 0;
kenjiArai 5:394920d6a82f 539 val = val * radix + c;
kenjiArai 5:394920d6a82f 540 c = *(++(*str));
kenjiArai 5:394920d6a82f 541 }
kenjiArai 5:394920d6a82f 542 if (s) val = -val;
kenjiArai 5:394920d6a82f 543 *res = val;
kenjiArai 5:394920d6a82f 544 return 1;
kenjiArai 5:394920d6a82f 545 }
kenjiArai 5:394920d6a82f 546
kenjiArai 6:16e1f9d065a3 547 void interrupt_by_sw() // Go to sleep
kenjiArai 6:16e1f9d065a3 548 {
kenjiArai 6:16e1f9d065a3 549 NVIC_SystemReset();
kenjiArai 6:16e1f9d065a3 550 // Not come here (Just in case)
kenjiArai 6:16e1f9d065a3 551 sleep();
kenjiArai 5:394920d6a82f 552 }
kenjiArai 5:394920d6a82f 553
kenjiArai 6:16e1f9d065a3 554 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
kenjiArai 6:16e1f9d065a3 555 {
kenjiArai 1:9b27a9710d94 556 DEBUG("Disconnected!\r\n");
kenjiArai 1:9b27a9710d94 557 DEBUG("Restarting the advertising process\r\n");
kenjiArai 7:0d94f4cf2a69 558 ble_uart.startAdvertising();
kenjiArai 1:9b27a9710d94 559 }
kenjiArai 1:9b27a9710d94 560
kenjiArai 6:16e1f9d065a3 561 void Update_Values(void)
kenjiArai 6:16e1f9d065a3 562 {
kenjiArai 6:16e1f9d065a3 563 bletx_mutex.lock();
kenjiArai 7:0d94f4cf2a69 564 ble_uart.updateCharacteristicValue(
kenjiArai 1:9b27a9710d94 565 uartServicePtr->getRXCharacteristicHandle(),
kenjiArai 1:9b27a9710d94 566 tx_buf,
kenjiArai 1:9b27a9710d94 567 tx_len
kenjiArai 1:9b27a9710d94 568 );
kenjiArai 6:16e1f9d065a3 569 bletx_mutex.unlock();
kenjiArai 1:9b27a9710d94 570 tx_len = 0;
kenjiArai 1:9b27a9710d94 571 }