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 &&