From 3e6b210a946795fb8336e706f97cd16d5703a3c4 Mon Sep 17 00:00:00 2001 From: moment-NEW Date: Sun, 23 Aug 2026 11:01:29 +0800 Subject: [PATCH 1/3] [bsp][stm32] Add BDMA support for SPI DMA driver --- .../libraries/HAL_Drivers/drivers/SConscript | 1 + .../drivers/config/h7/dma_config.h | 150 +++++---- .../drivers/config/h7/spi_config.h | 114 +++++-- .../libraries/HAL_Drivers/drivers/drv_dma.c | 139 ++++++--- .../libraries/HAL_Drivers/drivers/drv_dma.h | 293 +++++++++++------- .../libraries/HAL_Drivers/drivers/drv_spi.c | 272 +++++++++++----- .../libraries/HAL_Drivers/drivers/drv_spi.h | 43 ++- 7 files changed, 687 insertions(+), 325 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript b/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript index bd717ad88520..b10ef6eb32eb 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript @@ -8,6 +8,7 @@ group = [] src = [] # DMA-capable BSPs are expected to enable HAL_DMA_MODULE_ENABLED in the # STM32 HAL configuration, so keep the common DMA helper in the build. + src += ['drv_dma.c'] path = [cwd] diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/dma_config.h b/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/dma_config.h index d909db39a09f..14f002d62290 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/dma_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/dma_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2026, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -8,6 +8,7 @@ * 2019-01-02 zylx first version * 2019-01-08 SummerGift clean up the code * 2020-05-02 whj4674672 support stm32h7 dma1 and dma2 + * 2026-08-01 moment-NEW add BDMA support */ #ifndef __DMA_CONFIG_H__ @@ -21,136 +22,155 @@ extern "C" { /* DMA1 stream0 */ #if defined(BSP_UART2_RX_USING_DMA) && !defined(UART2_RX_DMA_INSTANCE) -#define UART2_DMA_RX_IRQHandler DMA1_Stream0_IRQHandler -#define UART2_RX_DMA_RCC RCC_AHB1ENR_DMA1EN -#define UART2_RX_DMA_INSTANCE DMA1_Stream0 -#define UART2_RX_DMA_REQUEST DMA_REQUEST_USART2_RX -#define UART2_RX_DMA_IRQ DMA1_Stream0_IRQn +#define UART2_DMA_RX_IRQHandler DMA1_Stream0_IRQHandler +#define UART2_RX_DMA_RCC RCC_AHB1ENR_DMA1EN +#define UART2_RX_DMA_INSTANCE DMA1_Stream0 +#define UART2_RX_DMA_REQUEST DMA_REQUEST_USART2_RX +#define UART2_RX_DMA_IRQ DMA1_Stream0_IRQn #endif /* DMA1 stream1 */ #if defined(BSP_UART2_TX_USING_DMA) && !defined(UART2_TX_DMA_INSTANCE) -#define UART2_DMA_TX_IRQHandler DMA1_Stream1_IRQHandler -#define UART2_TX_DMA_RCC RCC_AHB1ENR_DMA1EN -#define UART2_TX_DMA_INSTANCE DMA1_Stream1 -#define UART2_TX_DMA_REQUEST DMA_REQUEST_USART2_TX -#define UART2_TX_DMA_IRQ DMA1_Stream1_IRQn +#define UART2_DMA_TX_IRQHandler DMA1_Stream1_IRQHandler +#define UART2_TX_DMA_RCC RCC_AHB1ENR_DMA1EN +#define UART2_TX_DMA_INSTANCE DMA1_Stream1 +#define UART2_TX_DMA_REQUEST DMA_REQUEST_USART2_TX +#define UART2_TX_DMA_IRQ DMA1_Stream1_IRQn #endif /* DMA1 stream2 */ #if defined(BSP_SPI3_RX_USING_DMA) && !defined(SPI3_RX_DMA_INSTANCE) -#define SPI3_DMA_RX_IRQHandler DMA1_Stream2_IRQHandler -#define SPI3_RX_DMA_RCC RCC_AHB1ENR_DMA1EN -#define SPI3_RX_DMA_INSTANCE DMA1_Stream2 -#define SPI3_RX_DMA_IRQ DMA1_Stream2_IRQn +#define SPI3_DMA_RX_IRQHandler DMA1_Stream2_IRQHandler +#define SPI3_RX_DMA_RCC RCC_AHB1ENR_DMA1EN +#define SPI3_RX_DMA_INSTANCE DMA1_Stream2 +#define SPI3_RX_DMA_IRQ DMA1_Stream2_IRQn #endif /* DMA1 stream3 */ #if defined(BSP_SPI2_RX_USING_DMA) && !defined(SPI2_RX_DMA_INSTANCE) -#define SPI2_DMA_RX_IRQHandler DMA1_Stream3_IRQHandler -#define SPI2_RX_DMA_RCC RCC_AHB1ENR_DMA1EN -#define SPI2_RX_DMA_INSTANCE DMA1_Stream3 -#define SPI2_RX_DMA_IRQ DMA1_Stream3_IRQn +#define SPI2_DMA_RX_IRQHandler DMA1_Stream3_IRQHandler +#define SPI2_RX_DMA_RCC RCC_AHB1ENR_DMA1EN +#define SPI2_RX_DMA_INSTANCE DMA1_Stream3 +#define SPI2_RX_DMA_IRQ DMA1_Stream3_IRQn #endif /* DMA1 stream4 */ #if defined(BSP_SPI2_TX_USING_DMA) && !defined(SPI2_TX_DMA_INSTANCE) -#define SPI2_DMA_TX_IRQHandler DMA1_Stream4_IRQHandler -#define SPI2_TX_DMA_RCC RCC_AHB1ENR_DMA1EN -#define SPI2_TX_DMA_INSTANCE DMA1_Stream4 -#define SPI2_TX_DMA_IRQ DMA1_Stream4_IRQn +#define SPI2_DMA_TX_IRQHandler DMA1_Stream4_IRQHandler +#define SPI2_TX_DMA_RCC RCC_AHB1ENR_DMA1EN +#define SPI2_TX_DMA_INSTANCE DMA1_Stream4 +#define SPI2_TX_DMA_IRQ DMA1_Stream4_IRQn #endif /* DMA1 stream5 */ #if defined(BSP_SPI3_TX_USING_DMA) && !defined(SPI3_TX_DMA_INSTANCE) -#define SPI3_DMA_TX_IRQHandler DMA1_Stream5_IRQHandler -#define SPI3_TX_DMA_RCC RCC_AHB1ENR_DMA1EN -#define SPI3_TX_DMA_INSTANCE DMA1_Stream5 -#define SPI3_TX_DMA_IRQ DMA1_Stream5_IRQn +#define SPI3_DMA_TX_IRQHandler DMA1_Stream5_IRQHandler +#define SPI3_TX_DMA_RCC RCC_AHB1ENR_DMA1EN +#define SPI3_TX_DMA_INSTANCE DMA1_Stream5 +#define SPI3_TX_DMA_IRQ DMA1_Stream5_IRQn #endif /* DMA1 stream6 */ /* DMA1 stream7 */ #if defined(BSP_SPI3_TX_USING_DMA) && !defined(SPI3_TX_DMA_INSTANCE) -#define SPI3_DMA_TX_IRQHandler DMA1_Stream7_IRQHandler -#define SPI3_TX_DMA_RCC RCC_AHB1ENR_DMA1EN -#define SPI3_TX_DMA_INSTANCE DMA1_Stream7 -#define SPI3_TX_DMA_IRQ DMA1_Stream7_IRQn +#define SPI3_DMA_TX_IRQHandler DMA1_Stream7_IRQHandler +#define SPI3_TX_DMA_RCC RCC_AHB1ENR_DMA1EN +#define SPI3_TX_DMA_INSTANCE DMA1_Stream7 +#define SPI3_TX_DMA_IRQ DMA1_Stream7_IRQn #endif /* DMA2 stream0 */ #if defined(BSP_SPI1_RX_USING_DMA) && !defined(SPI1_RX_DMA_INSTANCE) -#define SPI1_DMA_RX_IRQHandler DMA2_Stream0_IRQHandler -#define SPI1_RX_DMA_RCC RCC_AHB1ENR_DMA2EN -#define SPI1_RX_DMA_INSTANCE DMA2_Stream0 -#define SPI1_RX_DMA_IRQ DMA2_Stream0_IRQn +#define SPI1_DMA_RX_IRQHandler DMA2_Stream0_IRQHandler +#define SPI1_RX_DMA_RCC RCC_AHB1ENR_DMA2EN +#define SPI1_RX_DMA_INSTANCE DMA2_Stream0 +#define SPI1_RX_DMA_IRQ DMA2_Stream0_IRQn #endif /* DMA2 stream1 */ #if defined(BSP_SPI4_TX_USING_DMA) && !defined(SPI4_TX_DMA_INSTANCE) -#define SPI4_DMA_TX_IRQHandler DMA2_Stream1_IRQHandler -#define SPI4_TX_DMA_RCC RCC_AHB1ENR_DMA2EN -#define SPI4_TX_DMA_INSTANCE DMA2_Stream1 -#define SPI4_TX_DMA_IRQ DMA2_Stream1_IRQn +#define SPI4_DMA_TX_IRQHandler DMA2_Stream1_IRQHandler +#define SPI4_TX_DMA_RCC RCC_AHB1ENR_DMA2EN +#define SPI4_TX_DMA_INSTANCE DMA2_Stream1 +#define SPI4_TX_DMA_IRQ DMA2_Stream1_IRQn #endif /* DMA2 stream2 */ #if defined(BSP_SPI1_RX_USING_DMA) && !defined(SPI1_RX_DMA_INSTANCE) -#define SPI1_DMA_RX_IRQHandler DMA2_Stream2_IRQHandler -#define SPI1_RX_DMA_RCC RCC_AHB1ENR_DMA2EN -#define SPI1_RX_DMA_INSTANCE DMA2_Stream2 -#define SPI1_RX_DMA_IRQ DMA2_Stream2_IRQn +#define SPI1_DMA_RX_IRQHandler DMA2_Stream2_IRQHandler +#define SPI1_RX_DMA_RCC RCC_AHB1ENR_DMA2EN +#define SPI1_RX_DMA_INSTANCE DMA2_Stream2 +#define SPI1_RX_DMA_IRQ DMA2_Stream2_IRQn #endif /* DMA2 stream3 */ #if defined(BSP_SPI5_RX_USING_DMA) && !defined(SPI5_RX_DMA_INSTANCE) -#define SPI5_DMA_RX_IRQHandler DMA2_Stream3_IRQHandler -#define SPI5_RX_DMA_RCC RCC_AHB1ENR_DMA2EN -#define SPI5_RX_DMA_INSTANCE DMA2_Stream3 -#define SPI5_RX_DMA_IRQ DMA2_Stream3_IRQn +#define SPI5_DMA_RX_IRQHandler DMA2_Stream3_IRQHandler +#define SPI5_RX_DMA_RCC RCC_AHB1ENR_DMA2EN +#define SPI5_RX_DMA_INSTANCE DMA2_Stream3 +#define SPI5_RX_DMA_IRQ DMA2_Stream3_IRQn #endif /* DMA2 stream4 */ #if defined(BSP_SPI5_TX_USING_DMA) && !defined(SPI5_TX_DMA_INSTANCE) -#define SPI5_DMA_TX_IRQHandler DMA2_Stream4_IRQHandler -#define SPI5_TX_DMA_RCC RCC_AHB1ENR_DMA2EN -#define SPI5_TX_DMA_INSTANCE DMA2_Stream4 -#define SPI5_TX_DMA_IRQ DMA2_Stream4_IRQn +#define SPI5_DMA_TX_IRQHandler DMA2_Stream4_IRQHandler +#define SPI5_TX_DMA_RCC RCC_AHB1ENR_DMA2EN +#define SPI5_TX_DMA_INSTANCE DMA2_Stream4 +#define SPI5_TX_DMA_IRQ DMA2_Stream4_IRQn #endif /* DMA2 stream5 */ #if defined(BSP_SPI1_TX_USING_DMA) && !defined(SPI1_TX_DMA_INSTANCE) -#define SPI1_DMA_TX_IRQHandler DMA2_Stream5_IRQHandler -#define SPI1_TX_DMA_RCC RCC_AHB1ENR_DMA2EN -#define SPI1_TX_DMA_INSTANCE DMA2_Stream5 -#define SPI1_TX_DMA_IRQ DMA2_Stream5_IRQn +#define SPI1_DMA_TX_IRQHandler DMA2_Stream5_IRQHandler +#define SPI1_TX_DMA_RCC RCC_AHB1ENR_DMA2EN +#define SPI1_TX_DMA_INSTANCE DMA2_Stream5 +#define SPI1_TX_DMA_IRQ DMA2_Stream5_IRQn #endif /* DMA2 stream6 */ #if defined(BSP_SPI5_TX_USING_DMA) && !defined(SPI5_TX_DMA_INSTANCE) -#define SPI5_DMA_TX_IRQHandler DMA2_Stream6_IRQHandler -#define SPI5_TX_DMA_RCC RCC_AHB1ENR_DMA2EN -#define SPI5_TX_DMA_INSTANCE DMA2_Stream6 -#define SPI5_TX_DMA_IRQ DMA2_Stream6_IRQn +#define SPI5_DMA_TX_IRQHandler DMA2_Stream6_IRQHandler +#define SPI5_TX_DMA_RCC RCC_AHB1ENR_DMA2EN +#define SPI5_TX_DMA_INSTANCE DMA2_Stream6 +#define SPI5_TX_DMA_IRQ DMA2_Stream6_IRQn #endif /* DMA2 stream7 */ #if defined(BSP_QSPI_USING_DMA) && !defined(QSPI_DMA_INSTANCE) -#define QSPI_DMA_IRQHandler DMA2_Stream7_IRQHandler -#define QSPI_DMA_RCC RCC_AHB1ENR_DMA2EN -#define QSPI_DMA_INSTANCE DMA2_Stream7 +#define QSPI_DMA_IRQHandler DMA2_Stream7_IRQHandler +#define QSPI_DMA_RCC RCC_AHB1ENR_DMA2EN +#define QSPI_DMA_INSTANCE DMA2_Stream7 #if defined(DMA_REQUEST_QUADSPI) -#define QSPI_DMA_REQUEST DMA_REQUEST_QUADSPI +#define QSPI_DMA_REQUEST DMA_REQUEST_QUADSPI #elif defined(DMA_REQUEST_QUADSPI1) -#define QSPI_DMA_REQUEST DMA_REQUEST_QUADSPI1 +#define QSPI_DMA_REQUEST DMA_REQUEST_QUADSPI1 #endif -#define QSPI_DMA_IRQ DMA2_Stream7_IRQn +#define QSPI_DMA_IRQ DMA2_Stream7_IRQn #endif +/*BDMA */ +#if defined(BSP_SPI6_TX_USING_BDMA) && !defined(SPI6_TX_BDMA_INSTANCE) +#define SPI6_BDMA_TX_IRQHandler BDMA_Channel0_IRQHandler +#define SPI6_TX_BDMA_INSTANCE BDMA_Channel0 +#define SPI6_TX_BDMA_RCC RCC_AHB4ENR_BDMAEN +#define SPI6_TX_BDMA_REQUEST BDMA_REQUEST_SPI6_TX +#define SPI6_TX_BDMA_IRQ BDMA_Channel0_IRQn +#endif + +#if defined(BSP_SPI6_RX_USING_BDMA) && !defined(SPI6_RX_BDMA_INSTANCE) +#define SPI6_BDMA_RX_IRQHandler BDMA_Channel1_IRQHandler +#define SPI6_RX_BDMA_INSTANCE BDMA_Channel1 +#define SPI6_RX_BDMA_RCC RCC_AHB4ENR_BDMAEN +#define SPI6_RX_BDMA_REQUEST BDMA_REQUEST_SPI6_RX +#define SPI6_RX_BDMA_IRQ BDMA_Channel1_IRQn +#endif + + #ifdef __cplusplus } #endif #endif /* __DMA_CONFIG_H__ */ + diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/spi_config.h index 4f5c8c9f82c2..847470428579 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/spi_config.h @@ -7,6 +7,7 @@ * Date Author Notes * 2018-11-06 SummerGift first version * 2026-04-13 wdfk-prog Unify DMA config descriptors + * 2026-08-01 moment-NEW add SPI6 & BDMA support */ #ifndef __SPI_CONFIG_H__ @@ -31,15 +32,15 @@ extern "C" { #ifdef BSP_SPI1_TX_USING_DMA #ifndef SPI1_TX_DMA_PRIORITY -#define SPI1_TX_DMA_PRIORITY DMA_PRIORITY_LOW +#define SPI1_TX_DMA_PRIORITY DMA_PRIORITY_LOW #endif /* SPI1_TX_DMA_PRIORITY */ #ifndef SPI1_TX_DMA_PREEMPT_PRIORITY -#define SPI1_TX_DMA_PREEMPT_PRIORITY 1 +#define SPI1_TX_DMA_PREEMPT_PRIORITY 1 #endif /* SPI1_TX_DMA_PREEMPT_PRIORITY */ #ifndef SPI1_TX_DMA_SUB_PRIORITY -#define SPI1_TX_DMA_SUB_PRIORITY 0 +#define SPI1_TX_DMA_SUB_PRIORITY 0 #endif /* SPI1_TX_DMA_SUB_PRIORITY */ #ifndef SPI1_TX_DMA_CONFIG #define SPI1_TX_DMA_CONFIG \ @@ -57,15 +58,15 @@ extern "C" { #ifdef BSP_SPI1_RX_USING_DMA #ifndef SPI1_RX_DMA_PRIORITY -#define SPI1_RX_DMA_PRIORITY DMA_PRIORITY_HIGH +#define SPI1_RX_DMA_PRIORITY DMA_PRIORITY_HIGH #endif /* SPI1_RX_DMA_PRIORITY */ #ifndef SPI1_RX_DMA_PREEMPT_PRIORITY -#define SPI1_RX_DMA_PREEMPT_PRIORITY 0 +#define SPI1_RX_DMA_PREEMPT_PRIORITY 0 #endif /* SPI1_RX_DMA_PREEMPT_PRIORITY */ #ifndef SPI1_RX_DMA_SUB_PRIORITY -#define SPI1_RX_DMA_SUB_PRIORITY 0 +#define SPI1_RX_DMA_SUB_PRIORITY 0 #endif /* SPI1_RX_DMA_SUB_PRIORITY */ #ifndef SPI1_RX_DMA_CONFIG #define SPI1_RX_DMA_CONFIG \ @@ -94,15 +95,15 @@ extern "C" { #ifdef BSP_SPI2_TX_USING_DMA #ifndef SPI2_TX_DMA_PRIORITY -#define SPI2_TX_DMA_PRIORITY DMA_PRIORITY_LOW +#define SPI2_TX_DMA_PRIORITY DMA_PRIORITY_LOW #endif /* SPI2_TX_DMA_PRIORITY */ #ifndef SPI2_TX_DMA_PREEMPT_PRIORITY -#define SPI2_TX_DMA_PREEMPT_PRIORITY 1 +#define SPI2_TX_DMA_PREEMPT_PRIORITY 1 #endif /* SPI2_TX_DMA_PREEMPT_PRIORITY */ #ifndef SPI2_TX_DMA_SUB_PRIORITY -#define SPI2_TX_DMA_SUB_PRIORITY 0 +#define SPI2_TX_DMA_SUB_PRIORITY 0 #endif /* SPI2_TX_DMA_SUB_PRIORITY */ #ifndef SPI2_TX_DMA_CONFIG #define SPI2_TX_DMA_CONFIG \ @@ -120,15 +121,15 @@ extern "C" { #ifdef BSP_SPI2_RX_USING_DMA #ifndef SPI2_RX_DMA_PRIORITY -#define SPI2_RX_DMA_PRIORITY DMA_PRIORITY_HIGH +#define SPI2_RX_DMA_PRIORITY DMA_PRIORITY_HIGH #endif /* SPI2_RX_DMA_PRIORITY */ #ifndef SPI2_RX_DMA_PREEMPT_PRIORITY -#define SPI2_RX_DMA_PREEMPT_PRIORITY 0 +#define SPI2_RX_DMA_PREEMPT_PRIORITY 0 #endif /* SPI2_RX_DMA_PREEMPT_PRIORITY */ #ifndef SPI2_RX_DMA_SUB_PRIORITY -#define SPI2_RX_DMA_SUB_PRIORITY 0 +#define SPI2_RX_DMA_SUB_PRIORITY 0 #endif /* SPI2_RX_DMA_SUB_PRIORITY */ #ifndef SPI2_RX_DMA_CONFIG #define SPI2_RX_DMA_CONFIG \ @@ -157,15 +158,15 @@ extern "C" { #ifdef BSP_SPI3_TX_USING_DMA #ifndef SPI3_TX_DMA_PRIORITY -#define SPI3_TX_DMA_PRIORITY DMA_PRIORITY_LOW +#define SPI3_TX_DMA_PRIORITY DMA_PRIORITY_LOW #endif /* SPI3_TX_DMA_PRIORITY */ #ifndef SPI3_TX_DMA_PREEMPT_PRIORITY -#define SPI3_TX_DMA_PREEMPT_PRIORITY 1 +#define SPI3_TX_DMA_PREEMPT_PRIORITY 1 #endif /* SPI3_TX_DMA_PREEMPT_PRIORITY */ #ifndef SPI3_TX_DMA_SUB_PRIORITY -#define SPI3_TX_DMA_SUB_PRIORITY 0 +#define SPI3_TX_DMA_SUB_PRIORITY 0 #endif /* SPI3_TX_DMA_SUB_PRIORITY */ #ifndef SPI3_TX_DMA_CONFIG #define SPI3_TX_DMA_CONFIG \ @@ -183,15 +184,15 @@ extern "C" { #ifdef BSP_SPI3_RX_USING_DMA #ifndef SPI3_RX_DMA_PRIORITY -#define SPI3_RX_DMA_PRIORITY DMA_PRIORITY_HIGH +#define SPI3_RX_DMA_PRIORITY DMA_PRIORITY_HIGH #endif /* SPI3_RX_DMA_PRIORITY */ #ifndef SPI3_RX_DMA_PREEMPT_PRIORITY -#define SPI3_RX_DMA_PREEMPT_PRIORITY 0 +#define SPI3_RX_DMA_PREEMPT_PRIORITY 0 #endif /* SPI3_RX_DMA_PREEMPT_PRIORITY */ #ifndef SPI3_RX_DMA_SUB_PRIORITY -#define SPI3_RX_DMA_SUB_PRIORITY 0 +#define SPI3_RX_DMA_SUB_PRIORITY 0 #endif /* SPI3_RX_DMA_SUB_PRIORITY */ #ifndef SPI3_RX_DMA_CONFIG #define SPI3_RX_DMA_CONFIG \ @@ -220,15 +221,15 @@ extern "C" { #ifdef BSP_SPI4_TX_USING_DMA #ifndef SPI4_TX_DMA_PRIORITY -#define SPI4_TX_DMA_PRIORITY DMA_PRIORITY_LOW +#define SPI4_TX_DMA_PRIORITY DMA_PRIORITY_LOW #endif /* SPI4_TX_DMA_PRIORITY */ #ifndef SPI4_TX_DMA_PREEMPT_PRIORITY -#define SPI4_TX_DMA_PREEMPT_PRIORITY 1 +#define SPI4_TX_DMA_PREEMPT_PRIORITY 1 #endif /* SPI4_TX_DMA_PREEMPT_PRIORITY */ #ifndef SPI4_TX_DMA_SUB_PRIORITY -#define SPI4_TX_DMA_SUB_PRIORITY 0 +#define SPI4_TX_DMA_SUB_PRIORITY 0 #endif /* SPI4_TX_DMA_SUB_PRIORITY */ #ifndef SPI4_TX_DMA_CONFIG #define SPI4_TX_DMA_CONFIG \ @@ -246,15 +247,15 @@ extern "C" { #ifdef BSP_SPI4_RX_USING_DMA #ifndef SPI4_RX_DMA_PRIORITY -#define SPI4_RX_DMA_PRIORITY DMA_PRIORITY_HIGH +#define SPI4_RX_DMA_PRIORITY DMA_PRIORITY_HIGH #endif /* SPI4_RX_DMA_PRIORITY */ #ifndef SPI4_RX_DMA_PREEMPT_PRIORITY -#define SPI4_RX_DMA_PREEMPT_PRIORITY 0 +#define SPI4_RX_DMA_PREEMPT_PRIORITY 0 #endif /* SPI4_RX_DMA_PREEMPT_PRIORITY */ #ifndef SPI4_RX_DMA_SUB_PRIORITY -#define SPI4_RX_DMA_SUB_PRIORITY 0 +#define SPI4_RX_DMA_SUB_PRIORITY 0 #endif /* SPI4_RX_DMA_SUB_PRIORITY */ #ifndef SPI4_RX_DMA_CONFIG #define SPI4_RX_DMA_CONFIG \ @@ -283,15 +284,15 @@ extern "C" { #ifdef BSP_SPI5_TX_USING_DMA #ifndef SPI5_TX_DMA_PRIORITY -#define SPI5_TX_DMA_PRIORITY DMA_PRIORITY_LOW +#define SPI5_TX_DMA_PRIORITY DMA_PRIORITY_LOW #endif /* SPI5_TX_DMA_PRIORITY */ #ifndef SPI5_TX_DMA_PREEMPT_PRIORITY -#define SPI5_TX_DMA_PREEMPT_PRIORITY 1 +#define SPI5_TX_DMA_PREEMPT_PRIORITY 1 #endif /* SPI5_TX_DMA_PREEMPT_PRIORITY */ #ifndef SPI5_TX_DMA_SUB_PRIORITY -#define SPI5_TX_DMA_SUB_PRIORITY 0 +#define SPI5_TX_DMA_SUB_PRIORITY 0 #endif /* SPI5_TX_DMA_SUB_PRIORITY */ #ifndef SPI5_TX_DMA_CONFIG #define SPI5_TX_DMA_CONFIG \ @@ -309,15 +310,15 @@ extern "C" { #ifdef BSP_SPI5_RX_USING_DMA #ifndef SPI5_RX_DMA_PRIORITY -#define SPI5_RX_DMA_PRIORITY DMA_PRIORITY_HIGH +#define SPI5_RX_DMA_PRIORITY DMA_PRIORITY_HIGH #endif /* SPI5_RX_DMA_PRIORITY */ #ifndef SPI5_RX_DMA_PREEMPT_PRIORITY -#define SPI5_RX_DMA_PREEMPT_PRIORITY 0 +#define SPI5_RX_DMA_PREEMPT_PRIORITY 0 #endif /* SPI5_RX_DMA_PREEMPT_PRIORITY */ #ifndef SPI5_RX_DMA_SUB_PRIORITY -#define SPI5_RX_DMA_SUB_PRIORITY 0 +#define SPI5_RX_DMA_SUB_PRIORITY 0 #endif /* SPI5_RX_DMA_SUB_PRIORITY */ #ifndef SPI5_RX_DMA_CONFIG #define SPI5_RX_DMA_CONFIG \ @@ -342,6 +343,59 @@ extern "C" { .irq_type = SPI6_IRQn, \ } #endif /* SPI6_BUS_CONFIG */ + +#ifdef BSP_SPI6_TX_USING_BDMA +#ifndef SPI6_TX_BDMA_PRIORITY +#define SPI6_TX_BDMA_PRIORITY DMA_PRIORITY_LOW +#endif /* SPI6_TX_BDMA_PRIORITY */ + +#ifndef SPI6_TX_BDMA_PREEMPT_PRIORITY +#define SPI6_TX_BDMA_PREEMPT_PRIORITY 1 +#endif /* SPI6_TX_BDMA_PREEMPT_PRIORITY */ + +#ifndef SPI6_TX_BDMA_SUB_PRIORITY +#define SPI6_TX_BDMA_SUB_PRIORITY 0 +#endif /* SPI6_TX_BDMA_SUB_PRIORITY */ + +#ifndef SPI6_TX_BDMA_CONFIG +#define SPI6_TX_BDMA_CONFIG \ + STM32_BDMA_TX_BYTE_CONFIG_INIT_EX( \ + SPI6_TX_BDMA_INSTANCE, \ + SPI6_TX_BDMA_RCC, \ + SPI6_TX_BDMA_IRQ, \ + BDMA_REQUEST_SPI6_TX, \ + SPI6_TX_BDMA_PRIORITY, \ + SPI6_TX_BDMA_PREEMPT_PRIORITY, \ + SPI6_TX_BDMA_SUB_PRIORITY) +#endif /* SPI6_TX_BDMA_CONFIG */ +#endif /* BSP_SPI6_TX_USING_BDMA */ + +#ifdef BSP_SPI6_RX_USING_BDMA +#ifndef SPI6_RX_BDMA_PRIORITY +#define SPI6_RX_BDMA_PRIORITY DMA_PRIORITY_HIGH +#endif /* SPI6_RX_BDMA_PRIORITY */ + +#ifndef SPI6_RX_BDMA_PREEMPT_PRIORITY +#define SPI6_RX_BDMA_PREEMPT_PRIORITY 0 +#endif /* SPI6_RX_BDMA_PREEMPT_PRIORITY */ + +#ifndef SPI6_RX_BDMA_SUB_PRIORITY +#define SPI6_RX_BDMA_SUB_PRIORITY 0 +#endif /* SPI6_RX_BDMA_SUB_PRIORITY */ + +#ifndef SPI6_RX_BDMA_CONFIG +#define SPI6_RX_BDMA_CONFIG \ + STM32_BDMA_RX_BYTE_CONFIG_INIT_EX( \ + SPI6_RX_BDMA_INSTANCE, \ + SPI6_RX_BDMA_RCC, \ + SPI6_RX_BDMA_IRQ, \ + BDMA_REQUEST_SPI6_RX, \ + SPI6_RX_BDMA_PRIORITY, \ + SPI6_RX_BDMA_PREEMPT_PRIORITY, \ + SPI6_RX_BDMA_SUB_PRIORITY) +#endif /* SPI6_RX_BDMA_CONFIG */ +#endif /* BSP_SPI6_RX_USING_BDMA */ + #endif /* BSP_USING_SPI6 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c index 01fbec237d61..bf3f6b67f62f 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c @@ -16,7 +16,7 @@ #include "drv_dma.h" // #define DRV_DEBUG -#define LOG_TAG "drv.dma" +#define LOG_TAG "drv.dma" #include /* * DMA-capable BSPs are expected to enable HAL_DMA_MODULE_ENABLED in the @@ -24,6 +24,19 @@ */ #ifdef HAL_DMA_MODULE_ENABLED +/** + * @brief Get the controller type name for logging. + * + * GPDMA-only series resolve to a constant string at compile time; other + * series distinguish BDMA and DMA by the descriptor type at runtime. + */ +#if defined(STM32_DMA_USES_GPDMA) +#define STM32_DMA_TYPE_NAME(dma_config) "gpdma" +#else +#define STM32_DMA_TYPE_NAME(dma_config) \ + (((dma_config)->common.type == STM32_DMA_TYPE_BDMA) ? "bdma" : "dma") +#endif /* defined(STM32_DMA_USES_GPDMA) */ + #if defined(STM32_DMA_USES_REQUEST) /** * @brief Enable the DMAMUX clock when the current STM32 DMA path needs it. @@ -39,13 +52,26 @@ static void stm32_dma_enable_dmamux_clock(void) #endif /* defined(STM32_DMA_USES_REQUEST) */ /** - * @brief Enable the clock of one DMA controller and wait for the write to complete. - * @param dma_rcc RCC enable bit of the DMA controller. + * @brief Enable the clock of one DMA/BDMA controller and wait for the write to complete. + * @param dma_rcc RCC enable bit of the DMA/BDMA controller. + * @param type Type of the DMA/BDMA controller. */ -static void stm32_dma_enable_clock(rt_uint32_t dma_rcc) +static void stm32_dma_enable_clock(rt_uint32_t dma_rcc, + stm32_dma_type type) { rt_uint32_t tmpreg = 0x00U; - +/*while using BDMA,careful for the return,because you cant visit the FIFO member*/ +/*if you did so there would be some illegal access.*/ +/*And,please note the domian you can visit*/ +#if defined(BSP_USING_BDMA) && (defined(SOC_SERIES_STM32H7)) + if (type == STM32_DMA_TYPE_BDMA) + { + SET_BIT(RCC->AHB4ENR, dma_rcc); + tmpreg = READ_BIT(RCC->AHB4ENR, dma_rcc); + UNUSED(tmpreg); + return; + } +#endif /* defined(BSP_USING_BDMA) && (defined(SOC_SERIES_STM32H7)) */ #if defined(STM32_DMA_USES_RCC_AHBENR) SET_BIT(RCC->AHBENR, dma_rcc); tmpreg = READ_BIT(RCC->AHBENR, dma_rcc); @@ -69,12 +95,9 @@ static void stm32_dma_enable_clock(rt_uint32_t dma_rcc) * DMA client does not disable a line still used by another active client. * All other DMA IRQs keep the direct enable/disable behavior. */ -#if (defined(SOC_SERIES_STM32F1) && defined(DMA2_Channel4_5_IRQn)) \ - || (defined(SOC_SERIES_STM32L0) && defined(DMA1_Channel4_5_6_7_IRQn)) \ - || (defined(SOC_SERIES_STM32G0) && defined(DMA1_Channel2_3_IRQn)) \ - || (defined(SOC_SERIES_STM32F0) && (defined(DMA1_Channel2_3_IRQn) || defined(DMA1_Channel4_5_IRQn) || defined(DMA1_Channel4_5_6_7_IRQn))) +#if (defined(SOC_SERIES_STM32F1) && defined(DMA2_Channel4_5_IRQn)) || (defined(SOC_SERIES_STM32L0) && defined(DMA1_Channel4_5_6_7_IRQn)) || (defined(SOC_SERIES_STM32G0) && defined(DMA1_Channel2_3_IRQn)) || (defined(SOC_SERIES_STM32F0) && (defined(DMA1_Channel2_3_IRQn) || defined(DMA1_Channel4_5_IRQn) || defined(DMA1_Channel4_5_6_7_IRQn))) #define STM32_DMA_HAS_SHARED_IRQ_REFCNT -#define STM32_DMA_IRQ_SLOT_COUNT ((rt_uint32_t)(sizeof(NVIC->ISER) / sizeof(NVIC->ISER[0]) * 32U)) +#define STM32_DMA_IRQ_SLOT_COUNT ((rt_uint32_t)(sizeof(NVIC->ISER) / sizeof(NVIC->ISER[0]) * 32U)) /** * @brief Reference count for each shared DMA IRQ line. @@ -122,24 +145,24 @@ static rt_bool_t stm32_dma_irq_needs_refcount(IRQn_Type dma_irq) #endif /* defined(SOC_SERIES_STM32G0) && defined(DMA1_Channel2_3_IRQn) */ #if defined(SOC_SERIES_STM32F0) -# if defined(DMA1_Channel2_3_IRQn) +#if defined(DMA1_Channel2_3_IRQn) if (dma_irq == DMA1_Channel2_3_IRQn) { return RT_TRUE; } -# endif /* defined(DMA1_Channel2_3_IRQn) */ -# if defined(DMA1_Channel4_5_IRQn) +#endif /* defined(DMA1_Channel2_3_IRQn) */ +#if defined(DMA1_Channel4_5_IRQn) if (dma_irq == DMA1_Channel4_5_IRQn) { return RT_TRUE; } -# endif /* defined(DMA1_Channel4_5_IRQn) */ -# if defined(DMA1_Channel4_5_6_7_IRQn) +#endif /* defined(DMA1_Channel4_5_IRQn) */ +#if defined(DMA1_Channel4_5_6_7_IRQn) if (dma_irq == DMA1_Channel4_5_6_7_IRQn) { return RT_TRUE; } -# endif /* defined(DMA1_Channel4_5_6_7_IRQn) */ +#endif /* defined(DMA1_Channel4_5_6_7_IRQn) */ #endif /* defined(SOC_SERIES_STM32F0) */ return RT_FALSE; @@ -206,42 +229,56 @@ static void stm32_dma_irq_put(IRQn_Type dma_irq) } /** - * @brief Copy one static DMA descriptor into one HAL DMA handle. + * @brief Apply common configuration fields from the base structure to a HAL DMA handle. * @param dma_handle DMA handle to update. - * @param dma_config Static DMA endpoint description. + * @param common Common configuration fields shared by DMA and BDMA. + */ +static void stm32_dma_apply_common_config(DMA_HandleTypeDef *dma_handle, + const struct stm32_dma_config_common *common) +{ + dma_handle->Instance = common->Instance; +#if defined(STM32_DMA_USES_REQUEST) || defined(STM32_BDMA_USES_REQUEST) + dma_handle->Init.Request = common->request; +#endif + dma_handle->Init.Direction = common->direction; + dma_handle->Init.PeriphInc = common->periph_inc; + dma_handle->Init.MemInc = common->mem_inc; + dma_handle->Init.PeriphDataAlignment = common->periph_data_alignment; + dma_handle->Init.MemDataAlignment = common->mem_data_alignment; + dma_handle->Init.Mode = common->mode; + dma_handle->Init.Priority = common->priority; +} + +/** + * @brief Apply common configuration fields and DMA-specific fields when applicable. + * + * BDMA endpoints only carry the common fields, so the DMA-specific fields are + * skipped based on the controller type stored in the common structure. */ static void stm32_dma_apply_config(DMA_HandleTypeDef *dma_handle, const struct stm32_dma_config *dma_config) { - dma_handle->Instance = dma_config->Instance; + stm32_dma_apply_common_config(dma_handle, &dma_config->common); + + if (dma_config->common.type == STM32_DMA_TYPE_BDMA) + { + return; + } + #if defined(STM32_DMA_USES_GPDMA) - dma_handle->Init.Request = dma_config->request; dma_handle->Init.BlkHWRequest = dma_config->blk_hw_request; - dma_handle->Init.Direction = dma_config->direction; dma_handle->Init.SrcInc = dma_config->src_inc; dma_handle->Init.DestInc = dma_config->dest_inc; dma_handle->Init.SrcDataWidth = dma_config->src_data_width; dma_handle->Init.DestDataWidth = dma_config->dest_data_width; - dma_handle->Init.Priority = dma_config->priority; dma_handle->Init.SrcBurstLength = dma_config->src_burst_length; dma_handle->Init.DestBurstLength = dma_config->dest_burst_length; dma_handle->Init.TransferAllocatedPort = dma_config->transfer_allocated_port; dma_handle->Init.TransferEventMode = dma_config->transfer_event_mode; - dma_handle->Init.Mode = dma_config->mode; #else #if defined(STM32_DMA_USES_CHANNEL) dma_handle->Init.Channel = dma_config->channel; #endif /* defined(STM32_DMA_USES_CHANNEL) */ -#if defined(STM32_DMA_USES_REQUEST) - dma_handle->Init.Request = dma_config->request; -#endif /* defined(STM32_DMA_USES_REQUEST) */ - dma_handle->Init.Direction = dma_config->direction; - dma_handle->Init.PeriphInc = dma_config->periph_inc; - dma_handle->Init.MemInc = dma_config->mem_inc; - dma_handle->Init.PeriphDataAlignment = dma_config->periph_data_alignment; - dma_handle->Init.MemDataAlignment = dma_config->mem_data_alignment; - dma_handle->Init.Mode = dma_config->mode; - dma_handle->Init.Priority = dma_config->priority; #if defined(STM32_DMA_SUPPORTS_FIFO) dma_handle->Init.FIFOMode = dma_config->fifo_mode; dma_handle->Init.FIFOThreshold = dma_config->fifo_threshold; @@ -263,21 +300,26 @@ rt_err_t stm32_dma_init(DMA_HandleTypeDef *dma_handle, { RT_ASSERT(dma_handle != RT_NULL); RT_ASSERT(dma_config != RT_NULL); - - stm32_dma_enable_clock(dma_config->dma_rcc); + stm32_dma_enable_clock(dma_config->common.dma_rcc, dma_config->common.type); stm32_dma_apply_config(dma_handle, dma_config); - LOG_D("dma init, dma=%p, irq=%d", dma_handle->Instance, dma_config->dma_irq); + LOG_D("%s init, dma=%p, irq=%d", + STM32_DMA_TYPE_NAME(dma_config), + dma_handle->Instance, dma_config->common.dma_irq); if (HAL_DMA_DeInit(dma_handle) != HAL_OK) { - LOG_E("dma deinit failed, dma=%p, irq=%d", dma_handle->Instance, dma_config->dma_irq); + LOG_E("%s deinit failed, dma=%p, irq=%d", + STM32_DMA_TYPE_NAME(dma_config), + dma_handle->Instance, dma_config->common.dma_irq); return -RT_ERROR; } if (HAL_DMA_Init(dma_handle) != HAL_OK) { - LOG_E("dma init failed, dma=%p, irq=%d", dma_handle->Instance, dma_config->dma_irq); + LOG_E("%s init failed, dma=%p, irq=%d", + STM32_DMA_TYPE_NAME(dma_config), + dma_handle->Instance, dma_config->common.dma_irq); return -RT_ERROR; } @@ -312,9 +354,11 @@ rt_err_t stm32_dma_setup(DMA_HandleTypeDef *dma_handle, dma_handle->Parent = parent_handle; } - stm32_dma_irq_get(dma_config->dma_irq, dma_config->preempt_priority, dma_config->sub_priority); + stm32_dma_irq_get(dma_config->common.dma_irq, dma_config->common.preempt_priority, dma_config->common.sub_priority); - LOG_D("dma setup, dma=%p, irq=%d", dma_handle->Instance, dma_config->dma_irq); + LOG_D("%s setup, dma=%p, irq=%d", + STM32_DMA_TYPE_NAME(dma_config), + dma_handle->Instance, dma_config->common.dma_irq); return RT_EOK; } @@ -334,24 +378,31 @@ rt_err_t stm32_dma_deinit(DMA_HandleTypeDef *dma_handle, RT_ASSERT(dma_handle != RT_NULL); RT_ASSERT(dma_config != RT_NULL); - stm32_dma_irq_put(dma_config->dma_irq); + stm32_dma_irq_put(dma_config->common.dma_irq); - LOG_D("dma deinit, dma=%p, irq=%d", dma_handle->Instance, dma_config->dma_irq); + LOG_D("%s deinit, dma=%p, irq=%d", + STM32_DMA_TYPE_NAME(dma_config), + dma_handle->Instance, dma_config->common.dma_irq); if (abort_first) { if (HAL_DMA_Abort(dma_handle) != HAL_OK) { - LOG_W("dma abort failed, continue deinit, dma=%p, irq=%d", dma_handle->Instance, dma_config->dma_irq); + LOG_W("%s abort failed, continue deinit, dma=%p, irq=%d", + STM32_DMA_TYPE_NAME(dma_config), + dma_handle->Instance, dma_config->common.dma_irq); } } if (HAL_DMA_DeInit(dma_handle) != HAL_OK) { - LOG_E("dma deinit failed, dma=%p, irq=%d", dma_handle->Instance, dma_config->dma_irq); + LOG_E("%s deinit failed, dma=%p, irq=%d", + STM32_DMA_TYPE_NAME(dma_config), + dma_handle->Instance, dma_config->common.dma_irq); return -RT_ERROR; } return RT_EOK; } + #endif /* HAL_DMA_MODULE_ENABLED */ diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.h index 83e1535e685b..7195e8959782 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.h @@ -34,14 +34,10 @@ extern "C" { /** * @brief DMA capability classification for STM32 series supported by this BSP. */ -#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32L5) \ - || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0) \ - || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32F3) \ - || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS) || defined(SOC_SERIES_STM32L1) -#define DMA_INSTANCE_TYPE DMA_Channel_TypeDef -#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) \ - || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) -#define DMA_INSTANCE_TYPE DMA_Stream_TypeDef +#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS) || defined(SOC_SERIES_STM32L1) +#define DMA_INSTANCE_TYPE DMA_Channel_TypeDef +#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) +#define DMA_INSTANCE_TYPE DMA_Stream_TypeDef #endif /* defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32F3) @@ -55,21 +51,17 @@ extern "C" { #define STM32_DMA_USES_GPDMA #endif /* defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS) */ -#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0) \ - || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) \ - || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS) +#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS) #define STM32_DMA_USES_REQUEST #endif /* defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS) */ -#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) \ - || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) +#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) #define STM32_DMA_SUPPORTS_FIFO #endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) */ -#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) \ - || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32L1) +#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32L1) #define STM32_DMA_USES_RCC_AHBENR #endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32L1) */ @@ -77,10 +69,7 @@ extern "C" { #define STM32_DMA_USES_RCC_MP_AHB2ENSETR #endif /* defined(SOC_SERIES_STM32MP1) */ -#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) \ - || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G4) \ - || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32L5) \ - || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS) +#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS) #define STM32_DMA_USES_RCC_AHB1ENR #endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G4) @@ -88,28 +77,28 @@ extern "C" { || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS) */ #ifndef STM32_DMA_DEFAULT_PRIORITY -#define STM32_DMA_DEFAULT_PRIORITY DMA_PRIORITY_LOW +#define STM32_DMA_DEFAULT_PRIORITY DMA_PRIORITY_LOW #endif /* STM32_DMA_DEFAULT_PRIORITY */ #ifndef STM32_DMA_DEFAULT_PREEMPT_PRIORITY -#define STM32_DMA_DEFAULT_PREEMPT_PRIORITY 0 +#define STM32_DMA_DEFAULT_PREEMPT_PRIORITY 0 #endif /* STM32_DMA_DEFAULT_PREEMPT_PRIORITY */ #ifndef STM32_DMA_DEFAULT_SUB_PRIORITY -#define STM32_DMA_DEFAULT_SUB_PRIORITY 0 +#define STM32_DMA_DEFAULT_SUB_PRIORITY 0 #endif /* STM32_DMA_DEFAULT_SUB_PRIORITY */ #if defined(STM32_DMA_USES_GPDMA) #ifndef STM32_GPDMA_DEFAULT_BLOCK_HW_REQUEST -#define STM32_GPDMA_DEFAULT_BLOCK_HW_REQUEST DMA_BREQ_SINGLE_BURST +#define STM32_GPDMA_DEFAULT_BLOCK_HW_REQUEST DMA_BREQ_SINGLE_BURST #endif /* STM32_GPDMA_DEFAULT_BLOCK_HW_REQUEST */ #ifndef STM32_GPDMA_DEFAULT_SRC_BURST_LENGTH -#define STM32_GPDMA_DEFAULT_SRC_BURST_LENGTH 1U +#define STM32_GPDMA_DEFAULT_SRC_BURST_LENGTH 1U #endif /* STM32_GPDMA_DEFAULT_SRC_BURST_LENGTH */ #ifndef STM32_GPDMA_DEFAULT_DEST_BURST_LENGTH -#define STM32_GPDMA_DEFAULT_DEST_BURST_LENGTH 1U +#define STM32_GPDMA_DEFAULT_DEST_BURST_LENGTH 1U #endif /* STM32_GPDMA_DEFAULT_DEST_BURST_LENGTH */ #ifndef STM32_GPDMA_DEFAULT_TRANSFER_ALLOCATED_PORT @@ -117,10 +106,49 @@ extern "C" { #endif /* STM32_GPDMA_DEFAULT_TRANSFER_ALLOCATED_PORT */ #ifndef STM32_GPDMA_DEFAULT_TRANSFER_EVENT_MODE -#define STM32_GPDMA_DEFAULT_TRANSFER_EVENT_MODE DMA_TCEM_BLOCK_TRANSFER +#define STM32_GPDMA_DEFAULT_TRANSFER_EVENT_MODE DMA_TCEM_BLOCK_TRANSFER #endif /* STM32_GPDMA_DEFAULT_TRANSFER_EVENT_MODE */ #endif /* defined(STM32_DMA_USES_GPDMA) */ + +/** + * @brief DMA type classification for STM32 series supported by this BSP. + */ +typedef enum +{ + STM32_DMA_TYPE_DMA = 0, + STM32_DMA_TYPE_BDMA, +} stm32_dma_type; + + +/** + * @brief Common DMA configuration fields shared by DMA and BDMA. + * + * This base structure contains all common configuration fields. Both DMA and + * BDMA descriptors embed it as their first member of struct stm32_dma_config, + * enabling zero-cost pointer conversion for shared logic. + */ +struct stm32_dma_config_common +{ + void *Instance; /**< DMA/BDMA controller instance pointer (typed by child). */ + enum stm32_dma_type type; /**< Type of the DMA controller. */ + rt_uint32_t dma_rcc; /**< RCC enable bit for the DMA/BDMA controller. */ + IRQn_Type dma_irq; /**< DMA/BDMA global IRQ number. */ + rt_uint32_t priority; /**< DMA/BDMA transfer priority. */ + rt_uint8_t preempt_priority; /**< NVIC preempt priority for the DMA/BDMA IRQ. */ + rt_uint8_t sub_priority; /**< NVIC sub priority for the DMA/BDMA IRQ. */ + +#if defined(STM32_DMA_USES_REQUEST) || defined(STM32_BDMA_USES_REQUEST) + rt_uint32_t request; /**< DMA/BDMA request selector. */ +#endif + rt_uint32_t direction; /**< DMA/BDMA transfer direction. */ + rt_uint32_t periph_inc; /**< Peripheral address increment mode. */ + rt_uint32_t mem_inc; /**< Memory address increment mode. */ + rt_uint32_t periph_data_alignment; /**< Peripheral data alignment. */ + rt_uint32_t mem_data_alignment; /**< Memory data alignment. */ + rt_uint32_t mode; /**< DMA/BDMA transfer mode. */ +}; + /** * @brief Static DMA endpoint description used by board-level config headers. * @@ -129,17 +157,10 @@ extern "C" { */ struct stm32_dma_config { - DMA_INSTANCE_TYPE *Instance; /**< DMA controller instance pointer. */ - rt_uint32_t dma_rcc; /**< RCC enable bit for the DMA controller. */ - IRQn_Type dma_irq; /**< DMA global IRQ number. */ - rt_uint32_t priority; /**< DMA transfer priority. */ - rt_uint8_t preempt_priority; /**< NVIC preempt priority for the DMA IRQ. */ - rt_uint8_t sub_priority; /**< NVIC sub priority for the DMA IRQ. */ + struct stm32_dma_config_common common; /**< Common DMA/BDMA configuration fields. */ #if defined(STM32_DMA_USES_GPDMA) - rt_uint32_t request; /**< DMA request selector for the GPDMA channel. */ rt_uint32_t blk_hw_request; /**< GPDMA block hardware request mode. */ - rt_uint32_t direction; /**< DMA transfer direction. */ rt_uint32_t src_inc; /**< GPDMA source increment mode. */ rt_uint32_t dest_inc; /**< GPDMA destination increment mode. */ rt_uint32_t src_data_width; /**< GPDMA source data width. */ @@ -148,23 +169,11 @@ struct stm32_dma_config rt_uint32_t dest_burst_length; /**< GPDMA destination burst length. */ rt_uint32_t transfer_allocated_port;/**< GPDMA allocated port selection. */ rt_uint32_t transfer_event_mode; /**< GPDMA transfer event mode. */ - rt_uint32_t mode; /**< DMA transfer mode. */ #else #ifdef STM32_DMA_USES_CHANNEL rt_uint32_t channel; /**< DMA channel selector for stream-based DMA. */ #endif /* STM32_DMA_USES_CHANNEL */ -#ifdef STM32_DMA_USES_REQUEST - rt_uint32_t request; /**< DMA request selector for DMAMUX/request-based DMA. */ -#endif /* STM32_DMA_USES_REQUEST */ - - rt_uint32_t direction; /**< DMA transfer direction. */ - rt_uint32_t periph_inc; /**< Peripheral address increment mode. */ - rt_uint32_t mem_inc; /**< Memory address increment mode. */ - rt_uint32_t periph_data_alignment; /**< Peripheral data alignment. */ - rt_uint32_t mem_data_alignment; /**< Memory data alignment. */ - rt_uint32_t mode; /**< DMA transfer mode. */ - #if defined(STM32_DMA_SUPPORTS_FIFO) rt_uint32_t fifo_mode; /**< FIFO enable state. */ rt_uint32_t fifo_threshold; /**< FIFO threshold selection. */ @@ -178,29 +187,29 @@ struct stm32_dma_config * @brief Optional selector fields kept in the descriptor for board-level readability. */ #if defined(STM32_DMA_USES_CHANNEL) -#define STM32_DMA_CHANNEL_FIELD(_channel) .channel = (_channel), +#define STM32_DMA_CHANNEL_FIELD(_channel) .channel = (_channel), #else #define STM32_DMA_CHANNEL_FIELD(_channel) #endif /* defined(STM32_DMA_USES_CHANNEL) */ #if defined(STM32_DMA_USES_REQUEST) -#define STM32_DMA_REQUEST_FIELD(_request) .request = (_request), +#define STM32_DMA_REQUEST_FIELD(_request) .request = (_request), #else #define STM32_DMA_REQUEST_FIELD(_request) #endif /* defined(STM32_DMA_USES_REQUEST) */ #if defined(STM32_DMA_SUPPORTS_FIFO) -#define STM32_DMA_FIFO_FIELD_DEFAULTS \ - .fifo_mode = DMA_FIFOMODE_DISABLE, \ - .fifo_threshold = DMA_FIFO_THRESHOLD_FULL, \ - .mem_burst = DMA_MBURST_SINGLE, \ - .periph_burst = DMA_PBURST_SINGLE, +#define STM32_DMA_FIFO_FIELD_DEFAULTS \ + .fifo_mode = DMA_FIFOMODE_DISABLE, \ + .fifo_threshold = DMA_FIFO_THRESHOLD_FULL, \ + .mem_burst = DMA_MBURST_SINGLE, \ + .periph_burst = DMA_PBURST_SINGLE, #define STM32_DMA_FIFO_FIELD_VALUES(_fifo_mode, _fifo_threshold, _mem_burst, _periph_burst) \ - .fifo_mode = (_fifo_mode), \ - .fifo_threshold = (_fifo_threshold), \ - .mem_burst = (_mem_burst), \ - .periph_burst = (_periph_burst), + .fifo_mode = (_fifo_mode), \ + .fifo_threshold = (_fifo_threshold), \ + .mem_burst = (_mem_burst), \ + .periph_burst = (_periph_burst), #else #define STM32_DMA_FIFO_FIELD_DEFAULTS #define STM32_DMA_FIFO_FIELD_VALUES(_fifo_mode, _fifo_threshold, _mem_burst, _periph_burst) @@ -211,21 +220,23 @@ struct stm32_dma_config */ #define STM32_DMA_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _channel, _request, _priority, _preempt_priority, _sub_priority, _direction, _periph_inc, _mem_inc, _periph_data_alignment, _mem_data_alignment, _mode) \ { \ - .Instance = (_instance), \ - .dma_rcc = (_dma_rcc), \ - .dma_irq = (_dma_irq), \ - .priority = (_priority), \ - .preempt_priority = (_preempt_priority), \ - .sub_priority = (_sub_priority), \ - STM32_DMA_CHANNEL_FIELD(_channel) \ - STM32_DMA_REQUEST_FIELD(_request) \ - .direction = (_direction), \ - .periph_inc = (_periph_inc), \ - .mem_inc = (_mem_inc), \ - .periph_data_alignment = (_periph_data_alignment), \ - .mem_data_alignment = (_mem_data_alignment), \ - .mode = (_mode), \ - STM32_DMA_FIFO_FIELD_DEFAULTS \ + .common = { \ + .Instance = (_instance), \ + .type = STM32_DMA_TYPE_DMA, \ + .dma_rcc = (_dma_rcc), \ + .dma_irq = (_dma_irq), \ + .priority = (_priority), \ + .preempt_priority = (_preempt_priority), \ + .sub_priority = (_sub_priority), \ + STM32_DMA_REQUEST_FIELD(_request) \ + .direction = (_direction), \ + .periph_inc = (_periph_inc), \ + .mem_inc = (_mem_inc), \ + .periph_data_alignment = (_periph_data_alignment), \ + .mem_data_alignment = (_mem_data_alignment), \ + .mode = (_mode), \ + }, \ + STM32_DMA_CHANNEL_FIELD(_channel) STM32_DMA_FIFO_FIELD_DEFAULTS \ } /** @@ -233,21 +244,23 @@ struct stm32_dma_config */ #define STM32_DMA_CONFIG_INIT_FIFO_EX(_instance, _dma_rcc, _dma_irq, _channel, _request, _priority, _preempt_priority, _sub_priority, _direction, _periph_inc, _mem_inc, _periph_data_alignment, _mem_data_alignment, _mode, _fifo_mode, _fifo_threshold, _mem_burst, _periph_burst) \ { \ - .Instance = (_instance), \ - .dma_rcc = (_dma_rcc), \ - .dma_irq = (_dma_irq), \ - .priority = (_priority), \ - .preempt_priority = (_preempt_priority), \ - .sub_priority = (_sub_priority), \ - STM32_DMA_CHANNEL_FIELD(_channel) \ - STM32_DMA_REQUEST_FIELD(_request) \ - .direction = (_direction), \ - .periph_inc = (_periph_inc), \ - .mem_inc = (_mem_inc), \ - .periph_data_alignment = (_periph_data_alignment), \ - .mem_data_alignment = (_mem_data_alignment), \ - .mode = (_mode), \ - STM32_DMA_FIFO_FIELD_VALUES(_fifo_mode, _fifo_threshold, _mem_burst, _periph_burst) \ + .common = { \ + .Instance = (_instance), \ + .type = STM32_DMA_TYPE_DMA, \ + .dma_rcc = (_dma_rcc), \ + .dma_irq = (_dma_irq), \ + .priority = (_priority), \ + .preempt_priority = (_preempt_priority), \ + .sub_priority = (_sub_priority), \ + STM32_DMA_REQUEST_FIELD(_request) \ + .direction = (_direction), \ + .periph_inc = (_periph_inc), \ + .mem_inc = (_mem_inc), \ + .periph_data_alignment = (_periph_data_alignment), \ + .mem_data_alignment = (_mem_data_alignment), \ + .mode = (_mode), \ + }, \ + STM32_DMA_CHANNEL_FIELD(_channel) STM32_DMA_FIFO_FIELD_VALUES(_fifo_mode, _fifo_threshold, _mem_burst, _periph_burst) \ } /** @@ -274,26 +287,21 @@ struct stm32_dma_config /** * @brief GPDMA descriptor initializer with explicit source and destination attributes. */ -#define STM32_GPDMA_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority, _direction, _src_inc, _dest_inc, _src_data_width, _dest_data_width, _mode) \ - { \ - .Instance = (_instance), \ - .dma_rcc = (_dma_rcc), \ - .dma_irq = (_dma_irq), \ - .priority = (_priority), \ - .preempt_priority = (_preempt_priority), \ - .sub_priority = (_sub_priority), \ - .request = (_request), \ - .blk_hw_request = STM32_GPDMA_DEFAULT_BLOCK_HW_REQUEST, \ - .direction = (_direction), \ - .src_inc = (_src_inc), \ - .dest_inc = (_dest_inc), \ - .src_data_width = (_src_data_width), \ - .dest_data_width = (_dest_data_width), \ - .src_burst_length = STM32_GPDMA_DEFAULT_SRC_BURST_LENGTH, \ - .dest_burst_length = STM32_GPDMA_DEFAULT_DEST_BURST_LENGTH, \ - .transfer_allocated_port = STM32_GPDMA_DEFAULT_TRANSFER_ALLOCATED_PORT, \ - .transfer_event_mode = STM32_GPDMA_DEFAULT_TRANSFER_EVENT_MODE, \ - .mode = (_mode), \ +#define STM32_GPDMA_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority, _direction, _src_inc, _dest_inc, _src_data_width, _dest_data_width, _mode) \ + { \ + .common = { \ + .Instance = (_instance), \ + .type = STM32_DMA_TYPE_DMA, \ + .dma_rcc = (_dma_rcc), \ + .dma_irq = (_dma_irq), \ + .priority = (_priority), \ + .preempt_priority = (_preempt_priority), \ + .sub_priority = (_sub_priority), \ + .request = (_request), \ + .direction = (_direction), \ + .mode = (_mode), \ + }, \ + .blk_hw_request = STM32_GPDMA_DEFAULT_BLOCK_HW_REQUEST, .src_inc = (_src_inc), .dest_inc = (_dest_inc), .src_data_width = (_src_data_width), .dest_data_width = (_dest_data_width), .src_burst_length = STM32_GPDMA_DEFAULT_SRC_BURST_LENGTH, .dest_burst_length = STM32_GPDMA_DEFAULT_DEST_BURST_LENGTH, .transfer_allocated_port = STM32_GPDMA_DEFAULT_TRANSFER_ALLOCATED_PORT, .transfer_event_mode = STM32_GPDMA_DEFAULT_TRANSFER_EVENT_MODE, \ } #define STM32_GPDMA_RX_BYTE_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority) \ @@ -357,6 +365,77 @@ rt_err_t stm32_dma_deinit(DMA_HandleTypeDef *dma_handle, #endif /* HAL_DMA_MODULE_ENABLED */ +#if defined(BSP_USING_BDMA) && (defined(SOC_SERIES_STM32H7)) + +/** + * @brief BDMA configuration structure that inherits from the common base. + * + * BDMA on STM32H7 uses DMA_Channel_TypeDef instances and has no FIFO support. + * All configuration fields are in the common base structure. The layout is a + * prefix-compatible subset of struct stm32_dma_config, so a pointer to this + * structure can be passed to the shared stm32_dma_init/setup/deinit API. + */ +struct stm32_bdma_config +{ + struct stm32_dma_config_common common; /**< Common DMA/BDMA configuration fields. */ +}; + +/** + * @brief BDMA-specific macro guards for consistency with DMA. + */ +#ifndef STM32_BDMA_USES_REQUEST +#define STM32_BDMA_USES_REQUEST +#endif + +#ifndef STM32_BDMA_DEFAULT_PRIORITY +#define STM32_BDMA_DEFAULT_PRIORITY DMA_PRIORITY_LOW +#endif + +#ifndef STM32_BDMA_DEFAULT_PREEMPT_PRIORITY +#define STM32_BDMA_DEFAULT_PREEMPT_PRIORITY 0 +#endif + +#ifndef STM32_BDMA_DEFAULT_SUB_PRIORITY +#define STM32_BDMA_DEFAULT_SUB_PRIORITY 0 +#endif + +/** + * @brief BDMA descriptor initializer with explicit direction and data layout. + * + * BDMA endpoints only use the common fields of struct stm32_dma_config; the + * DMA-specific fields are left zero and skipped at runtime by the type check. + */ +#define STM32_BDMA_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority, _direction, _periph_inc, _mem_inc, _periph_data_alignment, _mem_data_alignment, _mode) \ + { \ + .common = { \ + .Instance = (_instance), \ + .type = STM32_DMA_TYPE_BDMA, \ + .dma_rcc = (_dma_rcc), \ + .dma_irq = (_dma_irq), \ + .priority = (_priority), \ + .preempt_priority = (_preempt_priority), \ + .sub_priority = (_sub_priority), \ + .request = (_request), \ + .direction = (_direction), \ + .periph_inc = (_periph_inc), \ + .mem_inc = (_mem_inc), \ + .periph_data_alignment = (_periph_data_alignment), \ + .mem_data_alignment = (_mem_data_alignment), \ + .mode = (_mode), \ + } \ + } + +/** + * @brief BDMA byte/word transfer descriptor helpers for board-level config. + */ +#define STM32_BDMA_RX_BYTE_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority) \ + STM32_BDMA_CONFIG_INIT_EX((_instance), (_dma_rcc), (_dma_irq), (_request), (_priority), (_preempt_priority), (_sub_priority), DMA_PERIPH_TO_MEMORY, DMA_PINC_DISABLE, DMA_MINC_ENABLE, DMA_PDATAALIGN_BYTE, DMA_MDATAALIGN_BYTE, DMA_NORMAL) + +#define STM32_BDMA_TX_BYTE_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority) \ + STM32_BDMA_CONFIG_INIT_EX((_instance), (_dma_rcc), (_dma_irq), (_request), (_priority), (_preempt_priority), (_sub_priority), DMA_MEMORY_TO_PERIPH, DMA_PINC_DISABLE, DMA_MINC_ENABLE, DMA_PDATAALIGN_BYTE, DMA_MDATAALIGN_BYTE, DMA_NORMAL) + +#endif /* BSP_USING_BDMA && (SOC_SERIES_STM32H7) */ + #ifdef __cplusplus } #endif diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c index 2d68d48403a9..e6d128c6731e 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c @@ -61,7 +61,7 @@ #endif /* BSP_SPI_INT_TRANS_MIN_LEN */ /*#define DRV_DEBUG*/ -#define LOG_TAG "drv.spi" +#define LOG_TAG "drv.spi" #include /** @@ -99,8 +99,7 @@ enum * each enabled BSP_USING_SPIx instance. The table order must match the * SPIx_INDEX values and @ref spi_bus_obj. */ -static struct stm32_spi_config spi_config[] = -{ +static struct stm32_spi_config spi_config[] = { #ifdef BSP_USING_SPI1 SPI1_BUS_CONFIG, /**< Static bus configuration entry for SPI1. */ #endif /* BSP_USING_SPI1 */ @@ -129,37 +128,70 @@ static struct stm32_spi_config spi_config[] = /** * @brief Runtime STM32 SPI bus object table paired with @ref spi_config. */ -static struct stm32_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])] = {0}; +static struct stm32_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])] = { 0 }; -#ifdef BSP_SPI_USING_DMA +#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) /** - * @brief Roll back SPI DMA setup that was partially initialized. + * @brief Roll back SPI DMA/BDMA setup that was partially initialized. + * + * @note DMA and BDMA share the RT_DEVICE_FLAG_DMA_* bits. The engine used + * by an instance is selected by its dma_xx/bdma_xx config pointer, so + * both engines are handled here. * * @param spi_drv STM32 SPI driver context. - * @param dma_flags RT_DEVICE_FLAG_DMA_* bits indicating DMA channels to release. + * @param dma_flags RT_DEVICE_FLAG_DMA_* bits indicating channels to release. */ static void stm32_spi_dma_rollback(struct stm32_spi *spi_drv, rt_uint16_t dma_flags) { -#if defined(BSP_SPI_RX_USING_DMA) - if ((dma_flags & RT_DEVICE_FLAG_DMA_RX) && (spi_drv->config->dma_rx != RT_NULL)) +#if defined(BSP_SPI_RX_USING_DMA) || defined(BSP_SPI_RX_USING_BDMA) + if (dma_flags & RT_DEVICE_FLAG_DMA_RX) { - (void)stm32_dma_deinit(&spi_drv->dma.handle_rx, spi_drv->config->dma_rx, RT_FALSE); - spi_drv->dma.handle_rx.Parent = RT_NULL; - spi_drv->handle.hdmarx = RT_NULL; - } +#if defined(BSP_SPI_RX_USING_BDMA) + if (spi_drv->config->bdma_rx != RT_NULL) + { + (void)stm32_dma_deinit(&spi_drv->bdma.handle_rx, + (const struct stm32_dma_config *)spi_drv->config->bdma_rx, RT_FALSE); + spi_drv->bdma.handle_rx.Parent = RT_NULL; + spi_drv->handle.hdmarx = RT_NULL; + } +#endif /* BSP_SPI_RX_USING_BDMA */ + +#if defined(BSP_SPI_RX_USING_DMA) + if (spi_drv->config->dma_rx != RT_NULL) + { + (void)stm32_dma_deinit(&spi_drv->dma.handle_rx, spi_drv->config->dma_rx, RT_FALSE); + spi_drv->dma.handle_rx.Parent = RT_NULL; + spi_drv->handle.hdmarx = RT_NULL; + } #endif /* BSP_SPI_RX_USING_DMA */ + } +#endif /* BSP_SPI_RX_USING_DMA || BSP_SPI_RX_USING_BDMA */ -#if defined(BSP_SPI_TX_USING_DMA) - if ((dma_flags & RT_DEVICE_FLAG_DMA_TX) && (spi_drv->config->dma_tx != RT_NULL)) +#if defined(BSP_SPI_TX_USING_DMA) || defined(BSP_SPI_TX_USING_BDMA) + if (dma_flags & RT_DEVICE_FLAG_DMA_TX) { - (void)stm32_dma_deinit(&spi_drv->dma.handle_tx, spi_drv->config->dma_tx, RT_FALSE); - spi_drv->dma.handle_tx.Parent = RT_NULL; - spi_drv->handle.hdmatx = RT_NULL; - } +#if defined(BSP_SPI_TX_USING_BDMA) + if (spi_drv->config->bdma_tx != RT_NULL) + { + (void)stm32_dma_deinit(&spi_drv->bdma.handle_tx, + (const struct stm32_dma_config *)spi_drv->config->bdma_tx, RT_FALSE); + spi_drv->bdma.handle_tx.Parent = RT_NULL; + spi_drv->handle.hdmatx = RT_NULL; + } +#endif /* BSP_SPI_TX_USING_BDMA */ + +#if defined(BSP_SPI_TX_USING_DMA) + if (spi_drv->config->dma_tx != RT_NULL) + { + (void)stm32_dma_deinit(&spi_drv->dma.handle_tx, spi_drv->config->dma_tx, RT_FALSE); + spi_drv->dma.handle_tx.Parent = RT_NULL; + spi_drv->handle.hdmatx = RT_NULL; + } #endif /* BSP_SPI_TX_USING_DMA */ + } +#endif /* BSP_SPI_TX_USING_DMA || BSP_SPI_TX_USING_BDMA */ } -#endif /* BSP_SPI_USING_DMA */ - +#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ /** * @brief Initialize an STM32 SPI instance according to an RT-Thread SPI configuration. * @@ -311,20 +343,20 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur spi_handle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; spi_handle->State = HAL_SPI_STATE_RESET; #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32WB) - spi_handle->Init.NSSPMode = SPI_NSS_PULSE_DISABLE; + spi_handle->Init.NSSPMode = SPI_NSS_PULSE_DISABLE; #elif defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) - spi_handle->Init.NSS = SPI_NSS_SOFT; - spi_handle->Init.NSSPMode = SPI_NSS_PULSE_DISABLE; - spi_handle->Init.NSSPolarity = SPI_NSS_POLARITY_LOW; - spi_handle->Init.CRCPolynomial = 7; + spi_handle->Init.NSS = SPI_NSS_SOFT; + spi_handle->Init.NSSPMode = SPI_NSS_PULSE_DISABLE; + spi_handle->Init.NSSPolarity = SPI_NSS_POLARITY_LOW; + spi_handle->Init.CRCPolynomial = 7; spi_handle->Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN; spi_handle->Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN; - spi_handle->Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE; - spi_handle->Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE; - spi_handle->Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE; + spi_handle->Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE; + spi_handle->Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE; + spi_handle->Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE; spi_handle->Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; - spi_handle->Init.IOSwap = SPI_IO_SWAP_DISABLE; - spi_handle->Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA; + spi_handle->Init.IOSwap = SPI_IO_SWAP_DISABLE; + spi_handle->Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA; #endif if (HAL_SPI_Init(spi_handle) != HAL_OK) @@ -332,15 +364,14 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur return -RT_EIO; } -#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) \ - || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32WB) +#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32WB) SET_BIT(spi_handle->Instance->CR2, SPI_RXFIFO_THRESHOLD_HF); #endif #ifdef BSP_SPI_USING_DMA /* DMA configuration */ #if defined(BSP_SPI_RX_USING_DMA) - if (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_RX) + if ((spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_RX) && (spi_drv->config->dma_rx != RT_NULL)) { if (stm32_dma_setup(&spi_drv->dma.handle_rx, &spi_drv->handle, @@ -354,7 +385,7 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur #endif /* BSP_SPI_RX_USING_DMA */ #if defined(BSP_SPI_TX_USING_DMA) - if (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_TX) + if ((spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_TX) && (spi_drv->config->dma_tx != RT_NULL)) { if (stm32_dma_setup(&spi_drv->dma.handle_tx, &spi_drv->handle, @@ -368,9 +399,41 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur #endif /* BSP_SPI_TX_USING_DMA */ #endif /* BSP_SPI_USING_DMA */ +#ifdef BSP_SPI_USING_BDMA + /* BDMA configuration */ +#if defined(BSP_SPI_RX_USING_BDMA) + if ((spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_RX) && (spi_drv->config->bdma_rx != RT_NULL)) + { + if (stm32_dma_setup(&spi_drv->bdma.handle_rx, + &spi_drv->handle, + &spi_drv->handle.hdmarx, + (const struct stm32_dma_config *)spi_drv->config->bdma_rx) != RT_EOK) + { + stm32_spi_dma_rollback(spi_drv, RT_DEVICE_FLAG_DMA_RX); + return -RT_EIO; + } + } +#endif /* BSP_SPI_RX_USING_BDMA */ + +#if defined(BSP_SPI_TX_USING_BDMA) + if ((spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_TX) && (spi_drv->config->bdma_tx != RT_NULL)) + { + if (stm32_dma_setup(&spi_drv->bdma.handle_tx, + &spi_drv->handle, + &spi_drv->handle.hdmatx, + (const struct stm32_dma_config *)spi_drv->config->bdma_tx) != RT_EOK) + { + stm32_spi_dma_rollback(spi_drv, + RT_DEVICE_FLAG_DMA_TX | + (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_RX)); + return -RT_EIO; + } + } +#endif /* BSP_SPI_TX_USING_BDMA */ +#endif /* BSP_SPI_USING_BDMA */ + #ifdef BSP_SPI_USING_IRQ - if ((spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_TX) || (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_RX) - || (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_INT_TX) || (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_INT_RX)) + if ((spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_TX) || (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_RX) || (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_INT_TX) || (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_INT_RX)) { HAL_NVIC_SetPriority(spi_drv->config->irq_type, 2, 0); HAL_NVIC_EnableIRQ(spi_drv->config->irq_type); @@ -400,7 +463,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m RT_ASSERT(device->bus != RT_NULL); RT_ASSERT(message != RT_NULL); - struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus); + struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus); SPI_HandleTypeDef *spi_handle = &spi_drv->handle; rt_bool_t need_abort = RT_FALSE; @@ -416,7 +479,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m rt_tick_t timeout_tick = rt_tick_from_millisecond(timeout_ms); #endif /* BSP_SPI_USING_IRQ */ -#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT) +#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT) || defined(BSP_SPI_USING_BDMA) /* * Snapshot the call context once for the whole SPI message. * @@ -432,8 +495,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m const rt_bool_t scheduler_available = rt_scheduler_is_available(); const rt_bool_t irq_disabled = rt_hw_interrupt_is_disabled(); const rt_bool_t async_allowed = (scheduler_available && !irq_disabled); -#endif /* defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT) */ - +#endif /* defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT) || defined(BSP_SPI_USING_BDMA) */ if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) { if (device->config.mode & RT_SPI_CS_HIGH) @@ -481,7 +543,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m recv_buf = (rt_uint8_t *)message->recv_buf + already_send_length; } -#ifdef BSP_SPI_USING_DMA +#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) const rt_uint8_t *dma_send_buf = send_buf; rt_uint8_t *dma_recv_buf = recv_buf; @@ -489,16 +551,17 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m rt_uint8_t *aligned_recv_buf = RT_NULL; rt_bool_t dma_eligible = (send_length >= BSP_SPI_DMA_TRANS_MIN_LEN); -#if defined(BSP_SPI_TX_USING_DMA) +#if defined(BSP_SPI_TX_USING_DMA) || defined(BSP_SPI_TX_USING_BDMA) rt_bool_t use_tx_dma = dma_eligible && (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_TX); #else rt_bool_t use_tx_dma = RT_FALSE; -#endif /* BSP_SPI_TX_USING_DMA */ -#if defined(BSP_SPI_RX_USING_DMA) +#endif /* BSP_SPI_TX_USING_DMA || BSP_SPI_TX_USING_BDMA */ +#if defined(BSP_SPI_RX_USING_DMA) || defined(BSP_SPI_RX_USING_BDMA) rt_bool_t use_rx_dma = dma_eligible && (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_RX); #else rt_bool_t use_rx_dma = RT_FALSE; -#endif /* BSP_SPI_RX_USING_DMA */ +#endif /* BSP_SPI_RX_USING_DMA || BSP_SPI_RX_USING_BDMA */ + if (!async_allowed) { @@ -540,11 +603,17 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m #if defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) // D-Cache maintenance for buffers that will be used by DMA - if (dma_send_buf) rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)dma_send_buf, send_length); - if (dma_recv_buf) rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, dma_recv_buf, send_length); + if (dma_send_buf) + { + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)dma_send_buf, send_length); + } + if (dma_recv_buf) + { + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, dma_recv_buf, send_length); + } #endif } -#endif /* BSP_SPI_USING_DMA */ +#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ #ifdef BSP_SPI_USING_INT rt_bool_t int_eligible = (send_length >= BSP_SPI_INT_TRANS_MIN_LEN); @@ -572,15 +641,15 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m /* Start data exchange in full-duplex DMA mode. */ if (message->send_buf && message->recv_buf) { -#ifdef BSP_SPI_USING_DMA +#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) if (use_tx_dma && use_rx_dma) { state = HAL_SPI_TransmitReceive_DMA(spi_handle, (uint8_t *)dma_send_buf, dma_recv_buf, send_length); } else -#endif /* BSP_SPI_USING_DMA */ +#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ #ifdef BSP_SPI_USING_INT - if (use_tx_int && use_rx_int) + if (use_tx_int && use_rx_int) { state = HAL_SPI_TransmitReceive_IT(spi_handle, (uint8_t *)send_buf, recv_buf, send_length); } @@ -593,15 +662,15 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m } else if (message->send_buf) { -#ifdef BSP_SPI_USING_DMA +#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) if (use_tx_dma) { state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)dma_send_buf, send_length); } else -#endif /* BSP_SPI_USING_DMA */ +#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ #ifdef BSP_SPI_USING_INT - if (use_tx_int) + if (use_tx_int) { state = HAL_SPI_Transmit_IT(spi_handle, (uint8_t *)send_buf, send_length); } @@ -618,26 +687,26 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m /* clear the old error flag */ __HAL_SPI_CLEAR_OVRFLAG(spi_handle); -#ifdef BSP_SPI_USING_DMA +#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) if (use_rx_dma) { rx_dummy_buf = dma_recv_buf; } -#endif /* BSP_SPI_USING_DMA */ +#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ /* * STM32 HAL uses the receive buffer as dummy TX data in master * receive-only mode, so preload the actual HAL buffer with 0xFF. */ rt_memset(rx_dummy_buf, 0xFF, send_length); -#ifdef BSP_SPI_USING_DMA +#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) if (use_rx_dma) { state = HAL_SPI_Receive_DMA(spi_handle, dma_recv_buf, send_length); } else -#endif /* BSP_SPI_USING_DMA */ +#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ #ifdef BSP_SPI_USING_INT - if (use_rx_int) + if (use_rx_int) { state = HAL_SPI_Receive_IT(spi_handle, recv_buf, send_length); } @@ -705,8 +774,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m if (state == HAL_OK) { /* send-only */ - if (message->send_buf != RT_NULL && message->recv_buf == RT_NULL - && message->cs_release && (device->config.mode & RT_SPI_3WIRE)) + if (message->send_buf != RT_NULL && message->recv_buf == RT_NULL && message->cs_release && (device->config.mode & RT_SPI_3WIRE)) { /* release the CS by disable SPI when using 3 wires SPI */ __HAL_SPI_DISABLE(spi_handle); @@ -714,7 +782,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m LOG_D("%s transfer done", spi_drv->config->bus_name); } -transfer_cleanup: + transfer_cleanup: if (need_abort) { if (HAL_SPI_Abort(spi_handle) != HAL_OK) @@ -724,7 +792,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m spi_handle->ErrorCode); } } -#ifdef BSP_SPI_USING_DMA +#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) /* Post-transfer processing */ if (state == HAL_OK) { @@ -738,9 +806,15 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m } // Free any temporary buffers that were allocated - if (aligned_send_buf) rt_free_align(aligned_send_buf); - if (aligned_recv_buf) rt_free_align(aligned_recv_buf); -#endif /* BSP_SPI_USING_DMA */ + if (aligned_send_buf) + { + rt_free_align(aligned_send_buf); + } + if (aligned_recv_buf) + { + rt_free_align(aligned_recv_buf); + } +#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ if (state != HAL_OK) { break; @@ -750,12 +824,16 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) { if (device->config.mode & RT_SPI_CS_HIGH) + { rt_pin_write(device->cs_pin, PIN_LOW); + } else + { rt_pin_write(device->cs_pin, PIN_HIGH); + } } - if(state != HAL_OK) + if (state != HAL_OK) { return -RT_ERROR; } @@ -775,7 +853,7 @@ static rt_err_t spi_configure(struct rt_spi_device *device, RT_ASSERT(device != RT_NULL); RT_ASSERT(configuration != RT_NULL); - struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus); + struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus); spi_drv->cfg = configuration; return stm32_spi_init(spi_drv, configuration); @@ -784,8 +862,7 @@ static rt_err_t spi_configure(struct rt_spi_device *device, /** * @brief RT-Thread SPI operation callbacks implemented by the STM32 driver. */ -static const struct rt_spi_ops stm_spi_ops = -{ +static const struct rt_spi_ops stm_spi_ops = { .configure = spi_configure, .xfer = spixfer, }; @@ -894,6 +971,7 @@ rt_err_t rt_hw_spi_device_detach(const char *device_name) return RT_EOK; } + #if defined(BSP_USING_SPI1) && defined(BSP_SPI1_USING_IRQ) /** * @brief Handle the SPI1 peripheral interrupt. @@ -1182,6 +1260,38 @@ void SPI6_DMA_TX_IRQHandler(void) #endif /* BSP_SPI6_TX_USING_DMA */ #endif /* defined(BSP_USING_SPI6) && defined(BSP_SPI6_USING_IRQ) */ +#if defined(BSP_USING_SPI6) && defined(BSP_SPI6_TX_USING_BDMA) +/** + * @brief Handle the SPI6 TX BDMA interrupt. + */ +void SPI6_BDMA_TX_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + HAL_DMA_IRQHandler(&spi_bus_obj[SPI6_INDEX].bdma.handle_tx); + + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif /* defined(BSP_USING_SPI6) && defined(BSP_SPI6_TX_USING_BDMA) */ + +#if defined(BSP_USING_SPI6) && defined(BSP_SPI6_RX_USING_BDMA) +/** + * @brief Handle the SPI6 RX BDMA interrupt. + */ +void SPI6_BDMA_RX_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + HAL_DMA_IRQHandler(&spi_bus_obj[SPI6_INDEX].bdma.handle_rx); + + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif /* defined(BSP_USING_SPI6) && defined(BSP_SPI6_RX_USING_BDMA) */ + #ifdef BSP_SPI_USING_IRQ /** * @brief Populate per-instance SPI transfer flags and DMA configuration pointers. @@ -1318,6 +1428,18 @@ static void stm32_get_xfer_info(void) static const struct stm32_dma_config spi6_dma_tx = SPI6_TX_DMA_CONFIG; spi_config[SPI6_INDEX].dma_tx = &spi6_dma_tx; #endif +#ifdef BSP_SPI6_TX_USING_BDMA + spi_bus_obj[SPI6_INDEX].spi_xfer_flags |= RT_DEVICE_FLAG_DMA_TX; + /** SPI6 TX BDMA configuration descriptor. */ + static const struct stm32_bdma_config spi6_bdma_tx = SPI6_TX_BDMA_CONFIG; + spi_config[SPI6_INDEX].bdma_tx = &spi6_bdma_tx; +#endif /* BSP_SPI6_TX_USING_BDMA */ +#ifdef BSP_SPI6_RX_USING_BDMA + spi_bus_obj[SPI6_INDEX].spi_xfer_flags |= RT_DEVICE_FLAG_DMA_RX; + /** SPI6 RX BDMA configuration descriptor. */ + static const struct stm32_bdma_config spi6_bdma_rx = SPI6_RX_BDMA_CONFIG; + spi_config[SPI6_INDEX].bdma_rx = &spi6_bdma_rx; +#endif /* BSP_SPI6_RX_USING_BDMA */ #endif /* BSP_USING_SPI6 */ } @@ -1328,7 +1450,7 @@ static void stm32_get_xfer_info(void) */ void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) { - struct stm32_spi *spi_drv = rt_container_of(hspi, struct stm32_spi, handle); + struct stm32_spi *spi_drv = rt_container_of(hspi, struct stm32_spi, handle); rt_completion_done(&spi_drv->cpt); } @@ -1339,7 +1461,7 @@ void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) */ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) { - struct stm32_spi *spi_drv = rt_container_of(hspi, struct stm32_spi, handle); + struct stm32_spi *spi_drv = rt_container_of(hspi, struct stm32_spi, handle); rt_completion_done(&spi_drv->cpt); } @@ -1350,7 +1472,7 @@ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) */ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) { - struct stm32_spi *spi_drv = rt_container_of(hspi, struct stm32_spi, handle); + struct stm32_spi *spi_drv = rt_container_of(hspi, struct stm32_spi, handle); rt_completion_done(&spi_drv->cpt); } @@ -1361,7 +1483,7 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) */ void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) { - struct stm32_spi *spi_drv = rt_container_of(hspi, struct stm32_spi, handle); + struct stm32_spi *spi_drv = rt_container_of(hspi, struct stm32_spi, handle); LOG_W("%s error code 0x%08x", spi_drv->config->bus_name, hspi->ErrorCode); rt_completion_done(&spi_drv->cpt); } diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h index bcf14bfb6378..f13969de6adc 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2025 RT-Thread Development Team + * Copyright (c) 2006-2026, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -139,8 +139,25 @@ #if defined(BSP_SPI_TX_USING_INT) || defined(BSP_SPI_RX_USING_INT) #define BSP_SPI_USING_INT #endif +/* Aggregate BDMA transfer configuration from per-instance Kconfig macros. + * Only SPI6 lives in the D3 domain and can be served by BDMA on STM32H7. */ +#if defined(BSP_SPI6_TX_USING_BDMA) +#define BSP_SPI_TX_USING_BDMA +#endif + +#if defined(BSP_SPI6_RX_USING_BDMA) +#define BSP_SPI_RX_USING_BDMA +#endif + +#if defined(BSP_SPI6_TX_USING_BDMA) || defined(BSP_SPI6_RX_USING_BDMA) +#define BSP_SPI6_USING_BDMA +#endif -/* Aggregate IRQ requirements from DMA and interrupt transfer modes. */ +#if defined(BSP_SPI_TX_USING_BDMA) || defined(BSP_SPI_RX_USING_BDMA) +#define BSP_SPI_USING_BDMA +#endif + +/* Aggregate IRQ requirements from DMA, BDMA and interrupt transfer modes. */ #if defined(BSP_SPI1_USING_DMA) || defined(BSP_SPI1_USING_INT) #define BSP_SPI1_USING_IRQ #endif @@ -161,11 +178,11 @@ #define BSP_SPI5_USING_IRQ #endif -#if defined(BSP_SPI6_USING_DMA) || defined(BSP_SPI6_USING_INT) +#if defined(BSP_SPI6_USING_DMA) || defined(BSP_SPI6_USING_INT) || defined(BSP_SPI6_USING_BDMA) #define BSP_SPI6_USING_IRQ #endif -#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT) +#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT) || defined(BSP_SPI_USING_BDMA) #define BSP_SPI_USING_IRQ #endif @@ -209,6 +226,12 @@ struct stm32_spi_config #ifdef BSP_SPI_TX_USING_DMA const struct stm32_dma_config *dma_tx; /**< TX DMA configuration. */ #endif /* BSP_SPI_TX_USING_DMA */ +#ifdef BSP_SPI_RX_USING_BDMA + const struct stm32_bdma_config *bdma_rx; /**< RX BDMA configuration. */ +#endif /* BSP_SPI_RX_USING_BDMA */ +#ifdef BSP_SPI_TX_USING_BDMA + const struct stm32_bdma_config *bdma_tx; /**< TX BDMA configuration. */ +#endif /* BSP_SPI_TX_USING_BDMA */ }; /** @@ -245,6 +268,18 @@ struct stm32_spi #endif /* BSP_SPI_TX_USING_DMA */ } dma; /**< DMA handles associated with this SPI bus. */ #endif /* BSP_SPI_USING_DMA */ +#ifdef BSP_SPI_USING_BDMA + struct + { +#ifdef BSP_SPI_RX_USING_BDMA + DMA_HandleTypeDef handle_rx; /**< STM32 HAL RX BDMA handle. */ +#endif /* BSP_SPI_RX_USING_BDMA */ +#ifdef BSP_SPI_TX_USING_BDMA + DMA_HandleTypeDef handle_tx; /**< STM32 HAL TX BDMA handle. */ +#endif /* BSP_SPI_TX_USING_BDMA */ + } bdma; /**< BDMA handles associated with this SPI bus. */ +#endif /* BSP_SPI_USING_BDMA */ }; #endif /*__DRV_SPI_H__ */ + From b31712e2830581633f32fca93b3fa249fdfe18ea Mon Sep 17 00:00:00 2001 From: moment-NEW Date: Sun, 23 Aug 2026 03:04:30 +0000 Subject: [PATCH 2/3] style: format code with clang-format [skip ci] --- bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c index bf3f6b67f62f..bf062c5a3dcd 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c @@ -31,9 +31,9 @@ * series distinguish BDMA and DMA by the descriptor type at runtime. */ #if defined(STM32_DMA_USES_GPDMA) -#define STM32_DMA_TYPE_NAME(dma_config) "gpdma" +#define STM32_DMA_TYPE_NAME(dma_config) "gpdma" #else -#define STM32_DMA_TYPE_NAME(dma_config) \ +#define STM32_DMA_TYPE_NAME(dma_config) \ (((dma_config)->common.type == STM32_DMA_TYPE_BDMA) ? "bdma" : "dma") #endif /* defined(STM32_DMA_USES_GPDMA) */ From 1e24b57c8b1119b8c5811f74eedeb0d755dcf02c Mon Sep 17 00:00:00 2001 From: moment-NEW Date: Sat, 29 Aug 2026 08:53:45 +0800 Subject: [PATCH 3/3] [bsp][stm32] Unify DMA, BDMA, and GPDMA handling for SPI6 This update integrates SPI6 BDMA support into the unified DMA interface, allowing for a consistent handling of DMA and BDMA configurations. The changes include modifications to the DMA configuration structures and the SPI driver to accommodate both DMA types seamlessly. Additionally, Kconfig adjustments ensure proper selection between DMA and BDMA for SPI6. - Updated DMA type definitions and configurations. - Refactored SPI driver to route SPI6 BDMA through the unified DMA interface. - Adjusted Kconfig to prevent mutual exclusivity issues between DMA and BDMA for SPI6. Signed-off-by: moment-NEW --- .../libraries/HAL_Drivers/drivers/Kconfig | 19 ++ .../drivers/config/h7/spi_config.h | 4 +- .../libraries/HAL_Drivers/drivers/drv_dma.c | 98 +++--- .../libraries/HAL_Drivers/drivers/drv_dma.h | 297 +++++++++--------- .../libraries/HAL_Drivers/drivers/drv_spi.c | 137 +++----- .../libraries/HAL_Drivers/drivers/drv_spi.h | 65 ++-- 6 files changed, 289 insertions(+), 331 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/Kconfig b/bsp/stm32/libraries/HAL_Drivers/drivers/Kconfig index 633ffd2dd267..e68f439baa62 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/Kconfig +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/Kconfig @@ -169,3 +169,22 @@ config BSP_USING_UDID bool "Enable UDID (Unique Device Identifier)" select RT_USING_HWCRYPTO default n + +if SOC_SERIES_STM32H7 + config BSP_USING_BDMA + bool + + config BSP_SPI6_TX_USING_BDMA + bool "Enable SPI6 TX BDMA" + depends on BSP_USING_SPI6 + depends on !BSP_SPI6_TX_USING_DMA + select BSP_USING_BDMA + default n + + config BSP_SPI6_RX_USING_BDMA + bool "Enable SPI6 RX BDMA" + depends on BSP_USING_SPI6 + depends on !BSP_SPI6_RX_USING_DMA + select BSP_USING_BDMA + default n +endif diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/spi_config.h index 847470428579..b86b870345fc 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/spi_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/spi_config.h @@ -363,7 +363,7 @@ extern "C" { SPI6_TX_BDMA_INSTANCE, \ SPI6_TX_BDMA_RCC, \ SPI6_TX_BDMA_IRQ, \ - BDMA_REQUEST_SPI6_TX, \ + SPI6_TX_BDMA_REQUEST, \ SPI6_TX_BDMA_PRIORITY, \ SPI6_TX_BDMA_PREEMPT_PRIORITY, \ SPI6_TX_BDMA_SUB_PRIORITY) @@ -389,7 +389,7 @@ extern "C" { SPI6_RX_BDMA_INSTANCE, \ SPI6_RX_BDMA_RCC, \ SPI6_RX_BDMA_IRQ, \ - BDMA_REQUEST_SPI6_RX, \ + SPI6_RX_BDMA_REQUEST, \ SPI6_RX_BDMA_PRIORITY, \ SPI6_RX_BDMA_PREEMPT_PRIORITY, \ SPI6_RX_BDMA_SUB_PRIORITY) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c index bf3f6b67f62f..76d72dfcae91 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2026-04-13 wdfk-prog Add STM32 DMA common helpers + * 2026-08-28 moment-NEW Dispatch DMA/BDMA/GPDMA by descriptor type */ /** @@ -27,15 +28,12 @@ /** * @brief Get the controller type name for logging. * - * GPDMA-only series resolve to a constant string at compile time; other - * series distinguish BDMA and DMA by the descriptor type at runtime. + * The name follows the descriptor type so DMA, BDMA and GPDMA share one + * helper path while still producing a distinct log tag. */ -#if defined(STM32_DMA_USES_GPDMA) -#define STM32_DMA_TYPE_NAME(dma_config) "gpdma" -#else -#define STM32_DMA_TYPE_NAME(dma_config) \ - (((dma_config)->common.type == STM32_DMA_TYPE_BDMA) ? "bdma" : "dma") -#endif /* defined(STM32_DMA_USES_GPDMA) */ +#define STM32_DMA_TYPE_NAME(dma_config) \ + (((dma_config)->common.type == STM32_DMA_TYPE_GPDMA) ? "gpdma" : \ + ((dma_config)->common.type == STM32_DMA_TYPE_BDMA) ? "bdma" : "dma") #if defined(STM32_DMA_USES_REQUEST) /** @@ -60,10 +58,12 @@ static void stm32_dma_enable_clock(rt_uint32_t dma_rcc, stm32_dma_type type) { rt_uint32_t tmpreg = 0x00U; -/*while using BDMA,careful for the return,because you cant visit the FIFO member*/ -/*if you did so there would be some illegal access.*/ -/*And,please note the domian you can visit*/ -#if defined(BSP_USING_BDMA) && (defined(SOC_SERIES_STM32H7)) + + /* + * STM32H7 BDMA lives on AHB4. Enable that clock and return so the + * DMA1/DMA2 AHB1 path below is not used for a BDMA endpoint. + */ +#if defined(BSP_USING_BDMA) && defined(SOC_SERIES_STM32H7) if (type == STM32_DMA_TYPE_BDMA) { SET_BIT(RCC->AHB4ENR, dma_rcc); @@ -71,7 +71,7 @@ static void stm32_dma_enable_clock(rt_uint32_t dma_rcc, UNUSED(tmpreg); return; } -#endif /* defined(BSP_USING_BDMA) && (defined(SOC_SERIES_STM32H7)) */ +#endif /* defined(BSP_USING_BDMA) && defined(SOC_SERIES_STM32H7) */ #if defined(STM32_DMA_USES_RCC_AHBENR) SET_BIT(RCC->AHBENR, dma_rcc); tmpreg = READ_BIT(RCC->AHBENR, dma_rcc); @@ -229,63 +229,73 @@ static void stm32_dma_irq_put(IRQn_Type dma_irq) } /** - * @brief Apply common configuration fields from the base structure to a HAL DMA handle. + * @brief Apply fields shared by classic DMA, BDMA and GPDMA to a HAL handle. * @param dma_handle DMA handle to update. - * @param common Common configuration fields shared by DMA and BDMA. + * @param common Common configuration fields shared by all controller types. */ static void stm32_dma_apply_common_config(DMA_HandleTypeDef *dma_handle, const struct stm32_dma_config_common *common) { dma_handle->Instance = common->Instance; -#if defined(STM32_DMA_USES_REQUEST) || defined(STM32_BDMA_USES_REQUEST) +#if defined(STM32_DMA_USES_REQUEST) dma_handle->Init.Request = common->request; -#endif +#endif /* defined(STM32_DMA_USES_REQUEST) */ dma_handle->Init.Direction = common->direction; - dma_handle->Init.PeriphInc = common->periph_inc; - dma_handle->Init.MemInc = common->mem_inc; - dma_handle->Init.PeriphDataAlignment = common->periph_data_alignment; - dma_handle->Init.MemDataAlignment = common->mem_data_alignment; dma_handle->Init.Mode = common->mode; dma_handle->Init.Priority = common->priority; } /** - * @brief Apply common configuration fields and DMA-specific fields when applicable. + * @brief Apply one static descriptor to a HAL DMA handle. * - * BDMA endpoints only carry the common fields, so the DMA-specific fields are - * skipped based on the controller type stored in the common structure. + * Software dispatch uses @ref stm32_dma_config_common.type. HAL member names + * that exist only on classic DMA or only on GPDMA are still guarded by + * @ref STM32_DMA_USES_GPDMA so unused cases compile as empty on that series. */ static void stm32_dma_apply_config(DMA_HandleTypeDef *dma_handle, const struct stm32_dma_config *dma_config) { stm32_dma_apply_common_config(dma_handle, &dma_config->common); - if (dma_config->common.type == STM32_DMA_TYPE_BDMA) + switch (dma_config->common.type) { - return; - } - -#if defined(STM32_DMA_USES_GPDMA) - dma_handle->Init.BlkHWRequest = dma_config->blk_hw_request; - dma_handle->Init.SrcInc = dma_config->src_inc; - dma_handle->Init.DestInc = dma_config->dest_inc; - dma_handle->Init.SrcDataWidth = dma_config->src_data_width; - dma_handle->Init.DestDataWidth = dma_config->dest_data_width; - dma_handle->Init.SrcBurstLength = dma_config->src_burst_length; - dma_handle->Init.DestBurstLength = dma_config->dest_burst_length; - dma_handle->Init.TransferAllocatedPort = dma_config->transfer_allocated_port; - dma_handle->Init.TransferEventMode = dma_config->transfer_event_mode; -#else + case STM32_DMA_TYPE_DMA: + case STM32_DMA_TYPE_BDMA: +#if !defined(STM32_DMA_USES_GPDMA) + dma_handle->Init.PeriphInc = dma_config->config.classic.periph_inc; + dma_handle->Init.MemInc = dma_config->config.classic.mem_inc; + dma_handle->Init.PeriphDataAlignment = dma_config->config.classic.periph_data_alignment; + dma_handle->Init.MemDataAlignment = dma_config->config.classic.mem_data_alignment; + if (dma_config->common.type == STM32_DMA_TYPE_DMA) + { #if defined(STM32_DMA_USES_CHANNEL) - dma_handle->Init.Channel = dma_config->channel; + dma_handle->Init.Channel = dma_config->config.classic.channel; #endif /* defined(STM32_DMA_USES_CHANNEL) */ #if defined(STM32_DMA_SUPPORTS_FIFO) - dma_handle->Init.FIFOMode = dma_config->fifo_mode; - dma_handle->Init.FIFOThreshold = dma_config->fifo_threshold; - dma_handle->Init.MemBurst = dma_config->mem_burst; - dma_handle->Init.PeriphBurst = dma_config->periph_burst; + dma_handle->Init.FIFOMode = dma_config->config.classic.fifo_mode; + dma_handle->Init.FIFOThreshold = dma_config->config.classic.fifo_threshold; + dma_handle->Init.MemBurst = dma_config->config.classic.mem_burst; + dma_handle->Init.PeriphBurst = dma_config->config.classic.periph_burst; #endif /* defined(STM32_DMA_SUPPORTS_FIFO) */ + } +#endif /* !defined(STM32_DMA_USES_GPDMA) */ + break; + case STM32_DMA_TYPE_GPDMA: +#if defined(STM32_DMA_USES_GPDMA) + dma_handle->Init.BlkHWRequest = dma_config->config.gpdma.blk_hw_request; + dma_handle->Init.SrcInc = dma_config->config.gpdma.src_inc; + dma_handle->Init.DestInc = dma_config->config.gpdma.dest_inc; + dma_handle->Init.SrcDataWidth = dma_config->config.gpdma.src_data_width; + dma_handle->Init.DestDataWidth = dma_config->config.gpdma.dest_data_width; + dma_handle->Init.SrcBurstLength = dma_config->config.gpdma.src_burst_length; + dma_handle->Init.DestBurstLength = dma_config->config.gpdma.dest_burst_length; + dma_handle->Init.TransferAllocatedPort = dma_config->config.gpdma.transfer_allocated_port; + dma_handle->Init.TransferEventMode = dma_config->config.gpdma.transfer_event_mode; #endif /* defined(STM32_DMA_USES_GPDMA) */ + break; + default: + break; + } } /** diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.h index 7195e8959782..25f14e5a5757 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.h @@ -8,6 +8,7 @@ * 2018-11-10 SummerGift first version * 2020-10-14 PeakRacing Porting for stm32wbxx * 2026-04-13 wdfk-prog Add STM32 DMA common helpers + * 2026-08-28 moment-NEW Unify DMA/BDMA/GPDMA descriptors */ /** @@ -25,6 +26,18 @@ extern "C" { #endif +/* + * SPI6 BDMA on STM32H7 must also enable the BDMA clock helper. Close the + * Kconfig/C macro gap so AHB4 RCC code is compiled whenever SPI BDMA is + * selected, even if BSP_USING_BDMA was not selected explicitly. + */ +#if defined(SOC_SERIES_STM32H7) && \ + (defined(BSP_SPI6_TX_USING_BDMA) || defined(BSP_SPI6_RX_USING_BDMA)) +#ifndef BSP_USING_BDMA +#define BSP_USING_BDMA +#endif +#endif /* defined(SOC_SERIES_STM32H7) && SPI6 BDMA */ + /* * DMA-capable BSPs are expected to enable HAL_DMA_MODULE_ENABLED in the * STM32 HAL configuration, so keep the common DMA helper in the build. @@ -110,77 +123,86 @@ extern "C" { #endif /* STM32_GPDMA_DEFAULT_TRANSFER_EVENT_MODE */ #endif /* defined(STM32_DMA_USES_GPDMA) */ - /** - * @brief DMA type classification for STM32 series supported by this BSP. + * @brief DMA controller type stored in each endpoint descriptor. */ -typedef enum +typedef enum stm32_dma_type { STM32_DMA_TYPE_DMA = 0, STM32_DMA_TYPE_BDMA, + STM32_DMA_TYPE_GPDMA, } stm32_dma_type; - /** - * @brief Common DMA configuration fields shared by DMA and BDMA. - * - * This base structure contains all common configuration fields. Both DMA and - * BDMA descriptors embed it as their first member of struct stm32_dma_config, - * enabling zero-cost pointer conversion for shared logic. + * @brief Fields shared by classic DMA, BDMA and GPDMA descriptors. */ struct stm32_dma_config_common { - void *Instance; /**< DMA/BDMA controller instance pointer (typed by child). */ - enum stm32_dma_type type; /**< Type of the DMA controller. */ - rt_uint32_t dma_rcc; /**< RCC enable bit for the DMA/BDMA controller. */ - IRQn_Type dma_irq; /**< DMA/BDMA global IRQ number. */ - rt_uint32_t priority; /**< DMA/BDMA transfer priority. */ - rt_uint8_t preempt_priority; /**< NVIC preempt priority for the DMA/BDMA IRQ. */ - rt_uint8_t sub_priority; /**< NVIC sub priority for the DMA/BDMA IRQ. */ - -#if defined(STM32_DMA_USES_REQUEST) || defined(STM32_BDMA_USES_REQUEST) - rt_uint32_t request; /**< DMA/BDMA request selector. */ + void *Instance; /**< DMA/BDMA/GPDMA controller instance pointer. */ + stm32_dma_type type; /**< Controller type used to dispatch apply/clock. */ + rt_uint32_t dma_rcc; /**< RCC enable bit for the controller. */ + IRQn_Type dma_irq; /**< Controller global IRQ number. */ + rt_uint32_t priority; /**< Transfer priority. */ + rt_uint8_t preempt_priority; /**< NVIC preempt priority. */ + rt_uint8_t sub_priority; /**< NVIC sub priority. */ + +#if defined(STM32_DMA_USES_REQUEST) + rt_uint32_t request; /**< DMA request selector. */ #endif - rt_uint32_t direction; /**< DMA/BDMA transfer direction. */ - rt_uint32_t periph_inc; /**< Peripheral address increment mode. */ - rt_uint32_t mem_inc; /**< Memory address increment mode. */ - rt_uint32_t periph_data_alignment; /**< Peripheral data alignment. */ - rt_uint32_t mem_data_alignment; /**< Memory data alignment. */ - rt_uint32_t mode; /**< DMA/BDMA transfer mode. */ + rt_uint32_t direction; /**< Transfer direction. */ + rt_uint32_t mode; /**< Transfer mode. */ }; /** - * @brief Static DMA endpoint description used by board-level config headers. + * @brief Classic DMA / BDMA HAL configuration fields. * - * This descriptor stores one complete DMA endpoint configuration so peripheral - * drivers can initialize DMA directly from the board-level config tables. + * Channel and FIFO members are always present in the software descriptor. + * Initializers only fill them when the current series exposes those HAL + * fields; apply() copies them only for STM32_DMA_TYPE_DMA. */ -struct stm32_dma_config +struct stm32_dma_classic_config { - struct stm32_dma_config_common common; /**< Common DMA/BDMA configuration fields. */ + rt_uint32_t periph_inc; /**< Peripheral address increment mode. */ + rt_uint32_t mem_inc; /**< Memory address increment mode. */ + rt_uint32_t periph_data_alignment; /**< Peripheral data alignment. */ + rt_uint32_t mem_data_alignment; /**< Memory data alignment. */ + rt_uint32_t channel; /**< DMA channel selector for stream-based DMA. */ + rt_uint32_t fifo_mode; /**< FIFO enable state. */ + rt_uint32_t fifo_threshold; /**< FIFO threshold selection. */ + rt_uint32_t mem_burst; /**< Memory burst transfer mode. */ + rt_uint32_t periph_burst; /**< Peripheral burst transfer mode. */ +}; -#if defined(STM32_DMA_USES_GPDMA) - rt_uint32_t blk_hw_request; /**< GPDMA block hardware request mode. */ - rt_uint32_t src_inc; /**< GPDMA source increment mode. */ - rt_uint32_t dest_inc; /**< GPDMA destination increment mode. */ - rt_uint32_t src_data_width; /**< GPDMA source data width. */ - rt_uint32_t dest_data_width; /**< GPDMA destination data width. */ - rt_uint32_t src_burst_length; /**< GPDMA source burst length. */ - rt_uint32_t dest_burst_length; /**< GPDMA destination burst length. */ - rt_uint32_t transfer_allocated_port;/**< GPDMA allocated port selection. */ - rt_uint32_t transfer_event_mode; /**< GPDMA transfer event mode. */ -#else -#ifdef STM32_DMA_USES_CHANNEL - rt_uint32_t channel; /**< DMA channel selector for stream-based DMA. */ -#endif /* STM32_DMA_USES_CHANNEL */ +/** + * @brief GPDMA HAL configuration fields. + */ +struct stm32_gpdma_config +{ + rt_uint32_t blk_hw_request; /**< GPDMA block hardware request mode. */ + rt_uint32_t src_inc; /**< GPDMA source increment mode. */ + rt_uint32_t dest_inc; /**< GPDMA destination increment mode. */ + rt_uint32_t src_data_width; /**< GPDMA source data width. */ + rt_uint32_t dest_data_width; /**< GPDMA destination data width. */ + rt_uint32_t src_burst_length; /**< GPDMA source burst length. */ + rt_uint32_t dest_burst_length; /**< GPDMA destination burst length. */ + rt_uint32_t transfer_allocated_port; /**< GPDMA allocated port selection. */ + rt_uint32_t transfer_event_mode; /**< GPDMA transfer event mode. */ +}; -#if defined(STM32_DMA_SUPPORTS_FIFO) - rt_uint32_t fifo_mode; /**< FIFO enable state. */ - rt_uint32_t fifo_threshold; /**< FIFO threshold selection. */ - rt_uint32_t mem_burst; /**< Memory burst transfer mode. */ - rt_uint32_t periph_burst; /**< Peripheral burst transfer mode. */ -#endif /* defined(STM32_DMA_SUPPORTS_FIFO) */ -#endif /* defined(STM32_DMA_USES_GPDMA) */ +/** + * @brief Static DMA endpoint description used by board-level config headers. + * + * Controller differences are expressed by @ref stm32_dma_config_common.type + * and the corresponding union arm. Peripheral drivers always use this type. + */ +struct stm32_dma_config +{ + struct stm32_dma_config_common common; /**< Fields shared by all controller types. */ + union + { + struct stm32_dma_classic_config classic; /**< Classic DMA / BDMA fields. */ + struct stm32_gpdma_config gpdma; /**< GPDMA fields. */ + } config; }; /** @@ -230,13 +252,15 @@ struct stm32_dma_config .sub_priority = (_sub_priority), \ STM32_DMA_REQUEST_FIELD(_request) \ .direction = (_direction), \ + .mode = (_mode), \ + }, \ + .config.classic = { \ .periph_inc = (_periph_inc), \ .mem_inc = (_mem_inc), \ .periph_data_alignment = (_periph_data_alignment), \ .mem_data_alignment = (_mem_data_alignment), \ - .mode = (_mode), \ + STM32_DMA_CHANNEL_FIELD(_channel) STM32_DMA_FIFO_FIELD_DEFAULTS \ }, \ - STM32_DMA_CHANNEL_FIELD(_channel) STM32_DMA_FIFO_FIELD_DEFAULTS \ } /** @@ -254,13 +278,15 @@ struct stm32_dma_config .sub_priority = (_sub_priority), \ STM32_DMA_REQUEST_FIELD(_request) \ .direction = (_direction), \ + .mode = (_mode), \ + }, \ + .config.classic = { \ .periph_inc = (_periph_inc), \ .mem_inc = (_mem_inc), \ .periph_data_alignment = (_periph_data_alignment), \ .mem_data_alignment = (_mem_data_alignment), \ - .mode = (_mode), \ + STM32_DMA_CHANNEL_FIELD(_channel) STM32_DMA_FIFO_FIELD_VALUES(_fifo_mode, _fifo_threshold, _mem_burst, _periph_burst) \ }, \ - STM32_DMA_CHANNEL_FIELD(_channel) STM32_DMA_FIFO_FIELD_VALUES(_fifo_mode, _fifo_threshold, _mem_burst, _periph_burst) \ } /** @@ -284,24 +310,35 @@ struct stm32_dma_config #define STM32_DMA_TX_WORD_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _channel, _request, _priority, _preempt_priority, _sub_priority) \ STM32_DMA_CONFIG_INIT_EX((_instance), (_dma_rcc), (_dma_irq), (_channel), (_request), (_priority), (_preempt_priority), (_sub_priority), DMA_MEMORY_TO_PERIPH, DMA_PINC_DISABLE, DMA_MINC_ENABLE, DMA_PDATAALIGN_WORD, DMA_MDATAALIGN_WORD, DMA_NORMAL) +#if defined(STM32_DMA_USES_GPDMA) /** * @brief GPDMA descriptor initializer with explicit source and destination attributes. */ -#define STM32_GPDMA_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority, _direction, _src_inc, _dest_inc, _src_data_width, _dest_data_width, _mode) \ - { \ - .common = { \ - .Instance = (_instance), \ - .type = STM32_DMA_TYPE_DMA, \ - .dma_rcc = (_dma_rcc), \ - .dma_irq = (_dma_irq), \ - .priority = (_priority), \ - .preempt_priority = (_preempt_priority), \ - .sub_priority = (_sub_priority), \ - .request = (_request), \ - .direction = (_direction), \ - .mode = (_mode), \ - }, \ - .blk_hw_request = STM32_GPDMA_DEFAULT_BLOCK_HW_REQUEST, .src_inc = (_src_inc), .dest_inc = (_dest_inc), .src_data_width = (_src_data_width), .dest_data_width = (_dest_data_width), .src_burst_length = STM32_GPDMA_DEFAULT_SRC_BURST_LENGTH, .dest_burst_length = STM32_GPDMA_DEFAULT_DEST_BURST_LENGTH, .transfer_allocated_port = STM32_GPDMA_DEFAULT_TRANSFER_ALLOCATED_PORT, .transfer_event_mode = STM32_GPDMA_DEFAULT_TRANSFER_EVENT_MODE, \ +#define STM32_GPDMA_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority, _direction, _src_inc, _dest_inc, _src_data_width, _dest_data_width, _mode) \ + { \ + .common = { \ + .Instance = (_instance), \ + .type = STM32_DMA_TYPE_GPDMA, \ + .dma_rcc = (_dma_rcc), \ + .dma_irq = (_dma_irq), \ + .priority = (_priority), \ + .preempt_priority = (_preempt_priority), \ + .sub_priority = (_sub_priority), \ + .request = (_request), \ + .direction = (_direction), \ + .mode = (_mode), \ + }, \ + .config.gpdma = { \ + .blk_hw_request = STM32_GPDMA_DEFAULT_BLOCK_HW_REQUEST, \ + .src_inc = (_src_inc), \ + .dest_inc = (_dest_inc), \ + .src_data_width = (_src_data_width), \ + .dest_data_width = (_dest_data_width), \ + .src_burst_length = STM32_GPDMA_DEFAULT_SRC_BURST_LENGTH, \ + .dest_burst_length = STM32_GPDMA_DEFAULT_DEST_BURST_LENGTH, \ + .transfer_allocated_port = STM32_GPDMA_DEFAULT_TRANSFER_ALLOCATED_PORT, \ + .transfer_event_mode = STM32_GPDMA_DEFAULT_TRANSFER_EVENT_MODE, \ + }, \ } #define STM32_GPDMA_RX_BYTE_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority) \ @@ -321,6 +358,55 @@ struct stm32_dma_config #define STM32_GPDMA_TX_WORD_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority) \ STM32_GPDMA_CONFIG_INIT_EX((_instance), (_dma_rcc), (_dma_irq), (_request), (_priority), (_preempt_priority), (_sub_priority), DMA_MEMORY_TO_PERIPH, DMA_SINC_INCREMENTED, DMA_DINC_FIXED, DMA_SRC_DATAWIDTH_WORD, DMA_DEST_DATAWIDTH_WORD, DMA_NORMAL) +#endif /* defined(STM32_DMA_USES_GPDMA) */ + +#if defined(SOC_SERIES_STM32H7) +#ifndef STM32_BDMA_DEFAULT_PRIORITY +#define STM32_BDMA_DEFAULT_PRIORITY DMA_PRIORITY_LOW +#endif + +#ifndef STM32_BDMA_DEFAULT_PREEMPT_PRIORITY +#define STM32_BDMA_DEFAULT_PREEMPT_PRIORITY 0 +#endif + +#ifndef STM32_BDMA_DEFAULT_SUB_PRIORITY +#define STM32_BDMA_DEFAULT_SUB_PRIORITY 0 +#endif + +/** + * @brief BDMA descriptor initializer. Produces struct stm32_dma_config. + * + * BDMA shares classic increment/alignment fields and has no FIFO. apply() + * skips FIFO/channel copies when type is STM32_DMA_TYPE_BDMA. + */ +#define STM32_BDMA_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority, _direction, _periph_inc, _mem_inc, _periph_data_alignment, _mem_data_alignment, _mode) \ + { \ + .common = { \ + .Instance = (_instance), \ + .type = STM32_DMA_TYPE_BDMA, \ + .dma_rcc = (_dma_rcc), \ + .dma_irq = (_dma_irq), \ + .priority = (_priority), \ + .preempt_priority = (_preempt_priority), \ + .sub_priority = (_sub_priority), \ + STM32_DMA_REQUEST_FIELD(_request) \ + .direction = (_direction), \ + .mode = (_mode), \ + }, \ + .config.classic = { \ + .periph_inc = (_periph_inc), \ + .mem_inc = (_mem_inc), \ + .periph_data_alignment = (_periph_data_alignment), \ + .mem_data_alignment = (_mem_data_alignment), \ + }, \ + } + +#define STM32_BDMA_RX_BYTE_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority) \ + STM32_BDMA_CONFIG_INIT_EX((_instance), (_dma_rcc), (_dma_irq), (_request), (_priority), (_preempt_priority), (_sub_priority), DMA_PERIPH_TO_MEMORY, DMA_PINC_DISABLE, DMA_MINC_ENABLE, DMA_PDATAALIGN_BYTE, DMA_MDATAALIGN_BYTE, DMA_NORMAL) + +#define STM32_BDMA_TX_BYTE_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority) \ + STM32_BDMA_CONFIG_INIT_EX((_instance), (_dma_rcc), (_dma_irq), (_request), (_priority), (_preempt_priority), (_sub_priority), DMA_MEMORY_TO_PERIPH, DMA_PINC_DISABLE, DMA_MINC_ENABLE, DMA_PDATAALIGN_BYTE, DMA_MDATAALIGN_BYTE, DMA_NORMAL) +#endif /* defined(SOC_SERIES_STM32H7) */ /** * @brief Apply one static DMA descriptor and initialize the HAL DMA handle. @@ -365,77 +451,6 @@ rt_err_t stm32_dma_deinit(DMA_HandleTypeDef *dma_handle, #endif /* HAL_DMA_MODULE_ENABLED */ -#if defined(BSP_USING_BDMA) && (defined(SOC_SERIES_STM32H7)) - -/** - * @brief BDMA configuration structure that inherits from the common base. - * - * BDMA on STM32H7 uses DMA_Channel_TypeDef instances and has no FIFO support. - * All configuration fields are in the common base structure. The layout is a - * prefix-compatible subset of struct stm32_dma_config, so a pointer to this - * structure can be passed to the shared stm32_dma_init/setup/deinit API. - */ -struct stm32_bdma_config -{ - struct stm32_dma_config_common common; /**< Common DMA/BDMA configuration fields. */ -}; - -/** - * @brief BDMA-specific macro guards for consistency with DMA. - */ -#ifndef STM32_BDMA_USES_REQUEST -#define STM32_BDMA_USES_REQUEST -#endif - -#ifndef STM32_BDMA_DEFAULT_PRIORITY -#define STM32_BDMA_DEFAULT_PRIORITY DMA_PRIORITY_LOW -#endif - -#ifndef STM32_BDMA_DEFAULT_PREEMPT_PRIORITY -#define STM32_BDMA_DEFAULT_PREEMPT_PRIORITY 0 -#endif - -#ifndef STM32_BDMA_DEFAULT_SUB_PRIORITY -#define STM32_BDMA_DEFAULT_SUB_PRIORITY 0 -#endif - -/** - * @brief BDMA descriptor initializer with explicit direction and data layout. - * - * BDMA endpoints only use the common fields of struct stm32_dma_config; the - * DMA-specific fields are left zero and skipped at runtime by the type check. - */ -#define STM32_BDMA_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority, _direction, _periph_inc, _mem_inc, _periph_data_alignment, _mem_data_alignment, _mode) \ - { \ - .common = { \ - .Instance = (_instance), \ - .type = STM32_DMA_TYPE_BDMA, \ - .dma_rcc = (_dma_rcc), \ - .dma_irq = (_dma_irq), \ - .priority = (_priority), \ - .preempt_priority = (_preempt_priority), \ - .sub_priority = (_sub_priority), \ - .request = (_request), \ - .direction = (_direction), \ - .periph_inc = (_periph_inc), \ - .mem_inc = (_mem_inc), \ - .periph_data_alignment = (_periph_data_alignment), \ - .mem_data_alignment = (_mem_data_alignment), \ - .mode = (_mode), \ - } \ - } - -/** - * @brief BDMA byte/word transfer descriptor helpers for board-level config. - */ -#define STM32_BDMA_RX_BYTE_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority) \ - STM32_BDMA_CONFIG_INIT_EX((_instance), (_dma_rcc), (_dma_irq), (_request), (_priority), (_preempt_priority), (_sub_priority), DMA_PERIPH_TO_MEMORY, DMA_PINC_DISABLE, DMA_MINC_ENABLE, DMA_PDATAALIGN_BYTE, DMA_MDATAALIGN_BYTE, DMA_NORMAL) - -#define STM32_BDMA_TX_BYTE_CONFIG_INIT_EX(_instance, _dma_rcc, _dma_irq, _request, _priority, _preempt_priority, _sub_priority) \ - STM32_BDMA_CONFIG_INIT_EX((_instance), (_dma_rcc), (_dma_irq), (_request), (_priority), (_preempt_priority), (_sub_priority), DMA_MEMORY_TO_PERIPH, DMA_PINC_DISABLE, DMA_MINC_ENABLE, DMA_PDATAALIGN_BYTE, DMA_MDATAALIGN_BYTE, DMA_NORMAL) - -#endif /* BSP_USING_BDMA && (SOC_SERIES_STM32H7) */ - #ifdef __cplusplus } #endif diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c index e6d128c6731e..be3057392133 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c @@ -14,6 +14,7 @@ * 2025-09-22 wdfk_prog Refactor spixfer to fix DMA reception bug, correct timeout calculation. * 2026-04-14 wdfk_prog Refine SPI DMA config hierarchy * 2026-04-16 wdfk_prog Add SPI interrupt transfer mode scaffolding + * 2026-08-28 moment-NEW Route SPI6 BDMA through the unified DMA interface */ /** @@ -130,68 +131,41 @@ static struct stm32_spi_config spi_config[] = { */ static struct stm32_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])] = { 0 }; -#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) +#if defined(BSP_SPI_USING_DMA) /** - * @brief Roll back SPI DMA/BDMA setup that was partially initialized. - * - * @note DMA and BDMA share the RT_DEVICE_FLAG_DMA_* bits. The engine used - * by an instance is selected by its dma_xx/bdma_xx config pointer, so - * both engines are handled here. + * @brief Roll back SPI DMA setup that was partially initialized. * * @param spi_drv STM32 SPI driver context. * @param dma_flags RT_DEVICE_FLAG_DMA_* bits indicating channels to release. */ static void stm32_spi_dma_rollback(struct stm32_spi *spi_drv, rt_uint16_t dma_flags) { -#if defined(BSP_SPI_RX_USING_DMA) || defined(BSP_SPI_RX_USING_BDMA) +#ifdef BSP_SPI_RX_USING_DMA if (dma_flags & RT_DEVICE_FLAG_DMA_RX) { -#if defined(BSP_SPI_RX_USING_BDMA) - if (spi_drv->config->bdma_rx != RT_NULL) - { - (void)stm32_dma_deinit(&spi_drv->bdma.handle_rx, - (const struct stm32_dma_config *)spi_drv->config->bdma_rx, RT_FALSE); - spi_drv->bdma.handle_rx.Parent = RT_NULL; - spi_drv->handle.hdmarx = RT_NULL; - } -#endif /* BSP_SPI_RX_USING_BDMA */ - -#if defined(BSP_SPI_RX_USING_DMA) if (spi_drv->config->dma_rx != RT_NULL) { (void)stm32_dma_deinit(&spi_drv->dma.handle_rx, spi_drv->config->dma_rx, RT_FALSE); spi_drv->dma.handle_rx.Parent = RT_NULL; spi_drv->handle.hdmarx = RT_NULL; } -#endif /* BSP_SPI_RX_USING_DMA */ } -#endif /* BSP_SPI_RX_USING_DMA || BSP_SPI_RX_USING_BDMA */ +#endif /* BSP_SPI_RX_USING_DMA */ -#if defined(BSP_SPI_TX_USING_DMA) || defined(BSP_SPI_TX_USING_BDMA) +#ifdef BSP_SPI_TX_USING_DMA if (dma_flags & RT_DEVICE_FLAG_DMA_TX) { -#if defined(BSP_SPI_TX_USING_BDMA) - if (spi_drv->config->bdma_tx != RT_NULL) - { - (void)stm32_dma_deinit(&spi_drv->bdma.handle_tx, - (const struct stm32_dma_config *)spi_drv->config->bdma_tx, RT_FALSE); - spi_drv->bdma.handle_tx.Parent = RT_NULL; - spi_drv->handle.hdmatx = RT_NULL; - } -#endif /* BSP_SPI_TX_USING_BDMA */ - -#if defined(BSP_SPI_TX_USING_DMA) if (spi_drv->config->dma_tx != RT_NULL) { (void)stm32_dma_deinit(&spi_drv->dma.handle_tx, spi_drv->config->dma_tx, RT_FALSE); spi_drv->dma.handle_tx.Parent = RT_NULL; spi_drv->handle.hdmatx = RT_NULL; } -#endif /* BSP_SPI_TX_USING_DMA */ } -#endif /* BSP_SPI_TX_USING_DMA || BSP_SPI_TX_USING_BDMA */ +#endif /* BSP_SPI_TX_USING_DMA */ } -#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ +#endif /* BSP_SPI_USING_DMA */ + /** * @brief Initialize an STM32 SPI instance according to an RT-Thread SPI configuration. * @@ -399,39 +373,6 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur #endif /* BSP_SPI_TX_USING_DMA */ #endif /* BSP_SPI_USING_DMA */ -#ifdef BSP_SPI_USING_BDMA - /* BDMA configuration */ -#if defined(BSP_SPI_RX_USING_BDMA) - if ((spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_RX) && (spi_drv->config->bdma_rx != RT_NULL)) - { - if (stm32_dma_setup(&spi_drv->bdma.handle_rx, - &spi_drv->handle, - &spi_drv->handle.hdmarx, - (const struct stm32_dma_config *)spi_drv->config->bdma_rx) != RT_EOK) - { - stm32_spi_dma_rollback(spi_drv, RT_DEVICE_FLAG_DMA_RX); - return -RT_EIO; - } - } -#endif /* BSP_SPI_RX_USING_BDMA */ - -#if defined(BSP_SPI_TX_USING_BDMA) - if ((spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_TX) && (spi_drv->config->bdma_tx != RT_NULL)) - { - if (stm32_dma_setup(&spi_drv->bdma.handle_tx, - &spi_drv->handle, - &spi_drv->handle.hdmatx, - (const struct stm32_dma_config *)spi_drv->config->bdma_tx) != RT_EOK) - { - stm32_spi_dma_rollback(spi_drv, - RT_DEVICE_FLAG_DMA_TX | - (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_RX)); - return -RT_EIO; - } - } -#endif /* BSP_SPI_TX_USING_BDMA */ -#endif /* BSP_SPI_USING_BDMA */ - #ifdef BSP_SPI_USING_IRQ if ((spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_TX) || (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_RX) || (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_INT_TX) || (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_INT_RX)) { @@ -479,7 +420,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m rt_tick_t timeout_tick = rt_tick_from_millisecond(timeout_ms); #endif /* BSP_SPI_USING_IRQ */ -#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT) || defined(BSP_SPI_USING_BDMA) +#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT) /* * Snapshot the call context once for the whole SPI message. * @@ -495,7 +436,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m const rt_bool_t scheduler_available = rt_scheduler_is_available(); const rt_bool_t irq_disabled = rt_hw_interrupt_is_disabled(); const rt_bool_t async_allowed = (scheduler_available && !irq_disabled); -#endif /* defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT) || defined(BSP_SPI_USING_BDMA) */ +#endif /* defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT) */ if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) { if (device->config.mode & RT_SPI_CS_HIGH) @@ -543,7 +484,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m recv_buf = (rt_uint8_t *)message->recv_buf + already_send_length; } -#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) +#ifdef BSP_SPI_USING_DMA const rt_uint8_t *dma_send_buf = send_buf; rt_uint8_t *dma_recv_buf = recv_buf; @@ -551,16 +492,16 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m rt_uint8_t *aligned_recv_buf = RT_NULL; rt_bool_t dma_eligible = (send_length >= BSP_SPI_DMA_TRANS_MIN_LEN); -#if defined(BSP_SPI_TX_USING_DMA) || defined(BSP_SPI_TX_USING_BDMA) +#ifdef BSP_SPI_TX_USING_DMA rt_bool_t use_tx_dma = dma_eligible && (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_TX); #else rt_bool_t use_tx_dma = RT_FALSE; -#endif /* BSP_SPI_TX_USING_DMA || BSP_SPI_TX_USING_BDMA */ -#if defined(BSP_SPI_RX_USING_DMA) || defined(BSP_SPI_RX_USING_BDMA) +#endif /* BSP_SPI_TX_USING_DMA */ +#ifdef BSP_SPI_RX_USING_DMA rt_bool_t use_rx_dma = dma_eligible && (spi_drv->spi_xfer_flags & RT_DEVICE_FLAG_DMA_RX); #else rt_bool_t use_rx_dma = RT_FALSE; -#endif /* BSP_SPI_RX_USING_DMA || BSP_SPI_RX_USING_BDMA */ +#endif /* BSP_SPI_RX_USING_DMA */ if (!async_allowed) @@ -613,7 +554,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m } #endif } -#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ +#endif /* BSP_SPI_USING_DMA */ #ifdef BSP_SPI_USING_INT rt_bool_t int_eligible = (send_length >= BSP_SPI_INT_TRANS_MIN_LEN); @@ -641,13 +582,13 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m /* Start data exchange in full-duplex DMA mode. */ if (message->send_buf && message->recv_buf) { -#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) +#ifdef BSP_SPI_USING_DMA if (use_tx_dma && use_rx_dma) { state = HAL_SPI_TransmitReceive_DMA(spi_handle, (uint8_t *)dma_send_buf, dma_recv_buf, send_length); } else -#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ +#endif /* BSP_SPI_USING_DMA */ #ifdef BSP_SPI_USING_INT if (use_tx_int && use_rx_int) { @@ -662,13 +603,13 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m } else if (message->send_buf) { -#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) +#ifdef BSP_SPI_USING_DMA if (use_tx_dma) { state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)dma_send_buf, send_length); } else -#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ +#endif /* BSP_SPI_USING_DMA */ #ifdef BSP_SPI_USING_INT if (use_tx_int) { @@ -687,24 +628,24 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m /* clear the old error flag */ __HAL_SPI_CLEAR_OVRFLAG(spi_handle); -#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) +#ifdef BSP_SPI_USING_DMA if (use_rx_dma) { rx_dummy_buf = dma_recv_buf; } -#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ +#endif /* BSP_SPI_USING_DMA */ /* * STM32 HAL uses the receive buffer as dummy TX data in master * receive-only mode, so preload the actual HAL buffer with 0xFF. */ rt_memset(rx_dummy_buf, 0xFF, send_length); -#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) +#ifdef BSP_SPI_USING_DMA if (use_rx_dma) { state = HAL_SPI_Receive_DMA(spi_handle, dma_recv_buf, send_length); } else -#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ +#endif /* BSP_SPI_USING_DMA */ #ifdef BSP_SPI_USING_INT if (use_rx_int) { @@ -792,7 +733,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m spi_handle->ErrorCode); } } -#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_BDMA) +#ifdef BSP_SPI_USING_DMA /* Post-transfer processing */ if (state == HAL_OK) { @@ -814,7 +755,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m { rt_free_align(aligned_recv_buf); } -#endif /* BSP_SPI_USING_DMA || BSP_SPI_USING_BDMA */ +#endif /* BSP_SPI_USING_DMA */ if (state != HAL_OK) { break; @@ -1269,7 +1210,7 @@ void SPI6_BDMA_TX_IRQHandler(void) /* enter interrupt */ rt_interrupt_enter(); - HAL_DMA_IRQHandler(&spi_bus_obj[SPI6_INDEX].bdma.handle_tx); + HAL_DMA_IRQHandler(&spi_bus_obj[SPI6_INDEX].dma.handle_tx); /* leave interrupt */ rt_interrupt_leave(); @@ -1285,7 +1226,7 @@ void SPI6_BDMA_RX_IRQHandler(void) /* enter interrupt */ rt_interrupt_enter(); - HAL_DMA_IRQHandler(&spi_bus_obj[SPI6_INDEX].bdma.handle_rx); + HAL_DMA_IRQHandler(&spi_bus_obj[SPI6_INDEX].dma.handle_rx); /* leave interrupt */ rt_interrupt_leave(); @@ -1421,25 +1362,23 @@ static void stm32_get_xfer_info(void) /** SPI6 RX DMA configuration descriptor. */ static const struct stm32_dma_config spi6_dma_rx = SPI6_RX_DMA_CONFIG; spi_config[SPI6_INDEX].dma_rx = &spi6_dma_rx; +#elif defined(BSP_SPI6_RX_USING_BDMA) + spi_bus_obj[SPI6_INDEX].spi_xfer_flags |= RT_DEVICE_FLAG_DMA_RX; + /** SPI6 RX BDMA configuration descriptor. */ + static const struct stm32_dma_config spi6_dma_rx = SPI6_RX_BDMA_CONFIG; + spi_config[SPI6_INDEX].dma_rx = &spi6_dma_rx; #endif #ifdef BSP_SPI6_TX_USING_DMA spi_bus_obj[SPI6_INDEX].spi_xfer_flags |= RT_DEVICE_FLAG_DMA_TX; /** SPI6 TX DMA configuration descriptor. */ static const struct stm32_dma_config spi6_dma_tx = SPI6_TX_DMA_CONFIG; spi_config[SPI6_INDEX].dma_tx = &spi6_dma_tx; -#endif -#ifdef BSP_SPI6_TX_USING_BDMA +#elif defined(BSP_SPI6_TX_USING_BDMA) spi_bus_obj[SPI6_INDEX].spi_xfer_flags |= RT_DEVICE_FLAG_DMA_TX; /** SPI6 TX BDMA configuration descriptor. */ - static const struct stm32_bdma_config spi6_bdma_tx = SPI6_TX_BDMA_CONFIG; - spi_config[SPI6_INDEX].bdma_tx = &spi6_bdma_tx; -#endif /* BSP_SPI6_TX_USING_BDMA */ -#ifdef BSP_SPI6_RX_USING_BDMA - spi_bus_obj[SPI6_INDEX].spi_xfer_flags |= RT_DEVICE_FLAG_DMA_RX; - /** SPI6 RX BDMA configuration descriptor. */ - static const struct stm32_bdma_config spi6_bdma_rx = SPI6_RX_BDMA_CONFIG; - spi_config[SPI6_INDEX].bdma_rx = &spi6_bdma_rx; -#endif /* BSP_SPI6_RX_USING_BDMA */ + static const struct stm32_dma_config spi6_dma_tx = SPI6_TX_BDMA_CONFIG; + spi_config[SPI6_INDEX].dma_tx = &spi6_dma_tx; +#endif #endif /* BSP_USING_SPI6 */ } diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h index f13969de6adc..552de1e91fdb 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h @@ -66,12 +66,21 @@ #define BSP_SPI_USING_POLL #endif -/* Aggregate DMA transfer configuration from per-instance Kconfig macros. */ -#if defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI2_TX_USING_DMA) || defined(BSP_SPI3_TX_USING_DMA) || defined(BSP_SPI4_TX_USING_DMA) || defined(BSP_SPI5_TX_USING_DMA) || defined(BSP_SPI6_TX_USING_DMA) +#if defined(BSP_SPI6_TX_USING_DMA) && defined(BSP_SPI6_TX_USING_BDMA) +#error "SPI6 TX DMA and BDMA are mutually exclusive" +#endif + +#if defined(BSP_SPI6_RX_USING_DMA) && defined(BSP_SPI6_RX_USING_BDMA) +#error "SPI6 RX DMA and BDMA are mutually exclusive" +#endif + +/* Aggregate DMA transfer configuration from per-instance Kconfig macros. + * SPI6 BDMA is a DMA-engine backend, so it shares the DMA transport path. */ +#if defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI2_TX_USING_DMA) || defined(BSP_SPI3_TX_USING_DMA) || defined(BSP_SPI4_TX_USING_DMA) || defined(BSP_SPI5_TX_USING_DMA) || defined(BSP_SPI6_TX_USING_DMA) || defined(BSP_SPI6_TX_USING_BDMA) #define BSP_SPI_TX_USING_DMA #endif -#if defined(BSP_SPI1_RX_USING_DMA) || defined(BSP_SPI2_RX_USING_DMA) || defined(BSP_SPI3_RX_USING_DMA) || defined(BSP_SPI4_RX_USING_DMA) || defined(BSP_SPI5_RX_USING_DMA) || defined(BSP_SPI6_RX_USING_DMA) +#if defined(BSP_SPI1_RX_USING_DMA) || defined(BSP_SPI2_RX_USING_DMA) || defined(BSP_SPI3_RX_USING_DMA) || defined(BSP_SPI4_RX_USING_DMA) || defined(BSP_SPI5_RX_USING_DMA) || defined(BSP_SPI6_RX_USING_DMA) || defined(BSP_SPI6_RX_USING_BDMA) #define BSP_SPI_RX_USING_DMA #endif @@ -95,7 +104,7 @@ #define BSP_SPI5_USING_DMA #endif -#if defined(BSP_SPI6_TX_USING_DMA) || defined(BSP_SPI6_RX_USING_DMA) +#if defined(BSP_SPI6_TX_USING_DMA) || defined(BSP_SPI6_RX_USING_DMA) || defined(BSP_SPI6_TX_USING_BDMA) || defined(BSP_SPI6_RX_USING_BDMA) #define BSP_SPI6_USING_DMA #endif @@ -139,25 +148,8 @@ #if defined(BSP_SPI_TX_USING_INT) || defined(BSP_SPI_RX_USING_INT) #define BSP_SPI_USING_INT #endif -/* Aggregate BDMA transfer configuration from per-instance Kconfig macros. - * Only SPI6 lives in the D3 domain and can be served by BDMA on STM32H7. */ -#if defined(BSP_SPI6_TX_USING_BDMA) -#define BSP_SPI_TX_USING_BDMA -#endif - -#if defined(BSP_SPI6_RX_USING_BDMA) -#define BSP_SPI_RX_USING_BDMA -#endif -#if defined(BSP_SPI6_TX_USING_BDMA) || defined(BSP_SPI6_RX_USING_BDMA) -#define BSP_SPI6_USING_BDMA -#endif - -#if defined(BSP_SPI_TX_USING_BDMA) || defined(BSP_SPI_RX_USING_BDMA) -#define BSP_SPI_USING_BDMA -#endif - -/* Aggregate IRQ requirements from DMA, BDMA and interrupt transfer modes. */ +/* Aggregate IRQ requirements from DMA and interrupt transfer modes. */ #if defined(BSP_SPI1_USING_DMA) || defined(BSP_SPI1_USING_INT) #define BSP_SPI1_USING_IRQ #endif @@ -178,11 +170,11 @@ #define BSP_SPI5_USING_IRQ #endif -#if defined(BSP_SPI6_USING_DMA) || defined(BSP_SPI6_USING_INT) || defined(BSP_SPI6_USING_BDMA) +#if defined(BSP_SPI6_USING_DMA) || defined(BSP_SPI6_USING_INT) #define BSP_SPI6_USING_IRQ #endif -#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT) || defined(BSP_SPI_USING_BDMA) +#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT) #define BSP_SPI_USING_IRQ #endif @@ -221,17 +213,11 @@ struct stm32_spi_config char *bus_name; /**< RT-Thread SPI bus name. */ IRQn_Type irq_type; /**< SPI peripheral IRQ number. */ #ifdef BSP_SPI_RX_USING_DMA - const struct stm32_dma_config *dma_rx; /**< RX DMA configuration. */ + const struct stm32_dma_config *dma_rx; /**< RX DMA/BDMA configuration. */ #endif /* BSP_SPI_RX_USING_DMA */ #ifdef BSP_SPI_TX_USING_DMA - const struct stm32_dma_config *dma_tx; /**< TX DMA configuration. */ + const struct stm32_dma_config *dma_tx; /**< TX DMA/BDMA configuration. */ #endif /* BSP_SPI_TX_USING_DMA */ -#ifdef BSP_SPI_RX_USING_BDMA - const struct stm32_bdma_config *bdma_rx; /**< RX BDMA configuration. */ -#endif /* BSP_SPI_RX_USING_BDMA */ -#ifdef BSP_SPI_TX_USING_BDMA - const struct stm32_bdma_config *bdma_tx; /**< TX BDMA configuration. */ -#endif /* BSP_SPI_TX_USING_BDMA */ }; /** @@ -261,24 +247,13 @@ struct stm32_spi struct { #ifdef BSP_SPI_RX_USING_DMA - DMA_HandleTypeDef handle_rx; /**< STM32 HAL RX DMA handle. */ + DMA_HandleTypeDef handle_rx; /**< STM32 HAL RX DMA/BDMA handle. */ #endif /* BSP_SPI_RX_USING_DMA */ #ifdef BSP_SPI_TX_USING_DMA - DMA_HandleTypeDef handle_tx; /**< STM32 HAL TX DMA handle. */ + DMA_HandleTypeDef handle_tx; /**< STM32 HAL TX DMA/BDMA handle. */ #endif /* BSP_SPI_TX_USING_DMA */ } dma; /**< DMA handles associated with this SPI bus. */ #endif /* BSP_SPI_USING_DMA */ -#ifdef BSP_SPI_USING_BDMA - struct - { -#ifdef BSP_SPI_RX_USING_BDMA - DMA_HandleTypeDef handle_rx; /**< STM32 HAL RX BDMA handle. */ -#endif /* BSP_SPI_RX_USING_BDMA */ -#ifdef BSP_SPI_TX_USING_BDMA - DMA_HandleTypeDef handle_tx; /**< STM32 HAL TX BDMA handle. */ -#endif /* BSP_SPI_TX_USING_BDMA */ - } bdma; /**< BDMA handles associated with this SPI bus. */ -#endif /* BSP_SPI_USING_BDMA */ }; #endif /*__DRV_SPI_H__ */