From 468bc6171c6c7b2b60d6b41ce443e3a6f0013161 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Tue, 8 May 2012 10:04:39 -0700 Subject: Add LPC lightbar command to get the current sequence. Instead of making the STOP command synchronous, we can just have the host-side app tell the EC to stop, then poll until it has. BUG=chrome-os-partner:9349 TEST=manual "make BOARD=link", then copy build/link/util/lbplay to the host and run it. Change-Id: I846924ae7994a498e0089197785cf239898fe2a3 Signed-off-by: Bill Richardson --- util/ectool.c | 44 ++++++++++++++++++++++++++++---------------- util/lbplay.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 17 deletions(-) (limited to 'util') diff --git a/util/ectool.c b/util/ectool.c index d90db5dee5..c395a525af 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -11,10 +11,12 @@ #include #include +#include "battery.h" #include "lightbar.h" #include "lpc_commands.h" -#include "battery.h" +/* Handy tricks */ +#define BUILD_ASSERT(cond) ((void)sizeof(char[1 - 2*!(cond)])) #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) /* Don't use a macro where an inline will do... */ static inline int MIN(int a, int b) { return a < b ? a : b; } @@ -846,14 +848,14 @@ static const char const *lightbar_cmds[] = { }; #undef LBMSG -/* This needs to match the values used in common/lightbar.c. I'd like to +/* This needs to match the values defined in lightbar.h. I'd like to * define this in one and only one place, but I can't think of a good way to do * that without adding bunch of complexity. This will do for now. */ static const struct { uint8_t insize; uint8_t outsize; -} lb_command_paramcount[LIGHTBAR_NUM_CMDS] = { +} lb_command_paramcount[] = { { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.dump), sizeof(((struct lpc_params_lightbar_cmd *)0)->out.dump) }, { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.off), @@ -870,6 +872,8 @@ static const struct { sizeof(((struct lpc_params_lightbar_cmd *)0)->out.reg) }, { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.rgb), sizeof(((struct lpc_params_lightbar_cmd *)0)->out.rgb) }, + { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.get_seq), + sizeof(((struct lpc_params_lightbar_cmd *)0)->out.get_seq) }, }; static int lb_help(const char *cmd) @@ -898,15 +902,6 @@ static uint8_t lb_find_msg_by_name(const char *str) return LIGHTBAR_NUM_SEQUENCES; } -static void lb_show_msg_names(void) -{ - int i; - printf("sequence names:"); - for (i = 0; i < LIGHTBAR_NUM_SEQUENCES; i++) - printf(" %s", lightbar_cmds[i]); - printf("\n"); -} - static int lb_do_cmd(enum lightbar_command cmd, struct lpc_params_lightbar_cmd *ptr) { @@ -918,6 +913,21 @@ static int lb_do_cmd(enum lightbar_command cmd, return r; } +static void lb_show_msg_names(void) +{ + int i, current_state; + struct lpc_params_lightbar_cmd param; + + (void)lb_do_cmd(LIGHTBAR_CMD_GET_SEQ, ¶m); + current_state = param.out.get_seq.num; + + printf("sequence names:"); + for (i = 0; i < LIGHTBAR_NUM_SEQUENCES; i++) + printf(" %s", lightbar_cmds[i]); + printf("\nCurrent = 0x%x %s\n", current_state, + lightbar_cmds[current_state]); +} + static int cmd_lightbar(int argc, char **argv) { int i, r; @@ -927,11 +937,11 @@ static int cmd_lightbar(int argc, char **argv) r = lb_do_cmd(LIGHTBAR_CMD_DUMP, ¶m); if (r) return r; - for (i = 0; i < sizeof(param.out.dump); i += 3) { + for (i = 0; i < ARRAY_SIZE(param.out.dump.vals); i++) { printf(" %02x %02x %02x\n", - param.out.dump[i], - param.out.dump[i+1], - param.out.dump[i+2]); + param.out.dump.vals[i].reg, + param.out.dump.vals[i].ic0, + param.out.dump.vals[i].ic1); } return 0; } @@ -1465,6 +1475,8 @@ int main(int argc, char *argv[]) { const struct command *cmd; + BUILD_ASSERT(ARRAY_SIZE(lb_command_paramcount) == LIGHTBAR_NUM_CMDS); + if (argc < 2 || !strcasecmp(argv[1], "-?") || !strcasecmp(argv[1], "help")) { print_help(argv[0]); diff --git a/util/lbplay.c b/util/lbplay.c index 33d8bb731e..56934ebea2 100644 --- a/util/lbplay.c +++ b/util/lbplay.c @@ -13,6 +13,9 @@ #include "lightbar.h" #include "lpc_commands.h" +/* Handy tricks */ +#define BUILD_ASSERT(cond) ((void)sizeof(char[1 - 2*!(cond)])) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) /* Waits for the EC to be unbusy. Returns 0 if unbusy, non-zero if * timeout. */ @@ -80,7 +83,7 @@ static int ec_command(int command, const void *indata, int insize, static const struct { uint8_t insize; uint8_t outsize; -} lb_command_paramcount[LIGHTBAR_NUM_CMDS] = { +} lb_command_paramcount[] = { { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.dump), sizeof(((struct lpc_params_lightbar_cmd *)0)->out.dump) }, { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.off), @@ -97,6 +100,8 @@ static const struct { sizeof(((struct lpc_params_lightbar_cmd *)0)->out.reg) }, { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.rgb), sizeof(((struct lpc_params_lightbar_cmd *)0)->out.rgb) }, + { sizeof(((struct lpc_params_lightbar_cmd *)0)->in.get_seq), + sizeof(((struct lpc_params_lightbar_cmd *)0)->out.get_seq) }, }; @@ -169,11 +174,33 @@ void lightbar_rgb(int led, int red, int green, int blue) ¶m, lb_command_paramcount[param.in.cmd].outsize); } +void wait_for_ec_to_stop(void) +{ + int r; + struct lpc_params_lightbar_cmd param; + int count = 0; + + do { + usleep(100000); + param.in.cmd = LIGHTBAR_CMD_GET_SEQ; + r = ec_command(EC_LPC_COMMAND_LIGHTBAR_CMD, + ¶m, + lb_command_paramcount[param.in.cmd].insize, + ¶m, + lb_command_paramcount[param.in.cmd].outsize); + if (count++ > 10) { + fprintf(stderr, "EC isn't responding\n"); + exit(1); + } + } while (r != 0 && param.out.get_seq.num != LIGHTBAR_STOP); +} int main(int argc, char **argv) { int i; + BUILD_ASSERT(ARRAY_SIZE(lb_command_paramcount) == LIGHTBAR_NUM_CMDS); + /* Request I/O privilege */ if (iopl(3) < 0) { perror("Error getting I/O privilege"); @@ -184,6 +211,9 @@ int main(int argc, char **argv) /* Tell the EC to let us drive. */ lightbar_sequence(LIGHTBAR_STOP); + /* Wait until it's listening */ + wait_for_ec_to_stop(); + /* Initialize it */ lightbar_off(); lightbar_init_vals(); -- cgit v1.2.1