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

main.cpp

Committer:
oxtek
Date:
2015-11-22
Revision:
10:a358762e1188
Parent:
9:d88699a0905a

File content as of revision 10:a358762e1188:

#include "mbed.h"
#include "USBSerial.h"
#define MAX_SIZE 16
#include <ctype.h>

//Virtual serial port over USB
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)
}