1.4. UART
包含多个串口,支持奇偶校验,dma收发,1个起始位,8个数据位,1个停止位。其中串口1支持硬件流控。串口外设的数量及校验情况请参阅对应Soc规格书。 时钟源:std24m,std48m,lsb。一般为std48m。 详细的示例代码请参考SDK “uart_demo.c或uart_test.c”
备注
串口收发的dma buffer 必须使用全局buffer,或者使用dma_malloc申请,不能使用临时变量,或者malloc申请。
1.4.1. 串口基本接口
1.4.1.1. uart_init
初始化串口,支持指定串口号,或者自动分配串口。指定串口号方式节省代码空间。
原型:
int uart_init(uart_dev uart_num, const struct uart_config *config)
- 参数:
uart_num
串口号0~n,-1表示自动分配空闲的串口
config
串口配置信息
返回值
<0:串口初始化失败,>=0:为串口号
示例:
struct uart_config config = {
.baud_rate = 2000000,
.tx_pin = IO_PORTB_15,
.rx_pin = IO_PORTB_14,
.parity = UART_PARITY_DISABLE,
.tx_wait_mutex = 0,//1:发送接口不支持中断调用,启用互斥功能,0:支持中断,不互斥
};
int uart_num = uart_init(-1, &config);
if (uart_num < 0) {
printf("uart init error");
}else{
printf("uart%d init succ", uart_num);
}
1.4.1.2. uart_dma_init
串口dma初始化,串口接收必须配置dma参数,使用前先调用uart_init
原型:
int uart_dma_init(uart_dev uart_num, const struct uart_dma_config *dma_config);
- 参数:
uart_num
串口号
dma_config
串口配置信息
返回值
0:成功,<0:失败
示例:
const int uart_rx_dma_buffer_size = 768;
void *uart_rx_ptr = dma_malloc(uart_rx_dma_buffer_size);
struct uart_dma_config dma = {
.rx_timeout_thresh = 100, //接收数据不够frame_size,串口通信空闲100us后触发中断
.frame_size = 32, //接收32字节就触发RX中断,不足32byte触发RX_TIMEOUT中断
.event_mask = UART_EVENT_RX_TIMEOUT | UART_EVENT_RX_FIFO_OVF | UART_EVENT_TX_DONE,
.irq_callback = uart_irq_func,//在中断里面调用
.irq_priority = 3,//中断优先级
.rx_cbuffer = uart_rx_ptr, //使用支持dma的内存
.rx_cbuffer_size = uart_rx_dma_buffer_size,
};
//frame_size 一般是一个通讯帧的大小,rx_buffer_size一般为frame_size的两倍,内部是一个循环buffer
//使用前先调用uart_init
int r = uart_dma_init(uart_num, &dma);
if (r < 0) {
log_error("dma init error %d", uart_num);
} else {
log_info("dma init ok %d", uart_num);
}
1.4.1.3. uart_deinit
关闭串口,释放TX、RX io为高阻状态,关闭crossbar映射。
原型:
s32 uart_deinit(uart_dev uart_num)
- 参数:
uart_num
串口号
返回值
0:成功,<0:失败
1.4.1.4. uart_set_baudrate
设置串口波特率
原型:
s32 uart_set_baudrate(uart_dev uart_num, u32 baud_rate);
- 参数:
uart_num
串口号
baud_rate
波特率
返回值
实际波特率,>0:成功,<0:失败
1.4.1.5. uart_set_rx_timeout_thresh
设置超时时间ot,接收通信结束后ot时长后触发ot中断。
原型:
s32 uart_set_rx_timeout_thresh(uart_dev uart_num, u32 timeout_thresh);
- 参数:
uart_num
串口号
timeout_thresh
ot时间,单位us
返回值
0:成功,<0:失败
1.4.1.6. uart_send_bytes
启动串口发送dma,不等待dma发送结束,直接退出,由成员tx_wait_mutex决定能否在中断函数调用,数据指针要求在发送完成之前保持有效
原型:
s32 uart_send_bytes(uart_dev uart_num, const void *buffer, u32 size);
- 参数:
uart_num
串口号
buffer
需要发送的数据指针,需要使用dma_malloc申请,或者全局变量
size
需要发送的数据长度
返回值
等于发送的长度tx_size:ok,<0:error
1.4.1.7. uart_wait_tx_idle
等待串口发送完成,不允许在中断函数使用
原型:
s32 uart_wait_tx_idle(uart_dev uart_num, u32 timeout_ms);
- 参数:
uart_num
串口号
timeout_ms
超时时间,0就一直等,直到发送完成
返回值
0:成功,其他值:失败
1.4.1.8. uart_send_blocking
阻塞式发送数据,由成员tx_wait_mutex决定能否在中断函数调用
原型:
s32 uart_send_blocking(uart_dev uart_num, const void *buffer, u32 size, u32 timeout_ms);
- 参数:
uart_num
串口号
buffer
需要发送的数据指针,需要使用dma_malloc申请,或者全局变量
size
需要发送的数据长度
timeout_ms
超时时间,0就一直等,直到发送完成
返回值
等于发送的长度tx_size:ok,<0:error
1.4.1.9. uart_get_recv_len
获取dma接收长度,支持中断调用
原型:
//return,返回dma接收的长度 <0:error;
s32 uart_get_recv_len(uart_dev uart_num);
- 参数:
uart_num
串口号
返回值
接收的长度<0:error; 0=< <len:ok
1.4.1.10. uart_recv_bytes
获取接收数据,支持中断调用
原型:
s32 uart_recv_bytes(uart_dev uart_num void *buffer, u32 len);
- 参数:
uart_num
串口号
buffer
读取数据存放的buffer
len
需要读取数据长度
返回值
接收的长度<0:error; 0=< <len:ok
1.4.1.11. uart_recv_blocking
阻塞式读取串口接收的数据,不允许在中断函数,或者关闭中断的情况下使用
原型:
s32 uart_recv_blocking(uart_dev uart_num, void *buffer, u32 len, int timeout_ms);
- 参数:
uart_num
串口号
buffer
读取数据存放的buffer
len
需要读取数据长度
timeout_ms
超时时间,0就一直等,直到读取完成
返回值
接收的长度<0:error; 0=< <len:ok
1.4.1.12. uart_dma_rx_reset
dma rx fifo over接收溢出或接收错乱时重置dma及buf。
原型:
enum uart_state uart_dma_rx_reset(uart_dev uart_num);
- 参数:
uart_num
串口号
返回值
见枚举:uart_state
1.4.1.13. uart_set_idle_query_wait
配置串口延时进低功耗时间(默认延时30ms)。
原型:
void uart_set_idle_query_wait(u32 ms);
- 参数:
ms
延时时间ms
返回值
无
1.4.2. 串口硬件流接口
1.4.2.1. uart_flow_ctrl_init
流控配置,cts:检测到cts停止发送;rts:设置好阈值后当接收达到阈值会触发rts,当缓存少于阈值会释放rts,设置的阈值余量要足够。硬件流初始化后会后台运行。 查看芯片soc稳定确定是否支持硬件流控,一般uart1支持硬件流。
原型:
s32 uart_flow_ctrl_init(uart_dev uart_num, const struct uart_flow_ctrl *flow_ctrl);
- 参数:
uart_num
串口号
flow_ctrl
流控相关参数
返回值
0:成功,<0:失败
1.4.2.2. uart_flow_ctrl_deinit
关闭流控。当调uart_deinit关闭串口时会调用该函数关闭硬件流。
原型:
s32 uart_flow_ctrl_deinit(uart_dev uart_num);
- 参数:
uart_num
串口号
返回值
0:成功,<0:失败
1.4.3. 串口资源占用打印
1.4.3.1. uart_dump
打印所有串口初始化情况,功能启用情况。
原型:
//打印uart配置信息
void uart_dump();
- 参数:
返回值
无
1.4.4. 示例
- 示例:
详细的示例代码请参考SDK “uart_demo.c或uart_tset.c”
void uart_irq_func(uart_dev uart_num, enum uart_event enent)
{
if (event & UART_EVENT_TX_DONE){
uart_send_bytes(uart_num, tx_buffer, 32);
}
if (event & UART_EVENT_RX_TIMEOUT) {
// int rx_len = uart_recv_bytes(uart_num,rx_buffer,32);
printf("uart[%d] rx timerout data", uart_num);
}
if(event & UART_EVENT_RX_FIFO_OVF){
printf(" rx_buffer too small");
}
}
struct uart_config config = {
.baud_rate = 2000000,
.tx_pin = IO_PORTB_15,
.rx_pin = IO_PORTB_14,
.parity = UART_PARITY_DISABLE,
.tx_wait_mutex = 0,//1:不支持中断调用,互斥,0:支持中断,不互斥
};
//使用自动分配串口号模式(-1):消耗内存大;指定串口号消耗内存小
int uart_num = uart_init(-1, &config);
if (uart_num < 0) {
printf("uart init error");
}else{
printf("uart%d init succ", uart_num);
}
const int uart_rx_dma_buffer_size = 768;
void *uart_rx_ptr = dma_malloc(uart_rx_dma_buffer_size);
struct uart_dma_config dma = {
.rx_timeout_thresh = 100, //接收数据不够frame_size,串口通信空闲100us后触发中断
.event_mask = UART_EVENT_RX_FIFO_OVF | UART_EVENT_TX_DONE | UART_EVENT_RX_TIMEOUT,
.irq_callback = uart_irq_func,//在中断里面调用
.irq_priority = 3,
.rx_cbuffer = uart_rx_ptr, //使用支持dma的内存
.rx_cbuffer_size = uart_rx_dma_buffer_size,
.frame_size = uart_rx_dma_buffer_size,
};
//frame_size 一般是一个通讯帧的大小,rx_buffer_size一般为frame_size的两倍,内部是一个循环buffer
//串口dma初始化,串口收必须配置dma参数,使用前先调用uart_init
int r = uart_dma_init(uart_num, &dma);
if (r < 0) {
log_error("dma init error %d", uart_num);
} else {
log_info("dma init ok %d", uart_num);
}