From e224a41ec805cd7c0fb427f6befbca133904997c Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Wed, 14 Aug 2024 15:05:25 +0300 Subject: [PATCH] drivers: dai: sai: don't crash on underrun/overrun TX/RX FIFO underrun shouldn't crash the RTOS when it occurs. Also, since this can also happen under "normal" conditions (i.e: DMA doesn't copy data fast enough from/to SAI's FIFOs) the software should be able to recover from it. As such: 1) Remove `z_irq_spurious()` call. 2) Clear error flag 3) De-escalate error message to warning message Signed-off-by: Laurentiu Mihalcea --- drivers/dai/nxp/sai/sai.c | 14 ++++---------- drivers/dai/nxp/sai/sai.h | 5 +++++ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/dai/nxp/sai/sai.c b/drivers/dai/nxp/sai/sai.c index 8deb17e06a1..37c6832840a 100644 --- a/drivers/dai/nxp/sai/sai.c +++ b/drivers/dai/nxp/sai/sai.c @@ -95,20 +95,14 @@ void sai_isr(const void *parameter) /* check for TX FIFO error */ if (SAI_TX_RX_STATUS_IS_SET(DAI_DIR_TX, data->regmap, kSAI_FIFOErrorFlag)) { - LOG_ERR("FIFO underrun detected"); - /* TODO: this will crash the program and should be addressed as - * mentioned in TODO list's 2). - */ - z_irq_spurious(NULL); + LOG_WRN("FIFO underrun detected"); + SAI_TX_RX_STATUS_CLEAR(DAI_DIR_TX, data->regmap, kSAI_FIFOErrorFlag); } /* check for RX FIFO error */ if (SAI_TX_RX_STATUS_IS_SET(DAI_DIR_RX, data->regmap, kSAI_FIFOErrorFlag)) { - LOG_ERR("FIFO overrun detected"); - /* TODO: this will crash the program and should be addressed as - * mentioned in TODO list's 2). - */ - z_irq_spurious(NULL); + LOG_WRN("FIFO overrun detected"); + SAI_TX_RX_STATUS_CLEAR(DAI_DIR_RX, data->regmap, kSAI_FIFOErrorFlag); } } diff --git a/drivers/dai/nxp/sai/sai.h b/drivers/dai/nxp/sai/sai.h index 2fa890e9811..2a2ae48712d 100644 --- a/drivers/dai/nxp/sai/sai.h +++ b/drivers/dai/nxp/sai/sai.h @@ -210,6 +210,11 @@ LOG_MODULE_REGISTER(nxp_dai_sai); ((dir) == DAI_DIR_RX ? ((UINT_TO_I2S(regmap))->RCSR & (which)) : \ ((UINT_TO_I2S(regmap))->TCSR & (which))) +/* used to clear status flags */ +#define SAI_TX_RX_STATUS_CLEAR(dir, regmap, which) \ + ((dir) == DAI_DIR_RX ? SAI_RxClearStatusFlags(UINT_TO_I2S(regmap), which) \ + : SAI_TxClearStatusFlags(UINT_TO_I2S(regmap), which)) + /* used to retrieve the SYNC direction. Use this macro when you know for sure * you have 1 SYNC direction with 1 ASYNC direction. */