Skip to content

Commit

Permalink
If CONFIG_STM32_DMACAPABLE is defined, use stm32_dmacapable to workar…
Browse files Browse the repository at this point in the history
…ound attempt SPI DMAs from the CCM stack
  • Loading branch information
gregory-nutt committed Jun 4, 2013
1 parent 6275eae commit e7e1e83
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 19 deletions.
6 changes: 6 additions & 0 deletions nuttx/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -4885,4 +4885,10 @@
stm32_dmacapable() that can be used to determine if DMA is
possible from the specified memory address. From Petteri Aimonen
(2013-6-4).
* arch/arm/src/stm32/stm32_spi.c: If CONFIG_STM32_DMACAPABLE is
defined, use stm32_dmacapable() to determine if it is possible
to perform DMA from the specified address. This change is
important for the STM32 F4 which may have SPI data buffers
allocated on the stack in CCM memory which cannot support the
DMA. From Petteri Aimonen (2013-6-4).

55 changes: 36 additions & 19 deletions nuttx/arch/arm/src/stm32/stm32_spi.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/************************************************************************************
* arm/arm/src/stm32/stm32_spi.c
*
* Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2009-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -1215,7 +1215,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
}

/************************************************************************************
* Name: spi_exchange (no DMA)
* Name: spi_exchange (no DMA). aka spi_exchange_nodma
*
* Description:
* Exchange a block of data on SPI without using DMA
Expand All @@ -1234,9 +1234,14 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
*
************************************************************************************/

#ifndef CONFIG_STM32_SPI_DMA
#if !defined(CONFIG_STM32_SPI_DMA) || defined(CONFIG_STM32_DMACAPABLE)
#if !defined(CONFIG_STM32_SPI_DMA)
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
FAR void *rxbuffer, size_t nwords)
#else
static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
FAR void *rxbuffer, size_t nwords)
#endif
{
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
DEBUGASSERT(priv && priv->spibase);
Expand Down Expand Up @@ -1312,7 +1317,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
}
}
}
#endif
#endif /* !CONFIG_STM32_SPI_DMA || CONFIG_STM32_DMACAPABLE */

/*************************************************************************
* Name: spi_exchange (with DMA capability)
Expand All @@ -1338,29 +1343,41 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
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;
static uint16_t rxdummy = 0xffff;
static const uint16_t txdummy = 0xffff;
#ifdef CONFIG_STM32_DMACAPABLE
if ((txbuffer && !stm32_dmacapable((uint32_t)txbuffer)) ||
(rxbuffer && !stm32_dmacapable((uint32_t)rxbuffer)))
{
/* Unsupported memory region, fall back to non-DMA method. */

spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords);
DEBUGASSERT(priv && priv->spibase);
spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords);
}
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;

/* Setup DMAs */
spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords);
DEBUGASSERT(priv && priv->spibase);

spi_dmarxsetup(priv, rxbuffer, &rxdummy, nwords);
spi_dmatxsetup(priv, txbuffer, &txdummy, nwords);
/* Setup DMAs */

/* Start the DMAs */
spi_dmarxsetup(priv, rxbuffer, &rxdummy, nwords);
spi_dmatxsetup(priv, txbuffer, &txdummy, nwords);

spi_dmarxstart(priv);
spi_dmatxstart(priv);
/* Start the DMAs */

/* Then wait for each to complete */
spi_dmarxstart(priv);
spi_dmatxstart(priv);

spi_dmarxwait(priv);
spi_dmatxwait(priv);
/* Then wait for each to complete */

spi_dmarxwait(priv);
spi_dmatxwait(priv);
}
}
#endif
#endif /* CONFIG_STM32_SPI_DMA */

/*************************************************************************
* Name: spi_sndblock
Expand Down

0 comments on commit e7e1e83

Please sign in to comment.