UART missing interrupt

ID: COBALTSDK-892

Status: Open

First reported: 10.2.4.44

Fixed in: TBD

Description

The function hw_uart_enable_rx_int() should be made atomic (as mentioned in the comment) but is actually only disabling the UART interrupt, still allowing other interrupt sources. There’s a possibility that an RTOS context switch will prevent the UART interrupt to be enabled in a timely manner resulting in a missed interrupt.

Workaround

In the hw_uart.c apply the following changes:

@@ -247,17 +247,20 @@ __STATIC_INLINE void hw_uart_enable_rx_int(HW_UART_ID uart, bool enable)
          * and out of interrupt context, we better avoid the possibility of concurrent attempts to
          * update this register by always temporarily disabling the UART IRQs on the NVIC side
          * completely. */
-        NVIC_DisableIRQ(UART_INT(uart));
+        GLOBAL_INT_DISABLE();
         HW_UART_REG_SETF(uart, IER_DLH, ERBFI_DLH0, enable);
         NVIC_EnableIRQ(UART_INT(uart));
+        GLOBAL_INT_RESTORE();
 }
 
 __STATIC_INLINE void hw_uart_enable_tx_int(HW_UART_ID uart, bool enable)
 {
+        GLOBAL_INT_DISABLE();
         uint16_t ier_dlh_reg = UBA(uart)->UART2_IER_DLH_REG;
         REG_SET_FIELD(UART2, UART2_IER_DLH_REG, ETBEI_DLH1, ier_dlh_reg, enable);
         REG_SET_FIELD(UART2, UART2_IER_DLH_REG, PTIME_DLH7, ier_dlh_reg, enable);
         UBA(uart)->UART2_IER_DLH_REG = ier_dlh_reg;
+        GLOBAL_INT_RESTORE();
 }