stm32f7:spi Add buffers for DMA
This commit is contained in:
parent
a5e643b0cd
commit
6f32a6ad8f
@ -2297,6 +2297,13 @@ config STM32F7_SPI1_DMA
|
|||||||
---help---
|
---help---
|
||||||
Use DMA to improve SPI1 transfer performance.
|
Use DMA to improve SPI1 transfer performance.
|
||||||
|
|
||||||
|
config STM32F7_SPI1_DMA_BUFFER
|
||||||
|
int "SPI1 DMA buffer size"
|
||||||
|
default 0
|
||||||
|
depends on STM32F7_SPI1_DMA
|
||||||
|
---help---
|
||||||
|
Add a properly aligned DMA buffer for RX and TX DMA for SPI1.
|
||||||
|
|
||||||
config STM32F7_SPI2_DMA
|
config STM32F7_SPI2_DMA
|
||||||
bool "SPI2 DMA"
|
bool "SPI2 DMA"
|
||||||
default n
|
default n
|
||||||
@ -2304,6 +2311,13 @@ config STM32F7_SPI2_DMA
|
|||||||
---help---
|
---help---
|
||||||
Use DMA to improve SPI2 transfer performance.
|
Use DMA to improve SPI2 transfer performance.
|
||||||
|
|
||||||
|
config STM32F7_SPI2_DMA_BUFFER
|
||||||
|
int "SPI2 DMA buffer size"
|
||||||
|
default 0
|
||||||
|
depends on STM32F7_SPI2_DMA
|
||||||
|
---help---
|
||||||
|
Add a properly aligned DMA buffer for RX and TX DMA for SPI2.
|
||||||
|
|
||||||
config STM32F7_SPI3_DMA
|
config STM32F7_SPI3_DMA
|
||||||
bool "SPI3 DMA"
|
bool "SPI3 DMA"
|
||||||
default n
|
default n
|
||||||
@ -2311,6 +2325,13 @@ config STM32F7_SPI3_DMA
|
|||||||
---help---
|
---help---
|
||||||
Use DMA to improve SPI3 transfer performance.
|
Use DMA to improve SPI3 transfer performance.
|
||||||
|
|
||||||
|
config STM32F7_SPI3_DMA_BUFFER
|
||||||
|
int "SPI3 DMA buffer size"
|
||||||
|
default 0
|
||||||
|
depends on STM32F7_SPI3_DMA
|
||||||
|
---help---
|
||||||
|
Add a properly aligned DMA buffer for RX and TX DMA for SPI3.
|
||||||
|
|
||||||
config STM32F7_SPI4_DMA
|
config STM32F7_SPI4_DMA
|
||||||
bool "SPI4 DMA"
|
bool "SPI4 DMA"
|
||||||
default n
|
default n
|
||||||
@ -2318,6 +2339,13 @@ config STM32F7_SPI4_DMA
|
|||||||
---help---
|
---help---
|
||||||
Use DMA to improve SPI4 transfer performance.
|
Use DMA to improve SPI4 transfer performance.
|
||||||
|
|
||||||
|
config STM32F7_SPI4_DMA_BUFFER
|
||||||
|
int "SPI4 DMA buffer size"
|
||||||
|
default 0
|
||||||
|
depends on STM32F7_SPI4_DMA
|
||||||
|
---help---
|
||||||
|
Add a properly aligned DMA buffer for RX and TX DMA for SPI4.
|
||||||
|
|
||||||
config STM32F7_SPI5_DMA
|
config STM32F7_SPI5_DMA
|
||||||
bool "SPI5 DMA"
|
bool "SPI5 DMA"
|
||||||
default n
|
default n
|
||||||
@ -2325,6 +2353,13 @@ config STM32F7_SPI5_DMA
|
|||||||
---help---
|
---help---
|
||||||
Use DMA to improve SPI5 transfer performance.
|
Use DMA to improve SPI5 transfer performance.
|
||||||
|
|
||||||
|
config STM32F7_SPI5_DMA_BUFFER
|
||||||
|
int "SPI5 DMA buffer size"
|
||||||
|
default 0
|
||||||
|
depends on STM32F7_SPI5_DMA
|
||||||
|
---help---
|
||||||
|
Add a properly aligned DMA buffer for RX and TX DMA for SPI5.
|
||||||
|
|
||||||
config STM32F7_SPI6_DMA
|
config STM32F7_SPI6_DMA
|
||||||
bool "SPI6 DMA"
|
bool "SPI6 DMA"
|
||||||
default n
|
default n
|
||||||
@ -2332,6 +2367,13 @@ config STM32F7_SPI6_DMA
|
|||||||
---help---
|
---help---
|
||||||
Use DMA to improve SPI6 transfer performance.
|
Use DMA to improve SPI6 transfer performance.
|
||||||
|
|
||||||
|
config STM32F7_SPI6_DMA_BUFFER
|
||||||
|
int "SPI6 DMA buffer size"
|
||||||
|
default 0
|
||||||
|
depends on STM32F7_SPI6_DMA
|
||||||
|
---help---
|
||||||
|
Add a properly aligned DMA buffer for RX and TX DMA for SPI6.
|
||||||
|
|
||||||
endmenu # "SPI Configuration"
|
endmenu # "SPI Configuration"
|
||||||
|
|
||||||
menu "I2C Configuration"
|
menu "I2C Configuration"
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
@ -104,9 +105,9 @@
|
|||||||
# error "Unknown STM32 DMA"
|
# error "Unknown STM32 DMA"
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#if (SPI_DMA_PRIO & ~DMA_SCR_PL_MASK) != 0
|
# if (SPI_DMA_PRIO & ~DMA_SCR_PL_MASK) != 0
|
||||||
# error "Illegal value for CONFIG_SPI_DMAPRIO"
|
# error "Illegal value for CONFIG_SPI_DMAPRIO"
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
/* DMA channel configuration */
|
/* DMA channel configuration */
|
||||||
|
|
||||||
@ -118,6 +119,56 @@
|
|||||||
# define SPI_TXDMA8_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_MINC|DMA_SCR_DIR_M2P)
|
# define SPI_TXDMA8_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_MINC|DMA_SCR_DIR_M2P)
|
||||||
# define SPI_TXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_16BITS |DMA_SCR_DIR_M2P)
|
# define SPI_TXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_16BITS |DMA_SCR_DIR_M2P)
|
||||||
# define SPI_TXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_DIR_M2P)
|
# define SPI_TXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_DIR_M2P)
|
||||||
|
|
||||||
|
/* If built with CONFIG_ARMV7M_DCACHE Buffers need to be aligned and
|
||||||
|
* multiples of ARMV7M_DCACHE_LINESIZE
|
||||||
|
*/
|
||||||
|
|
||||||
|
# if defined(CONFIG_ARMV7M_DCACHE)
|
||||||
|
# define SPIDMA_BUFFER_MASK (ARMV7M_DCACHE_LINESIZE - 1)
|
||||||
|
# define SPIDMA_SIZE(b) (((b) + SPIDMA_BUFFER_MASK) & ~SPIDMA_BUFFER_MASK)
|
||||||
|
# define SPIDMA_BUF_ALIGN aligned_data(ARMV7M_DCACHE_LINESIZE)
|
||||||
|
# else
|
||||||
|
# define SPIDMA_SIZE(b) (b)
|
||||||
|
# define SPIDMA_BUF_ALIGN
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(CONFIG_STM32F7_SPI1_DMA_BUFFER) && \
|
||||||
|
CONFIG_STM32F7_SPI1_DMA_BUFFER > 0
|
||||||
|
# define SPI1_DMABUFSIZE_ADJUSTED SPIDMA_SIZE(CONFIG_STM32F7_SPI1_DMA_BUFFER)
|
||||||
|
# define SPI1_DMABUFSIZE_ALGN SPIDMA_BUF_ALIGN
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(CONFIG_STM32F7_SPI2_DMA_BUFFER) && \
|
||||||
|
CONFIG_STM32F7_SPI2_DMA_BUFFER > 0
|
||||||
|
# define SPI2_DMABUFSIZE_ADJUSTED SPIDMA_SIZE(CONFIG_STM32F7_SPI2_DMA_BUFFER)
|
||||||
|
# define SPI2_DMABUFSIZE_ALGN SPIDMA_BUF_ALIGN
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(CONFIG_STM32F7_SPI3_DMA_BUFFER) && \
|
||||||
|
CONFIG_STM32F7_SPI3_DMA_BUFFER > 0
|
||||||
|
# define SPI3_DMABUFSIZE_ADJUSTED SPIDMA_SIZE(CONFIG_STM32F7_SPI3_DMA_BUFFER)
|
||||||
|
# define SPI3_DMABUFSIZE_ALGN SPIDMA_BUF_ALIGN
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(CONFIG_STM32F7_SPI4_DMA_BUFFER) && \
|
||||||
|
CONFIG_STM32F7_SPI4_DMA_BUFFER > 0
|
||||||
|
# define SPI4_DMABUFSIZE_ADJUSTED SPIDMA_SIZE(CONFIG_STM32F7_SPI4_DMA_BUFFER)
|
||||||
|
# define SPI4_DMABUFSIZE_ALGN SPIDMA_BUF_ALIGN
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(CONFIG_STM32F7_SPI5_DMA_BUFFER) && \
|
||||||
|
CONFIG_STM32F7_SPI5_DMA_BUFFER > 0
|
||||||
|
# define SPI5_DMABUFSIZE_ADJUSTED SPIDMA_SIZE(CONFIG_STM32F7_SPI5_DMA_BUFFER)
|
||||||
|
# define SPI5_DMABUFSIZE_ALGN SPIDMA_BUF_ALIGN
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_STM32F7_SPI6_DMA_BUFFER) && \
|
||||||
|
CONFIG_STM32F7_SPI6_DMA_BUFFER > 0
|
||||||
|
# define SPI6_DMABUFSIZE_ADJUSTED SPIDMA_SIZE(CONFIG_STM32F7_SPI6_DMA_BUFFER)
|
||||||
|
# define SPI6_DMABUFSIZE_ALGN SPIDMA_BUF_ALIGN
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -141,6 +192,9 @@ struct stm32_spidev_s
|
|||||||
#endif
|
#endif
|
||||||
uint8_t rxch; /* The RX DMA channel number */
|
uint8_t rxch; /* The RX DMA channel number */
|
||||||
uint8_t txch; /* The TX DMA channel number */
|
uint8_t txch; /* The TX DMA channel number */
|
||||||
|
uint8_t *rxbuf; /* The RX DMA buffer */
|
||||||
|
uint8_t *txbuf; /* The TX DMA buffer */
|
||||||
|
size_t buflen; /* The DMA buffer length */
|
||||||
DMA_HANDLE rxdma; /* DMA channel handle for RX transfers */
|
DMA_HANDLE rxdma; /* DMA channel handle for RX transfers */
|
||||||
DMA_HANDLE txdma; /* DMA channel handle for TX transfers */
|
DMA_HANDLE txdma; /* DMA channel handle for TX transfers */
|
||||||
sem_t rxsem; /* Wait for RX DMA to complete */
|
sem_t rxsem; /* Wait for RX DMA to complete */
|
||||||
@ -172,7 +226,6 @@ static inline void spi_putreg(FAR struct stm32_spidev_s *priv,
|
|||||||
static inline uint16_t spi_readword(FAR struct stm32_spidev_s *priv);
|
static inline uint16_t spi_readword(FAR struct stm32_spidev_s *priv);
|
||||||
static inline void spi_writeword(FAR struct stm32_spidev_s *priv,
|
static inline void spi_writeword(FAR struct stm32_spidev_s *priv,
|
||||||
uint16_t byte);
|
uint16_t byte);
|
||||||
static inline bool spi_9to16bitmode(FAR struct stm32_spidev_s *priv);
|
|
||||||
|
|
||||||
/* DMA support */
|
/* DMA support */
|
||||||
|
|
||||||
@ -268,6 +321,11 @@ static const struct spi_ops_s g_sp1iops =
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(SPI1_DMABUFSIZE_ADJUSTED)
|
||||||
|
static uint8_t g_spi1_txbuf[SPI1_DMABUFSIZE_ADJUSTED] SPI1_DMABUFSIZE_ALGN;
|
||||||
|
static uint8_t g_spi1_rxbuf[SPI1_DMABUFSIZE_ADJUSTED] SPI1_DMABUFSIZE_ALGN;
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct stm32_spidev_s g_spi1dev =
|
static struct stm32_spidev_s g_spi1dev =
|
||||||
{
|
{
|
||||||
.spidev =
|
.spidev =
|
||||||
@ -283,6 +341,11 @@ static struct stm32_spidev_s g_spi1dev =
|
|||||||
# ifdef CONFIG_STM32F7_SPI1_DMA
|
# ifdef CONFIG_STM32F7_SPI1_DMA
|
||||||
.rxch = DMAMAP_SPI1_RX,
|
.rxch = DMAMAP_SPI1_RX,
|
||||||
.txch = DMAMAP_SPI1_TX,
|
.txch = DMAMAP_SPI1_TX,
|
||||||
|
#if defined(SPI1_DMABUFSIZE_ADJUSTED)
|
||||||
|
.rxbuf = g_spi1_rxbuf,
|
||||||
|
.txbuf = g_spi1_txbuf,
|
||||||
|
.buflen = SPI1_DMABUFSIZE_ADJUSTED,
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
.rxch = 0,
|
.rxch = 0,
|
||||||
.txch = 0,
|
.txch = 0,
|
||||||
@ -326,6 +389,11 @@ static const struct spi_ops_s g_sp2iops =
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(SPI2_DMABUFSIZE_ADJUSTED)
|
||||||
|
static uint8_t g_spi2_txbuf[SPI2_DMABUFSIZE_ADJUSTED] SPI2_DMABUFSIZE_ALGN;
|
||||||
|
static uint8_t g_spi2_rxbuf[SPI2_DMABUFSIZE_ADJUSTED] SPI2_DMABUFSIZE_ALGN;
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct stm32_spidev_s g_spi2dev =
|
static struct stm32_spidev_s g_spi2dev =
|
||||||
{
|
{
|
||||||
.spidev =
|
.spidev =
|
||||||
@ -341,6 +409,11 @@ static struct stm32_spidev_s g_spi2dev =
|
|||||||
# ifdef CONFIG_STM32F7_SPI2_DMA
|
# ifdef CONFIG_STM32F7_SPI2_DMA
|
||||||
.rxch = DMAMAP_SPI2_RX,
|
.rxch = DMAMAP_SPI2_RX,
|
||||||
.txch = DMAMAP_SPI2_TX,
|
.txch = DMAMAP_SPI2_TX,
|
||||||
|
#if defined(SPI2_DMABUFSIZE_ADJUSTED)
|
||||||
|
.rxbuf = g_spi2_rxbuf,
|
||||||
|
.txbuf = g_spi2_txbuf,
|
||||||
|
.buflen = SPI2_DMABUFSIZE_ADJUSTED,
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
.rxch = 0,
|
.rxch = 0,
|
||||||
.txch = 0,
|
.txch = 0,
|
||||||
@ -384,6 +457,11 @@ static const struct spi_ops_s g_sp3iops =
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(SPI3_DMABUFSIZE_ADJUSTED)
|
||||||
|
static uint8_t g_spi3_txbuf[SPI3_DMABUFSIZE_ADJUSTED] SPI3_DMABUFSIZE_ALGN;
|
||||||
|
static uint8_t g_spi3_rxbuf[SPI3_DMABUFSIZE_ADJUSTED] SPI3_DMABUFSIZE_ALGN;
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct stm32_spidev_s g_spi3dev =
|
static struct stm32_spidev_s g_spi3dev =
|
||||||
{
|
{
|
||||||
.spidev =
|
.spidev =
|
||||||
@ -399,6 +477,11 @@ static struct stm32_spidev_s g_spi3dev =
|
|||||||
# ifdef CONFIG_STM32F7_SPI3_DMA
|
# ifdef CONFIG_STM32F7_SPI3_DMA
|
||||||
.rxch = DMAMAP_SPI3_RX,
|
.rxch = DMAMAP_SPI3_RX,
|
||||||
.txch = DMAMAP_SPI3_TX,
|
.txch = DMAMAP_SPI3_TX,
|
||||||
|
#if defined(SPI3_DMABUFSIZE_ADJUSTED)
|
||||||
|
.rxbuf = g_spi3_rxbuf,
|
||||||
|
.txbuf = g_spi3_txbuf,
|
||||||
|
.buflen = SPI3_DMABUFSIZE_ADJUSTED,
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
.rxch = 0,
|
.rxch = 0,
|
||||||
.txch = 0,
|
.txch = 0,
|
||||||
@ -442,6 +525,11 @@ static const struct spi_ops_s g_sp4iops =
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(SPI4_DMABUFSIZE_ADJUSTED)
|
||||||
|
static uint8_t g_spi4_txbuf[SPI4_DMABUFSIZE_ADJUSTED] SPI4_DMABUFSIZE_ALGN;
|
||||||
|
static uint8_t g_spi4_rxbuf[SPI4_DMABUFSIZE_ADJUSTED] SPI4_DMABUFSIZE_ALGN;
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct stm32_spidev_s g_spi4dev =
|
static struct stm32_spidev_s g_spi4dev =
|
||||||
{
|
{
|
||||||
.spidev =
|
.spidev =
|
||||||
@ -457,6 +545,11 @@ static struct stm32_spidev_s g_spi4dev =
|
|||||||
# ifdef CONFIG_STM32F7_SPI4_DMA
|
# ifdef CONFIG_STM32F7_SPI4_DMA
|
||||||
.rxch = DMAMAP_SPI4_RX,
|
.rxch = DMAMAP_SPI4_RX,
|
||||||
.txch = DMAMAP_SPI4_TX,
|
.txch = DMAMAP_SPI4_TX,
|
||||||
|
#if defined(SPI4_DMABUFSIZE_ADJUSTED)
|
||||||
|
.rxbuf = g_spi4_rxbuf,
|
||||||
|
.txbuf = g_spi4_txbuf,
|
||||||
|
.buflen = SPI4_DMABUFSIZE_ADJUSTED,
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
.rxch = 0,
|
.rxch = 0,
|
||||||
.txch = 0,
|
.txch = 0,
|
||||||
@ -500,6 +593,11 @@ static const struct spi_ops_s g_sp5iops =
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(SPI5_DMABUFSIZE_ADJUSTED)
|
||||||
|
static uint8_t g_spi5_txbuf[SPI5_DMABUFSIZE_ADJUSTED] SPI5_DMABUFSIZE_ALGN;
|
||||||
|
static uint8_t g_spi5_rxbuf[SPI5_DMABUFSIZE_ADJUSTED] SPI5_DMABUFSIZE_ALGN;
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct stm32_spidev_s g_spi5dev =
|
static struct stm32_spidev_s g_spi5dev =
|
||||||
{
|
{
|
||||||
.spidev =
|
.spidev =
|
||||||
@ -515,6 +613,11 @@ static struct stm32_spidev_s g_spi5dev =
|
|||||||
# ifdef CONFIG_STM32F7_SPI5_DMA
|
# ifdef CONFIG_STM32F7_SPI5_DMA
|
||||||
.rxch = DMAMAP_SPI5_RX,
|
.rxch = DMAMAP_SPI5_RX,
|
||||||
.txch = DMAMAP_SPI5_TX,
|
.txch = DMAMAP_SPI5_TX,
|
||||||
|
#if defined(SPI5_DMABUFSIZE_ADJUSTED)
|
||||||
|
.rxbuf = g_spi5_rxbuf,
|
||||||
|
.txbuf = g_spi5_txbuf,
|
||||||
|
.buflen = SPI5_DMABUFSIZE_ADJUSTED,
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
.rxch = 0,
|
.rxch = 0,
|
||||||
.txch = 0,
|
.txch = 0,
|
||||||
@ -558,6 +661,11 @@ static const struct spi_ops_s g_sp6iops =
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(SPI6_DMABUFSIZE_ADJUSTED)
|
||||||
|
static uint8_t g_spi6_txbuf[SPI6_DMABUFSIZE_ADJUSTED] SPI6_DMABUFSIZE_ALGN;
|
||||||
|
static uint8_t g_spi6_rxbuf[SPI6_DMABUFSIZE_ADJUSTED] SPI6_DMABUFSIZE_ALGN;
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct stm32_spidev_s g_spi6dev =
|
static struct stm32_spidev_s g_spi6dev =
|
||||||
{
|
{
|
||||||
.spidev =
|
.spidev =
|
||||||
@ -573,6 +681,11 @@ static struct stm32_spidev_s g_spi6dev =
|
|||||||
# ifdef CONFIG_STM32F7_SPI6_DMA
|
# ifdef CONFIG_STM32F7_SPI6_DMA
|
||||||
.rxch = DMAMAP_SPI6_RX,
|
.rxch = DMAMAP_SPI6_RX,
|
||||||
.txch = DMAMAP_SPI6_TX,
|
.txch = DMAMAP_SPI6_TX,
|
||||||
|
#if defined(SPI6_DMABUFSIZE_ADJUSTED)
|
||||||
|
.rxbuf = g_spi6_rxbuf,
|
||||||
|
.txbuf = g_spi6_txbuf,
|
||||||
|
.buflen = SPI6_DMABUFSIZE_ADJUSTED,
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
.rxch = 0,
|
.rxch = 0,
|
||||||
.txch = 0,
|
.txch = 0,
|
||||||
@ -775,26 +888,6 @@ static inline void spi_writebyte(FAR struct stm32_spidev_s *priv,
|
|||||||
spi_putreg8(priv, STM32_SPI_DR_OFFSET, byte);
|
spi_putreg8(priv, STM32_SPI_DR_OFFSET, byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: spi_9to16bitmode
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Check if the SPI is operating in more then 8 bit mode
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* priv - Device-specific state data
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* true: >8 bit mode-bit mode, false: <= 8-bit mode
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static inline bool spi_9to16bitmode(FAR struct stm32_spidev_s *priv)
|
|
||||||
{
|
|
||||||
return ((spi_getreg(priv, STM32_SPI_CR2_OFFSET) & SPI_CR2_DS_9BIT) ==
|
|
||||||
SPI_CR2_DS_9BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: spi_dmarxwait
|
* Name: spi_dmarxwait
|
||||||
*
|
*
|
||||||
@ -926,7 +1019,7 @@ static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv,
|
|||||||
{
|
{
|
||||||
/* 8- or 16-bit mode? */
|
/* 8- or 16-bit mode? */
|
||||||
|
|
||||||
if (spi_9to16bitmode(priv))
|
if (priv->nbits > 8)
|
||||||
{
|
{
|
||||||
/* 16-bit mode -- is there a buffer to receive data in? */
|
/* 16-bit mode -- is there a buffer to receive data in? */
|
||||||
|
|
||||||
@ -977,7 +1070,7 @@ static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv,
|
|||||||
{
|
{
|
||||||
/* 8- or 16-bit mode? */
|
/* 8- or 16-bit mode? */
|
||||||
|
|
||||||
if (spi_9to16bitmode(priv))
|
if (priv->nbits > 8)
|
||||||
{
|
{
|
||||||
/* 16-bit mode -- is there a buffer to transfer data from? */
|
/* 16-bit mode -- is there a buffer to transfer data from? */
|
||||||
|
|
||||||
@ -1505,7 +1598,7 @@ static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
|||||||
* frames, two bytes are received by a 16-bit read of the data register!
|
* frames, two bytes are received by a 16-bit read of the data register!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (spi_9to16bitmode(priv))
|
if (priv->nbits > 8)
|
||||||
{
|
{
|
||||||
spi_writeword(priv, (uint16_t)(wd & 0xffff));
|
spi_writeword(priv, (uint16_t)(wd & 0xffff));
|
||||||
ret = (uint32_t)spi_readword(priv);
|
ret = (uint32_t)spi_readword(priv);
|
||||||
@ -1522,7 +1615,7 @@ static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
|||||||
|
|
||||||
regval = spi_getreg(priv, STM32_SPI_SR_OFFSET);
|
regval = spi_getreg(priv, STM32_SPI_SR_OFFSET);
|
||||||
|
|
||||||
if (spi_9to16bitmode(priv))
|
if (priv->nbits > 8)
|
||||||
{
|
{
|
||||||
spiinfo("Sent: %04x Return: %04x Status: %02x\n", wd, ret, regval);
|
spiinfo("Sent: %04x Return: %04x Status: %02x\n", wd, ret, regval);
|
||||||
}
|
}
|
||||||
@ -1574,7 +1667,7 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev,
|
|||||||
|
|
||||||
/* 8- or 16-bit mode? */
|
/* 8- or 16-bit mode? */
|
||||||
|
|
||||||
if (spi_9to16bitmode(priv))
|
if (priv->nbits > 8)
|
||||||
{
|
{
|
||||||
/* 16-bit mode */
|
/* 16-bit mode */
|
||||||
|
|
||||||
@ -1672,14 +1765,15 @@ 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;
|
||||||
|
FAR void * xbuffer = rxbuffer;
|
||||||
DEBUGASSERT(priv != NULL);
|
DEBUGASSERT(priv != NULL);
|
||||||
|
|
||||||
#ifdef CONFIG_STM32F7_SPI_DMATHRESHOLD
|
|
||||||
/* Convert the number of word to a number of bytes */
|
/* Convert the number of word to a number of bytes */
|
||||||
|
|
||||||
size_t nbytes = (priv->nbits > 8) ? nwords << 1 : nwords;
|
size_t nbytes = (priv->nbits > 8) ? nwords << 1 : nwords;
|
||||||
|
|
||||||
|
#ifdef CONFIG_STM32F7_SPI_DMATHRESHOLD
|
||||||
|
|
||||||
/* If this is a small SPI transfer, then let spi_exchange_nodma() do the work. */
|
/* If this is a small SPI transfer, then let spi_exchange_nodma() do the work. */
|
||||||
|
|
||||||
if (nbytes <= CONFIG_STM32F7_SPI_DMATHRESHOLD)
|
if (nbytes <= CONFIG_STM32F7_SPI_DMATHRESHOLD)
|
||||||
@ -1701,27 +1795,26 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_STM32F7_DMACAPABLE
|
#ifdef CONFIG_STM32F7_DMACAPABLE
|
||||||
if ((txbuffer &&
|
/* If this bus uses a in driver DMA aligned buffers we can skip the test */
|
||||||
|
|
||||||
|
if ((txbuffer && priv->txbuf == 0 &&
|
||||||
!stm32_dmacapable((uint32_t)txbuffer, nwords, priv->txccr)) ||
|
!stm32_dmacapable((uint32_t)txbuffer, nwords, priv->txccr)) ||
|
||||||
(rxbuffer &&
|
(rxbuffer && priv->rxbuf == 0 &&
|
||||||
!stm32_dmacapable((uint32_t)rxbuffer, nwords, priv->rxccr)))
|
!stm32_dmacapable((uint32_t)rxbuffer, nwords, priv->rxccr)))
|
||||||
{
|
{
|
||||||
/* Unsupported memory region fall back to non-DMA method. */
|
/* Unsupported memory region or not in driver buffers
|
||||||
|
* fall back to non-DMA method.
|
||||||
|
*/
|
||||||
|
|
||||||
spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords);
|
spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
static uint8_t rxdummy[ARMV7M_DCACHE_LINESIZE]
|
/* The dummy buffer is used to DMA with out increment into */
|
||||||
__attribute__((aligned(ARMV7M_DCACHE_LINESIZE)));
|
|
||||||
static const uint16_t txdummy = 0xffff;
|
|
||||||
size_t buflen = nwords;
|
|
||||||
|
|
||||||
if (spi_9to16bitmode(priv))
|
static uint8_t rxdummy[4] __attribute__((aligned(4)));
|
||||||
{
|
static const uint16_t txdummy = 0xffff;
|
||||||
buflen = nwords * sizeof(uint16_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n",
|
spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n",
|
||||||
txbuffer, rxbuffer, nwords);
|
txbuffer, rxbuffer, nwords);
|
||||||
@ -1729,6 +1822,27 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||||||
|
|
||||||
/* Setup DMAs */
|
/* Setup DMAs */
|
||||||
|
|
||||||
|
/* If this bus uses a in driver buffers we will incur 2 copies,
|
||||||
|
* The copy cost is << less the non DMA transfer time and having
|
||||||
|
* the buffer in the driver ensures DMA can be used. This is bacause
|
||||||
|
* the API does not support passing the buffer extent so the only
|
||||||
|
* extent is buffer + the transfer size. These can sizes be less than
|
||||||
|
* the cache line size, and not aligned and tyicaly greater then 4
|
||||||
|
* bytes, which is about the break even point for the DMA IO overhead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (txbuffer && priv->txbuf)
|
||||||
|
{
|
||||||
|
if (nbytes > priv->buflen)
|
||||||
|
{
|
||||||
|
nbytes = priv->buflen;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(priv->txbuf, txbuffer, nbytes);
|
||||||
|
txbuffer = priv->txbuf;
|
||||||
|
rxbuffer = rxbuffer ? priv->rxbuf : rxbuffer;
|
||||||
|
}
|
||||||
|
|
||||||
spi_dmarxsetup(priv, rxbuffer, (uint16_t *)rxdummy, nwords);
|
spi_dmarxsetup(priv, rxbuffer, (uint16_t *)rxdummy, nwords);
|
||||||
spi_dmatxsetup(priv, txbuffer, &txdummy, nwords);
|
spi_dmatxsetup(priv, txbuffer, &txdummy, nwords);
|
||||||
|
|
||||||
@ -1736,7 +1850,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||||||
|
|
||||||
if (txbuffer)
|
if (txbuffer)
|
||||||
{
|
{
|
||||||
up_flush_dcache((uintptr_t)txbuffer, (uintptr_t)txbuffer + buflen);
|
up_flush_dcache((uintptr_t)txbuffer, (uintptr_t)txbuffer + nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SPI_TRIGGER
|
#ifdef CONFIG_SPI_TRIGGER
|
||||||
@ -1776,12 +1890,12 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||||||
if (rxbuffer)
|
if (rxbuffer)
|
||||||
{
|
{
|
||||||
up_invalidate_dcache((uintptr_t)rxbuffer,
|
up_invalidate_dcache((uintptr_t)rxbuffer,
|
||||||
(uintptr_t)rxbuffer + buflen);
|
(uintptr_t)rxbuffer + nbytes);
|
||||||
}
|
|
||||||
else
|
if (priv->rxbuf)
|
||||||
{
|
{
|
||||||
up_invalidate_dcache((uintptr_t)rxdummy,
|
memcpy(xbuffer, priv->rxbuf, nbytes);
|
||||||
(uintptr_t)rxdummy + sizeof(rxdummy));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2244,6 +2358,7 @@ FAR struct spi_dev_s *stm32_spibus_initialize(int bus)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
spierr("ERROR: Unsupported SPI bus: %d\n", bus);
|
spierr("ERROR: Unsupported SPI bus: %d\n", bus);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user