TYBLE16 serial communication (UART) for both "Central" and "Peripheral".

Dependencies:   RingBuffer

Fork of TYBLE16_BME280_data_sender by Kenji Arai

Please refer following page.
/users/kenjiArai/notebook/tyble16-module--uart-communication-between-central/#

Revision:
2:f44ef892b2b2
Parent:
1:f2982d4f4037
--- a/main.cpp	Sun Oct 29 23:25:26 2017 +0000
+++ b/main.cpp	Sun Nov 19 09:46:27 2017 +0000
@@ -12,141 +12,96 @@
  *  http://www.page.sannet.ne.jp/kenjia/index.html
  *  http://mbed.org/users/kenjiArai/
  *      Created:    October   27th, 2017
- *      Revised:    October   30th, 2017
+ *      Revised:    November  19th, 2017
  */
 
 /*
     Tested condition
-        mbed-os-5.6.3 & mbed Rev.154
-    Nucleo-F446RE   TYBLE16 /also F411RE & F042K6(only mbed & pin assign differ)
-        PA_9         pin5 / P0.03(UART_RX)
-        PA_10        pin6 / P0.01(UART_TX)
-                     pin7 / P0.02(UART_CTS) connected to pin8 / P0.00(UART_RTS)
+        mbed-os-5.6.4 & mbed Rev.157(release 155?)
+    Nucleo-F446RE   TYBLE16 /also F411RE
+        PA_9 (D8)    pin5  / P0.03(UART_RX)
+        PA_10(D2)    pin6  / P0.01(UART_TX)
+                     pin7  / P0.02(UART_CTS) connected to pin8 / P0.00(UART_RTS)
+        PB_3 (D3)    pin15 / P0.23(MODE) Mode indication
         +3.3v        pin14 / +V
         GND          pin13 / GND
-    Nucleo-F446RE   BME280
-        PB_9(SDA)    SDI
-        PB_8(SCL)    SDK
-                     SDO = GND, CSB = +3.3V
-    Communcation with iPhone 7 iOS 11.0.3
-        TYs Terminal App
-        https://itunes.apple.com/jp/app/tys-terminal-app/id1184640145?mt=8
+ */
+
+/*
+ --- HOW TO ESTABLISH CENTRAL AND PERIPHERAL UART ---
+ 1) Prepare one peripheral module/TYBLE16
+ 2) Prepare another TYBLE16 module which was programed as "Central mode"
+    Please refer "TYBLE16_set_Central_or_ Peripheral" program
+ 3) Programing "TYBLE16_Uart_Central_and_Peripheral" into Mbed boards 
+    (same program into both "Central" and "Peripheral" Mbed board)
+ 4) If you turn on both the "Central" and "Peripheral" power at the same time,
+    the connection is automatically started
  */
 
 //  Include --------------------------------------------------------------------
-#include "mbed.h"
-#include "BME280.h"
+#include    "mbed.h"
+#include    "RingBuffer.h"
 
 //  Definition -----------------------------------------------------------------
-#define     TIME_OUT         5       // 5 sec
-#define     ADT_TIME        15       // 15 sec
+#define     TIME_OUT            5      // 5 sec
+#define     BF_SIZE_BLE         256
+#define     BF_SIZE_PC          256
+#define     BF_SIZE_LINE        32
 
 //  Object/ Constructor --------------------------------------------------------
 Serial      pc(USBTX,USBRX);
-Serial      tyble16(PA_9, PA_10);
-BME280      bme280(I2C_SDA, I2C_SCL);
+Serial      tyble16(D8, D2);
+DigitalIn   tyble16_mode(D3);
+Ticker      t;
+RingBuffer  ble_bf(BF_SIZE_BLE);
+RingBuffer  pc_bf(BF_SIZE_PC);
 
 //  RAM ------------------------------------------------------------------------
-bool        state_connection    = false;
-bool        received_data       = false;
-uint32_t    cmd_timeout_cntr    = ADT_TIME;
-Ticker      t;
 
 //  ROM / Constant data --------------------------------------------------------
 
 //  Function prototypes --------------------------------------------------------
 void check_connection(void);
-void parse_input(char *buf);
+void excute_command(char *);
+void ble_rx(void);
+void pc_rx(void);
 
 //------------------------------------------------------------------------------
 //  Control Program
 //------------------------------------------------------------------------------
