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 Oct 22 09:47:18 2017 +0000
Revision:
6:16e1f9d065a3
Parent:
5:394920d6a82f
Child:
7:0d94f4cf2a69
Run on Mbed-os5. Extend pc serial buffer. Delete low power related lib.

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