diff --git a/arch/arm/src/imxrt/imxrt_serial.c b/arch/arm/src/imxrt/imxrt_serial.c index 805f33e8741..6a2faf50fc5 100644 --- a/arch/arm/src/imxrt/imxrt_serial.c +++ b/arch/arm/src/imxrt/imxrt_serial.c @@ -1746,6 +1746,7 @@ static int imxrt_interrupt(int irq, void *context, void *arg) { struct imxrt_uart_s *priv = (struct imxrt_uart_s *)arg; uint32_t usr; + uint32_t lsr; int passes = 0; bool handled; @@ -1771,30 +1772,45 @@ static int imxrt_interrupt(int irq, void *context, void *arg) */ usr = imxrt_serialin(priv, IMXRT_LPUART_STAT_OFFSET); + + /* Removed all W1C from the last sr */ + + lsr = usr & ~(LPUART_STAT_LBKDIF | LPUART_STAT_RXEDGIF | + LPUART_STAT_IDLE | LPUART_STAT_OR | + LPUART_STAT_NF | LPUART_STAT_FE | + LPUART_STAT_PF | LPUART_STAT_MA1F | + LPUART_STAT_MA2F); + + /* Keep what we will service */ + usr &= (LPUART_STAT_RDRF | LPUART_STAT_TDRE | LPUART_STAT_OR | - LPUART_STAT_FE | LPUART_STAT_NF | LPUART_STAT_PF | + LPUART_STAT_FE | LPUART_STAT_NF | LPUART_STAT_PF | LPUART_STAT_IDLE); /* Clear serial overrun, parity and framing errors */ if ((usr & LPUART_STAT_OR) != 0) { - imxrt_serialout(priv, IMXRT_LPUART_STAT_OFFSET, LPUART_STAT_OR); + imxrt_serialout(priv, IMXRT_LPUART_STAT_OFFSET, + lsr | LPUART_STAT_OR); } if ((usr & LPUART_STAT_NF) != 0) { - imxrt_serialout(priv, IMXRT_LPUART_STAT_OFFSET, LPUART_STAT_NF); + imxrt_serialout(priv, IMXRT_LPUART_STAT_OFFSET, + lsr | LPUART_STAT_NF); } if ((usr & LPUART_STAT_PF) != 0) { - imxrt_serialout(priv, IMXRT_LPUART_STAT_OFFSET, LPUART_STAT_PF); + imxrt_serialout(priv, IMXRT_LPUART_STAT_OFFSET, + lsr | LPUART_STAT_PF); } if ((usr & LPUART_STAT_FE) != 0) { - imxrt_serialout(priv, IMXRT_LPUART_STAT_OFFSET, LPUART_STAT_FE); + imxrt_serialout(priv, IMXRT_LPUART_STAT_OFFSET, + lsr | LPUART_STAT_FE); } if ((usr & (LPUART_STAT_FE | LPUART_STAT_PF | LPUART_STAT_NF)) != 0) @@ -1809,7 +1825,8 @@ static int imxrt_interrupt(int irq, void *context, void *arg) if ((usr & LPUART_STAT_IDLE) != 0) { - imxrt_serialout(priv, IMXRT_LPUART_STAT_OFFSET, LPUART_STAT_IDLE); + imxrt_serialout(priv, IMXRT_LPUART_STAT_OFFSET, + lsr | LPUART_STAT_IDLE); imxrt_dma_rxcallback(priv->rxdma, priv, false, LPUART_STAT_IDLE); } #endif @@ -2723,12 +2740,10 @@ static void imxrt_dma_rxcallback(DMACH_HANDLE handle, void *arg, bool done, sr = imxrt_serialin(priv, IMXRT_LPUART_STAT_OFFSET); - if ((sr & (LPUART_STAT_OR | LPUART_STAT_NF | LPUART_STAT_FE)) != 0) + if ((sr & (LPUART_STAT_OR | LPUART_STAT_NF | LPUART_STAT_FE | + LPUART_STAT_PF)) != 0) { - imxrt_serialout(priv, IMXRT_LPUART_STAT_OFFSET, - sr & (LPUART_STAT_OR | - LPUART_STAT_NF | - LPUART_STAT_FE)); + imxrt_serialout(priv, IMXRT_LPUART_STAT_OFFSET, sr); } } #endif