drivers: spi: Implement workaround for unreliable busy flag

For some STM32 MCUs the busy flag of SPI is unreliable. This is a known
issue of the device and described in the device errata.
As a fix implement a configurable timeout which ensures that a call
to spi_transceive will eventually return.
Fixes #64927

Signed-off-by: Benedikt Schmidt <benedikt.schmidt@embedded-solutions.at>
This commit is contained in:
Benedikt Schmidt 2023-11-07 16:12:10 +01:00 committed by Carles Cufí
parent eb323be088
commit 3441fee460
2 changed files with 23 additions and 0 deletions

View File

@ -32,5 +32,22 @@ config SPI_STM32_USE_HW_SS
help
Use Slave Select pin instead of software Slave Select.
config SPI_STM32F7_ERRATA_BUSY
bool
default y
depends on SOC_STM32F745XX || SOC_STM32F746XX || \
SOC_STM32F750XX || SOC_STM32F756XX
help
Handles erratum "BSY bit may stay high at the end of a data
transfer in Slave mode".
Seen in Errata Sheet 0290 §2.11.2
if SPI_STM32F7_ERRATA_BUSY
config SPI_STM32_BUSY_FLAG_TIMEOUT
int "timeout in us for the STM32 busy flag workaround"
default 10000
endif # SPI_STM32F7_ERRATA_BUSY
endif # SPI_STM32

View File

@ -902,9 +902,15 @@ static int transceive_dma(const struct device *dev,
}
#endif
#ifdef CONFIG_SPI_STM32F7_ERRATA_BUSY
WAIT_FOR(ll_func_spi_dma_busy(spi) != 0,
CONFIG_SPI_STM32_BUSY_FLAG_TIMEOUT,
k_yield());
#else
/* wait until spi is no more busy (spi TX fifo is really empty) */
while (ll_func_spi_dma_busy(spi) == 0) {
}
#endif
#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi)
/* toggle the DMA transfer request */