From 4a2a512c118d8133ae6ecb69920bc9a707a95443 Mon Sep 17 00:00:00 2001 From: Dawid Niedzwiecki Date: Tue, 3 Jan 2023 09:38:48 +0100 Subject: [PATCH] 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 --- drivers/serial/uart_stm32.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/serial/uart_stm32.c b/drivers/serial/uart_stm32.c index d8c63cdbf13..4cfdb5e36ef 100644 --- a/drivers/serial/uart_stm32.c +++ b/drivers/serial/uart_stm32.c @@ -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; }