This is an automated email from the ASF dual-hosted git repository. aguettouche pushed a commit to branch pr420 in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit afb2248b7a47ec4ab72f10fe21100d538af67934 Author: Daniel Agar <dan...@agar.ca> AuthorDate: Mon Mar 2 16:02:54 2020 -0500 arm/stm32 add STM32_SPI_DMATHRESHOLD --- arch/arm/src/stm32/Kconfig | 9 +++++++++ arch/arm/src/stm32/stm32_spi.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index 4b5be6e..e6851a5 100644 --- a/arch/arm/src/stm32/Kconfig +++ b/arch/arm/src/stm32/Kconfig @@ -8820,6 +8820,15 @@ config STM32_SPI1_DMA ---help--- Use DMA to improve SPI1 transfer performance. +config STM32_SPI_DMATHRESHOLD + int "SPI DMA threshold" + default 4 + depends on STM32_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. + config STM32_SPI2_DMA bool "SPI2 DMA" default n diff --git a/arch/arm/src/stm32/stm32_spi.c b/arch/arm/src/stm32/stm32_spi.c index 5c651a6..293b45e 100644 --- a/arch/arm/src/stm32/stm32_spi.c +++ b/arch/arm/src/stm32/stm32_spi.c @@ -1677,17 +1677,40 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, { FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; -#ifdef CONFIG_STM32_DMACAPABLE + DEBUGASSERT(priv != NULL); + +#ifdef CONFIG_STM32_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_STM32_SPI_DMATHRESHOLD) + { + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + return; + } +#endif + if ((priv->rxdma == NULL) || (priv->txdma == NULL) || - (txbuffer && !stm32_dmacapable((uint32_t)txbuffer, nwords, priv->txccr)) || - (rxbuffer && !stm32_dmacapable((uint32_t)rxbuffer, nwords, priv->rxccr)) || up_interrupt_context()) { - /* Invalid DMA channels, unsupported memory region, or interrupt context, fall + /* Invalid DMA channels, or interrupt context, fall * back to non-DMA method. */ spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); + return; + } + +#ifdef CONFIG_STM32_DMACAPABLE + if ((txbuffer && !stm32_dmacapable((uint32_t)txbuffer, nwords, priv->txccr)) || + (rxbuffer && !stm32_dmacapable((uint32_t)rxbuffer, nwords, priv->rxccr))) + { + /* Unsupported memory region fall back to non-DMA method. */ + + spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords); } else #endif