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 f77398c9b0123c5b25dfd56ceeecf7785c89667e
Author: raiden00pl <[email protected]>
AuthorDate: Tue Oct 20 19:40:24 2026 +0200

    arch/arm/nrf53,nrf91: stop a running UARTE transfer before the configuration
    
    nRF53 anomaly 44 and nRF91 anomaly 23: a UARTE transfer left running,
    e.g. by a bootloader, is not stopped by disabling the peripheral. Stop
    it with the UARTE enabled.
    
    Assisted-by: Claude Code
    Signed-off-by: raiden00pl <[email protected]>
---
 arch/arm/src/nrf53/hardware/nrf53_uarte.h |  2 ++
 arch/arm/src/nrf53/nrf53_lowputc.c        | 24 ++++++++++++++++++++++--
 arch/arm/src/nrf91/hardware/nrf91_uarte.h |  2 ++
 arch/arm/src/nrf91/nrf91_lowputc.c        | 24 ++++++++++++++++++++++--
 4 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/arch/arm/src/nrf53/hardware/nrf53_uarte.h 
b/arch/arm/src/nrf53/hardware/nrf53_uarte.h
index 9d76f039d9a..b0b673ed7a1 100644
--- a/arch/arm/src/nrf53/hardware/nrf53_uarte.h
+++ b/arch/arm/src/nrf53/hardware/nrf53_uarte.h
@@ -69,6 +69,8 @@
 #define NRF53_UARTE_TXD_PTR_OFFSET          0x0544  /* Data pointer */
 #define NRF53_UARTE_TXD_MAXCNT_OFFSET       0x0548  /* Maximum number of bytes 
in transmit buffer */
 #define NRF53_UARTE_TXD_AMOUNT_OFFSET       0x054c  /* Number of bytes 
transferred in the last transaction */
+#define NRF53_UARTE_RXSTATE_OFFSET          0x0564  /* Undocumented RX state, 
anomaly 44 */
+#define NRF53_UARTE_TXSTATE_OFFSET          0x0568  /* Undocumented TX state, 
anomaly 44 */
 #define NRF53_UARTE_CONFIG_OFFSET           0x056c  /* Configuration of parity 
and hardware flow control */
 
 #define NRF53_UART_TASKS_STARTRX_OFFSET     0x0000 /* Start UART receiver */
diff --git a/arch/arm/src/nrf53/nrf53_lowputc.c 
b/arch/arm/src/nrf53/nrf53_lowputc.c
index 2c6a8ef1441..ae497892911 100644
--- a/arch/arm/src/nrf53/nrf53_lowputc.c
+++ b/arch/arm/src/nrf53/nrf53_lowputc.c
@@ -333,8 +333,28 @@ void nrf53_usart_configure(uintptr_t base,
   uint32_t regval = 0;
 
   putreg32(0xffffffff, base + NRF53_UARTE_INTENCLR_OFFSET);
-  putreg32(1, base + NRF53_UARTE_TASKS_STOPRX_OFFSET);
-  putreg32(1, base + NRF53_UARTE_TASKS_STOPTX_OFFSET);
+
+  /* Anomaly 44: a transfer left running survives disabling the UARTE.
+   * Stop it with the UARTE enabled and wait for the receiver to stop.
+   */
+
+  if (getreg32(base + NRF53_UARTE_TXSTATE_OFFSET) != 0)
+    {
+      putreg32(1, base + NRF53_UARTE_TASKS_STOPTX_OFFSET);
+    }
+
+  if (getreg32(base + NRF53_UARTE_RXSTATE_OFFSET) != 0)
+    {
+      putreg32(NRF53_UARTE_ENABLE_ENABLE, base + NRF53_UARTE_ENABLE_OFFSET);
+      putreg32(1, base + NRF53_UARTE_TASKS_STOPRX_OFFSET);
+      while (getreg32(base + NRF53_UARTE_RXSTATE_OFFSET) != 0)
+        {
+        }
+
+      putreg32(getreg32(base + NRF53_UARTE_ERRORSRC_OFFSET),
+               base + NRF53_UARTE_ERRORSRC_OFFSET);
+    }
+
   putreg32(NRF53_UARTE_ENABLE_DISABLE, base + NRF53_UARTE_ENABLE_OFFSET);
 
   /* Set UART format */
diff --git a/arch/arm/src/nrf91/hardware/nrf91_uarte.h 
b/arch/arm/src/nrf91/hardware/nrf91_uarte.h
index 4246d6dbf05..05cc9e0b5cd 100644
--- a/arch/arm/src/nrf91/hardware/nrf91_uarte.h
+++ b/arch/arm/src/nrf91/hardware/nrf91_uarte.h
@@ -69,6 +69,8 @@
 #define NRF91_UARTE_TXD_PTR_OFFSET          0x0544  /* Data pointer */
 #define NRF91_UARTE_TXD_MAXCNT_OFFSET       0x0548  /* Maximum number of bytes 
in transmit buffer */
 #define NRF91_UARTE_TXD_AMOUNT_OFFSET       0x054c  /* Number of bytes 
transferred in the last transaction */
+#define NRF91_UARTE_RXSTATE_OFFSET          0x0564  /* Undocumented RX state, 
anomaly 23 */
+#define NRF91_UARTE_TXSTATE_OFFSET          0x0568  /* Undocumented TX state, 
anomaly 23 */
 #define NRF91_UARTE_CONFIG_OFFSET           0x056c  /* Configuration of parity 
and hardware flow control */
 
 #define NRF91_UART_TASKS_STARTRX_OFFSET     0x0000 /* Start UART receiver */
diff --git a/arch/arm/src/nrf91/nrf91_lowputc.c 
b/arch/arm/src/nrf91/nrf91_lowputc.c
index 70aa0a7b9e4..17739b654fd 100644
--- a/arch/arm/src/nrf91/nrf91_lowputc.c
+++ b/arch/arm/src/nrf91/nrf91_lowputc.c
@@ -333,8 +333,28 @@ void nrf91_usart_configure(uintptr_t base,
   uint32_t regval = 0;
 
   putreg32(0xffffffff, base + NRF91_UARTE_INTENCLR_OFFSET);
-  putreg32(1, base + NRF91_UARTE_TASKS_STOPRX_OFFSET);
-  putreg32(1, base + NRF91_UARTE_TASKS_STOPTX_OFFSET);
+
+  /* Anomaly 23: a transfer left running survives disabling the UARTE.
+   * Stop it with the UARTE enabled and wait for the receiver to stop.
+   */
+
+  if (getreg32(base + NRF91_UARTE_TXSTATE_OFFSET) != 0)
+    {
+      putreg32(1, base + NRF91_UARTE_TASKS_STOPTX_OFFSET);
+    }
+
+  if (getreg32(base + NRF91_UARTE_RXSTATE_OFFSET) != 0)
+    {
+      putreg32(NRF91_UARTE_ENABLE_ENABLE, base + NRF91_UARTE_ENABLE_OFFSET);
+      putreg32(1, base + NRF91_UARTE_TASKS_STOPRX_OFFSET);
+      while (getreg32(base + NRF91_UARTE_RXSTATE_OFFSET) != 0)
+        {
+        }
+
+      putreg32(getreg32(base + NRF91_UARTE_ERRORSRC_OFFSET),
+               base + NRF91_UARTE_ERRORSRC_OFFSET);
+    }
+
   putreg32(NRF91_UARTE_ENABLE_DISABLE, base + NRF91_UARTE_ENABLE_OFFSET);
 
   /* Set UART format */

Reply via email to