/** * 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); }