diff --git a/ChangeLog b/ChangeLog index bdd9dd52eb..74df4b44e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5894,4 +5894,6 @@ VS1053 driver from ken Pettit (2013-10-27). * configs/mikroe-stm32f4/: Updated configuration for the Mikrow STM32F4 board from Ken Pettit (2013-10-27). + * arch/arm/src/stm32/stm32_spi.c: DMA-related fixe from Ken + Pettit (2013-10-27). diff --git a/arch/arm/src/stm32/stm32_spi.c b/arch/arm/src/stm32/stm32_spi.c index 1f50d9e23d..3f33818574 100644 --- a/arch/arm/src/stm32/stm32_spi.c +++ b/arch/arm/src/stm32/stm32_spi.c @@ -195,6 +195,8 @@ struct stm32_spidev_s DMA_HANDLE txdma; /* DMA channel handle for TX transfers */ sem_t rxsem; /* Wait for RX DMA to complete */ sem_t txsem; /* Wait for TX DMA to complete */ + uint32_t txccr; /* DMA control register for TX transfers */ + uint32_t rxccr; /* DMA control register for RX transfers */ #endif #ifndef CONFIG_SPI_OWNBUS sem_t exclsem; /* Held while chip is selected for mutual exclusion */ @@ -748,8 +750,6 @@ static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg) static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, FAR void *rxbuffer, FAR void *rxdummy, size_t nwords) { - uint32_t ccr; - /* 8- or 16-bit mode? */ if (spi_16bitmode(priv)) @@ -758,12 +758,12 @@ static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, FAR void *rxbuffer, if (rxbuffer) { - ccr = SPI_RXDMA16_CONFIG; + priv->rxccr = SPI_RXDMA16_CONFIG; } else { - rxbuffer = rxdummy; - ccr = SPI_RXDMA16NULL_CONFIG; + rxbuffer = rxdummy; + priv->rxccr = SPI_RXDMA16NULL_CONFIG; } } else @@ -772,18 +772,19 @@ static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, FAR void *rxbuffer, if (rxbuffer) { - ccr = SPI_RXDMA8_CONFIG; + priv->rxccr = SPI_RXDMA8_CONFIG; } else { - rxbuffer = rxdummy; - ccr = SPI_RXDMA8NULL_CONFIG; + rxbuffer = rxdummy; + priv->rxccr = SPI_RXDMA8NULL_CONFIG; } } /* Configure the RX DMA */ - stm32_dmasetup(priv->rxdma, priv->spibase + STM32_SPI_DR_OFFSET, (uint32_t)rxbuffer, nwords, ccr); + stm32_dmasetup(priv->rxdma, priv->spibase + STM32_SPI_DR_OFFSET, + (uint32_t)rxbuffer, nwords, priv->rxccr); } #endif @@ -799,8 +800,6 @@ static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, FAR void *rxbuffer, static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, FAR const void *txbuffer, FAR const void *txdummy, size_t nwords) { - uint32_t ccr; - /* 8- or 16-bit mode? */ if (spi_16bitmode(priv)) @@ -809,12 +808,12 @@ static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, FAR const void *txbu if (txbuffer) { - ccr = SPI_TXDMA16_CONFIG; + priv->txccr = SPI_TXDMA16_CONFIG; } else { - txbuffer = txdummy; - ccr = SPI_TXDMA16NULL_CONFIG; + txbuffer = txdummy; + priv->txccr = SPI_TXDMA16NULL_CONFIG; } } else @@ -823,18 +822,19 @@ static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, FAR const void *txbu if (txbuffer) { - ccr = SPI_TXDMA8_CONFIG; + priv->txccr = SPI_TXDMA8_CONFIG; } else { - txbuffer = txdummy; - ccr = SPI_TXDMA8NULL_CONFIG; + txbuffer = txdummy; + priv->txccr = SPI_TXDMA8NULL_CONFIG; } } /* Setup the TX DMA */ - stm32_dmasetup(priv->txdma, priv->spibase + STM32_SPI_DR_OFFSET,(uint32_t)txbuffer, nwords, ccr); + stm32_dmasetup(priv->txdma, priv->spibase + STM32_SPI_DR_OFFSET, + (uint32_t)txbuffer, nwords, priv->txccr); } #endif @@ -1180,7 +1180,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) spi_modifycr1(priv, 0, SPI_CR1_SPE); spi_modifycr1(priv, setbits, clrbits); spi_modifycr1(priv, SPI_CR1_SPE, 0); - + /* Save the selection so the subsequence re-configurations will be faster */ #ifndef CONFIG_SPI_OWNBUS @@ -1353,9 +1353,11 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff 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; + #ifdef CONFIG_STM32_DMACAPABLE - if ((txbuffer && !stm32_dmacapable((uint32_t)txbuffer)) || - (rxbuffer && !stm32_dmacapable((uint32_t)rxbuffer))) + 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. */ @@ -1364,7 +1366,6 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, else #endif { - FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; static uint16_t rxdummy = 0xffff; static const uint16_t txdummy = 0xffff; @@ -1513,7 +1514,7 @@ static void spi_portinitialize(FAR struct stm32_spidev_s *priv) priv->rxdma = stm32_dmachannel(priv->rxch); priv->txdma = stm32_dmachannel(priv->txch); DEBUGASSERT(priv->rxdma && priv->txdma); - + spi_putreg(priv, STM32_SPI_CR2_OFFSET, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN); #endif