1 /*
2 * Copyright (c) 2018 - 2019 Antmicro <www.antmicro.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT litex_uart0
8
9 #include <zephyr/kernel.h>
10 #include <zephyr/arch/cpu.h>
11 #include <zephyr/init.h>
12 #include <zephyr/irq.h>
13 #include <zephyr/device.h>
14 #include <zephyr/drivers/uart.h>
15 #include <zephyr/types.h>
16
17 #include <soc.h>
18
19 #define UART_RXTX_ADDR DT_INST_REG_ADDR_BY_NAME(0, rxtx)
20 #define UART_TXFULL_ADDR DT_INST_REG_ADDR_BY_NAME(0, txfull)
21 #define UART_RXEMPTY_ADDR DT_INST_REG_ADDR_BY_NAME(0, rxempty)
22 #define UART_EV_STATUS_ADDR DT_INST_REG_ADDR_BY_NAME(0, ev_status)
23 #define UART_EV_PENDING_ADDR DT_INST_REG_ADDR_BY_NAME(0, ev_pending)
24 #define UART_EV_ENABLE_ADDR DT_INST_REG_ADDR_BY_NAME(0, ev_enable)
25 #define UART_TXEMPTY_ADDR DT_INST_REG_ADDR_BY_NAME(0, txempty)
26 #define UART_RXFULL_ADDR DT_INST_REG_ADDR_BY_NAME(0, rxfull)
27
28 #define UART_EV_TX (1 << 0)
29 #define UART_EV_RX (1 << 1)
30 #define UART_IRQ DT_INST_IRQN(0)
31
32 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
33 typedef void (*irq_cfg_func_t)(void);
34 #endif
35
36 struct uart_liteuart_device_config {
37 uint32_t port;
38 uint32_t sys_clk_freq;
39 uint32_t baud_rate;
40 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
41 irq_cfg_func_t cfg_func;
42 #endif
43 };
44
45 struct uart_liteuart_data {
46 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
47 uart_irq_callback_user_data_t callback;
48 void *cb_data;
49 #endif
50 };
51
52 /**
53 * @brief Output a character in polled mode.
54 *
55 * Writes data to tx register. Waits for space if transmitter is full.
56 *
57 * @param dev UART device struct
58 * @param c Character to send
59 */
uart_liteuart_poll_out(const struct device * dev,unsigned char c)60 static void uart_liteuart_poll_out(const struct device *dev, unsigned char c)
61 {
62 /* wait for space */
63 while (litex_read8(UART_TXFULL_ADDR)) {
64 }
65
66 litex_write8(c, UART_RXTX_ADDR);
67 }
68
69 /**
70 * @brief Poll the device for input.
71 *
72 * @param dev UART device struct
73 * @param c Pointer to character
74 *
75 * @return 0 if a character arrived, -1 if the input buffer if empty.
76 */
uart_liteuart_poll_in(const struct device * dev,unsigned char * c)77 static int uart_liteuart_poll_in(const struct device *dev, unsigned char *c)
78 {
79 if (!litex_read8(UART_RXEMPTY_ADDR)) {
80 *c = litex_read8(UART_RXTX_ADDR);
81
82 /* refresh UART_RXEMPTY by writing UART_EV_RX
83 * to UART_EV_PENDING
84 */
85 litex_write8(UART_EV_RX, UART_EV_PENDING_ADDR);
86 return 0;
87 } else {
88 return -1;
89 }
90 }
91
92 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
93 /**
94 * @brief Enable TX interrupt in event register
95 *
96 * @param dev UART device struct
97 */
uart_liteuart_irq_tx_enable(const struct device * dev)98 static void uart_liteuart_irq_tx_enable(const struct device *dev)
99 {
100 uint8_t enable = litex_read8(UART_EV_ENABLE_ADDR);
101
102 litex_write8(enable | UART_EV_TX, UART_EV_ENABLE_ADDR);
103 }
104
105 /**
106 * @brief Disable TX interrupt in event register
107 *
108 * @param dev UART device struct
109 */
uart_liteuart_irq_tx_disable(const struct device * dev)110 static void uart_liteuart_irq_tx_disable(const struct device *dev)
111 {
112 uint8_t enable = litex_read8(UART_EV_ENABLE_ADDR);
113
114 litex_write8(enable & ~(UART_EV_TX), UART_EV_ENABLE_ADDR);
115 }
116
117 /**
118 * @brief Enable RX interrupt in event register
119 *
120 * @param dev UART device struct
121 */
uart_liteuart_irq_rx_enable(const struct device * dev)122 static void uart_liteuart_irq_rx_enable(const struct device *dev)
123 {
124 uint8_t enable = litex_read8(UART_EV_ENABLE_ADDR);
125
126 litex_write8(enable | UART_EV_RX, UART_EV_ENABLE_ADDR);
127 }
128
129 /**
130 * @brief Disable RX interrupt in event register
131 *
132 * @param dev UART device struct
133 */
uart_liteuart_irq_rx_disable(const struct device * dev)134 static void uart_liteuart_irq_rx_disable(const struct device *dev)
135 {
136 uint8_t enable = litex_read8(UART_EV_ENABLE_ADDR);
137
138 litex_write8(enable & ~(UART_EV_RX), UART_EV_ENABLE_ADDR);
139 }
140
141 /**
142 * @brief Check if Tx IRQ has been raised and UART is ready to accept new data
143 *
144 * @param dev UART device struct
145 *
146 * @return 1 if an IRQ has been raised, 0 otherwise
147 */
uart_liteuart_irq_tx_ready(const struct device * dev)148 static int uart_liteuart_irq_tx_ready(const struct device *dev)
149 {
150 uint8_t val = litex_read8(UART_TXFULL_ADDR);
151
152 return !val;
153 }
154
155 /**
156 * @brief Check if Rx IRQ has been raised and there's data to be read from UART
157 *
158 * @param dev UART device struct
159 *
160 * @return 1 if an IRQ has been raised, 0 otherwise
161 */
uart_liteuart_irq_rx_ready(const struct device * dev)162 static int uart_liteuart_irq_rx_ready(const struct device *dev)
163 {
164 uint8_t pending;
165
166 pending = litex_read8(UART_EV_PENDING_ADDR);
167
168 if (pending & UART_EV_RX) {
169 return 1;
170 } else {
171 return 0;
172 }
173 }
174
175 /**
176 * @brief Fill FIFO with data
177 *
178 * @param dev UART device struct
179 * @param tx_data Data to transmit
180 * @param size Number of bytes to send
181 *
182 * @return Number of bytes sent
183 */
uart_liteuart_fifo_fill(const struct device * dev,const uint8_t * tx_data,int size)184 static int uart_liteuart_fifo_fill(const struct device *dev,
185 const uint8_t *tx_data, int size)
186 {
187 int i;
188
189 for (i = 0; i < size && !litex_read8(UART_TXFULL_ADDR); i++) {
190 litex_write8(tx_data[i], UART_RXTX_ADDR);
191 }
192
193 return i;
194 }
195
196 /**
197 * @brief Read data from FIFO
198 *
199 * @param dev UART device struct
200 * @param rxData Data container
201 * @param size Container size
202 *
203 * @return Number of bytes read
204 */
uart_liteuart_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)205 static int uart_liteuart_fifo_read(const struct device *dev,
206 uint8_t *rx_data, const int size)
207 {
208 int i;
209
210 for (i = 0; i < size && !litex_read8(UART_RXEMPTY_ADDR); i++) {
211 rx_data[i] = litex_read8(UART_RXTX_ADDR);
212
213 /* refresh UART_RXEMPTY by writing UART_EV_RX
214 * to UART_EV_PENDING
215 */
216 litex_write8(UART_EV_RX, UART_EV_PENDING_ADDR);
217 }
218
219 return i;
220 }
221
uart_liteuart_irq_err(const struct device * dev)222 static void uart_liteuart_irq_err(const struct device *dev)
223 {
224 ARG_UNUSED(dev);
225 }
226
227 /**
228 * @brief Check if any IRQ is pending
229 *
230 * @param dev UART device struct
231 *
232 * @return 1 if an IRQ is pending, 0 otherwise
233 */
uart_liteuart_irq_is_pending(const struct device * dev)234 static int uart_liteuart_irq_is_pending(const struct device *dev)
235 {
236 uint8_t pending;
237
238 pending = litex_read8(UART_EV_PENDING_ADDR);
239
240 if (pending & (UART_EV_TX | UART_EV_RX)) {
241 return 1;
242 } else {
243 return 0;
244 }
245 }
246
uart_liteuart_irq_update(const struct device * dev)247 static int uart_liteuart_irq_update(const struct device *dev)
248 {
249 return 1;
250 }
251
252 /**
253 * @brief Set the callback function pointer for IRQ.
254 *
255 * @param dev UART device struct
256 * @param cb Callback function pointer.
257 */
uart_liteuart_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)258 static void uart_liteuart_irq_callback_set(const struct device *dev,
259 uart_irq_callback_user_data_t cb,
260 void *cb_data)
261 {
262 struct uart_liteuart_data *data;
263
264 data = dev->data;
265 data->callback = cb;
266 data->cb_data = cb_data;
267 }
268
liteuart_uart_irq_handler(const struct device * dev)269 static void liteuart_uart_irq_handler(const struct device *dev)
270 {
271 struct uart_liteuart_data *data = dev->data;
272 unsigned int key = irq_lock();
273
274 if (data->callback) {
275 data->callback(dev, data->cb_data);
276 }
277
278 /* Clear RX events, TX events still needed to enqueue the next transfer */
279 litex_write8(UART_EV_RX, UART_EV_PENDING_ADDR);
280
281 irq_unlock(key);
282 }
283 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
284
285 static const struct uart_driver_api uart_liteuart_driver_api = {
286 .poll_in = uart_liteuart_poll_in,
287 .poll_out = uart_liteuart_poll_out,
288 .err_check = NULL,
289 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
290 .fifo_fill = uart_liteuart_fifo_fill,
291 .fifo_read = uart_liteuart_fifo_read,
292 .irq_tx_enable = uart_liteuart_irq_tx_enable,
293 .irq_tx_disable = uart_liteuart_irq_tx_disable,
294 .irq_tx_ready = uart_liteuart_irq_tx_ready,
295 .irq_rx_enable = uart_liteuart_irq_rx_enable,
296 .irq_rx_disable = uart_liteuart_irq_rx_disable,
297 .irq_rx_ready = uart_liteuart_irq_rx_ready,
298 .irq_err_enable = uart_liteuart_irq_err,
299 .irq_err_disable = uart_liteuart_irq_err,
300 .irq_is_pending = uart_liteuart_irq_is_pending,
301 .irq_update = uart_liteuart_irq_update,
302 .irq_callback_set = uart_liteuart_irq_callback_set
303 #endif
304 };
305
306 static struct uart_liteuart_data uart_liteuart_data_0;
307 static int uart_liteuart_init(const struct device *dev);
308
309 static const struct uart_liteuart_device_config uart_liteuart_dev_cfg_0 = {
310 .port = UART_RXTX_ADDR,
311 .baud_rate = DT_INST_PROP(0, current_speed)
312 };
313
314 DEVICE_DT_INST_DEFINE(0,
315 uart_liteuart_init,
316 NULL,
317 &uart_liteuart_data_0, &uart_liteuart_dev_cfg_0,
318 PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY,
319 (void *)&uart_liteuart_driver_api);
320
uart_liteuart_init(const struct device * dev)321 static int uart_liteuart_init(const struct device *dev)
322 {
323 litex_write8(UART_EV_TX | UART_EV_RX, UART_EV_PENDING_ADDR);
324
325 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
326 IRQ_CONNECT(UART_IRQ, DT_INST_IRQ(0, priority),
327 liteuart_uart_irq_handler, DEVICE_DT_INST_GET(0),
328 0);
329 irq_enable(UART_IRQ);
330 #endif
331
332 return 0;
333 }
334