1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
|
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-02-02 [email protected] adapt to ls1b
*/
// 串口相关源码
#include <stdio.h>
#include <stdarg.h>
#include "ls1b_public.h"
#include "ls1b_regs.h"
#include "ls1b_pin.h"
#include "ls1b_uart.h"
#include "ls1b_clock.h"
#include "ls1b.h"
// 串口线路状态寄存器的位域
#define LS1B_UART_LSR_TE (1 << 6)
#define LS1B_UART_LSR_TFE (1 << 5)
// 打印缓存的大小
#define LS1B_UART_PRINT_BUF_SIZE (256)
// 调试串口信息
ls1b_uart_info_t debug_uart_info = {0};
/*
* 获取指定串口模块的基地址
* @UARTx 串口编号
* @ret 基地址
*/
void *uart_get_base(ls1b_uart_t UARTx)
{
void *base = NULL;
switch (UARTx)
{
case LS1B_UART00:
base = (void *)LS1B_UART00_BASE;
break;
case LS1B_UART01:
base = (void *)LS1B_UART01_BASE;
break;
case LS1B_UART1:
base = (void *)LS1B_UART1_BASE;
break;
case LS1B_UART2:
base = (void *)LS1B_UART2_BASE;
break;
case LS1B_UART3:
base = (void *)LS1B_UART3_BASE;
break;
case LS1B_UART4:
base = (void *)LS1B_UART4_BASE;
break;
case LS1B_UART5:
base = (void *)LS1B_UART5_BASE;
break;
case LS1B_UART6:
base = (void *)LS1B_UART6_BASE;
break;
case LS1B_UART7:
base = (void *)LS1B_UART7_BASE;
break;
case LS1B_UART8:
base = (void *)LS1B_UART8_BASE;
break;
case LS1B_UART9:
base = (void *)LS1B_UART9_BASE;
break;
case LS1B_UART10:
base = (void *)LS1B_UART10_BASE;
break;
case LS1B_UART11:
base = (void *)LS1B_UART11_BASE;
break;
default:
break;
}
return base;
}
/*
* 初始化指定的串口模块
* @uart_info_p 串口模块信息
*/
void uart_init(ls1b_uart_info_t *uart_info_p)
{
void *uart_base = uart_get_base(uart_info_p->UARTx);
unsigned long baudrate_div = 0;
// 禁止所有中断
reg_write_8(0, uart_base + LS1B_UART_IER_OFFSET);
// 接收FIFO的中断申请Trigger为14字节,清空发送和接收FIFO,并复位
reg_write_8(0xc3, uart_base + LS1B_UART_FCR_OFFSET);
// 设置波特率
reg_write_8(0x80, uart_base + LS1B_UART_LCR_OFFSET);
baudrate_div = clk_get_apb_rate() / 16 / uart_info_p->baudrate;
reg_write_8((baudrate_div >> 8) & 0xff, uart_base + LS1B_UART_MSB_OFFSET);
reg_write_8(baudrate_div & 0xff, uart_base + LS1B_UART_LSB_OFFSET);
// 8个数据位,1个停止位,无校验
reg_write_8(0x03, uart_base + LS1B_UART_LCR_OFFSET);
// 使能接收中断
if (TRUE == uart_info_p->rx_enable)
{
reg_write_8(IER_IRxE|IER_ILE , uart_base + LS1B_UART_IER_OFFSET);
}
return ;
}
/*
* 判断FIFO是否为空
* @uartx 串口号
* @ret TRUE or FALSE
*/
BOOL uart_is_transmit_empty(ls1b_uart_t uartx)
{
void *uart_base = uart_get_base(uartx);
unsigned char status = reg_read_8(uart_base + LS1B_UART_LSR_OFFSET);
if (status & (LS1B_UART_LSR_TE | LS1B_UART_LSR_TFE))
{
return TRUE;
}
else
{
return FALSE;
}
}
/*
* 发送一个字节
* @uartx 串口号
* @ch 待发送的字符串
*/
void uart_putc(ls1b_uart_t uartx, unsigned char ch)
{
void *uart_base = uart_get_base(uartx);
// 等待
while (FALSE == uart_is_transmit_empty(uartx))
;
// 发送
reg_write_8(ch, uart_base + LS1B_UART_DAT_OFFSET);
return ;
}
/*
* 打印一个字符串到指定串口
* @uartx 串口号
* @str 待打印的字符串
*/
void uart_print(ls1b_uart_t uartx, const char *str)
{
while ('\0' != *str) // 判断是否为字符串结束符
{
uart_putc(uartx, *str); // 发送一个字符
str++;
}
return ;
}
/*
* 初始化串口2
*/
void uart2_init(void)
{
unsigned int tx_gpio = 37;
unsigned int rx_gpio = 36;
// 设置复用
pin_set_remap(tx_gpio, PIN_REMAP_SECOND);
pin_set_remap(rx_gpio, PIN_REMAP_SECOND);
// 初始化相关寄存器
debug_uart_info.UARTx = LS1B_UART2;
debug_uart_info.baudrate = 115200;
debug_uart_info.rx_enable = FALSE; // 调试串口只需要打印(发送)功能,不需要接收功能
uart_init(&debug_uart_info);
return ;
}
/*
* 在串口2上打印字符串
* @str 待打印的字符串
*/
void uart2_print(const char *str)
{
uart_print(LS1B_UART2, str);
return ;
}
/*
* 在调试串口打印字符串
* @str 待打印的字符串
*/
void uart_debug_print(const char *str)
{
uart_print(debug_uart_info.UARTx, str);
return ;
}
/*
* 在调试串口打印一个字符
* @ch 待打印的字符
*/
void uart_debug_putc(unsigned char ch)
{
uart_putc(debug_uart_info.UARTx, ch);
return ;
}
|