/**********************************************************************\ * Kurzbeschreibung: automat.c * Stellt Funktionen zur Realisierung eines Automaten zur Verf�gung, * die �ber die in der automat.h vorgegebene C-Schnittstelle * mit einer grafischen Schnittstelle kommunizieren. * * Datum: Autor: Grund der Aenderung: * * \**********************************************************************/ #include #include #include #include "automat.h" typedef enum {A=0,B,C,D,E,F,G,H,I} state_t; typedef struct { int input; int mask; state_t nxtstate; } fsm_state_t; typedef struct { const fsm_state_t * transitions; int nrOfTransitions; state_t defaultNxtState; } fsm_full_state_t; #define SIZE_OF(a) (sizeof((a))/ sizeof(*(a))) #define NR_OF_STATES (I-A + 1) static state_t s_curstate = A; static const fsm_state_t s_transitions_A[] = { {0x002, ~0x004, B}, {0x003, ~0x004, C} }; static const fsm_state_t s_transitions_B[] = { {0x002, ~0x004, C}, {0x003, ~0x004, D} }; static const fsm_state_t s_transitions_C[] = { {0x002, ~0x004, D}, {0x003, ~0x000, F}, {0x007, ~0x000, H} }; static const fsm_state_t s_transitions_D[] = { {0x002, ~0x000, F}, {0x003, ~0x004, E}, {0x006, ~0x000, H} }; static const fsm_state_t s_transitions_E[] = { {0x006, ~0x000, H}, {0x002, ~0x004, F}, {0x003, ~0x004, G} }; static const fsm_state_t s_transitions_F[] = { {0x006, ~0x000, H} }; static const fsm_state_t s_transitions_G[] = { {0x006, ~0x000, I} }; static const fsm_state_t s_transitions_H[] = { {0x000, ~0x000, A} }; static const fsm_state_t s_transitions_I[] = { {0x000, ~0x000, A} }; static const fsm_full_state_t s_state_table[NR_OF_STATES] = { { s_transitions_A, SIZE_OF(s_transitions_A), A }, { s_transitions_B, SIZE_OF(s_transitions_B), B }, { s_transitions_C, SIZE_OF(s_transitions_C), C }, { s_transitions_D, SIZE_OF(s_transitions_D), D }, { s_transitions_E, SIZE_OF(s_transitions_E), E }, { s_transitions_F, SIZE_OF(s_transitions_F), F }, { s_transitions_G, SIZE_OF(s_transitions_G), G }, { s_transitions_H, SIZE_OF(s_transitions_H), H }, { s_transitions_I, SIZE_OF(s_transitions_I), I } }; static const fsm_action_t s_out_table[NR_OF_STATES] = { { false, false, false, 0, "Warten" }, // A { false, false, false, 1, "1 Euro" }, // B { false, false, false, 2, "2 Euro" }, // C { false, false, false, 3, "3 Euro" }, // D { true, false, false, 3, "3 Euro + M" }, // E { true, false, false, 4, "4 Euro" }, // F { true, true, false, 4, "4 Euro + M" }, // G { true, false, true, 4, "Kaffee" }, // H { false, false, false, 0, "Kaffee + M" } // I }; void automat_reset(void) { s_curstate = A; } void automat_transition(BOOL becher, BOOL muenze, BOOL muenz_wert) { int input = ((becher & 0x1) << 2) | ((muenze & 0x1) << 1) | (muenz_wert & 0x1); const fsm_full_state_t *current = &s_state_table[s_curstate]; for (int i = 0; i < current->nrOfTransitions; ++i) { if ((input & ~current->transitions[i].mask) == (current->transitions[i].input & ~current->transitions[i].mask)) { s_curstate = current->transitions[i].nxtstate; return; } } s_curstate = current->defaultNxtState; } fsm_action_t automat_output(void) { return s_out_table[s_curstate]; }