1 /*
2  * Copyright (c) 2022 Libre Solar Technologies GmbH
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT espressif_esp32_usb_serial
8 
9 #include <hal/usb_serial_jtag_ll.h>
10 
11 #include <zephyr/kernel.h>
12 #include <zephyr/device.h>
13 #include <errno.h>
14 #include <soc.h>
15 #include <zephyr/drivers/uart.h>
16 #if defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32C6)
17 #include <zephyr/drivers/interrupt_controller/intc_esp32c3.h>
18 #else
19 #include <zephyr/drivers/interrupt_controller/intc_esp32.h>
20 #endif
21 #include <zephyr/drivers/clock_control.h>
22 #include <zephyr/sys/util.h>
23 #include <esp_attr.h>
24 
25 #if defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32C6)
26 #define ISR_HANDLER isr_handler_t
27 #else
28 #define ISR_HANDLER intr_handler_t
29 #endif
30 
31 /*
32  * Timeout after which the poll_out function stops waiting for space in the tx fifo.
33  *
34  * Without this timeout, the function would get stuck forever and block the processor if no host is
35  * connected to the USB port.
36  *
37  * USB full-speed uses a frame rate of 1 ms. Thus, a timeout of 50 ms provides plenty of safety
38  * margin even for a loaded bus. This is the same value as used in the ESP-IDF.
39  */
40 #define USBSERIAL_POLL_OUT_TIMEOUT_MS (50U)
41 
42 struct serial_esp32_usb_config {
43 	const struct device *clock_dev;
44 	const clock_control_subsys_t clock_subsys;
45 	int irq_source;
46 	int irq_priority;
47 	int irq_flags;
48 };
49 
50 struct serial_esp32_usb_data {
51 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
52 	uart_irq_callback_user_data_t irq_cb;
53 	void *irq_cb_data;
54 #endif
55 	int64_t last_tx_time;
56 };
57 
58 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
59 static void serial_esp32_usb_isr(void *arg);
60 #endif
61 
serial_esp32_usb_poll_in(const struct device * dev,unsigned char * p_char)62 static int serial_esp32_usb_poll_in(const struct device *dev, unsigned char *p_char)
63 {
64 	if (!usb_serial_jtag_ll_rxfifo_data_available()) {
65 		return -1;
66 	}
67 
68 	usb_serial_jtag_ll_read_rxfifo(p_char, 1);
69 
70 	return 0;
71 }
72 
serial_esp32_usb_poll_out(const struct device * dev,unsigned char c)73 static void serial_esp32_usb_poll_out(const struct device *dev, unsigned char c)
74 {
75 	struct serial_esp32_usb_data *data = dev->data;
76 
77 	/*
78 	 * If there is no USB host connected, this function will busy-wait once for the timeout
79 	 * period, but return immediately for subsequent calls.
80 	 */
81 	do {
82 		if (usb_serial_jtag_ll_txfifo_writable()) {
83 			usb_serial_jtag_ll_write_txfifo(&c, 1);
84 			usb_serial_jtag_ll_txfifo_flush();
85 			data->last_tx_time = k_uptime_get();
86 			return;
87 		}
88 	} while ((k_uptime_get() - data->last_tx_time) < USBSERIAL_POLL_OUT_TIMEOUT_MS);
89 }
90 
serial_esp32_usb_err_check(const struct device * dev)91 static int serial_esp32_usb_err_check(const struct device *dev)
92 {
93 	ARG_UNUSED(dev);
94 
95 	return 0;
96 }
97 
serial_esp32_usb_init(const struct device * dev)98 static int serial_esp32_usb_init(const struct device *dev)
99 {
100 	const struct serial_esp32_usb_config *config = dev->config;
101 
102 	if (!device_is_ready(config->clock_dev)) {
103 		return -ENODEV;
104 	}
105 
106 	int ret = clock_control_on(config->clock_dev, config->clock_subsys);
107 
108 	if (ret != 0) {
109 		return ret;
110 	}
111 
112 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
113 	ret = esp_intr_alloc(config->irq_source,
114 			ESP_PRIO_TO_FLAGS(config->irq_priority) |
115 			ESP_INT_FLAGS_CHECK(config->irq_flags),
116 			(ISR_HANDLER)serial_esp32_usb_isr,
117 			(void *)dev, NULL);
118 #endif
119 	return ret;
120 }
121 
122 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
123 
serial_esp32_usb_fifo_fill(const struct device * dev,const uint8_t * tx_data,int len)124 static int serial_esp32_usb_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len)
125 {
126 	ARG_UNUSED(dev);
127 
128 	int ret = usb_serial_jtag_ll_write_txfifo(tx_data, len);
129 
130 	usb_serial_jtag_ll_txfifo_flush();
131 
132 	return ret;
133 }
134 
serial_esp32_usb_fifo_read(const struct device * dev,uint8_t * rx_data,const int len)135 static int serial_esp32_usb_fifo_read(const struct device *dev, uint8_t *rx_data, const int len)
136 {
137 	ARG_UNUSED(dev);
138 
139 	return usb_serial_jtag_ll_read_rxfifo(rx_data, len);
140 }
141 
serial_esp32_usb_irq_tx_enable(const struct device * dev)142 static void serial_esp32_usb_irq_tx_enable(const struct device *dev)
143 {
144 	struct serial_esp32_usb_data *data = dev->data;
145 
146 	usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
147 	usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
148 
149 	if (data->irq_cb != NULL) {
150 		unsigned int key = irq_lock();
151 		data->irq_cb(dev, data->irq_cb_data);
152 		arch_irq_unlock(key);
153 	}
154 }
155 
serial_esp32_usb_irq_tx_disable(const struct device * dev)156 static void serial_esp32_usb_irq_tx_disable(const struct device *dev)
157 {
158 	ARG_UNUSED(dev);
159 
160 	usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
161 }
162 
serial_esp32_usb_irq_tx_ready(const struct device * dev)163 static int serial_esp32_usb_irq_tx_ready(const struct device *dev)
164 {
165 	ARG_UNUSED(dev);
166 
167 	return (usb_serial_jtag_ll_txfifo_writable() &&
168 		usb_serial_jtag_ll_get_intr_ena_status() & USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
169 }
170 
serial_esp32_usb_irq_rx_enable(const struct device * dev)171 static void serial_esp32_usb_irq_rx_enable(const struct device *dev)
172 {
173 	ARG_UNUSED(dev);
174 
175 	usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
176 	usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
177 }
178 
serial_esp32_usb_irq_rx_disable(const struct device * dev)179 static void serial_esp32_usb_irq_rx_disable(const struct device *dev)
180 {
181 	ARG_UNUSED(dev);
182 
183 	usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
184 }
185 
serial_esp32_usb_irq_tx_complete(const struct device * dev)186 static int serial_esp32_usb_irq_tx_complete(const struct device *dev)
187 {
188 	ARG_UNUSED(dev);
189 
190 	return usb_serial_jtag_ll_txfifo_writable();
191 }
192 
serial_esp32_usb_irq_rx_ready(const struct device * dev)193 static int serial_esp32_usb_irq_rx_ready(const struct device *dev)
194 {
195 	ARG_UNUSED(dev);
196 
197 	return usb_serial_jtag_ll_rxfifo_data_available();
198 }
199 
serial_esp32_usb_irq_err_enable(const struct device * dev)200 static void serial_esp32_usb_irq_err_enable(const struct device *dev)
201 {
202 	ARG_UNUSED(dev);
203 }
204 
serial_esp32_usb_irq_err_disable(const struct device * dev)205 static void serial_esp32_usb_irq_err_disable(const struct device *dev)
206 {
207 	ARG_UNUSED(dev);
208 }
209 
serial_esp32_usb_irq_is_pending(const struct device * dev)210 static int serial_esp32_usb_irq_is_pending(const struct device *dev)
211 {
212 	return serial_esp32_usb_irq_rx_ready(dev) || serial_esp32_usb_irq_tx_ready(dev);
213 }
214 
serial_esp32_usb_irq_update(const struct device * dev)215 static int serial_esp32_usb_irq_update(const struct device *dev)
216 {
217 	ARG_UNUSED(dev);
218 
219 	usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
220 	usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
221 
222 	return 1;
223 }
224 
serial_esp32_usb_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)225 static void serial_esp32_usb_irq_callback_set(const struct device *dev,
226 					      uart_irq_callback_user_data_t cb, void *cb_data)
227 {
228 	struct serial_esp32_usb_data *data = dev->data;
229 
230 	data->irq_cb_data = cb_data;
231 	data->irq_cb = cb;
232 }
233 
serial_esp32_usb_isr(void * arg)234 static void serial_esp32_usb_isr(void *arg)
235 {
236 	const struct device *dev = (const struct device *)arg;
237 	struct serial_esp32_usb_data *data = dev->data;
238 	uint32_t uart_intr_status = usb_serial_jtag_ll_get_intsts_mask();
239 
240 	if (uart_intr_status == 0) {
241 		return;
242 	}
243 	usb_serial_jtag_ll_clr_intsts_mask(uart_intr_status);
244 
245 	if (data->irq_cb != NULL) {
246 		data->irq_cb(dev, data->irq_cb_data);
247 	}
248 }
249 
250 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
251 
252 static DEVICE_API(uart, serial_esp32_usb_api) = {
253 	.poll_in = serial_esp32_usb_poll_in,
254 	.poll_out = serial_esp32_usb_poll_out,
255 	.err_check = serial_esp32_usb_err_check,
256 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
257 	.fifo_fill = serial_esp32_usb_fifo_fill,
258 	.fifo_read = serial_esp32_usb_fifo_read,
259 	.irq_tx_enable = serial_esp32_usb_irq_tx_enable,
260 	.irq_tx_disable = serial_esp32_usb_irq_tx_disable,
261 	.irq_tx_ready = serial_esp32_usb_irq_tx_ready,
262 	.irq_rx_enable = serial_esp32_usb_irq_rx_enable,
263 	.irq_rx_disable = serial_esp32_usb_irq_rx_disable,
264 	.irq_tx_complete = serial_esp32_usb_irq_tx_complete,
265 	.irq_rx_ready = serial_esp32_usb_irq_rx_ready,
266 	.irq_err_enable = serial_esp32_usb_irq_err_enable,
267 	.irq_err_disable = serial_esp32_usb_irq_err_disable,
268 	.irq_is_pending = serial_esp32_usb_irq_is_pending,
269 	.irq_update = serial_esp32_usb_irq_update,
270 	.irq_callback_set = serial_esp32_usb_irq_callback_set,
271 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
272 };
273 
274 static const DRAM_ATTR struct serial_esp32_usb_config serial_esp32_usb_cfg = {
275 	.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0)),
276 	.clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(0, offset),
277 	.irq_source = DT_INST_IRQ_BY_IDX(0, 0, irq),
278 	.irq_priority = DT_INST_IRQ_BY_IDX(0, 0, priority),
279 	.irq_flags = DT_INST_IRQ_BY_IDX(0, 0, flags)
280 };
281 
282 static struct serial_esp32_usb_data serial_esp32_usb_data_0;
283 
284 DEVICE_DT_INST_DEFINE(0, serial_esp32_usb_init, NULL, &serial_esp32_usb_data_0,
285 		      &serial_esp32_usb_cfg, PRE_KERNEL_1,
286 		      CONFIG_SERIAL_INIT_PRIORITY, &serial_esp32_usb_api);
287