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

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

commit d4f31f73aafdc1a87eab147c348b42ce81a7ac46
Author: lccosy <[email protected]>
AuthorDate: Thu Jun 11 00:02:55 2026 +0800

    arch/arm/gd32f4: fix missing CTL selector bits in up_disableusartint.
    
    up_disableusartint() saves USART interrupt state from hardware CTL0-CTL3
    registers but omits the CTL selector bits (bits 24-27) in the encoded
    ie value. When up_restoreusartint() later restores interrupts, it uses
    ie >> 24 to determine which CTL register to write. Without selector bits
    this evaluates to 0, so no CTL register is updated and all interrupt
    enables (including RBNEIE) are permanently lost.
    
    This causes RX interrupts to never fire after any call to up_putc()
    (e.g. via syslog), making the serial console unable to receive input.
    
    Fix by adding the corresponding CTL selector bit (USART_CFG_CTLx_INT
    << USART_CFG_SHIFT) whenever a CTL register has active interrupt bits.
    
    Signed-off-by: lccosy <[email protected]>
---
 arch/arm/src/gd32f4/gd32f4xx_serial.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/arch/arm/src/gd32f4/gd32f4xx_serial.c 
b/arch/arm/src/gd32f4/gd32f4xx_serial.c
index 7291a9dceec..5ced798a320 100644
--- a/arch/arm/src/gd32f4/gd32f4xx_serial.c
+++ b/arch/arm/src/gd32f4/gd32f4xx_serial.c
@@ -1142,25 +1142,47 @@ static void up_disableusartint(struct up_dev_s *priv, 
uint32_t *ie)
     {
       uint32_t ctl;
 
+      ctl_ie = 0;
+
       /* Save interrupt in CTL0 register */
 
       ctl = up_serialin(priv, GD32_USART_CTL0_OFFSET);
-      ctl_ie = ((ctl & USART_CTL0_USED_INTS) >> USART_CFG_CTL0_INT_SHIFT);
+      if (ctl & USART_CTL0_USED_INTS)
+        {
+          ctl_ie |= ((ctl & USART_CTL0_USED_INTS) >>
+                       USART_CFG_CTL0_INT_SHIFT);
+          ctl_ie |= (USART_CFG_CTL0_INT << USART_CFG_SHIFT);
+        }
 
       /* Save interrupt in CTL1 register */
 
       ctl = up_serialin(priv, GD32_USART_CTL1_OFFSET);
-      ctl_ie |= ((ctl & USART_CTL1_USED_INTS) >> USART_CFG_CTL1_INT_SHIFT);
+      if (ctl & USART_CTL1_USED_INTS)
+        {
+          ctl_ie |= ((ctl & USART_CTL1_USED_INTS) >>
+                       USART_CFG_CTL1_INT_SHIFT);
+          ctl_ie |= (USART_CFG_CTL1_INT << USART_CFG_SHIFT);
+        }
 
       /* Save interrupt in CTL2 register */
 
       ctl = up_serialin(priv, GD32_USART_CTL2_OFFSET);
-      ctl_ie |= ((ctl & USART_CTL2_USED_INTS) << USART_CFG_CTL2_INT_SHIFT);
+      if (ctl & USART_CTL2_USED_INTS)
+        {
+          ctl_ie |= ((ctl & USART_CTL2_USED_INTS) <<
+                       USART_CFG_CTL2_INT_SHIFT);
+          ctl_ie |= (USART_CFG_CTL2_INT << USART_CFG_SHIFT);
+        }
 
       /* Save interrupt in CTL3 register */
 
       ctl = up_serialin(priv, GD32_USART_CTL3_OFFSET);
-      ctl_ie |= ((ctl & USART_CTL3_USED_INTS) << USART_CFG_CTL3_INT_SHIFT);
+      if (ctl & USART_CTL3_USED_INTS)
+        {
+          ctl_ie |= ((ctl & USART_CTL3_USED_INTS) <<
+                       USART_CFG_CTL3_INT_SHIFT);
+          ctl_ie |= (USART_CFG_CTL3_INT << USART_CFG_SHIFT);
+        }
 
       *ie = ctl_ie;
     }

Reply via email to