State machines are commonly used to implement decision making algorithms. State machines are used in applications where distinguishable states exist. A finite state machine (FSM) is based on the idea that a given system has a finite number of states.

Dependencies:   mbed

Fork of FRDM-K64F_FSM by Nikolaos Maliganis

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002  
00003 Serial pc(USBTX, USBRX);
00004  
00005 DigitalOut gpo1(D1);
00006 DigitalOut gpo2(D2);
00007 DigitalOut gpo3(D3);
00008 DigitalOut ledB(LED_BLUE);
00009 DigitalOut ledG(LED_GREEN);
00010 DigitalOut ledR(LED_RED);
00011 
00012 Ticker tick;
00013  
00014 typedef struct EventTag {
00015     uint16_t sig;                                    /* signal of the event */
00016 } Event;
00017 
00018 struct StateTableTag;                                /* forward declaration */
00019 
00020 typedef void (*Tran)(struct StateTableTag *me, Event const *e);
00021 
00022 typedef struct StateTableTag {
00023     uint8_t state;                              /* the current active state */
00024     uint8_t *st_desc;                           /* the current active state Name Descriprion */
00025     Tran const *state_table;                    /* the State-Table */
00026     uint8_t n_states;                           /* number of states */
00027     uint8_t n_signals;                          /* number of signals */
00028     Tran initial;                               /* the initial transition */
00029 } StateTable;
00030 
00031 void StTbl_ctor(StateTable *me,
00032                     Tran const *table, 
00033                     uint8_t n_states, 
00034                     uint8_t n_signals,
00035                     Tran initial);
00036                     
00037 void StTbl_init(StateTable *me);
00038 void StTbl_dispatch(StateTable *me, Event const *e);
00039 void StTbl_empty(StateTable *me, Event const *e);
00040 
00041 /* macro for taking a state transition inside a transition function */
00042 #define TRAN(target_)  (((StateTable *)me)->state = (uint8_t)(target_)) 
00043  
00044  void StTbl_ctor(StateTable *me,
00045 Tran const *table, uint8_t n_states, uint8_t n_signals,
00046 Tran initial)
00047 {
00048     me->state_table = table;
00049     me->n_states    = n_states;
00050     me->n_signals   = n_signals;
00051     me->initial     = initial;
00052 }
00053 
00054 void StTbl_init(StateTable *me) {
00055     me->state = me->n_states;
00056     (*me->initial)(me, (Event *)0);      
00057 }
00058 
00059 void StTbl_dispatch(StateTable *me, Event const *e) {
00060     Tran t;
00061 
00062     t = me->state_table[me->state*me->n_signals + e->sig];
00063     (*t)(me, e);                         
00064 }
00065 
00066 void StTbl_empty(StateTable *me, Event const *e) {
00067     (void)me;
00068     (void)e; 
00069 }
00070  
00071  typedef struct Tag {               /*  FSM */
00072     StateTable super;               /* derive from the StateTable structure */
00073     uint8_t timeout;                /* number of seconds till exp */
00074     uint8_t defuse;                 /* secret defuse code to disarm */
00075     uint8_t code;                   /* currently entered code to disarm  */
00076 } FSM1;
00077  
00078  
00079  enum FSMSignals {                          /* all signals for the Bomb FSM */
00080     GO_SIG,
00081     OUT_SIG,
00082     TICK_SIG,
00083     ERR_SIG,
00084     CONF_SIG,
00085     TRANADM_SIG,
00086 
00087     MAX_SIG                                        /* the number of signals */
00088 };
00089  
00090  enum FSMStates {
00091     SETTING_FSM_STATE,           /* Setting for FSM */
00092     READY_FSM_STATE,             /* Unassigned and Ready to be configured from PC */
00093     ASSIGNED_FSM_STATE,          /* Assigned to a user. None could use it apart from him.*/
00094     LOCKED_FSM_STATE,            /* Locked by user*/
00095     ERROR_STATE,                /* Error state. Only logging communication*/
00096     
00097     MAX_STATE
00098 };
00099   
00100  typedef struct TickEvtTag {
00101     Event super;                         /* derive from the Event structure */
00102     uint8_t fine_time;                           /* the fine 1/10 s counter */
00103 } TickEvt;
00104 
00105  
00106 static void FSM_initial (FSM1 *me, Event const *e)
00107 {
00108      (void)e;
00109      
00110     pc.printf("State --> Initial\n");
00111     TRAN(SETTING_FSM_STATE);
00112  }
00113 
00114 static void FSM_setting_GO    (FSM1 *me, Event const *e)
00115 {
00116     (void)e;
00117     pc.printf("State --> Setting - GO Event was caught\n");
00118     TRAN(READY_FSM_STATE);
00119 }
00120 
00121 static void FSM_setting_OUT   (FSM1 *me, Event const *e)
00122 {
00123     (void)e;
00124     pc.printf("State --> Setting - OUT Event was caught\n");
00125 }
00126 
00127 static void FSM_setting_ERR   (FSM1 *me, Event const *e)
00128 {
00129     (void)e;
00130     pc.printf("State --> Setting - ERR Event was caught\n");
00131     TRAN(ERROR_STATE);
00132 }
00133 
00134 static void FSM_setting_TRAN  (FSM1 *me, Event const *e)
00135 {
00136     (void)e;
00137     pc.printf("State --> Setting - TRAN ADMIN Event was caught\n");
00138 }
00139 
00140 static void FSM_ready_GO      (FSM1 *me, Event const *e)
00141 {
00142     (void)e;
00143     pc.printf("State --> Ready - GO Event was caught\n");
00144     TRAN(ASSIGNED_FSM_STATE);
00145 }
00146 
00147 static void FSM_ready_OUT     (FSM1 *me, Event const *e)
00148 {
00149     (void)e;
00150     pc.printf("State --> Ready - OUT Event was caught\n");
00151 }
00152 
00153 static void FSM_ready_TICK    (FSM1 *me, Event const *e)
00154 {
00155     (void)e;
00156     pc.printf("State --> Ready - TICK Event was caught\n");
00157 }
00158 
00159 static void FSM_ready_ERR     (FSM1 *me, Event const *e)
00160 {
00161     (void)e;
00162     pc.printf("State --> Ready - ERR Event was caught\n");
00163     TRAN(ERROR_STATE);
00164     
00165 }
00166 
00167 static void FSM_ready_CONF    (FSM1 *me, Event const *e)
00168 {
00169     (void)e;
00170     pc.printf("State --> Ready - CONF Event was caught\n");
00171     TRAN(SETTING_FSM_STATE); 
00172     
00173 }
00174 
00175 static void FSM_ready_TRAN    (FSM1 *me, Event const *e)
00176 {
00177     (void)e;
00178     pc.printf("State --> Ready - TRAN ADMIN Event was caught\n");
00179 }
00180 
00181 static void FSM_assigned_GO   (FSM1 *me, Event const *e)
00182 {
00183     (void)e;
00184     pc.printf("State --> Assigned - GO Event was caught\n");
00185     TRAN(LOCKED_FSM_STATE);
00186 }
00187 
00188 static void FSM_assigned_OUT  (FSM1 *me, Event const *e)
00189 {
00190     (void)e;    
00191     pc.printf("State --> Assigned - OUT Event was caught\n");
00192     TRAN(READY_FSM_STATE);
00193 }
00194 
00195 static void FSM_assigned_TICK (FSM1 *me, Event const *e)
00196 {
00197     (void)e;    
00198     pc.printf("State --> Assigned - TICK Event was caught\n");
00199 
00200 }
00201 
00202 static void FSM_assigned_ERR  (FSM1 *me, Event const *e)
00203 {
00204     (void)e;
00205     pc.printf("State --> Assigned - ERR Event was caught\n");
00206     TRAN(ERROR_STATE);
00207     
00208 }
00209 
00210 static void FSM_assigned_CONF (FSM1 *me, Event const *e)
00211 {
00212     (void)e;
00213     pc.printf("State --> Assigned - CONF Event was caught\n");
00214     TRAN(SETTING_FSM_STATE);
00215     
00216 }
00217 
00218 static void FSM_assigned_TRAN (FSM1 *me, Event const *e)
00219 {
00220     (void)e;
00221     pc.printf("State --> Assigned - TRAN ADMIN Event was caught\n");
00222     
00223 }
00224 
00225 static void FSM_locked_GO     (FSM1 *me, Event const *e)
00226 {
00227     (void)e;
00228     pc.printf("State --> Locked - GO Event was caught\n");
00229     
00230 }
00231 
00232 static void FSM_locked_OUT    (FSM1 *me, Event const *e)
00233 {
00234     (void)e;
00235     pc.printf("State --> Locked - OUT Event was caught\n");
00236     TRAN(ASSIGNED_FSM_STATE);
00237 
00238 }
00239 
00240 static void FSM_locked_TICK   (FSM1 *me, Event const *e)
00241 {
00242     (void)e;    
00243     pc.printf("State --> Locked - TICK Event was caught\n");
00244 
00245 }
00246 
00247 static void FSM_locked_ERR    (FSM1 *me, Event const *e)
00248 {
00249     (void)e;    
00250     pc.printf("State --> Locked - ERR Event was caught\n");
00251     TRAN(ERROR_STATE);
00252 
00253 }
00254 
00255 static void FSM_locked_CONF   (FSM1 *me, Event const *e)
00256 {
00257     (void)e;
00258     pc.printf("State --> Locked - CONF Event was caught\n");
00259     TRAN(SETTING_FSM_STATE);
00260     
00261 }
00262 
00263 static void FSM_locked_TRAN   (FSM1 *me, Event const *e)
00264 {
00265     (void)e;    
00266     pc.printf("State --> Locked - TRAN ADMIN Event was caught\n");
00267     
00268 }
00269  
00270  
00271 void FSM_ctor(FSM1 *me, uint8_t defuse) {
00272 
00273      static const Tran fsm_state_table[MAX_STATE][MAX_SIG] =
00274     {
00275         {(Tran)&FSM_setting_GO,  (Tran)&FSM_setting_OUT,  &StTbl_empty, (Tran)&FSM_setting_ERR, &StTbl_empty, (Tran)&FSM_setting_TRAN },
00276         {(Tran)&FSM_ready_GO,    (Tran)&FSM_ready_OUT,    (Tran)&FSM_ready_TICK, (Tran)&FSM_ready_ERR, (Tran)&FSM_ready_CONF, (Tran)&FSM_ready_TRAN },
00277         {(Tran)&FSM_assigned_GO, (Tran)&FSM_assigned_OUT, (Tran)&FSM_assigned_TICK, (Tran)&FSM_assigned_ERR, (Tran)&FSM_assigned_CONF, (Tran)&FSM_assigned_TRAN },
00278         {(Tran)&FSM_locked_GO,   (Tran)&FSM_locked_OUT,   (Tran)&FSM_locked_TICK, (Tran)&FSM_locked_ERR, (Tran)&FSM_locked_CONF, (Tran)&FSM_locked_TRAN }
00279     };
00280     
00281     StTbl_ctor(&me->super, &fsm_state_table[0][0], MAX_STATE, MAX_SIG, (Tran)&FSM_initial);
00282     
00283     me->defuse = defuse;
00284 }
00285 
00286 bool _t1_OVRFL = false;
00287  // ISR Timer per 1sec
00288  void ISR(void) {
00289     _t1_OVRFL = true;
00290 }
00291 
00292 char cmd;
00293 bool _pc_GTCMD = false;
00294 // ISR when Gets command
00295 void Serial_ISR(void) {
00296     _pc_GTCMD = true;
00297     cmd = pc.getc(); //Gets the command
00298 }
00299 
00300 int main()
00301 {
00302 
00303     pc.baud(9600);
00304     pc.attach(&Serial_ISR);
00305     tick.attach(&ISR, 1.0);
00306 
00307     static FSM1 _frdm_fsm;
00308     static Event const go_evt     = { GO_SIG   };
00309     static Event const out_evt    = { OUT_SIG };
00310     static Event const err_evt    = { ERR_SIG };
00311     static Event const conf_evt   = { CONF_SIG };
00312     static TickEvt tick_evt       = { TICK_SIG, 0};
00313 
00314     FSM_ctor(&_frdm_fsm, 0xFF);
00315     
00316     StTbl_init((StateTable *)&_frdm_fsm);
00317     
00318     pc.printf("Frdm K64F FSM App\r\n");
00319     Event const *e = (Event *)0;
00320        
00321     while (true) {
00322         
00323         pc.printf("Running\r\n\n");
00324         gpo1 = !gpo1; // toggle pin
00325         ledB = !ledB; // toggle led
00326         wait(0.2f);
00327         
00328         if(_t1_OVRFL)
00329         {
00330             _t1_OVRFL = false;
00331                 StTbl_dispatch((StateTable *)&_frdm_fsm, (Event *)&tick_evt);
00332         }
00333         
00334         switch (cmd) 
00335         {
00336             case 'G': {
00337                 pc.printf(" Go received \n");
00338                 e = &go_evt;
00339                 break;
00340             }
00341             case 'O': {
00342                 pc.printf(" Out Received \n");
00343                 e = &out_evt;
00344                 break;
00345             }
00346             case 'E': {
00347                 pc.printf(" Error Received \n");
00348                 e = &err_evt;
00349                 break;
00350             }
00351             case 'C': {
00352                 pc.printf(" Config Received \n");
00353                 e = &conf_evt;
00354                 break;
00355             }
00356         }
00357         if(_pc_GTCMD)
00358         {
00359             _pc_GTCMD = false;
00360             if (e != (Event *)0)
00361             {
00362                StTbl_dispatch((StateTable *)&_frdm_fsm, e);
00363             }
00364         }
00365         
00366     }
00367 }
00368