Files
chrg/apps/boot/bsp/bsp_uart.c
T
2025-08-16 22:58:22 +08:00

360 lines
9.0 KiB
C

/**
* Change Logs:
* 优化中断开关
*/
/* Includes ------------------------------------------------------------------*/
#include "bsp_uart.h"
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static void UART_CopyDataToUserBuff (struct UART_STRUCT *uart);
static void UART_RxIntHandler (struct UART_STRUCT *uart);
static void UART_RxIdleHandler (struct UART_STRUCT *uart);
static void UART_TxHandler (struct UART_STRUCT *uart);
/* Exported functions ---------------------------------------------------------*/
/**
* @brief UART 组件初始化
* @note 仅支持已实现的串口
* @param[in] id: 串口 ID
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_Init(BSP_UART_ID id)
{
/* GPIO/UART/DMA 等的初始化代码已由 cubeMX 生成 */
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
if (uart->init)
return BSP_UART_ERR_NO_INIT;
BSP_UART_Port_Init( uart,
UART_RxIntHandler,
UART_RxIdleHandler,
UART_CopyDataToUserBuff,
UART_TxHandler);
BSP_INT_DIS();
uart->init = 1;
BSP_INT_EN();
return BSP_UART_ERR_OK;
}
/**
* @brief 使能UART接收数据
* @note
* @param[in] id: 串口 ID
* @param[in] data: 接收的数据池
* @param[in] len: 指示接收数据长度的变量
* @param[in] max_len: 数据池的最大容量,单位 byte
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_EnableReceive(BSP_UART_ID id, uint8_t *data, uint16_t *len, uint16_t max_len)
{
ASSERT(data != NULL && len != NULL && max_len != 0);
BSP_UART_ERR ret;
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
uart->rx_data = data;
uart->rx_data_len = len;
uart->rx_data_max_len = max_len;
ret = BSP_UART_Port_EnableReceive(uart);
BSP_INT_DIS();
uart->rx_init = 1;
BSP_INT_EN();
return ret;
}
/**
* @brief 禁止 UART 接收数据
* @note
* @param[in] id: 串口 ID
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_DisableReceive(BSP_UART_ID id)
{
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
BSP_INT_DIS();
uart->rx_init = 0;
BSP_INT_EN();
return BSP_UART_Port_DisableReceive(uart);
}
/**
* @brief 判断 UART 是否收到了一帧数据
* @note 该接口为轮询的方式
* @param[in] id: 串口 ID
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_IsFrameEnd(BSP_UART_ID id)
{
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
// BSP_INT_DIS();
if (uart->idle_flag == 0)
{
// BSP_INT_EN();
return BSP_UART_ERR_NO_RECV_FRAME;
}
else
{
uart->idle_flag = 0;
// BSP_INT_EN();
return BSP_UART_ERR_OK;
}
}
/**
* @brief 挂载一个用户自定义的数据到 UART 对象上
* @note
* @param[in] id: 串口 ID
* @param[in] user_data: 用户自定义数据
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_LinkUserData(BSP_UART_ID id, void *user_data)
{
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
uart->user_data = user_data;
return BSP_UART_ERR_OK;
}
/**
* @brief 设置 UART 的发送完成指示回调函数
* @note
* @param[in] id: 串口 ID
* @param[in] TX_Complete: 函数指针
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_SetTxIndicate(BSP_UART_ID id, uint8_t (*TX_Complete)(struct UART_STRUCT *uart))
{
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
uart->TX_Complete = TX_Complete;
return BSP_UART_ERR_OK;
}
/**
* @brief 从 UART 发出一些数据
* @note 若使用 RTOS ,则 BSP_UART_Send、 BSP_UART_SendBlocking 均不能在中断中使用
* @param[in] id: 串口ID
* @param[in] data: 要发送的数据池
* @param[in] len: 要发送的数据长度,单位 byte
* @param[in] timeout: 发送最大超时等待时间,单位 ms
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_Send(BSP_UART_ID id, const uint8_t *data, uint16_t len, uint16_t timeout)
{
ASSERT(data != NULL && len != 0);
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
if (uart->init == 0)
return BSP_UART_ERR_NO_INIT;
return BSP_UART_Port_Send(uart, data, len, timeout);
}
/**
* @brief 清除用户传入的 UART 数据缓存池
* @note
* @param[in] id: 串口 ID
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_ClearUserBuff(BSP_UART_ID id)
{
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
BSP_INT_DIS();
if (uart->rx_data_len)
*(uart->rx_data_len) = 0;
BSP_INT_EN();
return BSP_UART_ERR_OK;
}
/* Private functions ---------------------------------------------------------*/
/**
* @brief 将 DMA 缓存池的 UART 数据搬运到用户数据池中
* @note
* @param[in] uart: UART 对象
* @retval None
*/
static void UART_CopyDataToUserBuff(struct UART_STRUCT *uart)
{
if (*(uart->rx_data_len) >= uart->rx_data_max_len)
return;
// BSP_INT_DIS();
uint8_t *user_buff = &uart->rx_data[0];
uint16_t *user_buff_len = (uint16_t *)(uart->rx_data_len);
uint16_t new_pos = uart->rx_buff_max_len - BSP_UART_Port_GetDmaCounter(uart); /* 计算缓冲区的接收字节数 */
uint16_t recv_len = 0;
if (new_pos != uart->old_pos) /* 收到新的数据 */
{
if (new_pos > uart->old_pos) /* 线性模式 */
{
recv_len = new_pos - uart->old_pos; /* 计算本次接收到的字节数 */
/* 数据超出用户 buff ,只能接收用户 buff 剩余空间的长度数据 */
if ((*user_buff_len) + recv_len > uart->rx_data_max_len)
{
recv_len = uart->rx_data_max_len - *user_buff_len;
}
memcpy(&user_buff[*user_buff_len], &uart->rx_buff[ uart->old_pos ], recv_len);
(*user_buff_len) += recv_len; /* 设置偏移量 */
}
else /* 溢出模式 */
{
/* 先处理未溢出的部分 */
recv_len = uart->rx_buff_max_len - uart->old_pos;
/* 数据超出用户 buff ,只能接收用户 buff 剩余空间的长度数据 */
if (*user_buff_len + recv_len > uart->rx_data_max_len)
{
recv_len = uart->rx_data_max_len - *user_buff_len;
}
memcpy(&user_buff[*user_buff_len], &uart->rx_buff[ uart->old_pos ], recv_len);
*user_buff_len += recv_len; /* 设置偏移量 */
/* 再处理溢出的部分 */
recv_len = new_pos;
if (recv_len != 0)
{
/* 数据超出用户 buff ,只能接收用户 buff 剩余空间的长度数据 */
if (*user_buff_len + recv_len > uart->rx_data_max_len)
{
recv_len = uart->rx_data_max_len - *user_buff_len;
}
memcpy(&user_buff[*user_buff_len], &uart->rx_buff[0], recv_len);
(*user_buff_len) += recv_len; /* 设置偏移量 */
}
}
}
uart->old_pos = new_pos;
if (uart->old_pos >= uart->rx_buff_max_len)
{
uart->old_pos = 0;
}
// BSP_INT_EN();
}
/**
* @brief 串口接收到单字节数据的中断处理函数
* @note
* @param[in] uart: UART 对象
* @retval None
*/
static void UART_RxIntHandler(struct UART_STRUCT *uart)
{
if (uart->rx_init == 0)
return;
uart->rx_data[ *(uart->rx_data_len) ] = (uint8_t)BSP_UART_Port_GetOneByte(uart);
*(uart->rx_data_len) += 1;
if (*(uart->rx_data_len) == uart->rx_data_max_len)
{
*(uart->rx_data_len) = 0;
}
}
/**
* @brief 串口发生空闲中断的处理函数
* @note
* @param[in] uart: UART 对象
* @retval None
*/
static void UART_RxIdleHandler(struct UART_STRUCT *uart)
{
if (uart->rx_init == 0)
return;
// BSP_INT_DIS();
uart->idle_flag = 1;
// BSP_INT_EN();
if (uart->handle.hdmarx)
UART_CopyDataToUserBuff(uart);
BSP_UART_Port_RxUnlock(uart);
}
/**
* @brief 串口发送完成的中断处理函数
* @note
* @param[in] uart: UART 对象
* @retval None
*/
static void UART_TxHandler(struct UART_STRUCT *uart)
{
BSP_UART_Port_TxUnlock(uart);
if (uart->TX_Complete)
uart->TX_Complete(uart);
}