From: Petr Hodina <[email protected]> Add a 'monitor' subcommand which redraws the state of all buttons every 100ms until Ctrl-C is pressed or a timeout expires (default 5s, 0 for none). This allows the buttons to be checked live on a device.
It reuses show_button_status() so both subcommands produce the same output. Signed-off-by: Petr Hodina <[email protected]> --- cmd/button.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/cmd/button.c b/cmd/button.c index da1bf1f6e3b..268f5a64952 100644 --- a/cmd/button.c +++ b/cmd/button.c @@ -7,8 +7,14 @@ #include <command.h> #include <dm.h> +#include <ansi.h> #include <button.h> +#include <console.h> +#include <stdio.h> +#include <time.h> +#include <vsprintf.h> #include <dm/uclass-internal.h> +#include <linux/delay.h> static const char *const state_label[] = { [BUTTON_OFF] = "off", @@ -65,6 +71,60 @@ static int list_buttons(void) return 0; } +static int monitor_buttons(unsigned long timeout_ms) +{ + ulong start = get_timer(0); + ulong elapsed; + int ret; + + /* Probe once; buttons which fail to probe are shown as <inactive> */ + ret = uclass_probe_all(UCLASS_BUTTON); + + puts(ANSI_CLEAR_CONSOLE); + printf(ANSI_CURSOR_POSITION, 1, 1); + puts("Button monitor\n"); + if (ret) + printf("Some buttons failed to probe (err=%d)", ret); + puts("\n"); + + for (;;) { + struct udevice *dev; + + if (ctrlc()) + break; + + elapsed = get_timer(start); + if (timeout_ms && elapsed >= timeout_ms) + break; + + printf(ANSI_CURSOR_POSITION, 3, 1); + if (timeout_ms) + printf("%lu.%lus left, Ctrl-C to quit" + ANSI_CLEAR_LINE_TO_END "\n", + (timeout_ms - elapsed) / 1000, + ((timeout_ms - elapsed) % 1000) / 100); + else + puts("Ctrl-C to quit" ANSI_CLEAR_LINE_TO_END "\n"); + puts("--------------------\n"); + + for (uclass_find_first_device(UCLASS_BUTTON, &dev); + dev; + uclass_find_next_device(&dev)) { + struct button_uc_plat *plat = dev_get_uclass_plat(dev); + + if (!plat->label) + continue; + printf("%-15s ", plat->label); + show_button_status(dev); + puts(ANSI_CLEAR_LINE_TO_END "\n"); + } + + mdelay(100); + } + + return 0; +} + int do_button(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { const char *button_label; @@ -77,6 +137,17 @@ int do_button(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) button_label = argv[1]; if (strncmp(button_label, "list", 4) == 0) return list_buttons(); + if (strcmp(button_label, "monitor") == 0) { + unsigned long timeout_ms = 5000; + char *endp; + + if (argc >= 3) { + timeout_ms = dectoul(argv[2], &endp); + if (endp == argv[2] || *endp) + return CMD_RET_USAGE; + } + return monitor_buttons(timeout_ms); + } ret = button_get_by_label(button_label, &dev); if (ret) { @@ -90,8 +161,11 @@ int do_button(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) } U_BOOT_CMD( - button, 2, 1, do_button, + button, 3, 1, do_button, "manage buttons", "<button_label> \tGet button state\n" - "button list\t\tShow a list of buttons" + "button list\t\tShow a list of buttons\n" + "button monitor [timeout_ms]\tLive table, updates every 100ms,\n" + " \tquits on timeout (default 5000ms,\n" + " \t0 = until Ctrl-C) or Ctrl-C" ); -- 2.55.0
