1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author            Notes
8  * 2021/04/22     Juice           Add UART0 support for JuiceVm.
9  */
10 
11 #include <rthw.h>
12 #include <rtthread.h>
13 #include <rtdevice.h>
14 
15 #include "board.h"
16 #include "drv_uart.h"
17 
18 #include "rv_mtvec_map.h"
19 
20 struct rt_serial_device *serial;
21 char *device_name = "uart0";
22 
23 static rt_err_t  uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
24 static rt_err_t  uart_control(struct rt_serial_device *serial, int cmd, void *arg);
25 static int       uart_putc(struct rt_serial_device *serial, char c);
26 static int       uart_getc(struct rt_serial_device *serial);
27 static rt_ssize_t uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
28 
29 void UART0_DriverIRQHandler(void);
30 
31 const struct rt_uart_ops _uart_ops =
32 {
33     uart_configure,
34     uart_control,
35     uart_putc,
36     uart_getc,
37     uart_dma_transmit
38 };
39 
40 static void uart_isr(struct rt_serial_device *serial);
41 
42 #if defined(BSP_USING_UART0)
43 struct rt_serial_device serial0;
44 
UART0_DriverIRQHandler(void)45 void UART0_DriverIRQHandler(void)
46 {
47     uart_isr(&serial0);
48 }
49 #endif
50 
51 
52 
53 /*
54  * UART Initiation
55  */
rt_hw_uart_init(void)56 int rt_hw_uart_init(void)
57 {
58     int i;
59     struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
60     serial = &serial0;
61     serial->ops    = &_uart_ops;
62     serial->config = config;
63 
64     /* register UART device */
65     rt_hw_serial_register(serial,
66                           device_name,
67                           RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
68                           (void *)0);
69 
70     return 0;
71 }
72 
73 /*
74  * UART interface
75  */
uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)76 static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
77 {
78 
79     RT_ASSERT(serial != RT_NULL);
80     RT_ASSERT(cfg != RT_NULL);
81 
82     return RT_EOK;
83 }
84 
uart_control(struct rt_serial_device * serial,int cmd,void * arg)85 static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
86 {
87     RT_ASSERT(serial != RT_NULL);
88 
89     return RT_EOK;
90 }
91 
uart_putc(struct rt_serial_device * serial,char c)92 static int uart_putc(struct rt_serial_device *serial, char c)
93 {
94 
95     RT_ASSERT(serial != RT_NULL);
96 
97     *((char *)(pdev_uart0_write_addr)) = c;
98 
99     return (1);
100 }
101 
uart_getc(struct rt_serial_device * serial)102 static int uart_getc(struct rt_serial_device *serial)
103 {
104     int ch;
105 
106     RT_ASSERT(serial != RT_NULL);
107 
108     ch = -1;
109 
110     if (*(char *)(pdev_uart0_state_addr) == pdev_uart0_readbusy_state)
111     {
112         ch = *(char *)(pdev_uart0_read_addr);
113         *(char *)(pdev_uart0_state_addr) = pdev_uart0_free_state;
114     }
115     return ch;
116 }
117 
uart_dma_transmit(struct rt_serial_device * serial,rt_uint8_t * buf,rt_size_t size,int direction)118 static rt_ssize_t uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
119 {
120     return (0);
121 }
122 
123 /* UART ISR */
124 /**
125  * Uart common interrupt process. This need add to uart ISR.
126  *
127  * @param serial serial device
128  */
uart_isr(struct rt_serial_device * serial)129 static void uart_isr(struct rt_serial_device *serial)
130 {
131     RT_ASSERT(serial != RT_NULL);
132 
133     if (*(char *)(pdev_uart0_state_addr) == pdev_uart0_readbusy_state)
134     {
135         rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
136     }
137 }
138