Skip to content

Commit 21f4fef

Browse files
simonguinotcarlescufi
authored andcommitted
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>
1 parent 53cbe5f commit 21f4fef

File tree

3 files changed

+335
-0
lines changed

3 files changed

+335
-0
lines changed

drivers/led/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ zephyr_sources_ifdef(CONFIG_LP503X lp503x.c)
66
zephyr_sources_ifdef(CONFIG_LP5562 lp5562.c)
77
zephyr_sources_ifdef(CONFIG_PCA9633 pca9633.c)
88

9+
zephyr_sources_ifdef(CONFIG_LED_SHELL led_shell.c)
10+
911
zephyr_sources_ifdef(CONFIG_USERSPACE led_handlers.c)

drivers/led/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ config LED_INIT_PRIORITY
2020
help
2121
System initialization priority for LED drivers.
2222

23+
config LED_SHELL
24+
bool "LED shell"
25+
depends on SHELL
26+
help
27+
Enable LED shell for testing.
28+
2329
source "drivers/led/Kconfig.ht16k33"
2430
source "drivers/led/Kconfig.lp3943"
2531
source "drivers/led/Kconfig.lp503x"

drivers/led/led_shell.c

Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
/*
2+
* Copyright (c) 2020 Seagate Technology LLC
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <shell/shell.h>
8+
#include <drivers/led.h>
9+
#include <stdlib.h>
10+
11+
#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
12+
#include <logging/log.h>
13+
LOG_MODULE_REGISTER(led_shell);
14+
15+
#define MAX_CHANNEL_ARGS 8
16+
17+
enum {
18+
arg_idx_dev = 1,
19+
arg_idx_led = 2,
20+
arg_idx_value = 3,
21+
};
22+
23+
static int parse_common_args(const struct shell *shell, char **argv,
24+
struct device **dev, uint32_t *led)
25+
{
26+
char *end_ptr;
27+
28+
*dev = device_get_binding(argv[arg_idx_dev]);
29+
if (!*dev) {
30+
shell_error(shell,
31+
"LED device %s not found", argv[arg_idx_dev]);
32+
return -ENODEV;
33+
}
34+
35+
*led = strtoul(argv[arg_idx_led], &end_ptr, 0);
36+
if (*end_ptr != '\0') {
37+
shell_error(shell, "Invalid LED number parameter %s",
38+
argv[arg_idx_led]);
39+
return -EINVAL;
40+
}
41+
42+
return 0;
43+
}
44+
45+
static int cmd_off(const struct shell *shell, size_t argc, char **argv)
46+
{
47+
struct device *dev;
48+
uint32_t led;
49+
int err;
50+
51+
err = parse_common_args(shell, argv, &dev, &led);
52+
if (err < 0) {
53+
return err;
54+
}
55+
56+
shell_print(shell, "%s: turning off LED %d", dev->name, led);
57+
58+
err = led_off(dev, led);
59+
if (err) {
60+
shell_error(shell, "Error: %d", err);
61+
}
62+
63+
return err;
64+
}
65+
66+
static int cmd_on(const struct shell *shell, size_t argc, char **argv)
67+
{
68+
struct device *dev;
69+
uint32_t led;
70+
int err;
71+
72+
err = parse_common_args(shell, argv, &dev, &led);
73+
if (err < 0) {
74+
return err;
75+
}
76+
77+
shell_print(shell, "%s: turning on LED %d", dev->name, led);
78+
79+
err = led_on(dev, led);
80+
if (err) {
81+
shell_error(shell, "Error: %d", err);
82+
}
83+
84+
return err;
85+
}
86+
87+
static int cmd_get_info(const struct shell *shell, size_t argc, char **argv)
88+
{
89+
struct device *dev;
90+
uint32_t led;
91+
int err;
92+
const struct led_info *info;
93+
int i;
94+
95+
err = parse_common_args(shell, argv, &dev, &led);
96+
if (err < 0) {
97+
return err;
98+
}
99+
100+
shell_print(shell, "%s: getting LED %d information", dev->name, led);
101+
102+
err = led_get_info(dev, led, &info);
103+
if (err) {
104+
shell_error(shell, "Error: %d", err);
105+
return err;
106+
}
107+
108+
shell_print(shell, "Label : %s", info->label ? : "<NULL>");
109+
shell_print(shell, "Index : %d", info->index);
110+
shell_print(shell, "Num colors : %d", info->num_colors);
111+
if (info->color_mapping) {
112+
shell_fprintf(shell, SHELL_NORMAL, "Colors : %d",
113+
info->color_mapping[0]);
114+
for (i = 1; i < info->num_colors; i++) {
115+
shell_fprintf(shell, SHELL_NORMAL, ":%d",
116+
info->color_mapping[i]);
117+
}
118+
shell_fprintf(shell, SHELL_NORMAL, "\n");
119+
}
120+
121+
return 0;
122+
}
123+
124+
static int cmd_set_brightness(const struct shell *shell,
125+
size_t argc, char **argv)
126+
{
127+
struct device *dev;
128+
uint32_t led;
129+
int err;
130+
char *end_ptr;
131+
unsigned long value;
132+
133+
err = parse_common_args(shell, argv, &dev, &led);
134+
if (err < 0) {
135+
return err;
136+
}
137+
138+
value = strtoul(argv[arg_idx_value], &end_ptr, 0);
139+
if (*end_ptr != '\0') {
140+
shell_error(shell, "Invalid LED brightness parameter %s",
141+
argv[arg_idx_value]);
142+
return -EINVAL;
143+
}
144+
if (value > 100) {
145+
shell_error(shell, "Invalid LED brightness value %d (max 100)",
146+
value);
147+
return -EINVAL;
148+
}
149+
150+
shell_print(shell, "%s: setting LED %d brightness to %d",
151+
dev->name, led, value);
152+
153+
err = led_set_brightness(dev, led, (uint8_t) value);
154+
if (err) {
155+
shell_error(shell, "Error: %d", err);
156+
}
157+
158+
return err;
159+
}
160+
161+
static int cmd_set_color(const struct shell *shell, size_t argc, char **argv)
162+
{
163+
struct device *dev;
164+
uint32_t led;
165+
int err;
166+
size_t num_colors;
167+
uint8_t i;
168+
uint8_t color[MAX_CHANNEL_ARGS];
169+
170+
err = parse_common_args(shell, argv, &dev, &led);
171+
if (err < 0) {
172+
return err;
173+
}
174+
175+
num_colors = argc - arg_idx_value;
176+
if (num_colors > MAX_CHANNEL_ARGS) {
177+
shell_error(shell,
178+
"Invalid number of colors %d (max %d)",
179+
num_colors, MAX_CHANNEL_ARGS);
180+
return -EINVAL;
181+
}
182+
183+
for (i = 0; i < num_colors; i++) {
184+
char *end_ptr;
185+
unsigned long col;
186+
187+
col = strtoul(argv[arg_idx_value + i], &end_ptr, 0);
188+
if (*end_ptr != '\0') {
189+
shell_error(shell, "Invalid LED color parameter %s",
190+
argv[arg_idx_value + i]);
191+
return -EINVAL;
192+
}
193+
if (col > 255) {
194+
shell_error(shell,
195+
"Invalid LED color value %d (max 255)",
196+
col);
197+
return -EINVAL;
198+
}
199+
color[i] = col;
200+
}
201+
202+
shell_fprintf(shell, SHELL_NORMAL, "%s: setting LED %d color to %d",
203+
dev->name, led, color[0]);
204+
for (i = 1; i < num_colors; i++) {
205+
shell_fprintf(shell, SHELL_NORMAL, ":%d", color[i]);
206+
}
207+
shell_fprintf(shell, SHELL_NORMAL, "\n");
208+
209+
err = led_set_color(dev, led, num_colors, color);
210+
if (err) {
211+
shell_error(shell, "Error: %d", err);
212+
}
213+
214+
return err;
215+
}
216+
217+
static int cmd_set_channel(const struct shell *shell, size_t argc, char **argv)
218+
{
219+
struct device *dev;
220+
uint32_t channel;
221+
int err;
222+
char *end_ptr;
223+
unsigned long value;
224+
225+
err = parse_common_args(shell, argv, &dev, &channel);
226+
if (err < 0) {
227+
return err;
228+
}
229+
230+
value = strtoul(argv[arg_idx_value], &end_ptr, 0);
231+
if (*end_ptr != '\0') {
232+
shell_error(shell, "Invalid channel value parameter %s",
233+
argv[arg_idx_value]);
234+
return -EINVAL;
235+
}
236+
if (value > 255) {
237+
shell_error(shell, "Invalid channel value %d (max 255)",
238+
value);
239+
return -EINVAL;
240+
}
241+
242+
shell_print(shell, "%s: setting channel %d to %d",
243+
dev->name, channel, value);
244+
245+
err = led_set_channel(dev, channel, (uint8_t) value);
246+
if (err) {
247+
shell_error(shell, "Error: %d", err);
248+
}
249+
250+
return err;
251+
}
252+
253+
static int
254+
cmd_write_channels(const struct shell *shell, size_t argc, char **argv)
255+
{
256+
struct device *dev;
257+
uint32_t start_channel;
258+
int err;
259+
size_t num_channels;
260+
uint8_t i;
261+
uint8_t value[MAX_CHANNEL_ARGS];
262+
263+
err = parse_common_args(shell, argv, &dev, &start_channel);
264+
if (err < 0) {
265+
return err;
266+
}
267+
268+
num_channels = argc - arg_idx_value;
269+
if (num_channels > MAX_CHANNEL_ARGS) {
270+
shell_error(shell,
271+
"Can't write %d channels (max %d)",
272+
num_channels, MAX_CHANNEL_ARGS);
273+
return -EINVAL;
274+
}
275+
276+
for (i = 0; i < num_channels; i++) {
277+
char *end_ptr;
278+
unsigned long val;
279+
280+
val = strtoul(argv[arg_idx_value + i], &end_ptr, 0);
281+
if (*end_ptr != '\0') {
282+
shell_error(shell,
283+
"Invalid channel value parameter %s",
284+
argv[arg_idx_value + i]);
285+
return -EINVAL;
286+
}
287+
if (val > 255) {
288+
shell_error(shell,
289+
"Invalid channel value %d (max 255)", val);
290+
return -EINVAL;
291+
}
292+
value[i] = val;
293+
}
294+
295+
shell_fprintf(shell, SHELL_NORMAL, "%s: writing from channel %d: %d",
296+
dev->name, start_channel, value[0]);
297+
for (i = 1; i < num_channels; i++) {
298+
shell_fprintf(shell, SHELL_NORMAL, " %d", value[i]);
299+
}
300+
shell_fprintf(shell, SHELL_NORMAL, "\n");
301+
302+
err = led_write_channels(dev, start_channel, num_channels, value);
303+
if (err) {
304+
shell_error(shell, "Error: %d", err);
305+
}
306+
307+
return err;
308+
}
309+
310+
SHELL_STATIC_SUBCMD_SET_CREATE(sub_led,
311+
SHELL_CMD_ARG(off, NULL, "<device> <led>", cmd_off, 3, 0),
312+
SHELL_CMD_ARG(on, NULL, "<device> <led>", cmd_on, 3, 0),
313+
SHELL_CMD_ARG(get_info, NULL, "<device> <led>", cmd_get_info, 3, 0),
314+
SHELL_CMD_ARG(set_brightness, NULL, "<device> <led> <value [0-255]>",
315+
cmd_set_brightness, 4, 0),
316+
SHELL_CMD_ARG(set_color, NULL,
317+
"<device> <led> <color 0 [0-255]> ... <color N>",
318+
cmd_set_color, 4, MAX_CHANNEL_ARGS - 1),
319+
SHELL_CMD_ARG(set_channel, NULL, "<device> <channel> <value [0-255]>",
320+
cmd_set_channel, 4, 0),
321+
SHELL_CMD_ARG(write_channels, NULL,
322+
"<device> <chan> <value 0 [0-255]> ... <value N>",
323+
cmd_write_channels, 4, MAX_CHANNEL_ARGS - 1),
324+
SHELL_SUBCMD_SET_END
325+
);
326+
327+
SHELL_CMD_REGISTER(led, &sub_led, "LED commands", NULL);

0 commit comments

Comments
 (0)