67. UART
67.1. 概述
主要特征功能
主要介绍先楫的uart外设的主要驱动接口说明和调用方法。更多内容请参考 hpm_uart_drv.h 的API说明以及相关用户手册。
支持5到9位数据位,支持地址匹配。可参考 uart_9bit 例子。 9bit数据位具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_9BIT_MODE 宏定义
支持DMA数据传输。可参考 uart_dma 例子
支持硬件RX空闲以及TX空间检测。可参考 uart_hardware_rx_idle 例子。具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_RX_IDLE_DETECT 宏定义
支持各类中断。可参考 uart_irq 例子
支持接收各类错误检测,比如奇偶校验错误, FIFO溢出等。可参考 uart_rx_line_status 例子
可配置停止位:1位,1.5位,2位。
可配置奇偶校验位:无,奇校验,偶校验。
可配置波特率。
支持硬件流控
接收和发送内置最大32字节的硬件FIFO缓存,具体深度可参考每个SOC的 hpm_soc_feature.h 的 UART_SOC_FIFO_SIZE 宏定义 或者使用 hpm_uart_drv.h 中的 uart_intr_tx_slot_avail API接口获取。
67.2. uart初始化
需要确保UART的时钟源已经开启,并且初始化了相关UART外设引脚。
可使用`clock_add_to_group` 函数用于将UART时钟源添加到时钟组中,从而确保UART时钟源已经开启。
相关枚举值介绍:
parity_setting_t 枚举用于配置UART奇偶校验类型,具体内容如下:
typedef enum parity { /**< 无校验 */ parity_none = 0, /**< 奇校验 */ parity_odd, /**< 偶校验 */ parity_even, /**< 校验位固定为1 */ parity_always_1, /**< 校验位固定为0 */ parity_always_0, } parity_setting_t;
num_of_stop_bits_t 枚举用于配置停止位长度,具体内容如下:
typedef enum num_of_stop_bits { /**< 1位停止位 */ stop_bits_1 = 0, /**< 1.5位停止位 */ stop_bits_1_5, /**< 2位停止位 */ stop_bits_2, } num_of_stop_bits_t;
word_length_t 枚举用于配置数据位长度,具体内容如下:
typedef enum word_length { /**< 5位数据位 */ word_length_5_bits = 0, /**< 6位数据位 */ word_length_6_bits, /**< 7位数据位 */ word_length_7_bits, /**< 8位数据位 */ word_length_8_bits, } word_length_t;
uart_rxline_idle_cond_t 枚举用于配置UART RX线以及TX线空闲检测条件,具体内容如下:
仅支持在当前SOC支持RX Idle检测的情况下使用,具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_RX_IDLE_DETECT 宏定义
typedef enum hpm_uart_rxline_idle_cond { /**< 当RX线保持高电平的持续时间超过阈值时视为空闲 */ uart_rxline_idle_cond_rxline_logic_one = 0, /**< 当接收状态机处于空闲状态的持续时间超过阈值时视为空闲 */ uart_rxline_idle_cond_state_machine_idle = 1 } uart_rxline_idle_cond_t;
相关结构体介绍:
uart_modem_config_t 结构体用于配置uart的硬件流控相关参数, 具体内容如下:
typedef struct uart_modem_config { /**< 自动流控制使能标志 */ bool auto_flow_ctrl_en; /**< 回环模式使能标志 */ bool loop_back_en; /**< 设置 RTS 信号电平为高标志 */ bool set_rts_high; } uart_modem_config_t;
uart_rxline_idle_config_t 结构体用于配置UART RX和TX线空闲检测参数,具体内容如下:
仅支持在当前SOC支持RX Idle检测的情况下使用,具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_RX_IDLE_DETECT 宏定义
typedef struct hpm_uart_rxline_idle_detect_config { /**< RX或者TX线空闲检测使能标志 */ bool detect_enable; /**< RX线或者TX线空闲检测中断使能标志 */ bool detect_irq_enable; /**< RX线或者TX线空闲检测条件 */ uart_rxline_idle_cond_t idle_cond; /**< RX线或者TX空闲检测阈值(以bit为单位) */ uint8_t threshold; } uart_rxline_idle_config_t;
uart_config_t 结构体用于配置uart的相关参数, 具体内容如下:
typedef struct hpm_uart_config { /**< uart时钟源频率(Hz) */ uint32_t src_freq_in_hz; /**< 波特率 */ uint32_t baudrate; /**< 停止位 */ uint8_t num_of_stop_bits; /**< 数据位 */ uint8_t word_length; /**< 奇偶校验 */ uint8_t parity;/**< 奇偶校验 */ /**< 发送FIFO触发中断或者DMA阈值 */ uint8_t tx_fifo_level; /**< 接收FIFO触发中断或者DMA阈值 */ uint8_t rx_fifo_level; /**< DMA使能标志 */ bool dma_enable;/**< DMA使能标志 */ /**< FIFO使能标志 */ bool fifo_enable; /**< 硬件流控配置 */ uart_modem_config_t modem_config; /**< 如果当前SOC支持RX Idle检测 */ #if defined(HPM_IP_FEATURE_UART_RX_IDLE_DETECT) && (HPM_IP_FEATURE_UART_RX_IDLE_DETECT == 1) /**< 接收空闲配置 */ uart_rxline_idle_config_t rxidle_config; #endif /**< 如果当前SOC支持TX Idle检测 */ #if defined(HPM_IP_FEATURE_UART_TX_IDLE_DETECT) && (HPM_IP_FEATURE_UART_TX_IDLE_DETECT == 1) /**< 发送空闲配置 */ uart_rxline_idle_config_t txidle_config; #endif /**< 如果当前SOC支持RX使能 */ #if defined(HPM_IP_FEATURE_UART_RX_EN) && (HPM_IP_FEATURE_UART_RX_EN == 1) /**< 此位是用来防止RX引脚跳动导致的错误接收。在上电启动的时候后默认会把RX信号强制为高电平,在初始化的时候需要把该位置位把RX输入为正常状态 */ bool rx_enable; #endif } uart_config_t;
fifo_enable: 用于配置uart是否使用FIFO。如果为true,则使用FIFO模式,这时候RBR/THR寄存器作为RX/TX FIFO使用;如果为flase,则为缓冲模式,RBR/THR寄存器作为单字节缓冲区使用。开启有效数据 uart_intr_id_rx_data_avail 中断时,FIFO模式下,当FIFO中数据达到阈值时会触发中断,缓冲模式下,当RBR/THR寄存器中有数据时会触发中断。
dma_enable: 用于配置uart是否使用DMA。如果为true,则使能uart的DMA模式,当FIFO中的数据达到阈值时会触发请求DMA。
tx_fifo_level: 用于配置uart发送FIFO触发中断或者DMA阈值。阈值设置可参考 uart_fifo_trg_lvl_t 枚举。有两个bit宽度方式的FIFO阈值
2bit位宽的FIFO阈值,范围为0-3,当FIFO小于阈值时,会触发中断或者DMA请求。表示的FIFO阈值是:
发送FIFO阈值
枚举定义
16字节的FIFO深度
32字节的FIFO深度
uart_tx_fifo_trg_not_full
不为满
不为满
uart_tx_fifo_trg_lt_three_quarters
小于12字节
小于24字节
uart_tx_fifo_trg_lt_half
小于8字节
小于16字节
uart_tx_fifo_trg_lt_one_quarter
小于4字节
小于8字节
举例:
tx_fifo_level = uart_tx_fifo_trg_lt_half, 在16字节FIFO深度的SOC下,发送FIFO深度小于8字节时,会触发一次DMA请求。
4bit位宽的FIFO阈值,范围为0-31,表示的FIFO阈值是:1到32字节的FIFO阈值, 当FIFO小于等于阈值时,会触发中断或者DMA请求。该部分定义只能支持的SOC是有在 hpm_soc_ip_feature.h 定义 HPM_IP_FEATURE_UART_FINE_FIFO_THRLD 宏定义。
举例:
tx_fifo_level = 15, 在32字节FIFO深度的SOC下,发送FIFO深度小于等于15字节时,会触发一次DMA请求。
rx_fifo_level: 用于配置uart接收FIFO触发中断或者DMA阈值。阈值设置可参考 uart_fifo_trg_lvl_t 枚举。
2bit位宽的FIFO阈值,范围为0-3,当FIFO大于阈值时,会触发中断或者DMA请求。表示的FIFO阈值是:
接收FIFO阈值
枚举定义
16字节的FIFO深度
32字节的FIFO深度
uart_rx_fifo_trg_not_empty
不为空
不为空
uart_rx_fifo_trg_gt_one_quarter
大于3字节
大于7字节
uart_rx_fifo_trg_gt_half
大于7字节
大于15字节
uart_rx_fifo_trg_gt_three_quarters
大于13字节
大于27字节
举例:
rx_fifo_level = uart_rx_fifo_trg_gt_one_quarter, 在16字节FIFO深度的SOC下,接收FIFO深度大于3字节时,会触发一次DMA请求。
4bit位宽的FIFO阈值,范围为0-31,表示的FIFO阈值是:1到32字节的FIFO阈值,当FIFO大于等于阈值时,会触发中断或者DMA请求。该部分定义只能支持的SOC是有在 hpm_soc_ip_feature.h 定义 HPM_IP_FEATURE_UART_FINE_FIFO_THRLD 宏定义。
举例:
rx_fifo_level = 27, 在32字节FIFO深度的SOC下,接收FIFO深度大于等于27字节时,会触发一次DMA请求。
rxidle_config: 用于配置uart接收空闲检测参数。该参数仅在当前SOC支持RX Idle检测的情况下使用,具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_RX_IDLE_DETECT 宏定义。
detect_enable: 用于配置uart接收空闲检测使能标志。如果为true,则使能uart的接收空闲检测。
detect_irq_enable: 用于配置uart接收空闲检测中断使能标志。如果为true,则使能uart的接收空闲检测中断。
idle_cond: 用于配置uart接收空闲检测条件。可以选择是当RX线保持高电平的持续时间超过阈值时视为空闲,或者当接收状态机处于空闲状态的持续时间超过阈值时视为空闲。
threshold: 用于配置uart接收空闲检测阈值。按bit单位计算。
txidle_config: 用于配置uart发送空闲检测参数。该参数仅在当前SOC支持TX Idle检测的情况下使用,具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_TX_IDLE_DETECT 宏定义。参数与 rxidle_config 相同。
初始化API:
uart_default_config 函数用于配置uart的默认缺省参数,建议在uart进行初始化之前调用。具体内容如下:
void uart_default_config(UART_Type *ptr, uart_config_t *config);
参数说明:
参数名
类型
描述
ptr
UART_Type *
指向UART控制器基地址的指针
config
uart_config_t *
指向UART配置结构体的指针,包含波特率/数据位/停止位等参数
默认参数值是:波特率为115200,数据位为8位,停止位为1位,无奇偶校验,使能FIFO,关闭DMA, 对于支持接收和发送空闲的soc, 使能接收空闲检测,关闭发送空闲检测。
hpm_stat_t uart_init(UART_Type *ptr, uart_config_t *config);
参数说明:
参数名
类型
描述
ptr
UART_Type *
指向UART控制器基地址的指针
config
uart_config_t *
指向UART配置结构体的指针,包含波特率/数据位/停止位等参数
返回值:
返回值
描述
status_success
初始化成功
status_uart_no_suitable_baudrate_parameter_found
未找到合适的波特率参数
status_invalid_argument
无效的参数
注意:
调用前需确保时钟源已正确配置
config参数中的波特率/数据位等参数需在有效范围内
需根据具体SOC特性启用相关功能宏
示例:
使用默认配置初始化UART0,波特率为11520,0数据位为8位,停止位为1位,无奇偶校验。
void uart_init_sample(void) { uart_config_t config; uart_default_config(HPM_UART0, &config); config.src_freq_in_hz = clock_get_frequency(clock_uart0); config.baudrate = 115200; hpm_stat_t status = uart_init(HPM_UART0, &config); if (status != status_success) { printf("UART初始化失败\n"); } }
67.3. uart发送
支持FIFO发送以及DMA发送
67.3.1. 发送
可以使用轮询方式进行FIFO发送,也可以使用中断方式进行FIFO发送。
使用中断方式需要打开plic控制器对应的UART中断,使用 intc_m_enable_irq API接口打开UART中断。
使用中断方式如果设置中断的优先级,使用 intc_m_enable_irq_with_priority API接口配置UART中断的优先级。
67.3.1.1. 轮询阻塞方式发送
单字节发送API,
hpm_stat_t uart_send_byte(UART_Type *ptr, uint8_t c);
参数说明:
参数名
类型
描述
ptr
UART_Type *
指向UART控制器基地址的指针
data
uint8_t
要发送的数据
返回值:
返回值
描述
status_success
发送成功
status_timeout
发送超时
注意:该API接口会阻塞等待FIFO发送完成。
示例:
void send_data_sample(void) { uint8_t data = 0x12; hpm_stat_t status = uart_send_byte(uart0, data); if (status == status_success) { printf("send data success\n"); } else { printf("send data failed\n"); } }
多字节发送API,
hpm_stat_t uart_send_data(UART_Type *ptr, uint8_t *source, uint32_t size_in_byte);
参数说明:
参数名
类型
描述
ptr
UART_Type *
指向UART控制器基地址的指针
source
uint8_t *
要发送的数据
size_in_byte
uint32_t
要发送的数据长度
返回值:
返回值
描述
status_success
发送成功
status_timeout
发送超时
注意:该API接口会阻塞等待FIFO发送完成。
示例:
void send_data_sample(void) { uint8_t data[] = {0x12, 0x34, 0x56, 0x78}; hpm_stat_t status = uart_send_data(uart0, data, sizeof(data)); if (status == status_success) { printf("send data success\n"); } else { printf("send data failed\n"); } }
67.3.1.2. 中断方式发送
先楫uart具有高达32字节的发送FIFO硬件缓存,可以开启发送空闲中断,在一开始发送数据的时候,数据塞入一部分到FIFO,然后开启发送空闲中断,当FIFO发送完成之后,会触发发送空闲中断,此时可以继续往FIFO塞入数据,直到FIFO满。
单字节发送API,此API是将数据写入FIFO,不会等待发送完成立即返回。
void uart_write_byte(UART_Type *ptr, uint8_t c)
参数说明:
参数名
类型
描述
ptr
UART_Type *
指向UART控制器基地址的指针
data
uint8_t
要发送的数据
示例:
#define UART_TX_SEND_SIZE 100 uint8_t tx_buffer[UART_TX_SEND_SIZE]; uint32_t tx_buffer_index = 0; uint8_t tx_fifo_size = 0; /* 中断处理函数 */ void uart0_isr(void) { uint8_t irq_id = uart_get_irq_id(TEST_UART); if (irq_id & uart_intr_id_tx_slot_avail) { /* 关闭发送FIFO空中断 */ uart_disable_irq(HPM_UART0, uart_intr_tx_slot_avail); /* 继续往FIFO塞入数据 */ send_size = (tx_fifo_size <= (UART_TX_SEND_SIZE - tx_buffer_index)) ? tx_fifo_size : (UART_TX_SEND_SIZE - tx_buffer_index); while (send_size--) { uart_write_byte(HPM_UART0, tx_buffer[tx_buffer_index]); tx_buffer_index++; } if (tx_buffer_index < UART_TX_SEND_SIZE) { /* 还有数据需要发送,继续开启发送FIFO空中断 */ uart_enable_irq(HPM_UART0, uart_intr_tx_slot_avail); } } } void send_data_sample(void) { uint8_t send_size = 0; /* 关闭发送FIFO空中断 */ uart_disable_irq(HPM_UART0, uart_intr_tx_slot_avail); /* 获取FIFO大小 */ tx_fifo_size = uart_get_fifo_size(HPM_UART0, uart_intr_tx_slot_avail); send_size = (tx_fifo_size <= UART_TX_SEND_SIZE) ? tx_fifo_size : UART_TX_SEND_SIZE; /* 往FIFO塞入数据 */ while (tx_buffer_index < send_size) { uart_write_byte(HPM_UART0, tx_buffer[tx_buffer_index]); tx_buffer_index++; } /* 开启发送FIFO空中断 */ uart_enable_irq(HPM_UART0, uart_intr_tx_slot_avail); }
注意: uart_intr_tx_slot_avail 中断指的是发送FIFO缓存为空中断,并不代表数据已经移位到发送移位寄存器。如果需要知道实际数据已经移位发送了,可以使用 uart_enable_rxline_idle_detection API开启使用发送空闲中断。
67.3.1.3. DMA方式发送
详情请参考 uart_dma 例子
67.4. uart接收
支持FIFO接收以及DMA接收
67.4.1. 接收
可以使用轮询方式进行FIFO接收,也可以使用中断方式进行FIFO接收。
使用中断方式需要打开plic控制器对应的UART中断,使用 intc_m_enable_irq API接口打开UART中断。
使用中断方式如果设置中断的优先级,使用 intc_m_enable_irq_with_priority API接口配置UART中断的优先级。
67.4.1.1. 轮询阻塞方式接收
单字节接收API,
hpm_stat_t uart_receive_byte(UART_Type *ptr, uint8_t *byte);
参数说明:
参数名
类型
描述
ptr
UART_Type *
指向UART控制器基地址的指针
byte
uint8_t *
接收的数据指针
返回值:
返回值
描述
status_success
接收成功
status_timeout
接收超时
注意:该API接口会阻塞等待FIFO接收完成。
示例:
void receive_data_sample(void) { uint8_t data = 0; hpm_stat_t status = uart_receive_byte(uart0, &data); if (status == status_success) { printf("receive data success, data = 0x%x\n", data); } else { printf("receive data failed\n"); } }
多字节接收API,
hpm_stat_t uart_receive_data(UART_Type *ptr, uint8_t *source, uint32_t size_in_byte);
参数说明:
参数名
类型
描述
ptr
UART_Type *
指向UART控制器基地址的指针
source
uint8_t *
接收的数据指针
size_in_byte
uint32_t
要接收的数据长度
返回值:
返回值
描述
status_success
接收成功
status_fail
接收失败
注意:该API接口会阻塞等待FIFO接收完成。
示例:
void receive_data_sample(void) { uint8_t data[100]; hpm_stat_t status = uart_receive_data(uart0, data, sizeof(data)); if (status == status_success) { printf("receive data success\n"); } else { printf("receive data failed\n"); } }
67.4.1.2. 中断方式接收
先楫uart具有高达32字节的接收FIFO硬件缓存,可以开启接收有效数据和超时中断,设置接收FIFO阈值,当FIFO中有数据时,会触发接收有效数据中断,当没有字符从接收 FIFO 中被移出或移入,并且在最后四个字符时间内接收 FIFO 中至少有一个字符这时候会触发FIFO超时中断。
单字节接收API:此API是从FIFO中读取数据,不会等待接收完成立即返回。
uint8_t uart_read_byte(UART_Type *ptr);
参数说明:
参数名
类型
描述
ptr
UART_Type *
指向UART控制器基地址的指针
返回值:
返回值
描述
接收到的数据
接收到的数据
示例: 可参考 uart_rx_timeout 例子
67.4.1.3. DMA方式接收
详情请参考 uart_dma 例子
67.5. 硬件自动流控
支持CTS和RTS硬件自动流控
结构体说明:
/* UART modem配置结构体 */ typedef struct uart_modem_config { /* 自动流控使能 */ bool auto_flow_ctrl_en; /* 内部RX TX loopback使能 */ bool loop_back_en; /* 使能RTS */ bool set_rts_high; } uart_modem_config_t;
注意
不需要loopback功能,可以把 loop_back_en 设置为false
只要`auto_flow_ctrl_en` 设置为true,就会使能硬件CTS硬件流控
如果只需要使能CTS,可以把 set_rts_high 设置为true,auto_flow_ctrl_en 设置为true
如果需要同时使能CTS和RTS,可以把 set_rts_high 设置为false,auto_flow_ctrl_en 设置为true
配置API说明:
使能硬件自动流控
void uart_modem_config(UART_Type *ptr, uart_modem_config_t *config);
参数说明:
参数名
类型
描述
ptr
UART_Type *
指向UART控制器基地址的指针
config
uart_modem_config_t *
指向uart modem结构体指针,包含自动流控使能,内部RX TX loopback使能,使能RTS等参数。
举例:使能RTS和CTS硬件流控,关闭loopback功能
void uart_modem_config_sample(void) { uart_modem_config_t config; config.auto_flow_ctrl_en = true; config.loop_back_en = false; config.set_rts_high = false; uart_modem_config(HPM_UART0, &config); }
67.5.1. CTS硬件流控
如果需要在中断中判断CTS电平状态,可以开启uart modem状态中断,然后在中断中获取CTS电平状态。
注意:
使用中断方式必须把硬件流控关闭,也就是 uart_modem_config_t 的 auto_flow_ctrl_en 成员变量设置为false。
如果开启硬件流控,uart modem中断即使使能也不会被触发,可以使用 uart_get_modem_status API接口获取CTS电平状态。
举例:使用中断方式判断CTS电平状态
SDK_DECLARE_EXT_ISR_M(IRQn_UART0, uart_isr) void uart_isr(void) { uint32_t irq_id = uart_get_irq_id(HPM_UART0); uint8_t cts_sta; if (irq_id == uart_intr_id_modem_stat) { /* 读取MSR清零中断标志 */ cts_sta = (uart_get_modem_status(HPM_UART0) & UART_MSR_DCTS_MASK) >> UART_MSR_DCTS_SHIFT; printf("CTS 0x%02x\r\n", cts_sta); } } void uart_modem_config_sample(void) { uart_enable_irq(HPM_UART0, uart_intr_modem_stat); intc_m_enable_irq_with_priority(IRQn_UART0, 2); uart_modem_config_t config; config.auto_flow_ctrl_en = false; config.loop_back_en = false; uart_modem_config(HPM_UART0, &config); }
67.5.2. 中断
需要打开plic控制器对应的UART中断,使用 intc_m_enable_irq API接口打开UART中断。
需要在plic控制器中配置UART中断的优先级,使用 intc_m_enable_irq_with_priority API接口配置UART中断的优先级。
每次对应的中断事件发生,可以在中断处理函数中调用 uart_get_irq_id API接口获取中断ID,比如相关中断使能为 uart_intr_rx_data_avail_or_timeout ,则调用 uart_get_irq_id 获取中断ID是否为 uart_intr_id_rx_data_avail 。
UART外设支持以下中断,可以从 uart_intr_enable 枚举类型中查看。
typedef enum uart_intr_enable { uart_intr_rx_data_avail_or_timeout = UART_IER_ERBI_MASK, /* 接收到的有效数据达到FIFO阈值或FIFO超时中断 */ uart_intr_tx_slot_avail = UART_IER_ETHEI_MASK, /* 发送FIFO为空中断 */ uart_intr_rx_line_stat = UART_IER_ELSI_MASK, /* 接收线路状态中断 */ uart_intr_modem_stat = UART_IER_EMSI_MASK, /* 流控状态中断 */ /* 如果当前的SOC支持串口空闲中断 */ #if defined(HPM_IP_FEATURE_UART_RX_IDLE_DETECT) && (HPM_IP_FEATURE_UART_RX_IDLE_DETECT == 1) uart_intr_rx_line_idle = UART_IER_ERXIDLE_MASK, /* 接收空闲中断 */ #endif /* 如果当前的SOC支持串口空闲中断 */ #if defined(HPM_IP_FEATURE_UART_TX_IDLE_DETECT) && (HPM_IP_FEATURE_UART_TX_IDLE_DETECT == 1) uart_intr_tx_line_idle = UART_IER_ETXIDLE_MASK, /* 发送空闲中断 */ #endif /* 如果当前SOC支持接收地址匹配功能 */ #if defined(HPM_IP_FEATURE_UART_ADDR_MATCH) && (HPM_IP_FEATURE_UART_ADDR_MATCH == 1) uart_intr_addr_match = UART_IER_EADDRM_MASK, /* 接收地址匹配中断 */ uart_intr_addr_match_and_rxidle = UART_IER_EADDRM_IDLE_MASK, /* 接收地址匹配和接收空闲中断 */ uart_intr_addr_datalost = UART_IER_EDATLOST_MASK, /* 接收地址匹配数据丢失中断 */ #endif /* 如果当前SOC支持接收状态检测 */ #if defined(HPM_IP_FEATURE_UART_RX_LINE_ERROR_DETECT) && (HPM_IP_FEATURE_UART_RX_LINE_ERROR_DETECT == 1) uart_intr_errf = UART_IER_LSR_ERRF_IRQ_EN_MASK, /* 接收状态错误中断 */ uart_intr_break_err = UART_IER_LSR_BREAK_IRQ_EN_MASK, /* 传输打断中断 */ uart_intr_framing_err = UART_IER_LSR_FRAMING_IRQ_EN_MASK, /* 帧格式错误中断 */ uart_intr_parity_err = UART_IER_LSR_PARITY_IRQ_EN_MASK, /* 奇偶校验错误中断 */ uart_intr_overrun = UART_IER_LSR_OVERRUN_IRQ_EN_MASK, /* 接收数据溢出中断 */ #endif } uart_intr_enable_t;
uart中断状态枚举定义
typedef enum uart_intr_id { uart_intr_id_modem_stat = 0x0, /* MODEM状态中断 */ uart_intr_id_tx_slot_avail = 0x2, /* 发送FIFO为空中断 ,不代表发送移位寄存器移位完成。*/ uart_intr_id_rx_data_avail = 0x4, /* 接收FIFO数据可用中断 */ uart_intr_id_rx_line_stat = 0x6, /* 接收线路状态中断 */ uart_intr_id_rx_timeout = 0xc, /* 接收FIFO数据超时中断 */ } uart_intr_id_t;
uart_intr_rx_data_avail_or_timeout
中断触发条件: 如果使能FIFO,当接收到的数据达到FIFO阈值时就会触发,当没有字符从接收 FIFO 中被移出或移入,并且在最后四个字符时间内接收 FIFO 中至少有一个字节就会发生超时触发。
中断标志清零:使用 uart_read_byte API 读取FIFO数据清零。 清零 uart_intr_id_rx_data_avail 状态,在FIFO模式下需要读取FIFO数据直到剩余数据小于FIFO阈值。
uart_intr_tx_slot_avail
中断触发条件:发送FIFO为空时会触发。
中断标志清零:使用 uart_write_byte API 写入FIFO数据。
uart_intr_rx_line_stat
中断触发条件:接收到奇偶校验错误、帧错误、溢出错误、超时错误等。
中断标志清零:使用 uart_get_status API 清零,该API也可以作为串口接收状态查询接口。
uart_intr_modem_stat
参考 CTS硬件流控 章节
uart_intr_rx_line_idle
中断触发条件:接收线路空闲时触发
中断标志清零:使用 uart_clear_rxline_idle_flag API 清零。
注意 仅支持在当前SOC支持RX Idle检测的情况下使用,具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_RX_IDLE_DETECT 宏定义
uart_intr_tx_line_idle
中断触发条件:发送线路空闲时触发
中断标志清零:使用 uart_clear_txline_idle_flag API 清零。
注意 仅支持在当前SOC支持TX Idle检测的情况下使用,具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_TX_IDLE_DETECT 宏定义
uart_intr_addr_match
中断触发条件:当收到的第一个字节数据与配置的Address匹配时触发。在中断函数使用 uart_is_addr_match API判断是否触发。
中断标志清零:使用 uart_clear_addr_match_flag API 清零。
注意 具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_ADDR_MATCH 宏定义
uart_intr_addr_match_and_rxidle
中断触发条件:当收到的第一个字节数据与配置的Address匹配后接收总线空闲时触发。在中断函数使用 uart_is_addr_match_and_rxidle API判断是否触发。
中断标志清零:使用 uart_clear_addr_match_and_rxidle_flag API 清零。
注意 具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_ADDR_MATCH 宏定义
uart_intr_addr_datalost
中断触发条件:在地址匹配前的数据会抛弃,然后产生中断,在中断函数使用 uart_is_data_lost API判断是否触发。比如准备两组数据,数据组1(没带可匹配的地址)在数据组2(带匹配的地址)之前产生中断,数据组1数据会抛弃。
中断标志清零:使用 uart_clear_data_lost_flag API 清零。
注意 具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_ADDR_MATCH 宏定义
uart_intr_errf
中断触发条件:接收 fifo 错误标志位,在 fifo 模式下,出现奇偶校验错误、帧错误或传输打断错误时触发,在中断函数使用 uart_rx_is_fifo_error API判断是否触发。
中断标志清零:使用 uart_clear_rx_fifo_error_flag API 清零。
注意 具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_RX_LINE_ERROR_DETECT 宏定义
uart_intr_framing_err
中断触发条件:在出现帧格式错误时触发,在中断函数使用 uart_rx_is_framing_error API判断是否触发。
中断标志清零:使用 uart_clear_rx_framing_error_flag API 清零。
注意 具体支持在SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_RX_LINE_ERROR_DETECT 宏定义
uart_intr_break_err
中断触发条件:在出现传输打断错误时产生时触发,在中断函数使用 uart_rx_is_break API判断是否触发。
中断标志清零:使用 uart_clear_rx_break_flag API 清零。
注意 具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_RX_LINE_ERROR_DETECT 宏定义
uart_intr_parity_err
中断触发条件:在出现奇偶校验错误时触发,在中断函数使用 uart_rx_is_parity_error API判断是否触发。
中断标志清零:使用 uart_clear_rx_parity_error_flag API 清零。
注意 具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_RX_LINE_ERROR_DETECT 宏定义
uart_intr_overrun
中断触发条件:接收数据过载时触发,在中断函数使用 uart_rx_is_overrun API判断是否触发。
中断标志清零:使用 uart_clear_rx_overrun_flag API 清零。
注意
具体支持参考每个SOC的 hpm_soc_ip_feature.h 的 HPM_IP_FEATURE_UART_RX_LINE_ERROR_DETECT 宏定义
在具有32字节FIFO的SOC下,由于存在1字节异步FIFO,接收到33字节数据时,才会触发。
相关API接口:
使能UART中断
void uart_enable_irq(UART_Type *ptr, uint32_t irq_mask);
参数说明:
参数名
类型
描述
ptr
UART_Type*
指向UART控制器基地址的指针,用于指定要配置的UART控制器。
irq_mask
uint32_t
中断掩码,用于指定要使能的中断。对应的中断掩码可以从 uart_intr_enable_t 枚举类型中查看。
返回值:
无
禁用UART中断
void uart_disable_irq(UART_Type *ptr, uint32_t irq_mask)
参数说明:
参数名
类型
描述
ptr
UART_Type*
指向UART控制器基地址的指针,用于指定要配置的UART控制器。
irq_mask
uint32_t
中断掩码,用于指定要使能的中断。对应的中断掩码可以从 uart_intr_enable_t 枚举类型中查看。
返回值:
无