1 /*
2 *
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Change Logs:
6 * Date Author Notes
7 * 2021-9-1 DongBowen first version
8 */
9
10 #include "drv_usart.h"
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include "board.h"
14
15 #ifdef RT_USING_SERIAL
16 #ifdef BSP_USING_UART
17
18 #if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && \
19 !defined(BSP_USING_UART3)
20 #error "Please define at least one BSP_USING_UARTx"
21 /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
22 #endif
23
24 enum
25 {
26 #ifdef BSP_USING_UART0
27 UART0_INDEX,
28 #endif
29 #ifdef BSP_USING_UART1
30 UART1_INDEX,
31 #endif
32 #ifdef BSP_USING_UART2
33 UART2_INDEX,
34 #endif
35 #ifdef BSP_USING_UART3
36 UART3_INDEX,
37 #endif
38 };
39
40 static struct hc_uart_cfg uart_cfg[] =
41 {
42 #ifdef BSP_USING_UART0
43 UART0_CFG,
44 #endif
45 #ifdef BSP_USING_UART1
46 UART1_CFG,
47 #endif
48 #ifdef BSP_USING_UART2
49 UART2_CFG,
50 #endif
51 #ifdef BSP_USING_UART3
52 UART3_CFG,
53 #endif
54 };
55
56 static struct hc_uart uart_drv[sizeof(uart_cfg) / sizeof(uart_cfg[0])] = {0};
57
_uart_init(struct rt_serial_device * serial_device,struct serial_configure * configure)58 static rt_err_t _uart_init(struct rt_serial_device *serial_device, struct serial_configure *configure)
59 {
60 stc_gpio_cfg_t stcGpioCfg;
61 stc_uart_cfg_t stcCfg;
62
63 struct hc_uart_cfg *cfg;
64 RT_ASSERT(serial_device != RT_NULL);
65 RT_ASSERT(configure != RT_NULL);
66 cfg = serial_device->parent.user_data;
67
68 /* configure rx and tx gpio */
69 rt_memset(&stcGpioCfg, 0, sizeof(stcGpioCfg));
70 Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
71 stcGpioCfg.enDir = GpioDirOut;
72 Gpio_Init(cfg->tx_port, cfg->tx_pin, &stcGpioCfg);
73 Gpio_SetAfMode(cfg->tx_port, cfg->tx_pin, cfg->tx_af);
74 stcGpioCfg.enDir = GpioDirIn;
75 Gpio_Init(cfg->rx_port, cfg->rx_pin, &stcGpioCfg);
76 Gpio_SetAfMode(cfg->rx_port, cfg->rx_pin, cfg->rx_af);
77
78 /* configure uart */
79 rt_memset(&stcCfg, 0, sizeof(stcCfg));
80
81 Sysctrl_SetPeripheralGate(cfg->uart_periph, TRUE);
82
83 stcCfg.stcBaud.u32Baud = configure->baud_rate;
84 stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;
85 stcCfg.stcBaud.u32Pclk = Sysctrl_GetPClkFreq();
86
87 switch (configure->data_bits)
88 {
89 case DATA_BITS_8:
90 break;
91 default:
92 break;
93 }
94
95 switch (configure->stop_bits)
96 {
97 case STOP_BITS_1:
98 stcCfg.enStopBit = UartMsk1bit;
99 break;
100 case STOP_BITS_2:
101 stcCfg.enStopBit = UartMsk2bit;
102 break;
103 default:
104 stcCfg.enStopBit = UartMsk1bit;
105 break;
106 }
107
108 switch (configure->parity)
109 {
110 case PARITY_NONE:
111 stcCfg.enMmdorCk = UartMskDataOrAddr;
112 stcCfg.enRunMode = UartMskMode1;
113 break;
114 case PARITY_ODD:
115 stcCfg.enMmdorCk = UartMskOdd;
116 stcCfg.enRunMode = UartMskMode3;
117 break;
118 case PARITY_EVEN:
119 stcCfg.enMmdorCk = UartMskEven;
120 stcCfg.enRunMode = UartMskMode3;
121 break;
122 default:
123 stcCfg.enMmdorCk = UartMskDataOrAddr;
124 stcCfg.enRunMode = UartMskMode1;
125 break;
126 }
127
128 Uart_Init(cfg->uart, &stcCfg);
129
130 Uart_ClrStatus(cfg->uart, UartRC);
131 Uart_ClrStatus(cfg->uart, UartTC);
132
133 rt_hw_us_delay(2);
134 return RT_EOK;
135 }
136
_uart_control(struct rt_serial_device * serial_device,int cmd,void * arg)137 static rt_err_t _uart_control(struct rt_serial_device *serial_device, int cmd, void *arg)
138 {
139 struct hc_uart_cfg *cfg;
140 RT_ASSERT(serial_device != RT_NULL);
141 cfg = serial_device->parent.user_data;
142
143 switch (cmd)
144 {
145 case RT_DEVICE_CTRL_CLR_INT:
146 /* disable rx irq */
147 Uart_DisableIrq(cfg->uart, UartRxIrq);
148 EnableNvic(cfg->irqn, IrqLevel3, FALSE);
149 break;
150 case RT_DEVICE_CTRL_SET_INT:
151 /* enable rx irq */
152 Uart_EnableIrq(cfg->uart, UartRxIrq);
153 EnableNvic(cfg->irqn, IrqLevel3, TRUE);
154 break;
155 }
156 return RT_EOK;
157 }
158
_uart_putc(struct rt_serial_device * serial_device,char c)159 static int _uart_putc(struct rt_serial_device *serial_device, char c)
160 {
161 struct hc_uart_cfg *cfg;
162 RT_ASSERT(serial_device != RT_NULL);
163 cfg = serial_device->parent.user_data;
164
165 Uart_SendDataPoll(cfg->uart, (uint8_t)c);
166 return 1;
167 }
168
_uart_getc(struct rt_serial_device * serial_device)169 static int _uart_getc(struct rt_serial_device *serial_device)
170 {
171 int ch;
172 struct hc_uart_cfg *cfg;
173 RT_ASSERT(serial_device != RT_NULL);
174 cfg = serial_device->parent.user_data;
175
176 ch = -1;
177
178 if (Uart_GetStatus(cfg->uart, UartRC))
179 {
180 Uart_ClrStatus(cfg->uart, UartRC);
181 ch = Uart_ReceiveData(cfg->uart);
182 }
183
184 return ch;
185 }
186
187 static const struct rt_uart_ops _uart_ops =
188 {
189 .configure = _uart_init,
190 .control = _uart_control,
191 .putc = _uart_putc,
192 .getc = _uart_getc,
193 .dma_transmit = RT_NULL
194 };
195
196 /**
197 * Uart common interrupt process. This need add to uart ISR.
198 *
199 * @param serial serial device
200 */
rt_hw_uart_isr(struct rt_serial_device * serial_device)201 static void rt_hw_uart_isr(struct rt_serial_device *serial_device)
202 {
203 struct hc_uart_cfg *cfg;
204 uint32_t status;
205 RT_ASSERT(serial_device != RT_NULL);
206
207 cfg = serial_device->parent.user_data;
208 status = cfg->uart->ISR;
209
210 /* UART in mode Receiver -------------------------------------------------*/
211 if (status & (1 << UartFE))
212 {
213 Uart_ClrStatus(cfg->uart, UartFE);
214 }
215 if (status & (1 << UartPE))
216 {
217 Uart_ClrStatus(cfg->uart, UartPE);
218 }
219 if (status & (1 << UartRC))
220 {
221 rt_hw_serial_isr(serial_device, RT_SERIAL_EVENT_RX_IND);
222 }
223 }
224
225 #if defined(BSP_USING_UART0)
Uart0_IRQHandler(void)226 void Uart0_IRQHandler(void)
227 {
228 /* enter interrupt */
229 rt_interrupt_enter();
230
231 rt_hw_uart_isr(&(uart_drv[UART0_INDEX].serial_device));
232
233 /* leave interrupt */
234 rt_interrupt_leave();
235 }
236 #endif /* BSP_USING_UART0 */
237
238 #if defined(BSP_USING_UART1)
Uart1_IRQHandler(void)239 void Uart1_IRQHandler(void)
240 {
241 /* enter interrupt */
242 rt_interrupt_enter();
243
244 rt_hw_uart_isr(&(uart_drv[UART1_INDEX].serial_device));
245
246 /* leave interrupt */
247 rt_interrupt_leave();
248 }
249 #endif /* BSP_USING_UART1 */
250
251 #if defined(BSP_USING_UART2)
Uart2_IRQHandler(void)252 void Uart2_IRQHandler(void)
253 {
254 /* enter interrupt */
255 rt_interrupt_enter();
256
257 rt_hw_uart_isr(&(uart_drv[UART2_INDEX].serial_device));
258
259 /* leave interrupt */
260 rt_interrupt_leave();
261 }
262 #endif /* BSP_USING_UART2 */
263
264 #if defined(BSP_USING_UART3)
Uart3_IRQHandler(void)265 void Uart3_IRQHandler(void)
266 {
267 /* enter interrupt */
268 rt_interrupt_enter();
269
270 rt_hw_uart_isr(&(uart_drv[UART3_INDEX].serial_device));
271
272 /* leave interrupt */
273 rt_interrupt_leave();
274 }
275 #endif /* BSP_USING_UART3 */
276
rt_hw_uart_init(void)277 int rt_hw_uart_init(void)
278 {
279 struct serial_configure cfg = RT_SERIAL_CONFIG_DEFAULT;
280 int i = 0;
281 rt_err_t result = RT_EOK;
282
283 for (i = 0; i < sizeof(uart_cfg) / sizeof(uart_cfg[0]); i++)
284 {
285 uart_drv[i].cfg = &uart_cfg[i];
286 uart_drv[i].serial_device.ops = &_uart_ops;
287 uart_drv[i].serial_device.config = cfg;
288 /* register UART device */
289 result = rt_hw_serial_register(&uart_drv[i].serial_device, uart_drv[i].cfg->name,
290 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart_drv[i].cfg);
291 RT_ASSERT(result == RT_EOK);
292 }
293
294 return result;
295 }
296 INIT_BOARD_EXPORT(rt_hw_uart_init);
297
298 #endif /* BSP_USING_UART */
299 #endif /* RT_USING_SERIAL */
300