1 /*
2 * Copyright (c) 2006-2018, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * first version
9 */
10 // 串口相关源码
11
12 #include <stdio.h>
13 #include <stdarg.h>
14 #include "ls1c_public.h"
15 #include "ls1c_regs.h"
16 #include "ls1c_pin.h"
17 #include "ls1c_uart.h"
18 #include "ls1c_clock.h"
19 #include "ls1c.h"
20
21
22 // 串口线路状态寄存器的位域
23 #define LS1C_UART_LSR_TE (1 << 6)
24 #define LS1C_UART_LSR_TFE (1 << 5)
25
26
27 // 打印缓存的大小
28 #define LS1C_UART_PRINT_BUF_SIZE (256)
29
30
31 // 调试串口信息
32 ls1c_uart_info_t debug_uart_info = {0};
33
34
35 /*
36 * 获取指定串口模块的基地址
37 * @UARTx 串口编号
38 * @ret 基地址
39 */
uart_get_base(ls1c_uart_t UARTx)40 void *uart_get_base(ls1c_uart_t UARTx)
41 {
42 void *base = NULL;
43
44 switch (UARTx)
45 {
46 case LS1C_UART00:
47 base = (void *)LS1C_UART00_BASE;
48 break;
49 case LS1C_UART01:
50 base = (void *)LS1C_UART01_BASE;
51 break;
52
53 case LS1C_UART1:
54 base = (void *)LS1C_UART1_BASE;
55 break;
56
57 case LS1C_UART2:
58 base = (void *)LS1C_UART2_BASE;
59 break;
60
61 case LS1C_UART3:
62 base = (void *)LS1C_UART3_BASE;
63 break;
64
65 case LS1C_UART4:
66 base = (void *)LS1C_UART4_BASE;
67 break;
68
69 case LS1C_UART5:
70 base = (void *)LS1C_UART5_BASE;
71 break;
72
73 case LS1C_UART6:
74 base = (void *)LS1C_UART6_BASE;
75 break;
76
77 case LS1C_UART7:
78 base = (void *)LS1C_UART7_BASE;
79 break;
80
81 case LS1C_UART8:
82 base = (void *)LS1C_UART8_BASE;
83 break;
84
85 case LS1C_UART9:
86 base = (void *)LS1C_UART9_BASE;
87 break;
88
89 case LS1C_UART10:
90 base = (void *)LS1C_UART10_BASE;
91 break;
92
93 case LS1C_UART11:
94 base = (void *)LS1C_UART11_BASE;
95 break;
96
97 default:
98 break;
99 }
100
101 return base;
102 }
103
104
105 /*
106 * 初始化指定的串口模块
107 * @uart_info_p 串口模块信息
108 */
uart_init(ls1c_uart_info_t * uart_info_p)109 void uart_init(ls1c_uart_info_t *uart_info_p)
110 {
111 void *uart_base = uart_get_base(uart_info_p->UARTx);
112 unsigned long baudrate_div = 0;
113
114 // 禁止所有中断
115 reg_write_8(0, uart_base + LS1C_UART_IER_OFFSET);
116
117 // 接收FIFO的中断申请Trigger为14字节,清空发送和接收FIFO,并复位
118 reg_write_8(0xc3, uart_base + LS1C_UART_FCR_OFFSET);
119
120 // 设置波特率
121 reg_write_8(0x80, uart_base + LS1C_UART_LCR_OFFSET);
122 baudrate_div = clk_get_cpu_rate() / 16 / uart_info_p->baudrate / 2;
123 reg_write_8((baudrate_div >> 8) & 0xff, uart_base + LS1C_UART_MSB_OFFSET);
124 reg_write_8(baudrate_div & 0xff, uart_base + LS1C_UART_LSB_OFFSET);
125
126 // 8个数据位,1个停止位,无校验
127 reg_write_8(0x03, uart_base + LS1C_UART_LCR_OFFSET);
128
129 // 使能接收中断
130 if (TRUE == uart_info_p->rx_enable)
131 {
132 reg_write_8(IER_IRxE|IER_ILE , uart_base + LS1C_UART_IER_OFFSET);
133 }
134
135 return ;
136 }
137
138
139 /*
140 * 判断FIFO是否为空
141 * @uartx 串口号
142 * @ret TRUE or FALSE
143 */
uart_is_transmit_empty(ls1c_uart_t uartx)144 BOOL uart_is_transmit_empty(ls1c_uart_t uartx)
145 {
146 void *uart_base = uart_get_base(uartx);
147 unsigned char status = reg_read_8(uart_base + LS1C_UART_LSR_OFFSET);
148
149 if (status & (LS1C_UART_LSR_TE | LS1C_UART_LSR_TFE))
150 {
151 return TRUE;
152 }
153 else
154 {
155 return FALSE;
156 }
157 }
158
159
160 /*
161 * 发送一个字节
162 * @uartx 串口号
163 * @ch 待发送的字符串
164 */
uart_putc(ls1c_uart_t uartx,unsigned char ch)165 void uart_putc(ls1c_uart_t uartx, unsigned char ch)
166 {
167 void *uart_base = uart_get_base(uartx);
168
169 // 等待
170 while (FALSE == uart_is_transmit_empty(uartx))
171 ;
172
173 // 发送
174 reg_write_8(ch, uart_base + LS1C_UART_DAT_OFFSET);
175
176 return ;
177 }
178
179
180 /*
181 * 打印一个字符串到指定串口
182 * @uartx 串口号
183 * @str 待打印的字符串
184 */
uart_print(ls1c_uart_t uartx,const char * str)185 void uart_print(ls1c_uart_t uartx, const char *str)
186 {
187 while ('\0' != *str) // 判断是否为字符串结束符
188 {
189 uart_putc(uartx, *str); // 发送一个字符
190 str++;
191 }
192
193 return ;
194 }
195
196
197 /*
198 * 初始化串口2
199 */
uart2_init(void)200 void uart2_init(void)
201 {
202 unsigned int tx_gpio = 37;
203 unsigned int rx_gpio = 36;
204
205 // 设置复用
206 pin_set_remap(tx_gpio, PIN_REMAP_SECOND);
207 pin_set_remap(rx_gpio, PIN_REMAP_SECOND);
208
209 // 初始化相关寄存器
210 debug_uart_info.UARTx = LS1C_UART2;
211 debug_uart_info.baudrate = 115200;
212 debug_uart_info.rx_enable = FALSE; // 调试串口只需要打印(发送)功能,不需要接收功能
213 uart_init(&debug_uart_info);
214
215 return ;
216 }
217
218
219 /*
220 * 在串口2上打印字符串
221 * @str 待打印的字符串
222 */
uart2_print(const char * str)223 void uart2_print(const char *str)
224 {
225 uart_print(LS1C_UART2, str);
226 return ;
227 }
228
229
230 /*
231 * 在调试串口打印字符串
232 * @str 待打印的字符串
233 */
uart_debug_print(const char * str)234 void uart_debug_print(const char *str)
235 {
236 uart_print(debug_uart_info.UARTx, str);
237 return ;
238 }
239
240
241 /*
242 * 在调试串口打印一个字符
243 * @ch 待打印的字符
244 */
uart_debug_putc(unsigned char ch)245 void uart_debug_putc(unsigned char ch)
246 {
247 uart_putc(debug_uart_info.UARTx, ch);
248 return ;
249 }
250
251
252 /*
253 * 把中断号转换为串口号
254 * @IRQn 中断号
255 * @ret 串口号
256 */
uart_irqn_to_uartx(int IRQn)257 ls1c_uart_t uart_irqn_to_uartx(int IRQn)
258 {
259 ls1c_uart_t uartx = LS1C_UART2;
260
261 switch (IRQn)
262 {
263 /* 串口UART00和UART01的中断号还待确定
264 case LS1C_UART00_IRQ:
265 uartx = LS1C_UART00;
266 break;
267
268 case LS1C_UART01_IRQ:
269 uartx = LS1C_UART01;
270 break;
271 */
272
273 case LS1C_UART1_IRQ:
274 uartx = LS1C_UART1;
275 break;
276
277 case LS1C_UART2_IRQ:
278 uartx = LS1C_UART2;
279 break;
280
281 case LS1C_UART3_IRQ:
282 uartx = LS1C_UART3;
283 break;
284
285 case LS1C_UART4_IRQ:
286 uartx = LS1C_UART4;
287 break;
288
289 case LS1C_UART5_IRQ:
290 uartx = LS1C_UART5;
291 break;
292
293 case LS1C_UART6_IRQ:
294 uartx = LS1C_UART6;
295 break;
296
297 case LS1C_UART7_IRQ:
298 uartx = LS1C_UART7;
299 break;
300
301 case LS1C_UART8_IRQ:
302 uartx = LS1C_UART8;
303 break;
304
305 case LS1C_UART9_IRQ:
306 uartx = LS1C_UART9;
307 break;
308
309 case LS1C_UART10_IRQ:
310 uartx = LS1C_UART10;
311 break;
312
313 case LS1C_UART11_IRQ:
314 uartx = LS1C_UART11;
315 break;
316
317 default:
318 uartx = LS1C_UART2;
319 break;
320 }
321
322 return uartx;
323 }
324
325
326