/* Copyright 2019 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* USB State Machine Framework */ #ifndef __CROS_EC_USB_SM_H #define __CROS_EC_USB_SM_H #include "compiler.h" /* for typeof() on Zephyr */ /* Function pointer that implements a portion of a usb state */ typedef void (*state_execution)(const int port); /* * General usb state that can be used in multiple state machines. * * 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 among various child usb_states. * entry: Parent function executes BEFORE child function. * run: Parent function executes AFTER child function. * exit: Parent function executes AFTER child function. * * Note: When transitioning between two child states with a shared parent, * that parent's exit and entry functions do not execute. */ 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; /* 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 = 0, /* Ensure static variables initialize to SM_INIT */ SM_RUN, SM_PAUSED, }; /* * A state machine can use these debug levels to regulate the amount of debug * information printed on the EC console * * The states currently defined are * Level 0: disabled * Level 1: state names * * Note that higher log level causes timing changes and thus may affect * performance. */ enum debug_level { DEBUG_DISABLE, DEBUG_LEVEL_1, DEBUG_LEVEL_2, DEBUG_LEVEL_3, DEBUG_LEVEL_MAX = DEBUG_LEVEL_3 }; /** * 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 * @param ctx State machine context * @param new_state State to transition to (NULL is valid and exits all states) */ void set_state(int port, struct sm_ctx *ctx, usb_state_ptr new_state); /** * Runs one iteration of a state machine (including any parent states) * * @param port USB-C port number * @param ctx State machine context */ void run_state(int port, struct sm_ctx *ctx); #ifdef TEST_BUILD /* * Struct for test builds that allow unit tests to easily iterate through * state machines */ struct test_sm_data { /* Base pointer of the state machine array */ const usb_state_ptr base; /* Size fo the state machine array above */ const int size; /* The array of names for states, can be NULL */ const char * const * const names; /* The size of the above names array */ const int names_size; }; #endif /* Creates a state machine state that will never link. Useful with IS_ENABLED */ #define GEN_NOT_SUPPORTED(state) extern typeof(state) state ## _NOT_SUPPORTED #endif /* __CROS_EC_USB_SM_H */