diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript b/bsp/stm32/libraries/HAL_Drivers/drivers/SConscript index bd717ad8852..b10ef6eb32e 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 d909db39a09..14f002d6229 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 4f5c8c9f82c..84747042857 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 01fbec237d6..bdc00945f8c 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 @@ -39,13 +39,30 @@ 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 is_bdma RT_TRUE for BDMA clock enable, RT_FALSE for regular DMA. */ -static void stm32_dma_enable_clock(rt_uint32_t dma_rcc) +static void stm32_dma_enable_clock(rt_uint32_t dma_rcc, rt_bool_t is_bdma) { rt_uint32_t tmpreg = 0x00U; +#if defined(BSP_USING_BDMA) && (defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32H7RS)) + if (is_bdma) + { + if (dma_rcc == 0) + { + LOG_E("bdma enable clock failed, dma_rcc is 0"); + __HAL_RCC_BDMA_CLK_ENABLE(); + return; + } + SET_BIT(RCC->AHB4ENR, dma_rcc); + tmpreg = READ_BIT(RCC->AHB4ENR, dma_rcc); + UNUSED(tmpreg); + return; + } +#endif /* BSP_USING_BDMA && (SOC_SERIES_STM32H7 || SOC_SERIES_STM32H7RS) */ + #if defined(STM32_DMA_USES_RCC_AHBENR) SET_BIT(RCC->AHBENR, dma_rcc); tmpreg = READ_BIT(RCC->AHBENR, dma_rcc); @@ -69,12 +86,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 +136,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,78 +220,97 @@ 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_config(DMA_HandleTypeDef *dma_handle, - const struct stm32_dma_config *dma_config) +static void stm32_dma_apply_common_config(DMA_HandleTypeDef *dma_handle, + const struct stm32_dma_config_common *common) { - dma_handle->Instance = dma_config->Instance; + 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 optional DMA-specific fields. + * @param dma_handle DMA handle to update. + * @param common Common configuration fields shared by DMA and BDMA. + * @param dma_config Optional DMA-specific configuration (NULL for BDMA). + */ +static void stm32_dma_apply_config_common(DMA_HandleTypeDef *dma_handle, + const struct stm32_dma_config_common *common, + const struct stm32_dma_config *dma_config) +{ + stm32_dma_apply_common_config(dma_handle, common); + + if (dma_config != RT_NULL) + { #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; + 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 #if defined(STM32_DMA_USES_CHANNEL) - dma_handle->Init.Channel = dma_config->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; - dma_handle->Init.MemBurst = dma_config->mem_burst; - dma_handle->Init.PeriphBurst = dma_config->periph_burst; + 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; #endif /* defined(STM32_DMA_SUPPORTS_FIFO) */ #endif /* defined(STM32_DMA_USES_GPDMA) */ + } } /** - * @brief Enable one DMA controller, apply the static descriptor and initialize HAL state. + * @brief Enable one DMA/BDMA controller, apply configuration and initialize HAL state. * @param dma_handle DMA handle owned by one peripheral driver. - * @param dma_config Board-level DMA endpoint description. + * @param common Common configuration fields shared by DMA and BDMA. + * @param dma_config Optional DMA-specific configuration (NULL for BDMA). + * @param is_bdma RT_TRUE for BDMA, RT_FALSE for regular DMA. + * @param log_tag Log tag for debug output ("drv.dma" or "drv.bdma"). * @retval RT_EOK Initialization succeeded. * @retval -RT_ERROR HAL initialization failed. */ -rt_err_t stm32_dma_init(DMA_HandleTypeDef *dma_handle, - const struct stm32_dma_config *dma_config) +static rt_err_t stm32_dma_init_common(DMA_HandleTypeDef *dma_handle, + const struct stm32_dma_config_common *common, + const struct stm32_dma_config *dma_config, + rt_bool_t is_bdma, + const char *log_tag) { RT_ASSERT(dma_handle != RT_NULL); - RT_ASSERT(dma_config != RT_NULL); + RT_ASSERT(common != RT_NULL); - stm32_dma_enable_clock(dma_config->dma_rcc); - stm32_dma_apply_config(dma_handle, dma_config); + stm32_dma_enable_clock(common->dma_rcc, is_bdma); + stm32_dma_apply_config_common(dma_handle, common, 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", log_tag, dma_handle->Instance, 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", log_tag, dma_handle->Instance, 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", log_tag, dma_handle->Instance, common->dma_irq); return -RT_ERROR; } @@ -285,22 +318,28 @@ rt_err_t stm32_dma_init(DMA_HandleTypeDef *dma_handle, } /** - * @brief Initialize one DMA handle, attach it to the parent HAL handle and enable the DMA IRQ. + * @brief Initialize one DMA/BDMA handle, attach it and enable the IRQ. * @param dma_handle DMA handle owned by one peripheral driver. * @param parent_handle Parent HAL handle, such as UART_HandleTypeDef or SPI_HandleTypeDef. * @param dma_slot Address of the parent handle DMA slot, such as &huart->hdmarx. - * @param dma_config Board-level DMA endpoint description. + * @param common Common configuration fields shared by DMA and BDMA. + * @param dma_config Optional DMA-specific configuration (NULL for BDMA). + * @param is_bdma RT_TRUE for BDMA, RT_FALSE for regular DMA. + * @param log_tag Log tag for debug output ("drv.dma" or "drv.bdma"). * @retval RT_EOK Initialization succeeded. * @retval -RT_ERROR HAL initialization failed. */ -rt_err_t stm32_dma_setup(DMA_HandleTypeDef *dma_handle, - void *parent_handle, - DMA_HandleTypeDef **dma_slot, - const struct stm32_dma_config *dma_config) +static rt_err_t stm32_dma_setup_common(DMA_HandleTypeDef *dma_handle, + void *parent_handle, + DMA_HandleTypeDef **dma_slot, + const struct stm32_dma_config_common *common, + const struct stm32_dma_config *dma_config, + rt_bool_t is_bdma, + const char *log_tag) { rt_err_t result; - result = stm32_dma_init(dma_handle, dma_config); + result = stm32_dma_init_common(dma_handle, common, dma_config, is_bdma, log_tag); if (result != RT_EOK) { return result; @@ -312,46 +351,148 @@ 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(common->dma_irq, common->preempt_priority, 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", log_tag, dma_handle->Instance, common->dma_irq); return RT_EOK; } /** - * @brief Disable one DMA IRQ, optionally abort the current transfer and de-initialize HAL state. + * @brief Disable one DMA/BDMA IRQ, optionally abort the current transfer and de-initialize HAL state. * @param dma_handle DMA handle owned by one peripheral driver. - * @param dma_config Board-level DMA endpoint description. + * @param common Common configuration fields shared by DMA and BDMA. * @param abort_first RT_TRUE aborts the ongoing transfer before HAL_DMA_DeInit(). + * @param log_tag Log tag for debug output ("drv.dma" or "drv.bdma"). * @retval RT_EOK De-initialization succeeded. * @retval -RT_ERROR HAL de-initialization failed. */ -rt_err_t stm32_dma_deinit(DMA_HandleTypeDef *dma_handle, - const struct stm32_dma_config *dma_config, - rt_bool_t abort_first) +static rt_err_t stm32_dma_deinit_common(DMA_HandleTypeDef *dma_handle, + const struct stm32_dma_config_common *common, + rt_bool_t abort_first, + const char *log_tag) { RT_ASSERT(dma_handle != RT_NULL); - RT_ASSERT(dma_config != RT_NULL); + RT_ASSERT(common != RT_NULL); - stm32_dma_irq_put(dma_config->dma_irq); + stm32_dma_irq_put(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", log_tag, dma_handle->Instance, 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", log_tag, dma_handle->Instance, 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", log_tag, dma_handle->Instance, common->dma_irq); return -RT_ERROR; } return RT_EOK; } + +/** + * @brief Enable one DMA controller, apply the static descriptor and initialize HAL state. + * @param dma_handle DMA handle owned by one peripheral driver. + * @param dma_config Board-level DMA endpoint description. + * @retval RT_EOK Initialization succeeded. + * @retval -RT_ERROR HAL initialization failed. + */ +rt_err_t stm32_dma_init(DMA_HandleTypeDef *dma_handle, + const struct stm32_dma_config *dma_config) +{ + RT_ASSERT(dma_config != RT_NULL); + return stm32_dma_init_common(dma_handle, &dma_config->common, dma_config, RT_FALSE, "drv.dma"); +} + +/** + * @brief Initialize one DMA handle, attach it to the parent HAL handle and enable the DMA IRQ. + * @param dma_handle DMA handle owned by one peripheral driver. + * @param parent_handle Parent HAL handle, such as UART_HandleTypeDef or SPI_HandleTypeDef. + * @param dma_slot Address of the parent handle DMA slot, such as &huart->hdmarx. + * @param dma_config Board-level DMA endpoint description. + * @retval RT_EOK Initialization succeeded. + * @retval -RT_ERROR HAL initialization failed. + */ +rt_err_t stm32_dma_setup(DMA_HandleTypeDef *dma_handle, + void *parent_handle, + DMA_HandleTypeDef **dma_slot, + const struct stm32_dma_config *dma_config) +{ + RT_ASSERT(dma_config != RT_NULL); + return stm32_dma_setup_common(dma_handle, parent_handle, dma_slot, &dma_config->common, dma_config, RT_FALSE, "drv.dma"); +} + +/** + * @brief Disable one DMA IRQ, optionally abort the current transfer and de-initialize HAL state. + * @param dma_handle DMA handle owned by one peripheral driver. + * @param dma_config Board-level DMA endpoint description. + * @param abort_first RT_TRUE aborts the ongoing transfer before HAL_DMA_DeInit(). + * @retval RT_EOK De-initialization succeeded. + * @retval -RT_ERROR HAL de-initialization failed. + */ +rt_err_t stm32_dma_deinit(DMA_HandleTypeDef *dma_handle, + const struct stm32_dma_config *dma_config, + rt_bool_t abort_first) +{ + RT_ASSERT(dma_config != RT_NULL); + return stm32_dma_deinit_common(dma_handle, &dma_config->common, abort_first, "drv.dma"); +} + +#if defined(BSP_USING_BDMA) && (defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32H7RS)) + +/** + * @brief Initialize one BDMA handle and apply the static descriptor. + * @param bdma_handle BDMA handle owned by one peripheral driver. + * @param bdma_config Board-level BDMA endpoint description. + * @retval RT_EOK Initialization succeeded. + * @retval -RT_ERROR HAL initialization failed. + */ +rt_err_t stm32_bdma_init(DMA_HandleTypeDef *bdma_handle, + const struct stm32_bdma_config *bdma_config) +{ + RT_ASSERT(bdma_config != RT_NULL); + return stm32_dma_init_common(bdma_handle, &bdma_config->common, RT_NULL, RT_TRUE, LOG_TAG); +} + +/** + * @brief Initialize one BDMA handle, attach it to the parent HAL handle and enable the IRQ. + * @param bdma_handle BDMA handle owned by one peripheral driver. + * @param parent_handle Parent HAL handle, such as SPI_HandleTypeDef. + * @param dma_slot Address of the parent handle DMA slot. + * @param bdma_config Board-level BDMA endpoint description. + * @retval RT_EOK Initialization succeeded. + * @retval -RT_ERROR HAL initialization failed. + */ +rt_err_t stm32_bdma_setup(DMA_HandleTypeDef *bdma_handle, + void *parent_handle, + DMA_HandleTypeDef **dma_slot, + const struct stm32_bdma_config *bdma_config) +{ + RT_ASSERT(bdma_config != RT_NULL); + return stm32_dma_setup_common(bdma_handle, parent_handle, dma_slot, &bdma_config->common, RT_NULL, RT_TRUE, LOG_TAG); +} + +/** + * @brief Disable one BDMA IRQ, optionally abort the current transfer and de-initialize HAL state. + * @param bdma_handle BDMA handle owned by one peripheral driver. + * @param bdma_config Board-level BDMA endpoint description. + * @param abort_first RT_TRUE aborts the ongoing transfer before de-initialization. + * @retval RT_EOK De-initialization succeeded. + * @retval -RT_ERROR HAL de-initialization failed. + */ +rt_err_t stm32_bdma_deinit(DMA_HandleTypeDef *bdma_handle, + const struct stm32_bdma_config *bdma_config, + rt_bool_t abort_first) +{ + RT_ASSERT(bdma_config != RT_NULL); + return stm32_dma_deinit_common(bdma_handle, &bdma_config->common, abort_first, LOG_TAG); +} + +#endif /* BSP_USING_BDMA && (SOC_SERIES_STM32H7 || SOC_SERIES_STM32H7RS) */ #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 83e1535e685..c13a5b26b1e 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,37 @@ 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 Common DMA configuration fields shared by DMA and BDMA. + * + * This base structure contains all common configuration fields. Both + * stm32_dma_config and stm32_bdma_config embed this as their first member, + * enabling zero-cost pointer conversion for shared logic. + */ +struct stm32_dma_config_common +{ + void *Instance; /**< DMA/BDMA controller instance pointer (typed by child). */ + 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 +145,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 +157,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 +175,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 +208,22 @@ 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), \ + .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 +231,22 @@ 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), \ + .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 +273,20 @@ 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), \ + .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 +350,115 @@ rt_err_t stm32_dma_deinit(DMA_HandleTypeDef *dma_handle, #endif /* HAL_DMA_MODULE_ENABLED */ +#if defined(BSP_USING_BDMA) && (defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32H7RS)) + +/** + * @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. + */ +struct stm32_bdma_config +{ + struct stm32_dma_config_common common; /**< Common DMA/BDMA configuration fields. */ +}; + +/** + * @brief Initialize one BDMA handle and apply the static descriptor. + * @param bdma_handle BDMA handle owned by one peripheral driver. + * @param bdma_config Board-level BDMA endpoint description. + * @retval RT_EOK Initialization succeeded. + * @retval -RT_ERROR HAL initialization failed. + */ +rt_err_t stm32_bdma_init(DMA_HandleTypeDef *bdma_handle, + const struct stm32_bdma_config *bdma_config); + +/** + * @brief Initialize one BDMA handle, attach it to the parent HAL handle and enable the IRQ. + * @param bdma_handle BDMA handle owned by one peripheral driver. + * @param parent_handle Parent HAL handle, such as SPI_HandleTypeDef. + * @param dma_slot Address of the parent handle DMA slot. + * @param bdma_config Board-level BDMA endpoint description. + * @retval RT_EOK Initialization succeeded. + * @retval -RT_ERROR HAL initialization failed. + */ +rt_err_t stm32_bdma_setup(DMA_HandleTypeDef *bdma_handle, + void *parent_handle, + DMA_HandleTypeDef **dma_slot, + const struct stm32_bdma_config *bdma_config); + +/** + * @brief Disable one BDMA IRQ, optionally abort the current transfer and de-initialize HAL state. + * @param bdma_handle BDMA handle owned by one peripheral driver. + * @param bdma_config Board-level BDMA endpoint description. + * @param abort_first RT_TRUE aborts the ongoing transfer before de-initialization. + * @retval RT_EOK De-initialization succeeded. + * @retval -RT_ERROR HAL de-initialization failed. + */ +rt_err_t stm32_bdma_deinit(DMA_HandleTypeDef *bdma_handle, + const struct stm32_bdma_config *bdma_config, + rt_bool_t abort_first); + +#endif /* BSP_USING_BDMA && (SOC_SERIES_STM32H7 || SOC_SERIES_STM32H7RS) */ + +#if defined(BSP_USING_BDMA) && (defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32H7RS)) +/** + * @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 request field selector (always present on H7 BDMA). + */ +#define STM32_BDMA_REQUEST_FIELD(_request) .request = (_request), + +/** + * @brief BDMA descriptor initializer with explicit direction and data layout. + */ +#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), \ + .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 || SOC_SERIES_STM32H7RS) */ + #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 2d68d48403a..33f0509a453 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,68 @@ 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_bdma_deinit(&spi_drv->bdma.handle_rx, 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_bdma_deinit(&spi_drv->bdma.handle_tx, 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 +341,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 +362,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 +383,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 +397,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_bdma_setup(&spi_drv->bdma.handle_rx, + &spi_drv->handle, + &spi_drv->handle.hdmarx, + 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_bdma_setup(&spi_drv->bdma.handle_tx, + &spi_drv->handle, + &spi_drv->handle.hdmatx, + 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 +461,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 +477,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 +493,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 +541,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 +549,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 +601,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 +639,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 +660,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 +685,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 +772,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 +780,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 +790,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 +804,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 +822,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 +851,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 +860,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 +969,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 +1258,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 +1426,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 +1448,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 +1459,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 +1470,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 +1481,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 bcf14bfb637..97e21ff0d11 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 * @@ -140,32 +140,32 @@ #define BSP_SPI_USING_INT #endif -/* Aggregate IRQ requirements from DMA and interrupt transfer modes. */ -#if defined(BSP_SPI1_USING_DMA) || defined(BSP_SPI1_USING_INT) +/* Aggregate IRQ requirements from DMA, BDMA and interrupt transfer modes. */ +#if defined(BSP_SPI1_USING_DMA) || defined(BSP_SPI1_USING_INT) || defined(BSP_SPI1_USING_BDMA) #define BSP_SPI1_USING_IRQ #endif -#if defined(BSP_SPI2_USING_DMA) || defined(BSP_SPI2_USING_INT) +#if defined(BSP_SPI2_USING_DMA) || defined(BSP_SPI2_USING_INT) || defined(BSP_SPI2_USING_BDMA) #define BSP_SPI2_USING_IRQ #endif -#if defined(BSP_SPI3_USING_DMA) || defined(BSP_SPI3_USING_INT) +#if defined(BSP_SPI3_USING_DMA) || defined(BSP_SPI3_USING_INT) || defined(BSP_SPI3_USING_BDMA) #define BSP_SPI3_USING_IRQ #endif -#if defined(BSP_SPI4_USING_DMA) || defined(BSP_SPI4_USING_INT) +#if defined(BSP_SPI4_USING_DMA) || defined(BSP_SPI4_USING_INT) || defined(BSP_SPI4_USING_BDMA) #define BSP_SPI4_USING_IRQ #endif -#if defined(BSP_SPI5_USING_DMA) || defined(BSP_SPI5_USING_INT) +#if defined(BSP_SPI5_USING_DMA) || defined(BSP_SPI5_USING_INT) || defined(BSP_SPI5_USING_BDMA) #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 +209,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 +251,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__ */ +