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

Reply via email to