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
Diff: main.cpp
- 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); + } + } + + } +} +