1 /*
2 * Copyright (c) 2024 Yishai Jaffe <yishai1999@gmail.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/drivers/uart.h>
8 #include <zephyr/shell/shell.h>
9 #include <stdlib.h>
10
11 #include <zephyr/logging/log.h>
12 LOG_MODULE_REGISTER(uart_shell, CONFIG_LOG_DEFAULT_LEVEL);
13
device_is_uart(const struct device * dev)14 static bool device_is_uart(const struct device *dev)
15 {
16 return DEVICE_API_IS(uart, dev);
17 }
18
cmd_uart_write(const struct shell * sh,size_t argc,char ** argv)19 static int cmd_uart_write(const struct shell *sh, size_t argc, char **argv)
20 {
21 char *s_dev_name = argv[1];
22 const struct device *dev = shell_device_get_binding(s_dev_name);
23
24 if (!dev || !device_is_uart(dev)) {
25 shell_error(sh, "UART: Device driver %s not found.", s_dev_name);
26 return -ENODEV;
27 }
28
29 char *buf = argv[2];
30 int msg_len = strlen(buf);
31
32 for (int i = 0; i < msg_len; i++) {
33 uart_poll_out(dev, buf[i]);
34 }
35
36 return 0;
37 }
38
cmd_uart_baudrate(const struct shell * sh,size_t argc,char ** argv)39 static int cmd_uart_baudrate(const struct shell *sh, size_t argc, char **argv)
40 {
41 char *s_dev_name = argv[1];
42 const struct device *dev;
43 struct uart_config cfg;
44 uint32_t baudrate;
45 int ret;
46
47 dev = shell_device_get_binding(s_dev_name);
48 if (!dev || !device_is_uart(dev)) {
49 shell_error(sh, "UART: Device driver %s not found.", s_dev_name);
50 return -ENODEV;
51 }
52
53 baudrate = strtol(argv[2], NULL, 10);
54 ret = uart_config_get(dev, &cfg);
55 if (ret < 0) {
56 shell_error(sh, "UART: Failed to get current configuration: %d", ret);
57 return ret;
58 }
59 cfg.baudrate = baudrate;
60
61 ret = uart_configure(dev, &cfg);
62 if (ret < 0) {
63 shell_error(sh, "UART: Failed to configure device: %d", ret);
64 return ret;
65 }
66 return 0;
67 }
68
cmd_uart_flow_control(const struct shell * sh,size_t argc,char ** argv)69 static int cmd_uart_flow_control(const struct shell *sh, size_t argc, char **argv)
70 {
71 char *s_dev_name = argv[1];
72 const struct device *dev;
73 struct uart_config cfg;
74 uint8_t flow_control;
75 int ret;
76
77 dev = shell_device_get_binding(s_dev_name);
78 if (!dev || !device_is_uart(dev)) {
79 shell_error(sh, "UART: Device driver %s not found.", s_dev_name);
80 return -ENODEV;
81 }
82
83 if (!strcmp(argv[2], "none")) {
84 flow_control = UART_CFG_FLOW_CTRL_NONE;
85 } else if (!strcmp(argv[2], "rtscts")) {
86 flow_control = UART_CFG_FLOW_CTRL_RTS_CTS;
87 } else if (!strcmp(argv[2], "dtrdsr")) {
88 flow_control = UART_CFG_FLOW_CTRL_DTR_DSR;
89 } else if (!strcmp(argv[2], "rs485")) {
90 flow_control = UART_CFG_FLOW_CTRL_RS485;
91 } else {
92 shell_error(sh, "Unknown: '%s'", argv[2]);
93 shell_help(sh);
94 return SHELL_CMD_HELP_PRINTED;
95 }
96
97 ret = uart_config_get(dev, &cfg);
98 if (ret < 0) {
99 shell_error(sh, "UART: Failed to get current configuration: %d", ret);
100 return ret;
101 }
102 cfg.flow_ctrl = flow_control;
103
104 ret = uart_configure(dev, &cfg);
105 if (ret < 0) {
106 shell_error(sh, "UART: Failed to configure device: %d", ret);
107 return ret;
108 }
109 return 0;
110 }
111
device_name_get(size_t idx,struct shell_static_entry * entry)112 static void device_name_get(size_t idx, struct shell_static_entry *entry)
113 {
114 const struct device *dev = shell_device_filter(idx, device_is_uart);
115
116 entry->syntax = (dev != NULL) ? dev->name : NULL;
117 entry->handler = NULL;
118 entry->help = NULL;
119 entry->subcmd = NULL;
120 }
121
122 SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get);
123
124 SHELL_STATIC_SUBCMD_SET_CREATE(sub_uart_cmds,
125 SHELL_CMD_ARG(write, &dsub_device_name,
126 "Write data to the UART device\n"
127 "Usage: write <device> <data>",
128 cmd_uart_write, 3, 0),
129 SHELL_CMD_ARG(baudrate, &dsub_device_name,
130 "Configure UART device baudrate\n"
131 "Usage: baudrate <device> <baudrate>",
132 cmd_uart_baudrate, 3, 0),
133 SHELL_CMD_ARG(fc, &dsub_device_name,
134 "Configure UART device flow control\n"
135 "Usage: fc <device> <none|rtscts|dtrdsr|rs485>",
136 cmd_uart_flow_control, 3, 0),
137 SHELL_SUBCMD_SET_END /* Array terminated. */
138 );
139
140 SHELL_CMD_REGISTER(uart, &sub_uart_cmds, "UART commands", NULL);
141