-// special command for BME280 data collection
-bool excute_command(char *buf)
-{
-    char c = buf[1];
-    switch (c){
-        case 'a':       // All data
-        case 'A':
-            tyble16.printf("Pressure: %04.2f hPa\r\n",
-                            bme280.getPressure());
-            tyble16.printf("Temperature: %2.2f degC\r\n",
-                            bme280.getTemperature());
-            tyble16.printf("Humidity: %2.2f %%\r\n",
-                            bme280.getHumidity());
-            break;
-        case 'p':       // Pressure
-        case 'P':
-            tyble16.printf("Pressure: %04.2f hPa\r\n",
-                            bme280.getPressure());
-            break;
-        case 't':       // Temperature
-        case 'T':
-            tyble16.printf("Temperature: %2.2f degC\r\n",
-                            bme280.getTemperature());
-            break;
-        case 'h':       // Humidity
-        case 'H':
-            tyble16.printf("Humidity: %2.2f %%\r\n",
-                            bme280.getHumidity());
-            break;
-        case '?':       // Help
-            tyble16.printf("Command syntax\r\n");
-            tyble16.printf("@a All of data\r\n");
-            tyble16.printf("@p Pressure\r\n");
-            tyble16.printf("@t Temperature\r\n");
-            tyble16.printf("@h Humidity\r\n");
-            break;
-        default:        // no available command
-            tyble16.printf("ommand not available, hit '@?'\r\n");
-            break;
-    }
-    return true;
-}
-
 int main()
 {
-    static char rcv_bf[128];
+    static char rcv_bf[BF_SIZE_LINE];
     static uint8_t n = 0;
     char c = 0;
 
-    pc.printf("\r\n\r\nApplication for AE-TYBLE16 Module ");
-    pc.printf(" Peripheral(Sever) side\r\n");
-    pc.printf("  created on %s %s\r\n", __DATE__, __TIME__);
-    tyble16.printf("I'm TYBLE16 module!\r\n");
-    // warming up the sensor
-    for (int n = 0; n < 6; n++){
-        bme280.getPressure();
-        bme280.getTemperature();
-        bme280.getHumidity();
-    }
+    tyble16.attach(&ble_rx, Serial::RxIrq);     // Set interrupt handler
+    pc.attach(&pc_rx, Serial::RxIrq);           // Set interrupt handler
+    pc.printf("\r\nUART/TYBLE16(%s, %s UTC)\r\n", __DATE__, __TIME__);
+    tyble16.printf("I'm TYBLE16\r\n");
     t.attach(check_connection, 1);
     while(true){
-        while(tyble16.readable()){
-            //----- data receive from Client -----------------------------------
-            received_data = true;
-            c = tyble16.getc();         // received data from client
+        while(ble_bf.check() != 0){
+            //----- receive data -----------------------------------------------
+            c = ble_bf.read();          // data received
             pc.putc(c);                 // show to console
             rcv_bf[n++] = c;            // save int buf
+            // avoid buffer overflow
+            if (n >= (BF_SIZE_LINE - 5)){ n = (BF_SIZE_LINE - 5);}
             if (c == '\n'){             // end one line
                 pc.putc('\r');
                 rcv_bf[n] = 0;
-                if (n >3){
-                    parse_input(rcv_bf);    // ckeck command or not
-                    /*for (int i=0;; i++){
-                        if (rcv_bf[i] == 0){break;}
-                        pc.printf("0x%x,", rcv_bf[i]);
-                    }*/
-                    if ((rcv_bf[0] == '@') && (rcv_bf[2] == '\r')){
-                        excute_command(rcv_bf); // BME280 data output 
+                if (n >3){  // command ~?\r\n ?=specified one character 
+                    if ((rcv_bf[0] == '~') && (rcv_bf[2] == '\r')){
+                        excute_command(rcv_bf);
                     }
                 }
                 n = 0;  // Clear buffer
             }
         }
-        while(pc.readable()){
-            //----- data send to Client ----------------------------------------
-            char c = pc.getc();
+        while(pc_bf.check() != 0){
+            //----- send data --------------------------------------------------
+            char c = pc_bf.read();
             tyble16.putc(c);
             pc.putc(c);                 // echo back
             if(c == '\r'){              // if CR then put LF
@@ -157,41 +112,48 @@
     }
 }
 
-// Check Response Events
-void parse_input(char *buf)
+// special command (You can make your own commands)
+void excute_command(char *buf)
 {
-    if        (strstr(buf, "CON")){     // Connection successful
-        state_connection = true;
-    } else if (strstr(buf, "DCO")){     // Disconnect
-        state_connection = false; 
-    } else if (strstr(buf, "ADT")){     // Advertising Timeout
-        state_connection = false;
-        cmd_timeout_cntr = 0;
-    } else if (strstr(buf, "NAK")){     // Failed
-        state_connection = false;
-        if (cmd_timeout_cntr == 0){
-            // Both Advertising Start. Connectable and Discoverable.
-            tyble16.printf("BCD3\r\n");     // send Advertising command
-            cmd_timeout_cntr = ADT_TIME;
-        }
+    char c = buf[1];
+    switch (c){
+        case 'x':   // corrent -> nothing to do
+            tyble16.printf("Accept 'x' Command\r\n");
+            break;
+        case '?':       // Help
+            tyble16.printf("Command not available\r\n");
+            tyble16.printf("Please set your own command\r\n");
+            break;
+        default:        // no available command
+            tyble16.printf("Command not available\r\n");
+            break;
     }
 }
 
+// Interrupt routine / Data from BLE
+void ble_rx()
+{
+    ble_bf.save(tyble16.getc());    // BLE RX data save into ring buffer
+}
+
+// Interrupt routine / Data from PC
+void pc_rx()
+{
+    pc_bf.save(pc.getc());          // PC RX data save into ring buffer
+}
+
 // Every one second, check communication status
 void check_connection(void)
 {
     static int8_t counter = 0;
 
-    if ((received_data == false) && (state_connection == false)){
+    if (tyble16_mode == 0){ // Not connected
         if (++counter >= TIME_OUT){
-            tyble16.putc('\n');
+            // Software reset
+            tyble16.puts("BRS\r\n");
             counter = 0;
         }
     } else {
         counter = 0;
     }
-    if (cmd_timeout_cntr != 0){
-        --cmd_timeout_cntr;
-    }
-    received_data = false;
 }