1 /*
2 * Copyright (c) 2006-2024, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2024-04-08 QT-one first version
9 */
10
11 #include "drv_usart.h"
12
13 #ifdef RT_USING_SERIAL
14 #if !defined(BSP_USING_USART0) && !defined(BSP_USING_USART1) && \
15 !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && \
16 !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3)
17 #error "Please define at least one BSP_USING_UARTx"
18 #endif
19
20 struct ht32_usart
21 {
22 char *name;
23 HT_USART_TypeDef *usart_x;
24 IRQn_Type irq;
25 struct rt_serial_device serial;
26 };
27
28 enum
29 {
30 #ifdef BSP_USING_USART0
31 USART0_INDEX,
32 #endif
33 #ifdef BSP_USING_USART1
34 USART1_INDEX,
35 #endif
36 #ifdef BSP_USING_UART0
37 UART0_INDEX,
38 #endif
39 #ifdef BSP_USING_UART1
40 UART1_INDEX,
41 #endif
42 #ifdef BSP_USING_UART2
43 UART2_INDEX,
44 #endif
45 #ifdef BSP_USING_UART3
46 UART3_INDEX,
47 #endif
48
49 };
50
51 static struct ht32_usart usart_config[] =
52 {
53 #ifdef BSP_USING_USART0
54 {
55 .name = BSP_USING_USART0_NAME,
56 .usart_x = HT_USART0,
57 .irq = USART0_IRQn,
58 .serial = RT_NULL
59 },
60 #endif
61 #ifdef BSP_USING_USART1
62 {
63 .name = BSP_USING_USART1_NAME,
64 .usart_x = HT_USART1,
65 .irq = USART1_IRQn,
66 .serial = RT_NULL
67 },
68 #endif
69 #ifdef BSP_USING_UART0
70 {
71 .name = BSP_USING_UART0_NAME,
72 .usart_x = HT_UART0,
73 .irq = UART0_IRQn,
74 .serial = RT_NULL
75 },
76 #endif
77 #ifdef BSP_USING_UART1
78 {
79 .name = BSP_USING_UART1_NAME,
80 .usart_x = HT_UART1,
81 .irq = UART1_IRQn,
82 .serial = RT_NULL
83 },
84 #endif
85 #ifdef BSP_USING_UART2
86 {
87 .name = BSP_USING_UART2_NAME,
88 .usart_x = HT_UART2,
89 .irq = UART0_UART2_IRQn,
90 .serial = RT_NULL
91 },
92 #endif
93 #ifdef BSP_USING_UART3
94 {
95 .name = BSP_USING_UART3_NAME,
96 .usart_x = HT_UART3,
97 .irq = UART1_UART3_IRQn,
98 .serial = RT_NULL
99 },
100 #endif
101 };
102
ht32_configure(struct rt_serial_device * serial,struct serial_configure * cfg)103 static rt_err_t ht32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
104 {
105
106 CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
107 USART_InitTypeDef USART_InitStructure = {0};
108
109 struct ht32_usart *usart_instance = (struct ht32_usart *)serial->parent.user_data;
110
111 RT_ASSERT(serial != RT_NULL);
112 RT_ASSERT(cfg != RT_NULL);
113
114 CKCUClock.Bit.AFIO = 1;
115
116 if ((usart_instance->usart_x) == HT_UART0)
117 CKCUClock.Bit.UART0 = 1;
118 #if defined(HT_USART0)
119 else if ((usart_instance->usart_x) == HT_USART0)
120 CKCUClock.Bit.USART0 = 1;
121 #endif
122 #if defined(HT_USART1)
123 else if ((usart_instance->usart_x) == HT_USART1)
124 CKCUClock.Bit.USART1 = 1;
125 #endif
126 #if defined(HT_UART1)
127 else if ((usart_instance->usart_x) == HT_UART1)
128 CKCUClock.Bit.UART1 = 1;
129 #endif
130 #if defined(HT_UART2)
131 else if ((usart_instance->usart_x) == HT_UART2)
132 CKCUClock.Bit.UART2 = 1;
133 #endif
134 #if defined(HT_UART3)
135 else if ((usart_instance->usart_x) == HT_UART3)
136 CKCUClock.Bit.UART3 = 1;
137 #endif
138 CKCU_PeripClockConfig(CKCUClock, ENABLE);
139
140 /* UART gpio init */
141 ht32_usart_gpio_init((void *)usart_instance->usart_x);
142
143 /* baud rate */
144 USART_InitStructure.USART_BaudRate = (cfg->baud_rate);
145
146 /* data width */
147 switch (cfg->data_bits)
148 {
149 case DATA_BITS_7:
150 USART_InitStructure.USART_WordLength = USART_WORDLENGTH_7B;
151 break;
152 case DATA_BITS_8:
153 USART_InitStructure.USART_WordLength = USART_WORDLENGTH_8B;
154 break;
155 case DATA_BITS_9:
156 USART_InitStructure.USART_WordLength = USART_WORDLENGTH_9B;
157 break;
158 default:
159 USART_InitStructure.USART_WordLength = USART_WORDLENGTH_8B;
160 break;
161 }
162
163 /* stop bit */
164 switch (cfg->stop_bits)
165 {
166 case STOP_BITS_1:
167 USART_InitStructure.USART_StopBits = USART_STOPBITS_1;
168 break;
169 case STOP_BITS_2:
170 USART_InitStructure.USART_StopBits = USART_STOPBITS_2;
171 break;
172 default:
173 USART_InitStructure.USART_StopBits = USART_STOPBITS_1;
174 break;
175 }
176
177 switch (cfg->parity)
178 {
179 case PARITY_NONE:
180 USART_InitStructure.USART_Parity = USART_PARITY_NO;
181 break;
182 case PARITY_ODD:
183 USART_InitStructure.USART_Parity = USART_PARITY_ODD;
184 break;
185 case PARITY_EVEN:
186 USART_InitStructure.USART_Parity = USART_PARITY_EVEN;
187 break;
188 default:
189 USART_InitStructure.USART_Parity = USART_PARITY_NO;
190 break;
191 }
192
193 /* UART mode */
194 USART_InitStructure.USART_Mode = USART_MODE_NORMAL;
195 /* UART init */
196 USART_Init((usart_instance->usart_x), &USART_InitStructure);
197 /*UART enable */
198 USART_TxCmd((usart_instance->usart_x), ENABLE);
199 USART_RxCmd((usart_instance->usart_x), ENABLE);
200
201 return RT_EOK;
202 }
203
ht32_control(struct rt_serial_device * serial,int cmd,void * arg)204 static rt_err_t ht32_control(struct rt_serial_device *serial, int cmd, void *arg)
205 {
206 struct ht32_usart *usart;
207
208 RT_ASSERT(serial != RT_NULL);
209 usart = (struct ht32_usart *) serial->parent.user_data;
210 RT_ASSERT(usart != RT_NULL);
211
212 switch (cmd)
213 {
214 case RT_DEVICE_CTRL_CLR_INT:
215 NVIC_DisableIRQ(usart->irq);
216 USART_IntConfig(usart->usart_x, USART_INT_RXDR, DISABLE);
217 break;
218 case RT_DEVICE_CTRL_SET_INT:
219 NVIC_EnableIRQ(usart->irq);
220 USART_IntConfig(usart->usart_x, USART_INT_RXDR, ENABLE);
221 break;
222 }
223 return RT_EOK;
224 }
225
ht32_putc(struct rt_serial_device * serial,char c)226 static int ht32_putc(struct rt_serial_device *serial, char c)
227 {
228 struct ht32_usart *usart;
229
230 RT_ASSERT(serial != RT_NULL);
231 usart = (struct ht32_usart *) serial->parent.user_data;
232 RT_ASSERT(usart != RT_NULL);
233
234 while ((usart->usart_x->SR & USART_FLAG_TXC) == 0);
235 usart->usart_x->DR = (u8)c;
236
237 return 1;
238 }
239
ht32_getc(struct rt_serial_device * serial)240 static int ht32_getc(struct rt_serial_device *serial)
241 {
242 int ch;
243 struct ht32_usart *usart;
244
245 RT_ASSERT(serial != RT_NULL);
246 usart = (struct ht32_usart *) serial->parent.user_data;
247 RT_ASSERT(usart != RT_NULL);
248
249 ch = -1;
250 if (USART_GetFlagStatus(usart->usart_x, USART_FLAG_RXDR) != RESET)
251 {
252 ch = USART_ReceiveData(usart->usart_x);
253 }
254 return ch;
255 }
256
ht32_dma_transmit(struct rt_serial_device * serial,rt_uint8_t * buf,rt_size_t size,int direction)257 static rt_ssize_t ht32_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
258 {
259 return -RT_ERROR;
260 }
261
262 static const struct rt_uart_ops ht32_usart_ops =
263 {
264 .configure = ht32_configure,
265 .control = ht32_control,
266 .putc = ht32_putc,
267 .getc = ht32_getc,
268 .dma_transmit = ht32_dma_transmit,
269 };
270
rt_hw_usart_init(void)271 int rt_hw_usart_init(void)
272 {
273 rt_size_t obj_num;
274 int index;
275
276 obj_num = sizeof(usart_config) / sizeof(struct ht32_usart);
277 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
278 rt_err_t result = 0;
279
280 for (index = 0; index < obj_num; index++)
281 {
282 usart_config[index].serial.ops = &ht32_usart_ops;
283 usart_config[index].serial.config = config;
284
285 /* register uart device */
286 result = rt_hw_serial_register(&usart_config[index].serial,
287 usart_config[index].name,
288 RT_DEVICE_FLAG_RDWR |
289 RT_DEVICE_FLAG_INT_RX |
290 RT_DEVICE_FLAG_INT_TX,
291 &usart_config[index]);
292 RT_ASSERT(result == RT_EOK);
293 }
294
295 return result;
296 }
297 INIT_BOARD_EXPORT(rt_hw_usart_init);
298
usart_isr(struct rt_serial_device * serial)299 static void usart_isr(struct rt_serial_device *serial)
300 {
301
302 struct ht32_usart *usart = (struct ht32_usart *)serial->parent.user_data;
303 RT_ASSERT(usart != RT_NULL);
304
305 if ((USART_GetFlagStatus(usart->usart_x, USART_FLAG_RXDR) != RESET) && ((usart->usart_x->IER & USART_INT_RXDR) != RESET))
306 {
307 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
308 }
309 }
310
311 #ifdef BSP_USING_USART0
USART0_IRQHandler(void)312 void USART0_IRQHandler(void)
313 {
314 /* enter interrupt */
315 rt_interrupt_enter();
316 usart_isr(&usart_config[USART0_INDEX].serial);
317 /* leave interrupt */
318 rt_interrupt_leave();
319 }
320 #endif
321 #ifdef BSP_USING_USART1
USART1_IRQHandler(void)322 void USART1_IRQHandler(void)
323 {
324 /* enter interrupt */
325 rt_interrupt_enter();
326 usart_isr(&usart_config[USART1_INDEX].serial);
327 /* leave interrupt */
328 rt_interrupt_leave();
329 }
330 #endif
331 #ifdef BSP_USING_UART0
UART0_IRQHandler(void)332 void UART0_IRQHandler(void)
333 {
334 /* enter interrupt */
335 rt_interrupt_enter();
336 usart_isr(&usart_config[UART0_INDEX].serial);
337 /* leave interrupt */
338 rt_interrupt_leave();
339 }
340 #endif
341 #ifdef BSP_USING_UART1
UART1_IRQHandler(void)342 void UART1_IRQHandler(void)
343 {
344 /* enter interrupt */
345 rt_interrupt_enter();
346 usart_isr(&usart_config[UART1_INDEX].serial);
347 /* leave interrupt */
348 rt_interrupt_leave();
349 }
350 #endif
351 #ifdef BSP_USING_UART2
UART2_IRQHandler(void)352 void UART2_IRQHandler(void)
353 {
354 /* enter interrupt */
355 rt_interrupt_enter();
356 usart_isr(&usart_config[UART2_INDEX].serial);
357 /* leave interrupt */
358 rt_interrupt_leave();
359 }
360 #endif
361 #ifdef BSP_USING_UART3
UART3_IRQHandler(void)362 void UART3_IRQHandler(void)
363 {
364 /* enter interrupt */
365 rt_interrupt_enter();
366 usart_isr(&usart_config[UART3_INDEX].serial);
367 /* leave interrupt */
368 rt_interrupt_leave();
369 }
370 #endif
371
372 #endif /* RT_USING_SERIAL */
373