From 30a48e4217bb796d199e92cbf99e6c7b67d09ab6 Mon Sep 17 00:00:00 2001 From: Daniel Agar Date: Mon, 2 Mar 2020 16:08:11 -0500 Subject: [PATCH] arm/stm32h7 add STM32H7_SPI_DMATHRESHOLD --- arch/arm/src/stm32h7/Kconfig | 9 +++++++++ arch/arm/src/stm32h7/stm32_spi.c | 27 ++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/arch/arm/src/stm32h7/Kconfig b/arch/arm/src/stm32h7/Kconfig index 2b552ce4d9..9c89be3492 100644 --- a/arch/arm/src/stm32h7/Kconfig +++ b/arch/arm/src/stm32h7/Kconfig @@ -612,6 +612,15 @@ config STM32H7_SPI_DMA ---help--- Use DMA to improve SPI transfer performance. Cannot be used with STM32H7_SPI_INTERRUPT. +config STM32H7_SPI_DMATHRESHOLD + int "SPI DMA threshold" + default 4 + depends on STM32H7_SPI_DMA + ---help--- + When SPI DMA is enabled, small DMA transfers will still be performed + by polling logic. But we need a threshold value to determine what + is small. + endmenu # "SPI Configuration" menu "U[S]ART Configuration" diff --git a/arch/arm/src/stm32h7/stm32_spi.c b/arch/arm/src/stm32h7/stm32_spi.c index df3fc14f85..b8447c8191 100644 --- a/arch/arm/src/stm32h7/stm32_spi.c +++ b/arch/arm/src/stm32h7/stm32_spi.c @@ -1716,6 +1716,31 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, DEBUGASSERT(priv != NULL); +#ifdef CONFIG_STM32H7_SPI_DMATHRESHOLD + /* Convert the number of word to a number of bytes */ + + size_t nbytes = (priv->nbits > 8) ? nwords << 1 : nwords; + + /* If this is a small SPI transfer, then let spi_exchange_nodma() do the work. */ + + if (nbytes <= CONFIG_STM32H7_SPI_DMATHRESHOLD) + { + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + return; + } +#endif + + if ((priv->rxdma == NULL) || (priv->txdma == NULL) || + up_interrupt_context()) + { + /* Invalid DMA channels, or interrupt context, fall + * back to non-DMA method. + */ + + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + return; + } + #ifdef CONFIG_STM32H7_DMACAPABLE stm32_dmacfg_t dmacfg1; stm32_dmacfg_t dmacfg2; @@ -1735,7 +1760,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, if ((txbuffer && !stm32_dmacapable(priv->txdma, &dmacfg1)) || (rxbuffer && !stm32_dmacapable(priv->rxdma, &dmacfg2))) { - /* Unsupported memory region, fall back to non-DMA method. */ + /* Unsupported memory region fall back to non-DMA method. */ spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); }