drivers: led: add shell support
This patch introduces the "led" shell command. This allows to run the LED API functions (and to test the LED drivers) from the Zephyr shell. The following subcommands are supported: - on - off - get_info - set_brightness - set_color - set_channel - write_channels Signed-off-by: Simon Guinot <simon.guinot@seagate.com>
This commit is contained in:
parent
53cbe5ff29
commit
21f4fef78b
3 changed files with 335 additions and 0 deletions
|
@ -6,4 +6,6 @@ zephyr_sources_ifdef(CONFIG_LP503X lp503x.c)
|
|||
zephyr_sources_ifdef(CONFIG_LP5562 lp5562.c)
|
||||
zephyr_sources_ifdef(CONFIG_PCA9633 pca9633.c)
|
||||
|
||||
zephyr_sources_ifdef(CONFIG_LED_SHELL led_shell.c)
|
||||
|
||||
zephyr_sources_ifdef(CONFIG_USERSPACE led_handlers.c)
|
||||
|
|
|
@ -20,6 +20,12 @@ config LED_INIT_PRIORITY
|
|||
help
|
||||
System initialization priority for LED drivers.
|
||||
|
||||
config LED_SHELL
|
||||
bool "LED shell"
|
||||
depends on SHELL
|
||||
help
|
||||
Enable LED shell for testing.
|
||||
|
||||
source "drivers/led/Kconfig.ht16k33"
|
||||
source "drivers/led/Kconfig.lp3943"
|
||||
source "drivers/led/Kconfig.lp503x"
|
||||
|
|
327
drivers/led/led_shell.c
Normal file
327
drivers/led/led_shell.c
Normal file
|
@ -0,0 +1,327 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Seagate Technology LLC
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <shell/shell.h>
|
||||
#include <drivers/led.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_REGISTER(led_shell);
|
||||
|
||||
#define MAX_CHANNEL_ARGS 8
|
||||
|
||||
enum {
|
||||
arg_idx_dev = 1,
|
||||
arg_idx_led = 2,
|
||||
arg_idx_value = 3,
|
||||
};
|
||||
|
||||
static int parse_common_args(const struct shell *shell, char **argv,
|
||||
struct device **dev, uint32_t *led)
|
||||
{
|
||||
char *end_ptr;
|
||||
|
||||
*dev = device_get_binding(argv[arg_idx_dev]);
|
||||
if (!*dev) {
|
||||
shell_error(shell,
|
||||
"LED device %s not found", argv[arg_idx_dev]);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
*led = strtoul(argv[arg_idx_led], &end_ptr, 0);
|
||||
if (*end_ptr != '\0') {
|
||||
shell_error(shell, "Invalid LED number parameter %s",
|
||||
argv[arg_idx_led]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_off(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
struct device *dev;
|
||||
uint32_t led;
|
||||
int err;
|
||||
|
||||
err = parse_common_args(shell, argv, &dev, &led);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
shell_print(shell, "%s: turning off LED %d", dev->name, led);
|
||||
|
||||
err = led_off(dev, led);
|
||||
if (err) {
|
||||
shell_error(shell, "Error: %d", err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cmd_on(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
struct device *dev;
|
||||
uint32_t led;
|
||||
int err;
|
||||
|
||||
err = parse_common_args(shell, argv, &dev, &led);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
shell_print(shell, "%s: turning on LED %d", dev->name, led);
|
||||
|
||||
err = led_on(dev, led);
|
||||
if (err) {
|
||||
shell_error(shell, "Error: %d", err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cmd_get_info(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
struct device *dev;
|
||||
uint32_t led;
|
||||
int err;
|
||||
const struct led_info *info;
|
||||
int i;
|
||||
|
||||
err = parse_common_args(shell, argv, &dev, &led);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
shell_print(shell, "%s: getting LED %d information", dev->name, led);
|
||||
|
||||
err = led_get_info(dev, led, &info);
|
||||
if (err) {
|
||||
shell_error(shell, "Error: %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
shell_print(shell, "Label : %s", info->label ? : "<NULL>");
|
||||
shell_print(shell, "Index : %d", info->index);
|
||||
shell_print(shell, "Num colors : %d", info->num_colors);
|
||||
if (info->color_mapping) {
|
||||
shell_fprintf(shell, SHELL_NORMAL, "Colors : %d",
|
||||
info->color_mapping[0]);
|
||||
for (i = 1; i < info->num_colors; i++) {
|
||||
shell_fprintf(shell, SHELL_NORMAL, ":%d",
|
||||
info->color_mapping[i]);
|
||||
}
|
||||
shell_fprintf(shell, SHELL_NORMAL, "\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_set_brightness(const struct shell *shell,
|
||||
size_t argc, char **argv)
|
||||
{
|
||||
struct device *dev;
|
||||
uint32_t led;
|
||||
int err;
|
||||
char *end_ptr;
|
||||
unsigned long value;
|
||||
|
||||
err = parse_common_args(shell, argv, &dev, &led);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
value = strtoul(argv[arg_idx_value], &end_ptr, 0);
|
||||
if (*end_ptr != '\0') {
|
||||
shell_error(shell, "Invalid LED brightness parameter %s",
|
||||
argv[arg_idx_value]);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (value > 100) {
|
||||
shell_error(shell, "Invalid LED brightness value %d (max 100)",
|
||||
value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
shell_print(shell, "%s: setting LED %d brightness to %d",
|
||||
dev->name, led, value);
|
||||
|
||||
err = led_set_brightness(dev, led, (uint8_t) value);
|
||||
if (err) {
|
||||
shell_error(shell, "Error: %d", err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cmd_set_color(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
struct device *dev;
|
||||
uint32_t led;
|
||||
int err;
|
||||
size_t num_colors;
|
||||
uint8_t i;
|
||||
uint8_t color[MAX_CHANNEL_ARGS];
|
||||
|
||||
err = parse_common_args(shell, argv, &dev, &led);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
num_colors = argc - arg_idx_value;
|
||||
if (num_colors > MAX_CHANNEL_ARGS) {
|
||||
shell_error(shell,
|
||||
"Invalid number of colors %d (max %d)",
|
||||
num_colors, MAX_CHANNEL_ARGS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_colors; i++) {
|
||||
char *end_ptr;
|
||||
unsigned long col;
|
||||
|
||||
col = strtoul(argv[arg_idx_value + i], &end_ptr, 0);
|
||||
if (*end_ptr != '\0') {
|
||||
shell_error(shell, "Invalid LED color parameter %s",
|
||||
argv[arg_idx_value + i]);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (col > 255) {
|
||||
shell_error(shell,
|
||||
"Invalid LED color value %d (max 255)",
|
||||
col);
|
||||
return -EINVAL;
|
||||
}
|
||||
color[i] = col;
|
||||
}
|
||||
|
||||
shell_fprintf(shell, SHELL_NORMAL, "%s: setting LED %d color to %d",
|
||||
dev->name, led, color[0]);
|
||||
for (i = 1; i < num_colors; i++) {
|
||||
shell_fprintf(shell, SHELL_NORMAL, ":%d", color[i]);
|
||||
}
|
||||
shell_fprintf(shell, SHELL_NORMAL, "\n");
|
||||
|
||||
err = led_set_color(dev, led, num_colors, color);
|
||||
if (err) {
|
||||
shell_error(shell, "Error: %d", err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cmd_set_channel(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
struct device *dev;
|
||||
uint32_t channel;
|
||||
int err;
|
||||
char *end_ptr;
|
||||
unsigned long value;
|
||||
|
||||
err = parse_common_args(shell, argv, &dev, &channel);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
value = strtoul(argv[arg_idx_value], &end_ptr, 0);
|
||||
if (*end_ptr != '\0') {
|
||||
shell_error(shell, "Invalid channel value parameter %s",
|
||||
argv[arg_idx_value]);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (value > 255) {
|
||||
shell_error(shell, "Invalid channel value %d (max 255)",
|
||||
value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
shell_print(shell, "%s: setting channel %d to %d",
|
||||
dev->name, channel, value);
|
||||
|
||||
err = led_set_channel(dev, channel, (uint8_t) value);
|
||||
if (err) {
|
||||
shell_error(shell, "Error: %d", err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
cmd_write_channels(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
struct device *dev;
|
||||
uint32_t start_channel;
|
||||
int err;
|
||||
size_t num_channels;
|
||||
uint8_t i;
|
||||
uint8_t value[MAX_CHANNEL_ARGS];
|
||||
|
||||
err = parse_common_args(shell, argv, &dev, &start_channel);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
num_channels = argc - arg_idx_value;
|
||||
if (num_channels > MAX_CHANNEL_ARGS) {
|
||||
shell_error(shell,
|
||||
"Can't write %d channels (max %d)",
|
||||
num_channels, MAX_CHANNEL_ARGS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_channels; i++) {
|
||||
char *end_ptr;
|
||||
unsigned long val;
|
||||
|
||||
val = strtoul(argv[arg_idx_value + i], &end_ptr, 0);
|
||||
if (*end_ptr != '\0') {
|
||||
shell_error(shell,
|
||||
"Invalid channel value parameter %s",
|
||||
argv[arg_idx_value + i]);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (val > 255) {
|
||||
shell_error(shell,
|
||||
"Invalid channel value %d (max 255)", val);
|
||||
return -EINVAL;
|
||||
}
|
||||
value[i] = val;
|
||||
}
|
||||
|
||||
shell_fprintf(shell, SHELL_NORMAL, "%s: writing from channel %d: %d",
|
||||
dev->name, start_channel, value[0]);
|
||||
for (i = 1; i < num_channels; i++) {
|
||||
shell_fprintf(shell, SHELL_NORMAL, " %d", value[i]);
|
||||
}
|
||||
shell_fprintf(shell, SHELL_NORMAL, "\n");
|
||||
|
||||
err = led_write_channels(dev, start_channel, num_channels, value);
|
||||
if (err) {
|
||||
shell_error(shell, "Error: %d", err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(sub_led,
|
||||
SHELL_CMD_ARG(off, NULL, "<device> <led>", cmd_off, 3, 0),
|
||||
SHELL_CMD_ARG(on, NULL, "<device> <led>", cmd_on, 3, 0),
|
||||
SHELL_CMD_ARG(get_info, NULL, "<device> <led>", cmd_get_info, 3, 0),
|
||||
SHELL_CMD_ARG(set_brightness, NULL, "<device> <led> <value [0-255]>",
|
||||
cmd_set_brightness, 4, 0),
|
||||
SHELL_CMD_ARG(set_color, NULL,
|
||||
"<device> <led> <color 0 [0-255]> ... <color N>",
|
||||
cmd_set_color, 4, MAX_CHANNEL_ARGS - 1),
|
||||
SHELL_CMD_ARG(set_channel, NULL, "<device> <channel> <value [0-255]>",
|
||||
cmd_set_channel, 4, 0),
|
||||
SHELL_CMD_ARG(write_channels, NULL,
|
||||
"<device> <chan> <value 0 [0-255]> ... <value N>",
|
||||
cmd_write_channels, 4, MAX_CHANNEL_ARGS - 1),
|
||||
SHELL_SUBCMD_SET_END
|
||||
);
|
||||
|
||||
SHELL_CMD_REGISTER(led, &sub_led, "LED commands", NULL);
|
Loading…
Add table
Add a link
Reference in a new issue