SPI DMA design simplification
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2148 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
2e8f38671b
commit
a2763cf4fc
@ -301,10 +301,31 @@ void weak_function stm32_dmainitialize(void)
|
|||||||
* Name: stm32_dmachannel
|
* Name: stm32_dmachannel
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Allocate a DMA channel
|
* Allocate a DMA channel. This function gives the caller mutually
|
||||||
|
* exclusive access to the DMA channel specified by the 'chan' argument.
|
||||||
|
* DMA channels are shared on the STM32: Devices sharing the same DMA
|
||||||
|
* channel cannot do DMA concurrently! See the DMACHAN_* definitions in
|
||||||
|
* stm32_dma.h.
|
||||||
|
*
|
||||||
|
* If the DMA channel is not available, then stm32_dmachannel() will wait
|
||||||
|
* until the holder of the channel relinquishes the channel by calling
|
||||||
|
* stm32_dmafree(). WARNING: If you have two devices sharing a DMA
|
||||||
|
* channel and the code never releases the channel, the stm32_dmachannel
|
||||||
|
* call for the other will hang forever in this function! Don't let your
|
||||||
|
* design do that!
|
||||||
|
*
|
||||||
|
* Hmm.. I suppose this interface could be extended to make a non-blocking
|
||||||
|
* version. Feel free to do that if that is what you need.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* On success, a void* DMA channel handle; NULL on failure
|
* Provided that 'chan' is valid, this function ALWAYS returns a non-NULL,
|
||||||
|
* void* DMA channel handle. (If 'chan' is invalid, the function will
|
||||||
|
* assert if debug is enabled or do something ignorant otherwise).
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* - The caller does not hold he DMA channel.
|
||||||
|
* - The caller can wait for the DMA channel to be freed if it is no
|
||||||
|
* available.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
@ -326,10 +347,14 @@ DMA_HANDLE stm32_dmachannel(int chan)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: stm32_dmarelease
|
* Name: stm32_dmafree
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Release a DMA channel
|
* Release a DMA channel. If another thread is waiting for this DMA channel
|
||||||
|
* in a call to stm32_dmachannel, then this function will re-assign the
|
||||||
|
* DMA channel to that thread and wake it up. NOTE: The 'handle' used
|
||||||
|
* in this argument must NEVER be used again until stm32_dmachannel() is
|
||||||
|
* called again to re-gain access to the channel.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
|
@ -494,24 +494,53 @@ EXTERN void weak_function stm32_dmainitialize(void);
|
|||||||
* Name: stm32_dmachannel
|
* Name: stm32_dmachannel
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Allocate a DMA channel
|
* Allocate a DMA channel. This function gives the caller mutually
|
||||||
|
* exclusive access to the DMA channel specified by the 'chan' argument.
|
||||||
|
* DMA channels are shared on the STM32: Devices sharing the same DMA
|
||||||
|
* channel cannot do DMA concurrently! See the DMACHAN_* definitions in
|
||||||
|
* stm32_dma.h.
|
||||||
|
*
|
||||||
|
* If the DMA channel is not available, then stm32_dmachannel() will wait
|
||||||
|
* until the holder of the channel relinquishes the channel by calling
|
||||||
|
* stm32_dmafree(). WARNING: If you have two devices sharing a DMA
|
||||||
|
* channel and the code never releases the channel, the stm32_dmachannel
|
||||||
|
* call for the other will hang forever in this function! Don't let your
|
||||||
|
* design do that!
|
||||||
|
*
|
||||||
|
* Hmm.. I suppose this interface could be extended to make a non-blocking
|
||||||
|
* version. Feel free to do that if that is what you need.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* On success, a void* DMA channel handle; NULL on failure
|
* Provided that 'chan' is valid, this function ALWAYS returns a non-NULL,
|
||||||
|
* void* DMA channel handle. (If 'chan' is invalid, the function will
|
||||||
|
* assert if debug is enabled or do something ignorant otherwise).
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* - The caller does not hold he DMA channel.
|
||||||
|
* - The caller can wait for the DMA channel to be freed if it is no
|
||||||
|
* available.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
EXTERN DMA_HANDLE stm32_dmachannel(int chan);
|
EXTERN DMA_HANDLE stm32_dmachannel(int chan);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: stm32_dmarelease
|
* Name: stm32_dmafree
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Release a DMA channel
|
* Release a DMA channel. If another thread is waiting for this DMA channel
|
||||||
|
* in a call to stm32_dmachannel, then this function will re-assign the
|
||||||
|
* DMA channel to that thread and wake it up. NOTE: The 'handle' used
|
||||||
|
* in this argument must NEVER be used again until stm32_dmachannel() is
|
||||||
|
* called again to re-gain access to the channel.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* - The caller holds the DMA channel.
|
||||||
|
* - There is no DMA in progress
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
EXTERN void stm32_dmafree(DMA_HANDLE handle);
|
EXTERN void stm32_dmafree(DMA_HANDLE handle);
|
||||||
|
@ -163,14 +163,6 @@ static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv,
|
|||||||
FAR const void *txbuffer, FAR const void *txdummy, size_t nwords);
|
FAR const void *txbuffer, FAR const void *txdummy, size_t nwords);
|
||||||
static inline void spi_dmarxstart(FAR struct stm32_spidev_s *priv);
|
static inline void spi_dmarxstart(FAR struct stm32_spidev_s *priv);
|
||||||
static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv);
|
static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv);
|
||||||
static inline void spi_dmaexchange(FAR struct stm32_spidev_s *priv,
|
|
||||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
|
||||||
size_t nwords);
|
|
||||||
static inline void spi_dmatxexchange(FAR struct stm32_spidev_s *priv,
|
|
||||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
|
||||||
size_t nwords);
|
|
||||||
static inline void spi_dmarxexchange(FAR struct stm32_spidev_s *priv, FAR const void *txbuffer,
|
|
||||||
FAR void *rxbuffer, size_t nwords);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* SPI methods */
|
/* SPI methods */
|
||||||
@ -179,13 +171,8 @@ static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequen
|
|||||||
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
|
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||||
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits);
|
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits);
|
||||||
static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 wd);
|
static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 wd);
|
||||||
#ifdef CONFIG_STM32_SPI_DMA
|
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||||
static void spi_copyexchange(FAR struct spi_dev_s *dev,
|
FAR void *rxbuffer, size_t nwords);
|
||||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
|
||||||
size_t nwords);
|
|
||||||
#endif
|
|
||||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|
||||||
FAR void *rxbuffer, size_t nwords);
|
|
||||||
#ifndef CONFIG_SPI_EXCHANGE
|
#ifndef CONFIG_SPI_EXCHANGE
|
||||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||||
size_t nwords);
|
size_t nwords);
|
||||||
@ -652,226 +639,6 @@ static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/************************************************************************************
|
|
||||||
* Name: spi_dmaexchange
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Perform concurrent RX and TX DMA transfers
|
|
||||||
*
|
|
||||||
* priv - Device-specific state data
|
|
||||||
* txbuffer - A pointer to the buffer of data to be sent
|
|
||||||
* rxbuffer - A pointer to a buffer in which to receive data
|
|
||||||
* nwords - the length of data to be exchaned in units of words.
|
|
||||||
* The wordsize is determined by the number of bits-per-word
|
|
||||||
* selected for the SPI interface. If nbits <= 8, the data is
|
|
||||||
* packed into ubytes; if nbits >8, the data is packed into uint16's
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
************************************************************************************/
|
|
||||||
|
|
||||||
#ifdef CONFIG_STM32_SPI_DMA
|
|
||||||
static inline void spi_dmaexchange(FAR struct stm32_spidev_s *priv,
|
|
||||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
|
||||||
size_t nwords)
|
|
||||||
{
|
|
||||||
uint16 rxdummy = 0xffff;
|
|
||||||
uint16 txdummy;
|
|
||||||
|
|
||||||
/* Setup DMAs */
|
|
||||||
|
|
||||||
spi_dmarxsetup(priv, rxbuffer, &rxdummy, nwords);
|
|
||||||
spi_dmatxsetup(priv, txbuffer, &txdummy, nwords);
|
|
||||||
|
|
||||||
/* Start the DMAs */
|
|
||||||
|
|
||||||
spi_dmarxstart(priv);
|
|
||||||
spi_dmatxstart(priv);
|
|
||||||
|
|
||||||
/* Then wait for each to complete */
|
|
||||||
|
|
||||||
spi_dmarxwait(priv);
|
|
||||||
spi_dmatxwait(priv);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/************************************************************************************
|
|
||||||
* Name: spi_dmatxexchange
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Perform SPI exchange using DMA on the TX side only
|
|
||||||
*
|
|
||||||
* priv - Device-specific state data
|
|
||||||
* txbuffer - A pointer to the buffer of data to be sent
|
|
||||||
* rxbuffer - A pointer to a buffer in which to receive data
|
|
||||||
* nwords - the length of data to be exchaned in units of words.
|
|
||||||
* The wordsize is determined by the number of bits-per-word
|
|
||||||
* selected for the SPI interface. If nbits <= 8, the data is
|
|
||||||
* packed into ubytes; if nbits >8, the data is packed into uint16's
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
************************************************************************************/
|
|
||||||
|
|
||||||
#ifdef CONFIG_STM32_SPI_DMA
|
|
||||||
static inline void spi_dmatxexchange(FAR struct stm32_spidev_s *priv,
|
|
||||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
|
||||||
size_t nwords)
|
|
||||||
{
|
|
||||||
uint16 txdummy;
|
|
||||||
|
|
||||||
/* Setup and start the TX DMA */
|
|
||||||
|
|
||||||
spi_dmatxsetup(priv, txbuffer, &txdummy, nwords);
|
|
||||||
spi_dmatxstart(priv);
|
|
||||||
|
|
||||||
/* Then read the RX data via a polling loop */
|
|
||||||
|
|
||||||
/* 8- or 16-bit mode? */
|
|
||||||
|
|
||||||
if (spi_16bitmode(priv))
|
|
||||||
{
|
|
||||||
/* 16-bit mode */
|
|
||||||
|
|
||||||
uint16 *dest = (uint16*)rxbuffer;
|
|
||||||
uint16 word;
|
|
||||||
|
|
||||||
while (nwords-- > 0)
|
|
||||||
{
|
|
||||||
/* Read one word */
|
|
||||||
|
|
||||||
word = spi_readword(priv);
|
|
||||||
|
|
||||||
/* Is there a buffer to receive the return value? */
|
|
||||||
|
|
||||||
if (dest)
|
|
||||||
{
|
|
||||||
*dest++ = word;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 8-bit mode */
|
|
||||||
|
|
||||||
ubyte *dest = (ubyte*)rxbuffer;
|
|
||||||
ubyte word;
|
|
||||||
|
|
||||||
while (nwords-- > 0)
|
|
||||||
{
|
|
||||||
/* Read one word */
|
|
||||||
|
|
||||||
word = (ubyte)spi_readword(priv);
|
|
||||||
|
|
||||||
/* Is there a buffer to receive the return value? */
|
|
||||||
|
|
||||||
if (dest)
|
|
||||||
{
|
|
||||||
*dest++ = word;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Then wait for the TX DMA to complete (should already be finished) */
|
|
||||||
|
|
||||||
spi_dmatxwait(priv);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/************************************************************************************
|
|
||||||
* Name: spi_dmarxexchange
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Perform SPI exchange using DMA on the RX side only
|
|
||||||
*
|
|
||||||
* priv - Device-specific state data
|
|
||||||
* txbuffer - A pointer to the buffer of data to be sent
|
|
||||||
* rxbuffer - A pointer to a buffer in which to receive data
|
|
||||||
* nwords - the length of data to be exchaned in units of words.
|
|
||||||
* The wordsize is determined by the number of bits-per-word
|
|
||||||
* selected for the SPI interface. If nbits <= 8, the data is
|
|
||||||
* packed into ubytes; if nbits >8, the data is packed into uint16's
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
************************************************************************************/
|
|
||||||
|
|
||||||
#ifdef CONFIG_STM32_SPI_DMA
|
|
||||||
static inline void spi_dmarxexchange(FAR struct stm32_spidev_s *priv,
|
|
||||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
|
||||||
size_t nwords)
|
|
||||||
{
|
|
||||||
uint16 rxdummy = 0xffff;
|
|
||||||
|
|
||||||
/* Setup and start the RX DMA */
|
|
||||||
|
|
||||||
spi_dmarxsetup(priv, rxbuffer, &rxdummy, nwords);
|
|
||||||
spi_dmarxstart(priv);
|
|
||||||
|
|
||||||
/* Then send all of the TX data via a copy loop */
|
|
||||||
|
|
||||||
/* 8- or 16-bit mode? */
|
|
||||||
|
|
||||||
if (spi_16bitmode(priv))
|
|
||||||
{
|
|
||||||
/* 16-bit mode */
|
|
||||||
|
|
||||||
const uint16 *src = (const uint16*)txbuffer;;
|
|
||||||
uint16 word;
|
|
||||||
|
|
||||||
while (nwords-- > 0)
|
|
||||||
{
|
|
||||||
/* Get the next word to write. Is there a source buffer? */
|
|
||||||
|
|
||||||
if (src)
|
|
||||||
{
|
|
||||||
word = *src++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
word = 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write one word */
|
|
||||||
|
|
||||||
spi_writeword(priv, word);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 8-bit mode */
|
|
||||||
|
|
||||||
const ubyte *src = (const ubyte*)txbuffer;;
|
|
||||||
ubyte word;
|
|
||||||
|
|
||||||
while (nwords-- > 0)
|
|
||||||
{
|
|
||||||
/* Get the next word to write. Is there a source buffer? */
|
|
||||||
|
|
||||||
if (src)
|
|
||||||
{
|
|
||||||
word = *src++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
word = 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write one word */
|
|
||||||
|
|
||||||
spi_writeword(priv, (uint16)word);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Then wait for the RX DMA to complete */
|
|
||||||
|
|
||||||
spi_dmarxwait(priv);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: spi_modifycr1
|
* Name: spi_modifycr1
|
||||||
*
|
*
|
||||||
@ -1098,10 +865,10 @@ static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 wd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Name: spi_exchange (no DMA) or spi_copyexchange (with DMA capability)
|
* Name: spi_exchange (no DMA)
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Exchange a block of data on SPI
|
* Exchange a block of data on SPI without using DMA
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* dev - Device-specific state data
|
* dev - Device-specific state data
|
||||||
@ -1117,14 +884,9 @@ static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 wd)
|
|||||||
*
|
*
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_STM32_SPI_DMA
|
#ifndef CONFIG_STM32_SPI_DMA
|
||||||
static void spi_copyexchange(FAR struct spi_dev_s *dev,
|
|
||||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
|
||||||
size_t nwords)
|
|
||||||
#else
|
|
||||||
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 void *rxbuffer, size_t nwords)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||||
DEBUGASSERT(priv && priv->spibase);
|
DEBUGASSERT(priv && priv->spibase);
|
||||||
@ -1198,12 +960,13 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Name: spi_exchange (with DMA capability)
|
* Name: spi_exchange (with DMA capability)
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Exchange a block of data on SPI
|
* Exchange a block of data on SPI using DMA
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* dev - Device-specific state data
|
* dev - Device-specific state data
|
||||||
@ -1224,42 +987,25 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||||||
FAR void *rxbuffer, size_t nwords)
|
FAR void *rxbuffer, size_t nwords)
|
||||||
{
|
{
|
||||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||||
|
uint16 rxdummy = 0xffff;
|
||||||
|
uint16 txdummy;
|
||||||
|
|
||||||
DEBUGASSERT(priv && priv->spibase);
|
DEBUGASSERT(priv && priv->spibase);
|
||||||
|
|
||||||
/* Do we have a TX dma channel? */
|
/* Setup DMAs */
|
||||||
|
|
||||||
if (priv->txdma)
|
spi_dmarxsetup(priv, rxbuffer, &rxdummy, nwords);
|
||||||
{
|
spi_dmatxsetup(priv, txbuffer, &txdummy, nwords);
|
||||||
/* Yes.. Do we have an RX dma channel too? */
|
|
||||||
|
|
||||||
if (priv->rxdma)
|
/* Start the DMAs */
|
||||||
{
|
|
||||||
/* Yes.. do the full DMA exchange */
|
|
||||||
|
|
||||||
spi_dmaexchange(priv, txbuffer, rxbuffer, nwords);
|
spi_dmarxstart(priv);
|
||||||
}
|
spi_dmatxstart(priv);
|
||||||
else
|
|
||||||
{
|
|
||||||
/* No... do the exchange with only TX DMA */
|
|
||||||
|
|
||||||
spi_dmatxexchange(priv, txbuffer, rxbuffer, nwords);
|
/* Then wait for each to complete */
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do we have an RX dma channel? */
|
spi_dmarxwait(priv);
|
||||||
|
spi_dmatxwait(priv);
|
||||||
else if (priv->rxdma)
|
|
||||||
{
|
|
||||||
/* Yes... do the exchange with only RX DMA */
|
|
||||||
|
|
||||||
spi_dmarxexchange(priv, txbuffer, rxbuffer, nwords);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* No... do the exchange with no DMA */
|
|
||||||
|
|
||||||
spi_copyexchange(dev, txbuffer, rxbuffer, nwords);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1366,12 +1112,17 @@ static void spi_portinitialize(FAR struct stm32_spidev_s *priv)
|
|||||||
sem_init(&priv->rxsem, 0, 0);
|
sem_init(&priv->rxsem, 0, 0);
|
||||||
sem_init(&priv->txsem, 0, 0);
|
sem_init(&priv->txsem, 0, 0);
|
||||||
|
|
||||||
/* Get DMA channels. Note that if we fail to get a DMA channel, we will just
|
/* Get DMA channels. NOTE: stm32_dmachannel() will always assign the DMA channel.
|
||||||
* fall back to dumb I/O.
|
* if the channel is not available, then stm32_dmachannel() will block and wait
|
||||||
|
* until the channel becomes available. WARNING: If you have another device sharing
|
||||||
|
* a DMA channel with SPI and the code never releases that channel, then the call
|
||||||
|
* to stm32_dmachannel() will hang forever in this function! Don't let your
|
||||||
|
* design do that!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
priv->rxdma = stm32_dmachannel(priv->rxch);
|
priv->rxdma = stm32_dmachannel(priv->rxch);
|
||||||
priv->txdma = stm32_dmachannel(priv->txch);
|
priv->txdma = stm32_dmachannel(priv->txch);
|
||||||
|
DEBUGASSERT(priv->rxdma && priv->txdma);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Enable spi */
|
/* Enable spi */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user