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);
}