Finite State Machine move between STATE virtual com port USB connect to PC while UART connect to modem

Dependencies:   USBDevice mbed

Fork of USBSerial_HelloWorld by Samuel Mokrani

Revision:
10:a358762e1188
Parent:
9:d88699a0905a
--- a/main.cpp	Fri Mar 01 13:33:02 2013 +0000
+++ b/main.cpp	Sun Nov 22 09:44:43 2015 +0000
@@ -1,14 +1,223 @@
 #include "mbed.h"
 #include "USBSerial.h"
- 
+#define MAX_SIZE 16
+#include <ctype.h>
+
 //Virtual serial port over USB
-USBSerial serial;
- 
-int main(void) {
- 
-    while(1)
-    {
-        serial.printf("I am a virtual serial port\r\n");
-        wait(1);
+USBSerial pc;
+DigitalOut WDO(P0_20);
+DigitalOut LED(P0_7);
+
+
+
+Serial device(P0_19, P0_18);  // tx, rx of RS232 pins
+Timeout flipper;
+char buf[MAX_SIZE];
+char data[MAX_SIZE];
+unsigned int i,j;
+bool begin_msg=false;
+
+Ticker t1;
+
+// ******************************************************
+//              Finite State Machine Declare variable
+// ******************************************************
+
+
+/* Various states */
+typedef enum tState {
+    STATE_A,
+    STATE_B,
+    STATE_C
+} tState;
+
+/* Variables */
+tState       state;       /* Current state */
+volatile unsigned char         trigger;     /* Bit set to indicate which button triggers */
+
+
+
+/* task to be executed during each state transition */
+void do_task(int n)
+{
+    pc.printf("Task: %d \r\n", n);
+    wait(0.5);
+    trigger = 0;
+    pc.printf("Task %d done ... trigger=%d\r\n\r\n", n, trigger);
+    
+}
+
+void sleep(void)
+{
+    __WFI();   /* Power-saving sleeping mode */
+}
+
+// ***************************************************
+//      End of Finite State Machine declare variable
+// ***************************************************
+
+
+void determine_event(){
+    if ( strstr(data, "OK") != NULL ){
+        trigger = 0x02;    
+    }    
+    else if ( strstr(data, "ERROR") != NULL){
+        trigger = 0x04;    
+    }
+    else{
+        trigger = 0x08;    
+    }
+        
+}
+
+
+
+// process to run after timeout in receiving char from serial device ( device.getc() )
+void printout()
+{
+    //for ( j=0; j<MAX_SIZE; j++) {       // Put the character received into the computer.
+    //    pc.putc(buf[j]);
+    //    data[j] = buf[j];
+    //    buf[j] = 0;
+    //}
+
+    memcpy(data, buf, MAX_SIZE);
+    memset(buf, 0, MAX_SIZE*sizeof(unsigned char) );
+    i = 0;   //reset index
+    pc.printf(" data=%s<--\r\n", data);
+    
+    determine_event();
+}
+void time_out()
+{
+    printout();
+    //pc.printf("time out\n");
+    flipper.detach();                   //reset timer
+}
+
+// char receive within window size (MAX_SIZE) or within window time (start_timer) otherwise discard
+void check_frame()
+{
+    //pc.printf(" i=%d \n",i);
+    if ( i == 0 ) {                      // if the 1st char receive
+        flipper.attach(&time_out, 3 ); //start_timer
+        pc.printf("data in UART start timer ... ");
+    }
+    if ( i >= MAX_SIZE ) {               // char i receive exceed window size
+        printout();
+    } else {                             // char i still in window size
+        i++;                             // continue count
     }
+
+}
+
+void rec()                              // Here's my serial interrupt routine.
+{
+    if ( device.readable() ) {
+        trigger = 0;
+        //pc.printf("device.readable() there is some input in i=%d\r\n",i);
+        buf[i] = device.getc();
+        check_frame();
+    } else {
+        pc.printf(" device.readable() is not ready \n");
+    }
+}                                       // interrupt is done.
+
+void blink()
+{
+    LED = !LED;
+    WDO = !WDO;
+}
+
+
+int main(void)
+{
+
+    device.baud(115200);
+
+    wait(1);
+    device.attach(&rec);
+    wait(3);
+    pc.printf("start at PC usb \r\n");
+    device.printf("start at P0_19,P0_18 \r\n");
+    i = 0;
+    t1.attach(&blink, 3.0);
+
+    /* initial the state machine */
+    state = STATE_A;
+    do_task(STATE_A);
+
+    while(1) {
+        /*
+        if(device.readable()) {
+            pc.putc(device.getc());
+        }
+        */
+
+        if(pc.readable()) {
+            //trigger = 1;
+            device.putc(pc.getc());
+        }
+
+        /* While I am not triggered, sleep */
+        //while (!trigger) {
+        //     sleep();
+        //}
+        /* I am awake now. Check which button has triggered*/
+        switch (state) {
+                //////////////////////////////////////////////////////////////////
+            case STATE_A:  ///////////////////////////////////////////////////
+                //////////////////////////////////////////////////////////////////
+                if (trigger & 0x02) { /* Button 1 down */
+                    pc.printf("STATE_A ");
+                    do_task(1);
+                    
+                    pc.printf("will enter STATE_B \r\n");
+                    state = STATE_B; /* Transit to STATE_B */
+                }
+                // trigger has to be set before state
+                //trigger = 0; /* Ignore other triggers in this state */
+                                
+                break;
+
+                //////////////////////////////////////////////////////////////////
+            case STATE_B:  ///////////////////////////////////////////////////
+                //////////////////////////////////////////////////////////////////
+                if (trigger & 0x04) { /* Button 1 down */
+                    pc.printf("STATE_B ");
+                    do_task(2);
+                    state = STATE_C;
+                    pc.printf("will enter STATE_C \r\n");
+                }
+                
+                //if (trigger & 0x02) { /* Button 2 down */
+                //    do_task(3);
+                    /* Remain in the same state */
+                //}
+                //if (trigger & 0x04) { /* Button 3 down */
+                //    do_task(4);
+                //    state = STATE_C;
+                //}               
+                
+                // trigger have to be set before state
+                //trigger = 0; /* Ignore other triggers in this state */
+                //state = STATE_A;
+                break;
+
+                //////////////////////////////////////////////////////////////////
+            case STATE_C:  ///////////////////////////////////////////////////
+                //////////////////////////////////////////////////////////////////
+                if (trigger & 0x08) { /* Button 3 down */
+                    pc.printf("STATE_C ");
+                    do_task(3);
+                    state = STATE_A;
+                    pc.printf("will enter STATE_A \r\n");
+                }
+                // trigger has to be set before state
+                //trigger = 0;
+                //state = STATE_A;
+                break;
+        } // switch
+
+    }//while(1)
 }
\ No newline at end of file