[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/stm32f4xx_hal_uart.h b/Inc/stm32f4xx_hal_uart.h
index 244bc85..e6ce82f 100644
--- a/Inc/stm32f4xx_hal_uart.h
+++ b/Inc/stm32f4xx_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/stm32f4xx_hal_uart.c b/Src/stm32f4xx_hal_uart.c
index f9ca9c7..043bf7a 100644
--- a/Src/stm32f4xx_hal_uart.c
+++ b/Src/stm32f4xx_hal_uart.c
@@ -420,6 +420,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;
}
@@ -489,6 +490,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;
}
@@ -569,6 +571,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;
}
@@ -652,6 +655,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;
}
@@ -694,6 +698,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);
@@ -1641,6 +1646,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();
@@ -1678,6 +1684,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;
@@ -1764,6 +1771,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);
@@ -1825,6 +1833,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);
@@ -1855,6 +1864,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.
@@ -2526,6 +2565,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));
@@ -2556,6 +2600,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);
@@ -2791,6 +2840,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);
@@ -2818,6 +2868,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);
@@ -3040,6 +3091,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)
{
@@ -3063,6 +3115,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)
@@ -3098,6 +3154,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)
@@ -3619,6 +3679,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)