From b2e79959b188a40de39f0cd7daac0c5fe162acef Mon Sep 17 00:00:00 2001
From: jfbortolotti <jfbortolotti@gmail.com>
Date: Tue, 6 Dec 2016 10:52:27 +0100
Subject: [PATCH] cpu: nRF52: move clearing of TXRDY flag

... before writing the data to avoid an infinite loop in case of multiple thread accessing the UART. (#6029)
---
 cpu/nrf5x_common/periph/uart.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/cpu/nrf5x_common/periph/uart.c b/cpu/nrf5x_common/periph/uart.c
index fa6b6f5582..7b90cad4d7 100644
--- a/cpu/nrf5x_common/periph/uart.c
+++ b/cpu/nrf5x_common/periph/uart.c
@@ -140,12 +140,22 @@ void uart_write(uart_t uart, const uint8_t *data, size_t len)
 {
     if (uart == 0) {
         for (size_t i = 0; i < len; i++) {
+            /* This section of the function is not thread safe:
+                - another thread may mess up with the uart at the same time.
+               In order to avoid an infinite loop in the interrupted thread,
+               the TXRDY flag must be cleared before writing the data to be
+               sent and not after. This way, the higher priority thread will
+               exit this function with the TXRDY flag set, then the interrupted
+               thread may have not transmitted his data but will still exit the
+               while loop.
+            */
+
+            /* reset ready flag */
+            NRF_UART0->EVENTS_TXDRDY = 0;
             /* write data into transmit register */
             NRF_UART0->TXD = data[i];
             /* wait for any transmission to be done */
             while (NRF_UART0->EVENTS_TXDRDY == 0) {}
-            /* reset ready flag */
-            NRF_UART0->EVENTS_TXDRDY = 0;
         }
     }
 }
-- 
GitLab