You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ag...@apache.org on 2020/03/02 22:08:38 UTC

[incubator-nuttx] 04/04: arm/stm32h7 add STM32H7_SPI_DMATHRESHOLD

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 30a48e4217bb796d199e92cbf99e6c7b67d09ab6
Author: Daniel Agar <da...@agar.ca>
AuthorDate: Mon Mar 2 16:08:11 2020 -0500

    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 2b552ce..9c89be3 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 df3fc14..b8447c8 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);
     }