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();
}