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/#

Revision:
1:9b27a9710d94
Parent:
0:6b0eca2bcb7a
Child:
2:2322afea6ecf
--- a/main.cpp	Sat Apr 16 08:33:46 2016 +0000
+++ b/main.cpp	Sat Apr 16 12:12:59 2016 +0000
@@ -1,12 +1,321 @@
-#include "mbed.h"
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * 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.
+ */
+
+/*
+ *  ------- BLE Peripheral UART function --------------------------------
+ *      --- Tested on Switch Science mbed TY51822r3 ---
+ *
+ *      http://www.page.sannet.ne.jp/kenjia/index.html
+ *      http://mbed.org/users/kenjiArai/
+ *
+ *      Started:  March     7th, 2016
+ *      Revised:  April    16th, 2016
+ *
+ *  Original program:
+ *      BLE_LoopbackUART
+ *      https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_LoopbackUART/
+ *  Tested Controller Device:
+ *      BLE_Uart_Client
+ *      https://developer.mbed.org/users/kenjiArai/code/BLE_Uart_Client/
+ *
+ */
 
-DigitalOut myled(LED1);
+//  Include ---------------------------------------------------------------------------------------
+#include "mbed.h"
+#include "BLE.h"
+#include "UARTService.h"
+#include "nRF51_Vdd.h"
+#include "nRF51_WakeUp.h"
+
+//  Definition ------------------------------------------------------------------------------------
+#define GOTO_SLEEP_MODE         0
+#define NEED_CONSOLE_OUTPUT     0
+
+#if NEED_CONSOLE_OUTPUT
+#define DEBUG(...) { printf(__VA_ARGS__); }
+#else
+#define DEBUG(...)
+#endif
+
+//  Object ----------------------------------------------------------------------------------------
+BLEDevice       ble;
+DigitalOut      connectedLED(LED2);
+InterruptIn     wake_up_sw(P0_1);
+nRF51_WakeUp    wakeup(LED1, P0_0);
+nRF51_Vdd       vdd(3.0f, 2.2f);
+Serial          pc(USBTX, USBRX);
+UARTService     *uartServicePtr;
+Ticker          ticker;
+
+//  ROM / Constant data ---------------------------------------------------------------------------
+#warning "You need to confirm your device name."
+const char      *deviceName = "UART_P";
+
+//  RAM -------------------------------------------------------------------------------------------
+uint8_t             tx_buf[24];
+uint8_t             tx_len          = 0;
+uint8_t             rx_buf[24];
+uint8_t             rx_len          = 0;
+volatile bool    trigger_transmit   = false;
+volatile bool    trigger_receive    = false;
+volatile uint8_t command_continue   = 0;
+uint16_t            time_out_cntr   = 3600;
+volatile bool       time_out        = false;
+bool                line_input      = false;
+uint8_t             linebuf_irq[24];
+int                 linebf_irq_len  = 0;
+uint8_t             linebuf[24];
+int                 linebf_len      = 0;
 
