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

simbit18 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 9777dfc83f9 arch/arm/src/common/stm32: Flush serial RX DMA buffer on 
idle line
9777dfc83f9 is described below

commit 9777dfc83f98fee6acd7929c6bb1ee084ad9a03b
Author: raiden00pl <[email protected]>
AuthorDate: Wed Aug 26 14:37:56 2026 +0200

    arch/arm/src/common/stm32: Flush serial RX DMA buffer on idle line
    
    Enable the USART idle line interrupt when RX DMA is used and deliver
    any buffered fraction of RX data from the interrupt handler. Without
    this, received bytes below the DMA half-transfer threshold are not
    delivered until more data arrives.
    
    This is the same mechanism the stm32h7 serial driver uses. The other
    STM32 serial drivers rely on stm32_serial_dma_poll() being called
    periodically, which no in-tree board does.
    
    Signed-off-by: raiden00pl <[email protected]>
    Assisted-by: Claude Code
---
 arch/arm/src/common/stm32/stm32_serial_m33_v3.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

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 c17b35a9d16..28b4c8c7ec7 100644
--- a/arch/arm/src/common/stm32/stm32_serial_m33_v3.c
+++ b/arch/arm/src/common/stm32/stm32_serial_m33_v3.c
@@ -1458,6 +1458,9 @@ void stm32serial_setusartint(struct stm32_serial_s *priv,
   cr = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET);
   cr &= ~(USART_CR1_USED_INTS);
   cr |= (ie & (USART_CR1_USED_INTS));
+#ifdef SERIAL_HAVE_DMA
+  cr |= USART_CR1_IDLEIE;
+#endif
   stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr);
 
   cr = stm32serial_getreg(priv, STM32_USART_CR3_OFFSET);
@@ -2123,6 +2126,9 @@ static int stm32serial_setup(struct uart_dev_s *dev)
   regval      = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET);
   regval     |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE |
                  USART_CR1_FIFOEN);
+#ifdef SERIAL_HAVE_DMA
+  regval     |= USART_CR1_IDLEIE;
+#endif
   stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, regval);
 
 #endif /* CONFIG_SUPPRESS_UART_CONFIG */
@@ -2457,7 +2463,7 @@ static int stm32serial_interrupt(int irq, void *context, 
void *arg)
        *
        * Enable           Status         Meaning                Usage
        * ---------------- -------------- ---------------------- -------------
-       * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected     (not used)
+       * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected     (RX DMA)
        * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to
        *                                 be Read
        * "              " USART_ISR_ORE  Overrun Error Detected
@@ -2504,6 +2510,20 @@ static int stm32serial_interrupt(int irq, void *context, 
void *arg)
         }
 #endif
 
+#ifdef SERIAL_HAVE_DMA
+      /* The line going to idle, deliver any fraction of RX data */
+
+      if ((priv->sr & USART_ISR_IDLE) != 0)
+        {
+          stm32serial_putreg(priv, STM32_USART_ICR_OFFSET,
+                             USART_ICR_IDLECF);
+          if (priv->rxdma != NULL)
+            {
+              stm32serial_dmarxcallback(priv->rxdma, 0, priv);
+            }
+        }
+#endif
+
       /* Handle incoming, receive bytes. */
 
       if ((priv->sr & USART_ISR_RXNE) != 0 &&

Reply via email to