[HAL][UART] Add a new API HAL_UARTEx_GetRxEventType that could be used to retrieve the type of event that has led the RxEventCallback execution
diff --git a/Inc/stm32f2xx_hal_uart.h b/Inc/stm32f2xx_hal_uart.h index fca10bf..2c2f84d 100644 --- a/Inc/stm32f2xx_hal_uart.h +++ b/Inc/stm32f2xx_hal_uart.h
@@ -137,13 +137,24 @@ /** * @brief HAL UART Reception type definition * @note HAL UART Reception type value aims to identify which type of Reception is ongoing. - * It is expected to admit following values : + * This parameter can be a value of @ref UART_Reception_Type_Values : * HAL_UART_RECEPTION_STANDARD = 0x00U, * HAL_UART_RECEPTION_TOIDLE = 0x01U, */ typedef uint32_t HAL_UART_RxTypeTypeDef; /** + * @brief HAL UART Rx Event type definition + * @note HAL UART Rx Event type value aims to identify which type of Event has occurred + * leading to call of the RxEvent callback. + * This parameter can be a value of @ref UART_RxEvent_Type_Values : + * HAL_UART_RXEVENT_TC = 0x00U, + * HAL_UART_RXEVENT_HT = 0x01U, + * HAL_UART_RXEVENT_IDLE = 0x02U, + */ +typedef uint32_t HAL_UART_RxEventTypeTypeDef; + +/** * @brief UART handle Structure definition */ typedef struct __UART_HandleTypeDef @@ -166,6 +177,8 @@ __IO HAL_UART_RxTypeTypeDef ReceptionType; /*!< Type of ongoing reception */ + __IO HAL_UART_RxEventTypeTypeDef RxEventType; /*!< Type of Rx Event */ + DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */ DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */ @@ -381,7 +394,7 @@ * @} */ -/** @defgroup UART_RECEPTION_TYPE_Values UART Reception type values +/** @defgroup UART_Reception_Type_Values UART Reception type values * @{ */ #define HAL_UART_RECEPTION_STANDARD (0x00000000U) /*!< Standard reception */ @@ -390,6 +403,16 @@ * @} */ +/** @defgroup UART_RxEvent_Type_Values UART RxEvent type values + * @{ + */ +#define HAL_UART_RXEVENT_TC (0x00000000U) /*!< RxEvent linked to Transfer Complete event */ +#define HAL_UART_RXEVENT_HT (0x00000001U) /*!< RxEvent linked to Half Transfer event */ +#define HAL_UART_RXEVENT_IDLE (0x00000002U) +/** + * @} + */ + /** * @} */ @@ -734,6 +757,8 @@ HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); +HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(UART_HandleTypeDef *huart); + /* Transfer Abort functions */ HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart); HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart);
diff --git a/Src/stm32f2xx_hal_uart.c b/Src/stm32f2xx_hal_uart.c index b9eb54e..8014374 100644 --- a/Src/stm32f2xx_hal_uart.c +++ b/Src/stm32f2xx_hal_uart.c
@@ -414,6 +414,7 @@ huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; + huart->RxEventType = HAL_UART_RXEVENT_TC; return HAL_OK; } @@ -483,6 +484,7 @@ huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; + huart->RxEventType = HAL_UART_RXEVENT_TC; return HAL_OK; } @@ -563,6 +565,7 @@ huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; + huart->RxEventType = HAL_UART_RXEVENT_TC; return HAL_OK; } @@ -646,6 +649,7 @@ huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; + huart->RxEventType = HAL_UART_RXEVENT_TC; return HAL_OK; } @@ -688,6 +692,7 @@ huart->gState = HAL_UART_STATE_RESET; huart->RxState = HAL_UART_STATE_RESET; huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + huart->RxEventType = HAL_UART_RXEVENT_TC; /* Process Unlock */ __HAL_UNLOCK(huart); @@ -1635,6 +1640,7 @@ huart->ErrorCode = HAL_UART_ERROR_NONE; huart->RxState = HAL_UART_STATE_BUSY_RX; huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; + huart->RxEventType = HAL_UART_RXEVENT_TC; /* Init tickstart for timeout management */ tickstart = HAL_GetTick(); @@ -1672,6 +1678,7 @@ /* If Set, and data has already been received, this means Idle Event is valid : End reception */ if (*RxLen > 0U) { + huart->RxEventType = HAL_UART_RXEVENT_IDLE; huart->RxState = HAL_UART_STATE_READY; return HAL_OK; @@ -1758,6 +1765,7 @@ /* Set Reception type to reception till IDLE Event*/ huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; + huart->RxEventType = HAL_UART_RXEVENT_TC; status = UART_Start_Receive_IT(huart, pData, Size); @@ -1819,6 +1827,7 @@ /* Set Reception type to reception till IDLE Event*/ huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; + huart->RxEventType = HAL_UART_RXEVENT_TC; status = UART_Start_Receive_DMA(huart, pData, Size); @@ -1849,6 +1858,36 @@ } /** + * @brief Provide Rx Event type that has lead to RxEvent callback execution. + * @note When HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, progress + * of reception process is provided to application through calls of Rx Event callback (either default one + * HAL_UARTEx_RxEventCallback() or user registered one). As several types of events could occur (IDLE event, + * Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead + * to Rx Event callback execution. + * @note This function is expected to be called within the user implementation of Rx Event Callback, + * in order to provide the accurate value : + * In Interrupt Mode : + * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received) + * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of + * received data is lower than expected one) + * In DMA Mode : + * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received) + * - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received + * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of + * received data is lower than expected one). + * In DMA mode, RxEvent callback could be called several times; + * When DMA is configured in Normal Mode, HT event does not stop Reception process; + * When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process; + * @param huart UART handle. + * @retval Rx Event Type (returned value will be a value of @ref UART_RxEvent_Type_Values) + */ +HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(UART_HandleTypeDef *huart) +{ + /* Return Rx Event type value, as stored in UART handle */ + return(huart->RxEventType); +} + +/** * @brief Abort ongoing transfers (blocking mode). * @param huart UART handle. * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. @@ -2520,6 +2559,11 @@ /* Last bytes received, so no need as the abort is immediate */ (void)HAL_DMA_Abort(huart->hdmarx); } + + /* Initialize type of RxEvent that correspond to RxEvent callback execution; + In this case, Rx Event type is Idle Event */ + huart->RxEventType = HAL_UART_RXEVENT_IDLE; + #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) /*Call registered Rx Event callback*/ huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount)); @@ -2550,6 +2594,11 @@ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + /* Initialize type of RxEvent that correspond to RxEvent callback execution; + In this case, Rx Event type is Idle Event */ + huart->RxEventType = HAL_UART_RXEVENT_IDLE; + #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) /*Call registered Rx complete callback*/ huart->RxEventCallback(huart, nb_rx_data); @@ -2785,6 +2834,7 @@ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RWU); huart->gState = HAL_UART_STATE_READY; + huart->RxEventType = HAL_UART_RXEVENT_TC; /* Process Unlocked */ __HAL_UNLOCK(huart); @@ -2812,6 +2862,7 @@ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RWU); huart->gState = HAL_UART_STATE_READY; + huart->RxEventType = HAL_UART_RXEVENT_TC; /* Process Unlocked */ __HAL_UNLOCK(huart); @@ -3034,6 +3085,7 @@ static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) { UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + /* DMA Normal mode*/ if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U) { @@ -3057,6 +3109,10 @@ } } + /* Initialize type of RxEvent that correspond to RxEvent callback execution; + In this case, Rx Event type is Transfer Complete */ + huart->RxEventType = HAL_UART_RXEVENT_TC; + /* Check current reception Mode : If Reception till IDLE event has been selected : use Rx Event callback */ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) @@ -3092,6 +3148,10 @@ { UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + /* Initialize type of RxEvent that correspond to RxEvent callback execution; + In this case, Rx Event type is Half Transfer */ + huart->RxEventType = HAL_UART_RXEVENT_HT; + /* Check current reception Mode : If Reception till IDLE event has been selected : use Rx Event callback */ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) @@ -3613,6 +3673,9 @@ /* Rx process is completed, restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; + /* Initialize type of RxEvent to Transfer Complete */ + huart->RxEventType = HAL_UART_RXEVENT_TC; + /* Check current reception Mode : If Reception till IDLE event has been selected : */ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)