GPDMAv1 and SPIv4 ready for testing

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@16408 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2023-11-14 12:49:29 +00:00
parent a3b2b44a9c
commit d340c452ee
5 changed files with 336 additions and 245 deletions

View File

@ -321,9 +321,9 @@
* SPI driver system settings.
*/
#define STM32_SPI_USE_SPI1 TRUE
#define STM32_SPI_USE_SPI2 FALSE
#define STM32_SPI_USE_SPI3 FALSE
#define STM32_SPI_USE_SPI4 FALSE
#define STM32_SPI_USE_SPI2 TRUE
#define STM32_SPI_USE_SPI3 TRUE
#define STM32_SPI_USE_SPI4 TRUE
#define STM32_SPI_SPI1_RX_GPDMA_CHANNEL STM32_GPDMA1_MASK_FIFO2
#define STM32_SPI_SPI1_TX_GPDMA_CHANNEL STM32_GPDMA1_MASK_FIFO2
#define STM32_SPI_SPI2_RX_GPDMA_CHANNEL STM32_GPDMA2_MASK_FIFO2

View File

@ -25,8 +25,6 @@
#ifndef STM32_GPDMA_H
#define STM32_GPDMA_H
#if defined(STM32_GPDMA_REQUIRED) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
@ -70,8 +68,8 @@
DMA_CSR_TCF)
#define STM32_GPDMA_CCR_PRIO_POS DMA_CCR_PRIO_Pos
#define STM32_GPDMA_CCR_PRIO_MASK (3U << STM32_GPDMA_CR_PRIO_POS)
#define STM32_GPDMA_CCR_PRIO(n) ((n) << STM32_GPDMA_CR_PRIO_POS)
#define STM32_GPDMA_CCR_PRIO_MASK (3U << STM32_GPDMA_CCR_PRIO_POS)
#define STM32_GPDMA_CCR_PRIO(n) ((n) << STM32_GPDMA_CCR_PRIO_POS)
#define STM32_GPDMA_CCR_LAP DMA_CCR_LAP
#define STM32_GPDMA_CCR_LSM DMA_CCR_LSM
#define STM32_GPDMA_CCR_TOIE DMA_CCR_TOIE
@ -120,9 +118,9 @@
#define STM32_GPDMA_CTR1_SDW_LOG2_POS DMA_CTR1_SDW_LOG2_Pos
#define STM32_GPDMA_CTR1_SDW_LOG2_MASK (3U << STM32_GPDMA_CTR1_SDW_LOG2_POS)
#define STM32_GPDMA_CTR1_SDW_LOG2(n) ((n) << STM32_GPDMA_CTR1_SDW_LOG2_POS)
#define STM32_GPDMA_CTR1_SDW_BYTE(n) STM32_GPDMA_CTR1_SDW_LOG2(0U)
#define STM32_GPDMA_CTR1_SDW_HALF(n) STM32_GPDMA_CTR1_SDW_LOG2(1U)
#define STM32_GPDMA_CTR1_SDW_WORD(n) STM32_GPDMA_CTR1_SDW_LOG2(2U)
#define STM32_GPDMA_CTR1_SDW_BYTE STM32_GPDMA_CTR1_SDW_LOG2(0U)
#define STM32_GPDMA_CTR1_SDW_HALF STM32_GPDMA_CTR1_SDW_LOG2(1U)
#define STM32_GPDMA_CTR1_SDW_WORD STM32_GPDMA_CTR1_SDW_LOG2(2U)
#define STM32_GPDMA_CTR2_TCEM_POS DMA_CTR2_TCEM_Pos
#define STM32_GPDMA_CTR2_TCEM_MASK (3U << STM32_GPDMA_CTR2_TCEM_POS)
@ -206,15 +204,15 @@
(((prio) >= 0U) && ((prio) <= 3U))
/**
* @brief Checks if a GPDMA channel id is within the valid range.
* @brief Checks if a GPDMA channels mask contains all valid channels.
*
* @param[in] id GPDMA channel id
* @param[in] m mask of GPDMA channels
* @retval The check result.
* @retval false invalid GPDMA channel.
* @retval true correct GPDMA channel.
* @retval false invalid GPDMA channels in the mask.
* @retval true correct GPDMA channels.
*/
#define STM32_GPDMA_IS_VALID_CHANNEL(id) (((id) >= 0U) && \
((id) <= STM32_GPDMA_NUM_CHANNELS))
#define STM32_GPDMA_ARE_VALID_CHANNELS(m) \
(((m) & ~STM32_GPDMA_MASK_ANY) == 0U)
/**
* @brief Returns an unique numeric identifier for a GPDMA channel.
@ -356,7 +354,7 @@
* @brief Any channel on any GPDMA.
*/
#define STM32_GPDMA_MASK_ANY \
(STM32_GPDM1_MASK_ANY | STM32_GPDMA2_MASK_ANY)
(STM32_GPDMA1_MASK_ANY | STM32_GPDMA2_MASK_ANY)
/*===========================================================================*/
/* Driver data structures and types. */
@ -582,11 +580,73 @@ extern "C" {
/* Inline functions. */
/*===========================================================================*/
/**
* @brief Channel (re)initialization.
* @note CCR and CLBAR are initialized, all other registers are cleared.
*
* @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure
* @param[in] lbar CLBAR register initialization value
* @param[in] cr CCR register initialization value
*
* @api
*/
__STATIC_FORCEINLINE
void gpdmaChannelInit(const stm32_gpdma_channel_t *dmachp,
uint32_t lbar, uint32_t cr) {
DMA_Channel_TypeDef *chp;
/* Associated physical channel.*/
chp = dmachp->channel;
chp->CLBAR = lbar;
chp->CCR = cr;
chp->CSR = STM32_GPDMA_CSR_TOF | STM32_GPDMA_CSR_SUSPF |
STM32_GPDMA_CSR_USEF | STM32_GPDMA_CSR_ULEF |
STM32_GPDMA_CSR_DTEF | STM32_GPDMA_CSR_HTF |
STM32_GPDMA_CSR_TCF;
chp->CTR1 = 0U;
chp->CTR2 = 0U;
chp->CBR1 = 0U;
chp->CSAR = 0U;
chp->CDAR = 0U;
chp->CTR3 = 0U;
chp->CBR2 = 0U;
chp->CLLR = 0U;
}
/**
* @brief Prepares a GPDMA channel for transfer.
*
* @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure
* @param[in] cr CCR register initialization value
* @param[in] tr1 CTR1 register initialization value
* @param[in] tr2 CTR2 register initialization value
* @param[in] br1 CBR1 register initialization value
* @param[in] sar CSAR register initialization value
* @param[in] dar CDAR register initialization value
* @param[in] llr CLLR register initialization value
*
* @api
*/
__STATIC_FORCEINLINE
void gpdmaChannelSetupTransfer(const stm32_gpdma_channel_t *dmachp,
uint32_t tr1, uint32_t tr2, uint32_t br1,
volatile const void *sar, volatile void *dar,
uint32_t llr) {
DMA_Channel_TypeDef *chp = dmachp->channel;
chp->CTR1 = tr1;
chp->CTR2 = tr2;
chp->CBR1 = br1;
chp->CSAR = (uint32_t)sar;
chp->CDAR = (uint32_t)dar;
chp->CLLR = llr;
}
/**
* @brief Prepares a GPDMA channel for a 2D transfer.
* @note The channel must have 2D capability.
*
* @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure
* @param[in] tr1 CTR1 register initialization value
* @param[in] tr2 CTR2 register initialization value
* @param[in] br1 CBR1 register initialization value
@ -599,14 +659,11 @@ extern "C" {
* @api
*/
__STATIC_FORCEINLINE
void gpdmaSetupFullTransfer(const stm32_gpdma_channel_t *dmachp,
uint32_t cr, uint32_t tr1, uint32_t tr2,
uint32_t br1, const void *sar, void *dar,
uint32_t tr3, uint32_t br2, uint32_t llr) {
DMA_Channel_TypeDef *chp;
/* Associated physical channel.*/
chp = dmachp->channel;
void gpdmaChannelSetupTransfer2D(const stm32_gpdma_channel_t *dmachp,
uint32_t tr1, uint32_t tr2, uint32_t br1,
volatile const void *sar, volatile void *dar,
uint32_t tr3, uint32_t br2, uint32_t llr) {
DMA_Channel_TypeDef *chp = dmachp->channel;
chp->CTR1 = tr1;
chp->CTR2 = tr2;
@ -616,32 +673,89 @@ void gpdmaSetupFullTransfer(const stm32_gpdma_channel_t *dmachp,
chp->CTR3 = tr3;
chp->CBR2 = br2;
chp->CLLR = llr;
chp->CCR = cr; /* Last, because EN bit.*/
}
/**
* @brief Prepares a GPDMA channel for transfer.
* @note Unused channel registers are initialized to zero.
* @brief Channel enable.
*
* @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure
* @param[in] cr CCR register initialization value
* @param[in] tr1 CTR1 register initialization value
* @param[in] tr2 CTR2 register initialization value
* @param[in] br1 CBR1 register initialization value
* @param[in] sar CSAR register initialization value
* @param[in] dar CDAR register initialization value
*
* @api
*/
__STATIC_FORCEINLINE
void gpdmaSetupImmediateTransfer(const stm32_gpdma_channel_t *dmachp,
uint32_t cr, uint32_t tr1, uint32_t tr2,
uint32_t br1, const void *sar, void *dar) {
void gpdmaChannelEnable(const stm32_gpdma_channel_t *dmachp) {
DMA_Channel_TypeDef *chp = dmachp->channel;
gpdmaSetupFullTransfer(dmachp, cr, tr1, br1, tr2, sar, dar, 0U, 0U, 0U);
chp->CCR |= STM32_GPDMA_CCR_EN;
}
#endif /* defined(STM32_GPDMA_REQUIRED) */
/**
* @brief Set channel source pointer.
*
* @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure
* @param[in] s source pointer
*
* @api
*/
__STATIC_FORCEINLINE
void gpdmaChannelSetSource(const stm32_gpdma_channel_t *dmachp,
volatile const void *s) {
DMA_Channel_TypeDef *chp = dmachp->channel;
chp->CSAR = (uint32_t)s;
}
/**
* @brief Set channel destination pointer.
*
* @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure
* @param[in] d destination pointer
*
* @api
*/
__STATIC_FORCEINLINE
void gpdmaChannelSetDestination(const stm32_gpdma_channel_t *dmachp,
volatile const void *d) {
DMA_Channel_TypeDef *chp = dmachp->channel;
chp->CDAR = (uint32_t)d;
}
/**
* @brief Set channel transfer modes and triggers.
*
* @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure
* @param[in] tr1 CTR1 register initialization value
* @param[in] tr2 CTR2 register initialization value
* @param[in] llr CLLR register initialization value
*
* @api
*/
__STATIC_FORCEINLINE
void gpdmaChannelSetMode(const stm32_gpdma_channel_t *dmachp,
uint32_t tr1, uint32_t tr2, uint32_t llr) {
DMA_Channel_TypeDef *chp = dmachp->channel;
chp->CTR1 = tr1;
chp->CTR2 = tr2;
chp->CLLR = llr;
}
/**
* @brief Set channel counters.
*
* @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure
* @param[in] n transaction size
*
* @api
*/
__STATIC_FORCEINLINE
void gpdmaChannelTransactionSize(const stm32_gpdma_channel_t *dmachp,
size_t n) {
DMA_Channel_TypeDef *chp = dmachp->channel;
chp->CBR1 = (uint32_t)n;
}
#endif /* STM32_GPDMA_H */

View File

@ -114,8 +114,8 @@ static void spi_lld_suspend(SPIDriver *spip) {
static void spi_lld_stop_abort(SPIDriver *spip) {
/* Stopping DMAs and waiting for FIFOs to be empty.*/
gpdmaChannelDisable(spip->tx.dma);
gpdmaChannelDisable(spip->rx.dma);
gpdmaChannelDisable(spip->dmatx);
gpdmaChannelDisable(spip->dmarx);
/* Resetting SPI, this will stop it for sure and leave it
in a clean state.*/
@ -182,8 +182,8 @@ static msg_t spi_lld_stop_nicely(SPIDriver *spip) {
}
/* Stopping DMAs and waiting for FIFOs to be empty.*/
gpdmaChannelDisable(spip->tx.dma);
gpdmaChannelisable(spip->rx.dma);
gpdmaChannelDisable(spip->dmatx);
gpdmaChannelDisable(spip->dmarx);
/* Stopping SPI.*/
spi_lld_suspend(spip);
@ -288,18 +288,18 @@ static void spi_lld_serve_interrupt(SPIDriver *spip) {
static msg_t spi_lld_get_dma(SPIDriver *spip, uint32_t rxchn,
uint32_t txchn, uint32_t priority) {
spip->rx.dma = gpdmaChannelAllocI(rxchn, priority,
(stm32_gpdmaisr_t)spi_lld_serve_dma_rx_interrupt,
(void *)spip);
if (spip->rx.dma == NULL) {
spip->dmarx = gpdmaChannelAllocI(rxchn, priority,
(stm32_gpdmaisr_t)spi_lld_serve_dma_rx_interrupt,
(void *)spip);
if (spip->dmarx == NULL) {
return HAL_RET_NO_RESOURCE;
}
spip->tx.dma = gpdmaChannelAllocI(txchn, priority,
(stm32_gpdmaisr_t)spi_lld_serve_dma_tx_interrupt,
(void *)spip);
if (spip->tx.dma == NULL) {
gpdmaChannelFreeI(spip->rx.dma);
spip->dmatx = gpdmaChannelAllocI(txchn, priority,
(stm32_gpdmaisr_t)spi_lld_serve_dma_tx_interrupt,
(void *)spip);
if (spip->dmatx == NULL) {
gpdmaChannelFreeI(spip->dmarx);
return HAL_RET_NO_RESOURCE;
}
@ -450,8 +450,8 @@ void spi_lld_init(void) {
#if STM32_SPI_USE_SPI1
spiObjectInit(&SPID1);
SPID1.spi = SPI1;
SPID1.rx.dma = NULL;
SPID1.tx.dma = NULL;
SPID1.dmarx = NULL;
SPID1.dmatx = NULL;
SPID1.dreqrx = STM32_GPDMA_REQ_SPI1_RX;
SPID1.dreqtx = STM32_GPDMA_REQ_SPI1_TX;
SPID1.dprio = STM32_SPI_SPI1_DMA_PRIORITY;
@ -463,8 +463,8 @@ void spi_lld_init(void) {
#if STM32_SPI_USE_SPI2
spiObjectInit(&SPID2);
SPID2.spi = SPI2;
SPID2.rx.dma = NULL;
SPID2.tx.dma = NULL;
SPID2.dmarx = NULL;
SPID2.dmatx = NULL;
SPID2.dreqrx = STM32_GPDMA_REQ_SPI2_RX;
SPID2.dreqtx = STM32_GPDMA_REQ_SPI2_TX;
SPID2.dprio = STM32_SPI_SPI2_DMA_PRIORITY;
@ -476,8 +476,8 @@ void spi_lld_init(void) {
#if STM32_SPI_USE_SPI3
spiObjectInit(&SPID3);
SPID3.spi = SPI3;
SPID3.rx.dma = NULL;
SPID3.tx.dma = NULL;
SPID3.dmarx = NULL;
SPID3.dmatx = NULL;
SPID3.dreqrx = STM32_GPDMA_REQ_SPI3_RX;
SPID3.dreqtx = STM32_GPDMA_REQ_SPI3_TX;
SPID3.dprio = STM32_SPI_SPI3_DMA_PRIORITY;
@ -489,8 +489,8 @@ void spi_lld_init(void) {
#if STM32_SPI_USE_SPI4
spiObjectInit(&SPID4);
SPID4.spi = SPI4;
SPID4.rx.dma = NULL;
SPID4.tx.dma = NULL;
SPID4.dmarx = NULL;
SPID4.dmatx = NULL;
SPID4.dreqrx = STM32_GPDMA_REQ_SPI4_RX;
SPID4.dreqtx = STM32_GPDMA_REQ_SPI4_TX;
SPID4.dprio = STM32_SPI_SPI4_DMA_PRIORITY;
@ -502,8 +502,8 @@ void spi_lld_init(void) {
#if STM32_SPI_USE_SPI5
spiObjectInit(&SPID5);
SPID5.spi = SPI5;
SPID5.rx.dma = NULL;
SPID5.tx.dma = NULL;
SPID5.dmarx = NULL;
SPID5.dmatx = NULL;
SPID5.dreqrx = STM32_GPDMA_REQ_SPI5_RX;
SPID5.dreqtx = STM32_GPDMA_REQ_SPI5_TX;
SPID5.dprio = STM32_SPI_SPI5_DMA_PRIORITY;
@ -515,8 +515,8 @@ void spi_lld_init(void) {
#if STM32_SPI_USE_SPI6
spiObjectInit(&SPID6);
SPID6.spi = SPI6;
SPID6.rx.dma = NULL;
SPID6.tx.dma = NULL;
SPID6.dmarx = NULL;
SPID6.dmatx = NULL;
SPID6.dreqrx = STM32_GPDMA_REQ_SPI6_RX;
SPID6.dreqtx = STM32_GPDMA_REQ_SPI6_TX;
SPID6.dprio = STM32_SPI_SPI6_DMA_PRIORITY;
@ -652,31 +652,31 @@ msg_t spi_lld_start(SPIDriver *spip) {
// if (spip->config->circular) {
// dmaccr |= STM32_GPDMA_CCR_HTIE;
// }
gpdmaChannelInit(spip->dma.rx, dmalbar, dmaccr);
gpdmaChannelInit(spip->dma.tx, dmalbar, dmaccr);
gpdmaChannelInit(spip->dmarx, dmalbar, dmaccr);
gpdmaChannelSetSource(spip->dmarx, &spip->spi->RXDR);
gpdmaChannelInit(spip->dmatx, dmalbar, dmaccr);
gpdmaChannelSetDestination(spip->dmatx, &spip->spi->TXDR);
/* GPDMA transfer settings depending on frame size.*/
dsize = (spip->config->cfg1 & SPI_CFG1_DSIZE_Msk) + 1U;
spip->dtr1rx = STM32_GPDMA_CTR1_DAP_MEM |
STM32_GPDMA_CTR1_DINC |
STM32_GPDMA_CTR1_SAP_PER);
STM32_GPDMA_CTR1_SAP_PER;
spip->dtr1tx = STM32_GPDMA_CTR1_DAP_PER |
STM32_GPDMA_CTR1_SAP_MEM |
STM32_GPDMA_CTR1_SINC);
STM32_GPDMA_CTR1_SAP_MEM;
if (dsize <= 8U) {
/* Frame width is between 4 and 8 bits.*/
spip->dtr1rx |= STM32_GPDMA_CTR1_DDW_BYTE | STM32_GPDMA_CTR1_SDW_BYTE);
spip->tr1tx |= STM32_GPDMA_CTR1_DDW_BYTE | STM32_GPDMA_CTR1_SDW_BYTE);
spip->dtr1rx |= STM32_GPDMA_CTR1_DDW_BYTE | STM32_GPDMA_CTR1_SDW_BYTE;
spip->dtr1tx |= STM32_GPDMA_CTR1_DDW_BYTE | STM32_GPDMA_CTR1_SDW_BYTE;
}
else if (dsize <= 16U) {
/* Frame width is between 9 and 16 bits.*/
spip->dtr1rx |= STM32_GPDMA_CTR1_DDW_HALF | STM32_GPDMA_CTR1_SDW_HALF);
spip->dtr1tx |= STM32_GPDMA_CTR1_DDW_HALF | STM32_GPDMA_CTR1_SDW_HALF);
spip->dtr1rx |= STM32_GPDMA_CTR1_DDW_HALF | STM32_GPDMA_CTR1_SDW_HALF;
spip->dtr1tx |= STM32_GPDMA_CTR1_DDW_HALF | STM32_GPDMA_CTR1_SDW_HALF;
}
else {
/* Frame width is between 16 and 32 bits.*/
spip->dtr1rx |= STM32_GPDMA_CTR1_DDW_WORD | STM32_GPDMA_CTR1_SDW_WORD);
spip->dtr1tx |= STM32_GPDMA_CTR1_DDW_WORD | STM32_GPDMA_CTR1_SDW_WORD);
spip->dtr1rx |= STM32_GPDMA_CTR1_DDW_WORD | STM32_GPDMA_CTR1_SDW_WORD;
spip->dtr1tx |= STM32_GPDMA_CTR1_DDW_WORD | STM32_GPDMA_CTR1_SDW_WORD;
}
/* SPI setup and enable.*/
@ -714,8 +714,8 @@ void spi_lld_stop(SPIDriver *spip) {
#endif
#if defined(STM32_SPI_DMA_REQUIRED)
{
dmaStreamFreeI(spip->rx.dma);
dmaStreamFreeI(spip->tx.dma);
dmaStreamFreeI(spip->dmarx);
dmaStreamFreeI(spip->dmatx);
}
#endif
@ -806,42 +806,30 @@ void spi_lld_unselect(SPIDriver *spip) {
*/
msg_t spi_lld_ignore(SPIDriver *spip, size_t n) {
osalDbgAssert(n <= STM32_DMA_MAX_TRANSFER, "unsupported GPDMA transfer size");
osalDbgAssert(n <= STM32_GPDMA_MAX_TRANSFER, "unsupported GPDMA transfer size");
#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
if (spip->is_bdma)
#endif
#if defined(STM32_SPI_BDMA_REQUIRED)
{
bdmaStreamSetMemory(spip->rx.bdma, &spip->rxsink);
bdmaStreamSetTransactionSize(spip->rx.bdma, n);
bdmaStreamSetMode(spip->rx.bdma, spip->rxdmamode);
/* Setting up RX DMA channel.*/
gpdmaChannelSetDestination(spip->dmarx, &spip->rxsink);
gpdmaChannelTransactionSize(spip->dmarx, n);
gpdmaChannelSetMode(spip->dmarx,
(spip->config->dtr1rx |
spip->dtr1rx),
(spip->config->dtr2rx |
STM32_GPDMA_CTR2_REQSEL(spip->dreqrx)),
0U);
gpdmaChannelEnable(spip->dmarx);
bdmaStreamSetMemory(spip->tx.bdma, &spip->txsource);
bdmaStreamSetTransactionSize(spip->tx.bdma, n);
bdmaStreamSetMode(spip->tx.bdma, spip->txdmamode);
bdmaStreamEnable(spip->rx.bdma);
bdmaStreamEnable(spip->tx.bdma);
}
#endif
#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
else
#endif
#if defined(STM32_SPI_DMA_REQUIRED)
{
dmaStreamSetMemory0(spip->rx.dma, &spip->rxsink);
dmaStreamSetTransactionSize(spip->rx.dma, n);
dmaStreamSetMode(spip->rx.dma, spip->rxdmamode);
dmaStreamSetMemory0(spip->tx.dma, &spip->txsource);
dmaStreamSetTransactionSize(spip->tx.dma, n);
dmaStreamSetMode(spip->tx.dma, spip->txdmamode);
dmaStreamEnable(spip->rx.dma);
dmaStreamEnable(spip->tx.dma);
}
#endif
/* Setting up TX DMA channel.*/
gpdmaChannelSetSource(spip->dmatx, &spip->txsource);
gpdmaChannelTransactionSize(spip->dmatx, n);
gpdmaChannelSetMode(spip->dmatx,
(spip->config->dtr1tx |
spip->dtr1tx),
(spip->config->dtr2tx |
STM32_GPDMA_CTR2_REQSEL(spip->dreqtx) |
STM32_GPDMA_CTR2_DREQ),
0U);
gpdmaChannelEnable(spip->dmatx);
spi_lld_resume(spip);
@ -867,42 +855,32 @@ msg_t spi_lld_ignore(SPIDriver *spip, size_t n) {
msg_t spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
osalDbgAssert(n <= STM32_DMA_MAX_TRANSFER, "unsupported GPDMA transfer size");
osalDbgAssert(n <= STM32_GPDMA_CCR_PRIO_POS, "unsupported GPDMA transfer size");
#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
if (spip->is_bdma)
#endif
#if defined(STM32_SPI_BDMA_REQUIRED)
{
bdmaStreamSetMemory(spip->rx.bdma, rxbuf);
bdmaStreamSetTransactionSize(spip->rx.bdma, n);
bdmaStreamSetMode(spip->rx.bdma, spip->rxdmamode | STM32_BDMA_CR_MINC);
/* Setting up RX DMA channel.*/
gpdmaChannelSetDestination(spip->dmarx, rxbuf);
gpdmaChannelTransactionSize(spip->dmarx, n);
gpdmaChannelSetMode(spip->dmarx,
(spip->config->dtr1rx |
spip->dtr1rx |
STM32_GPDMA_CTR1_DINC),
(spip->config->dtr2rx |
STM32_GPDMA_CTR2_REQSEL(spip->dreqrx)),
0U);
gpdmaChannelEnable(spip->dmarx);
bdmaStreamSetMemory(spip->tx.bdma, txbuf);
bdmaStreamSetTransactionSize(spip->tx.bdma, n);
bdmaStreamSetMode(spip->tx.bdma, spip->txdmamode | STM32_BDMA_CR_MINC);
bdmaStreamEnable(spip->rx.bdma);
bdmaStreamEnable(spip->tx.bdma);
}
#endif
#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
else
#endif
#if defined(STM32_SPI_DMA_REQUIRED)
{
dmaStreamSetMemory0(spip->rx.dma, rxbuf);
dmaStreamSetTransactionSize(spip->rx.dma, n);
dmaStreamSetMode(spip->rx.dma, spip->rxdmamode | STM32_DMA_CR_MINC);
dmaStreamSetMemory0(spip->tx.dma, txbuf);
dmaStreamSetTransactionSize(spip->tx.dma, n);
dmaStreamSetMode(spip->tx.dma, spip->txdmamode | STM32_DMA_CR_MINC);
dmaStreamEnable(spip->rx.dma);
dmaStreamEnable(spip->tx.dma);
}
#endif
/* Setting up TX DMA channel.*/
gpdmaChannelSetSource(spip->dmatx, txbuf);
gpdmaChannelTransactionSize(spip->dmatx, n);
gpdmaChannelSetMode(spip->dmatx,
(spip->config->dtr1tx |
spip->dtr1tx |
STM32_GPDMA_CTR1_SINC),
(spip->config->dtr2tx |
STM32_GPDMA_CTR2_REQSEL(spip->dreqtx) |
STM32_GPDMA_CTR2_DREQ),
0U);
gpdmaChannelEnable(spip->dmatx);
spi_lld_resume(spip);
@ -925,42 +903,32 @@ msg_t spi_lld_exchange(SPIDriver *spip, size_t n,
*/
msg_t spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
osalDbgAssert(n <= STM32_DMA_MAX_TRANSFER, "unsupported GPDMA transfer size");
osalDbgAssert(n <= STM32_GPDMA_CCR_PRIO_POS, "unsupported GPDMA transfer size");
#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
if (spip->is_bdma)
#endif
#if defined(STM32_SPI_BDMA_REQUIRED)
{
bdmaStreamSetMemory(spip->rx.bdma, &spip->rxsink);
bdmaStreamSetTransactionSize(spip->rx.bdma, n);
bdmaStreamSetMode(spip->rx.bdma, spip->rxdmamode);
/* Setting up RX DMA channel.*/
gpdmaChannelSetDestination(spip->dmarx, &spip->rxsink);
gpdmaChannelTransactionSize(spip->dmarx, n);
gpdmaChannelSetMode(spip->dmarx,
(spip->config->dtr1rx |
spip->dtr1rx |
STM32_GPDMA_CTR1_DINC),
(spip->config->dtr2rx |
STM32_GPDMA_CTR2_REQSEL(spip->dreqrx)),
0U);
gpdmaChannelEnable(spip->dmarx);
bdmaStreamSetMemory(spip->tx.bdma, txbuf);
bdmaStreamSetTransactionSize(spip->tx.bdma, n);
bdmaStreamSetMode(spip->tx.bdma, spip->txdmamode | STM32_BDMA_CR_MINC);
bdmaStreamEnable(spip->rx.bdma);
bdmaStreamEnable(spip->tx.bdma);
}
#endif
#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
else
#endif
#if defined(STM32_SPI_DMA_REQUIRED)
{
dmaStreamSetMemory0(spip->rx.dma, &spip->rxsink);
dmaStreamSetTransactionSize(spip->rx.dma, n);
dmaStreamSetMode(spip->rx.dma, spip->rxdmamode);
dmaStreamSetMemory0(spip->tx.dma, txbuf);
dmaStreamSetTransactionSize(spip->tx.dma, n);
dmaStreamSetMode(spip->tx.dma, spip->txdmamode | STM32_DMA_CR_MINC);
dmaStreamEnable(spip->rx.dma);
dmaStreamEnable(spip->tx.dma);
}
#endif
/* Setting up TX DMA channel.*/
gpdmaChannelSetSource(spip->dmatx, txbuf);
gpdmaChannelTransactionSize(spip->dmatx, n);
gpdmaChannelSetMode(spip->dmatx,
(spip->config->dtr1tx |
spip->dtr1tx |
STM32_GPDMA_CTR1_SINC),
(spip->config->dtr2tx |
STM32_GPDMA_CTR2_REQSEL(spip->dreqtx) |
STM32_GPDMA_CTR2_DREQ),
0U);
gpdmaChannelEnable(spip->dmatx);
spi_lld_resume(spip);
@ -983,42 +951,32 @@ msg_t spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
*/
msg_t spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
osalDbgAssert(n <= STM32_DMA_MAX_TRANSFER, "unsupported GPDMA transfer size");
osalDbgAssert(n <= STM32_GPDMA_CCR_PRIO_POS, "unsupported GPDMA transfer size");
#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
if (spip->is_bdma)
#endif
#if defined(STM32_SPI_BDMA_REQUIRED)
{
bdmaStreamSetMemory(spip->rx.bdma, rxbuf);
bdmaStreamSetTransactionSize(spip->rx.bdma, n);
bdmaStreamSetMode(spip->rx.bdma, spip->rxdmamode | STM32_BDMA_CR_MINC);
/* Setting up RX DMA channel.*/
gpdmaChannelSetDestination(spip->dmarx, rxbuf);
gpdmaChannelTransactionSize(spip->dmarx, n);
gpdmaChannelSetMode(spip->dmarx,
(spip->config->dtr1rx |
spip->dtr1rx |
STM32_GPDMA_CTR1_DINC),
(spip->config->dtr2rx |
STM32_GPDMA_CTR2_REQSEL(spip->dreqrx)),
0U);
gpdmaChannelEnable(spip->dmarx);
bdmaStreamSetMemory(spip->tx.bdma, &spip->txsource);
bdmaStreamSetTransactionSize(spip->tx.bdma, n);
bdmaStreamSetMode(spip->tx.bdma, spip->txdmamode);
bdmaStreamEnable(spip->rx.bdma);
bdmaStreamEnable(spip->tx.bdma);
}
#endif
#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
else
#endif
#if defined(STM32_SPI_DMA_REQUIRED)
{
dmaStreamSetMemory0(spip->rx.dma, rxbuf);
dmaStreamSetTransactionSize(spip->rx.dma, n);
dmaStreamSetMode(spip->rx.dma, spip->rxdmamode | STM32_DMA_CR_MINC);
dmaStreamSetMemory0(spip->tx.dma, &spip->txsource);
dmaStreamSetTransactionSize(spip->tx.dma, n);
dmaStreamSetMode(spip->tx.dma, spip->txdmamode);
dmaStreamEnable(spip->rx.dma);
dmaStreamEnable(spip->tx.dma);
}
#endif
/* Setting up TX DMA channel.*/
gpdmaChannelSetSource(spip->dmatx, &spip->txsource);
gpdmaChannelTransactionSize(spip->dmatx, n);
gpdmaChannelSetMode(spip->dmatx,
(spip->config->dtr1tx |
spip->dtr1tx |
STM32_GPDMA_CTR1_SINC),
(spip->config->dtr2tx |
STM32_GPDMA_CTR2_REQSEL(spip->dreqtx) |
STM32_GPDMA_CTR2_DREQ),
0U);
gpdmaChannelEnable(spip->dmatx);
spi_lld_resume(spip);
@ -1055,7 +1013,7 @@ msg_t spi_lld_stop_transfer(SPIDriver *spip, size_t *sizep) {
#endif
#if defined(STM32_SPI_DMA_REQUIRED)
{
*sizep = dmaStreamGetTransactionSize(spip->rx.dma);
*sizep = dmaStreamGetTransactionSize(spip->dmarx);
}
#endif
}

View File

@ -345,92 +345,92 @@
/* Check on the validity of the assigned GPDMA channels.*/
#if STM32_SPI_USE_SPI1 && \
!STM32_GPDMA_IS_VALID_CHANNEL(STM32_SPI_SPI1_RX_GPDMA_CHANNEL)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI1_RX_GPDMA_CHANNEL)
#error "Invalid GPDMA channel assigned to SPI1 RX"
#endif
#if STM32_SPI_USE_SPI1 && \
!STM32_GPDMA_IS_VALID_CHANNEL(STM32_SPI_SPI1_TX_GPDMA_CHANNEL)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI1_TX_GPDMA_CHANNEL)
#error "Invalid GPDMA channel assigned to SPI1 TX"
#endif
#if STM32_SPI_USE_SPI2 && \
!STM32_GPDMA_IS_VALID_CHANNEL(STM32_SPI_SPI2_RX_GPDMA_CHANNEL)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI2_RX_GPDMA_CHANNEL)
#error "Invalid GPDMA channel assigned to SPI2 RX"
#endif
#if STM32_SPI_USE_SPI2 && \
!STM32_GPDMA_IS_VALID_CHANNEL(STM32_SPI_SPI2_TX_GPDMA_CHANNEL)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI2_TX_GPDMA_CHANNEL)
#error "Invalid GPDMA channel assigned to SPI2 TX"
#endif
#if STM32_SPI_USE_SPI3 && \
!STM32_GPDMA_IS_VALID_CHANNEL(STM32_SPI_SPI3_RX_GPDMA_CHANNEL)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI3_RX_GPDMA_CHANNEL)
#error "Invalid GPDMA channel assigned to SPI3 RX"
#endif
#if STM32_SPI_USE_SPI3 && \
!STM32_GPDMA_IS_VALID_CHANNEL(STM32_SPI_SPI3_TX_GPDMA_CHANNEL)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI3_TX_GPDMA_CHANNEL)
#error "Invalid GPDMA channel assigned to SPI3 TX"
#endif
#if STM32_SPI_USE_SPI4 && \
!STM32_GPDMA_IS_VALID_CHANNEL(STM32_SPI_SPI4_RX_GPDMA_CHANNEL)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI4_RX_GPDMA_CHANNEL)
#error "Invalid GPDMA channel assigned to SPI4 RX"
#endif
#if STM32_SPI_USE_SPI4 && \
!STM32_GPDMA_IS_VALID_CHANNEL(STM32_SPI_SPI4_TX_GPDMA_CHANNEL)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI4_TX_GPDMA_CHANNEL)
#error "Invalid GPDMA channel assigned to SPI4 TX"
#endif
#if STM32_SPI_USE_SPI5 && \
!STM32_GPDMA_IS_VALID_CHANNEL(STM32_SPI_SPI5_RX_GPDMA_CHANNEL)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI5_RX_GPDMA_CHANNEL)
#error "Invalid GPDMA channel assigned to SPI5 RX"
#endif
#if STM32_SPI_USE_SPI5 && \
!STM32_GPDMA_IS_VALID_CHANNEL(STM32_SPI_SPI5_TX_GPDMA_CHANNEL)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI5_TX_GPDMA_CHANNEL)
#error "Invalid GPDMA channel assigned to SPI5 TX"
#endif
#if STM32_SPI_USE_SPI6 && \
!STM32_GPDMA_IS_VALID_CHANNEL(STM32_SPI_SPI6_RX_BGPDMA_CHANNEL)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI6_RX_BGPDMA_CHANNEL)
#error "Invalid GPDMA channel assigned to SPI6 RX"
#endif
#if STM32_SPI_USE_SPI6 && \
!STM32_GPDMA_IS_VALID_CHANNEL(STM32_SPI_SPI6_TX_BGPDMA_CHANNEL)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI6_TX_BGPDMA_CHANNEL)
#error "Invalid GPDMA channel assigned to SPI6 TX"
#endif
#if STM32_SPI_USE_SPI1 && \
!STM32_GPDMA_IS_VALID_PRIORITY(STM32_SPI_SPI1_DMA_PRIORITY)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI1_DMA_PRIORITY)
#error "Invalid GPDMA priority assigned to SPI1"
#endif
#if STM32_SPI_USE_SPI2 && \
!STM32_GPDMA_IS_VALID_PRIORITY(STM32_SPI_SPI2_DMA_PRIORITY)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI2_DMA_PRIORITY)
#error "Invalid GPDMA priority assigned to SPI2"
#endif
#if STM32_SPI_USE_SPI3 && \
!STM32_GPDMA_IS_VALID_PRIORITY(STM32_SPI_SPI3_DMA_PRIORITY)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI3_DMA_PRIORITY)
#error "Invalid GPDMA priority assigned to SPI3"
#endif
#if STM32_SPI_USE_SPI4 && \
!STM32_GPDMA_IS_VALID_PRIORITY(STM32_SPI_SPI4_DMA_PRIORITY)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI4_DMA_PRIORITY)
#error "Invalid GPDMA priority assigned to SPI4"
#endif
#if STM32_SPI_USE_SPI5 && \
!STM32_GPDMA_IS_VALID_PRIORITY(STM32_SPI_SPI5_DMA_PRIORITY)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI5_DMA_PRIORITY)
#error "Invalid GPDMA priority assigned to SPI5"
#endif
#if STM32_SPI_USE_SPI6 && \
!STM32_GPDMA_IS_VALID_PRIORITY(STM32_SPI_SPI6_DMA_PRIORITY)
!STM32_GPDMA_ARE_VALID_CHANNELS(STM32_SPI_SPI6_DMA_PRIORITY)
#error "Invalid GPDMA priority assigned to SPI6"
#endif
@ -456,16 +456,10 @@
#define spi_lld_driver_fields \
/* Pointer to the SPIx registers block.*/ \
SPI_TypeDef *spi; \
/** Union of the RX GPDMA channels.*/ \
union { \
/* Receive GPDMA channel.*/ \
const stm32_gpdma_channel_t *dma; \
} rx; \
/* Union of the TX GPDMA channels.*/ \
union { \
/* Transmit GPDMA channel.*/ \
const stm32_gpdma_channel_t *dma; \
} tx; \
/* Receive GPDMA channel.*/ \
const stm32_gpdma_channel_t *dmarx; \
/* Transmit GPDMA channel.*/ \
const stm32_gpdma_channel_t *dmatx; \
/* DMA request line for RX.*/ \
uint8_t dreqrx; \
/* DMA request line for TX.*/ \
@ -488,7 +482,15 @@
/* SPI CFG1 register initialization data.*/ \
uint32_t cfg1; \
/* SPI CFG2 register initialization data.*/ \
uint32_t cfg2
uint32_t cfg2; \
/* DMA RX extra TR1 settings.*/ \
uint32_t dtr1rx; \
/* DMA TX extra TR1 settings.*/ \
uint32_t dtr1tx; \
/* DMA RX extra TR2 settings.*/ \
uint32_t dtr2rx; \
/* DMA TX extra TR2 settings.*/ \
uint32_t dtr2tx
/*===========================================================================*/
/* External declarations. */

View File

@ -148,6 +148,23 @@
#define STM32_EXTI14_NUMBER 25
#define STM32_EXTI15_NUMBER 26
/*
* SPI units.
*/
#define STM32_SPI1_HANDLER Vector11C
#define STM32_SPI2_HANDLER Vector120
#define STM32_SPI3_HANDLER Vector124
#define STM32_SPI4_HANDLER Vector188
#define STM32_SPI5_HANDLER Vector18C
#define STM32_SPI6_HANDLER Vector190
#define STM32_SPI1_NUMBER 55
#define STM32_SPI2_NUMBER 56
#define STM32_SPI3_NUMBER 57
#define STM32_SPI4_NUMBER 82
#define STM32_SPI5_NUMBER 83
#define STM32_SPI6_NUMBER 84
/*
* TIM units.
*/