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 * 2018-02-08 RT-Thread the first version
9 */
10
11 #include <rthw.h>
12 #include <rtthread.h>
13 #include <rtdevice.h>
14
15 #include "drv_uart.h"
16 #include "interrupt.h"
17
18 #include "drv_gpio.h"
19 #include "drv_clock.h"
20
21 #define readl(addr) (*(volatile unsigned int *)(addr))
22 #define writel(value,addr) (*(volatile unsigned int *)(addr) = (value))
23
24 #ifdef RT_USING_SERIAL
25
26 struct device_uart
27 {
28 rt_uint32_t hw_base;
29 rt_uint32_t irqno;
30 char name[RT_NAME_MAX];
31 rt_uint32_t gpio_rx_port;
32 rt_uint32_t gpio_tx_port;
33 rt_uint32_t gpio_rx_pin;
34 rt_uint32_t gpio_tx_pin;
35 rt_uint32_t gpio_rx_fun;
36 rt_uint32_t gpio_tx_fun;
37 };
38
39 static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
40 static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg);
41 static int uart_putc(struct rt_serial_device *serial, char c);
42 static int uart_getc(struct rt_serial_device *serial);
43 static rt_ssize_t uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
44
45 void uart_irq_handler(int irqno, void *param);
46
47 const struct rt_uart_ops _uart_ops =
48 {
49 uart_configure,
50 uart_control,
51 uart_putc,
52 uart_getc,
53 uart_dma_transmit
54 };
55
56 /*
57 * UART Initiation
58 */
rt_hw_uart_init(void)59 int rt_hw_uart_init(void)
60 {
61 struct rt_serial_device *serial;
62 struct device_uart *uart;
63 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
64
65 #ifdef TINA_USING_UART0
66 {
67 static struct rt_serial_device serial0;
68 static struct device_uart uart0;
69
70 serial = &serial0;
71 uart = &uart0;
72
73 serial->ops = &_uart_ops;
74 serial->config = config;
75 serial->config.baud_rate = 115200;
76
77 uart->hw_base = UART0_BASE_ADDR; // UART0_BASE;
78 uart->irqno = UART0_INTERRUPT; // IRQ_UART0;
79 uart->gpio_rx_port = GPIO_PORT_E;
80 uart->gpio_tx_port = GPIO_PORT_E;
81 uart->gpio_rx_pin = GPIO_PIN_0;
82 uart->gpio_tx_pin = GPIO_PIN_1;
83 uart->gpio_rx_fun = IO_FUN_4;
84 uart->gpio_tx_fun = IO_FUN_4;
85
86 rt_hw_serial_register(serial,
87 "uart0",
88 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
89 uart);
90 }
91 #endif
92
93 #ifdef TINA_USING_UART1
94 {
95 static struct rt_serial_device serial1;
96 static struct device_uart uart1;
97
98 serial = &serial1;
99 uart = &uart1;
100
101 serial->ops = &_uart_ops;
102 serial->config = config;
103 serial->config.baud_rate = 115200;
104
105 uart->hw_base = UART1_BASE_ADDR; // UART1_BASE;
106 uart->irqno = UART1_INTERRUPT; // IRQ_UART1;
107 uart->gpio_rx_port = GPIO_PORT_A;
108 uart->gpio_tx_port = GPIO_PORT_A;
109 uart->gpio_rx_pin = GPIO_PIN_2;
110 uart->gpio_tx_pin = GPIO_PIN_3;
111 uart->gpio_rx_fun = IO_FUN_4;
112 uart->gpio_tx_fun = IO_FUN_4;
113
114 rt_hw_serial_register(serial,
115 "uart1",
116 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
117 uart);
118 }
119 #endif
120
121 #ifdef TINA_USING_UART2
122 {
123 static struct rt_serial_device serial2;
124 static struct device_uart uart2;
125
126 serial = &serial2;
127 uart = &uart2;
128
129 serial->ops = &_uart_ops;
130 serial->config = config;
131 serial->config.baud_rate = 115200;
132
133 uart->hw_base = UART2_BASE_ADDR; // UART1_BASE;
134 uart->irqno = UART2_INTERRUPT; // IRQ_UART1;
135 uart->gpio_rx_port = GPIO_PORT_E;
136 uart->gpio_tx_port = GPIO_PORT_E;
137 uart->gpio_rx_pin = GPIO_PIN_8;
138 uart->gpio_tx_pin = GPIO_PIN_7;
139 uart->gpio_rx_fun = IO_FUN_2;
140 uart->gpio_tx_fun = IO_FUN_2;
141
142 rt_hw_serial_register(serial,
143 "uart2",
144 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
145 uart);
146 }
147 #endif
148
149 return 0;
150 }
151
152 /*
153 * UART interface
154 */
uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)155 static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
156 {
157 rt_uint32_t addr, val;
158 struct device_uart *uart;
159
160 RT_ASSERT(serial != RT_NULL);
161 serial->config = *cfg;
162
163 uart = serial->parent.user_data;
164 RT_ASSERT(uart != RT_NULL);
165 /* config gpio port */
166 gpio_set_func(uart->gpio_rx_port, uart->gpio_rx_pin, uart->gpio_rx_fun);
167 gpio_set_func(uart->gpio_tx_port, uart->gpio_tx_pin, uart->gpio_tx_fun);
168 /* Enable UART clock */
169 /* Open the clock gate for uart */
170 if ((rt_uint32_t)(uart->hw_base) == UART0_BASE_ADDR)
171 {
172 bus_gate_clk_enalbe(UART0_GATING);
173 bus_software_reset_enalbe(UART0_GATING);
174 bus_software_reset_disalbe(UART0_GATING);
175 }
176 else if ((rt_uint32_t)(uart->hw_base) == UART1_BASE_ADDR)
177 {
178 bus_gate_clk_enalbe(UART1_GATING);
179 bus_software_reset_enalbe(UART1_GATING);
180 bus_software_reset_disalbe(UART1_GATING);
181 }
182 else if ((rt_uint32_t)(uart->hw_base) == UART2_BASE_ADDR)
183 {
184 bus_gate_clk_enalbe(UART2_GATING);
185 bus_software_reset_enalbe(UART2_GATING);
186 bus_software_reset_disalbe(UART2_GATING);
187 }
188 else
189 RT_ASSERT(0);
190 /* Config uart0 to 115200-8-1-0 */
191 addr = uart->hw_base;
192 /* close uart irq */
193 writel(0x0, addr + UART_IER);
194 /* config fifo */
195 writel(0x37, addr + UART_FCR);
196 /* config modem */
197 writel(0x0, addr + UART_MCR);
198 /* config baud */
199 val = readl(addr + UART_LCR);
200 val |= (1 << 7);
201 writel(val, addr + UART_LCR);
202 val = apb_get_clk() / 16 / serial->config.baud_rate;
203 writel(val & 0xff, addr + UART_DLL);
204 writel((val >> 8) & 0xff, addr + UART_DLH);
205 val = readl(addr + UART_LCR);
206 val &= ~(1 << 7);
207 writel(val, addr + UART_LCR);
208
209 val = readl(addr + UART_LCR);
210 val &= ~0x1f;
211 val |= ((serial->config.data_bits - DATA_BITS_5) << 0) | (0 << 2) | (0x0 << 3);
212 writel(val, addr + UART_LCR);
213
214 writel(0xf, addr + UART_TFL);
215 writel(0x3F, addr + UART_RFL);
216
217 writel(0x1, addr + UART_IER);
218 return RT_EOK;
219 }
220
uart_control(struct rt_serial_device * serial,int cmd,void * arg)221 static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
222 {
223 struct device_uart *uart;
224
225 uart = serial->parent.user_data;
226
227 RT_ASSERT(uart != RT_NULL);
228
229 switch (cmd)
230 {
231 case RT_DEVICE_CTRL_CLR_INT:
232 /* Disable the UART Interrupt */
233 rt_hw_interrupt_mask(uart->irqno);
234 writel(0x00, uart->hw_base + UART_IER);
235 break;
236
237 case RT_DEVICE_CTRL_SET_INT:
238 /* install interrupt */
239 rt_hw_interrupt_install(uart->irqno, uart_irq_handler,
240 serial, uart->name);
241 rt_hw_interrupt_umask(uart->irqno);
242 writel(0x01, uart->hw_base + UART_IER);
243 /* Enable the UART Interrupt */
244 break;
245 }
246
247 return (RT_EOK);
248 }
249
250
uart_putc(struct rt_serial_device * serial,char c)251 static int uart_putc(struct rt_serial_device *serial, char c)
252 {
253 struct device_uart *uart;
254 volatile rt_uint32_t *sed_buf;
255 volatile rt_uint32_t *sta;
256
257 uart = serial->parent.user_data;
258 sed_buf = (rt_uint32_t *)(uart->hw_base + UART_THR);
259 sta = (rt_uint32_t *)(uart->hw_base + UART_USR);
260 /* FIFO status, contain valid data */
261 while (!(*sta & 0x02));
262 *sed_buf = c;
263
264 return (1);
265 }
266
uart_getc(struct rt_serial_device * serial)267 static int uart_getc(struct rt_serial_device *serial)
268 {
269 int ch = -1;
270 volatile rt_uint32_t *rec_buf;
271 volatile rt_uint32_t *sta;
272 struct device_uart *uart = serial->parent.user_data;
273
274 RT_ASSERT(serial != RT_NULL);
275
276 rec_buf = (rt_uint32_t *)(uart->hw_base + UART_RHB);
277 sta = (rt_uint32_t *)(uart->hw_base + UART_USR);
278 /* Receive Data Available */
279 if (*sta & 0x08)
280 {
281 ch = *rec_buf & 0xff;
282 }
283
284 return ch;
285 }
286
uart_dma_transmit(struct rt_serial_device * serial,rt_uint8_t * buf,rt_size_t size,int direction)287 static rt_ssize_t uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
288 {
289 return (0);
290 }
291
292 /* UART ISR */
uart_irq_handler(int irqno,void * param)293 void uart_irq_handler(int irqno, void *param)
294 {
295 rt_uint32_t val;
296 struct rt_serial_device *serial = (struct rt_serial_device *)param;
297 struct device_uart *uart = serial->parent.user_data;
298
299 val = readl(uart->hw_base + 0x08) & 0x0F;
300 /* read interrupt status and clear it */
301 if (val & 0x4) /* rx ind */
302 {
303 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
304 }
305
306 if (0) /* tx done */
307 {
308 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
309 }
310
311 }
312
313 #endif
314