summaryrefslogtreecommitdiff
path: root/include/usb_sm.h
diff options
context:
space:
mode:
authorJett Rink <jettrink@chromium.org>2019-08-02 16:20:50 -0600
committerCommit Bot <commit-bot@chromium.org>2019-08-20 15:53:16 +0000
commit2a7996a3caf25d358164a48e80723758e8be1fd1 (patch)
treea6dd0682b7ab1c3cc408450137e5f10988cf9da7 /include/usb_sm.h
parenta1aea89ae15c85d56f52976289a329e7c58bc8f6 (diff)
downloadchrome-ec-2a7996a3caf25d358164a48e80723758e8be1fd1.tar.gz
usb: update state machine framework
- OBJ is renamed to context (CTX) for current and last state - State definition now includes its parent (no need for the boiler plate function that takes in a signal) - The init_state, set_state, and exe_state have been re-written to take advantages of new state machine definition. I had to add more logic to handle hierarchical states fully. - Explicitly create the USB states at the bottom of the file with all of the statics. Don't need to use macros (even though I did suggest them) - Use NULL when we do_nothing instead of calling into a function - Created a "private" enum in the C file that lists all of the states in the file, that we can use to refer to a state (it is also the index into the states array for that state). - Changed prototype of state function to return void, since we aren't really using the return value and it cleans up a lot of return 0 that aren't needed. - Add const to int port since we can and should - Moves struct definition to implementation file only to keep implementation details private. We can access data through accessor if needed. BRANCH=none BUG=none TEST=all unit tests passes Change-Id: I482a63e08f7d63022d5102b891a2fac0b0faa46f Signed-off-by: Jett Rink <jettrink@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1733744 Commit-Queue: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'include/usb_sm.h')
-rw-r--r--include/usb_sm.h155
1 files changed, 37 insertions, 118 deletions
diff --git a/include/usb_sm.h b/include/usb_sm.h
index e57cd0b873..f9f10b439f 100644
--- a/include/usb_sm.h
+++ b/include/usb_sm.h
@@ -8,142 +8,61 @@
#ifndef __CROS_EC_USB_SM_H
#define __CROS_EC_USB_SM_H
-#define DECLARE_SM_FUNC_(prefix, name, run, exit) \
- DECLARE_SM_FUNC_##run(prefix, name); \
- DECLARE_SM_FUNC_##exit(prefix, name)
-
-#define DECLARE_SM_FUNC_WITH_RUN(prefix, name) static int \
- prefix##_##name##_run(int port)
-
-#define DECLARE_SM_FUNC_WITH_EXIT(prefix, name) static int \
- prefix##_##name##_exit(int port)
-
-#define DECLARE_SM_FUNC_NOOP(prefix, name)
-
-#define DECLARE_SM_SIG_RUN(prefix, name, run) DECLARE_SM_##run(prefix, name)
-#define DECLARE_SM_WITH_RUN(prefix, name) prefix##_##name##_run
-
-#define DECLARE_SM_SIG_EXIT(prefix, name, exit) DECLARE_SM_##exit(prefix, name)
-#define DECLARE_SM_WITH_EXIT(prefix, name) prefix##_##name##_exit
-
-#define DECLARE_SM_NOOP(prefix, name) sm_do_nothing
+/* Function pointer that implements a portion of a usb state */
+typedef void (*state_execution)(const int port);
/*
- * Helper macro for the declaration of states.
- *
- * @param prefix - prefix of state function name
- * @param name - name of state
- * @param run - if WITH_RUN, generates a run state function name
- * if NOOP, generates a do nothing function name
- * @param exit - if WITH_EXIT, generates an exit state function name
- * if NOOP, generates a do nothing function name
- *
- * EXAMPLE:
- *
- * DECLARE_STATE(tc, test, WITH_RUN, WITH_EXIT); generates the following:
+ * General usb state that can be used in multiple state machines.
*
- * static unsigned int tc_test(int port, enum sm_signal sig);
- * static unsigned int tc_test_entry(int port);
- * static unsigned int tc_test_run(int port);
- * static unsigned int tc_test_exit(int port);
- * static const state_sig tc_test_sig[] = {
- * tc_test_entry,
- * tc_test_run,
- * tc_test_exit,
- * sm_get_super_state };
- *
- * DECLARE_STATE(tc, test, NOOP, NOOP); generates the following:
- *
- * static unsigned int tc_test(int port, enum sm_signal sig);
- * static unsigned int tc_test_entry(int port);
- * static const state_sig tc_test_sig[] = {
- * tc_test_entry,
- * sm_do_nothing,
- * sm_do_nothing,
- * sm_get_super_state };
+ * entry - Optional method that will be run when this state is entered
+ * run - Optional method that will be run repeatedly during state machine loop
+ * exit - Optional method that will be run when this state exists
+ * parent- Optional parent usb_state that contains common entry/run/exit
+ * implementation between various usb state. All parent entry/run
+ * functions will before any child entry/run functions. All parent exit
+ * functions will run after any child exit functions.
*/
-#define DECLARE_STATE(prefix, name, run, exit) \
-static int prefix##_##name(int port, enum sm_signal sig); \
-static int prefix##_##name##_entry(int port); \
-DECLARE_SM_FUNC_(prefix, name, run, exit); \
-static const state_sig prefix##_##name##_sig[] = { \
-prefix##_##name##_entry, \
-DECLARE_SM_SIG_RUN(prefix, name, run), \
-DECLARE_SM_SIG_EXIT(prefix, name, exit), \
-sm_get_super_state \
-}
+struct usb_state {
+ const state_execution entry;
+ const state_execution run;
+ const state_execution exit;
+ const struct usb_state *parent;
+};
+
+typedef const struct usb_state *usb_state_ptr;
-#define SM_OBJ(smo) ((struct sm_obj *)&smo)
-#define SM_SUPER(r, sig, s) ((((r) == 0) || ((sig) == SM_ENTRY_SIG) || \
- ((sig) == SM_EXIT_SIG)) ? 0 : ((uintptr_t)(s)))
-#define SM_RUN_SUPER 1
+/* Defines the current context of the usb statemachine. */
+struct sm_ctx {
+ usb_state_ptr current;
+ usb_state_ptr previous;
+ /* We use intptr_t type to accommodate host tests ptr size variance */
+ intptr_t internal[2];
+};
/* Local state machine states */
enum sm_local_state {
- SM_INIT,
+ SM_INIT = 0, /* Ensure static variables initialize to SM_INIT */
SM_RUN,
- SM_PAUSED
-};
-
-/* State Machine signals */
-enum sm_signal {
- SM_ENTRY_SIG = 0,
- SM_RUN_SIG,
- SM_EXIT_SIG,
- SM_SUPER_SIG,
+ SM_PAUSED,
};
-typedef int (*state_sig)(int port);
-typedef int (*sm_state)(int port, enum sm_signal sig);
-
-struct sm_obj {
- sm_state task_state;
- sm_state last_state;
-};
-
-/**
- * Initialize a State Machine
- *
- * @param port USB-C port number
- * @param obj State machine object
- * @param target Initial state of state machine
- */
-void sm_init_state(int port, struct sm_obj *obj, sm_state target);
-
-/**
- * Changes a state machines state
- *
- * @param port USB-C port number
- * @param obj State machine object
- * @param target State to transition to
- * @return 0
- */
-int sm_set_state(int port, struct sm_obj *obj, sm_state target);
-
-/**
- * Runs a state machine
- *
- * @param port USB-C port number
- * @param obj State machine object
- * @param sig State machine signal
- */
-void sm_run_state_machine(int port, struct sm_obj *obj, enum sm_signal sig);
-
/**
- * Substitute this function for states that do not implement a
- * run or exit state.
+ * Changes a state machines state. This handles exiting the previous state and
+ * entering the target state. A common parent state will not exited nor be
+ * re-entered.
*
- * @param port USB-C port number
- * @return 0
+ * @param port USB-C port number
+ * @param ctx State machine context
+ * @param new_state State to transition to (NULL is valid and exits all states)
*/
-int sm_do_nothing(int port);
+void set_state(int port, struct sm_ctx *ctx, usb_state_ptr new_state);
/**
- * Called by the state machine framework to execute a states super state.
+ * Runs one iteration of a state machine (including any parent states)
*
* @param port USB-C port number
- * @return RUN_SUPER
+ * @param ctx State machine context
*/
-int sm_get_super_state(int port);
+void exe_state(int port, struct sm_ctx *ctx);
#endif /* __CROS_EC_USB_SM_H */