1 /*
2 * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 * http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2009-12-22
13 * Description: UniProton hi3093 demo
14 */
15 #include "serial.h"
16 #include "securec.h"
17 #include "common.h"
18
19 serial_t g_sys_serial;
20 #define HW_UART_NO (g_sys_serial.cfg.hw_uart_no)
21 #define UART_CLK (PERI_APB_FREQ)
22 #define EAGAIN 11
23
serial_soft_init(serial_cfg * cfg,uart_ops * hw_ops)24 void serial_soft_init(serial_cfg *cfg, uart_ops *hw_ops)
25 {
26 if (!cfg || !hw_ops) {
27 return;
28 }
29
30 g_sys_serial.cfg.init_done = 0;
31 g_sys_serial.cfg.hw_uart_no = SERIAL_SEL_UART_PORT;
32 g_sys_serial.cfg.uart_src_clk = UART_CLK;
33 strncpy_s(g_sys_serial.cfg.name, SERIAL_NAME_SIZE, cfg->name, SERIAL_NAME_SIZE - 1);
34 g_sys_serial.cfg.data_bits = cfg->data_bits;
35 g_sys_serial.cfg.stop = cfg->stop;
36 g_sys_serial.cfg.pen = cfg->pen;
37 g_sys_serial.cfg.eps = cfg->eps;
38 g_sys_serial.cfg.baud_rate = cfg->baud_rate;
39 g_sys_serial.hw_ops = hw_ops;
40
41 g_sys_serial.cfg.init_done = 1;
42
43 return;
44 }
45
serial_init(serial_cfg * cfg,uart_ops * hw_ops)46 void serial_init(serial_cfg *cfg, uart_ops *hw_ops)
47 {
48 if (!cfg || !hw_ops) {
49 return;
50 }
51
52 serial_soft_init(cfg, hw_ops);
53
54 g_sys_serial.cfg.init_done = 0;
55
56 if (g_sys_serial.hw_ops->init(&g_sys_serial.cfg)) {
57 return;
58 }
59
60 g_sys_serial.cfg.init_done = 1;
61
62 return;
63 }
64
serial_putc(const char ch)65 void serial_putc(const char ch)
66 {
67 uart_ops *hw_ops = g_sys_serial.hw_ops;
68
69 if (g_sys_serial.cfg.init_done) {
70 if (ch == '\n') {
71 hw_ops->put_char(HW_UART_NO, '\r');
72 }
73 hw_ops->put_char(HW_UART_NO, ch);
74 }
75
76 return;
77 }
78
serial_getc(void)79 S32 serial_getc(void)
80 {
81 uart_ops *hw_ops = g_sys_serial.hw_ops;
82
83 if (g_sys_serial.cfg.init_done) {
84 if (!hw_ops->rx_ready(HW_UART_NO)) {
85 return -EAGAIN;
86 }
87
88 return hw_ops->get_char(HW_UART_NO);
89 }
90
91 return -EAGAIN;
92 }
93
serial_puts(const char * s)94 void serial_puts(const char *s)
95 {
96 if (!g_sys_serial.cfg.init_done) {
97 return;
98 }
99
100 while (*s) {
101 serial_putc(*s++);
102 }
103
104 return;
105 }
106
serial_tstc(void)107 S32 serial_tstc(void)
108 {
109 uart_ops *hw_ops = NULL;
110
111 if (!g_sys_serial.cfg.init_done) {
112 return OS_OK;
113 }
114
115 hw_ops = g_sys_serial.hw_ops;
116
117 return (S32)hw_ops->rx_ready(HW_UART_NO);
118 }
119
serial_flush(void)120 void serial_flush(void)
121 {
122 uart_ops *hw_ops = g_sys_serial.hw_ops;
123
124 if (!g_sys_serial.cfg.init_done) {
125 return;
126 }
127
128 /* just flush, don't care fail */
129 (void)hw_ops->wait4idle(g_sys_serial.cfg.hw_uart_no, SERIAL_FLUSH_TMOUT);
130 }
131