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

commit 5d98f73cca6dd9a300f13293cfbe0d285fef4170
Author: raiden00pl <[email protected]>
AuthorDate: Tue Oct 20 18:56:50 2026 +0200

    arch/arm/nrf54l: keep a UART byte received with the delivery disabled
    
    rxint(false) only gated the delivery, so a byte completed by DMA in the
    window uart_read leaves before rxint(true) was dropped. Keep it and
    restart the DMA when the upper half takes it.
    
    Assisted-by: Claude Code
    Signed-off-by: raiden00pl <[email protected]>
---
 arch/arm/src/nrf54l/nrf54l_serial.c | 49 ++++++++++++++++++++++++++++---------
 1 file changed, 37 insertions(+), 12 deletions(-)

diff --git a/arch/arm/src/nrf54l/nrf54l_serial.c 
b/arch/arm/src/nrf54l/nrf54l_serial.c
index 7d60272d18f..bbd5d87247d 100644
--- a/arch/arm/src/nrf54l/nrf54l_serial.c
+++ b/arch/arm/src/nrf54l/nrf54l_serial.c
@@ -539,6 +539,31 @@ static void nrf54l_rxstart(struct nrf54l_dev_s *priv)
   nrf54l_uart_putreg(priv, NRF54L_UARTE_TASKS_STARTRX_OFFSET, 1);
 }
 
+/****************************************************************************
+ * Name: nrf54l_rxdeliver
+ *
+ * Description:
+ *   Deliver the completed byte and restart the one-byte DMA. A byte
+ *   received with the delivery disabled is kept, the UART FIFO holds the
+ *   next bytes until rxint() enables the delivery.
+ *
+ ****************************************************************************/
+
+static void nrf54l_rxdeliver(struct uart_dev_s *dev)
+{
+  struct nrf54l_dev_s *priv = dev->priv;
+
+  if (priv->rxvalid && priv->rxenabled)
+    {
+      uart_recvchars(dev);
+      if (!priv->rxvalid)
+        {
+          UP_DMB();
+          nrf54l_uart_putreg(priv, NRF54L_UARTE_TASKS_STARTRX_OFFSET, 1);
+        }
+    }
+}
+
 /****************************************************************************
  * Name: nrf54l_rxstop
  *
@@ -770,7 +795,7 @@ static int nrf54l_interrupt(int irq, void *context, void 
*arg)
   else
     {
       /* Copy the completed byte before restarting DMA. Automatic END-to-
-       * START would let DMA overwrite a buffer before the interrupt handler
+       * START would let DMA overwrite a buffer before the upper half
        * consumes it. The UART FIFO holds incoming bytes between transfers.
        */
 
@@ -780,16 +805,9 @@ static int nrf54l_interrupt(int irq, void *context, void 
*arg)
           UP_DMB();
           priv->rxchar = priv->rxdma;
           priv->rxvalid = true;
-          UP_DMB();
-          nrf54l_uart_putreg(priv, NRF54L_UARTE_TASKS_STARTRX_OFFSET, 1);
         }
 
-      if (priv->rxvalid && priv->rxenabled)
-        {
-          uart_recvchars(dev);
-        }
-
-      priv->rxvalid = false;
+      nrf54l_rxdeliver(dev);
       nrf54l_uart_clrevent(priv, NRF54L_UARTE_EVENTS_RXTO_OFFSET);
     }
 
@@ -1045,12 +1063,19 @@ static int nrf54l_receive(struct uart_dev_s *dev, 
unsigned int *status)
 static void nrf54l_rxint(struct uart_dev_s *dev, bool enable)
 {
   struct nrf54l_dev_s *priv = dev->priv;
+  irqstate_t flags = enter_critical_section();
 
 #ifdef CONFIG_SUPPRESS_SERIAL_INTS
-  priv->rxenabled = false;
-#else
-  priv->rxenabled = enable;
+  enable = false;
 #endif
+
+  priv->rxenabled = enable;
+  if (enable)
+    {
+      nrf54l_rxdeliver(dev);
+    }
+
+  leave_critical_section(flags);
 }
 
 /****************************************************************************

Reply via email to