1 /*
2  * Copyright (c) 2018 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef SHELL_UART_H__
8 #define SHELL_UART_H__
9 
10 #include <zephyr/drivers/serial/uart_async_rx.h>
11 #include <zephyr/mgmt/mcumgr/transport/smp_shell.h>
12 #include <zephyr/shell/shell.h>
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 extern const struct shell_transport_api shell_uart_transport_api;
19 
20 #ifndef CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE
21 #define CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE 0
22 #endif
23 
24 #ifndef CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE
25 #define CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE 0
26 #endif
27 
28 #ifndef CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_COUNT
29 #define CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_COUNT 0
30 #endif
31 
32 #ifndef CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_SIZE
33 #define CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_SIZE 0
34 #endif
35 
36 #define ASYNC_RX_BUF_SIZE (CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_COUNT * \
37 		(CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_SIZE + \
38 		 UART_ASYNC_RX_BUF_OVERHEAD))
39 
40 struct shell_uart_common {
41 	const struct device *dev;
42 	shell_transport_handler_t handler;
43 	void *context;
44 	bool blocking_tx;
45 #ifdef CONFIG_MCUMGR_TRANSPORT_SHELL
46 	struct smp_shell_data smp;
47 #endif /* CONFIG_MCUMGR_TRANSPORT_SHELL */
48 };
49 
50 struct shell_uart_int_driven {
51 	struct shell_uart_common common;
52 	struct ring_buf tx_ringbuf;
53 	struct ring_buf rx_ringbuf;
54 	uint8_t tx_buf[CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE];
55 	uint8_t rx_buf[CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE];
56 	struct k_timer dtr_timer;
57 	atomic_t tx_busy;
58 };
59 
60 struct shell_uart_async {
61 	struct shell_uart_common common;
62 	struct k_sem tx_sem;
63 	struct uart_async_rx async_rx;
64 	struct uart_async_rx_config async_rx_config;
65 	atomic_t pending_rx_req;
66 	uint8_t rx_data[ASYNC_RX_BUF_SIZE];
67 };
68 
69 struct shell_uart_polling {
70 	struct shell_uart_common common;
71 	struct ring_buf rx_ringbuf;
72 	uint8_t rx_buf[CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE];
73 	struct k_timer rx_timer;
74 };
75 
76 #ifdef CONFIG_SHELL_BACKEND_SERIAL_API_POLLING
77 #define SHELL_UART_STRUCT struct shell_uart_polling
78 #elif defined(CONFIG_SHELL_BACKEND_SERIAL_API_ASYNC)
79 #define SHELL_UART_STRUCT struct shell_uart_async
80 #else
81 #define SHELL_UART_STRUCT struct shell_uart_int_driven
82 #endif
83 
84 /**
85  * @brief Macro for creating shell UART transport instance named @p _name
86  *
87  * @note Additional arguments are accepted (but ignored) for compatibility with
88  * previous Zephyr version, it will be removed in future release.
89  */
90 #define SHELL_UART_DEFINE(_name, ...)                                                              \
91 	static SHELL_UART_STRUCT _name##_shell_uart;                                               \
92 	struct shell_transport _name = {                                                           \
93 		.api = &shell_uart_transport_api,                                                  \
94 		.ctx = (struct shell_telnet *)&_name##_shell_uart,                                 \
95 	}
96 
97 /**
98  * @brief This function provides pointer to the shell UART backend instance.
99  *
100  * Function returns pointer to the shell UART instance. This instance can be
101  * next used with shell_execute_cmd function in order to test commands behavior.
102  *
103  * @returns Pointer to the shell instance.
104  */
105 const struct shell *shell_backend_uart_get_ptr(void);
106 
107 /**
108  * @brief This function provides pointer to the smp shell data of the UART shell transport.
109  *
110  * @returns Pointer to the smp shell data.
111  */
112 struct smp_shell_data *shell_uart_smp_shell_data_get_ptr(void);
113 
114 #ifdef __cplusplus
115 }
116 #endif
117 
118 #endif /* SHELL_UART_H__ */
119