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 * 2017-05-30 Bernard the first version
9 * 2018-03-15 flyingcys add amebaz
10 */
11 #include <rtl8710b.h>
12 #include <serial_api.h>
13 #include "board.h"
14 #include "drv_uart.h"
15
16 struct device_uart
17 {
18 serial_t serial;
19
20 rt_uint32_t irqno;
21 };
22
23 extern int LOGUART_SetBaud(u32 BaudRate);
24
25 #ifdef BSP_USING_UART0
26 static struct rt_serial_device serial0;
27 static struct device_uart uart0;
28 #endif
29
30 static rt_err_t ameba_uart_configure (struct rt_serial_device *serial, struct serial_configure *cfg);
31 static rt_err_t ameba_uart_control (struct rt_serial_device *serial, int cmd, void *arg);
32 static int ameba_uart_putc (struct rt_serial_device *serial, char c);
33 static int ameba_uart_getc (struct rt_serial_device *serial);
34 static rt_ssize_t ameba_uart_dma_transmit (struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
35
36 static void ameba_uart_irq(uint32_t id, SerialIrq event);
37
38 const struct rt_uart_ops _uart_ops =
39 {
40 ameba_uart_configure,
41 ameba_uart_control,
42 ameba_uart_putc,
43 ameba_uart_getc,
44 ameba_uart_dma_transmit
45 };
46
47 /*
48 * UART interface
49 */
ameba_uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)50 static rt_err_t ameba_uart_configure (struct rt_serial_device *serial, struct serial_configure *cfg)
51 {
52 struct device_uart * uart;
53
54 RT_ASSERT(serial != RT_NULL);
55 serial->config = *cfg;
56
57 uart = serial->parent.user_data;
58 RT_ASSERT(uart != RT_NULL);
59
60 /* Set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */
61 serial_format(&uart->serial, 8, ParityNone, 1);
62
63 /* set baudrate */
64 serial_baud(&uart->serial, 115200);
65
66 return (RT_EOK);
67 }
68
ameba_uart_control(struct rt_serial_device * serial,int cmd,void * arg)69 static rt_err_t ameba_uart_control (struct rt_serial_device *serial, int cmd, void *arg)
70 {
71 struct device_uart * uart;
72
73 uart = serial->parent.user_data;
74
75 RT_ASSERT(uart != RT_NULL);
76
77 switch (cmd)
78 {
79 case RT_DEVICE_CTRL_CLR_INT:
80 /* Disable the UART Interrupt */
81 serial_irq_set(&uart->serial, RxIrq, 0);
82 serial_irq_handler(&uart->serial, RT_NULL, 0);
83 break;
84
85 case RT_DEVICE_CTRL_SET_INT:
86 /* install interrupt */
87 serial_irq_handler(&uart->serial, ameba_uart_irq, (uint32_t)serial);
88
89 /* Enable the UART Interrupt */
90 serial_irq_set(&uart->serial, RxIrq, 1);
91 break;
92 }
93
94 return (RT_EOK);
95 }
96
ameba_uart_putc(struct rt_serial_device * serial,char c)97 static int ameba_uart_putc (struct rt_serial_device *serial, char c)
98 {
99 struct device_uart* uart;
100
101 uart = serial->parent.user_data;
102
103 /* FIFO status, contain valid data */
104 /* write data */
105 serial_putc(&uart->serial, c);
106
107 return (1);
108 }
109
ameba_uart_getc(struct rt_serial_device * serial)110 static int ameba_uart_getc (struct rt_serial_device *serial)
111 {
112 struct device_uart* uart = serial->parent.user_data;
113
114 if(!serial_readable(&uart->serial))
115 return -1;
116
117 /* Receive Data Available */
118 return serial_getc(&uart->serial);
119 }
120
ameba_uart_dma_transmit(struct rt_serial_device * serial,rt_uint8_t * buf,rt_size_t size,int direction)121 static rt_ssize_t ameba_uart_dma_transmit (struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
122 {
123 return (0);
124 }
125
ameba_uart_irq(uint32_t id,SerialIrq event)126 static void ameba_uart_irq(uint32_t id, SerialIrq event)
127 {
128 struct rt_serial_device *serial = (struct rt_serial_device *)id;
129 if(event == RxIrq)
130 {
131 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
132 }
133 else if(event == TxIrq)
134 {
135 }
136 }
137
138 static rt_err_t dbg_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
139 static rt_err_t dbg_control(struct rt_serial_device *serial, int cmd, void *arg);
140 static int dbg_putc(struct rt_serial_device *serial, char c);
141 static int dbg_getc(struct rt_serial_device *serial);
142
143 static struct rt_serial_device ameba_dbg_serial;
144 const struct rt_uart_ops _ambed_dbg_ops =
145 {
146 dbg_configure,
147 dbg_control,
148 dbg_putc,
149 dbg_getc,
150 RT_NULL,
151 };
152
dbg_configure(struct rt_serial_device * serial,struct serial_configure * cfg)153 static rt_err_t dbg_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
154 {
155 LOGUART_SetBaud(115200);
156 return RT_EOK;
157 }
158
dbg_uart_irq_handler(void * data)159 void dbg_uart_irq_handler(void * data)
160 {
161 u32 IrqEn = DiagGetIsrEnReg();
162
163 DiagSetIsrEnReg(0);
164
165 rt_hw_serial_isr(&ameba_dbg_serial, RT_SERIAL_EVENT_RX_IND);
166
167 DiagSetIsrEnReg(IrqEn);
168 }
169
dbg_control(struct rt_serial_device * serial,int cmd,void * arg)170 static rt_err_t dbg_control(struct rt_serial_device *serial, int cmd, void *arg)
171 {
172 switch (cmd)
173 {
174 case RT_DEVICE_CTRL_CLR_INT:
175 /* Disable the UART Interrupt */
176 NVIC_DisableIRQ(UART_LOG_IRQ); /* this is rom_code_patch */
177 break;
178
179 case RT_DEVICE_CTRL_SET_INT:
180 /* install interrupt */
181 DIAG_UartReInit((IRQ_FUN) dbg_uart_irq_handler);
182 /* Enable the UART Interrupt */
183 NVIC_SetPriority(UART_LOG_IRQ, 10); /* this is rom_code_patch */
184 break;
185 }
186
187 return (RT_EOK);
188 }
189
dbg_putc(struct rt_serial_device * serial,char c)190 static int dbg_putc(struct rt_serial_device *serial, char c)
191 {
192 DiagPutChar(c);
193
194 return 1;
195 };
196
dbg_getc(struct rt_serial_device * serial)197 static int dbg_getc(struct rt_serial_device *serial)
198 {
199 int c = -1;
200
201 if(!UART_Readable(UART2_DEV))
202 return -1;
203
204 c = DiagGetChar(_FALSE);
205
206 return c;
207 }
208
209 /*
210 * UART Initiation
211 */
rt_hw_uart_init(void)212 int rt_hw_uart_init(void)
213 {
214 struct rt_serial_device *serial;
215 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
216
217 #ifdef BSP_USING_UART0
218 {
219 struct device_uart *uart;
220
221 serial = &serial0;
222 uart = &uart0;
223
224 /* Init UART Hardware */
225 serial_init(&uart->serial, UART_TX, UART_RX);
226
227 serial->ops = &_uart_ops;
228 serial->config = config;
229 serial->config.baud_rate = 115200;
230
231 uart->irqno = UART0_IRQ;
232
233 rt_hw_serial_register(serial,
234 "uart0",
235 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
236 uart);
237 }
238 #endif
239
240 {
241 serial = &ameba_dbg_serial;
242
243 serial->ops = &_ambed_dbg_ops;
244 serial->config = config;
245
246 rt_hw_serial_register(serial,
247 RT_CONSOLE_DEVICE_NAME,
248 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
249 RT_NULL);
250 }
251 return 0;
252 }
253