1 /*
2 * Copyright (c) 2019 Winner Microelectronics Co., Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2018-09-15 flyingcys 1st version
9 */
10
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include "board.h"
14 #include "wm_io.h"
15 #include "wm_uart.h"
16 #include "wm_gpio_afsel.h"
17 #include "wm_type_def.h"
18 #include "wm_cpu.h"
19 #include "drv_uart.h"
20 #include "pin_map.h"
21
22 #define WM600_UART0 (TLS_UART_REGS_T *) HR_UART0_BASE_ADDR
23 #define WM600_UART1 (TLS_UART_REGS_T *) HR_UART1_BASE_ADDR
24 #define WM600_UART2 (TLS_UART_REGS_T *) HR_UART2_BASE_ADDR
25
wm_uart_reg_init(TLS_UART_REGS_T * UARTx)26 static void wm_uart_reg_init(TLS_UART_REGS_T *UARTx)
27 {
28 RT_ASSERT(UARTx == WM600_UART0 || UARTx == WM600_UART1 || UARTx == WM600_UART2);
29
30 if (UARTx == WM600_UART0)
31 {
32 /* disable auto flow control */
33 tls_reg_write32(HR_UART0_FLOW_CTRL, 0);
34 /* disable dma */
35 tls_reg_write32(HR_UART0_DMA_CTRL, 0);
36 /* one byte tx */
37 tls_reg_write32(HR_UART0_FIFO_CTRL, 0);
38 /* disable interrupt */
39 tls_reg_write32(HR_UART0_INT_MASK, 0xFF);
40 /* enable rx/timeout interrupt */
41 tls_reg_write32(HR_UART0_INT_MASK, ~(3 << 2));
42 }
43 else if (UARTx == WM600_UART1)
44 {
45 /* 4 byte tx, 8 bytes rx */
46 tls_reg_write32(HR_UART1_FIFO_CTRL, (0x01 << 2) | (0x02 << 4));
47 /* enable rx timeout, disable rx dma, disable tx dma */
48 tls_reg_write32(HR_UART1_DMA_CTRL, (8 << 3) | (1 << 2));
49 /* enable rx/timeout interrupt */
50 tls_reg_write32(HR_UART1_INT_MASK, ~(3 << 2));
51 }
52 else if (UARTx == WM600_UART2)
53 {
54 /* 4 byte tx, 8 bytes rx */
55 tls_reg_write32(HR_UART2_FIFO_CTRL, (0x01 << 2) | (0x02 << 4));
56 /* enable rx timeout, disable rx dma, disable tx dma */
57 tls_reg_write32(HR_UART2_DMA_CTRL, (8 << 3) | (1 << 2));
58 /* enable rx/timeout interrupt */
59 tls_reg_write32(HR_UART2_INT_MASK, ~(3 << 2));
60 UARTx->UR_LC &= ~(0x1000000);
61 }
62 }
63
wm_uart_gpio_config(TLS_UART_REGS_T * UARTx)64 static void wm_uart_gpio_config(TLS_UART_REGS_T *UARTx)
65 {
66 #if defined(BSP_USING_UART1) || defined(BSP_USING_UART2)
67 rt_int16_t gpio_pin;
68 #endif
69
70 RT_ASSERT(UARTx == WM600_UART0 || UARTx == WM600_UART1 || UARTx == WM600_UART2);
71
72 if (UARTx == WM600_UART0)
73 {
74 /* UART0_TX-PA04 UART0_RX-PA05 */
75 wm_uart0_tx_config(WM_IO_PA_04);
76 wm_uart0_rx_config(WM_IO_PA_05);
77 }
78 #ifdef BSP_USING_UART1
79 else if (UARTx == WM600_UART1)
80 {
81
82 gpio_pin = wm_get_pin(WM_UART1_RX_PIN);
83 if (gpio_pin >= 0)
84 {
85 wm_uart1_rx_config((enum tls_io_name)gpio_pin);
86 }
87 gpio_pin = wm_get_pin(WM_UART1_TX_PIN);
88 if (gpio_pin >= 0)
89 {
90 wm_uart1_tx_config((enum tls_io_name)gpio_pin);
91 }
92 }
93 #endif
94 #ifdef BSP_USING_UART2
95 else if (UARTx == WM600_UART2)
96 {
97 gpio_pin = wm_get_pin(WM_UART2_RX_PIN);
98 if (gpio_pin >= 0)
99 {
100 wm_uart2_rx_config((enum tls_io_name)gpio_pin);
101 }
102 gpio_pin = wm_get_pin(WM_UART2_TX_PIN);
103 if (gpio_pin >= 0)
104 {
105 wm_uart2_tx_scio_config((enum tls_io_name)gpio_pin);
106 }
107 }
108 #endif
109 }
110
wm_uart_irq_config(TLS_UART_REGS_T * UARTx)111 static void wm_uart_irq_config(TLS_UART_REGS_T *UARTx)
112 {
113 RT_ASSERT(UARTx == WM600_UART0 || UARTx == WM600_UART1 || UARTx == WM600_UART2);
114
115 /* config uart interrupt register */
116 /* clear interrupt */
117 UARTx->UR_INTS = 0xFFFFFFFF;
118 /* enable interupt */
119 UARTx->UR_INTM = 0x0;
120 UARTx->UR_DMAC = (4UL << UDMA_RX_FIFO_TIMEOUT_SHIFT) | UDMA_RX_FIFO_TIMEOUT;
121
122 /* config FIFO control */
123 UARTx->UR_FIFOC = UFC_TX_FIFO_LVL_16_BYTE | UFC_RX_FIFO_LVL_16_BYTE | UFC_TX_FIFO_RESET | UFC_RX_FIFO_RESET;
124 UARTx->UR_LC &= ~(ULCON_TX_EN | ULCON_RX_EN);
125 UARTx->UR_LC |= ULCON_TX_EN | ULCON_RX_EN;
126 }
127
wm_uart_baudrate_set(TLS_UART_REGS_T * UARTx,u32 baudrate)128 static int wm_uart_baudrate_set(TLS_UART_REGS_T *UARTx, u32 baudrate)
129 {
130 u32 value;
131 u32 apbclk;
132 tls_sys_clk sysclk;
133
134 RT_ASSERT(UARTx == WM600_UART0 || UARTx == WM600_UART1 || UARTx == WM600_UART2);
135
136 tls_sys_clk_get(&sysclk);
137 apbclk = sysclk.apbclk * 1000000;
138 value = (apbclk / (16 * baudrate) - 1) |
139 (((apbclk % (baudrate * 16)) * 16 / (baudrate * 16)) << 16);
140 UARTx->UR_BD = value;
141
142 return WM_SUCCESS;
143 }
144
wm_uart_parity_set(TLS_UART_REGS_T * UARTx,TLS_UART_PMODE_T paritytype)145 static int wm_uart_parity_set(TLS_UART_REGS_T *UARTx, TLS_UART_PMODE_T paritytype)
146 {
147 RT_ASSERT(UARTx == WM600_UART0 || UARTx == WM600_UART1 || UARTx == WM600_UART2);
148
149 if (paritytype == TLS_UART_PMODE_DISABLED)
150 UARTx->UR_LC &= ~ULCON_PMD_EN;
151 else if (paritytype == TLS_UART_PMODE_EVEN)
152 {
153 UARTx->UR_LC &= ~ULCON_PMD_MASK;
154 UARTx->UR_LC |= ULCON_PMD_EVEN;
155 }
156 else if (paritytype == TLS_UART_PMODE_ODD)
157 {
158 UARTx->UR_LC &= ~ULCON_PMD_MASK;
159 UARTx->UR_LC |= ULCON_PMD_ODD;
160 }
161 else
162 return WM_FAILED;
163
164 return WM_SUCCESS;
165 }
166
wm_uart_stopbits_set(TLS_UART_REGS_T * UARTx,TLS_UART_STOPBITS_T stopbits)167 static int wm_uart_stopbits_set(TLS_UART_REGS_T *UARTx, TLS_UART_STOPBITS_T stopbits)
168 {
169 RT_ASSERT(UARTx == WM600_UART0 || UARTx == WM600_UART1 || UARTx == WM600_UART2);
170
171 if (stopbits == TLS_UART_TWO_STOPBITS)
172 UARTx->UR_LC |= ULCON_STOP_2;
173 else
174 UARTx->UR_LC &= ~ULCON_STOP_2;
175
176 return WM_SUCCESS;
177 }
178
wm_uart_databits_set(TLS_UART_REGS_T * UARTx,TLS_UART_CHSIZE_T charlength)179 static int wm_uart_databits_set(TLS_UART_REGS_T *UARTx, TLS_UART_CHSIZE_T charlength)
180 {
181 RT_ASSERT(UARTx == WM600_UART0 || UARTx == WM600_UART1 || UARTx == WM600_UART2);
182
183 UARTx->UR_LC &= ~ULCON_WL_MASK;
184
185 if (charlength == TLS_UART_CHSIZE_5BIT)
186 UARTx->UR_LC |= ULCON_WL5;
187 else if (charlength == TLS_UART_CHSIZE_6BIT)
188 UARTx->UR_LC |= ULCON_WL6;
189 else if (charlength == TLS_UART_CHSIZE_7BIT)
190 UARTx->UR_LC |= ULCON_WL7;
191 else if (charlength == TLS_UART_CHSIZE_8BIT)
192 UARTx->UR_LC |= ULCON_WL8;
193 else
194 return WM_FAILED;
195
196 return WM_SUCCESS;
197 }
198
wm_uart_flow_ctrl_set(TLS_UART_REGS_T * UARTx,TLS_UART_FLOW_CTRL_MODE_T flow_ctrl)199 static int wm_uart_flow_ctrl_set(TLS_UART_REGS_T *UARTx, TLS_UART_FLOW_CTRL_MODE_T flow_ctrl)
200 {
201 RT_ASSERT(UARTx == WM600_UART0 || UARTx == WM600_UART1 || UARTx == WM600_UART2);
202
203 switch (flow_ctrl)
204 {
205 case TLS_UART_FLOW_CTRL_NONE:
206 UARTx->UR_FC = 0;
207 break;
208
209 case TLS_UART_FLOW_CTRL_HARDWARE:
210 UARTx->UR_FC = (1UL << 0) | (6UL << 2);
211 break;
212
213 default:
214 break;
215 }
216
217 return WM_SUCCESS;
218 }
219
220 struct device_uart
221 {
222 TLS_UART_REGS_T volatile *uart_device;
223
224 rt_uint32_t uart_irq_no;
225 };
226
227 static rt_err_t drv_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
228 static rt_err_t drv_uart_control(struct rt_serial_device *serial, int cmd, void *arg);
229 static int drv_uart_putc(struct rt_serial_device *serial, char c);
230 static int drv_uart_getc(struct rt_serial_device *serial);
231 static rt_ssize_t drv_uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
232
233 const struct rt_uart_ops _uart_ops =
234 {
235 drv_uart_configure,
236 drv_uart_control,
237 drv_uart_putc,
238 drv_uart_getc,
239 drv_uart_dma_transmit
240 };
241
242 /*
243 * UART interface
244 */
drv_uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)245 static rt_err_t drv_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
246 {
247 struct device_uart *uart;
248 u32 baud_rate;
249 TLS_UART_PMODE_T parity;
250 TLS_UART_STOPBITS_T stop_bits;
251 TLS_UART_CHSIZE_T data_bits;
252
253 RT_ASSERT(serial != RT_NULL && cfg != RT_NULL);
254 serial->config = *cfg;
255
256 uart = (struct device_uart *)serial->parent.user_data;
257 RT_ASSERT(uart != RT_NULL);
258
259 switch (cfg->baud_rate)
260 {
261 case BAUD_RATE_2000000:
262 case BAUD_RATE_921600:
263 case BAUD_RATE_460800:
264 case BAUD_RATE_230400:
265 case BAUD_RATE_115200:
266 case BAUD_RATE_57600:
267 case BAUD_RATE_38400:
268 case BAUD_RATE_19200:
269 case BAUD_RATE_9600:
270 case BAUD_RATE_4800:
271 case BAUD_RATE_2400:
272 baud_rate = cfg->baud_rate;
273 break;
274
275 default:
276 rt_kprintf("baudrate set failed... default rate:115200\r\n");
277 baud_rate = BAUD_RATE_115200;
278 break;
279 }
280 wm_uart_baudrate_set((TLS_UART_REGS_T *)uart->uart_device, baud_rate);
281
282 switch (cfg->parity)
283 {
284 case PARITY_ODD:
285 parity = TLS_UART_PMODE_ODD;
286 break;
287
288 case PARITY_EVEN:
289 parity = TLS_UART_PMODE_EVEN;
290 break;
291
292 case PARITY_NONE:
293 default:
294 parity = TLS_UART_PMODE_DISABLED;
295 break;
296 }
297 wm_uart_parity_set((TLS_UART_REGS_T *)uart->uart_device, parity);
298
299 switch (cfg->stop_bits)
300 {
301 case STOP_BITS_2:
302 stop_bits = TLS_UART_TWO_STOPBITS;
303 break;
304
305 case STOP_BITS_1:
306 default:
307 stop_bits = TLS_UART_ONE_STOPBITS;
308 break;
309 }
310 wm_uart_stopbits_set((TLS_UART_REGS_T *)uart->uart_device, stop_bits);
311
312 switch (cfg->data_bits)
313 {
314 case DATA_BITS_5:
315 data_bits = TLS_UART_CHSIZE_5BIT;
316 break;
317
318 case DATA_BITS_6:
319 data_bits = TLS_UART_CHSIZE_6BIT;
320 break;
321
322 case DATA_BITS_7:
323 data_bits = TLS_UART_CHSIZE_7BIT;
324 break;
325
326 case DATA_BITS_8:
327 default:
328 data_bits = TLS_UART_CHSIZE_8BIT;
329 break;
330 }
331 wm_uart_databits_set((TLS_UART_REGS_T *)uart->uart_device, data_bits);
332 wm_uart_flow_ctrl_set((TLS_UART_REGS_T *)uart->uart_device, TLS_UART_FLOW_CTRL_NONE);
333
334 return (RT_EOK);
335 }
336
drv_uart_control(struct rt_serial_device * serial,int cmd,void * arg)337 static rt_err_t drv_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
338 {
339 struct device_uart *uart;
340
341 RT_ASSERT(serial != RT_NULL);
342
343 uart = (struct device_uart *)serial->parent.user_data;
344 RT_ASSERT(uart != RT_NULL);
345
346 switch (cmd)
347 {
348 case RT_DEVICE_CTRL_CLR_INT:
349 /* Disable the UART Interrupt */
350 tls_irq_disable(uart->uart_irq_no);
351 break;
352
353 case RT_DEVICE_CTRL_SET_INT:
354 /* Enable the UART Interrupt */
355 tls_irq_enable(uart->uart_irq_no);
356 break;
357 }
358
359 return (RT_EOK);
360 }
361
drv_uart_putc(struct rt_serial_device * serial,char c)362 static int drv_uart_putc(struct rt_serial_device *serial, char c)
363 {
364 struct device_uart *uart;
365
366 RT_ASSERT(serial != RT_NULL);
367 uart = (struct device_uart *)serial->parent.user_data;
368 RT_ASSERT(uart != RT_NULL);
369
370 while (uart->uart_device->UR_FIFOS & 0x3F); /* wait THR is empty */
371 uart->uart_device->UR_TXW = (char)c;
372
373 return (1);
374 }
375
drv_uart_getc(struct rt_serial_device * serial)376 static int drv_uart_getc(struct rt_serial_device *serial)
377 {
378 int ch;
379 struct device_uart *uart;
380
381 RT_ASSERT(serial != RT_NULL);
382 uart = (struct device_uart *)serial->parent.user_data;
383 RT_ASSERT(uart != RT_NULL);
384
385 ch = -1;
386
387 if (uart->uart_device->UR_FIFOS & UFS_RX_FIFO_CNT_MASK)
388 ch = (int)uart->uart_device->UR_RXW;
389
390 return ch;
391 }
392
drv_uart_dma_transmit(struct rt_serial_device * serial,rt_uint8_t * buf,rt_size_t size,int direction)393 static rt_ssize_t drv_uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
394 {
395 return (0);
396 }
397
drv_uart_irq_handler(struct rt_serial_device * serial)398 static void drv_uart_irq_handler(struct rt_serial_device *serial)
399 {
400 u32 intr_src;
401 struct device_uart *uart;
402
403 RT_ASSERT(serial != RT_NULL);
404 uart = (struct device_uart *)serial->parent.user_data;
405 RT_ASSERT(uart != RT_NULL);
406
407 /* check interrupt status */
408 intr_src = uart->uart_device->UR_INTS;
409 uart->uart_device->UR_INTS = intr_src;
410
411 if ((intr_src & UART_RX_INT_FLAG) && (0 == (uart->uart_device->UR_INTM & UIS_RX_FIFO)))
412 {
413 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
414 }
415
416 if (intr_src & UART_TX_INT_FLAG)
417 {
418
419 }
420
421 if (intr_src & UIS_CTS_CHNG)
422 {
423
424 }
425 }
426
427 #ifdef BSP_USING_UART0
428 static struct rt_serial_device serial0;
429 static struct device_uart uart0 =
430 {
431 WM600_UART0,
432 UART0_INT,
433 };
434
UART0_IRQHandler(void)435 void UART0_IRQHandler(void)
436 {
437 /* enter interrupt */
438 rt_interrupt_enter();
439
440 drv_uart_irq_handler(&serial0);
441
442 /* leave interrupt */
443 rt_interrupt_leave();
444 }
445 #endif
446
447 #ifdef BSP_USING_UART1
448 static struct rt_serial_device serial1;
449 static struct device_uart uart1 =
450 {
451 WM600_UART1,
452 UART1_INT,
453 };
454
UART1_IRQHandler(void)455 void UART1_IRQHandler(void)
456 {
457 /* enter interrupt */
458 rt_interrupt_enter();
459
460 drv_uart_irq_handler(&serial1);
461
462 /* leave interrupt */
463 rt_interrupt_leave();
464
465 }
466 #endif
467
468 #ifdef BSP_USING_UART2
469 static struct rt_serial_device serial2;
470 static struct device_uart uart2 =
471 {
472 WM600_UART2,
473 UART2_INT,
474 };
475
UART2_IRQHandler(void)476 void UART2_IRQHandler(void)
477 {
478 /* enter interrupt */
479 rt_interrupt_enter();
480
481 drv_uart_irq_handler(&serial2);
482
483 /* leave interrupt */
484 rt_interrupt_leave();
485
486 }
487 #endif
488 /*
489 * UART Initiation
490 */
wm_hw_uart_init(void)491 int wm_hw_uart_init(void)
492 {
493 struct rt_serial_device *serial;
494 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
495
496 struct device_uart *uart;
497
498 #ifdef BSP_USING_UART0
499 {
500 serial = &serial0;
501 uart = &uart0;
502
503 /* Init UART Hardware */
504 wm_uart_gpio_config((TLS_UART_REGS_T *)uart->uart_device);
505 wm_uart_reg_init((TLS_UART_REGS_T *)uart->uart_device);
506 wm_uart_irq_config((TLS_UART_REGS_T *)uart->uart_device);
507
508 serial->ops = &_uart_ops;
509 serial->config = config;
510 serial->config.baud_rate = 115200;
511
512 rt_hw_serial_register(serial,
513 "uart0",
514 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
515 uart);
516 }
517 #endif /* BSP_USING_UART0 */
518
519 #ifdef BSP_USING_UART1
520 {
521 serial = &serial1;
522 uart = &uart1;
523
524 /* Init UART Hardware */
525 wm_uart_gpio_config((TLS_UART_REGS_T *)uart->uart_device);
526 wm_uart_reg_init((TLS_UART_REGS_T *)uart->uart_device);
527 wm_uart_irq_config((TLS_UART_REGS_T *)uart->uart_device);
528
529 serial->ops = &_uart_ops;
530 serial->config = config;
531 serial->config.baud_rate = WM_UART1_BAUDRATE;
532
533 rt_hw_serial_register(serial,
534 "uart1",
535 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
536 uart);
537 }
538 #endif /* BSP_USING_UART1 */
539 #ifdef BSP_USING_UART2
540 {
541 serial = &serial2;
542 uart = &uart2;
543
544 /* Init UART Hardware */
545 wm_uart_gpio_config((TLS_UART_REGS_T *)uart->uart_device);
546 wm_uart_reg_init((TLS_UART_REGS_T *)uart->uart_device);
547 wm_uart_irq_config((TLS_UART_REGS_T *)uart->uart_device);
548
549 serial->ops = &_uart_ops;
550 serial->config = config;
551 serial->config.baud_rate = WM_UART2_BAUDRATE;
552
553 rt_hw_serial_register(serial,
554 "uart2",
555 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
556 uart);
557 }
558 #endif /* BSP_USING_UART2 */
559 return 0;
560 }
561 INIT_BOARD_EXPORT(wm_hw_uart_init);
562