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