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