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

Revision:
0:17539d6d4289
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Aug 07 15:02:42 2014 +0000
@@ -0,0 +1,368 @@
+#include "mbed.h"
+ 
+Serial pc(USBTX, USBRX);
+ 
+DigitalOut gpo1(D1);
+DigitalOut gpo2(D2);
+DigitalOut gpo3(D3);
+DigitalOut ledB(LED_BLUE);
+DigitalOut ledG(LED_GREEN);
+DigitalOut ledR(LED_RED);
+
+Ticker tick;
+ 
+typedef struct EventTag {
+    uint16_t sig;                                    /* signal of the event */
+} Event;
+
+struct StateTableTag;                                /* forward declaration */
+
+typedef void (*Tran)(struct StateTableTag *me, Event const *e);
+
+typedef struct StateTableTag {
+    uint8_t state;                              /* the current active state */
+    uint8_t *st_desc;                           /* the current active state Name Descriprion */
+    Tran const *state_table;                    /* the State-Table */
+    uint8_t n_states;                           /* number of states */
+    uint8_t n_signals;                          /* number of signals */
+    Tran initial;                               /* the initial transition */
+} StateTable;
+
+void StTbl_ctor(StateTable *me,
+                    Tran const *table, 
+                    uint8_t n_states, 
+                    uint8_t n_signals,
+                    Tran initial);
+                    
+void StTbl_init(StateTable *me);
+void StTbl_dispatch(StateTable *me, Event const *e);
+void StTbl_empty(StateTable *me, Event const *e);
+
+/* macro for taking a state transition inside a transition function */
+#define TRAN(target_)  (((StateTable *)me)->state = (uint8_t)(target_)) 
+ 
+ void StTbl_ctor(StateTable *me,
+Tran const *table, uint8_t n_states, uint8_t n_signals,
+Tran initial)
+{
+    me->state_table = table;
+    me->n_states    = n_states;
+    me->n_signals   = n_signals;
+    me->initial     = initial;
+}
+
+void StTbl_init(StateTable *me) {
+    me->state = me->n_states;
+    (*me->initial)(me, (Event *)0);      
+}
+
+void StTbl_dispatch(StateTable *me, Event const *e) {
+    Tran t;
+
+    t = me->state_table[me->state*me->n_signals + e->sig];
+    (*t)(me, e);                         
+}
+
+void StTbl_empty(StateTable *me, Event const *e) {
+    (void)me;
+    (void)e; 
+}
+ 
+ typedef struct Tag {               /*  FSM */
+    StateTable super;               /* derive from the StateTable structure */
+    uint8_t timeout;                /* number of seconds till exp */
+    uint8_t defuse;                 /* secret defuse code to disarm */
+    uint8_t code;                   /* currently entered code to disarm  */
+} FSM1;
+ 
+ 
+ enum FSMSignals {                          /* all signals for the Bomb FSM */
+    GO_SIG,
+    OUT_SIG,
+    TICK_SIG,
+    ERR_SIG,
+    CONF_SIG,
+    TRANADM_SIG,
+
+    MAX_SIG                                        /* the number of signals */
+};
+ 
+ enum FSMStates {
+    SETTING_FSM_STATE,           /* Setting for FSM */
+    READY_FSM_STATE,             /* Unassigned and Ready to be configured from PC */
+    ASSIGNED_FSM_STATE,          /* Assigned to a user. None could use it apart from him.*/
+    LOCKED_FSM_STATE,            /* Locked by user*/
+    ERROR_STATE,                /* Error state. Only logging communication*/
+    
+    MAX_STATE
+};
+  
+ typedef struct TickEvtTag {
+    Event super;                         /* derive from the Event structure */
+    uint8_t fine_time;                           /* the fine 1/10 s counter */
+} TickEvt;
+
+ 
+static void FSM_initial (FSM1 *me, Event const *e)
+{
+     (void)e;
+     
+    pc.printf("State --> Initial\n");
+    TRAN(SETTING_FSM_STATE);
+ }
+
+static void FSM_setting_GO    (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Setting - GO Event was caught\n");
+    TRAN(READY_FSM_STATE);
+}
+
+static void FSM_setting_OUT   (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Setting - OUT Event was caught\n");
+}
+
+static void FSM_setting_ERR   (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Setting - ERR Event was caught\n");
+    TRAN(ERROR_STATE);
+}
+
+static void FSM_setting_TRAN  (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Setting - TRAN ADMIN Event was caught\n");
+}
+
+static void FSM_ready_GO      (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Ready - GO Event was caught\n");
+    TRAN(ASSIGNED_FSM_STATE);
+}
+
+static void FSM_ready_OUT     (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Ready - OUT Event was caught\n");
+}
+
+static void FSM_ready_TICK    (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Ready - TICK Event was caught\n");
+}
+
+static void FSM_ready_ERR     (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Ready - ERR Event was caught\n");
+    TRAN(ERROR_STATE);
+    
+}
+
+static void FSM_ready_CONF    (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Ready - CONF Event was caught\n");
+    TRAN(SETTING_FSM_STATE); 
+    
+}
+
+static void FSM_ready_TRAN    (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Ready - TRAN ADMIN Event was caught\n");
+}
+
+static void FSM_assigned_GO   (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Assigned - GO Event was caught\n");
+    TRAN(LOCKED_FSM_STATE);
+}
+
+static void FSM_assigned_OUT  (FSM1 *me, Event const *e)
+{
+    (void)e;    
+    pc.printf("State --> Assigned - OUT Event was caught\n");
+    TRAN(READY_FSM_STATE);
+}
+
+static void FSM_assigned_TICK (FSM1 *me, Event const *e)
+{
+    (void)e;    
+    pc.printf("State --> Assigned - TICK Event was caught\n");
+
+}
+
+static void FSM_assigned_ERR  (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Assigned - ERR Event was caught\n");
+    TRAN(ERROR_STATE);
+    
+}
+
+static void FSM_assigned_CONF (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Assigned - CONF Event was caught\n");
+    TRAN(SETTING_FSM_STATE);
+    
+}
+
+static void FSM_assigned_TRAN (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Assigned - TRAN ADMIN Event was caught\n");
+    
+}
+
+static void FSM_locked_GO     (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Locked - GO Event was caught\n");
+    
+}
+
+static void FSM_locked_OUT    (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Locked - OUT Event was caught\n");
+    TRAN(ASSIGNED_FSM_STATE);
+
+}
+
+static void FSM_locked_TICK   (FSM1 *me, Event const *e)
+{
+    (void)e;    
+    pc.printf("State --> Locked - TICK Event was caught\n");
+
+}
+
+static void FSM_locked_ERR    (FSM1 *me, Event const *e)
+{
+    (void)e;    
+    pc.printf("State --> Locked - ERR Event was caught\n");
+    TRAN(ERROR_STATE);
+
+}
+
+static void FSM_locked_CONF   (FSM1 *me, Event const *e)
+{
+    (void)e;
+    pc.printf("State --> Locked - CONF Event was caught\n");
+    TRAN(SETTING_FSM_STATE);
+    
+}
+
+static void FSM_locked_TRAN   (FSM1 *me, Event const *e)
+{
+    (void)e;    
+    pc.printf("State --> Locked - TRAN ADMIN Event was caught\n");
+    
+}
+ 
+ 
+void FSM_ctor(FSM1 *me, uint8_t defuse) {
+
+     static const Tran fsm_state_table[MAX_STATE][MAX_SIG] =
+    {
+        {(Tran)&FSM_setting_GO,  (Tran)&FSM_setting_OUT,  &StTbl_empty, (Tran)&FSM_setting_ERR, &StTbl_empty, (Tran)&FSM_setting_TRAN },
+        {(Tran)&FSM_ready_GO,    (Tran)&FSM_ready_OUT,    (Tran)&FSM_ready_TICK, (Tran)&FSM_ready_ERR, (Tran)&FSM_ready_CONF, (Tran)&FSM_ready_TRAN },
+        {(Tran)&FSM_assigned_GO, (Tran)&FSM_assigned_OUT, (Tran)&FSM_assigned_TICK, (Tran)&FSM_assigned_ERR, (Tran)&FSM_assigned_CONF, (Tran)&FSM_assigned_TRAN },
+        {(Tran)&FSM_locked_GO,   (Tran)&FSM_locked_OUT,   (Tran)&FSM_locked_TICK, (Tran)&FSM_locked_ERR, (Tran)&FSM_locked_CONF, (Tran)&FSM_locked_TRAN }
+    };
+    
+    StTbl_ctor(&me->super, &fsm_state_table[0][0], MAX_STATE, MAX_SIG, (Tran)&FSM_initial);
+    
+    me->defuse = defuse;
+}
+
+bool _t1_OVRFL = false;
+ // ISR Timer per 1sec
+ void ISR(void) {
+    _t1_OVRFL = true;
+}
+
+char cmd;
+bool _pc_GTCMD = false;
+// ISR when Gets command
+void Serial_ISR(void) {
+    _pc_GTCMD = true;
+    cmd = pc.getc(); //Gets the command
+}
+
+int main()
+{
+
+    pc.baud(9600);
+    pc.attach(&Serial_ISR);
+    tick.attach(&ISR, 1.0);
+
+    static FSM1 _frdm_fsm;
+    static Event const go_evt     = { GO_SIG   };
+    static Event const out_evt    = { OUT_SIG };
+    static Event const err_evt    = { ERR_SIG };
+    static Event const conf_evt   = { CONF_SIG };
+    static TickEvt tick_evt       = { TICK_SIG, 0};
+
+    FSM_ctor(&_frdm_fsm, 0xFF);
+    
+    StTbl_init((StateTable *)&_frdm_fsm);
+    
+    pc.printf("Frdm K64F FSM App\r\n");
+    Event const *e = (Event *)0;
+       
+    while (true) {
+        
+        pc.printf("Running\r\n\n");
+        gpo1 = !gpo1; // toggle pin
+        ledB = !ledB; // toggle led
+        wait(0.2f);
+        
+        if(_t1_OVRFL)
+        {
+            _t1_OVRFL = false;
+                StTbl_dispatch((StateTable *)&_frdm_fsm, (Event *)&tick_evt);
+        }
+        
+        switch (cmd) 
+        {
+            case 'G': {
+                pc.printf(" Go received \n");
+                e = &go_evt;
+                break;
+            }
+            case 'O': {
+                pc.printf(" Out Received \n");
+                e = &out_evt;
+                break;
+            }
+            case 'E': {
+                pc.printf(" Error Received \n");
+                e = &err_evt;
+                break;
+            }
+            case 'C': {
+                pc.printf(" Config Received \n");
+                e = &conf_evt;
+                break;
+            }
+        }
+        if(_pc_GTCMD)
+        {
+            _pc_GTCMD = false;
+            if (e != (Event *)0)
+            {
+               StTbl_dispatch((StateTable *)&_frdm_fsm, e);
+            }
+        }
+        
+    }
+}
+