From dee86bd16eba1a6e80292da346964703bca3c134 Mon Sep 17 00:00:00 2001 From: Jerome Jutteau Date: Tue, 5 Mar 2013 19:48:42 +0100 Subject: digital/ai/src/fsm: new return system --- digital/ai/src/fsm/Makefile.fsm | 8 +- digital/ai/src/fsm/angfsm.h | 21 +- digital/ai/src/fsm/angfsm.host.c | 1226 +++++++++++++++++++++------------ digital/ai/src/fsm/angfsm_generic.h | 54 +- digital/ai/src/fsm/angfsm_host_exec.h | 145 ++-- digital/ai/src/fsm/angfsm_renaming.h | 15 +- digital/ai/src/fsm/init.c | 20 +- 7 files changed, 939 insertions(+), 550 deletions(-) diff --git a/digital/ai/src/fsm/Makefile.fsm b/digital/ai/src/fsm/Makefile.fsm index 97363bbd..310a4925 100644 --- a/digital/ai/src/fsm/Makefile.fsm +++ b/digital/ai/src/fsm/Makefile.fsm @@ -1,12 +1,12 @@ fsm_AI_gen.avr.c: angfsm_gen_avr_AI.h dot_AI_1.dot: fsm_AI_gen.h angfsm_gen_avr_AI.h: io_hub.host - ./$< --ang-gen avr + ./$< --ang-gen avr --ang-dot AI.dot mv angfsm_gen_avr_AI.c fsm_AI_gen.avr.c -view: dot_AI_1.view -png: dot_AI_1.png -svg: dot_AI_1.svg +view: AI.view +png: AI.png +svg: AI.svg %.view: %.dot dot -Txlib $< diff --git a/digital/ai/src/fsm/angfsm.h b/digital/ai/src/fsm/angfsm.h index 2934ec4e..12ce101a 100644 --- a/digital/ai/src/fsm/angfsm.h +++ b/digital/ai/src/fsm/angfsm.h @@ -1,6 +1,6 @@ /* AngFSM - Almost Non Generated Finite State Machine - Copyright 2011, 2012 Jerome Jutteau + Copyright 2011-2013 Jerome Jutteau This file is part of AngFSM. @@ -36,20 +36,33 @@ ANGFSM_PASTE_EXPAND (a, ANGFSM_PASTE_EXPAND (b, c)) #define FIRST(first, others...) first +#define IFELSE_ARG1(yes, no, params...) \ + IFELSE_ARG1_ (params, IFELSE_ARG1_SEQ_(yes, no)) +#define IFELSE_ARG1_(params...) \ + IFELSE_ARG1__ (params) +#define IFELSE_ARG1__( _a1, \ + _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, \ + _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \ + selector, ...) selector +#define IFELSE_ARG1_SEQ_(yes, no) \ + no, no, no, no, no, no, no, no, no, no, \ + no, no, no, no, no, no, no, no, no, no, \ + yes + #ifdef __HOST_ARCH__ /* Include generated header. */ -#include XSTR (ANGFSM_PASTE_EXPAND (angfsm_gen_host_, ANGFSM_NAME).h) #include "angfsm_generic.h" +#include XSTR (ANGFSM_PASTE_EXPAND (angfsm_gen_host_, ANGFSM_NAME).h) #elif defined(__AVR_ARCH__) /* Include generated header. */ -#include XSTR (ANGFSM_PASTE_EXPAND (angfsm_gen_avr_, ANGFSM_NAME).h) #include "angfsm_generic.h" +#include XSTR (ANGFSM_PASTE_EXPAND (angfsm_gen_avr_, ANGFSM_NAME).h) #elif defined(__arm__) /* Include generated header. */ -#include XSTR (ANGFSM_PASTE_EXPAND (angfsm_gen_arm_, ANGFSM_NAME).h) #include "angfsm_generic.h" +#include XSTR (ANGFSM_PASTE_EXPAND (angfsm_gen_arm_, ANGFSM_NAME).h) #else /* Compiling for HOST but for direct execution. */ diff --git a/digital/ai/src/fsm/angfsm.host.c b/digital/ai/src/fsm/angfsm.host.c index fe8f403e..03201bae 100644 --- a/digital/ai/src/fsm/angfsm.host.c +++ b/digital/ai/src/fsm/angfsm.host.c @@ -1,6 +1,6 @@ /* AngFSM - Almost Non Generated Finite State Machine - Copyright 2011, 2012 Jerome Jutteau + Copyright 2011-2013 Jerome Jutteau This file is part of AngFSM. @@ -18,8 +18,6 @@ along with AngFSM. If not, see . */ -#ifdef HOST - #include "angfsm.h" #include @@ -37,7 +35,7 @@ void angfsm_build_print_help () { printf ( - "AngFSM Copyright (C) 2011, 2012 Jérôme Jutteau\n" + "AngFSM Copyright (C) 2011-2013 Jérôme Jutteau\n" "This program comes with ABSOLUTELY NO WARRANTY;\n" "This is free software, and you are welcome to redistribute it\n" "under certain conditions; consult license for details.\n" @@ -71,10 +69,10 @@ angfsm_build_print_help () " for a selected fsm. Put this option before --ang-gen.\n" "--ang-no-sanity-check\n" " Disable sanity check during execution on the selected fsm or on\n" - " all fsm. Sanity checks are not embedded in generated code." + " all fsm. Sanity checks are not embedded in generated code.\n" "--ang-print-transitions\n" " Print transition to stdout each time one occurs. Not available for\n" - " generated code." + " generated code.\n" ); } @@ -145,10 +143,13 @@ angfsm_build_arg_free (char ***tab, int nb) } void -angfsm_build_print (angfsm_build_t *fsm, - angfsm_build_trans_t *trans, - angfsm_build_branch_chain_t *branch) +angfsm_build_print_trans (angfsm_build_t *fsm, + angfsm_build_trans_t *trans, + angfsm_build_branch_chain_t *branch) { + assert (fsm); + assert (trans); + assert (branch); if (branch->name == NULL) fprintf (stderr, "Transition: %s -- %s --> %s\n", trans->state->var_name, @@ -361,13 +362,6 @@ angfsm_build_sanity_check (angfsm_build_t *fsm) } sc = sc->next; } - - /* Sanity check 8: any transition output error ? - * for example, as we are in state s42, making a angfsm_NEXT (s1, e2) will - * work but this is a user's mistake. - * - * TODO Find a way to check this. - **/ } void @@ -386,6 +380,21 @@ angfsm_build_reset (angfsm_build_t *fsm) fsm->run.active_states[i++] = &curs->state; curs = curs->next; } + + /* Reset timeouts. */ + for (i = 0; i < fsm->max_active_states; i++) + fsm->run.timeout_counters[i] = -1; + for (i = 0; i < fsm->max_active_states; i++) + { + angfsm_build_timeout_chain_t *toc = fsm->timeouts; + while (toc != NULL) + { + if (fsm->run.active_states[i]->code + == toc->timeout.trans->state->code) + fsm->run.timeout_counters[i] = toc->timeout.timeout; + toc = toc->next; + } + } } void @@ -476,16 +485,21 @@ angfsm_build_init (angfsm_build_t *fsm, char *name) fsm->trans = NULL; fsm->name = name; fsm->max_active_states = 0; - fsm->event_nb = 0; + fsm->max_events_per_states = 0; + fsm->max_branches_per_trans = 1; fsm->state_nb = 0; + fsm->event_nb = 0; fsm->starters = NULL; fsm->timeouts = NULL; + fsm->u_branch_nb = 0; + fsm->u_branch_name = NULL; fsm->run.trans_table = NULL; fsm->run.active_states = NULL; fsm->run.events_before_active_state = NULL; fsm->run.func_pool = NULL; fsm->run.timeout_counters = NULL; + fsm->run.trans_callback = NULL; /* Set default user's options. */ fsm->options.embedded_strings = 0; @@ -502,6 +516,84 @@ angfsm_build_init (angfsm_build_t *fsm, char *name) angfsm_build_all_fsm = niou; } +/* Compute last details about fsm. */ +void +angfsm_build_init_finalize (angfsm_build_t *fsm) +{ + uint i, j, k; + uint *cpt; + char **t; + angfsm_build_trans_chain_t *tc; + angfsm_build_branch_chain_t *bc; + assert (fsm); + + /* Compute maximal number of events per states. */ + cpt = (uint *) calloc (fsm->state_nb, sizeof (uint)); + tc = fsm->trans; + while (tc != NULL) + { + cpt[tc->trans.state->code]++; + tc = tc->next; + } + for (i = 0; i < fsm->state_nb; i++) + if (cpt[i] > fsm->max_events_per_states) + fsm->max_events_per_states = cpt[i]; + free (cpt); + + /* Populate every unique branch names. */ + /* 1. count the number of branch with a name. */ + j = 0; + tc = fsm->trans; + while (tc != NULL) + { + bc = tc->trans.output_branches; + while (bc != NULL) + { + if (bc->name != NULL) + j++; + bc = bc->next; + } + tc = tc->next; + } + /* 2. Create temporary array and fill it. */ + if (j > 0) + { + t = (char **) calloc (j, sizeof (char *)); + k = 0; + tc = fsm->trans; + /* In all transitions. */ + while (tc != NULL) + { + bc = tc->trans.output_branches; + /* In all branches. */ + while (bc != NULL) + { + if (bc->name != NULL) + { + /* Check if this name already exists. */ + int exists = 0; + for (i = 0; i < j; i++) + if (t[i] && strcmp (bc->name, t[i]) == 0) + exists = 1; + /* Add to array. */ + if (!exists) + { + t[k] = bc->name; + k++; + } + } + bc = bc->next; + } + tc = tc->next; + } + /* 3. Rescale the array and store it. */ + if (k < j) + t = (char **) realloc (t, k * sizeof (char *)); + fsm->u_branch_nb = k; + fsm->u_branch_name = t; + } +} + /* Prepare the fsm to run (at very end). */ void angfsm_build_run_init (angfsm_build_t *fsm) @@ -563,8 +655,9 @@ angfsm_build_run_init (angfsm_build_t *fsm) malloc (fsm->max_active_states * sizeof (int)); for (i = 0; i < fsm->max_active_states; i++) fsm->run.timeout_counters[i] = -1; - angfsm_build_timeout_chain_t *toc = fsm->timeouts; for (i = 0; i < fsm->max_active_states; i++) + { + angfsm_build_timeout_chain_t *toc = fsm->timeouts; while (toc != NULL) { if (fsm->run.active_states[i]->code @@ -572,6 +665,7 @@ angfsm_build_run_init (angfsm_build_t *fsm) fsm->run.timeout_counters[i] = toc->timeout.timeout; toc = toc->next; } + } } void @@ -671,6 +765,23 @@ angfsm_build_get_state_by_code (angfsm_build_t *fsm, uint state) return NULL; } +angfsm_build_trans_t* +angfsm_build_get_trans (angfsm_build_t *fsm, uint state, uint event) +{ + assert (fsm); + assert (state < fsm->state_nb); + assert (event < fsm->event_nb); + + angfsm_build_trans_chain_t *tc = fsm->trans; + while (tc != NULL) + { + if (tc->trans.event->code == event && tc->trans.state->code == state) + return &(tc->trans); + tc = tc->next; + } + return NULL; +} + uint16_t angfsm_build_get_event_code (angfsm_build_t *fsm, char *event) { @@ -680,6 +791,35 @@ angfsm_build_get_event_code (angfsm_build_t *fsm, char *event) return e->code; } +angfsm_build_branch_chain_t* +angfsm_build_get_event_branch (angfsm_build_t *fsm, + angfsm_build_trans_t *trans, + uint branch) +{ + assert (fsm); + assert (trans); + angfsm_build_branch_chain_t *b = trans->output_branches; + while (b != NULL) + { + if (angfsm_build_get_branch (fsm, b->name) == branch) + break; + b = b->next; + } + return b; +} + +uint +angfsm_build_get_branch (angfsm_build_t *fsm, char *branch) +{ + assert (fsm); + uint i; + if (branch && strlen (branch) > 0) + for (i = 0; i < fsm->u_branch_nb; i++) + if (strcmp (branch, fsm->u_branch_name[i]) == 0) + return i; + return fsm->u_branch_nb; +} + void angfsm_build_trans (angfsm_build_t *fsm, char *state, @@ -700,6 +840,11 @@ angfsm_build_trans (angfsm_build_t *fsm, assert (t.event); angfsm_build_arg_parse (output_branches, &args, &nb); + + /* Are we the winner of the maximal branches per transitions ? */ + if ((uint) ((nb / 2)) > fsm->max_branches_per_trans) + fsm->max_branches_per_trans = nb / 2; + /* Only one output state. */ if (nb == 1) { @@ -717,6 +862,9 @@ angfsm_build_trans (angfsm_build_t *fsm, malloc (sizeof (angfsm_build_branch_chain_t)); b->name = strdup (args[i]); b->state = angfsm_build_get_state (fsm, args[i + 1]); + if (!b->state) + fprintf (stderr, "Error: the state \"%s\" has not been declared in fsm %s.\n", + args[i + 1], fsm->name); assert (b->state); b->next = t.output_branches; t.output_branches = b; @@ -806,8 +954,12 @@ angfsm_build_handle (angfsm_build_t *fsm, angfsm_build_event_t *e) { angfsm_build_state_t *s = NULL; angfsm_build_timeout_chain_t *toc = NULL; + angfsm_build_state_t *out; + angfsm_build_branch_chain_t* bc; assert (e); uint i; + uint b = 0; + int mono; int handled = 0; for (i = 0; i < fsm->max_active_states; i++) { @@ -815,7 +967,52 @@ angfsm_build_handle (angfsm_build_t *fsm, angfsm_build_event_t *e) if (s && fsm->run.trans_table[e->code][s->code]) { fsm->run.events_before_active_state[i] = e; - fsm->run.active_states[i] = fsm->run.trans_table[e->code][s->code](); + + /* Get transition. */ + angfsm_build_trans_t *t = angfsm_build_get_trans (fsm, s->code, e->code); + assert (t); + + /* Is it a mono or multi branch function ? */ + assert (t->output_branches); + if (t->output_branches->next == NULL) + mono = 1; + else + mono = 0; + + /* Get transition function. */ + angfsm_build_run_strans_func_t f = fsm->run.trans_table[e->code][s->code]; + angfsm_build_run_strans_func_branches_t fb = (angfsm_build_run_strans_func_branches_t) f; + + /* Run transition. */ + if (mono) + f (); + else + b = fb(); + + /* Get next branch. */ + bc = NULL; + if (mono) + bc = t->output_branches; + else + bc = angfsm_build_get_event_branch (fsm, t, b); + + if (bc == NULL) + fprintf (stderr, "FSM: %s STATE: %s EVENT: %s - Cannot handle given branch \"%s\" (%s)\n", fsm->name, s->var_name, e->var_name, (b < fsm->u_branch_nb ? fsm->u_branch_name[b] : ""), (b < fsm->u_branch_nb ? "wrong branch ?" : "bad branch name ?")); + assert (bc); + out = bc->state; + assert (out); + + /* Transition print. */ + if (fsm->options.print_trans) + angfsm_build_print_trans (fsm, t, bc); + + /* Transition callback. */ + if (fsm->run.trans_callback) + fsm->run.trans_callback (s->code, e->code, out->code, (mono ? -1 : (int) b)); + + /* Update active states. */ + fsm->run.active_states[i] = out; + /* Check the new state has a timeout or not. */ toc = fsm->timeouts; fsm->run.timeout_counters[i] = -1; @@ -905,57 +1102,6 @@ angfsm_build_handle_timeout (angfsm_build_t *fsm) return out; } -angfsm_build_state_t* -angfsm_build_get_next_state (angfsm_build_t *fsm, - char *state, - char *event, - char *branch) -{ - angfsm_build_state_t *s; - angfsm_build_event_t *e; - angfsm_build_trans_chain_t *t_curs; - angfsm_build_branch_chain_t *b_curs; - - /* Convert input data. */ - s = angfsm_build_get_state (fsm, state); - e = angfsm_build_get_event (fsm, event); - assert (s && e); - - /* Get transition. */ - t_curs = fsm->trans; - while (t_curs != NULL) - { - if (s == t_curs->trans.state && e == t_curs->trans.event) - break; - t_curs = t_curs->next; - } - assert (t_curs); - assert (t_curs->trans.output_branches); - - /* If we have only one branch. */ - if (strlen (branch) == 0) - { - /* Branch has to be given is there are multiple branches. */ - assert (t_curs->trans.output_branches->next == NULL); - if (fsm->options.print_trans) - angfsm_build_print (fsm, &t_curs->trans, t_curs->trans.output_branches); - return t_curs->trans.output_branches->state; - } - - /* Find correct branch. */ - b_curs = t_curs->trans.output_branches; - while (b_curs != NULL) - { - if (strcmp (b_curs->name, branch) == 0) - break; - b_curs = b_curs->next; - } - assert (b_curs); - if (fsm->options.print_trans) - angfsm_build_print (fsm, &t_curs->trans, b_curs); - return b_curs->state; -} - int angfsm_build_options (int argc, char **argv) { @@ -1098,11 +1244,8 @@ angfsm_build_gen_no_opti_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) angfsm_build_state_chain_t *sc; angfsm_build_event_chain_t *ec; angfsm_build_trans_chain_t *tc; - angfsm_build_branch_chain_t *bc; - angfsm_build_state_t *s; - angfsm_build_event_t *e; angfsm_build_chain_t *all_fsm; - uint i, j; + uint i; uint embedded_strings = fsm->options.embedded_strings; /* Open file. */ @@ -1135,6 +1278,16 @@ angfsm_build_gen_no_opti_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) fsm->name, fsm->max_active_states); + /* Gen max number of events per states. */ + fprintf (f, "#define angfsm_%s_max_events_per_states %u\n", + fsm->name, + fsm->max_events_per_states); + + /* Gen max number of branches per transitions. */ + fprintf (f, "#define angfsm_%s_max_branches_per_trans %u\n", + fsm->name, + fsm->max_branches_per_trans); + /* Gen state enum. */ fprintf (f, "typedef enum\n{\n"); sc = fsm->states; @@ -1143,9 +1296,12 @@ angfsm_build_gen_no_opti_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) fprintf (f, "\tangfsm_STATE_%s_%s = %u,\n", fsm->name, sc->state.var_name, sc->state.code); sc = sc->next; } - fprintf (f, "\tangfsm_STATE_%s_NB_ = %u\n", fsm->name, fsm->state_nb); + fprintf (f, "\tangfsm_STATE_%s_NB = %u\n", fsm->name, fsm->state_nb); fprintf (f, "} angfsm_%s_state_t;\n\n", fsm->name); + /* Gen transition callback reference. */ + fprintf (f, "extern void (*angfsm_%s_trans_callback) (int state, int event, int output_branch, int branch);\n", fsm->name); + /* Gen event enum. */ fprintf (f, "typedef enum\n{\n"); ec = fsm->events; @@ -1154,133 +1310,106 @@ angfsm_build_gen_no_opti_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) fprintf (f, "\tangfsm_EVENT_%s_%s = %u,\n", fsm->name, ec->event.var_name, ec->event.code); ec = ec->next; } - fprintf (f, "\tangfsm_EVENT_%s_NB_ = %u\n", fsm->name, fsm->event_nb); + fprintf (f, "\tangfsm_EVENT_%s_NB = %u\n", fsm->name, fsm->event_nb); fprintf (f, "} angfsm_%s_event_t;\n\n", fsm->name); - /* Gen state strings. */ - if (embedded_strings) + /* Gen branches unique name enum. */ + fprintf (f, "typedef enum\n{\n"); + if (fsm->u_branch_nb > 0) { - sc = fsm->states; - while (sc != NULL) - { - fprintf (f, "extern char angfsm_%s_state_str_%s[%u];\n", - fsm->name, - sc->state.var_name, - strlen (sc->state.var_name) + 1); - sc = sc->next; - } - fprintf (f, "extern char *angfsm_%s_state_str[%u];\n\n", - fsm->name, - fsm->state_nb); - - /* Gen event strings. */ - ec = fsm->events; - while (ec != NULL) - { - fprintf (f, "extern char angfsm_%s_event_str_%s[%u];\n", - fsm->name, - ec->event.var_name, - strlen (ec->event.var_name) + 1); - ec = ec->next; - } - fprintf (f, "extern char *angfsm_%s_event_str[%u];\n\n", - fsm->name, - fsm->event_nb); - - /* Create a RAM string able to store event or state string. */ - j = 0; - for (i = 0; i < fsm->event_nb; i++) - { - e = angfsm_build_get_event_by_code (fsm, i); - if (strlen (e->var_name) > j) - j = strlen (e->var_name); - } - for (i = 0; i < fsm->state_nb; i++) - { - s = angfsm_build_get_state_by_code (fsm, i); - if (strlen (s->var_name) > j) - j = strlen (s->var_name); - } - fprintf (f, "extern char angfsm_%s_str_buff[%u];\n", fsm->name, j + 1); - - /* Convert an event enum in string. */ - fprintf (f, "char *\nangfsm_%s_get_event_string_from_enum \ - (angfsm_%s_event_t e);\n", fsm->name, fsm->name); + for (i = 0; i < fsm->u_branch_nb; i++) + fprintf (f, "\tangfsm_BRANCH_%s_%s = %u,\n", + fsm->name, + fsm->u_branch_name[i], + i); + } + fprintf (f, "\tangfsm_BRANCH_%s_NB = %u\n", fsm->name, fsm->u_branch_nb); + fprintf (f, "} angfsm_%s_branch_t;\n\n", fsm->name); - /* Convert a event string in enum. */ - fprintf (f, "angfsm_%s_event_t\nangfsm_%s_get_event_enum_from_string \ - (char *str);\n", fsm->name, fsm->name); + /* Gen strings. */ + if (embedded_strings) + { + fprintf (f, "extern char *angfsm_%s_state_str[];\n", fsm->name); + fprintf (f, "extern char *angfsm_%s_event_str[];\n", fsm->name); + fprintf (f, "extern char *angfsm_%s_branch_str[];\n", fsm->name); - /* Convert an state enum in string. */ - fprintf (f, "char *\nangfsm_%s_get_state_string_from_enum \ - (angfsm_%s_state_t s);\n", fsm->name, fsm->name); + /* Convert an event in string. */ + fprintf (f, "char *\nangfsm_%s_get_event_str (angfsm_%s_event_t e);\n", fsm->name, fsm->name); + /* Convert a state in string. */ + fprintf (f, "char *\nangfsm_%s_get_state_str (angfsm_%s_state_t s);\n", fsm->name, fsm->name); + /* Convert a branch in string. */ + fprintf (f, "char *\nangfsm_%s_get_branch_str (angfsm_%s_branch_t s);\n", fsm->name, fsm->name); - /* Convert a state string in enum. */ - fprintf (f, "angfsm_%s_state_t\nangfsm_%s_get_state_enum_from_string \ - (char *str);\n", fsm->name, fsm->name); + fprintf (f, "\n"); } - - /* Gen transitions branches enum. */ - fprintf (f, "typedef enum\n{\n"); - tc = fsm->trans; - while (tc != NULL) + else { - bc = tc->trans.output_branches; - while (bc != NULL) - { - if (bc->name != NULL) - fprintf (f, "\tangfsm_BRANCH_%s_%s_%s_%s = %u,\n", - fsm->name, - tc->trans.state->var_name, - tc->trans.event->var_name, - bc->name, - bc->state->code); - else - fprintf (f, "\tangfsm_BRANCH_%s_%s_%s_ = %u,\n", - fsm->name, - tc->trans.state->var_name, - tc->trans.event->var_name, - bc->state->code); - bc = bc->next; - } - tc = tc->next; + /* Disable string macros. */ + fprintf (f, "#undef ANGFSM_STATE_STR\n#define ANGFSM_STATE_STR(s) ((char *)0)\n"); + fprintf (f, "#undef ANGFSM_EVENT_STR\n#define ANGFSM_EVENT_STR(e) ((char *)0)\n"); + fprintf (f, "#undef ANGFSM_BRANCH_STR\n#define ANGFSM_BRANCH_STR(b) ((char *)0)\n"); } - fprintf (f, "} angfsm_%s_branch_t;\n\n", fsm->name); /* Gen function headers. */ tc = fsm->trans; while (tc != NULL) { - fprintf (f, "angfsm_%s_branch_t angfsm_%s_trans_func_%s_%s (void);\n", - fsm->name, - fsm->name, - tc->trans.state->var_name, - tc->trans.event->var_name); + assert (tc->trans.output_branches); + /* Mono branch */ + if (tc->trans.output_branches->next==NULL) + fprintf (f, "void angfsm_%s_trans_func_%s_%s ();\n", + fsm->name, + tc->trans.state->var_name, + tc->trans.event->var_name); + else + fprintf (f, "angfsm_%s_branch_t angfsm_%s_trans_func_%s_%s ();\n", + fsm->name, + fsm->name, + tc->trans.state->var_name, + tc->trans.event->var_name); tc = tc->next; } fprintf (f, "\n"); - /* Gen function table. */ - fprintf (f, "typedef angfsm_%s_branch_t (*angfsm_%s_func_t)(void);\n", fsm->name, + /* Declare function type. */ + fprintf (f, "typedef void (*angfsm_%s_func_t)();\n", fsm->name); + fprintf (f, "typedef angfsm_%s_branch_t (*angfsm_%s_func_branches_t)();\n\n", + fsm->name, fsm->name); + + /* Gen branch structure. */ + fprintf (f, "typedef struct\n{\n"); + fprintf (f, "\tangfsm_%s_branch_t branch;\n", fsm->name); + fprintf (f, "\tangfsm_%s_state_t state;\n", fsm->name); + fprintf (f, "} angfsm_%s_next_t;\n\n", fsm->name); + + /* Gen transition structure. */ + fprintf (f, "typedef struct\n{\n"); + fprintf (f, "\tangfsm_%s_event_t event;\n", fsm->name); + fprintf (f, "\tangfsm_%s_func_t func;\n", fsm->name); + fprintf (f, "\tangfsm_%s_next_t branches[angfsm_%s_max_branches_per_trans];\n", + fsm->name, fsm->name); - fprintf (f, "extern const angfsm_%s_func_t angfsm_%s_trans_table[%u][%u];\n", + fprintf (f, "} angfsm_%s_trans_t;\n\n", fsm->name); + + /* Gen transition table. */ + fprintf (f, "extern const angfsm_%s_trans_t angfsm_%s_trans_table[angfsm_STATE_%s_NB][angfsm_%s_max_events_per_states];\n\n", + fsm->name, fsm->name, fsm->name, - fsm->event_nb, - fsm->state_nb); + fsm->name); + /* Gen read function for trans table. */ - fprintf (f, "angfsm_%s_func_t angfsm_%s_read_trans (angfsm_%s_event_t event, " - "angfsm_%s_state_t state);\n\n", + fprintf (f, "inline angfsm_%s_trans_t* angfsm_%s_read_trans (angfsm_%s_event_t event, angfsm_%s_state_t state);\n\n", fsm->name, fsm->name, fsm->name, fsm->name); /* Gen active states array. */ - fprintf (f, "extern angfsm_%s_state_t angfsm_%s_active_states[%u];\n\n", + fprintf (f, "extern angfsm_%s_state_t angfsm_%s_active_states[angfsm_%s_max_active_states];\n\n", fsm->name, fsm->name, - fsm->max_active_states); + fsm->name); /* Gen initialization function. */ sc = fsm->starters; @@ -1305,20 +1434,20 @@ angfsm_build_gen_no_opti_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) fsm->name); /* Gen timeout values. */ - fprintf (f, "extern int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB_];\n", + fprintf (f, "extern int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB];\n", fsm->name, fsm->name); /* Gen timeout corresponding events. */ - fprintf (f, "extern angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB_];\n", + fprintf (f, "extern angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB];\n", fsm->name, fsm->name, fsm->name); /* Gen timeout counters array. */ - fprintf (f, "extern int32_t angfsm_%s_timeout_counters[%u];\n\n", + fprintf (f, "extern int32_t angfsm_%s_timeout_counters[angfsm_%s_max_active_states];\n\n", fsm->name, - fsm->max_active_states); + fsm->name); } /* Conclusion. */ @@ -1332,14 +1461,15 @@ angfsm_build_gen_no_opti_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) void angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) { + assert (fsm); assert (arch < ANGFSM_BUILD_ARCH_NB); angfsm_build_state_chain_t *sc; angfsm_build_event_chain_t *ec; angfsm_build_trans_chain_t *tc; angfsm_build_timeout_chain_t *toc; + angfsm_build_branch_chain_t *bc; angfsm_build_state_t *s; - angfsm_build_event_t *e; - uint i, j, found; + uint i, j, k, count; uint embedded_strings = fsm->options.embedded_strings; /* Open file. */ @@ -1356,165 +1486,191 @@ angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) angfsm_build_arch_name[arch], fsm->name); - /* Gen state strings. */ + /* Gen strings if configured. */ if (embedded_strings) { - sc = fsm->states; - while (sc != NULL) - { - fprintf (f, "char angfsm_%s_state_str_%s[] = \"%s\";\n", - fsm->name, - sc->state.var_name, - sc->state.var_name); - sc = sc->next; - } + /* Gen state strings. */ fprintf (f, "char *angfsm_%s_state_str[] =\n{\n", fsm->name); for (i = 0; i < fsm->state_nb; i++) { - s = angfsm_build_get_state_by_code (fsm, i); - fprintf (f, "\tangfsm_%s_state_str_%s", fsm->name, s->var_name); - if (i == fsm->state_nb - 1) - fprintf (f, "\n"); - else - fprintf (f, ",\n"); + sc = fsm->states; + while (sc != NULL) + { + if (sc->state.code == i) + { + fprintf (f, "\t\"%s\"", sc->state.var_name); + if (i != fsm->state_nb) + fprintf (f, ", "); + fprintf (f, "\n"); + } + sc = sc->next; + } } fprintf (f, "};\n\n"); /* Gen event strings. */ - ec = fsm->events; - while (ec != NULL) - { - fprintf (f, "char angfsm_%s_event_str_%s[] = \"%s\";\n", - fsm->name, - ec->event.var_name, - ec->event.var_name); - ec = ec->next; - } fprintf (f, "char *angfsm_%s_event_str[] =\n{\n", fsm->name); for (i = 0; i < fsm->event_nb; i++) { - e = angfsm_build_get_event_by_code (fsm, i); - fprintf (f, "\tangfsm_%s_event_str_%s", fsm->name, e->var_name); - if (i == fsm->event_nb - 1) - fprintf (f, "\n"); - else - fprintf (f, ",\n"); + ec = fsm->events; + while (ec != NULL) + { + if (ec->event.code == i) + { + fprintf (f, "\t\"%s\"", ec->event.var_name); + if (i != fsm->event_nb) + fprintf (f, ", "); + fprintf (f, "\n"); + } + ec = ec->next; + } } fprintf (f, "};\n\n"); - /* Create a RAM string able to store event or state string. */ - j = 0; - for (i = 0; i < fsm->event_nb; i++) + /* Gen branch strings. */ + fprintf (f, "char *angfsm_%s_branch_str[] =\n{\n", fsm->name); + for (i = 0; i < fsm->u_branch_nb; i++) { - e = angfsm_build_get_event_by_code (fsm, i); - if (strlen (e->var_name) > j) - j = strlen (e->var_name); - } - for (i = 0; i < fsm->state_nb; i++) - { - s = angfsm_build_get_state_by_code (fsm, i); - if (strlen (s->var_name) > j) - j = strlen (s->var_name); + fprintf (f, "\t\"%s\"", fsm->u_branch_name[i]); + if (i != fsm->u_branch_nb - 1) + fprintf (f, ", "); + fprintf (f, "\n"); } - fprintf (f, "char angfsm_%s_str_buff[%u];\n", fsm->name, j + 1); + fprintf (f, "};\n\n"); + /* Generate string read functions. */ /* Convert an event enum in string. */ - fprintf (f, "char *\nangfsm_%s_get_event_string_from_enum \ - (angfsm_%s_event_t e)\n{\n", fsm->name, fsm->name); - fprintf (f, "\treturn strcpy (angfsm_%s_str_buff, \ - (char *) (&(angfsm_%s_event_str[e])));\n", fsm->name, fsm->name); - fprintf (f, "}\n\n"); - - /* Convert a event string in enum. */ - fprintf (f, "angfsm_%s_event_t\nangfsm_%s_get_event_enum_from_string \ - (char *str)\n{\n", fsm->name, fsm->name); - fprintf (f, "\tuint16_t i;\n"); - fprintf (f, "\tfor (i = 0; i < angfsm_EVENT_%s_NB_; i++)\n", fsm->name); - fprintf (f, "\t\tif (strcpy (str, \ - (char *) (&(angfsm_%s_event_str[i]))) == 0)\n", fsm->name); - fprintf (f, "\t\t\treturn i;\n"); - fprintf (f, "\treturn angfsm_EVENT_%s_NB_;\n", fsm->name); + fprintf (f, "inline char *\nangfsm_%s_get_event_str (angfsm_%s_event_t e)\n{\n", fsm->name, fsm->name); + fprintf (f, "\treturn angfsm_%s_event_str[e];\n", fsm->name); fprintf (f, "}\n\n"); - - /* Convert an state enum in string. */ - fprintf (f, "char *\nangfsm_%s_get_state_string_from_enum \ - (angfsm_%s_state_t s)\n{\n", fsm->name, fsm->name); - fprintf (f, "\treturn strcpy (angfsm_%s_str_buff, \ - (char *) (&(angfsm_%s_state_str[s])));\n", fsm->name, fsm->name); + /* Convert a state enum in string. */ + fprintf (f, "inline char *\nangfsm_%s_get_state_str (angfsm_%s_state_t s)\n{\n", fsm->name, fsm->name); + fprintf (f, "\treturn angfsm_%s_state_str[s];\n", fsm->name); fprintf (f, "}\n\n"); - - /* Convert a state string in enum. */ - fprintf (f, "angfsm_%s_state_t\nangfsm_%s_get_state_enum_from_string \ - (char *str)\n{\n", fsm->name, fsm->name); - fprintf (f, "\tuint16_t i;\n"); - fprintf (f, "\tfor (i = 0; i < angfsm_STATE_%s_NB_; i++)\n", fsm->name); - fprintf (f, "\t\tif (strcpy (str, \ - (char *) (&(angfsm_%s_state_str[i]))) == 0)\n", fsm->name); - fprintf (f, "\t\t\treturn i;\n"); - fprintf (f, "\treturn angfsm_STATE_%s_NB_;\n", fsm->name); + /* Convert a branch enum in string. */ + fprintf (f, "inline char *\nangfsm_%s_get_branch_str (angfsm_%s_branch_t b)\n{\n", fsm->name, fsm->name); + fprintf (f, "\treturn angfsm_%s_branch_str[b];\n", fsm->name); fprintf (f, "}\n\n"); } - /* Gen function table. */ - fprintf (f, "const angfsm_%s_func_t angfsm_%s_trans_table[%u][%u] = \n{\n", + /* Gen transition table. */ + fprintf (f, "const angfsm_%s_trans_t angfsm_%s_trans_table[angfsm_STATE_%s_NB][angfsm_%s_max_events_per_states] = \n{\n", fsm->name, fsm->name, - fsm->event_nb, - fsm->state_nb); - /* for each events and state, see if it exists an associated transition. */ - for (i = 0; i < fsm->event_nb; i++) + fsm->name, + fsm->name); + for (i = 0; i < fsm->state_nb; i++) { - e = angfsm_build_get_event_by_code (fsm, i); - fprintf (f, "\t{"); - for (j = 0; j < fsm->state_nb; j++) + count = 0; + fprintf (f, "\t{\n"); + tc = fsm->trans; + while (tc != NULL) { - s = angfsm_build_get_state_by_code (fsm, j); - tc = fsm->trans; - found = 0; - while (tc != NULL) - { - if (tc->trans.state == s && tc->trans.event == e) - { - found = 1; - fprintf (f, "&angfsm_%s_trans_func_%s_%s", - fsm->name, - tc->trans.state->var_name, - tc->trans.event->var_name); - tc = tc->next; - break; - } - tc = tc->next; - } - if (!found) - fprintf (f, "(angfsm_%s_func_t) 0", fsm->name); - if (j == fsm->state_nb - 1) - fprintf (f, "}"); - else - fprintf (f, ", "); + if (tc->trans.state->code == i) + { + fprintf (f, "\t\t{\n"); + fprintf (f, "\t\t\tangfsm_EVENT_%s_%s,\n", + fsm->name, + tc->trans.event->var_name); + fprintf (f, "\t\t\t(angfsm_%s_func_t) &angfsm_%s_trans_func_%s_%s,\n", + fsm->name, + fsm->name, + tc->trans.state->var_name, + tc->trans.event->var_name); + /* Gen branche array */ + fprintf (f, "\t\t\t{\n"); + j = 0; + bc = tc->trans.output_branches; + while (bc != NULL) + { + fprintf (f, "\t\t\t\t{angfsm_BRANCH_%s_%s, angfsm_STATE_%s_%s}", + fsm->name, + (bc->name ? bc->name : "NB"), + fsm->name, + bc->state->var_name); + if (j != fsm->max_branches_per_trans - 1) + fprintf (f, ", "); + fprintf (f, "\n"); + j++; + bc = bc->next; + } + /* Fill blank branches. */ + for (k = j; k < fsm->max_branches_per_trans; k++) + { + fprintf (f, "\t\t\t\t{angfsm_BRANCH_%s_NB, angfsm_STATE_%s_NB}", + fsm->name, + fsm->name); + if (k != fsm->max_branches_per_trans - 1) + fprintf (f, ","); + fprintf (f, "\n"); + } + + fprintf (f, "\t\t\t}\n"); + if (tc->next != NULL || count != fsm->max_events_per_states) + fprintf (f, "\t\t},\n"); + else + fprintf (f, "\t\t}\n"); + count++; + } + tc = tc->next; } - if (i != fsm->event_nb - 1) - fprintf (f, ","); - fprintf (f, "\n"); + /* Fill blank transitions. */ + for (k = count; k < fsm->max_events_per_states; k++) + { + fprintf (f, "\t\t{\n"); + fprintf (f, "\t\t\tangfsm_EVENT_%s_NB,\n",fsm->name); + fprintf (f, "\t\t\t(angfsm_%s_func_t) 0,\n", fsm->name); + fprintf (f, "\t\t\t{\n"); + for (j = 0; j < fsm->max_branches_per_trans; j++) + { + fprintf (f, "\t\t\t\t{angfsm_BRANCH_%s_NB, angfsm_STATE_%s_NB}", + fsm->name, + fsm->name); + if (j != fsm->max_branches_per_trans - 1) + fprintf (f, ","); + fprintf (f, "\n"); + } + fprintf (f, "\t\t\t}\n"); + if (k != fsm->max_events_per_states - 1) + fprintf (f, "\t\t},\n"); + else + fprintf (f, "\t\t}\n"); + } + + if (i == fsm->state_nb - 1) + fprintf (f, "\t}\n"); + else + fprintf (f, "\t},\n"); } fprintf (f, "};\n\n"); - /* Gen read function for trans table. */ - fprintf (f, "angfsm_%s_func_t angfsm_%s_read_trans (angfsm_%s_event_t event, " - "angfsm_%s_state_t state)\n{\n", - fsm->name, - fsm->name, + /* Transition callback. */ + fprintf (f, "void (*angfsm_%s_trans_callback) (int state, int event, int output_branch, int branch);\n", fsm->name); + + /* Gen active states array. */ + fprintf (f, "angfsm_%s_state_t angfsm_%s_active_states[angfsm_%s_max_active_states];\n\n", fsm->name, - fsm->name); - fprintf (f, "\treturn (angfsm_%s_func_t) angfsm_%s_trans_table[event][state];\n", fsm->name, fsm->name); - fprintf (f, "}\n\n"); - /* Gen active states array. */ - fprintf (f, "angfsm_%s_state_t angfsm_%s_active_states[%u];\n\n", + /* Gen read transition from event and state. */ + fprintf (f, "inline angfsm_%s_trans_t* angfsm_%s_read_trans " + "(angfsm_%s_event_t event, angfsm_%s_state_t state)\n{\n", fsm->name, fsm->name, - fsm->max_active_states); + fsm->name, + fsm->name); + fprintf (f, "\tint i;\n"); + fprintf (f, "\tangfsm_%s_trans_t* t;\n", fsm->name); + fprintf (f, "\tfor (i = 0; i < angfsm_%s_max_events_per_states; i++)\n\t{\n", + fsm->name); + fprintf (f, "\t\tt = (angfsm_%s_trans_t *) (&angfsm_%s_trans_table[state][i]);\n", + fsm->name, + fsm->name); + fprintf (f, "\t\tif (t->func == (angfsm_%s_func_t) 0)\n\t\t\tbreak;\n", fsm->name); + fprintf (f, "\t\tif (t->event == event)\n"); + fprintf (f, "\t\t\treturn t;\n"); + fprintf (f, "\t}\n\treturn (angfsm_%s_trans_t*) 0;\n}\n\n", fsm->name); /* Gen initialization function. */ sc = fsm->starters; @@ -1522,11 +1678,11 @@ angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) fprintf (f, "void\nangfsm_%s_init ()\n{\n", fsm->name); while (sc != NULL) { - fprintf (f, "\tangfsm_%s_active_states[%u] = (angfsm_%s_state_t) %u;\n", + fprintf (f, "\tangfsm_%s_active_states[%u] = angfsm_STATE_%s_%s;\n", fsm->name, i, fsm->name, - sc->state.code); + sc->state.var_name); if (fsm->timeouts != NULL) { toc = fsm->timeouts; @@ -1545,23 +1701,43 @@ angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) i++; sc = sc->next; } + /* Set transition callback to NULL. */ + fprintf (f, "\tangfsm_%s_trans_callback = (typeof (angfsm_%s_trans_callback)) 0;\n", fsm->name, fsm->name); fprintf (f, "}\n\n"); /* Gen handle function. */ fprintf (f, "int\nangfsm_%s_handle (angfsm_%s_event_t e)\n{\n", fsm->name, fsm->name); - fprintf (f, "\tuint16_t i;\n"); + fprintf (f, "\tuint16_t i, j;\n"); fprintf (f, "\tint handled = 0;\n"); + fprintf (f, "\tangfsm_%s_branch_t b;\n", fsm->name); fprintf (f, "\tfor (i = 0; i < angfsm_%s_max_active_states; i++)\n\t{\n", fsm->name); - fprintf (f, "\t\tangfsm_%s_func_t trans = angfsm_%s_read_trans (e, angfsm_%s_active_states[i]);\n", + fprintf (f, "\t\tangfsm_%s_trans_t *trans = angfsm_%s_read_trans (e, angfsm_%s_active_states[i]);\n", fsm->name, fsm->name, fsm->name); fprintf (f, "\t\tif (trans)\n"); fprintf (f, "\t\t{\n"); - fprintf (f, "\t\t\tangfsm_%s_active_states[i] = (angfsm_%s_state_t) trans ();\n", fsm->name, fsm->name); + fprintf (f, "\t\t\tangfsm_%s_state_t s = angfsm_STATE_%s_NB;\n", fsm->name, fsm->name); + fprintf (f, "\t\t\tif (trans->branches[0].branch == angfsm_BRANCH_%s_NB)\n\t\t\t{\n", fsm->name); + fprintf (f, "\t\t\t\ttrans->func ();\n"); + fprintf (f, "\t\t\t\ts = trans->branches[0].state;\n"); + fprintf (f, "\t\t\t\tif (angfsm_%s_trans_callback)\n", fsm->name); + fprintf (f, "\t\t\t\t\tangfsm_%s_trans_callback(angfsm_%s_active_states[i], e, s, -1);\n", fsm->name, fsm->name); + fprintf (f, "\t\t\t}\n\t\t\telse\n\t\t\t{\n"); + fprintf (f, "\t\t\t\tb = ((angfsm_%s_func_branches_t) trans->func) ();\n", fsm->name); + fprintf (f, "\t\t\t\tfor (j = 0; j < angfsm_%s_max_branches_per_trans; j++)\n", fsm->name); + fprintf (f, "\t\t\t\t\tif (trans->branches[j].branch == b)\n"); + fprintf (f, "\t\t\t\t\t\ts = trans->branches[j].state;\n"); + fprintf (f, "\t\t\t\t\tif (angfsm_%s_trans_callback)\n", fsm->name); + fprintf (f, "\t\t\t\t\t\tangfsm_%s_trans_callback(angfsm_%s_active_states[i], e, s, b);\n", fsm->name, fsm->name); + fprintf (f, "\t\t\t}\n"); + fprintf (f, "\t\t\tif (s != angfsm_STATE_%s_NB)\n", fsm->name); + fprintf (f, "\t\t\t\tangfsm_%s_active_states[i] = s;\n", fsm->name); + fprintf (f, "\t\t\telse\n"); + fprintf (f, "\t\t\t\t{;} //XXX show some error ?\n"); fprintf (f, "\t\t\thandled = 1;\n"); if (fsm->timeouts != NULL) { @@ -1593,12 +1769,12 @@ angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) if (fsm->timeouts != NULL) { /* Gen timeout counters array. */ - fprintf (f, "int32_t angfsm_%s_timeout_counters[%u];\n", + fprintf (f, "int32_t angfsm_%s_timeout_counters[angfsm_%s_max_active_states];\n", fsm->name, - fsm->max_active_states); + fsm->name); /* Gen timeout values array. */ - fprintf (f, "int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB_] =\n{\n", + fprintf (f, "int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB] =\n{\n", fsm->name, fsm->name); int value; @@ -1625,7 +1801,7 @@ angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) fprintf (f, "};\n\n"); /* Gen timeout corresponding events array. */ - fprintf (f, "angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB_] =\n{\n", + fprintf (f, "angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB] =\n{\n", fsm->name, fsm->name, fsm->name); @@ -1645,7 +1821,7 @@ angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) toc = toc->next; } if (value == -1) - fprintf (f, "\t(angfsm_%s_event_t) angfsm_STATE_%s_NB_", fsm->name, fsm->name); + fprintf (f, "\t(angfsm_%s_event_t) angfsm_STATE_%s_NB", fsm->name, fsm->name); else fprintf (f, "\t(angfsm_%s_event_t) %u", fsm->name, value); @@ -1692,10 +1868,10 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) angfsm_build_state_chain_t *sc; angfsm_build_event_chain_t *ec; angfsm_build_trans_chain_t *tc; - angfsm_build_branch_chain_t *bc; + angfsm_build_chain_t *all_fsm; angfsm_build_state_t *s; angfsm_build_event_t *e; - angfsm_build_chain_t *all_fsm; + uint i, j; uint embedded_strings = fsm->options.embedded_strings; @@ -1729,6 +1905,16 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) fsm->name, fsm->max_active_states); + /* Gen max number of events per states. */ + fprintf (f, "#define angfsm_%s_max_events_per_states %u\n", + fsm->name, + fsm->max_events_per_states); + + /* Gen max number of branches per transitions. */ + fprintf (f, "#define angfsm_%s_max_branches_per_trans %u\n", + fsm->name, + fsm->max_branches_per_trans); + /* Gen state enum. */ fprintf (f, "typedef enum\n{\n"); sc = fsm->states; @@ -1737,9 +1923,12 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) fprintf (f, "\tangfsm_STATE_%s_%s = %u,\n", fsm->name, sc->state.var_name, sc->state.code); sc = sc->next; } - fprintf (f, "\tangfsm_STATE_%s_NB_ = %u\n", fsm->name, fsm->state_nb); + fprintf (f, "\tangfsm_STATE_%s_NB = %u\n", fsm->name, fsm->state_nb); fprintf (f, "} angfsm_%s_state_t;\n\n", fsm->name); + /* Gen transition callback reference. */ + fprintf (f, "extern void (*angfsm_%s_trans_callback) (int state, int event, int output_branch, int branch);\n", fsm->name); + /* Gen event enum. */ fprintf (f, "typedef enum\n{\n"); ec = fsm->events; @@ -1748,12 +1937,26 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) fprintf (f, "\tangfsm_EVENT_%s_%s = %u,\n", fsm->name, ec->event.var_name, ec->event.code); ec = ec->next; } - fprintf (f, "\tangfsm_EVENT_%s_NB_ = %u\n", fsm->name, fsm->event_nb); + fprintf (f, "\tangfsm_EVENT_%s_NB = %u\n", fsm->name, fsm->event_nb); fprintf (f, "} angfsm_%s_event_t;\n\n", fsm->name); - /* Gen state strings. */ + /* Gen branches unique name enum. */ + fprintf (f, "typedef enum\n{\n"); + if (fsm->u_branch_nb > 0) + { + for (i = 0; i < fsm->u_branch_nb; i++) + fprintf (f, "\tangfsm_BRANCH_%s_%s = %u,\n", + fsm->name, + fsm->u_branch_name[i], + i); + } + fprintf (f, "\tangfsm_BRANCH_%s_NB = %u\n", fsm->name, fsm->u_branch_nb); + fprintf (f, "} angfsm_%s_branch_t;\n\n", fsm->name); + + /* Gen strings. */ if (embedded_strings) { + /* Gen state strings header. */ sc = fsm->states; while (sc != NULL) { @@ -1767,7 +1970,7 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) fsm->name, fsm->state_nb); - /* Gen event strings. */ + /* Gen event strings header. */ ec = fsm->events; while (ec != NULL) { @@ -1781,6 +1984,18 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) fsm->name, fsm->event_nb); + /* Gen branch strings header. */ + for (i = 0; i < fsm->u_branch_nb; i++) + { + fprintf (f, "extern prog_char angfsm_%s_branch_str_%s[%u] PROGMEM;\n", + fsm->name, + fsm->u_branch_name[i], + strlen (fsm->u_branch_name[i]) + 1); + } + fprintf (f, "extern const char *angfsm_%s_branch_str[%u] PROGMEM;\n\n", + fsm->name, + fsm->u_branch_nb); + /* Create a RAM string able to store event or state string. */ j = 0; for (i = 0; i < fsm->event_nb; i++) @@ -1795,86 +2010,88 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) if (strlen (s->var_name) > j) j = strlen (s->var_name); } + for (i = 0; i < fsm->u_branch_nb; i++) + { + if (strlen (fsm->u_branch_name[i]) > j) + j = strlen (fsm->u_branch_name[i]); + } fprintf (f, "extern char angfsm_%s_str_buff[%u];\n", fsm->name, j + 1); - /* Convert an event enum in string. */ - fprintf (f, "char *\nangfsm_%s_get_event_string_from_enum \ - (angfsm_%s_event_t e);\n", fsm->name, fsm->name); - - /* Convert a event string in enum. */ - fprintf (f, "angfsm_%s_event_t\nangfsm_%s_get_event_enum_from_string \ - (char *str);\n", fsm->name, fsm->name); - - /* Convert an state enum in string. */ - fprintf (f, "char *\nangfsm_%s_get_state_string_from_enum \ - (angfsm_%s_state_t s);\n", fsm->name, fsm->name); - - /* Convert a state string in enum. */ - fprintf (f, "angfsm_%s_state_t\nangfsm_%s_get_state_enum_from_string \ - (char *str);\n", fsm->name, fsm->name); + /* Convert an event in string. */ + fprintf (f, "char *\nangfsm_%s_get_event_str (angfsm_%s_event_t e);\n", fsm->name, fsm->name); + /* Convert a state in string. */ + fprintf (f, "char *\nangfsm_%s_get_state_str (angfsm_%s_state_t s);\n", fsm->name, fsm->name); + /* Convert a branch in string. */ + fprintf (f, "char *\nangfsm_%s_get_branch_str (angfsm_%s_branch_t s);\n", fsm->name, fsm->name); } - - /* Gen transitions branches enum. */ - fprintf (f, "typedef enum\n{\n"); - tc = fsm->trans; - while (tc != NULL) + else { - bc = tc->trans.output_branches; - while (bc != NULL) - { - if (bc->name != NULL) - fprintf (f, "\tangfsm_BRANCH_%s_%s_%s_%s = %u,\n", - fsm->name, - tc->trans.state->var_name, - tc->trans.event->var_name, - bc->name, - bc->state->code); - else - fprintf (f, "\tangfsm_BRANCH_%s_%s_%s_ = %u,\n", - fsm->name, - tc->trans.state->var_name, - tc->trans.event->var_name, - bc->state->code); - bc = bc->next; - } - tc = tc->next; + /* Disable string macros. */ + fprintf (f, "#undef ANGFSM_STATE_STR\n#define ANGFSM_STATE_STR(s) ((char *)0)\n"); + fprintf (f, "#undef ANGFSM_EVENT_STR\n#define ANGFSM_EVENT_STR(e) ((char *)0)\n"); + fprintf (f, "#undef ANGFSM_BRANCH_STR\n#define ANGFSM_BRANCH_STR(b) ((char *)0)\n"); } - fprintf (f, "} angfsm_%s_branch_t;\n\n", fsm->name); /* Gen function headers. */ tc = fsm->trans; while (tc != NULL) { - fprintf (f, "angfsm_%s_branch_t angfsm_%s_trans_func_%s_%s (void);\n", - fsm->name, - fsm->name, - tc->trans.state->var_name, - tc->trans.event->var_name); + assert (tc->trans.output_branches); + /* Mono branch */ + if (tc->trans.output_branches->next==NULL) + fprintf (f, "void angfsm_%s_trans_func_%s_%s ();\n", + fsm->name, + tc->trans.state->var_name, + tc->trans.event->var_name); + else + fprintf (f, "angfsm_%s_branch_t angfsm_%s_trans_func_%s_%s ();\n", + fsm->name, + fsm->name, + tc->trans.state->var_name, + tc->trans.event->var_name); tc = tc->next; } fprintf (f, "\n"); - /* Gen function table. */ - fprintf (f, "typedef angfsm_%s_branch_t (*angfsm_%s_func_t)(void);\n", fsm->name, + /* Declare function type. */ + fprintf (f, "typedef void (*angfsm_%s_func_t)();\n", fsm->name); + fprintf (f, "typedef angfsm_%s_branch_t (*angfsm_%s_func_branches_t)();\n\n", + fsm->name, fsm->name); + + /* Gen branch structure. */ + fprintf (f, "typedef struct\n{\n"); + fprintf (f, "\tangfsm_%s_branch_t branch;\n", fsm->name); + fprintf (f, "\tangfsm_%s_state_t state;\n", fsm->name); + fprintf (f, "} angfsm_%s_next_t;\n\n", fsm->name); + + /* Gen transition structure. */ + fprintf (f, "typedef struct\n{\n"); + fprintf (f, "\tangfsm_%s_event_t event;\n", fsm->name); + fprintf (f, "\tangfsm_%s_func_t func;\n", fsm->name); + fprintf (f, "\tangfsm_%s_next_t branches[angfsm_%s_max_branches_per_trans];\n", + fsm->name, fsm->name); - fprintf (f, "extern const angfsm_%s_func_t PROGMEM angfsm_%s_trans_table[%u][%u];\n", + fprintf (f, "} angfsm_%s_trans_t;\n\n", fsm->name); + + /* Gen transition table. */ + fprintf (f, "extern const angfsm_%s_trans_t PROGMEM angfsm_%s_trans_table[angfsm_STATE_%s_NB][angfsm_%s_max_events_per_states];\n\n", + fsm->name, fsm->name, fsm->name, - fsm->event_nb, - fsm->state_nb); + fsm->name); + /* Gen read function for trans table. */ - fprintf (f, "angfsm_%s_func_t angfsm_%s_read_trans (angfsm_%s_event_t event, " - "angfsm_%s_state_t state);\n\n", + fprintf (f, "inline angfsm_%s_trans_t* angfsm_%s_read_trans (angfsm_%s_event_t event, angfsm_%s_state_t state);\n\n", fsm->name, fsm->name, fsm->name, fsm->name); /* Gen active states array. */ - fprintf (f, "extern angfsm_%s_state_t angfsm_%s_active_states[%u];\n\n", + fprintf (f, "extern angfsm_%s_state_t angfsm_%s_active_states[angfsm_%s_max_active_states];\n\n", fsm->name, fsm->name, - fsm->max_active_states); + fsm->name); /* Gen initialization function. */ sc = fsm->starters; @@ -1899,20 +2116,20 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) fsm->name); /* Gen timeout values. */ - fprintf (f, "extern int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB_];\n", + fprintf (f, "extern int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB];\n", fsm->name, fsm->name); /* Gen timeout corresponding events. */ - fprintf (f, "extern angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB_];\n", + fprintf (f, "extern angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB];\n", fsm->name, fsm->name, fsm->name); /* Gen timeout counters array. */ - fprintf (f, "extern int32_t angfsm_%s_timeout_counters[%u];\n\n", + fprintf (f, "extern int32_t angfsm_%s_timeout_counters[angfsm_%s_max_active_states];\n\n", fsm->name, - fsm->max_active_states); + fsm->name); } /* Conclusion. */ @@ -1926,14 +2143,16 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch) void angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) { + assert (fsm); assert (arch < ANGFSM_BUILD_ARCH_NB); angfsm_build_state_chain_t *sc; angfsm_build_event_chain_t *ec; angfsm_build_trans_chain_t *tc; angfsm_build_timeout_chain_t *toc; + angfsm_build_branch_chain_t *bc; angfsm_build_state_t *s; angfsm_build_event_t *e; - uint i, j, found; + uint i, j, k, count; uint embedded_strings = fsm->options.embedded_strings; /* Open file. */ @@ -1950,9 +2169,10 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) angfsm_build_arch_name[arch], fsm->name); - /* Gen state strings. */ + /* Gen strings if configured. */ if (embedded_strings) { + /* Gen state strings. */ sc = fsm->states; while (sc != NULL) { @@ -1996,6 +2216,25 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) } fprintf (f, "};\n\n"); + /* Gen branch strings. */ + for (i = 0; i < fsm->u_branch_nb; i++) + { + fprintf (f, "prog_char angfsm_%s_branch_str_%s[] PROGMEM = \"%s\";\n", + fsm->name, + fsm->u_branch_name[i], + fsm->u_branch_name[i]); + } + fprintf (f, "const char *angfsm_%s_branch_str[] PROGMEM =\n{\n", fsm->name); + for (i = 0; i < fsm->u_branch_nb; i++) + { + fprintf (f, "\tangfsm_%s_branch_str_%s", fsm->name, fsm->u_branch_name[i]); + if (i == fsm->u_branch_nb - 1) + fprintf (f, "\n"); + else + fprintf (f, ",\n"); + } + fprintf (f, "};\n\n"); + /* Create a RAM string able to store event or state string. */ j = 0; for (i = 0; i < fsm->event_nb; i++) @@ -2010,106 +2249,152 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) if (strlen (s->var_name) > j) j = strlen (s->var_name); } + for (i = 0; i < fsm->u_branch_nb; i++) + { + if (strlen (fsm->u_branch_name[i]) > j) + j = strlen (fsm->u_branch_name[i]); + } fprintf (f, "char angfsm_%s_str_buff[%u];\n", fsm->name, j + 1); + /* Generate string read functions. */ /* Convert an event enum in string. */ - fprintf (f, "char *\nangfsm_%s_get_event_string_from_enum \ + fprintf (f, "char *\nangfsm_%s_get_event_str \ (angfsm_%s_event_t e)\n{\n", fsm->name, fsm->name); fprintf (f, "\treturn strcpy_P (angfsm_%s_str_buff, \ (char *) pgm_read_word (&(angfsm_%s_event_str[e])));\n", fsm->name, fsm->name); fprintf (f, "}\n\n"); - - /* Convert a event string in enum. */ - fprintf (f, "angfsm_%s_event_t\nangfsm_%s_get_event_enum_from_string \ - (char *str)\n{\n", fsm->name, fsm->name); - fprintf (f, "\tuint16_t i;\n"); - fprintf (f, "\tfor (i = 0; i < angfsm_EVENT_%s_NB_; i++)\n", fsm->name); - fprintf (f, "\t\tif (strcpy_P (str, \ - (char *) pgm_read_word (&(angfsm_%s_event_str[i]))) == 0)\n", fsm->name); - fprintf (f, "\t\t\treturn i;\n"); - fprintf (f, "\treturn angfsm_EVENT_%s_NB_;\n", fsm->name); - fprintf (f, "}\n\n"); - - /* Convert an state enum in string. */ - fprintf (f, "char *\nangfsm_%s_get_state_string_from_enum \ + /* Convert a state enum in string. */ + fprintf (f, "char *\nangfsm_%s_get_state_str \ (angfsm_%s_state_t s)\n{\n", fsm->name, fsm->name); fprintf (f, "\treturn strcpy_P (angfsm_%s_str_buff, \ (char *) pgm_read_word (&(angfsm_%s_state_str[s])));\n", fsm->name, fsm->name); fprintf (f, "}\n\n"); - - /* Convert a state string in enum. */ - fprintf (f, "angfsm_%s_state_t\nangfsm_%s_get_state_enum_from_string \ - (char *str)\n{\n", fsm->name, fsm->name); - fprintf (f, "\tuint16_t i;\n"); - fprintf (f, "\tfor (i = 0; i < angfsm_STATE_%s_NB_; i++)\n", fsm->name); - fprintf (f, "\t\tif (strcpy_P (str, \ - (char *) pgm_read_word (&(angfsm_%s_state_str[i]))) == 0)\n", fsm->name); - fprintf (f, "\t\t\treturn i;\n"); - fprintf (f, "\treturn angfsm_STATE_%s_NB_;\n", fsm->name); + /* Convert a branch enum in string. */ + fprintf (f, "char *\nangfsm_%s_get_branch_str \ + (angfsm_%s_branch_t b)\n{\n", fsm->name, fsm->name); + fprintf (f, "\treturn strcpy_P (angfsm_%s_str_buff, \ + (char *) pgm_read_word (&(angfsm_%s_branch_str[b])));\n", fsm->name, fsm->name); fprintf (f, "}\n\n"); } - /* Gen function table. */ - fprintf (f, "const angfsm_%s_func_t PROGMEM angfsm_%s_trans_table[%u][%u] = \n{\n", + /* Gen transition table. */ + fprintf (f, "const angfsm_%s_trans_t PROGMEM angfsm_%s_trans_table[angfsm_STATE_%s_NB][angfsm_%s_max_events_per_states] = \n{\n", fsm->name, fsm->name, - fsm->event_nb, - fsm->state_nb); - /* for each events and state, see if it exists an associated transition. */ - for (i = 0; i < fsm->event_nb; i++) + fsm->name, + fsm->name); + for (i = 0; i < fsm->state_nb; i++) { - e = angfsm_build_get_event_by_code (fsm, i); - fprintf (f, "\t{"); - for (j = 0; j < fsm->state_nb; j++) + count = 0; + fprintf (f, "\t{\n"); + tc = fsm->trans; + while (tc != NULL) { - s = angfsm_build_get_state_by_code (fsm, j); - tc = fsm->trans; - found = 0; - while (tc != NULL) - { - if (tc->trans.state == s && tc->trans.event == e) - { - found = 1; - fprintf (f, "&angfsm_%s_trans_func_%s_%s", - fsm->name, - tc->trans.state->var_name, - tc->trans.event->var_name); - tc = tc->next; - break; - } - tc = tc->next; - } - if (!found) - fprintf (f, "(angfsm_%s_func_t) 0", fsm->name); - if (j == fsm->state_nb - 1) - fprintf (f, "}"); - else - fprintf (f, ", "); + if (tc->trans.state->code == i) + { + fprintf (f, "\t\t{\n"); + fprintf (f, "\t\t\tangfsm_EVENT_%s_%s,\n", + fsm->name, + tc->trans.event->var_name); + fprintf (f, "\t\t\t(angfsm_%s_func_t) &angfsm_%s_trans_func_%s_%s,\n", + fsm->name, + fsm->name, + tc->trans.state->var_name, + tc->trans.event->var_name); + /* Gen branche array */ + fprintf (f, "\t\t\t{\n"); + j = 0; + bc = tc->trans.output_branches; + while (bc != NULL) + { + fprintf (f, "\t\t\t\t{angfsm_BRANCH_%s_%s, angfsm_STATE_%s_%s}", + fsm->name, + (bc->name ? bc->name : "NB"), + fsm->name, + bc->state->var_name); + if (j != fsm->max_branches_per_trans - 1) + fprintf (f, ", "); + fprintf (f, "\n"); + j++; + bc = bc->next; + } + /* Fill blank branches. */ + for (k = j; k < fsm->max_branches_per_trans; k++) + { + fprintf (f, "\t\t\t\t{angfsm_BRANCH_%s_NB, angfsm_STATE_%s_NB}", + fsm->name, + fsm->name); + if (k != fsm->max_branches_per_trans - 1) + fprintf (f, ","); + fprintf (f, "\n"); + } + + fprintf (f, "\t\t\t}\n"); + if (tc->next != NULL || count != fsm->max_events_per_states) + fprintf (f, "\t\t},\n"); + else + fprintf (f, "\t\t}\n"); + count++; + } + tc = tc->next; } - if (i != fsm->event_nb - 1) - fprintf (f, ","); - fprintf (f, "\n"); + /* Fill blanch transitions. */ + for (k = count; k < fsm->max_events_per_states; k++) + { + fprintf (f, "\t\t{\n"); + fprintf (f, "\t\t\tangfsm_EVENT_%s_NB,\n",fsm->name); + fprintf (f, "\t\t\t(angfsm_%s_func_t) 0,\n", fsm->name); + fprintf (f, "\t\t\t{\n"); + for (j = 0; j < fsm->max_branches_per_trans; j++) + { + fprintf (f, "\t\t\t\t{angfsm_BRANCH_%s_NB, angfsm_STATE_%s_NB}", + fsm->name, + fsm->name); + if (j != fsm->max_branches_per_trans - 1) + fprintf (f, ","); + fprintf (f, "\n"); + } + fprintf (f, "\t\t\t}\n"); + if (k != fsm->max_events_per_states - 1) + fprintf (f, "\t\t},\n"); + else + fprintf (f, "\t\t}\n"); + } + + if (i == fsm->state_nb - 1) + fprintf (f, "\t}\n"); + else + fprintf (f, "\t},\n"); } fprintf (f, "};\n\n"); - /* Gen read function for trans table. */ - fprintf (f, "angfsm_%s_func_t angfsm_%s_read_trans (angfsm_%s_event_t event, " - "angfsm_%s_state_t state)\n{\n", - fsm->name, - fsm->name, + /* Transition callback. */ + fprintf (f, "void (*angfsm_%s_trans_callback) (int state, int event, int output_branch, int branch);\n", fsm->name); + + /* Gen active states array. */ + fprintf (f, "angfsm_%s_state_t angfsm_%s_active_states[angfsm_%s_max_active_states];\n\n", fsm->name, - fsm->name); - fprintf (f, "\treturn (angfsm_%s_func_t) pgm_read_word " - "(&angfsm_%s_trans_table[event][state]);\n", fsm->name, fsm->name); - fprintf (f, "}\n\n"); - /* Gen active states array. */ - fprintf (f, "angfsm_%s_state_t angfsm_%s_active_states[%u];\n\n", + /* Gen read transition from event and state. */ + fprintf (f, "inline angfsm_%s_trans_t* angfsm_%s_read_trans " + "(angfsm_%s_event_t event, angfsm_%s_state_t state)\n{\n", fsm->name, fsm->name, - fsm->max_active_states); + fsm->name, + fsm->name); + fprintf (f, "\tint i;\n"); + fprintf (f, "\tangfsm_%s_trans_t* t;\n", fsm->name); + fprintf (f, "\tfor (i = 0; i < angfsm_%s_max_events_per_states; i++)\n\t{\n", + fsm->name); + fprintf (f, "\t\tt = (angfsm_%s_trans_t *) pgm_read_word (&angfsm_%s_trans_table[state][i]);\n", + fsm->name, + fsm->name); + fprintf (f, "\t\tif (t->func == (angfsm_%s_func_t) 0)\n\t\t\tbreak;\n", fsm->name); + fprintf (f, "\t\tif (t->event == event)\n"); + fprintf (f, "\t\t\treturn t;\n"); + fprintf (f, "\t}\n\treturn (angfsm_%s_trans_t*) 0;\n}\n\n", fsm->name); /* Gen initialization function. */ sc = fsm->starters; @@ -2117,11 +2402,11 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) fprintf (f, "void\nangfsm_%s_init ()\n{\n", fsm->name); while (sc != NULL) { - fprintf (f, "\tangfsm_%s_active_states[%u] = (angfsm_%s_state_t) %u;\n", + fprintf (f, "\tangfsm_%s_active_states[%u] = angfsm_STATE_%s_%s;\n", fsm->name, i, fsm->name, - sc->state.code); + sc->state.var_name); if (fsm->timeouts != NULL) { toc = fsm->timeouts; @@ -2140,23 +2425,43 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) i++; sc = sc->next; } + /* Set transition callback to NULL. */ + fprintf (f, "\tangfsm_%s_trans_callback = (typeof (angfsm_%s_trans_callback)) 0;\n", fsm->name, fsm->name); fprintf (f, "}\n\n"); /* Gen handle function. */ fprintf (f, "int\nangfsm_%s_handle (angfsm_%s_event_t e)\n{\n", fsm->name, fsm->name); - fprintf (f, "\tuint16_t i;\n"); + fprintf (f, "\tuint16_t i, j;\n"); fprintf (f, "\tint handled = 0;\n"); + fprintf (f, "\tangfsm_%s_branch_t b;\n", fsm->name); fprintf (f, "\tfor (i = 0; i < angfsm_%s_max_active_states; i++)\n\t{\n", fsm->name); - fprintf (f, "\t\tangfsm_%s_func_t trans = angfsm_%s_read_trans (e, angfsm_%s_active_states[i]);\n", + fprintf (f, "\t\tangfsm_%s_trans_t *trans = angfsm_%s_read_trans (e, angfsm_%s_active_states[i]);\n", fsm->name, fsm->name, fsm->name); fprintf (f, "\t\tif (trans)\n"); fprintf (f, "\t\t{\n"); - fprintf (f, "\t\t\tangfsm_%s_active_states[i] = (angfsm_%s_state_t) trans ();\n", fsm->name, fsm->name); + fprintf (f, "\t\t\tangfsm_%s_state_t s = angfsm_STATE_%s_NB;\n", fsm->name, fsm->name); + fprintf (f, "\t\t\tif (trans->branches[0].branch == angfsm_BRANCH_%s_NB)\n\t\t\t{\n", fsm->name); + fprintf (f, "\t\t\t\ttrans->func ();\n"); + fprintf (f, "\t\t\t\ts = trans->branches[0].state;\n"); + fprintf (f, "\t\t\t\tif (angfsm_%s_trans_callback)\n", fsm->name); + fprintf (f, "\t\t\t\t\tangfsm_%s_trans_callback(angfsm_%s_active_states[i], e, s, -1);\n", fsm->name, fsm->name); + fprintf (f, "\t\t\t}\n\t\t\telse\n\t\t\t{\n"); + fprintf (f, "\t\t\t\tb = ((angfsm_%s_func_branches_t) trans->func) ();\n", fsm->name); + fprintf (f, "\t\t\t\tfor (j = 0; j < angfsm_%s_max_branches_per_trans; j++)\n", fsm->name); + fprintf (f, "\t\t\t\t\tif (trans->branches[j].branch == b)\n"); + fprintf (f, "\t\t\t\t\t\ts = trans->branches[j].state;\n"); + fprintf (f, "\t\t\t\t\tif (angfsm_%s_trans_callback)\n", fsm->name); + fprintf (f, "\t\t\t\t\t\tangfsm_%s_trans_callback(angfsm_%s_active_states[i], e, s, b);\n", fsm->name, fsm->name); + fprintf (f, "\t\t\t}\n"); + fprintf (f, "\t\t\tif (s != angfsm_STATE_%s_NB)\n", fsm->name); + fprintf (f, "\t\t\t\tangfsm_%s_active_states[i] = s;\n", fsm->name); + fprintf (f, "\t\t\telse\n"); + fprintf (f, "\t\t\t\t{;} //XXX show some error ?\n"); fprintf (f, "\t\t\thandled = 1;\n"); if (fsm->timeouts != NULL) { @@ -2188,12 +2493,12 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) if (fsm->timeouts != NULL) { /* Gen timeout counters array. */ - fprintf (f, "int32_t angfsm_%s_timeout_counters[%u];\n", + fprintf (f, "int32_t angfsm_%s_timeout_counters[angfsm_%s_max_active_states];\n", fsm->name, - fsm->max_active_states); + fsm->name); /* Gen timeout values array. */ - fprintf (f, "int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB_] =\n{\n", + fprintf (f, "int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB] =\n{\n", fsm->name, fsm->name); int value; @@ -2220,7 +2525,7 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) fprintf (f, "};\n\n"); /* Gen timeout corresponding events array. */ - fprintf (f, "angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB_] =\n{\n", + fprintf (f, "angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB] =\n{\n", fsm->name, fsm->name, fsm->name); @@ -2240,7 +2545,7 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch) toc = toc->next; } if (value == -1) - fprintf (f, "\t(angfsm_%s_event_t) angfsm_STATE_%s_NB_", fsm->name, fsm->name); + fprintf (f, "\t(angfsm_%s_event_t) angfsm_STATE_%s_NB", fsm->name, fsm->name); else fprintf (f, "\t(angfsm_%s_event_t) %u", fsm->name, value); @@ -2429,6 +2734,11 @@ angfsm_build_free (angfsm_build_t *fsm) free (toc_tmp); } + /* Free unique branch names array. */ + /* Strings are already free in transitions. */ + if (fsm->u_branch_name) + free (fsm->u_branch_name); + /* Free run data (trans_table). */ for (i = 0; i < fsm->event_nb; i++) free (fsm->run.trans_table[i]); @@ -2452,5 +2762,3 @@ angfsm_build_free (angfsm_build_t *fsm) /*Free run data (timeout counters). */ free (fsm->run.timeout_counters); } - -#endif /* HOST */ diff --git a/digital/ai/src/fsm/angfsm_generic.h b/digital/ai/src/fsm/angfsm_generic.h index 4e1c589f..f2840beb 100644 --- a/digital/ai/src/fsm/angfsm_generic.h +++ b/digital/ai/src/fsm/angfsm_generic.h @@ -1,6 +1,6 @@ /* AngFSM - Almost Non Generated Finite State Machine - Copyright 2011, 2012 Jerome Jutteau + Copyright 2011-2013 Jerome Jutteau This file is part of AngFSM. @@ -50,9 +50,7 @@ /** Disable dot generation. */ #define ANGFSM_GEN_DOT(fsm, output) -/** Disable state defining - * - * Define states of the fsm, can be called several times to add other states. */ +/** Disable state defining */ #define ANGFSM_STATES(states...) /** Disable event defining */ @@ -62,28 +60,52 @@ #define ANGFSM_START_WITH(starters...) #define ANGFSM_TRANS(state, event, output_branches...) \ - ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_branch_t) \ - ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_trans_func_##state##_##event) () + IFELSE_ARG1(void, ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_branch_t), output_branches) ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_trans_func_##state##_##event) () -#define ANGFSM_NEXT(state, event, branch...) \ - ANGFSM_PASTE3_EXPAND (angfsm_BRANCH_, ANGFSM_NAME,_##state##_##event##_##branch) +/** Transform an event in a numeric value. */ +#define ANGFSM_EVENT(event) (ANGFSM_PASTE3_EXPAND (angfsm_EVENT_,ANGFSM_NAME,_##event)) +#define ANGFSM_EVENT_F(fsm, event) angfsm_EVENT_##fsm##_##event -/** Transform an event in uint16_t. */ -#define ANGFSM_EVENT(fsm, event) angfsm_EVENT_##fsm##_##event +/** Transform a state in a numeric value. */ +#define ANGFSM_STATE(state) (ANGFSM_PASTE3_EXPAND (angfsm_STATE_,ANGFSM_NAME,_##state)) +#define ANGFSM_STATE_F(fsm, state) angfsm_STATE_##fsm##_##state -/** Handle event from uint16_t. */ +/** Transform a branch in a numeric value. */ +#define ANGFSM_BRANCH(branch) (ANGFSM_PASTE3_EXPAND (angfsm_BRANCH_,ANGFSM_NAME,_##branch)) +#define ANGFSM_BRANCH_F(fsm, branch) angfsm_BRANCH_##fsm##_##branch + +/** Handle event from numeric event. */ #define ANGFSM_HANDLE_VAR(fsm, event) angfsm_##fsm##_handle (event) -/* Can we handle event from uint16_t ? */ +/* Can we handle event from numeric event ? */ #define ANGFSM_CAN_HANDLE_VAR(fsm, event) angfsm_##fsm##_can_handle (event) /* Time out macros. */ #define ANGFSM_TRANS_TIMEOUT(state, timeout, output_branches...) \ ANGFSM_TRANS (state, state##_TIMEOUT, output_branches) -#define ANGFSM_NEXT_TIMEOUT(state, branch...) \ - ANGFSM_NEXT (state, state##_TIMEOUT, branch) - #define ANGFSM_HANDLE_TIMEOUT(fsm_name) angfsm_##fsm_name##_handle_timeout () -#endif \ No newline at end of file +/* Callback for transitions. */ +#define ANGFSM_TRANS_CALLBACK(cb) \ + ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_trans_callback) = cb; + +/* Get state string. + * This macro is disabled if strings has no been embedded. + */ +#define ANGFSM_STATE_STR(state) \ + ((char *) ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_get_state_str (state))) + +/* Get event string. + * This macro is disabled if strings has no been embedded. + */ +#define ANGFSM_EVENT_STR(event) \ + ((char *) ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_get_event_str (event))) + +/* Get branch string. + * This macro is disabled if strings has no been embedded. + */ +#define ANGFSM_BRANCH_STR(branch) \ + ((char *) ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_get_branch_str (branch))) + +#endif diff --git a/digital/ai/src/fsm/angfsm_host_exec.h b/digital/ai/src/fsm/angfsm_host_exec.h index 956ef4ed..8fac0a42 100644 --- a/digital/ai/src/fsm/angfsm_host_exec.h +++ b/digital/ai/src/fsm/angfsm_host_exec.h @@ -1,6 +1,6 @@ /* AngFSM - Almost Non Generated Finite State Machine - Copyright 2011, 2012 Jerome Jutteau + Copyright 2011-2013 Jerome Jutteau This file is part of AngFSM. @@ -103,8 +103,15 @@ typedef struct angfsm_build_trans_chain_t { struct angfsm_build_trans_chain_t *next; } angfsm_build_trans_chain_t; -/* Pointer to a transition function. */ -typedef angfsm_build_state_t* (*angfsm_build_run_strans_func_t)(void); +/* Pointer to a transition function. + * out_branch corresponds to function's return. + * Mono branch transitions do not return anything, + * It permits to avoid ugly warnings. + * Multi branches returns a uint, the function is transtyped as a + * angfsm_build_run_strans_func_branches_t + */ +typedef void (*angfsm_build_run_strans_func_t) (); +typedef uint (*angfsm_build_run_strans_func_branches_t) (); /* Chain of transitions with associated function's pointer. */ typedef struct angfsm_trans_func_chain_t { @@ -146,6 +153,11 @@ typedef struct { /* Array of counters for timeout events. * -1 mean counter is off. */ int *timeout_counters; + /* Callback to transitions. */ + void (*trans_callback) (int state, + int event, + int output_branch, + int branch); } angfsm_build_run_t; /* Store all Finite State Machine (fsm) informations. */ @@ -160,6 +172,10 @@ typedef struct { char *name; /* Maximal number of active states. */ uint max_active_states; + /* Maximal number of events per states. */ + uint max_events_per_states; + /* Maximal number of branches per transitions. */ + uint max_branches_per_trans; /* Total number of events. */ uint event_nb; /* Total number of states. */ @@ -168,6 +184,13 @@ typedef struct { angfsm_build_state_chain_t *starters; /* All timeout. */ angfsm_build_timeout_chain_t *timeouts; + /* Total number of unique branch name. */ + uint u_branch_nb; + /* List of unique branches strings. + * Unique number corresponding to string is the position of the string + *in the array. + */ + char **u_branch_name; /* Data for running purposes. */ angfsm_build_run_t run; /* User's options. */ @@ -189,7 +212,8 @@ void angfsm_build_init_all_fsm() __attribute__((constructor(101))); * function. This permits initilialization of the fsm. */ extern angfsm_build_t ANGFSM_PASTE_EXPAND(angfsm_, ANGFSM_NAME); void ANGFSM_PASTE_EXPAND(angfsm_build_init_, ANGFSM_NAME)() __attribute__((constructor(102))); -void ANGFSM_PASTE_EXPAND(angfsm_build_run_init_, ANGFSM_NAME)() __attribute__((constructor(107))); +void ANGFSM_PASTE_EXPAND(angfsm_build_init_finalize_, ANGFSM_NAME)() __attribute__((constructor(107))); +void ANGFSM_PASTE_EXPAND(angfsm_build_run_init_, ANGFSM_NAME)() __attribute__((constructor(108))); void ANGFSM_PASTE_EXPAND(angfsm_build_free_, ANGFSM_NAME)() __attribute__((destructor)); #define ANGFSM_INIT \ @@ -198,6 +222,10 @@ void ANGFSM_PASTE_EXPAND(angfsm_build_free_, ANGFSM_NAME)() __attribute__((destr { \ angfsm_build_init (ANGFSM_PASTE_EXPAND (&angfsm_, ANGFSM_NAME), XSTR(ANGFSM_NAME)); \ } \ + void ANGFSM_PASTE_EXPAND (angfsm_build_init_finalize_, ANGFSM_NAME)() \ + { \ + angfsm_build_init_finalize (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME)); \ + } \ void ANGFSM_PASTE_EXPAND (angfsm_build_run_init_, ANGFSM_NAME)() \ { \ angfsm_build_run_init (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME)); \ @@ -262,23 +290,14 @@ extern angfsm_build_t angfsm_##fsm_name; * See examples for reel usage. */ #define ANGFSM_TRANS(state, event, output_branches...) \ -angfsm_build_state_t* ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state##_##event) (); \ + IFELSE_ARG1(void, uint, output_branches) ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state##_##event) (); \ void ANGFSM_PASTE3_EXPAND (angfsm_build_trans_, ANGFSM_NAME,_##state##_##event)() __attribute__((constructor(105))); \ void ANGFSM_PASTE3_EXPAND (angfsm_build_trans_, ANGFSM_NAME,_##state##_##event)() \ { \ - angfsm_build_trans (& ANGFSM_PASTE_EXPAND(angfsm_, ANGFSM_NAME), #state, #event, \ - #output_branches, \ - & ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state##_##event)); \ + angfsm_build_trans (& ANGFSM_PASTE_EXPAND(angfsm_, ANGFSM_NAME), #state, #event, #output_branches, \ + (angfsm_build_run_strans_func_t) &ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state##_##event)); \ } \ - angfsm_build_state_t* ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state##_##event) () - -/** - * Used to return next state by giving the actual transition informations and - * the branch (if there are several branches). - * Not directly returning the state can avoid some errors. * - */ -#define ANGFSM_NEXT(state, event, branch...) \ - angfsm_build_get_next_state (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), #state, #event, #branch) + IFELSE_ARG1(void, uint, output_branches) ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state##_##event) () /** * Define a transition when a state times out. @@ -296,28 +315,51 @@ angfsm_build_state_t* ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state# ANGFSM_EVENTS (state##_TIMEOUT) \ ANGFSM_TRANS (state, state##_TIMEOUT, output_branches) -/** - * Used to return next state after a timeout. - * Same as ANGFSM_NEXT but without specifying an event. - */ -#define ANGFSM_NEXT_TIMEOUT(state, branch...) \ - ANGFSM_NEXT (state, state##_TIMEOUT, branch) - /** Used to handle timeout events. */ #define ANGFSM_HANDLE_TIMEOUT(fsm_name) \ - angfsm_build_handle_timeout (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME)) + (angfsm_build_handle_timeout (& angfsm_##fsm_name)) + +/** Transform an event in a numeric value. */ +#define ANGFSM_EVENT(event) \ + (angfsm_build_get_event_code (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), #event)) +#define ANGFSM_EVENT_F(fsm_name, event) \ + (angfsm_build_get_event_code (& angfsm_##fsm_name, #event)) + +/** Transform a state in a numeric value. */ +#define ANGFSM_STATE(state) \ + (angfsm_build_get_state (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), #state)->code) +#define ANGFSM_STATE_F(fsm_name, state) \ + (angfsm_build_get_state (& angfsm_##fsm_name, #state)->code) + +/** Transform a branch in a numeric value. */ +#define ANGFSM_BRANCH(branch) \ + (angfsm_build_get_branch (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), #branch)) +#define ANGFSM_BRANCH_F(fsm_name, branch) \ + (angfsm_build_get_branch (& angfsm_##fsm_name, #branch)) + +/** Handle event from numeric value. */ +#define ANGFSM_HANDLE_VAR(fsm, event) \ + angfsm_build_handle_integer (& angfsm_##fsm, event) -/** Transform an event in uint16_t. */ -#define ANGFSM_EVENT(fsm_name, event) \ - angfsm_build_get_event_code (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), #event) +/* Can we handle event from numeric value ? */ +#define ANGFSM_CAN_HANDLE_VAR(fsm, event) \ + angfsm_build_can_handle_integer (& angfsm_##fsm, event) -/** Handle event from uint16_t. */ -#define ANGFSM_HANDLE_VAR(fsm, event) \ - angfsm_build_handle_integer (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), event) +/* Callback for transitions. */ +#define ANGFSM_TRANS_CALLBACK(cb) \ + ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME).run.trans_callback = cb -/* Can we handle event from uint16_t ? */ -#define ANGFSM_CAN_HANDLE_VAR(fSM, event) \ - angfsm_build_can_handle_integer (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), event) +/* Get state string. */ +#define ANGFSM_STATE_STR(state) \ + ((char *)((angfsm_build_get_state_by_code((& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME)), state))->var_name)) + +/* Get event string. */ +#define ANGFSM_EVENT_STR(event) \ + ((char *)((angfsm_build_get_event_by_code((& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME)), event))->var_name)) + +/* Get branch string. */ +#define ANGFSM_BRANCH_STR(branch) \ + ((char *)(ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME).u_branch_name[branch])) /** * Parse a string who contains a list of arguments separated by comma. @@ -339,15 +381,15 @@ void angfsm_build_arg_free(char ***tab, int nb); /** - * This function is executed when a state is returned by a transition. + * Print transition. * \param fsm fsm * \param trans transition where the return occurs * \param branch branch to transition has chosen. */ void -angfsm_build_print(angfsm_build_t *fsm, - angfsm_build_trans_t* trans, - angfsm_build_branch_chain_t* branch); +angfsm_build_print_trans (angfsm_build_t *fsm, + angfsm_build_trans_t* trans, + angfsm_build_branch_chain_t* branch); /** * Test the fsm and search for errors. @@ -371,6 +413,10 @@ angfsm_build_gen_dot(angfsm_build_t *fsm, char *output); void angfsm_build_init(angfsm_build_t *fsm, char *name); +/** Finalize the preparation of the FSM informations. */ +void +angfsm_build_init_finalize (angfsm_build_t *fsm); + /** Initialize the running data of the fsm. */ void angfsm_build_run_init(angfsm_build_t *fsm); @@ -407,10 +453,24 @@ angfsm_build_get_event_by_code(angfsm_build_t *fsm, uint event); angfsm_build_state_t* angfsm_build_get_state_by_code(angfsm_build_t *fsm, uint state); -/** Get event code as uint16_t */ +/** Get transition pointer by giving it's state and event. */ +angfsm_build_trans_t* +angfsm_build_get_trans (angfsm_build_t *fsm, uint state, uint event); + +/** Get event code as a numeric value. */ uint16_t angfsm_build_get_event_code(angfsm_build_t *fsm, char *event); +/** Get branch pointer from transition and branch string. */ +angfsm_build_branch_chain_t* +angfsm_build_get_event_branch (angfsm_build_t *fsm, + angfsm_build_trans_t *trans, + uint branch); + +/** Get branch unique code from branch name. */ +uint +angfsm_build_get_branch (angfsm_build_t *fsm, char *branch); + /** * Add a transition to the fsm. * \param fsm fsm @@ -482,13 +542,6 @@ angfsm_build_can_handle_integer(angfsm_build_t *fsm, uint16_t event); int angfsm_build_handle_timeout(angfsm_build_t *fsm); -/** Give the state at the transition output. */ -angfsm_build_state_t* -angfsm_build_get_next_state(angfsm_build_t *fsm, - char *state, - char *event, - char *branch); - /** Pass parameters to AngFSM at execution. Try --ang-help * \param argc argc from your main. * \param argv argv from your main. diff --git a/digital/ai/src/fsm/angfsm_renaming.h b/digital/ai/src/fsm/angfsm_renaming.h index 393fad42..f50f692e 100644 --- a/digital/ai/src/fsm/angfsm_renaming.h +++ b/digital/ai/src/fsm/angfsm_renaming.h @@ -28,18 +28,25 @@ #define FSM_HANDLE ANGFSM_HANDLE #define FSM_CAN_HANDLE ANGFSM_CAN_HANDLE #define FSM_RESET ANGFSM_RESET -#define FSM_GEN_DOTANGFSM_GEN_DOT +#define FSM_GEN_DOT ANGFSM_GEN_DOT #define FSM_STATES ANGFSM_STATES #define FSM_EVENTS ANGFSM_EVENTS #define FSM_START_WITH ANGFSM_START_WITH #define FSM_TRANS ANGFSM_TRANS -#define FSM_NEXT ANGFSM_NEXT +#define FSM_STATE ANGFSM_STATE #define FSM_EVENT ANGFSM_EVENT +#define FSM_BRANCH ANGFSM_BRANCH +#define FSM_STATE_F ANGFSM_STATE_F +#define FSM_EVENT_F ANGFSM_EVENT_F +#define FSM_BRANCH_F ANGFSM_BRANCH_F #define FSM_HANDLE_VAR ANGFSM_HANDLE_VAR #define FSM_CAN_HANDLE_VAR ANGFSM_CAN_HANDLE_VAR #define FSM_TRANS_TIMEOUT ANGFSM_TRANS_TIMEOUT -#define FSM_NEXT_TIMEOUT ANGFSM_NEXT_TIMEOUT #define FSM_HANDLE_TIMEOUT ANGFSM_HANDLE_TIMEOUT - +#define FSM_TRANS_CALLBACK ANGFSM_TRANS_CALLBACK +#define FSM_STATE_STR ANGFSM_STATE_STR +#define FSM_EVENT_STR ANGFSM_EVENT_STR +#define FSM_BRANCH_STR ANGFSM_BRANCH_STR + #endif /* #ifdef _ANGFSM_RENAME_ */ diff --git a/digital/ai/src/fsm/init.c b/digital/ai/src/fsm/init.c index 72479a32..00c5a08f 100644 --- a/digital/ai/src/fsm/init.c +++ b/digital/ai/src/fsm/init.c @@ -88,61 +88,52 @@ FSM_START_WITH (INIT_START) FSM_TRANS (INIT_START, jack_inserted, INIT_WAITING_FIRST_JACK_OUT) { - return FSM_NEXT (INIT_START, jack_inserted); } FSM_TRANS (INIT_WAITING_FIRST_JACK_OUT, jack_removed, INIT_INITIALISING_ACTUATORS) { - fsm_queue_post_event (FSM_EVENT (AI, init_actuators)); - return FSM_NEXT (INIT_WAITING_FIRST_JACK_OUT, jack_removed); + fsm_queue_post_event (FSM_EVENT (init_actuators)); } FSM_TRANS (INIT_INITIALISING_ACTUATORS, jack_inserted, INIT_WAITING_HANDS_OUT) { team_color = contact_get_color (); - return FSM_NEXT (INIT_INITIALISING_ACTUATORS, jack_inserted); } FSM_TRANS_TIMEOUT (INIT_WAITING_HANDS_OUT, 225, INIT_FINDING_FIRST_WALL) { asserv_set_speed (BOT_SPEED_INIT); asserv_push_the_wall (INIT_FIRST_WALL_PUSH); - return FSM_NEXT_TIMEOUT (INIT_WAITING_HANDS_OUT); } FSM_TRANS (INIT_FINDING_FIRST_WALL, robot_move_success, INIT_GOING_AWAY_FIRST_WALL) { asserv_move_linearly (INIT_FIRST_WALL_AWAY); - return FSM_NEXT (INIT_FINDING_FIRST_WALL, robot_move_success); } FSM_TRANS (INIT_GOING_AWAY_FIRST_WALL, robot_move_success, INIT_FACING_SECOND_WALL) { asserv_goto_angle (INIT_SECOND_WALL_ANGLE); - return FSM_NEXT (INIT_GOING_AWAY_FIRST_WALL, robot_move_success); } FSM_TRANS (INIT_FACING_SECOND_WALL, robot_move_success, INIT_WAITING_AFTER_FACING_SECOND_WALL) { - return FSM_NEXT (INIT_FACING_SECOND_WALL, robot_move_success); } FSM_TRANS_TIMEOUT (INIT_WAITING_AFTER_FACING_SECOND_WALL, 225 / 2, INIT_FINDING_SECOND_WALL) { asserv_push_the_wall (INIT_SECOND_WALL_PUSH); - return FSM_NEXT_TIMEOUT (INIT_WAITING_AFTER_FACING_SECOND_WALL); } FSM_TRANS (INIT_FINDING_SECOND_WALL, robot_move_success, INIT_GOING_AWAY_SECOND_WALL) { asserv_move_linearly (INIT_SECOND_WALL_AWAY); - return FSM_NEXT (INIT_FINDING_SECOND_WALL, robot_move_success); } #ifdef INIT_START_POSITION_ANGLE @@ -150,14 +141,12 @@ FSM_TRANS (INIT_GOING_AWAY_SECOND_WALL, robot_move_success, INIT_FACING_START_POSITION) { asserv_goto_angle (INIT_START_POSITION_ANGLE); - return FSM_NEXT (INIT_GOING_AWAY_SECOND_WALL, robot_move_success); } FSM_TRANS (INIT_FACING_START_POSITION, robot_move_success, INIT_GOING_TO_START_POSITION) { asserv_goto_xya (INIT_START_POSITION); - return FSM_NEXT (INIT_FACING_START_POSITION, robot_move_success); } #else @@ -166,7 +155,6 @@ FSM_TRANS (INIT_GOING_AWAY_SECOND_WALL, robot_move_success, INIT_GOING_TO_START_POSITION) { asserv_goto_xya (INIT_START_POSITION); - return FSM_NEXT (INIT_GOING_AWAY_SECOND_WALL, robot_move_success); } #endif @@ -174,15 +162,13 @@ FSM_TRANS (INIT_GOING_AWAY_SECOND_WALL, robot_move_success, FSM_TRANS (INIT_GOING_TO_START_POSITION, robot_move_success, INIT_WAITING_SECOND_JACK_OUT) { - fsm_queue_post_event (FSM_EVENT (AI, init_done)); + fsm_queue_post_event (FSM_EVENT (init_done)); asserv_set_speed (BOT_SPEED_NORMAL); - return FSM_NEXT (INIT_GOING_TO_START_POSITION, robot_move_success); } FSM_TRANS (INIT_WAITING_SECOND_JACK_OUT, jack_removed, INIT_FINISHED) { chrono_start (); - fsm_queue_post_event (FSM_EVENT (AI, init_start_round)); - return FSM_NEXT (INIT_WAITING_SECOND_JACK_OUT, jack_removed); + fsm_queue_post_event (FSM_EVENT (init_start_round)); } -- cgit v1.2.3