From 574b2593e69ae832247364f70339379f3ff280da Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Tue, 22 Oct 2019 08:48:26 +0300 Subject: [PATCH] arch/arm/src/stm32h7/stm32_spi.c: Correct the dmacapable check First, configure the dmacfg in spi_dmarxsetup and spi_dmatxsetup. Then, check for dmacapable, and only after that set up the dma. This way the dmacapable actually works, and we don't need to initialize the dmacfg structures twice. Signed-off-by: Jukka Laitinen --- arch/arm/src/stm32h7/stm32_spi.c | 78 +++++++++++++------------------- 1 file changed, 31 insertions(+), 47 deletions(-) diff --git a/arch/arm/src/stm32h7/stm32_spi.c b/arch/arm/src/stm32h7/stm32_spi.c index d827c7c1285..a19203ed6fd 100644 --- a/arch/arm/src/stm32h7/stm32_spi.c +++ b/arch/arm/src/stm32h7/stm32_spi.c @@ -290,11 +290,13 @@ static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, FAR void *rxbuffer, FAR void *rxdummy, - size_t nwords); + size_t nwords, + stm32_dmacfg_t *dmacfg); static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, FAR const void *txbuffer, FAR const void *txdummy, - size_t nwords); + size_t nwords, + stm32_dmacfg_t *dmacfg); static inline void spi_dmarxstart(FAR struct stm32_spidev_s *priv); static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv); #endif @@ -1074,10 +1076,8 @@ static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg) #ifdef CONFIG_STM32H7_SPI_DMA static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, FAR void *rxbuffer, FAR void *rxdummy, - size_t nwords) + size_t nwords, stm32_dmacfg_t *dmacfg) { - stm32_dmacfg_t dmacfg; - /* 8- or 16-bit mode? */ if (priv->nbits > 8) @@ -1111,13 +1111,11 @@ static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, /* Configure the RX DMA */ - dmacfg.paddr = priv->spibase + STM32_SPI_RXDR_OFFSET; - dmacfg.maddr = (uint32_t)rxbuffer; - dmacfg.ndata = nwords; - dmacfg.cfg1 = priv->rxccr; - dmacfg.cfg2 = 0; - - stm32_dmasetup(priv->rxdma, &dmacfg); + dmacfg->paddr = priv->spibase + STM32_SPI_RXDR_OFFSET; + dmacfg->maddr = (uint32_t)rxbuffer; + dmacfg->ndata = nwords; + dmacfg->cfg1 = priv->rxccr; + dmacfg->cfg2 = 0; } #endif @@ -1132,10 +1130,8 @@ static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, #ifdef CONFIG_STM32H7_SPI_DMA static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, FAR const void *txbuffer, FAR const void *txdummy, - size_t nwords) + size_t nwords, stm32_dmacfg_t *dmacfg) { - stm32_dmacfg_t dmacfg; - /* 8- or 16-bit mode? */ if (priv->nbits > 8) @@ -1167,15 +1163,11 @@ static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, } } - dmacfg.paddr = priv->spibase + STM32_SPI_TXDR_OFFSET; - dmacfg.maddr = (uint32_t)txbuffer; - dmacfg.ndata = nwords; - dmacfg.cfg1 = priv->txccr; - dmacfg.cfg2 = 0; - - /* Setup the TX DMA */ - - stm32_dmasetup(priv->txdma, &dmacfg); + dmacfg->paddr = priv->spibase + STM32_SPI_TXDR_OFFSET; + dmacfg->maddr = (uint32_t)txbuffer; + dmacfg->ndata = nwords; + dmacfg->cfg1 = priv->txccr; + dmacfg->cfg2 = 0; } #endif @@ -1813,6 +1805,11 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, FAR void *rxbuffer, size_t nwords) { FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; + stm32_dmacfg_t rxdmacfg; + stm32_dmacfg_t txdmacfg; + static uint8_t rxdummy[ARMV7M_DCACHE_LINESIZE] + __attribute__((aligned(ARMV7M_DCACHE_LINESIZE))); + static const uint16_t txdummy = 0xffff; DEBUGASSERT(priv != NULL); @@ -1843,9 +1840,12 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, return; } + /* Setup the DMA configs */ + + spi_dmatxsetup(priv, txbuffer, &txdummy, nwords, &txdmacfg); + spi_dmarxsetup(priv, rxbuffer, (uint16_t *)rxdummy, nwords, &rxdmacfg); + #ifdef CONFIG_STM32H7_DMACAPABLE - stm32_dmacfg_t dmatxcfg; - stm32_dmacfg_t dmarxcfg; /* Setup DMAs */ @@ -1870,22 +1870,8 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, rxbuffer = rxbuffer ? priv->rxbuf : rxbuffer; } - /* TX transfer configuration */ - - dmatxcfg.maddr = (uint32_t)txbuffer; - dmatxcfg.ndata = nwords; - dmatxcfg.cfg1 = priv->txccr; - - /* RX transfer configuration */ - - dmarxcfg.maddr = (uint32_t)rxbuffer; - dmarxcfg.ndata = nwords; - dmarxcfg.cfg1 = priv->rxccr; - - if ((txbuffer && priv->txbuf == 0 && - !stm32_dmacapable(priv->txdma, &dmatxcfg)) || - (rxbuffer && priv->rxbuf == 0 && - !stm32_dmacapable(priv->rxdma, &dmarxcfg))) + if (!stm32_dmacapable(priv->txdma, &txdmacfg) || + !stm32_dmacapable(priv->rxdma, &rxdmacfg)) { /* Unsupported memory region fall back to non-DMA method. */ @@ -1894,9 +1880,6 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, else #endif { - static uint8_t rxdummy[4] __attribute__((aligned(4))); - static const uint16_t txdummy = 0xffff; - /* When starting communication using DMA, to prevent DMA channel * management raising error events, these steps must be followed in * order: @@ -1917,8 +1900,9 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, txbuffer, rxbuffer, nwords); DEBUGASSERT(priv->spibase != 0); - spi_dmarxsetup(priv, rxbuffer, (uint16_t *)rxdummy, nbytes); - spi_dmatxsetup(priv, txbuffer, &txdummy, nbytes); + /* Setup the DMA */ + stm32_dmasetup(priv->txdma, &txdmacfg); + stm32_dmasetup(priv->rxdma, &rxdmacfg); spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, 0, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);