[HAL][UART] Rework of UART_WaitOnFlagUntilTimeout() API to avoid being stuck forever when UART overrun error occurs and to enhance behavior
diff --git a/Inc/Legacy/stm32_hal_legacy.h b/Inc/Legacy/stm32_hal_legacy.h
index fc8bb49..0512ae6 100644
--- a/Inc/Legacy/stm32_hal_legacy.h
+++ b/Inc/Legacy/stm32_hal_legacy.h
@@ -1271,7 +1271,7 @@
#define TIM_TIM3_TI1_COMP1COMP2_OUT TIM_TIM3_TI1_COMP1_COMP2
#endif
-#if defined(STM32U5) || defined(STM32MP2)
+#if defined(STM32U5)
#define OCREF_CLEAR_SELECT_Pos OCREF_CLEAR_SELECT_POS
#define OCREF_CLEAR_SELECT_Msk OCREF_CLEAR_SELECT_MSK
#endif
diff --git a/Src/stm32l4xx_hal_uart.c b/Src/stm32l4xx_hal_uart.c
index d3c46ac..f7da1c9 100644
--- a/Src/stm32l4xx_hal_uart.c
+++ b/Src/stm32l4xx_hal_uart.c
@@ -1184,6 +1184,9 @@
{
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
{
+
+ huart->gState = HAL_UART_STATE_READY;
+
return HAL_TIMEOUT;
}
if (pdata8bits == NULL)
@@ -1201,6 +1204,8 @@
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
{
+ huart->gState = HAL_UART_STATE_READY;
+
return HAL_TIMEOUT;
}
@@ -1276,6 +1281,8 @@
{
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
{
+ huart->RxState = HAL_UART_STATE_READY;
+
return HAL_TIMEOUT;
}
if (pdata8bits == NULL)
@@ -3463,6 +3470,17 @@
/* Wait until TEACK flag is set */
if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
{
+ /* Disable TXE interrupt for the interrupt process */
+#if defined(USART_CR1_FIFOEN)
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE));
+#else
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE));
+#endif /* USART_CR1_FIFOEN */
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ __HAL_UNLOCK(huart);
+
/* Timeout occurred */
return HAL_TIMEOUT;
}
@@ -3474,6 +3492,19 @@
/* Wait until REACK flag is set */
if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error)
+ interrupts for the interrupt process */
+#if defined(USART_CR1_FIFOEN)
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
+#else
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+#endif /* USART_CR1_FIFOEN */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ huart->RxState = HAL_UART_STATE_READY;
+
+ __HAL_UNLOCK(huart);
+
/* Timeout occurred */
return HAL_TIMEOUT;
}
@@ -3511,43 +3542,39 @@
{
if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
{
- /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error)
- interrupts for the interrupt process */
-#if defined(USART_CR1_FIFOEN)
- ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE |
- USART_CR1_TXEIE_TXFNFIE));
-#else
- ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
-#endif /* USART_CR1_FIFOEN */
- ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
-
- huart->gState = HAL_UART_STATE_READY;
- huart->RxState = HAL_UART_STATE_READY;
-
- __HAL_UNLOCK(huart);
return HAL_TIMEOUT;
}
if (READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U)
{
+ if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) == SET)
+ {
+ /* Clear Overrun Error flag*/
+ __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
+
+ /* Blocking error : transfer is aborted
+ Set the UART state ready to be able to start again the process,
+ Disable Rx Interrupts if ongoing */
+ UART_EndRxTransfer(huart);
+
+ huart->ErrorCode = HAL_UART_ERROR_ORE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_ERROR;
+ }
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF) == SET)
{
/* Clear Receiver Timeout flag*/
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
- /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error)
- interrupts for the interrupt process */
-#if defined(USART_CR1_FIFOEN)
- ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE |
- USART_CR1_TXEIE_TXFNFIE));
-#else
- ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
-#endif /* USART_CR1_FIFOEN */
- ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+ /* Blocking error : transfer is aborted
+ Set the UART state ready to be able to start again the process,
+ Disable Rx Interrupts if ongoing */
+ UART_EndRxTransfer(huart);
- huart->gState = HAL_UART_STATE_READY;
- huart->RxState = HAL_UART_STATE_READY;
huart->ErrorCode = HAL_UART_ERROR_RTO;
/* Process Unlocked */