-int main() {
-    while(1) {
-        myled = 1;
-        wait(0.2);
-        myled = 0;
-        wait(0.2);
+//  Function prototypes ---------------------------------------------------------------------------
+//      BLE
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params);
+void onDataWritten(const GattWriteCallbackParams *params);
+void periodicCallback(void);
+//      Application related
+void adjust_line(uint8_t *bf);
+void action_tx_help(void);
+void action_tx_vdd(void);
+void action_tx_temperature(void);
+void action_tx_pwrup(void);
+void action_tx_pwrdwn(void);
+void fill_space_n(uint8_t *bf, uint8_t n);
+void Update_Values(void);
+//      Interrupt related
+void action_tx_quit(void);
+void interrupt_by_sw(void);
+void serialRxCallback(void);
+
+//-------------------------------------------------------------------------------------------------
+//  Control Program
+//-------------------------------------------------------------------------------------------------
+int main(void){
+    connectedLED = 0;
+    pc.attach(&serialRxCallback, Serial::RxIrq);
+    ticker.attach(periodicCallback, 1);
+    for (int k = 0; k < 20; k++) { pc.printf("\r\n");}          // clear terminal output
+    pc.printf("UART Communication / Peripheral side\r\n");      // opening message
+    pc.printf("  Client(Central) and Peripheral(device)\r\n");  // opening message
+    // Interrupt by switch
+    wake_up_sw.fall(&interrupt_by_sw);
+    ble.init();
+    ble.setDeviceName((const uint8_t *)deviceName);
+    ble.onDisconnection(disconnectionCallback);
+    ble.onDataWritten(onDataWritten);
+    /* setup advertising */
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
+    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
+                                    (const uint8_t *)deviceName,
+                                     strlen(deviceName)
+                                    );
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
+                                    (const uint8_t *)UARTServiceUUID_reversed,
+                                     sizeof(UARTServiceUUID_reversed)
+                                    );
+    // Advertize Interval
+    ble.setAdvertisingInterval(1000); /* 1000ms; in multiples of 0.625ms. */
+    // Start
+    ble.startAdvertising();
+    UARTService uartService(ble);
+    uartServicePtr = &uartService;
+    while(true){
+        if (time_out){
+#if GOTO_SLEEP_MODE
+            wakeup.set_and_wait(10);
+            while(true){    // never come here but just in case
+                deepsleep();
+            }
+#endif
+        }
+        if (line_input){
+            line_input = false;
+            adjust_line(linebuf);
+            ble.updateCharacteristicValue(
+                uartServicePtr->getRXCharacteristicHandle(),
+                linebuf,
+                20
+            );
+        }
+        if (trigger_transmit){
+            trigger_transmit = false;
+            pc.printf("%s\r\n", rx_buf);
+            if (rx_buf[0] == '*'){          
+                switch (rx_buf[1]){
+                    case 'v':
+                        action_tx_vdd();
+                        break;
+                    case 't':
+                        action_tx_temperature();
+                        break;
+                    case 'q':
+                        action_tx_quit();
+                        break;
+                    case 'h':
+                    case '?':
+                        action_tx_help();
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+        ble.waitForEvent();        
     }
 }
+
+void serialRxCallback(){
+    char c = pc.getc();
+    if (c == '\r') {
+        linebuf_irq[linebf_irq_len++] = c;
+        pc.printf("\r\n");
+        linebf_len = linebf_irq_len;
+        strcpy((char *)linebuf, (char *)linebuf_irq);
+        linebf_irq_len = 0;
+        line_input = true;
+    } else if ((c == '\b') && linebf_irq_len) {
+        linebf_irq_len--;
+        pc.putc(c);
+        pc.putc(' ');
+        pc.putc(c);
+    } else if (((uint8_t)c >= ' ') && (linebf_irq_len < 20)) {
+        linebuf_irq[linebf_irq_len++] = c;
+        pc.putc(c);
+    } else if ( c == 0x1f ){    // Control+?
+        SCB->AIRCR = 0x05fa0004;    // System RESET!!
+    }
+    linebuf_irq[linebf_irq_len] = 0; 
+}
+
+void adjust_line(uint8_t *bf){
+uint8_t i, c;
+
+    for (i = 0; i <20; bf++, i++){
+        c = *bf;
+        if ( (c == '\r') || (c == '\n') || (c == 0)){
+            break;
+        }
+    }
+    for (; i < 20; bf++, i++){
+        *bf = ' ';
+    }
+    *(bf + 1) = 0;
+}
+
+void onDataWritten(const GattWriteCallbackParams *params){
+    if ((uartServicePtr != NULL) && 
+        (params->handle == uartServicePtr->getTXCharacteristicHandle()))
+    {
+        strcpy((char *)rx_buf, (const char *)params->data);
+        rx_len = params->len;
+        trigger_transmit = true;
+        DEBUG("RX_data\r\n");
+        DEBUG("Length: %d\r\n", rx_len);
+        DEBUG("Data: ");
+        DEBUG("%s", rx_buf);
+        DEBUG("\r\n");
+    }
+}
+
+void action_tx_help(){
+                //          12345678901234567890
+    sprintf((char *)tx_buf,"?:help by JH1PJL");
+    tx_len = strlen((const char *)tx_buf); 
+    Update_Values();
+    wait(0.2);
+                //          12345678901234567890
+    sprintf((char *)tx_buf,"v:vdd");
+    tx_len = strlen((const char *)tx_buf); 
+    Update_Values();
+    wait(0.2);
+                //          12345678901234567890
+    sprintf((char *)tx_buf,"t:temperature");
+    tx_len = strlen((const char *)tx_buf); 
+    Update_Values();
+    wait(0.2);
+                //          12345678901234567890
+    sprintf((char *)tx_buf,"q:quit/sleep");
+    tx_len = strlen((const char *)tx_buf); 
+    Update_Values();
+    wait(0.2);
+}
+
+void action_tx_vdd(){
+    sprintf((char *)tx_buf,"Vdd:%3.2fV", vdd.read_real_value());
+    tx_len = strlen((const char *)tx_buf);
+    Update_Values();
+}
+
+void action_tx_temperature(){
+    int32_t p_temp;
+    float temperature;
+ 
+    // Update a temperature (inside nRF51822 chip)
+    sd_temp_get(&p_temp);
+    // -16.0f is offset vale for chip die temp to ambient temp (depend on your board)
+    temperature = float(p_temp) / 4; // Original = float(p_temp)/4.0f - 16.0f;
+    sprintf((char *)tx_buf,"T:%+4.1fdC", temperature);
+    tx_len = strlen((const char *)tx_buf);
+    Update_Values();
+}
+
+void action_tx_quit(){
+#if GOTO_SLEEP_MODE 
+    ticker.detach();
+                //          12345678901234567890
+    sprintf((char *)tx_buf,"Terminated the BLE");
+    tx_len = strlen((const char *)tx_buf); 
+    Update_Values();
+    wait(1.0);
+    wakeup.set_and_wait(120);
+    while(true){    // never come here but just in case
+        deepsleep();
+    }
+#else
+    SCB->AIRCR = 0x05fa0004;    // System RESET!!
+#endif
+}
+
+void interrupt_by_sw(){         // Go to sleep
+    NVIC_SystemReset();
+    // Not come here (Just in case)
+    deepsleep();
+}
+
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params){
+    DEBUG("Disconnected!\r\n");
+    DEBUG("Restarting the advertising process\r\n");
+    ble.startAdvertising();
+}
+
+void periodicCallback(void){
+#if GOTO_SLEEP_MODE
+    if (--time_out_cntr == 0){
+        time_out = true;
+    }
+#endif
+}
+
+void Update_Values(void){
+    ble.updateCharacteristicValue(
+        uartServicePtr->getRXCharacteristicHandle(),
+        tx_buf,
+        tx_len
+    );
+    DEBUG("TX_data: %s\r\n", tx_buf);
+    DEBUG("Length: %d\r\n", tx_len);
+    tx_len = 0;
+}