drivers: serial: fix STM32 async uart driver

Fix a bug that causes not handling an IDLE line detection interrupt for
some STM chips, e.g. STM32F412. It impacts the async UART
communication - an information that data have been recieved is lost.

The issue occurs when the IDLE flag is set during handling another UART
interrupt, e.g Transmission complete. The ISR calls uart_stm32_err_check
function, which clears the noise error flag with LL_USART_ClearFlag_NE
without any additional checks. Unfortunately, clearing the noise flag
also clears the IDLE flag for some chips(an read to the USART_SR
register followed by a read to the USART_DR register for STM32F412
clears PE, FE, NF, ORE and IDLE flags), hence the ISR is not called
again for the IDLE event. The IDLE flag is no longer set.

Add checking the noise flag before clearing it.

Signed-off-by: Dawid Niedzwiecki <dn@semihalf.com>
This commit is contained in:
Dawid Niedzwiecki 2023-01-03 09:38:48 +01:00 committed by Carles Cufí
commit 4a2a512c11

View file

@ -616,6 +616,10 @@ static int uart_stm32_err_check(const struct device *dev)
err |= UART_ERROR_FRAMING;
}
if (LL_USART_IsActiveFlag_NE(config->usart)) {
err |= UART_ERROR_NOISE;
}
#if !defined(CONFIG_SOC_SERIES_STM32F0X) || defined(USART_LIN_SUPPORT)
if (LL_USART_IsActiveFlag_LBD(config->usart)) {
err |= UART_BREAK;
@ -641,10 +645,10 @@ static int uart_stm32_err_check(const struct device *dev)
if (err & UART_ERROR_FRAMING) {
LL_USART_ClearFlag_FE(config->usart);
}
/* Clear noise error as well,
* it is not represented by the errors enum
*/
LL_USART_ClearFlag_NE(config->usart);
if (err & UART_ERROR_NOISE) {
LL_USART_ClearFlag_NE(config->usart);
}
return err;
}