/** * Change Logs: * 增加 __HAL_UART_FLUSH_DRREGISTER */ /* Includes ------------------------------------------------------------------*/ #include "bsp_uart.h" /* Private variables ---------------------------------------------------------*/ #if (BSP_USING_UART2_RE || BSP_USING_UART3_RE) static volatile uint8_t _uart2_alter; static volatile uint8_t _uart3_alter; #endif static UART_Callback_t _UART_RxCallback; static UART_Callback_t _UART_RxIdleCallback; static UART_Callback_t _UART_DMA_RxCallback; static UART_Callback_t _UART_DMA_TxCallback; #if (BSP_USING_UART1) UART_CREATE(1); #endif #if (BSP_USING_UART2) UART_CREATE(2); #endif #if (BSP_USING_UART2_RE) UART_CREATE(2_RE); #endif #if (BSP_USING_UART3) UART_CREATE(3); #endif #if (BSP_USING_UART3_RE) UART_CREATE(3_RE); #endif #if (BSP_USING_UART4) UART_CREATE(4); #endif #if (BSP_USING_UART5) UART_CREATE(5); #endif #if (BSP_USING_UART6) UART_CREATE(6); #endif struct UART_STRUCT *_uart_group[] = { #if (BSP_USING_UART1) &UART(1), #endif #if (BSP_USING_UART2) &UART(2), #endif #if (BSP_USING_UART2_RE) &UART(2_RE), #endif #if (BSP_USING_UART3) &UART(3), #endif #if (BSP_USING_UART3_RE) &UART(3_RE), #endif #if (BSP_USING_UART4) &UART(4), #endif #if (BSP_USING_UART5) &UART(5), #endif #if (BSP_USING_UART6) &UART(6), #endif }; static const uint8_t _uart_qty = sizeof(_uart_group) / sizeof(struct UART_STRUCT *); /* Private function prototypes -----------------------------------------------*/ static inline void _UART_IntHandler (struct UART_STRUCT *uart); static inline void _UART_Alternate (struct UART_STRUCT *uart); /* Exported functions ---------------------------------------------------------*/ /** * @brief UART 接口初始? * @note 需?UART 外设初始化后或本函数处进?UART 外设初始化后才可调用 * @param[in] uart: UART 对象 * @param[in] rx_callback: 接收单字节数据中断的回调函数 * @param[in] rx_idle_callback: 空闲中断的回调函? * @param[in] dma_rx_callback: DMA 接收中断的回调函? * @param[in] dma_tx_callback: DMA 发送完成的回调函数 * @retval None */ void BSP_UART_Port_Init( struct UART_STRUCT *uart, UART_Callback_t rx_callback, UART_Callback_t rx_idle_callback, UART_Callback_t dma_rx_callback, UART_Callback_t dma_tx_callback) { BSP_UART_Port_LockInit(uart); _UART_RxCallback = rx_callback; _UART_RxIdleCallback = rx_idle_callback; _UART_DMA_RxCallback = dma_rx_callback; _UART_DMA_TxCallback = dma_tx_callback; /** * ?uart->handle 的外设由系统初始化时,例?CubeMX 生成的初始化代码,以下赋值操作是必须的? * 否则,需要自己将 uart->handle 初始化? * 由此可见?BSP_UART_Port_Init 需?UART 外设初始化后或本函数处进?UART 外设初始化后才可调用? */ switch (uart->id) { #if (BSP_USING_UART1) case BSP_UART1: uart->handle = UART1_HANDLE; break; #endif #if (BSP_USING_UART2) case BSP_UART2: uart->handle = UART2_HANDLE; break; #endif #if (BSP_USING_UART2_RE) case BSP_UART2_RE: uart->handle = UART2_HANDLE; break; #endif #if (BSP_USING_UART3) case BSP_UART3: uart->handle = UART3_HANDLE; break; #endif #if (BSP_USING_UART3_RE) case BSP_UART3_RE: uart->handle = UART3_HANDLE; break; #endif #if (BSP_USING_UART4) case BSP_UART4: uart->handle = UART4_HANDLE; break; #endif #if (BSP_USING_UART5) case BSP_UART5: uart->handle = UART5_HANDLE; break; #endif #if (BSP_USING_UART6) case BSP_UART6: uart->handle = UART6_HANDLE; break; #endif default: break; } if (uart->handle.hdmatx) uart->handle.hdmatx->Parent = &uart->handle; /* Clean the input path */ __HAL_UART_FLUSH_DRREGISTER(&uart->handle); } /** * @brief UART 接口通信控制锁的初始? * @note * @param[in] uart: UART 对象 * @retval BSP_UART_ERR */ BSP_UART_ERR BSP_UART_Port_LockInit(struct UART_STRUCT *uart) { return BSP_UART_ERR_OK; } /** * @brief UART 等待接收数据的信号锁 * @note * @param[in] uart: UART 对象 * @retval BSP_UART_ERR */ inline BSP_UART_ERR BSP_UART_Port_RxLock(struct UART_STRUCT *uart) { return BSP_UART_ERR_OK; } /** * @brief UART 接收到数据发出的信号? * @note * @param[in] uart: UART 对象 * @retval BSP_UART_ERR */ inline BSP_UART_ERR BSP_UART_Port_RxUnlock(struct UART_STRUCT *uart) { return BSP_UART_ERR_OK; } /** * @brief UART 发送锁 * @note * @param[in] uart: UART 对象 * @retval BSP_UART_ERR */ inline BSP_UART_ERR BSP_UART_Port_TxLock(struct UART_STRUCT *uart) { return BSP_UART_ERR_OK; } /** * @brief UART 发送完毕解? * @note * @param[in] uart: UART 对象 * @retval BSP_UART_ERR */ inline BSP_UART_ERR BSP_UART_Port_TxUnlock(struct UART_STRUCT *uart) { return BSP_UART_ERR_OK; } /** * @brief 使能 UART 接收数据 * @note * @param[in] uart: UART 对象 * @retval BSP_UART_ERR */ BSP_UART_ERR BSP_UART_Port_EnableReceive(struct UART_STRUCT *uart) { BSP_UART_ERR ret = BSP_UART_ERR_OK; if (uart->handle.hdmarx) uart->handle.hdmarx->Parent = &uart->handle; _UART_Alternate(uart); if (uart->handle.hdmarx) ret = (BSP_UART_ERR)HAL_UART_Receive_DMA(&uart->handle, (uint8_t *)uart->rx_buff, uart->rx_buff_max_len); else __HAL_UART_ENABLE_IT(&uart->handle, UART_IT_RXNE); /* 开启空闲中?*/ __HAL_UART_ENABLE_IT(&uart->handle, UART_IT_IDLE); return ret; } /** * @brief 禁止 UART 接收数据 * @note * @param[in] uart: UART 对象 * @retval BSP_UART_ERR */ BSP_UART_ERR BSP_UART_Port_DisableReceive(struct UART_STRUCT *uart) { BSP_UART_ERR ret = BSP_UART_ERR_OK; if (uart->handle.hdmarx) ret = (BSP_UART_ERR)HAL_UART_DMAPause(&uart->handle); else __HAL_UART_DISABLE_IT(&uart->handle, UART_IT_RXNE); __HAL_UART_DISABLE_IT(&uart->handle, UART_IT_IDLE); return ret; } /** * @brief 控制 UART 发送一帧数? * @note * @param[in] uart: UART 对象 * @param[in] data: 要发送的数据 * @param[in] len: 要发送的数据长度,单?byte。最大长? 65535 byte * @param[in] timeout: 最大处理超时时间,单位 ms。最大指定时? 65535 ms * @retval BSP_UART_ERR */ BSP_UART_ERR BSP_UART_Port_Send(struct UART_STRUCT *uart, const uint8_t *data, uint16_t len, uint16_t timeout) { _UART_Alternate(uart); if (timeout == 0) { if (uart->handle.hdmatx) return (BSP_UART_ERR)HAL_UART_Transmit_DMA(&uart->handle, (uint8_t *)data, len); else return (BSP_UART_ERR)HAL_UART_Transmit_IT(&uart->handle, (uint8_t *)data, len); } else return (BSP_UART_ERR)HAL_UART_Transmit(&uart->handle, (uint8_t *)data, len, timeout); } /** * @brief ?UART 获取一个字节的数据 * @note * @param[in] uart: UART 对象 * @retval UART 数据 */ inline uint32_t BSP_UART_Port_GetOneByte(struct UART_STRUCT *uart) { return uart->handle.Instance->DR; } /** * @brief 获取 DMA 当前的计? * @note * @param[in] uart: UART 对象 * @retval 计数? */ inline uint32_t BSP_UART_Port_GetDmaCounter(struct UART_STRUCT *uart) { return __HAL_DMA_GET_COUNTER(uart->handle.hdmarx); } /** * @brief 通过 UART ID 获取 UART 对象 * @note * @param[in] id: 串口 ID * @retval NULL: 无效?ID。非 NULL: UART 对象 */ struct UART_STRUCT *BSP_UART_Port_GetHandle(BSP_UART_ID id) { for (uint8_t i = 0; i < _uart_qty; i++) { if (_uart_group[i]->id == id) { return _uart_group[i]; } } return NULL; } /* Private functions ---------------------------------------------------------*/ /** * @brief UART 中断的集中处? * @note * @param[in] uart: UART 对象 * @retval None */ static inline void _UART_IntHandler(struct UART_STRUCT *uart) { if (uart->handle.Instance == NULL) return; if (__HAL_UART_GET_FLAG(&uart->handle, UART_FLAG_RXNE) != RESET) { /* RXNE 中断标志位会在读?DR 寄存器的时候清零,但无法确?_UART_RxCallback 是否会读取DR寄存器, 所以在此处进行一次清?*/ __HAL_UART_CLEAR_FLAG(&uart->handle, UART_FLAG_RXNE); if (_UART_RxCallback) _UART_RxCallback(uart); } else if ((__HAL_UART_GET_FLAG(&uart->handle, UART_FLAG_IDLE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&uart->handle, UART_IT_IDLE) != RESET)) { /* IDLE 中断标志位只能软件清?*/ __HAL_UART_CLEAR_IDLEFLAG(&uart->handle); if (_UART_RxIdleCallback) _UART_RxIdleCallback(uart); } else { HAL_UART_IRQHandler(&(uart->handle)); } } /** * @brief 串口复用切换函数 * @note * @param[in] uart: UART 对象 * @retval None */ static inline void _UART_Alternate(struct UART_STRUCT *uart) { #if (BSP_USING_UART2_RE || BSP_USING_UART3_RE) switch (uart->id) { case BSP_UART2: case BSP_UART2_RE: { if (_uart2_alter != uart->id) /* 复用切换 */ { if (uart->id == BSP_UART2) { BSP_GPIO_SetMode(GET_PIN(A, 2), GPIO_MODE_AF_PP, GPIO_PULLUP); /* TX */ BSP_GPIO_SetMode(GET_PIN(A, 3), GPIO_MODE_INPUT, GPIO_PULLUP); /* RX */ __HAL_AFIO_REMAP_USART2_DISABLE(); } else { BSP_GPIO_SetMode(GET_PIN(D, 5), GPIO_MODE_AF_PP, GPIO_PULLUP); /* TX */ BSP_GPIO_SetMode(GET_PIN(D, 6), GPIO_MODE_INPUT, GPIO_PULLUP); /* RX */ __HAL_AFIO_REMAP_USART2_ENABLE(); } _uart2_alter = uart->id; } break; } case BSP_UART3: case BSP_UART3_RE: { if (_uart3_alter != uart->id) /* 复用切换 */ { if (uart->id == BSP_UART3) { BSP_GPIO_SetMode(GET_PIN(B, 10), GPIO_MODE_AF_PP, GPIO_PULLUP); /* TX */ BSP_GPIO_SetMode(GET_PIN(B, 11), GPIO_MODE_INPUT, GPIO_PULLUP); /* RX */ __HAL_AFIO_REMAP_USART3_DISABLE(); } else { BSP_GPIO_SetMode(GET_PIN(D, 8), GPIO_MODE_AF_PP, GPIO_PULLUP); /* TX */ BSP_GPIO_SetMode(GET_PIN(D, 9), GPIO_MODE_INPUT, GPIO_PULLUP); /* RX */ __HAL_AFIO_REMAP_USART3_ENABLE(); } _uart3_alter = uart->id; } break; } default: break; } #endif } /* Callback functions ---------------------------------------------------------*/ /* 以下 4 个函数均?HAL ?UART 相关的中断函数的回调函数 */ /* UART DMA 接收半满中断 */ void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) { struct UART_STRUCT *uart = (struct UART_STRUCT *)huart; if (_UART_DMA_RxCallback) _UART_DMA_RxCallback(uart); } /* UART DMA 接收全满中断 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { struct UART_STRUCT *uart = (struct UART_STRUCT *)huart; if (_UART_DMA_RxCallback) _UART_DMA_RxCallback(uart); } /* UART DMA 发送完成中?*/ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { struct UART_STRUCT *uart = (struct UART_STRUCT *)huart; if (_UART_DMA_TxCallback) _UART_DMA_TxCallback(uart); } /* UART 中断检测到错误的回调函?*/ void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) { struct UART_STRUCT *uart = (struct UART_STRUCT *)huart; //printf("%s: %d %d\r\n", __FUNCTION__, uart->id, huart->ErrorCode); } /* Interrupt request functions ---------------------------------------------------------*/ #if (BSP_USING_UART1) void USART1_IRQHandler(void) { BSP_INT_ENTER(); _UART_IntHandler(&UART(1)); BSP_INT_EXIT(); } void UART1_DMA_RX_IRQHandler(void) { BSP_INT_ENTER(); if (UART(1).rx_init) { HAL_DMA_IRQHandler(UART(1).handle.hdmarx); } BSP_INT_EXIT(); } void UART1_DMA_TX_IRQHandler(void) { BSP_INT_ENTER(); HAL_DMA_IRQHandler(UART(1).handle.hdmatx); BSP_INT_EXIT(); } #endif #if (BSP_USING_UART2) void USART2_IRQHandler(void) { BSP_INT_ENTER(); #if (BSP_USING_UART2_RE) if (_uart2_alter == BSP_UART2) _UART_IntHandler(&UART(2)); else _UART_IntHandler(&UART(2_RE)); #else _UART_IntHandler(&UART(2)); #endif BSP_INT_EXIT(); } void UART2_DMA_RX_IRQHandler(void) { BSP_INT_ENTER(); if (UART(2).rx_init) { #if (BSP_USING_UART2_RE) if (_uart2_alter == BSP_UART2) HAL_DMA_IRQHandler(UART(2).handle.hdmarx); else HAL_DMA_IRQHandler(UART(2_RE).handle.hdmarx); #else HAL_DMA_IRQHandler(UART(2).handle.hdmarx); #endif } BSP_INT_EXIT(); } void UART2_DMA_TX_IRQHandler(void) { BSP_INT_ENTER(); #if (BSP_USING_UART2_RE) if (_uart2_alter == BSP_UART2) HAL_DMA_IRQHandler(UART(2).handle.hdmatx); else HAL_DMA_IRQHandler(UART(2_RE).handle.hdmarx); #else HAL_DMA_IRQHandler(UART(2).handle.hdmarx); #endif BSP_INT_EXIT(); } #endif #if (BSP_USING_UART3) void USART3_IRQHandler(void) { BSP_INT_ENTER(); #if (BSP_USING_UART3_RE) if (_uart3_alter == BSP_UART3) _UART_IntHandler(&UART(3)); else _UART_IntHandler(&UART(3_RE)); #else _UART_IntHandler(&UART(3)); #endif BSP_INT_EXIT(); } void UART3_DMA_RX_IRQHandler(void) { BSP_INT_ENTER(); if (UART(3).rx_init) { #if (BSP_USING_UART3_RE) if (_uart3_alter == BSP_UART3) HAL_DMA_IRQHandler(UART(3).handle.hdmarx); else HAL_DMA_IRQHandler(UART(3_RE).handle.hdmarx); #else HAL_DMA_IRQHandler(UART(3).handle.hdmarx); #endif } BSP_INT_EXIT(); } void UART3_DMA_TX_IRQHandler(void) { BSP_INT_ENTER(); #if (BSP_USING_UART3_RE) if (_uart3_alter == BSP_UART3) HAL_DMA_IRQHandler(UART(3).handle.hdmarx); else HAL_DMA_IRQHandler(UART(3_RE).handle.hdmarx); #else HAL_DMA_IRQHandler(UART(3).handle.hdmarx); #endif BSP_INT_EXIT(); } #endif #if (BSP_USING_UART4) void UART4_IRQHandler(void) { BSP_INT_ENTER(); _UART_IntHandler(&UART(4)); BSP_INT_EXIT(); } void UART4_DMA_RX_IRQHandler(void) { BSP_INT_ENTER(); if (UART(4).rx_init) { HAL_DMA_IRQHandler(UART(4).handle.hdmarx); } BSP_INT_EXIT(); } void UART4_DMA_TX_IRQHandler(void) { BSP_INT_ENTER(); HAL_DMA_IRQHandler(UART(4).handle.hdmatx); BSP_INT_EXIT(); } #endif #if (BSP_USING_UART5) void UART5_IRQHandler(void) { BSP_INT_ENTER(); _UART_IntHandler(&UART(5)); BSP_INT_EXIT(); } void UART5_DMA_RX_IRQHandler(void) { BSP_INT_ENTER(); if (UART(5).rx_init) { HAL_DMA_IRQHandler(UART(5).handle.hdmarx); } BSP_INT_EXIT(); } void UART5_DMA_TX_IRQHandler(void) { BSP_INT_ENTER(); HAL_DMA_IRQHandler(UART(5).handle.hdmatx); BSP_INT_EXIT(); } #endif #if (BSP_USING_UART6) void USART6_IRQHandler(void) { BSP_INT_ENTER(); _UART_IntHandler(&UART(6)); BSP_INT_EXIT(); } void UART6_DMA_RX_IRQHandler(void) { BSP_INT_ENTER(); if (UART(6).rx_init) { HAL_DMA_IRQHandler(UART(6).handle.hdmarx); } BSP_INT_EXIT(); } void UART6_DMA_TX_IRQHandler(void) { BSP_INT_ENTER(); HAL_DMA_IRQHandler(UART(6).handle.hdmatx); BSP_INT_EXIT(); } #endif