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-08-15 Jonas first version
9 */
10
11 #include <board.h>
12 #include "drv_usart.h"
13
14 #ifdef RT_USING_SERIAL
15 #if !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2)
16 #error "Please define at least one BSP_USING_UARTx"
17 /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
18 #endif
19
20 struct hk32_usart
21 {
22 char *name;
23 USART_TypeDef *usartx;
24 IRQn_Type irqn;
25 struct rt_serial_device serial;
26 };
27
28 enum
29 {
30 #ifdef BSP_USING_UART1
31 USART1_INDEX,
32 #endif
33 #ifdef BSP_USING_UART2
34 USART2_INDEX,
35 #endif
36 };
37
38 static struct hk32_usart usart_config[] =
39 {
40 #ifdef BSP_USING_UART1
41 {
42 "uart1",
43 USART1,
44 USART1_IRQn,
45 },
46 #endif
47 #ifdef BSP_USING_UART2
48 {
49 "uart2",
50 USART2,
51 USART2_IRQn,
52 },
53 #endif
54 };
55
hk32_configure(struct rt_serial_device * serial,struct serial_configure * cfg)56 static rt_err_t hk32_configure(struct rt_serial_device *serial,
57 struct serial_configure *cfg)
58 {
59 struct hk32_usart *usart_instance = (struct hk32_usart *) serial->parent.user_data;
60 USART_InitTypeDef USART_InitStructure;
61
62 RT_ASSERT(serial != RT_NULL);
63 RT_ASSERT(cfg != RT_NULL);
64
65 RT_ASSERT(usart_instance != RT_NULL);
66
67 hk32_msp_usart_init((void *)usart_instance->usartx);
68
69 USART_StructInit(&USART_InitStructure);
70
71 USART_DeInit(usart_instance->usartx);
72 USART_InitStructure.USART_BaudRate = cfg->baud_rate;
73 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
74 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
75
76 switch (cfg->data_bits)
77 {
78 case DATA_BITS_8:
79 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
80 break;
81
82 case DATA_BITS_9:
83 USART_InitStructure.USART_WordLength = USART_WordLength_9b;
84 break;
85 default:
86 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
87 break;
88 }
89
90 switch (cfg->stop_bits)
91 {
92 case STOP_BITS_1:
93 USART_InitStructure.USART_StopBits = USART_StopBits_1;
94 break;
95 case STOP_BITS_2:
96 USART_InitStructure.USART_StopBits = USART_StopBits_2;
97 break;
98 default:
99 USART_InitStructure.USART_StopBits = USART_StopBits_1;
100 break;
101 }
102
103 switch (cfg->parity)
104 {
105 case PARITY_NONE:
106 USART_InitStructure.USART_Parity = USART_Parity_No;
107 break;
108 case PARITY_ODD:
109 USART_InitStructure.USART_Parity = USART_Parity_Odd;
110 break;
111 case PARITY_EVEN:
112 USART_InitStructure.USART_Parity = USART_Parity_Even;
113 break;
114 default:
115 USART_InitStructure.USART_Parity = USART_Parity_No;
116 break;
117 }
118 USART_Init(usart_instance->usartx, &USART_InitStructure);
119 USART_Cmd(usart_instance->usartx, ENABLE);
120
121 return RT_EOK;
122 }
123
hk32_control(struct rt_serial_device * serial,int cmd,void * arg)124 static rt_err_t hk32_control(struct rt_serial_device *serial, int cmd,
125 void *arg)
126 {
127 struct hk32_usart *usart;
128
129 NVIC_InitTypeDef NVIC_InitStruct;
130
131 RT_ASSERT(serial != RT_NULL);
132 usart = (struct hk32_usart *) serial->parent.user_data;
133 RT_ASSERT(usart != RT_NULL);
134
135 NVIC_InitStruct.NVIC_IRQChannel = usart->irqn;
136 NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
137
138 switch (cmd)
139 {
140 case RT_DEVICE_CTRL_CLR_INT:
141 NVIC_InitStruct.NVIC_IRQChannelCmd = DISABLE;
142 NVIC_Init(&NVIC_InitStruct);
143 USART_ITConfig(usart->usartx, USART_IT_RXNE, DISABLE);
144 break;
145 case RT_DEVICE_CTRL_SET_INT:
146 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
147 NVIC_Init(&NVIC_InitStruct);
148 USART_ITConfig(usart->usartx, USART_IT_RXNE, ENABLE);
149 break;
150 }
151
152 return RT_EOK;
153 }
154
hk32_putc(struct rt_serial_device * serial,char ch)155 static int hk32_putc(struct rt_serial_device *serial, char ch)
156 {
157 struct hk32_usart *usart;
158
159 RT_ASSERT(serial != RT_NULL);
160 usart = (struct hk32_usart *) serial->parent.user_data;
161 RT_ASSERT(usart != RT_NULL);
162
163 USART_SendData(usart->usartx, (uint8_t) ch);
164 while (USART_GetFlagStatus(usart->usartx, USART_FLAG_TXE) == RESET);
165
166 return 1;
167 }
168
hk32_getc(struct rt_serial_device * serial)169 static int hk32_getc(struct rt_serial_device *serial)
170 {
171 int ch;
172 struct hk32_usart *usart;
173
174 RT_ASSERT(serial != RT_NULL);
175 usart = (struct hk32_usart *) serial->parent.user_data;
176 RT_ASSERT(usart != RT_NULL);
177
178 ch = -1;
179 if (RESET != USART_GetFlagStatus(usart->usartx, USART_FLAG_RXNE))
180 {
181 ch = USART_ReceiveData(usart->usartx) & 0xff;
182 }
183
184 return ch;
185 }
186
187 static const struct rt_uart_ops hk32_usart_ops =
188 {
189 hk32_configure,
190 hk32_control,
191 hk32_putc,
192 hk32_getc,
193 RT_NULL
194 };
195
usart_isr(struct rt_serial_device * serial)196 static void usart_isr(struct rt_serial_device *serial)
197 {
198 struct hk32_usart *usart_instance;
199
200 RT_ASSERT(serial != RT_NULL);
201
202 usart_instance = (struct hk32_usart *) serial->parent.user_data;
203 RT_ASSERT(usart_instance != RT_NULL);
204
205 if ((USART_GetITStatus(usart_instance->usartx, USART_IT_RXNE) != RESET) \
206 && (RESET != USART_GetFlagStatus(usart_instance->usartx, USART_FLAG_RXNE)))
207 {
208 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
209 USART_ClearITPendingBit(usart_instance->usartx, USART_IT_RXNE);
210 USART_ClearFlag(usart_instance->usartx, USART_FLAG_RXNE);
211 }
212 else
213 {
214 if (USART_GetFlagStatus(usart_instance->usartx, USART_FLAG_CTS) != RESET)
215 {
216 USART_ClearFlag(usart_instance->usartx, USART_FLAG_CTS);
217 }
218
219 if (USART_GetFlagStatus(usart_instance->usartx, USART_FLAG_TC) != RESET)
220 {
221 USART_ClearFlag(usart_instance->usartx, USART_FLAG_TC);
222 }
223 }
224 }
225
226 #ifdef BSP_USING_UART1
USART1_IRQHandler(void)227 void USART1_IRQHandler(void)
228 {
229 rt_interrupt_enter();
230
231 usart_isr(&usart_config[USART1_INDEX].serial);
232
233 rt_interrupt_leave();
234 }
235 #endif
236 #ifdef BSP_USING_UART2
USART2_IRQHandler(void)237 void USART2_IRQHandler(void)
238 {
239 rt_interrupt_enter();
240
241 usart_isr(&usart_config[USART2_INDEX].serial);
242
243 rt_interrupt_leave();
244 }
245 #endif
246
rt_hw_usart_init(void)247 int rt_hw_usart_init(void)
248 {
249 rt_size_t obj_num;
250 int index;
251
252 obj_num = sizeof(usart_config) / sizeof(struct hk32_usart);
253 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
254 rt_err_t result = 0;
255
256 for (index = 0; index < obj_num; index++)
257 {
258 usart_config[index].serial.ops = &hk32_usart_ops;
259 usart_config[index].serial.config = config;
260
261 /* register UART device */
262 result = rt_hw_serial_register(&usart_config[index].serial,
263 usart_config[index].name,
264 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX
265 | RT_DEVICE_FLAG_INT_TX, &usart_config[index]);
266 RT_ASSERT(result == RT_EOK);
267 }
268
269 return result;
270 }
271
272 INIT_BOARD_EXPORT(rt_hw_usart_init);
273
274 #endif /* BSP_USING_SERIAL */
275