Finite State Machine move between STATE virtual com port USB connect to PC while UART connect to modem
Fork of USBSerial_HelloWorld by
main.cpp@10:a358762e1188, 2015-11-22 (annotated)
- Committer:
- oxtek
- Date:
- Sun Nov 22 09:44:43 2015 +0000
- Revision:
- 10:a358762e1188
- Parent:
- 9:d88699a0905a
usb as virtual com port connect to PC and UART connect to modem
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
samux | 7:5e693654d5b4 | 1 | #include "mbed.h" |
samux | 7:5e693654d5b4 | 2 | #include "USBSerial.h" |
oxtek | 10:a358762e1188 | 3 | #define MAX_SIZE 16 |
oxtek | 10:a358762e1188 | 4 | #include <ctype.h> |
oxtek | 10:a358762e1188 | 5 | |
samux | 7:5e693654d5b4 | 6 | //Virtual serial port over USB |
oxtek | 10:a358762e1188 | 7 | USBSerial pc; |
oxtek | 10:a358762e1188 | 8 | DigitalOut WDO(P0_20); |
oxtek | 10:a358762e1188 | 9 | DigitalOut LED(P0_7); |
oxtek | 10:a358762e1188 | 10 | |
oxtek | 10:a358762e1188 | 11 | |
oxtek | 10:a358762e1188 | 12 | |
oxtek | 10:a358762e1188 | 13 | Serial device(P0_19, P0_18); // tx, rx of RS232 pins |
oxtek | 10:a358762e1188 | 14 | Timeout flipper; |
oxtek | 10:a358762e1188 | 15 | char buf[MAX_SIZE]; |
oxtek | 10:a358762e1188 | 16 | char data[MAX_SIZE]; |
oxtek | 10:a358762e1188 | 17 | unsigned int i,j; |
oxtek | 10:a358762e1188 | 18 | bool begin_msg=false; |
oxtek | 10:a358762e1188 | 19 | |
oxtek | 10:a358762e1188 | 20 | Ticker t1; |
oxtek | 10:a358762e1188 | 21 | |
oxtek | 10:a358762e1188 | 22 | // ****************************************************** |
oxtek | 10:a358762e1188 | 23 | // Finite State Machine Declare variable |
oxtek | 10:a358762e1188 | 24 | // ****************************************************** |
oxtek | 10:a358762e1188 | 25 | |
oxtek | 10:a358762e1188 | 26 | |
oxtek | 10:a358762e1188 | 27 | /* Various states */ |
oxtek | 10:a358762e1188 | 28 | typedef enum tState { |
oxtek | 10:a358762e1188 | 29 | STATE_A, |
oxtek | 10:a358762e1188 | 30 | STATE_B, |
oxtek | 10:a358762e1188 | 31 | STATE_C |
oxtek | 10:a358762e1188 | 32 | } tState; |
oxtek | 10:a358762e1188 | 33 | |
oxtek | 10:a358762e1188 | 34 | /* Variables */ |
oxtek | 10:a358762e1188 | 35 | tState state; /* Current state */ |
oxtek | 10:a358762e1188 | 36 | volatile unsigned char trigger; /* Bit set to indicate which button triggers */ |
oxtek | 10:a358762e1188 | 37 | |
oxtek | 10:a358762e1188 | 38 | |
oxtek | 10:a358762e1188 | 39 | |
oxtek | 10:a358762e1188 | 40 | /* task to be executed during each state transition */ |
oxtek | 10:a358762e1188 | 41 | void do_task(int n) |
oxtek | 10:a358762e1188 | 42 | { |
oxtek | 10:a358762e1188 | 43 | pc.printf("Task: %d \r\n", n); |
oxtek | 10:a358762e1188 | 44 | wait(0.5); |
oxtek | 10:a358762e1188 | 45 | trigger = 0; |
oxtek | 10:a358762e1188 | 46 | pc.printf("Task %d done ... trigger=%d\r\n\r\n", n, trigger); |
oxtek | 10:a358762e1188 | 47 | |
oxtek | 10:a358762e1188 | 48 | } |
oxtek | 10:a358762e1188 | 49 | |
oxtek | 10:a358762e1188 | 50 | void sleep(void) |
oxtek | 10:a358762e1188 | 51 | { |
oxtek | 10:a358762e1188 | 52 | __WFI(); /* Power-saving sleeping mode */ |
oxtek | 10:a358762e1188 | 53 | } |
oxtek | 10:a358762e1188 | 54 | |
oxtek | 10:a358762e1188 | 55 | // *************************************************** |
oxtek | 10:a358762e1188 | 56 | // End of Finite State Machine declare variable |
oxtek | 10:a358762e1188 | 57 | // *************************************************** |
oxtek | 10:a358762e1188 | 58 | |
oxtek | 10:a358762e1188 | 59 | |
oxtek | 10:a358762e1188 | 60 | void determine_event(){ |
oxtek | 10:a358762e1188 | 61 | if ( strstr(data, "OK") != NULL ){ |
oxtek | 10:a358762e1188 | 62 | trigger = 0x02; |
oxtek | 10:a358762e1188 | 63 | } |
oxtek | 10:a358762e1188 | 64 | else if ( strstr(data, "ERROR") != NULL){ |
oxtek | 10:a358762e1188 | 65 | trigger = 0x04; |
oxtek | 10:a358762e1188 | 66 | } |
oxtek | 10:a358762e1188 | 67 | else{ |
oxtek | 10:a358762e1188 | 68 | trigger = 0x08; |
oxtek | 10:a358762e1188 | 69 | } |
oxtek | 10:a358762e1188 | 70 | |
oxtek | 10:a358762e1188 | 71 | } |
oxtek | 10:a358762e1188 | 72 | |
oxtek | 10:a358762e1188 | 73 | |
oxtek | 10:a358762e1188 | 74 | |
oxtek | 10:a358762e1188 | 75 | // process to run after timeout in receiving char from serial device ( device.getc() ) |
oxtek | 10:a358762e1188 | 76 | void printout() |
oxtek | 10:a358762e1188 | 77 | { |
oxtek | 10:a358762e1188 | 78 | //for ( j=0; j<MAX_SIZE; j++) { // Put the character received into the computer. |
oxtek | 10:a358762e1188 | 79 | // pc.putc(buf[j]); |
oxtek | 10:a358762e1188 | 80 | // data[j] = buf[j]; |
oxtek | 10:a358762e1188 | 81 | // buf[j] = 0; |
oxtek | 10:a358762e1188 | 82 | //} |
oxtek | 10:a358762e1188 | 83 | |
oxtek | 10:a358762e1188 | 84 | memcpy(data, buf, MAX_SIZE); |
oxtek | 10:a358762e1188 | 85 | memset(buf, 0, MAX_SIZE*sizeof(unsigned char) ); |
oxtek | 10:a358762e1188 | 86 | i = 0; //reset index |
oxtek | 10:a358762e1188 | 87 | pc.printf(" data=%s<--\r\n", data); |
oxtek | 10:a358762e1188 | 88 | |
oxtek | 10:a358762e1188 | 89 | determine_event(); |
oxtek | 10:a358762e1188 | 90 | } |
oxtek | 10:a358762e1188 | 91 | void time_out() |
oxtek | 10:a358762e1188 | 92 | { |
oxtek | 10:a358762e1188 | 93 | printout(); |
oxtek | 10:a358762e1188 | 94 | //pc.printf("time out\n"); |
oxtek | 10:a358762e1188 | 95 | flipper.detach(); //reset timer |
oxtek | 10:a358762e1188 | 96 | } |
oxtek | 10:a358762e1188 | 97 | |
oxtek | 10:a358762e1188 | 98 | // char receive within window size (MAX_SIZE) or within window time (start_timer) otherwise discard |
oxtek | 10:a358762e1188 | 99 | void check_frame() |
oxtek | 10:a358762e1188 | 100 | { |
oxtek | 10:a358762e1188 | 101 | //pc.printf(" i=%d \n",i); |
oxtek | 10:a358762e1188 | 102 | if ( i == 0 ) { // if the 1st char receive |
oxtek | 10:a358762e1188 | 103 | flipper.attach(&time_out, 3 ); //start_timer |
oxtek | 10:a358762e1188 | 104 | pc.printf("data in UART start timer ... "); |
oxtek | 10:a358762e1188 | 105 | } |
oxtek | 10:a358762e1188 | 106 | if ( i >= MAX_SIZE ) { // char i receive exceed window size |
oxtek | 10:a358762e1188 | 107 | printout(); |
oxtek | 10:a358762e1188 | 108 | } else { // char i still in window size |
oxtek | 10:a358762e1188 | 109 | i++; // continue count |
samux | 7:5e693654d5b4 | 110 | } |
oxtek | 10:a358762e1188 | 111 | |
oxtek | 10:a358762e1188 | 112 | } |
oxtek | 10:a358762e1188 | 113 | |
oxtek | 10:a358762e1188 | 114 | void rec() // Here's my serial interrupt routine. |
oxtek | 10:a358762e1188 | 115 | { |
oxtek | 10:a358762e1188 | 116 | if ( device.readable() ) { |
oxtek | 10:a358762e1188 | 117 | trigger = 0; |
oxtek | 10:a358762e1188 | 118 | //pc.printf("device.readable() there is some input in i=%d\r\n",i); |
oxtek | 10:a358762e1188 | 119 | buf[i] = device.getc(); |
oxtek | 10:a358762e1188 | 120 | check_frame(); |
oxtek | 10:a358762e1188 | 121 | } else { |
oxtek | 10:a358762e1188 | 122 | pc.printf(" device.readable() is not ready \n"); |
oxtek | 10:a358762e1188 | 123 | } |
oxtek | 10:a358762e1188 | 124 | } // interrupt is done. |
oxtek | 10:a358762e1188 | 125 | |
oxtek | 10:a358762e1188 | 126 | void blink() |
oxtek | 10:a358762e1188 | 127 | { |
oxtek | 10:a358762e1188 | 128 | LED = !LED; |
oxtek | 10:a358762e1188 | 129 | WDO = !WDO; |
oxtek | 10:a358762e1188 | 130 | } |
oxtek | 10:a358762e1188 | 131 | |
oxtek | 10:a358762e1188 | 132 | |
oxtek | 10:a358762e1188 | 133 | int main(void) |
oxtek | 10:a358762e1188 | 134 | { |
oxtek | 10:a358762e1188 | 135 | |
oxtek | 10:a358762e1188 | 136 | device.baud(115200); |
oxtek | 10:a358762e1188 | 137 | |
oxtek | 10:a358762e1188 | 138 | wait(1); |
oxtek | 10:a358762e1188 | 139 | device.attach(&rec); |
oxtek | 10:a358762e1188 | 140 | wait(3); |
oxtek | 10:a358762e1188 | 141 | pc.printf("start at PC usb \r\n"); |
oxtek | 10:a358762e1188 | 142 | device.printf("start at P0_19,P0_18 \r\n"); |
oxtek | 10:a358762e1188 | 143 | i = 0; |
oxtek | 10:a358762e1188 | 144 | t1.attach(&blink, 3.0); |
oxtek | 10:a358762e1188 | 145 | |
oxtek | 10:a358762e1188 | 146 | /* initial the state machine */ |
oxtek | 10:a358762e1188 | 147 | state = STATE_A; |
oxtek | 10:a358762e1188 | 148 | do_task(STATE_A); |
oxtek | 10:a358762e1188 | 149 | |
oxtek | 10:a358762e1188 | 150 | while(1) { |
oxtek | 10:a358762e1188 | 151 | /* |
oxtek | 10:a358762e1188 | 152 | if(device.readable()) { |
oxtek | 10:a358762e1188 | 153 | pc.putc(device.getc()); |
oxtek | 10:a358762e1188 | 154 | } |
oxtek | 10:a358762e1188 | 155 | */ |
oxtek | 10:a358762e1188 | 156 | |
oxtek | 10:a358762e1188 | 157 | if(pc.readable()) { |
oxtek | 10:a358762e1188 | 158 | //trigger = 1; |
oxtek | 10:a358762e1188 | 159 | device.putc(pc.getc()); |
oxtek | 10:a358762e1188 | 160 | } |
oxtek | 10:a358762e1188 | 161 | |
oxtek | 10:a358762e1188 | 162 | /* While I am not triggered, sleep */ |
oxtek | 10:a358762e1188 | 163 | //while (!trigger) { |
oxtek | 10:a358762e1188 | 164 | // sleep(); |
oxtek | 10:a358762e1188 | 165 | //} |
oxtek | 10:a358762e1188 | 166 | /* I am awake now. Check which button has triggered*/ |
oxtek | 10:a358762e1188 | 167 | switch (state) { |
oxtek | 10:a358762e1188 | 168 | ////////////////////////////////////////////////////////////////// |
oxtek | 10:a358762e1188 | 169 | case STATE_A: /////////////////////////////////////////////////// |
oxtek | 10:a358762e1188 | 170 | ////////////////////////////////////////////////////////////////// |
oxtek | 10:a358762e1188 | 171 | if (trigger & 0x02) { /* Button 1 down */ |
oxtek | 10:a358762e1188 | 172 | pc.printf("STATE_A "); |
oxtek | 10:a358762e1188 | 173 | do_task(1); |
oxtek | 10:a358762e1188 | 174 | |
oxtek | 10:a358762e1188 | 175 | pc.printf("will enter STATE_B \r\n"); |
oxtek | 10:a358762e1188 | 176 | state = STATE_B; /* Transit to STATE_B */ |
oxtek | 10:a358762e1188 | 177 | } |
oxtek | 10:a358762e1188 | 178 | // trigger has to be set before state |
oxtek | 10:a358762e1188 | 179 | //trigger = 0; /* Ignore other triggers in this state */ |
oxtek | 10:a358762e1188 | 180 | |
oxtek | 10:a358762e1188 | 181 | break; |
oxtek | 10:a358762e1188 | 182 | |
oxtek | 10:a358762e1188 | 183 | ////////////////////////////////////////////////////////////////// |
oxtek | 10:a358762e1188 | 184 | case STATE_B: /////////////////////////////////////////////////// |
oxtek | 10:a358762e1188 | 185 | ////////////////////////////////////////////////////////////////// |
oxtek | 10:a358762e1188 | 186 | if (trigger & 0x04) { /* Button 1 down */ |
oxtek | 10:a358762e1188 | 187 | pc.printf("STATE_B "); |
oxtek | 10:a358762e1188 | 188 | do_task(2); |
oxtek | 10:a358762e1188 | 189 | state = STATE_C; |
oxtek | 10:a358762e1188 | 190 | pc.printf("will enter STATE_C \r\n"); |
oxtek | 10:a358762e1188 | 191 | } |
oxtek | 10:a358762e1188 | 192 | |
oxtek | 10:a358762e1188 | 193 | //if (trigger & 0x02) { /* Button 2 down */ |
oxtek | 10:a358762e1188 | 194 | // do_task(3); |
oxtek | 10:a358762e1188 | 195 | /* Remain in the same state */ |
oxtek | 10:a358762e1188 | 196 | //} |
oxtek | 10:a358762e1188 | 197 | //if (trigger & 0x04) { /* Button 3 down */ |
oxtek | 10:a358762e1188 | 198 | // do_task(4); |
oxtek | 10:a358762e1188 | 199 | // state = STATE_C; |
oxtek | 10:a358762e1188 | 200 | //} |
oxtek | 10:a358762e1188 | 201 | |
oxtek | 10:a358762e1188 | 202 | // trigger have to be set before state |
oxtek | 10:a358762e1188 | 203 | //trigger = 0; /* Ignore other triggers in this state */ |
oxtek | 10:a358762e1188 | 204 | //state = STATE_A; |
oxtek | 10:a358762e1188 | 205 | break; |
oxtek | 10:a358762e1188 | 206 | |
oxtek | 10:a358762e1188 | 207 | ////////////////////////////////////////////////////////////////// |
oxtek | 10:a358762e1188 | 208 | case STATE_C: /////////////////////////////////////////////////// |
oxtek | 10:a358762e1188 | 209 | ////////////////////////////////////////////////////////////////// |
oxtek | 10:a358762e1188 | 210 | if (trigger & 0x08) { /* Button 3 down */ |
oxtek | 10:a358762e1188 | 211 | pc.printf("STATE_C "); |
oxtek | 10:a358762e1188 | 212 | do_task(3); |
oxtek | 10:a358762e1188 | 213 | state = STATE_A; |
oxtek | 10:a358762e1188 | 214 | pc.printf("will enter STATE_A \r\n"); |
oxtek | 10:a358762e1188 | 215 | } |
oxtek | 10:a358762e1188 | 216 | // trigger has to be set before state |
oxtek | 10:a358762e1188 | 217 | //trigger = 0; |
oxtek | 10:a358762e1188 | 218 | //state = STATE_A; |
oxtek | 10:a358762e1188 | 219 | break; |
oxtek | 10:a358762e1188 | 220 | } // switch |
oxtek | 10:a358762e1188 | 221 | |
oxtek | 10:a358762e1188 | 222 | }//while(1) |
samux | 7:5e693654d5b4 | 223 | } |