blob: e040cb5bc5c03d0a17c7c22de0361603e3405ed1 [file] [log] [blame]
Martin Jäger2ed42b32022-03-21 22:02:19 +01001/*
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
Martin Jäger2ed42b32022-03-21 22:02:19 +01009#include <hal/usb_serial_jtag_ll.h>
10
Martin Jäger2ed42b32022-03-21 22:02:19 +010011#include <device.h>
Martin Jägere8250ea2022-07-13 16:56:22 +020012#include <errno.h>
Martin Jäger2ed42b32022-03-21 22:02:19 +010013#include <soc.h>
14#include <zephyr/drivers/uart.h>
15#include <zephyr/drivers/interrupt_controller/intc_esp32c3.h>
16#include <zephyr/drivers/clock_control.h>
Martin Jäger2ed42b32022-03-21 22:02:19 +010017#include <zephyr/sys/util.h>
18#include <esp_attr.h>
19
Martin Jäger2ed42b32022-03-21 22:02:19 +010020struct serial_esp32_usb_config {
21 const struct device *clock_dev;
22 const clock_control_subsys_t clock_subsys;
Martin Jäger2ed42b32022-03-21 22:02:19 +010023 int irq_source;
24};
25
26struct serial_esp32_usb_data {
Martin Jäger2ed42b32022-03-21 22:02:19 +010027#ifdef CONFIG_UART_INTERRUPT_DRIVEN
28 uart_irq_callback_user_data_t irq_cb;
29 void *irq_cb_data;
30#endif
31 int irq_line;
32};
33
Martin Jäger2ed42b32022-03-21 22:02:19 +010034#ifdef CONFIG_UART_INTERRUPT_DRIVEN
35static void serial_esp32_usb_isr(void *arg);
36#endif
37
38static int serial_esp32_usb_poll_in(const struct device *dev, unsigned char *p_char)
39{
40 struct serial_esp32_usb_data *data = dev->data;
41
42 if (!usb_serial_jtag_ll_rxfifo_data_available()) {
43 return -1;
44 }
45
46 usb_serial_jtag_ll_read_rxfifo(p_char, 1);
47
48 return 0;
49}
50
51static void serial_esp32_usb_poll_out(const struct device *dev, unsigned char c)
52{
53 ARG_UNUSED(dev);
54
55 /* Wait for space in FIFO */
56 while (usb_serial_jtag_ll_txfifo_writable() == 0) {
57 ;
58 }
59
60 /* Send a character */
61 usb_serial_jtag_ll_write_txfifo(&c, 1);
62
63 usb_serial_jtag_ll_txfifo_flush();
64}
65
66static int serial_esp32_usb_err_check(const struct device *dev)
67{
68 ARG_UNUSED(dev);
69
70 return 0;
71}
72
Martin Jäger802f7492022-07-13 18:07:37 +020073static int serial_esp32_usb_init(const struct device *dev)
Martin Jäger2ed42b32022-03-21 22:02:19 +010074{
75 const struct serial_esp32_usb_config *config = dev->config;
76 struct serial_esp32_usb_data *data = dev->data;
77
Martin Jäger802f7492022-07-13 18:07:37 +020078 int ret = clock_control_on(config->clock_dev, config->clock_subsys);
Martin Jäger2ed42b32022-03-21 22:02:19 +010079
80#ifdef CONFIG_UART_INTERRUPT_DRIVEN
81 const struct serial_esp32_usb_config *config = dev->config;
82
Martin Jägere8250ea2022-07-13 16:56:22 +020083 data->irq_line = esp_intr_alloc(config->irq_source, 0, (isr_handler_t)serial_esp32_usb_isr,
Martin Jäger2ed42b32022-03-21 22:02:19 +010084 (void *)dev, NULL);
85#endif
86 return ret;
87}
88
89#ifdef CONFIG_UART_INTERRUPT_DRIVEN
90
91static int serial_esp32_usb_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len)
92{
93 ARG_UNUSED(dev);
94
95 int ret = usb_serial_jtag_ll_write_txfifo(tx_data, len);
96
97 usb_serial_jtag_ll_txfifo_flush();
98
99 return ret;
100}
101
102static int serial_esp32_usb_fifo_read(const struct device *dev, uint8_t *rx_data, const int len)
103{
104 ARG_UNUSED(dev);
105
106 return usb_serial_jtag_ll_read_rxfifo(rx_data, len);
107}
108
109static void serial_esp32_usb_irq_tx_enable(const struct device *dev)
110{
111 ARG_UNUSED(dev);
112
113 usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
114 usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
115}
116
117static void serial_esp32_usb_irq_tx_disable(const struct device *dev)
118{
119 ARG_UNUSED(dev);
120
121 usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
122}
123
124static int serial_esp32_usb_irq_tx_ready(const struct device *dev)
125{
126 ARG_UNUSED(dev);
127
128 return (usb_serial_jtag_ll_txfifo_writable() &&
129 usb_serial_jtag_ll_get_intr_ena_status() & USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
130}
131
132static void serial_esp32_usb_irq_rx_enable(const struct device *dev)
133{
134 ARG_UNUSED(dev);
135
136 usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
137 usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
138}
139
140static void serial_esp32_usb_irq_rx_disable(const struct device *dev)
141{
142 ARG_UNUSED(dev);
143
144 usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
145}
146
147static int serial_esp32_usb_irq_tx_complete(const struct device *dev)
148{
149 ARG_UNUSED(dev);
150
151 return usb_serial_jtag_ll_txfifo_writable();
152}
153
154static int serial_esp32_usb_irq_rx_ready(const struct device *dev)
155{
156 ARG_UNUSED(dev);
157
158 return usb_serial_jtag_ll_rxfifo_data_available();
159}
160
161static void serial_esp32_usb_irq_err_enable(const struct device *dev)
162{
163 ARG_UNUSED(dev);
164}
165
166static void serial_esp32_usb_irq_err_disable(const struct device *dev)
167{
168 ARG_UNUSED(dev);
169}
170
171static int serial_esp32_usb_irq_is_pending(const struct device *dev)
172{
173 return serial_esp32_usb_irq_rx_ready(dev) || serial_esp32_usb_irq_tx_ready(dev);
174}
175
176static int serial_esp32_usb_irq_update(const struct device *dev)
177{
178 ARG_UNUSED(dev);
179
180 usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
181 usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
182
183 return 1;
184}
185
186static void serial_esp32_usb_irq_callback_set(const struct device *dev,
187 uart_irq_callback_user_data_t cb, void *cb_data)
188{
189 struct serial_esp32_usb_data *data = dev->data;
190
191 data->irq_cb = cb;
192 data->irq_cb_data = cb_data;
193}
194
195static void serial_esp32_usb_isr(void *arg)
196{
197 const struct device *dev = (const struct device *)arg;
198 struct serial_esp32_usb_data *data = dev->data;
199 uint32_t uart_intr_status = usb_serial_jtag_ll_get_intsts_mask();
200
201 if (uart_intr_status == 0) {
202 return;
203 }
204 usb_serial_jtag_ll_clr_intsts_mask(uart_intr_status);
205
206 if (data->irq_cb != NULL) {
207 data->irq_cb(dev, data->irq_cb_data);
208 }
209}
210
211#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
212
213static const DRAM_ATTR struct uart_driver_api serial_esp32_usb_api = {
214 .poll_in = serial_esp32_usb_poll_in,
215 .poll_out = serial_esp32_usb_poll_out,
216 .err_check = serial_esp32_usb_err_check,
Martin Jäger2ed42b32022-03-21 22:02:19 +0100217#ifdef CONFIG_UART_INTERRUPT_DRIVEN
218 .fifo_fill = serial_esp32_usb_fifo_fill,
219 .fifo_read = serial_esp32_usb_fifo_read,
220 .irq_tx_enable = serial_esp32_usb_irq_tx_enable,
221 .irq_tx_disable = serial_esp32_usb_irq_tx_disable,
222 .irq_tx_ready = serial_esp32_usb_irq_tx_ready,
223 .irq_rx_enable = serial_esp32_usb_irq_rx_enable,
224 .irq_rx_disable = serial_esp32_usb_irq_rx_disable,
225 .irq_tx_complete = serial_esp32_usb_irq_tx_complete,
226 .irq_rx_ready = serial_esp32_usb_irq_rx_ready,
227 .irq_err_enable = serial_esp32_usb_irq_err_enable,
228 .irq_err_disable = serial_esp32_usb_irq_err_disable,
229 .irq_is_pending = serial_esp32_usb_irq_is_pending,
230 .irq_update = serial_esp32_usb_irq_update,
231 .irq_callback_set = serial_esp32_usb_irq_callback_set,
232#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
233};
234
Martin Jäger802f7492022-07-13 18:07:37 +0200235static const DRAM_ATTR struct serial_esp32_usb_config serial_esp32_usb_cfg = {
236 .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0)),
237 .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(0, offset),
238 .irq_source = DT_INST_IRQN(0)
239};
Martin Jäger2ed42b32022-03-21 22:02:19 +0100240
Martin Jäger802f7492022-07-13 18:07:37 +0200241static struct serial_esp32_usb_data serial_esp32_usb_data_0;
242
243DEVICE_DT_INST_DEFINE(0, &serial_esp32_usb_init, NULL, &serial_esp32_usb_data_0,
244 &serial_esp32_usb_cfg, PRE_KERNEL_1,
245 CONFIG_SERIAL_INIT_PRIORITY, &serial_esp32_usb_api);