2348726_en-US

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

2348726_en-US

2348726_en-US

i.MX8MM ECSPI driver (fsl_ecspi.c) interrupt does not stop due to FIFO count inconsistency

Hi,

I found a potential issue in the ECSPI driver (fsl_ecspi.c) on i.MX8MM, specifically in ECSPI_SendTransfer().

The following code calculates the available FIFO space:

dataCounts =
((uint32_t)FSL_FEATURE_ECSPI_TX_FIFO_SIZEn(base) - (uint32_t)ECSPI_GetTxFifoCount(base)) < txRemainingBytes ?
((uint32_t)FSL_FEATURE_ECSPI_TX_FIFO_SIZEn(base) - (uint32_t)ECSPI_GetTxFifoCount(base)) :
txRemainingBytes;

However, ECSPI_GetTxFifoCount(base) reads a hardware register, and the FIFO level is dynamically updated.
Because this function is called multiple times in the same expression, the returned value may differ between evaluations.

As a result, the calculated available FIFO space may become inconsistent,
and dataCounts may exceed the expected value under certain timing conditions.

This can lead to incorrect transfer behavior, and in my case, the ECSPI interrupt does not stop (interrupt keeps firing).

I believe the root cause is that the FIFO count register is read multiple times,
and the driver assumes the value remains consistent within the expression.

Proposed solution:
- Read the FIFO count register only once
- Store it in a local variable
- Use the cached value for subsequent calculations

Example fix:

uint32_t fifoAvailableCount = ((uint32_t)FSL_FEATURE_ECSPI_TX_FIFO_SIZEn(base) - (uint32_t)ECSPI_GetTxFifoCount(base));
dataCounts = (fifoAvailableCount < txRemainingBytes) ? fifoAvailableCount : txRemainingBytes;

Could you confirm if this is a known issue or unintended behavior?

i.MX 8M | i.MX 8M Mini | i.MX 8M NanoRe: i.MX8MM ECSPI driver (fsl_ecspi.c) interrupt does not stop due to FIFO count inconsistency

Hi, @pengyong_zhang 

Thank you for your response.

I am not using Linux.
I am running a bare-metal / RTOS environment on the A53 core of i.MX8MM.

The ECSPI driver I am using is based on the MCUXpresso SDK driver.
For example, the following implementation:

https://github.com/nxp-mcuxpresso/mcuxsdk-core/blob/main/drivers/ecspi/fsl_ecspi.c#L180

In this implementation, the FIFO status is read multiple times in the interrupt handler.
Since the FIFO count can change between reads, I believe this may cause dataCounts to exceed txRemainingBytes in rare cases.

Could you confirm whether this behavior is expected, or if this is a known issue in the ECSPI driver?

Best regards,

Re: i.MX8MM ECSPI driver (fsl_ecspi.c) interrupt does not stop due to FIFO count inconsistency

Hi @N_Eco_Logic 

Our imx8mm ECSPI driver code file is as follows:

https://github.com/nxp-imx/linux-imx/blob/de3ebf27b0f69724f13bdd9bb8809aabd47c78b9/drivers/spi/spi-i...

Which version of the kernel are you using?

B.R

Re: i.MX8MM ECSPI driver (fsl_ecspi.c) interrupt does not stop due to FIFO count inconsistency

I also have seen this issue, and I've put in an PR to fix it: https://github.com/nxp-mcuxpresso/mcuxsdk-core/pull/33

Separately noting that there's a case where the code as written (even with this fix) triggers an overflow of the RXFIFO if, in the IRQ, there are bytes that are transmitted out of the TXFIFO while the RXFIFO is being drained. For example, if at the time ECSPI_GetRxFifoCount is called there are e.g. 60 bytes in the RXFIFO and 4 in the TXFIFO, and then by the time ECSPI_GetTxFifoCount is called, the 4 bytes have been sent, the TXFIFO will be filled (up to 64 bytes in the i.MX8MP case). If the ISR isn't serviced again fast enough, this leads to an overflow since it results in 64 + 4 items transmitted before any are read. That can be fixed by using handle->rxRemainingBytes - handle->txRemainingBytes instead of fifoCounts bytes in the patch, but that is only necessary if the ISR fails to drain the RXFIFO fast enough (was the case for me, but may not be the case everywhere, and this could lead to slower transactions/more interrupts, so I opted not to include this change in the PR).

Tags (1)
No ratings
Version history
Last update:
a week ago
Updated by: