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