1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2020-04-16 bigmagic first version
9 * 2020-05-26 bigmagic add other uart
10 */
11
12 #include <rthw.h>
13 #include <rtthread.h>
14 #include <rtdevice.h>
15
16 #include "board.h"
17 #include "drv_uart.h"
18 #include "drv_gpio.h"
19 #include <mmu.h>
20
21 size_t uart0_addr = 0;
22 size_t uart3_addr = 0;
23 size_t uart4_addr = 0;
24 size_t uart5_addr = 0;
25
26 #ifdef RT_USING_UART0
27 static struct rt_serial_device _serial0;
28 #endif
29
30 #ifdef RT_USING_UART1
31 static struct rt_serial_device _serial1;
32 #endif
33
34 #ifdef RT_USING_UART3
35 static struct rt_serial_device _serial3;
36 #endif
37
38 #ifdef RT_USING_UART4
39 static struct rt_serial_device _serial4;
40 #endif
41
42 #ifdef RT_USING_UART5
43 static struct rt_serial_device _serial5;
44 #endif
45
46 struct hw_uart_device
47 {
48 rt_ubase_t hw_base;
49 rt_uint32_t irqno;
50 };
51
uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)52 static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
53 {
54 struct hw_uart_device *uart;
55 uint32_t bauddiv = (UART_REFERENCE_CLOCK / cfg->baud_rate)* 1000 / 16;
56 uint32_t ibrd = bauddiv / 1000;
57
58 RT_ASSERT(serial != RT_NULL);
59 uart = (struct hw_uart_device *)serial->parent.user_data;
60
61 if(uart->hw_base == AUX_BASE)
62 {
63 prev_raspi_pin_mode(GPIO_PIN_14, ALT5);
64 prev_raspi_pin_mode(GPIO_PIN_15, ALT5);
65
66 AUX_ENABLES(uart->hw_base) = 1; /* Enable UART1 */
67 AUX_MU_IER_REG(uart->hw_base) = 0; /* Disable interrupt */
68 AUX_MU_CNTL_REG(uart->hw_base) = 0; /* Disable Transmitter and Receiver */
69 AUX_MU_LCR_REG(uart->hw_base) = 3; /* Works in 8-bit mode */
70 AUX_MU_MCR_REG(uart->hw_base) = 0; /* Disable RTS */
71 AUX_MU_IIR_REG(uart->hw_base) = 0xC6; /* Enable FIFO, Clear FIFO */
72 AUX_MU_BAUD_REG(uart->hw_base) = 270; /* 115200 = system clock 250MHz / (8 * (baud + 1)), baud = 270 */
73 AUX_MU_CNTL_REG(uart->hw_base) = 3; /* Enable Transmitter and Receiver */
74 return RT_EOK;
75 }
76
77 if(uart->hw_base == uart0_addr)
78 {
79 prev_raspi_pin_mode(GPIO_PIN_14, ALT0);
80 prev_raspi_pin_mode(GPIO_PIN_15, ALT0);
81 }
82
83 if(uart->hw_base == uart3_addr)
84 {
85 prev_raspi_pin_mode(GPIO_PIN_4, ALT4);
86 prev_raspi_pin_mode(GPIO_PIN_5, ALT4);
87 }
88
89 if(uart->hw_base == uart4_addr)
90 {
91 prev_raspi_pin_mode(GPIO_PIN_8, ALT4);
92 prev_raspi_pin_mode(GPIO_PIN_9, ALT4);
93 }
94
95 if(uart->hw_base == uart5_addr)
96 {
97 prev_raspi_pin_mode(GPIO_PIN_12, ALT4);
98 prev_raspi_pin_mode(GPIO_PIN_13, ALT4);
99 }
100
101 PL011_REG_CR(uart->hw_base) = 0;/*Clear UART setting*/
102 PL011_REG_LCRH(uart->hw_base) = 0;/*disable FIFO*/
103 PL011_REG_IBRD(uart->hw_base) = ibrd;
104 PL011_REG_FBRD(uart->hw_base) = (((bauddiv - ibrd * 1000) * 64 + 500) / 1000);
105 PL011_REG_LCRH(uart->hw_base) = PL011_LCRH_WLEN_8;/*FIFO*/
106 PL011_REG_CR(uart->hw_base) = PL011_CR_UARTEN | PL011_CR_TXE | PL011_CR_RXE;/*art enable, TX/RX enable*/
107
108 return RT_EOK;
109 }
110
uart_control(struct rt_serial_device * serial,int cmd,void * arg)111 static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
112 {
113 struct hw_uart_device *uart;
114
115 RT_ASSERT(serial != RT_NULL);
116 uart = (struct hw_uart_device *)serial->parent.user_data;
117 switch (cmd)
118 {
119 case RT_DEVICE_CTRL_CLR_INT:
120 break;
121
122 case RT_DEVICE_CTRL_SET_INT:
123 /* enable rx irq */
124 if(uart->hw_base == AUX_BASE)
125 {
126 AUX_MU_IER_REG(uart->hw_base) = 0x1;
127 }
128 else
129 {
130 PL011_REG_IMSC(uart->hw_base) |= PL011_IMSC_RXIM;
131 }
132 rt_hw_interrupt_umask(uart->irqno);
133 break;
134 }
135 return RT_EOK;
136 }
137
uart_putc(struct rt_serial_device * serial,char c)138 static int uart_putc(struct rt_serial_device *serial, char c)
139 {
140 struct hw_uart_device *uart;
141 RT_ASSERT(serial != RT_NULL);
142 uart = (struct hw_uart_device *)serial->parent.user_data;
143 if(uart->hw_base == AUX_BASE)
144 {
145 while (!(AUX_MU_LSR_REG(uart->hw_base) & 0x20));
146 AUX_MU_IO_REG(uart->hw_base) = c;
147 }
148 else
149 {
150 while ((PL011_REG_FR(uart->hw_base) & PL011_FR_TXFF));
151 PL011_REG_DR(uart->hw_base) = (uint8_t)c;
152 }
153 return 1;
154 }
155
uart_getc(struct rt_serial_device * serial)156 static int uart_getc(struct rt_serial_device *serial)
157 {
158 int ch = -1;
159 struct hw_uart_device *uart;
160
161 RT_ASSERT(serial != RT_NULL);
162 uart = (struct hw_uart_device *)serial->parent.user_data;
163
164 if(uart->hw_base == AUX_BASE)
165 {
166 if ((AUX_MU_LSR_REG(uart->hw_base) & 0x01))
167 {
168 ch = AUX_MU_IO_REG(uart->hw_base) & 0xff;
169 }
170 }
171 else
172 {
173 if((PL011_REG_FR(uart->hw_base) & PL011_FR_RXFE) == 0)
174 {
175 ch = PL011_REG_DR(uart->hw_base) & 0xff;
176 }
177 }
178
179 return ch;
180 }
181
182 static const struct rt_uart_ops _uart_ops =
183 {
184 uart_configure,
185 uart_control,
186 uart_putc,
187 uart_getc,
188 };
189
190 volatile void *earlycon_base = 0;
191 const size_t earlycon_size = 0x1000;
192
early_putc(int c)193 extern void early_putc(int c)
194 {
195 if (c == '\n')
196 {
197 early_putc('\r');
198 }
199 while (!(AUX_MU_LSR_REG(earlycon_base) & 0x20));
200 AUX_MU_IO_REG(earlycon_base) = c;
201 }
202
rt_hw_earlycon_ioremap_early(void)203 void rt_hw_earlycon_ioremap_early(void)
204 {
205 earlycon_base = rt_ioremap_early((void *)AUX_BASE, earlycon_size);
206 }
207
rt_hw_console_output(const char * str)208 void rt_hw_console_output(const char *str)
209 {
210 if (earlycon_base)
211 {
212 while (*str)
213 {
214 early_putc(*str++);
215 }
216 }
217 }
218
early_printhex(rt_ubase_t number)219 void early_printhex(rt_ubase_t number)
220 {
221 char str[sizeof("0123456789abcdef")];
222
223 str[16] = 0;
224
225 for (int i = 15; i >= 0; --i)
226 {
227 str[i] = "0123456789abcdef"[(number & 0xf)];
228
229 number >>= 4;
230 }
231
232 rt_kputs(str);
233 }
234
235 #ifdef RT_USING_UART1
rt_hw_aux_uart_isr(int irqno,void * param)236 static void rt_hw_aux_uart_isr(int irqno, void *param)
237 {
238 struct rt_serial_device *serial = (struct rt_serial_device*)param;
239 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
240 }
241 #endif
242
rt_hw_uart_isr(int irqno,void * param)243 static void rt_hw_uart_isr(int irqno, void *param)
244 {
245 #ifdef RT_USING_UART0
246 if((PACTL_CS & IRQ_UART0) == IRQ_UART0)
247 {
248 PACTL_CS &= ~(IRQ_UART0);
249 rt_hw_serial_isr(&_serial0, RT_SERIAL_EVENT_RX_IND);
250 PL011_REG_ICR(uart0_addr) = PL011_INTERRUPT_RECEIVE;
251 }
252 #endif
253
254 #ifdef RT_USING_UART3
255 if((PACTL_CS & IRQ_UART3) == IRQ_UART3)
256 {
257 PACTL_CS &= ~(IRQ_UART3);
258 rt_hw_serial_isr(&_serial3, RT_SERIAL_EVENT_RX_IND);
259 PL011_REG_ICR(uart3_addr) = PL011_INTERRUPT_RECEIVE;
260 }
261 #endif
262
263 #ifdef RT_USING_UART4
264 if((PACTL_CS & IRQ_UART4) == IRQ_UART4)
265 {
266 PACTL_CS &= ~(IRQ_UART4);
267 rt_hw_serial_isr(&_serial4, RT_SERIAL_EVENT_RX_IND);
268 PL011_REG_ICR(uart4_addr) = PL011_INTERRUPT_RECEIVE;
269 }
270 #endif
271
272 #ifdef RT_USING_UART5
273 if((PACTL_CS & IRQ_UART5) == IRQ_UART5)
274 {
275 PACTL_CS &= ~(IRQ_UART5);
276 rt_hw_serial_isr(&_serial5, RT_SERIAL_EVENT_RX_IND);
277 PL011_REG_ICR(uart5_addr) = PL011_INTERRUPT_RECEIVE;
278 }
279 #endif
280 }
281
282 #ifdef RT_USING_UART0
283 /* UART device driver structure */
284 static struct hw_uart_device _uart0_device =
285 {
286 UART0_BASE,
287 IRQ_PL011,
288 };
289 #endif
290
291 #ifdef RT_USING_UART1
292 /* UART device driver structure */
293 static struct hw_uart_device _uart1_device =
294 {
295 AUX_BASE,
296 IRQ_AUX_UART,
297 };
298 #endif
299
300 #ifdef RT_USING_UART3
301 static struct hw_uart_device _uart3_device =
302 {
303 UART3_BASE,
304 IRQ_PL011,
305 };
306 #endif
307
308 #ifdef RT_USING_UART4
309 static struct hw_uart_device _uart4_device =
310 {
311 UART4_BASE,
312 IRQ_PL011,
313 };
314 #endif
315
316 #ifdef RT_USING_UART5
317 static struct hw_uart_device _uart5_device =
318 {
319 UART5_BASE,
320 IRQ_PL011,
321 };
322 #endif
323
rt_hw_uart_init(void)324 int rt_hw_uart_init(void)
325 {
326 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
327 #ifdef RT_USING_UART0
328 struct hw_uart_device *uart0;
329 uart0 = &_uart0_device;
330
331 _serial0.ops = &_uart_ops;
332 _serial0.config = config;
333
334 uart0_addr = UART0_BASE;
335 #ifdef RT_USING_SMART
336 uart0_addr = (size_t)rt_ioremap((void*)UART0_BASE, 0x1000);
337 #endif
338 earlycon_base = (void *)uart0_addr;
339 uart0->hw_base = uart0_addr;
340
341
342 /* register UART0 device */
343 rt_hw_serial_register(&_serial0, "uart0",
344 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
345 uart0);
346 rt_hw_interrupt_install(uart0->irqno, rt_hw_uart_isr, &_serial0, "uart0");
347
348 #endif
349
350 #ifdef RT_USING_UART1
351 struct hw_uart_device *uart1;
352 uart1 = &_uart1_device;
353
354 _serial1.ops = &_uart_ops;
355 _serial1.config = config;
356
357 uart1->hw_base = (size_t)rt_ioremap((void*)AUX_BASE, 0x1000);
358
359 /* register UART1 device */
360 rt_hw_serial_register(&_serial1, "uart1",
361 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
362 uart1);
363 rt_hw_interrupt_install(uart1->irqno, rt_hw_aux_uart_isr, &_serial1, "uart1");
364 #endif
365
366 #ifdef RT_USING_UART3
367 struct hw_uart_device *uart3;
368 uart3 = &_uart3_device;
369
370 _serial3.ops = &_uart_ops;
371 _serial3.config = config;
372
373 uart3_addr = (size_t)rt_ioremap((void*)UART3_BASE, 0x1000);
374 uart3->hw_base = uart3_addr;
375
376 /* register UART3 device */
377 rt_hw_serial_register(&_serial3, "uart3",
378 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
379 uart3);
380 rt_hw_interrupt_install(uart3->irqno, rt_hw_uart_isr, &_serial3, "uart3");
381 #endif
382
383 #ifdef RT_USING_UART4
384 struct hw_uart_device *uart4;
385 uart4 = &_uart4_device;
386
387 _serial4.ops = &_uart_ops;
388 _serial4.config = config;
389
390 uart4_addr = (size_t)rt_ioremap((void*)UART4_BASE, 0x1000);
391 uart4->hw_base = uart4_addr;
392
393 /* register UART4 device */
394 rt_hw_serial_register(&_serial4, "uart4",
395 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
396 uart4);
397 rt_hw_interrupt_install(uart4->irqno, rt_hw_uart_isr, &_serial4, "uart4");
398 #endif
399
400 #ifdef RT_USING_UART5
401 struct hw_uart_device *uart5;
402 uart5 = &_uart5_device;
403
404 _serial5.ops = &_uart_ops;
405 _serial5.config = config;
406
407 uart5_addr = (size_t)rt_ioremap((void*)UART5_BASE, 0x1000);
408 uart5->hw_base = uart5_addr;
409
410 /* register UART5 device */
411 rt_hw_serial_register(&_serial5, "uart5",
412 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
413 uart5);
414 rt_hw_interrupt_install(uart5->irqno, rt_hw_uart_isr, &_serial5, "uart5");
415 #endif
416 return 0;
417 }
418
419