This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 706e098afce arch/arm/src/common/stm32: disable USART while changing 
line format
706e098afce is described below

commit 706e098afce6d352328fc3a9d412a2b3e2ce58fa
Author: Swatantra Yadav <[email protected]>
AuthorDate: Wed Nov 4 01:53:04 2026 +0530

    arch/arm/src/common/stm32: disable USART while changing line format
    
    In stm32serial_setformat(), BRR, CR2 STOP bits, and the PCE, PS,
    and M0/M1 bits of CR1 were modified with the USART enabled. Per
    the ST Reference Manuals (e.g., RM0456 for STM32H5, RM0454 for STM32U5,
    RM0438 for STM32L5, and RM0481 for STM32C5), these registers and bits
    can only be written while UE = 0. Modifying them while UE = 1 is ignored
    by the hardware, so a run-time tcsetattr() call attempting to change
    baud rate, parity, or word length returned success while leaving the
    hardware USART registers unchanged.
    
    Clear UE before updating the line configuration and restore it
    afterwards inside a critical section, aligning stm32_serial_m33_v3.c with
    the approved implementations in STM32N6 (commit 2b1b82c73b), STM32WL5
    (PR #21336), STM32WB (PR #21334), and STM32L4 (commit 47180bf5ea).
    
    Signed-off-by: Swatantra Yadav <[email protected]>
    Assisted-by: Google Gemini
---
 arch/arm/src/common/stm32/stm32_serial_m33_v3.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/src/common/stm32/stm32_serial_m33_v3.c 
b/arch/arm/src/common/stm32/stm32_serial_m33_v3.c
index e7209c8a9eb..e0267bfdbd5 100644
--- a/arch/arm/src/common/stm32/stm32_serial_m33_v3.c
+++ b/arch/arm/src/common/stm32/stm32_serial_m33_v3.c
@@ -1575,8 +1575,21 @@ static void stm32serial_setformat(struct uart_dev_s *dev)
   struct stm32_serial_s *priv =
     (struct stm32_serial_s *)dev->priv;
   uint32_t regval;
+  uint32_t cr1_ue;
   uint32_t brr;
   uint32_t cr1;
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  /* Disable UE: the baud rate, parity and word length bits can not be
+   * written while UE = 1.
+   */
+
+  regval = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET);
+  cr1_ue = regval & USART_CR1_UE;
+  stm32serial_putreg(priv, STM32_USART_CR1_OFFSET,
+                     regval & ~USART_CR1_UE);
 
   /* This first implementation is for U[S]ARTs that support oversampling
    * by 8 in additional to the standard oversampling by 16.  The LPUART
@@ -1792,6 +1805,13 @@ static void stm32serial_setformat(struct uart_dev_s *dev)
 #endif
 
   stm32serial_putreg(priv, STM32_USART_CR3_OFFSET, regval);
+
+  /* Restore UE */
+
+  regval = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET);
+  stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, regval | cr1_ue);
+
+  leave_critical_section(flags);
 }
 #endif /* CONFIG_SUPPRESS_UART_CONFIG */
 

Reply via email to