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/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..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 @@ -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, \ + SPI6_TX_BDMA_REQUEST, \ + 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, \ + SPI6_RX_BDMA_REQUEST, \ + 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..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 */ /** @@ -16,7 +17,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 +25,16 @@ */ #ifdef HAL_DMA_MODULE_ENABLED +/** + * @brief Get the controller type name for logging. + * + * The name follows the descriptor type so DMA, BDMA and GPDMA share one + * helper path while still producing a distinct log tag. + */ +#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) /** * @brief Enable the DMAMUX clock when the current STM32 DMA path needs it. @@ -39,13 +50,28 @@ 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; + /* + * 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); + 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,49 +229,73 @@ static void stm32_dma_irq_put(IRQn_Type dma_irq) } /** - * @brief Copy one static DMA descriptor into one 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 dma_config Static DMA endpoint description. + * @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) + dma_handle->Init.Request = common->request; +#endif /* defined(STM32_DMA_USES_REQUEST) */ + dma_handle->Init.Direction = common->direction; + dma_handle->Init.Mode = common->mode; + dma_handle->Init.Priority = common->priority; +} + +/** + * @brief Apply one static descriptor to a HAL DMA handle. + * + * 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) { - dma_handle->Instance = dma_config->Instance; -#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 + stm32_dma_apply_common_config(dma_handle, &dma_config->common); + + switch (dma_config->common.type) + { + 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_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; - 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; + } } /** @@ -263,21 +310,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 +364,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 +388,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..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. @@ -34,14 +47,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 +64,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 +82,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 +90,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,90 +119,119 @@ 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 Static DMA endpoint description used by board-level config headers. - * - * This descriptor stores one complete DMA endpoint configuration so peripheral - * drivers can initialize DMA directly from the board-level config tables. + * @brief DMA controller type stored in each endpoint descriptor. */ -struct stm32_dma_config +typedef enum stm32_dma_type { - 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. */ + STM32_DMA_TYPE_DMA = 0, + STM32_DMA_TYPE_BDMA, + STM32_DMA_TYPE_GPDMA, +} stm32_dma_type; -#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. */ - 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. */ - 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 */ +/** + * @brief Fields shared by classic DMA, BDMA and GPDMA descriptors. + */ +struct stm32_dma_config_common +{ + 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. */ -#ifdef STM32_DMA_USES_REQUEST - rt_uint32_t request; /**< DMA request selector for DMAMUX/request-based DMA. */ -#endif /* STM32_DMA_USES_REQUEST */ +#if defined(STM32_DMA_USES_REQUEST) + rt_uint32_t request; /**< DMA request selector. */ +#endif + rt_uint32_t direction; /**< Transfer direction. */ + rt_uint32_t mode; /**< Transfer mode. */ +}; - 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. */ +/** + * @brief Classic DMA / BDMA HAL configuration fields. + * + * 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_classic_config +{ + 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_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 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. */ +}; + +/** + * @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; }; /** * @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 +242,25 @@ 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), \ + .mode = (_mode), \ + }, \ + .config.classic = { \ + .periph_inc = (_periph_inc), \ + .mem_inc = (_mem_inc), \ + .periph_data_alignment = (_periph_data_alignment), \ + .mem_data_alignment = (_mem_data_alignment), \ + STM32_DMA_CHANNEL_FIELD(_channel) STM32_DMA_FIFO_FIELD_DEFAULTS \ + }, \ } /** @@ -233,21 +268,25 @@ 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), \ + .mode = (_mode), \ + }, \ + .config.classic = { \ + .periph_inc = (_periph_inc), \ + .mem_inc = (_mem_inc), \ + .periph_data_alignment = (_periph_data_alignment), \ + .mem_data_alignment = (_mem_data_alignment), \ + STM32_DMA_CHANNEL_FIELD(_channel) STM32_DMA_FIFO_FIELD_VALUES(_fifo_mode, _fifo_threshold, _mem_burst, _periph_burst) \ + }, \ } /** @@ -271,29 +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) \ { \ - .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), \ + .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) \ @@ -313,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. diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c index 2d68d48403a9..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 */ /** @@ -61,7 +62,7 @@ #endif /* BSP_SPI_INT_TRANS_MIN_LEN */ /*#define DRV_DEBUG*/ -#define LOG_TAG "drv.spi" +#define LOG_TAG "drv.spi" #include /** @@ -99,8 +100,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,32 +129,38 @@ 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) /** * @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 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)) +#ifdef BSP_SPI_RX_USING_DMA + 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 (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 */ -#if defined(BSP_SPI_TX_USING_DMA) - if ((dma_flags & RT_DEVICE_FLAG_DMA_TX) && (spi_drv->config->dma_tx != RT_NULL)) +#ifdef BSP_SPI_TX_USING_DMA + 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 (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 */ } @@ -311,20 +317,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 +338,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 +359,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, @@ -369,8 +374,7 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur #endif /* BSP_SPI_USING_DMA */ #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 +404,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; @@ -433,7 +437,6 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m 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) */ - if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) { if (device->config.mode & RT_SPI_CS_HIGH) @@ -489,17 +492,18 @@ 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) +#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 */ -#if defined(BSP_SPI_RX_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 */ + if (!async_allowed) { use_rx_dma = use_tx_dma = dma_eligible = RT_FALSE; @@ -540,8 +544,14 @@ 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 */ @@ -580,7 +590,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m else #endif /* BSP_SPI_USING_DMA */ #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); } @@ -601,7 +611,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m else #endif /* BSP_SPI_USING_DMA */ #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); } @@ -637,7 +647,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m else #endif /* BSP_SPI_USING_DMA */ #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 +715,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 +723,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) @@ -738,8 +747,14 @@ 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); + 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 (state != HAL_OK) { @@ -750,12 +765,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 +794,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 +803,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 +912,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 +1201,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].dma.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].dma.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. @@ -1311,12 +1362,22 @@ 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; +#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_dma_config spi6_dma_tx = SPI6_TX_BDMA_CONFIG; + spi_config[SPI6_INDEX].dma_tx = &spi6_dma_tx; #endif #endif /* BSP_USING_SPI6 */ } @@ -1328,7 +1389,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 +1400,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 +1411,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 +1422,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..552de1e91fdb 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 * @@ -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 @@ -204,10 +213,10 @@ 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 */ }; @@ -238,13 +247,14 @@ 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 */ }; #endif /*__DRV_SPI_H__ */ +