From dd2b8c1155d016800cbbaa1bd70efdd81f9da493 Mon Sep 17 00:00:00 2001 From: Diego Rondini Date: Mon, 11 Apr 2022 12:02:09 +0200 Subject: [PATCH] cmd: gpio: Add `gpio read` subcommand As explained in commit 4af2a33ee5b9 ("cmd: gpio: Make `gpio input` return pin value again") the `gpio input` is used in scripts to obtain the value of a pin, despite the fact that CMD_RET_FAILURE is indistinguishable from a valid pin value. To be able to detect failures and properly use the value of a GPIO in scripts we introduce the `gpio read` command that sets the variable `name` to the value of the pin. Return code of the `gpio read` command can be used to check for CMD_RET_SUCCESS or CMD_RET_FAILURE. CONFIG_CMD_GPIO_READ is used to enable the `gpio read` command. Signed-off-by: Diego Rondini --- cmd/Kconfig | 7 ++++++ cmd/gpio.c | 45 +++++++++++++++++++++++++++++++++++--- configs/sandbox_defconfig | 1 + test/py/tests/test_gpio.py | 14 ++++++++++++ 4 files changed, 64 insertions(+), 3 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index d3abe3a06b..f580797d2d 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -996,6 +996,13 @@ config CMD_GPIO help GPIO support. +config CMD_GPIO_READ + bool "gpio read - save GPIO value to variable" + depends on CMD_GPIO + help + Enables the 'gpio read' command that saves the value + of a GPIO pin to a variable. + config CMD_PWM bool "pwm" depends on DM_PWM diff --git a/cmd/gpio.c b/cmd/gpio.c index 4150024e62..53e9ce666f 100644 --- a/cmd/gpio.c +++ b/cmd/gpio.c @@ -12,6 +12,9 @@ #include #include #include +#ifdef CONFIG_CMD_GPIO_READ +#include +#endif #include #include @@ -25,6 +28,9 @@ enum gpio_cmd { GPIOC_SET, GPIOC_CLEAR, GPIOC_TOGGLE, +#ifdef CONFIG_CMD_GPIO_READ + GPIOC_READ, +#endif }; #if defined(CONFIG_DM_GPIO) && !defined(gpio_status) @@ -125,6 +131,9 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc, enum gpio_cmd sub_cmd; int value; const char *str_cmd, *str_gpio = NULL; +#ifdef CONFIG_CMD_GPIO_READ + const char *str_var = NULL; +#endif int ret; #ifdef CONFIG_DM_GPIO bool all = false; @@ -137,11 +146,20 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc, argc -= 2; argv += 2; #ifdef CONFIG_DM_GPIO - if (argc > 0 && !strcmp(*argv, "-a")) { + if (argc > 0 && !strncmp(str_cmd, "status", 2) && !strcmp(*argv, "-a")) { all = true; argc--; argv++; } +#endif +#ifdef CONFIG_CMD_GPIO_READ + if (argc > 0 && !strncmp(str_cmd, "read", 2)) { + if (argc < 2) + goto show_usage; + str_var = *argv; + argc--; + argv++; + } #endif if (argc > 0) str_gpio = *argv; @@ -174,6 +192,11 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc, case 't': sub_cmd = GPIOC_TOGGLE; break; +#ifdef CONFIG_CMD_GPIO_READ + case 'r': + sub_cmd = GPIOC_READ; + break; +#endif default: goto show_usage; } @@ -205,7 +228,11 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc, } /* finally, let's do it: set direction and exec command */ - if (sub_cmd == GPIOC_INPUT) { + if (sub_cmd == GPIOC_INPUT +#ifdef CONFIG_CMD_GPIO_READ + || sub_cmd == GPIOC_READ +#endif + ) { gpio_direction_input(gpio); value = gpio_get_value(gpio); } else { @@ -233,9 +260,17 @@ static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc, goto err; } else { printf("%d\n", value); +#ifdef CONFIG_CMD_GPIO_READ + if (sub_cmd == GPIOC_READ) + env_set_ulong(str_var, (ulong)value); +#endif } - if (sub_cmd != GPIOC_INPUT && !IS_ERR_VALUE(value)) { + if (sub_cmd != GPIOC_INPUT && !IS_ERR_VALUE(value) +#ifdef CONFIG_CMD_GPIO_READ + && sub_cmd != GPIOC_READ +#endif + ) { int nval = gpio_get_value(gpio); if (IS_ERR_VALUE(nval)) { @@ -267,4 +302,8 @@ U_BOOT_CMD(gpio, 4, 0, do_gpio, "query and control gpio pins", " \n" " - input/set/clear/toggle the specified pin\n" +#ifdef CONFIG_CMD_GPIO_READ + "gpio read \n" + " - set environment variable 'name' to the specified pin\n" +#endif "gpio status [-a] [ | ] - show [all/claimed] GPIOs"); diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 06dbf38dcc..14d7af4db2 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -60,6 +60,7 @@ CONFIG_CMD_UNZIP=y CONFIG_CMD_BIND=y CONFIG_CMD_DEMO=y CONFIG_CMD_GPIO=y +CONFIG_CMD_GPIO_READ=y CONFIG_CMD_PWM=y CONFIG_CMD_GPT=y CONFIG_CMD_GPT_RENAME=y diff --git a/test/py/tests/test_gpio.py b/test/py/tests/test_gpio.py index 109649e2c7..fa0af5f82b 100644 --- a/test/py/tests/test_gpio.py +++ b/test/py/tests/test_gpio.py @@ -46,6 +46,20 @@ def test_gpio_exit_statuses(u_boot_console): response = u_boot_console.run_command('gpio input 200; echo rc:$?') assert(expected_response in response) +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('cmd_gpio') +def test_gpio_read(u_boot_console): + """Test that gpio read correctly sets the variable to the value of a gpio pin.""" + + response = u_boot_console.run_command('gpio read var 0; echo val:$var,rc:$?') + expected_response = 'val:0,rc:0' + assert(expected_response in response) + response = u_boot_console.run_command('gpio toggle 0; gpio read var 0; echo val:$var,rc:$?') + expected_response = 'val:1,rc:0' + assert(expected_response in response) + response = u_boot_console.run_command('setenv var; gpio read var nonexistent-gpio; echo val:$var,rc:$?') + expected_response = 'val:,rc:1' + assert(expected_response in response) """ Generic Tests for 'gpio' command on sandbox and real hardware. -- 2.39.5