From d340c452ee73bbcecb63d384eac7f7f3fd55fad6 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 14 Nov 2023 12:49:29 +0000 Subject: [PATCH] GPDMAv1 and SPIv4 ready for testing git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@16408 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- .../RT-STM32H563ZI-NUCLEO144/cfg/mcuconf.h | 6 +- os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.h | 188 ++++++++--- os/hal/ports/STM32/LLD/SPIv4/hal_spi_v2_lld.c | 310 ++++++++---------- os/hal/ports/STM32/LLD/SPIv4/hal_spi_v2_lld.h | 60 ++-- os/hal/ports/STM32/STM32H5xx/stm32_isr.h | 17 + 5 files changed, 336 insertions(+), 245 deletions(-) diff --git a/demos/STM32/RT-STM32H563ZI-NUCLEO144/cfg/mcuconf.h b/demos/STM32/RT-STM32H563ZI-NUCLEO144/cfg/mcuconf.h index 30484f285..18d107232 100644 --- a/demos/STM32/RT-STM32H563ZI-NUCLEO144/cfg/mcuconf.h +++ b/demos/STM32/RT-STM32H563ZI-NUCLEO144/cfg/mcuconf.h @@ -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 diff --git a/os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.h b/os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.h index fc9e46659..3751ceaa8 100644 --- a/os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.h +++ b/os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.h @@ -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 */ diff --git a/os/hal/ports/STM32/LLD/SPIv4/hal_spi_v2_lld.c b/os/hal/ports/STM32/LLD/SPIv4/hal_spi_v2_lld.c index eb0a8839e..7c893f80b 100644 --- a/os/hal/ports/STM32/LLD/SPIv4/hal_spi_v2_lld.c +++ b/os/hal/ports/STM32/LLD/SPIv4/hal_spi_v2_lld.c @@ -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 } diff --git a/os/hal/ports/STM32/LLD/SPIv4/hal_spi_v2_lld.h b/os/hal/ports/STM32/LLD/SPIv4/hal_spi_v2_lld.h index c2ba79c16..da1eaf1a1 100644 --- a/os/hal/ports/STM32/LLD/SPIv4/hal_spi_v2_lld.h +++ b/os/hal/ports/STM32/LLD/SPIv4/hal_spi_v2_lld.h @@ -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. */ diff --git a/os/hal/ports/STM32/STM32H5xx/stm32_isr.h b/os/hal/ports/STM32/STM32H5xx/stm32_isr.h index 5dc34f818..d7d879f57 100644 --- a/os/hal/ports/STM32/STM32H5xx/stm32_isr.h +++ b/os/hal/ports/STM32/STM32H5xx/stm32_isr.h @@ -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. */