cr50: Let state machines print their own states

Add a function to translate device_state enum into a string, then use
it for printing the ec and RDD state.

Refactor ec_state so that all state transitions go through a
set_state() function, which makes it easier to turn on debugging all
state transitions.  That's normally not compiled in because it would
be spammy during debouncing.

BUG=none
BRANCH=cr50
TEST=ccd command prints EC and RDD states

Change-Id: Ie7bc56c7b66beee23d1d1989711c640e5e39ce43
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/642121
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
This commit is contained in:
Randall Spangler
2017-08-28 15:54:14 -07:00
committed by chrome-bot
parent 63deaa4f59
commit b0891c9450
6 changed files with 78 additions and 18 deletions

View File

@@ -115,6 +115,28 @@ void ec_tx_cr50_rx(enum gpio_signal signal)
hook_call_deferred(&ec_uart_deferred__data, 0);
}
const char *device_state_names[] = {
"init",
"init_debouncing",
"init_rx_only",
"disconnected",
"off",
"undetectable",
"connected",
"on",
"debouncing",
"unknown"
};
BUILD_ASSERT(ARRAY_SIZE(device_state_names) == DEVICE_STATE_COUNT);
const char *device_state_name(enum device_state state)
{
if (state >= 0 && state < DEVICE_STATE_COUNT)
return device_state_names[state];
else
return "?";
}
int board_use_plt_rst(void)
{
return !!(board_properties & BOARD_USE_PLT_RESET);

View File

@@ -220,8 +220,19 @@ enum device_state {
/* Device state is unknown. Used only by legacy device_state code. */
DEVICE_STATE_UNKNOWN,
/* Number of device states */
DEVICE_STATE_COUNT
};
/**
* Return the name of the device state as as string.
*
* @param state State to look up
* @return Name of the state, or "?" if no match.
*/
const char *device_state_name(enum device_state state);
/* NVMem variables. */
enum nvmem_vars {
NVMEM_VAR_CONSOLE_LOCKED = 0,
@@ -270,6 +281,8 @@ int board_is_first_factory_boot(void);
void enable_ccd_uart(int uart);
void disable_ccd_uart(int uart);
void print_ec_state(void);
int ap_is_on(void);
int ec_is_on(void);
int rdd_is_connected(void);

View File

@@ -15,12 +15,37 @@
static enum device_state state = DEVICE_STATE_INIT;
void print_ec_state(void)
{
ccprintf("EC: %s\n", device_state_name(state));
}
int ec_is_on(void)
{
/* Debouncing and on are both still on */
return (state == DEVICE_STATE_DEBOUNCING || state == DEVICE_STATE_ON);
}
/**
* Set the EC state.
*
* Done as a function to make it easier to debug state transitions. Note that
* this ONLY sets the state (and possibly prints debug info), and doesn't do
* all the additional transition work that set_ec_on(), etc. do.
*
* @param new_state State to set.
*/
static void set_state(enum device_state new_state)
{
#ifdef CR50_DEBUG_EC_STATE
/* Print all state transitions. May spam the console. */
if (state != new_state)
CPRINTS("EC %s -> %s",
device_state_name(state), device_state_name(new_state));
#endif
state = new_state;
}
/**
* Move the EC to the ON state.
*
@@ -41,13 +66,13 @@ static void set_ec_on(void)
CPRINTS("EC RX only");
if (!uart_bitbang_is_enabled(UART_EC))
uartn_enable(UART_EC);
state = DEVICE_STATE_INIT_RX_ONLY;
set_state(DEVICE_STATE_INIT_RX_ONLY);
return;
}
/* If we were debouncing ON->OFF, cancel it because we're still on */
if (state == DEVICE_STATE_DEBOUNCING)
state = DEVICE_STATE_ON;
set_state(DEVICE_STATE_ON);
/* If we're already on, done */
if (state == DEVICE_STATE_ON)
@@ -55,7 +80,7 @@ static void set_ec_on(void)
/* We were previously off */
CPRINTS("EC on");
state = DEVICE_STATE_ON;
set_state(DEVICE_STATE_ON);
/* Enable UART RX if we're not bit-banging */
if (!uart_bitbang_is_enabled(UART_EC))
@@ -94,7 +119,7 @@ static void ec_detect(void)
if (state == DEVICE_STATE_DEBOUNCING ||
state == DEVICE_STATE_INIT_DEBOUNCING) {
CPRINTS("EC off");
state = DEVICE_STATE_OFF;
set_state(DEVICE_STATE_OFF);
disable_ccd_uart(UART_EC);
return;
}
@@ -104,9 +129,9 @@ static void ec_detect(void)
* is actually off or just sending a 0-bit. So start debouncing.
*/
if (state == DEVICE_STATE_INIT)
state = DEVICE_STATE_INIT_DEBOUNCING;
set_state(DEVICE_STATE_INIT_DEBOUNCING);
else
state = DEVICE_STATE_DEBOUNCING;
set_state(DEVICE_STATE_DEBOUNCING);
gpio_enable_interrupt(GPIO_DETECT_EC);
}
DECLARE_HOOK(HOOK_SECOND, ec_detect, HOOK_PRIO_DEFAULT);

View File

@@ -189,9 +189,10 @@ static int command_ccd(int argc, char **argv)
return EC_ERROR_PARAM1;
}
ccprintf("CCD: %s\n",
rdd_detect_is_forced() ? "forced enable" :
rdd_is_connected() ? "enabled" : "disabled");
print_ec_state();
print_rdd_state();
ccprintf("CCD: %s\n", rdd_is_connected() ? "enabled" : "disabled");
ccprintf("AP UART: %s\n",
uartn_is_enabled(UART_AP) ?
uart_tx_is_connected(UART_AP) ? "RX+TX" : "RX" : "disabled");

View File

@@ -49,6 +49,12 @@ static int rdd_is_detected(void)
return (cc1 == cc2 && (cc1 == 3 || cc1 == 1));
}
void print_rdd_state(void)
{
ccprintf("RDD: %s\n",
force_detected ? "forced enable" : device_state_name(state));
}
/**
* Handle debug accessory disconnecting
*/
@@ -234,8 +240,3 @@ void force_rdd_detect(int enable)
if (force_detected)
hook_call_deferred(&rdd_connect_data, 0);
}
int rdd_detect_is_forced(void)
{
return force_detected;
}

View File

@@ -22,10 +22,8 @@ void init_rdd_state(void);
void force_rdd_detect(int enable);
/**
* Check if debug accessory detection is forced.
*
* @return 1 if keepalive is enabled, 0 if disabled.
* Print debug accessory detect state
*/
int rdd_detect_is_forced(void);
void print_rdd_state(void);
#endif /* __CROS_RDD_H */