1 /*
2 * Copyright (c) 2021 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-09-19 HPMICRO First version
9 *
10 */
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include <rtdbg.h>
14 #include "board.h"
15 #include "drv_uart.h"
16 #include "hpm_uart_drv.h"
17 #include "hpm_sysctl_drv.h"
18
19
20 #ifdef RT_USING_SERIAL
21
22 #define UART_ROOT_CLK_FREQ BOARD_APP_UART_SRC_FREQ
23
24 struct hpm_uart {
25 UART_Type *uart_base;
26 uint32_t irq_num;
27 struct rt_serial_device *serial;
28 char *device_name;
29 };
30
31
32 extern void init_uart_pins(UART_Type *ptr);
33 static void hpm_uart_isr(struct rt_serial_device *serial);
34 static rt_err_t hpm_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
35 static rt_err_t hpm_uart_control(struct rt_serial_device *serial, int cmd, void *arg);
36 static int hpm_uart_putc(struct rt_serial_device *serial, char ch);
37 static int hpm_uart_getc(struct rt_serial_device *serial);
38
39
40 #if defined(BSP_USING_UART0)
41 struct rt_serial_device serial0;
uart0_isr(void)42 void uart0_isr(void)
43 {
44 hpm_uart_isr(&serial0);
45 }
46 SDK_DECLARE_EXT_ISR_M(IRQn_UART0,uart0_isr)
47 #endif
48
49
50 #if defined(BSP_USING_UART1)
51 struct rt_serial_device serial1;
uart1_isr(void)52 void uart1_isr(void)
53 {
54 hpm_uart_isr(&serial1);
55 }
56 SDK_DECLARE_EXT_ISR_M(IRQn_UART1,uart1_isr)
57 #endif
58
59
60 #if defined(BSP_USING_UART2)
61 struct rt_serial_device serial2;
uart2_isr(void)62 void uart2_isr(void)
63 {
64 hpm_uart_isr(&serial2);
65 }
66 SDK_DECLARE_EXT_ISR_M(IRQn_UART2,uart2_isr)
67 #endif
68
69
70 #if defined(BSP_USING_UART3)
71 struct rt_serial_device serial3;
uart3_isr(void)72 void uart3_isr(void)
73 {
74 hpm_uart_isr(&serial3);
75 }
76 SDK_DECLARE_EXT_ISR_M(IRQn_UART3,uart3_isr)
77 #endif
78
79
80 #if defined(BSP_USING_UART4)
81 struct rt_serial_device serial4;
uart4_isr(void)82 void uart4_isr(void)
83 {
84 hpm_uart_isr(&serial4);
85 }
86 SDK_DECLARE_EXT_ISR_M(IRQn_UART4,uart4_isr)
87 #endif
88
89
90 #if defined(BSP_USING_UART5)
91 struct rt_serial_device serial5;
uart5_isr(void)92 void uart5_isr(void)
93 {
94 hpm_uart_isr(&serial5);
95 }
96 SDK_DECLARE_EXT_ISR_M(IRQn_UART5,uart5_isr)
97 #endif
98
99
100 #if defined(BSP_USING_UART6)
101 struct rt_serial_device serial6;
uart6_isr(void)102 void uart6_isr(void)
103 {
104 hpm_uart_isr(&serial6);
105 }
106 SDK_DECLARE_EXT_ISR_M(IRQn_UART6,uart6_isr)
107 #endif
108
109
110 #if defined(BSP_USING_UART7)
111 struct rt_serial_device serial7;
uart7_isr(void)112 void uart7_isr(void)
113 {
114 hpm_uart_isr(&serial7);
115 }
116 SDK_DECLARE_EXT_ISR_M(IRQn_UART7,uart7_isr)
117 #endif
118
119
120 #if defined(BSP_USING_UART8)
121 struct rt_serial_device serial8;
uart8_isr(void)122 void uart8_isr(void)
123 {
124 hpm_uart_isr(&serial8);
125 }
126 SDK_DECLARE_EXT_ISR_M(IRQn_UART8,uart8_isr)
127 #endif
128
129
130 #if defined(BSP_USING_UART9)
131 struct rt_serial_device serial9;
uart9_isr(void)132 void uart9_isr(void)
133 {
134 hpm_uart_isr(&serial9);
135 }
136 SDK_DECLARE_EXT_ISR_M(IRQn_UART9,uart9_isr)
137 #endif
138
139
140 #if defined(BSP_USING_UART10)
141 struct rt_serial_device serial10;
uart10_isr(void)142 void uart10_isr(void)
143 {
144 hpm_uart_isr(&serial10);
145 }
146 SDK_DECLARE_EXT_ISR_M(IRQn_UART10,uart10_isr)
147 #endif
148
149 #if defined(BSP_USING_UART11)
150 struct rt_serial_device serial11;
uart11_isr(void)151 void uart11_isr(void)
152 {
153 hpm_uart_isr(&serial11);
154 }
155 SDK_DECLARE_EXT_ISR_M(IRQn_UART11,uart11_isr)
156 #endif
157
158 #if defined(BSP_USING_UART12)
159 struct rt_serial_device serial12;
uart12_isr(void)160 void uart12_isr(void)
161 {
162 hpm_uart_isr(&serial12);
163 }
164 SDK_DECLARE_EXT_ISR_M(IRQn_UART12,uart12_isr)
165 #endif
166
167 #if defined(BSP_USING_UART13)
168 struct rt_serial_device serial13;
uart13_isr(void)169 void uart13_isr(void)
170 {
171 hpm_uart_isr(&serial13);
172 }
173 SDK_DECLARE_EXT_ISR_M(IRQn_UART13,uart13_isr)
174 #endif
175
176 #if defined(BSP_USING_UART14)
177 struct rt_serial_device serial14;
uart14_isr(void)178 void uart14_isr(void)
179 {
180 hpm_uart_isr(&serial14);
181 }
182 SDK_DECLARE_EXT_ISR_M(IRQn_UART14,uart14_isr)
183 #endif
184
185 #if defined(BSP_USING_UART15)
186 struct rt_serial_device serial15;
uart15_isr(void)187 void uart15_isr(void)
188 {
189 hpm_uart_isr(&serial15);
190 }
191 SDK_DECLARE_EXT_ISR_M(IRQn_UART15,uart15_isr)
192 #endif
193
194 static const struct hpm_uart uarts[] = {
195 #if defined(BSP_USING_UART0)
196 {
197 HPM_UART0,
198 IRQn_UART0,
199 &serial0,
200 "uart0",
201 },
202 #endif
203
204 #if defined(BSP_USING_UART1)
205 {
206 HPM_UART1,
207 IRQn_UART1,
208 &serial1,
209 "uart1",
210 },
211 #endif
212
213 #if defined(BSP_USING_UART2)
214 {
215 HPM_UART2,
216 IRQn_UART2,
217 &serial2,
218 "uart2",
219 },
220 #endif
221
222 #if defined(BSP_USING_UART3)
223 {
224 HPM_UART3,
225 IRQn_UART3,
226 &serial3,
227 "uart3",
228 },
229 #endif
230
231 #if defined(BSP_USING_UART4)
232 {
233 HPM_UART4,
234 IRQn_UART4,
235 &serial4,
236 "uart4",
237 },
238 #endif
239
240 #if defined(BSP_USING_UART5)
241 {
242 HPM_UART5,
243 IRQn_UART5,
244 &serial5,
245 "uart5",
246 },
247 #endif
248
249 #if defined(BSP_USING_UART6)
250 {
251 HPM_UART6,
252 IRQn_UART6,
253 &serial6,
254 "uart6",
255 },
256 #endif
257
258 #if defined(BSP_USING_UART7)
259 {
260 HPM_UART7,
261 IRQn_UART7,
262 &serial7,
263 "uart7",
264 },
265 #endif
266
267 #if defined(BSP_USING_UART8)
268 {
269 HPM_UART8,
270 IRQn_UART8,
271 &serial8,
272 "uart8",
273 },
274 #endif
275
276 #if defined(BSP_USING_UART9)
277 {
278 HPM_UART9,
279 IRQn_UART9,
280 &serial9,
281 "uart9",
282 },
283 #endif
284
285 #if defined(BSP_USING_UART10)
286 {
287 HPM_UART10,
288 IRQn_UART10,
289 &serial10,
290 "uart10",
291 },
292 #endif
293
294 #if defined(BSP_USING_UART11)
295 {
296 HPM_UART11,
297 IRQn_UART11,
298 &serial11,
299 "uart11",
300 },
301 #endif
302
303 #if defined(BSP_USING_UART12)
304 {
305 HPM_UART12,
306 IRQn_UART12,
307 &serial12,
308 "uart12",
309 },
310 #endif
311
312 #if defined(BSP_USING_UART13)
313 {
314 HPM_UART13,
315 IRQn_UART13,
316 &serial13,
317 "uart13",
318 },
319 #endif
320
321 #if defined(BSP_USING_UART14)
322 {
323 HPM_UART14,
324 IRQn_UART14,
325 &serial14,
326 "uart14",
327 },
328 #endif
329
330 #if defined(BSP_USING_UART15)
331 {
332 HPM_UART15,
333 IRQn_UART15,
334 &serial15,
335 "uart15",
336 },
337 #endif
338
339 };
340
341 /**
342 * @brief UART common interrupt process. This
343 *
344 * @param serial Serial device
345 */
hpm_uart_isr(struct rt_serial_device * serial)346 static void hpm_uart_isr(struct rt_serial_device *serial)
347 {
348 struct hpm_uart *uart;
349
350 RT_ASSERT(serial != RT_NULL);
351
352 uart = (struct hpm_uart *)serial->parent.user_data;
353 RT_ASSERT(uart != RT_NULL);
354 /* UART in mode Receiver */
355 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
356 }
357
358
hpm_uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)359 static rt_err_t hpm_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
360 {
361
362 RT_ASSERT(serial != RT_NULL);
363 RT_ASSERT(cfg != RT_NULL);
364
365 uart_config_t uart_config;
366 struct hpm_uart *uart = (struct hpm_uart *)serial->parent.user_data;
367
368 init_uart_pins(uart->uart_base);
369 uart_default_config(uart->uart_base, &uart_config);
370
371 uart_config.src_freq_in_hz = board_init_uart_clock(uart->uart_base);
372 uart_config.baudrate = cfg->baud_rate;
373 uart_config.num_of_stop_bits = cfg->stop_bits;
374 uart_config.parity = cfg->parity;
375
376 uart_config.word_length = cfg->data_bits - DATA_BITS_5;
377
378 board_init_uart(uart->uart_base);
379 uart_init(uart->uart_base, &uart_config);
380
381 hpm_uart_control(serial, RT_DEVICE_CTRL_SET_INT, NULL);
382 }
383
384
hpm_uart_control(struct rt_serial_device * serial,int cmd,void * arg)385 static rt_err_t hpm_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
386 {
387 RT_ASSERT(serial != RT_NULL);
388
389 struct hpm_uart *uart = (struct hpm_uart *)serial->parent.user_data;
390
391 switch (cmd) {
392 case RT_DEVICE_CTRL_CLR_INT:
393 /* disable rx irq */
394 uart_disable_irq(uart->uart_base, uart_intr_rx_data_avail_or_timeout);
395 intc_m_disable_irq(uart->irq_num);
396 break;
397
398 case RT_DEVICE_CTRL_SET_INT:
399 /* enable rx irq */
400 uart_enable_irq(uart->uart_base, uart_intr_rx_data_avail_or_timeout);
401 intc_m_enable_irq_with_priority(uart->irq_num, 1);
402 break;
403 }
404
405 return RT_EOK;
406 }
407
408
hpm_uart_putc(struct rt_serial_device * serial,char ch)409 static int hpm_uart_putc(struct rt_serial_device *serial, char ch)
410 {
411 struct hpm_uart *uart = (struct hpm_uart *)serial->parent.user_data;
412 uart_write_byte(uart->uart_base, ch);
413 while(!uart_check_status(uart->uart_base, uart_stat_transmitter_empty)) {
414 }
415 }
416
hpm_uart_getc(struct rt_serial_device * serial)417 static int hpm_uart_getc(struct rt_serial_device *serial)
418 {
419 int result = -1;
420 struct hpm_uart *uart = (struct hpm_uart *)serial->parent.user_data;
421
422 if (uart_check_status(uart->uart_base, uart_stat_data_ready)) {
423 uart_receive_byte(uart->uart_base, (uint8_t*)&result);
424 }
425
426 return result;
427 }
428
429
430 static const struct rt_uart_ops hpm_uart_ops = {
431 hpm_uart_configure,
432 hpm_uart_control,
433 hpm_uart_putc,
434 hpm_uart_getc,
435 };
436
437
438
rt_hw_uart_init(void)439 int rt_hw_uart_init(void)
440 {
441
442 /* Added bypass logic here since the rt_hw_uart_init function will be initialized twice, the 2nd initialization should be bypassed */
443 static bool initialized;
444 rt_err_t err = RT_EOK;
445 if (initialized)
446 {
447 return err;
448 }
449 else
450 {
451 initialized = true;
452 }
453 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
454
455 for (uint32_t i = 0; i < sizeof(uarts) / sizeof(uarts[0]); i++) {
456 uarts[i].serial->ops = &hpm_uart_ops;
457 uarts[i].serial->config = config;
458
459 /* register UART deivce */
460 err = rt_hw_serial_register(uarts[i].serial,
461 uarts[i].device_name,
462 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
463 (void*)&uarts[i]);
464 }
465
466 return err;
467 }
468
469 INIT_BOARD_EXPORT(rt_hw_uart_init);
470
471 #endif /* RT_USING_SERIAL */
472