Przeglądaj źródła

refactor[STM32][DMA]: add common DMA helper layer for HAL drivers

- add drv_dma common helpers and stm32_dma_config descriptors for STM32 series
- refactor i2c, spi, usart, qspi, and sdio DMA setup and deinit paths to reuse the common layer
- unify DMA IRQ enable, rollback handling, and const board-level DMA configuration usage
wdfk-prog 2 dni temu
rodzic
commit
c45f5f9267

+ 4 - 1
bsp/stm32/libraries/HAL_Drivers/drivers/SConscript

@@ -6,6 +6,9 @@ import os
 cwd = GetCurrentDir()
 cwd = GetCurrentDir()
 group = []
 group = []
 src = []
 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]
 path = [cwd]
 
 
 if GetDepend(['RT_USING_PIN']):
 if GetDepend(['RT_USING_PIN']):
@@ -35,7 +38,7 @@ if GetDepend('RT_USING_SOFT_SPI'):
 if GetDepend(['RT_USING_I2C', 'RT_USING_I2C_BITOPS']):
 if GetDepend(['RT_USING_I2C', 'RT_USING_I2C_BITOPS']):
     if GetDepend('BSP_USING_I2C1') or GetDepend('BSP_USING_I2C2') or GetDepend('BSP_USING_I2C3') or GetDepend('BSP_USING_I2C4'):
     if GetDepend('BSP_USING_I2C1') or GetDepend('BSP_USING_I2C2') or GetDepend('BSP_USING_I2C3') or GetDepend('BSP_USING_I2C4'):
         src += ['drv_soft_i2c.c']
         src += ['drv_soft_i2c.c']
-        
+
 if GetDepend(['RT_USING_I2C']):
 if GetDepend(['RT_USING_I2C']):
     if GetDepend('BSP_USING_HARD_I2C1') or GetDepend('BSP_USING_HARD_I2C2') or GetDepend('BSP_USING_HARD_I2C3') or GetDepend('BSP_USING_HARD_I2C4'):
     if GetDepend('BSP_USING_HARD_I2C1') or GetDepend('BSP_USING_HARD_I2C2') or GetDepend('BSP_USING_HARD_I2C3') or GetDepend('BSP_USING_HARD_I2C4'):
         src += ['drv_hard_i2c.c']
         src += ['drv_hard_i2c.c']

+ 1 - 0
bsp/stm32/libraries/HAL_Drivers/drivers/drv_config.h

@@ -14,6 +14,7 @@
 
 
 #include <board.h>
 #include <board.h>
 #include <rtdevice.h>
 #include <rtdevice.h>
+#include "drv_dma.h"
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 extern "C" {
 extern "C" {

+ 357 - 0
bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c

@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2006-2026, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2026-04-13     wdfk-prog    Add STM32 DMA common helpers
+ */
+
+/**
+ * @file drv_dma.c
+ * @brief STM32 DMA common helper layer for peripheral drivers.
+ */
+
+#include "drv_dma.h"
+
+// #define DRV_DEBUG
+#define LOG_TAG             "drv.dma"
+#include <drv_log.h>
+/*
+ * 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.
+ */
+#ifdef HAL_DMA_MODULE_ENABLED
+
+#if defined(STM32_DMA_USES_REQUEST)
+/**
+ * @brief Enable the DMAMUX clock when the current STM32 DMA path needs it.
+ */
+static void stm32_dma_enable_dmamux_clock(void)
+{
+#if defined(DMAMUX1) && defined(__HAL_RCC_DMAMUX1_CLK_ENABLE)
+    __HAL_RCC_DMAMUX1_CLK_ENABLE();
+#elif defined(DMAMUX) && defined(__HAL_RCC_DMAMUX_CLK_ENABLE)
+    __HAL_RCC_DMAMUX_CLK_ENABLE();
+#endif /* defined(DMAMUX1) && defined(__HAL_RCC_DMAMUX1_CLK_ENABLE) */
+}
+#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.
+ */
+static void stm32_dma_enable_clock(rt_uint32_t dma_rcc)
+{
+    rt_uint32_t tmpreg = 0x00U;
+
+#if defined(STM32_DMA_USES_RCC_AHBENR)
+    SET_BIT(RCC->AHBENR, dma_rcc);
+    tmpreg = READ_BIT(RCC->AHBENR, dma_rcc);
+#elif defined(STM32_DMA_USES_RCC_MP_AHB2ENSETR)
+    SET_BIT(RCC->MP_AHB2ENSETR, dma_rcc);
+    tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, dma_rcc);
+#elif defined(STM32_DMA_USES_RCC_AHB1ENR)
+    SET_BIT(RCC->AHB1ENR, dma_rcc);
+    tmpreg = READ_BIT(RCC->AHB1ENR, dma_rcc);
+#endif /* defined(STM32_DMA_USES_RCC_AHBENR) || defined(STM32_DMA_USES_RCC_MP_AHB2ENSETR) || defined(STM32_DMA_USES_RCC_AHB1ENR) */
+
+#if defined(STM32_DMA_USES_REQUEST)
+    stm32_dma_enable_dmamux_clock();
+#endif /* defined(STM32_DMA_USES_REQUEST) */
+
+    UNUSED(tmpreg);
+}
+
+/* Only a few STM32 families expose DMA requests on shared NVIC lines.
+ * Use reference counting only for those known shared IRQ numbers so one
+ * 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)))
+#define STM32_DMA_HAS_SHARED_IRQ_REFCNT
+#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.
+ */
+static rt_uint16_t stm32_dma_irq_ref_count[STM32_DMA_IRQ_SLOT_COUNT];
+
+/**
+ * @brief Check whether one DMA IRQ number can index the local reference table.
+ * @param dma_irq DMA IRQ number to validate.
+ * @retval RT_TRUE The IRQ number maps to one valid table slot.
+ * @retval RT_FALSE The IRQ number is negative or outside the table range.
+ */
+static rt_bool_t stm32_dma_irq_is_valid(IRQn_Type dma_irq)
+{
+    return ((int32_t)dma_irq >= 0) && ((rt_uint32_t)dma_irq < STM32_DMA_IRQ_SLOT_COUNT);
+}
+
+/**
+ * @brief Check whether one DMA IRQ line is shared and needs reference counting.
+ * @param dma_irq DMA IRQ number to inspect.
+ * @retval RT_TRUE The IRQ line is shared by multiple DMA endpoints.
+ * @retval RT_FALSE The IRQ line can use direct enable and disable handling.
+ */
+static rt_bool_t stm32_dma_irq_needs_refcount(IRQn_Type dma_irq)
+{
+#if defined(SOC_SERIES_STM32F1) && defined(DMA2_Channel4_5_IRQn)
+    if (dma_irq == DMA2_Channel4_5_IRQn)
+    {
+        return RT_TRUE;
+    }
+#endif /* defined(SOC_SERIES_STM32F1) && defined(DMA2_Channel4_5_IRQn) */
+
+#if defined(SOC_SERIES_STM32L0) && defined(DMA1_Channel4_5_6_7_IRQn)
+    if (dma_irq == DMA1_Channel4_5_6_7_IRQn)
+    {
+        return RT_TRUE;
+    }
+#endif /* defined(SOC_SERIES_STM32L0) && defined(DMA1_Channel4_5_6_7_IRQn) */
+
+#if defined(SOC_SERIES_STM32G0) && defined(DMA1_Channel2_3_IRQn)
+    if (dma_irq == DMA1_Channel2_3_IRQn)
+    {
+        return RT_TRUE;
+    }
+#endif /* defined(SOC_SERIES_STM32G0) && defined(DMA1_Channel2_3_IRQn) */
+
+#if defined(SOC_SERIES_STM32F0)
+# 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)
+    if (dma_irq == DMA1_Channel4_5_IRQn)
+    {
+        return RT_TRUE;
+    }
+# 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(SOC_SERIES_STM32F0) */
+
+    return RT_FALSE;
+}
+#endif /* shared DMA IRQ families */
+
+/**
+ * @brief Enable one DMA IRQ line and apply the requested NVIC priority.
+ * @param dma_irq DMA IRQ number to enable.
+ * @param preempt_priority NVIC preempt priority for the DMA IRQ.
+ * @param sub_priority NVIC subpriority for the DMA IRQ.
+ */
+static void stm32_dma_irq_get(IRQn_Type dma_irq,
+                              rt_uint8_t preempt_priority,
+                              rt_uint8_t sub_priority)
+{
+#if defined(STM32_DMA_HAS_SHARED_IRQ_REFCNT)
+    rt_base_t level;
+
+    if (stm32_dma_irq_needs_refcount(dma_irq) && stm32_dma_irq_is_valid(dma_irq))
+    {
+        level = rt_hw_interrupt_disable();
+        if (stm32_dma_irq_ref_count[(rt_uint32_t)dma_irq] == 0U)
+        {
+            HAL_NVIC_SetPriority(dma_irq, preempt_priority, sub_priority);
+            HAL_NVIC_EnableIRQ(dma_irq);
+        }
+        stm32_dma_irq_ref_count[(rt_uint32_t)dma_irq]++;
+        rt_hw_interrupt_enable(level);
+        return;
+    }
+#endif /* defined(STM32_DMA_HAS_SHARED_IRQ_REFCNT) */
+
+    HAL_NVIC_SetPriority(dma_irq, preempt_priority, sub_priority);
+    HAL_NVIC_EnableIRQ(dma_irq);
+}
+
+/**
+ * @brief Release one DMA IRQ line and disable it when no user remains.
+ * @param dma_irq DMA IRQ number to release.
+ */
+static void stm32_dma_irq_put(IRQn_Type dma_irq)
+{
+#if defined(STM32_DMA_HAS_SHARED_IRQ_REFCNT)
+    rt_base_t level;
+
+    if (stm32_dma_irq_needs_refcount(dma_irq) && stm32_dma_irq_is_valid(dma_irq))
+    {
+        level = rt_hw_interrupt_disable();
+        if (stm32_dma_irq_ref_count[(rt_uint32_t)dma_irq] > 0U)
+        {
+            stm32_dma_irq_ref_count[(rt_uint32_t)dma_irq]--;
+            if (stm32_dma_irq_ref_count[(rt_uint32_t)dma_irq] == 0U)
+            {
+                HAL_NVIC_DisableIRQ(dma_irq);
+            }
+        }
+        rt_hw_interrupt_enable(level);
+        return;
+    }
+#endif /* defined(STM32_DMA_HAS_SHARED_IRQ_REFCNT) */
+
+    HAL_NVIC_DisableIRQ(dma_irq);
+}
+
+/**
+ * @brief Copy one static DMA descriptor into one HAL DMA handle.
+ * @param dma_handle DMA handle to update.
+ * @param dma_config Static DMA endpoint description.
+ */
+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
+#if defined(STM32_DMA_USES_CHANNEL)
+    dma_handle->Init.Channel = dma_config->channel;
+#endif /* defined(STM32_DMA_USES_CHANNEL) */
+#if defined(STM32_DMA_USES_REQUEST)
+    dma_handle->Init.Request = dma_config->request;
+#endif /* defined(STM32_DMA_USES_REQUEST) */
+    dma_handle->Init.Direction = dma_config->direction;
+    dma_handle->Init.PeriphInc = dma_config->periph_inc;
+    dma_handle->Init.MemInc = dma_config->mem_inc;
+    dma_handle->Init.PeriphDataAlignment = dma_config->periph_data_alignment;
+    dma_handle->Init.MemDataAlignment = dma_config->mem_data_alignment;
+    dma_handle->Init.Mode = dma_config->mode;
+    dma_handle->Init.Priority = dma_config->priority;
+#if defined(STM32_DMA_SUPPORTS_FIFO)
+    dma_handle->Init.FIFOMode = dma_config->fifo_mode;
+    dma_handle->Init.FIFOThreshold = dma_config->fifo_threshold;
+    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.
+ * @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_handle != RT_NULL);
+    RT_ASSERT(dma_config != RT_NULL);
+
+    stm32_dma_enable_clock(dma_config->dma_rcc);
+    stm32_dma_apply_config(dma_handle, dma_config);
+
+    LOG_D("dma init, dma=%p, irq=%d", dma_handle->Instance, dma_config->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);
+        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);
+        return -RT_ERROR;
+    }
+
+    return RT_EOK;
+}
+
+/**
+ * @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_err_t result;
+
+    result = stm32_dma_init(dma_handle, dma_config);
+    if (result != RT_EOK)
+    {
+        return result;
+    }
+
+    if ((parent_handle != RT_NULL) && (dma_slot != RT_NULL))
+    {
+        *dma_slot = dma_handle;
+        dma_handle->Parent = parent_handle;
+    }
+
+    stm32_dma_irq_get(dma_config->dma_irq, dma_config->preempt_priority, dma_config->sub_priority);
+
+    LOG_D("dma setup, dma=%p, irq=%d", dma_handle->Instance, dma_config->dma_irq);
+
+    return RT_EOK;
+}
+
+/**
+ * @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_handle != RT_NULL);
+    RT_ASSERT(dma_config != RT_NULL);
+
+    stm32_dma_irq_put(dma_config->dma_irq);
+
+    LOG_D("dma deinit, dma=%p, irq=%d", dma_handle->Instance, dma_config->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);
+        }
+    }
+
+    if (HAL_DMA_DeInit(dma_handle) != HAL_OK)
+    {
+        LOG_E("dma deinit failed, dma=%p, irq=%d", dma_handle->Instance, dma_config->dma_irq);
+        return -RT_ERROR;
+    }
+
+    return RT_EOK;
+}
+#endif /* HAL_DMA_MODULE_ENABLED */

+ 325 - 18
bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.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
  * SPDX-License-Identifier: Apache-2.0
  *
  *
@@ -7,6 +7,12 @@
  * Date           Author       Notes
  * Date           Author       Notes
  * 2018-11-10     SummerGift   first version
  * 2018-11-10     SummerGift   first version
  * 2020-10-14     PeakRacing   Porting for stm32wbxx
  * 2020-10-14     PeakRacing   Porting for stm32wbxx
+ * 2026-04-13     wdfk-prog    Add STM32 DMA common helpers
+ */
+
+/**
+ * @file drv_dma.h
+ * @brief STM32 DMA common descriptors and helper interfaces.
  */
  */
 
 
 #ifndef __DRV_DMA_H_
 #ifndef __DRV_DMA_H_
@@ -19,33 +25,334 @@
 extern "C" {
 extern "C" {
 #endif
 #endif
 
 
-#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32L5)\
+/*
+ * 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.
+ */
+#ifdef HAL_DMA_MODULE_ENABLED
+
+/**
+ * @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_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_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
 #define DMA_INSTANCE_TYPE              DMA_Channel_TypeDef
-#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)\
+#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) \
     || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1)
     || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1)
 #define DMA_INSTANCE_TYPE              DMA_Stream_TypeDef
 #define DMA_INSTANCE_TYPE              DMA_Stream_TypeDef
-#endif /*  defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL)  */
+#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)
+|| defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS) || defined(SOC_SERIES_STM32L1)*/
 
 
-struct dma_config {
-    DMA_INSTANCE_TYPE *Instance;
-    rt_uint32_t dma_rcc;
-    IRQn_Type dma_irq;
+#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
+#define STM32_DMA_USES_CHANNEL
+#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */
 
 
-#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)|| defined(SOC_SERIES_STM32F3)
-    rt_uint32_t channel;
-#endif
+#if defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) || defined(SOC_SERIES_STM32H7RS)
+#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_STM32H7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32L5)
-    rt_uint32_t request;
-#endif
+#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)
+#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)
+#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) */
+
+#if defined(SOC_SERIES_STM32MP1)
+#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)
+#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)
+|| defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32L5)
+|| 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
+#endif /* STM32_DMA_DEFAULT_PRIORITY */
+
+#ifndef STM32_DMA_DEFAULT_PREEMPT_PRIORITY
+#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
+#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
+#endif /* STM32_GPDMA_DEFAULT_BLOCK_HW_REQUEST */
+
+#ifndef STM32_GPDMA_DEFAULT_SRC_BURST_LENGTH
+#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
+#endif /* STM32_GPDMA_DEFAULT_DEST_BURST_LENGTH */
+
+#ifndef STM32_GPDMA_DEFAULT_TRANSFER_ALLOCATED_PORT
+#define STM32_GPDMA_DEFAULT_TRANSFER_ALLOCATED_PORT 0U
+#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
+#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.
+ */
+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. */
+
+#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 */
+
+#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. */
+    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 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),
+#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),
+#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_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),
+#else
+#define STM32_DMA_FIFO_FIELD_DEFAULTS
+#define STM32_DMA_FIFO_FIELD_VALUES(_fifo_mode, _fifo_threshold, _mem_burst, _periph_burst)
+#endif /* defined(STM32_DMA_SUPPORTS_FIFO) */
+
+/**
+ * @brief Generic descriptor initializer with explicit DMA direction and data layout.
+ */
+#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                                                                                                                                                                                   \
+    }
+
+/**
+ * @brief Generic descriptor initializer for controllers that expose FIFO and burst fields.
+ */
+#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)                                                                                                                                                                                          \
+    }
+
+/**
+ * @brief Common byte/word transfer descriptor helpers used by board-level config headers.
+ */
+#define STM32_DMA_RX_BYTE_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_PERIPH_TO_MEMORY, DMA_PINC_DISABLE, DMA_MINC_ENABLE, DMA_PDATAALIGN_BYTE, DMA_MDATAALIGN_BYTE, DMA_NORMAL)
+
+#define STM32_DMA_TX_BYTE_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_BYTE, DMA_MDATAALIGN_BYTE, DMA_NORMAL)
+
+#define STM32_DMA_RX_BYTE_CIRCULAR_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_PERIPH_TO_MEMORY, DMA_PINC_DISABLE, DMA_MINC_ENABLE, DMA_PDATAALIGN_BYTE, DMA_MDATAALIGN_BYTE, DMA_CIRCULAR)
+
+#define STM32_DMA_RX_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_PERIPH_TO_MEMORY, DMA_PINC_DISABLE, DMA_MINC_ENABLE, DMA_PDATAALIGN_WORD, DMA_MDATAALIGN_WORD, DMA_NORMAL)
+
+#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)
+
+/**
+ * @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_RX_BYTE_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_PERIPH_TO_MEMORY, DMA_SINC_FIXED, DMA_DINC_INCREMENTED, DMA_SRC_DATAWIDTH_BYTE, DMA_DEST_DATAWIDTH_BYTE, DMA_NORMAL)
+
+#define STM32_GPDMA_TX_BYTE_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_BYTE, DMA_DEST_DATAWIDTH_BYTE, DMA_NORMAL)
+
+#define STM32_GPDMA_RX_BYTE_CIRCULAR_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_PERIPH_TO_MEMORY, DMA_SINC_FIXED, DMA_DINC_INCREMENTED, DMA_SRC_DATAWIDTH_BYTE, DMA_DEST_DATAWIDTH_BYTE, DMA_CIRCULAR)
+
+#define STM32_GPDMA_RX_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_PERIPH_TO_MEMORY, DMA_SINC_FIXED, DMA_DINC_INCREMENTED, DMA_SRC_DATAWIDTH_WORD, DMA_DEST_DATAWIDTH_WORD, DMA_NORMAL)
+
+#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)
+
+/**
+ * @brief Apply one static DMA descriptor and initialize the HAL DMA handle.
+ * @param dma_handle DMA handle to initialize.
+ * @param dma_config Static DMA endpoint description.
+ * @retval RT_EOK Success.
+ * @retval -RT_ERROR HAL initialization failed.
+ */
+rt_err_t stm32_dma_init(DMA_HandleTypeDef *dma_handle,
+                        const struct stm32_dma_config *dma_config);
+
+/**
+ * @brief Initialize one DMA handle, link it to the parent peripheral and enable its IRQ.
+ * @param dma_handle DMA handle to initialize.
+ * @param parent_handle Parent peripheral HAL handle.
+ * @param dma_slot Parent peripheral DMA slot address, such as &huart->hdmarx.
+ * @param dma_config Static DMA endpoint description.
+ * @retval RT_EOK Success.
+ * @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);
+
+/**
+ * @brief Abort and de-initialize one DMA handle.
+ *
+ * The helper uses IRQ reference counting only for known shared DMA IRQ lines:
+ * STM32F1 DMA2_Channel4_5_IRQn, STM32L0 DMA1_Channel4_5_6_7_IRQn and
+ * STM32G0 DMA1_Channel2_3_IRQn. Other series keep direct IRQ disable behavior.
+ *
+ * @param dma_handle DMA handle to de-initialize.
+ * @param dma_config Static DMA endpoint description.
+ * @param abort_first RT_TRUE aborts the DMA transfer before de-initialization.
+ * @retval RT_EOK Success.
+ * @retval -RT_ERROR HAL abort or 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);
+
+#endif /* HAL_DMA_MODULE_ENABLED */
+
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif
 
 
-#endif /*__DRV_DMA_H_ */
+#endif /* __DRV_DMA_H_ */

+ 47 - 110
bsp/stm32/libraries/HAL_Drivers/drivers/drv_hard_i2c.c

@@ -79,6 +79,29 @@ static void stm32_i2c_apply_default_config(struct stm32_i2c_config *cfg)
     }
     }
 }
 }
 
 
+#if defined(BSP_I2C_RX_USING_DMA) || defined(BSP_I2C_TX_USING_DMA)
+static void stm32_i2c_dma_rollback(struct stm32_i2c *i2c_drv, rt_uint16_t dma_flags)
+{
+#if defined(BSP_I2C_RX_USING_DMA)
+    if ((dma_flags & RT_DEVICE_FLAG_DMA_RX) && (i2c_drv->config->dma_rx != RT_NULL))
+    {
+        (void)stm32_dma_deinit(&i2c_drv->dma.handle_rx, i2c_drv->config->dma_rx, RT_FALSE);
+        i2c_drv->dma.handle_rx.Parent = RT_NULL;
+        i2c_drv->handle.hdmarx = RT_NULL;
+    }
+#endif /* defined(BSP_I2C_RX_USING_DMA) */
+
+#if defined(BSP_I2C_TX_USING_DMA)
+    if ((dma_flags & RT_DEVICE_FLAG_DMA_TX) && (i2c_drv->config->dma_tx != RT_NULL))
+    {
+        (void)stm32_dma_deinit(&i2c_drv->dma.handle_tx, i2c_drv->config->dma_tx, RT_FALSE);
+        i2c_drv->dma.handle_tx.Parent = RT_NULL;
+        i2c_drv->handle.hdmatx = RT_NULL;
+    }
+#endif /* defined(BSP_I2C_TX_USING_DMA) */
+}
+#endif /* defined(BSP_I2C_RX_USING_DMA) || defined(BSP_I2C_TX_USING_DMA) */
+
 static rt_err_t stm32_i2c_init(struct stm32_i2c *i2c_drv)
 static rt_err_t stm32_i2c_init(struct stm32_i2c *i2c_drv)
 {
 {
     RT_ASSERT(i2c_drv != RT_NULL);
     RT_ASSERT(i2c_drv != RT_NULL);
@@ -129,25 +152,27 @@ static rt_err_t stm32_i2c_init(struct stm32_i2c *i2c_drv)
     /* I2C2 DMA Init */
     /* I2C2 DMA Init */
     if (i2c_drv->i2c_dma_flag & RT_DEVICE_FLAG_DMA_RX)
     if (i2c_drv->i2c_dma_flag & RT_DEVICE_FLAG_DMA_RX)
     {
     {
-        HAL_DMA_Init(&i2c_drv->dma.handle_rx);
-
-        __HAL_LINKDMA(&i2c_drv->handle, hdmarx, i2c_drv->dma.handle_rx);
-
-        /* NVIC configuration for DMA transfer complete interrupt */
-        HAL_NVIC_SetPriority(i2c_drv->config->dma_rx->dma_irq, 0, 0);
-        HAL_NVIC_EnableIRQ(i2c_drv->config->dma_rx->dma_irq);
+        if (stm32_dma_setup(&i2c_drv->dma.handle_rx,
+                            &i2c_drv->handle,
+                            &i2c_drv->handle.hdmarx,
+                            i2c_drv->config->dma_rx) != RT_EOK)
+        {
+            stm32_i2c_dma_rollback(i2c_drv, RT_DEVICE_FLAG_DMA_RX);
+            return -RT_EFAULT;
+        }
     }
     }
 #endif /* defined(BSP_I2C_RX_USING_DMA) */
 #endif /* defined(BSP_I2C_RX_USING_DMA) */
 #if defined(BSP_I2C_TX_USING_DMA)
 #if defined(BSP_I2C_TX_USING_DMA)
     if (i2c_drv->i2c_dma_flag & RT_DEVICE_FLAG_DMA_TX)
     if (i2c_drv->i2c_dma_flag & RT_DEVICE_FLAG_DMA_TX)
     {
     {
-        HAL_DMA_Init(&i2c_drv->dma.handle_tx);
-
-        __HAL_LINKDMA(&i2c_drv->handle, hdmatx, i2c_drv->dma.handle_tx);
-
-        /* NVIC configuration for DMA transfer complete interrupt */
-        HAL_NVIC_SetPriority(i2c_drv->config->dma_tx->dma_irq, 1, 0);
-        HAL_NVIC_EnableIRQ(i2c_drv->config->dma_tx->dma_irq);
+        if (stm32_dma_setup(&i2c_drv->dma.handle_tx,
+                            &i2c_drv->handle,
+                            &i2c_drv->handle.hdmatx,
+                            i2c_drv->config->dma_tx) != RT_EOK)
+        {
+            stm32_i2c_dma_rollback(i2c_drv, RT_DEVICE_FLAG_DMA_TX | (i2c_drv->i2c_dma_flag & RT_DEVICE_FLAG_DMA_RX));
+            return -RT_EFAULT;
+        }
     }
     }
 #endif /* defined(BSP_I2C_TX_USING_DMA) */
 #endif /* defined(BSP_I2C_TX_USING_DMA) */
 #if defined(BSP_I2C_USING_IRQ)
 #if defined(BSP_I2C_USING_IRQ)
@@ -533,94 +558,6 @@ int RT_hw_i2c_bus_init(void)
         i2c_objs[i].i2c_bus.config.max_hz = i2c_config[i].timing;
         i2c_objs[i].i2c_bus.config.max_hz = i2c_config[i].timing;
         i2c_objs[i].i2c_bus.config.usage_freq = i2c_config[i].timing;
         i2c_objs[i].i2c_bus.config.usage_freq = i2c_config[i].timing;
 #endif
 #endif
-
-#ifdef BSP_I2C_USING_DMA
-        if ((i2c_objs[i].i2c_dma_flag & RT_DEVICE_FLAG_DMA_RX))
-        {
-            i2c_objs[i].dma.handle_rx.Instance = i2c_config[i].dma_rx->Instance;
-#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
-            i2c_objs[i].dma.handle_rx.Init.Channel = i2c_config[i].dma_rx->channel;
-#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
-            i2c_objs[i].dma.handle_rx.Init.Request = i2c_config[i].dma_rx->request;
-#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */
-#ifndef SOC_SERIES_STM32U5
-            i2c_objs[i].dma.handle_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
-            i2c_objs[i].dma.handle_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
-            i2c_objs[i].dma.handle_rx.Init.MemInc              = DMA_MINC_ENABLE;
-            i2c_objs[i].dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
-            i2c_objs[i].dma.handle_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
-            i2c_objs[i].dma.handle_rx.Init.Mode                = DMA_NORMAL;
-            i2c_objs[i].dma.handle_rx.Init.Priority            = DMA_PRIORITY_LOW;
-#endif
-#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7)
-            i2c_objs[i].dma.handle_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
-            i2c_objs[i].dma.handle_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
-            i2c_objs[i].dma.handle_rx.Init.MemBurst            = DMA_MBURST_INC4;
-            i2c_objs[i].dma.handle_rx.Init.PeriphBurst         = DMA_PBURST_INC4;
-#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) */
-            {
-                rt_uint32_t tmpreg = 0x00U;
-#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0)
-                /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
-                SET_BIT(RCC->AHBENR, i2c_config[i].dma_rx->dma_rcc);
-                tmpreg = READ_BIT(RCC->AHBENR, i2c_config[i].dma_rx->dma_rcc);
-#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
-                SET_BIT(RCC->AHB1ENR, i2c_config[i].dma_rx->dma_rcc);
-                /* Delay after an RCC peripheral clock enabling */
-                tmpreg = READ_BIT(RCC->AHB1ENR, i2c_config[i].dma_rx->dma_rcc);
-#elif defined(SOC_SERIES_STM32MP1)
-                __HAL_RCC_DMAMUX_CLK_ENABLE();
-                SET_BIT(RCC->MP_AHB2ENSETR, i2c_config[i].dma_rx->dma_rcc);
-                tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, i2c_config[i].dma_rx->dma_rcc);
-#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0) */
-                UNUSED(tmpreg); /* To avoid compiler warnings */
-            }
-        }
-
-        if (i2c_objs[i].i2c_dma_flag & RT_DEVICE_FLAG_DMA_TX)
-        {
-            i2c_objs[i].dma.handle_tx.Instance = i2c_config[i].dma_tx->Instance;
-#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
-            i2c_objs[i].dma.handle_tx.Init.Channel = i2c_config[i].dma_tx->channel;
-#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
-            i2c_objs[i].dma.handle_tx.Init.Request = i2c_config[i].dma_tx->request;
-#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */
-#ifndef SOC_SERIES_STM32U5
-            i2c_objs[i].dma.handle_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
-            i2c_objs[i].dma.handle_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
-            i2c_objs[i].dma.handle_tx.Init.MemInc              = DMA_MINC_ENABLE;
-            i2c_objs[i].dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
-            i2c_objs[i].dma.handle_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
-            i2c_objs[i].dma.handle_tx.Init.Mode                = DMA_NORMAL;
-            i2c_objs[i].dma.handle_tx.Init.Priority            = DMA_PRIORITY_LOW;
-#endif /* SOC_SERIES_STM32U5 */
-#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7)
-
-            i2c_objs[i].dma.handle_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
-            i2c_objs[i].dma.handle_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
-            i2c_objs[i].dma.handle_tx.Init.MemBurst = DMA_MBURST_INC4;
-            i2c_objs[i].dma.handle_tx.Init.PeriphBurst = DMA_PBURST_INC4;
-#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) */
-            {
-                rt_uint32_t tmpreg = 0x00U;
-#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0)
-                /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
-                SET_BIT(RCC->AHBENR, i2c_config[i].dma_tx->dma_rcc);
-                tmpreg = READ_BIT(RCC->AHBENR, i2c_config[i].dma_tx->dma_rcc);
-#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
-                SET_BIT(RCC->AHB1ENR, i2c_config[i].dma_tx->dma_rcc);
-                /* Delay after an RCC peripheral clock enabling */
-                tmpreg = READ_BIT(RCC->AHB1ENR, i2c_config[i].dma_tx->dma_rcc);
-#elif defined(SOC_SERIES_STM32MP1)
-                __HAL_RCC_DMAMUX_CLK_ENABLE();
-                SET_BIT(RCC->MP_AHB2ENSETR, i2c_config[i].dma_tx->dma_rcc);
-                tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, i2c_config[i].dma_tx->dma_rcc);
-#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0) */
-                UNUSED(tmpreg); /* To avoid compiler warnings */
-            }
-        }
-
-#endif /* BSP_I2C_USING_DMA */
 #if defined(BSP_I2C_USING_IRQ)
 #if defined(BSP_I2C_USING_IRQ)
         rt_completion_init(&i2c_objs[i].completion);
         rt_completion_init(&i2c_objs[i].completion);
 #endif /* defined(BSP_I2C_USING_IRQ) */
 #endif /* defined(BSP_I2C_USING_IRQ) */
@@ -653,7 +590,7 @@ static void stm32_get_info(void)
 #endif /* defined (BSP_I2C1_TX_USING_INT) */
 #endif /* defined (BSP_I2C1_TX_USING_INT) */
 #if defined(BSP_I2C1_TX_USING_DMA)
 #if defined(BSP_I2C1_TX_USING_DMA)
     i2c_objs[I2C1_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
     i2c_objs[I2C1_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config I2C1_dma_tx = I2C1_TX_DMA_CONFIG;
+    static const struct stm32_dma_config I2C1_dma_tx = I2C1_TX_DMA_CONFIG;
     i2c_config[I2C1_INDEX].dma_tx = &I2C1_dma_tx;
     i2c_config[I2C1_INDEX].dma_tx = &I2C1_dma_tx;
 #endif /* defined (BSP_I2C1_TX_USING_DMA) */
 #endif /* defined (BSP_I2C1_TX_USING_DMA) */
 
 
@@ -662,7 +599,7 @@ static void stm32_get_info(void)
 #endif /* defined (BSP_I2C1_RX_USING_INT) */
 #endif /* defined (BSP_I2C1_RX_USING_INT) */
 #if defined(BSP_I2C1_RX_USING_DMA)
 #if defined(BSP_I2C1_RX_USING_DMA)
     i2c_objs[I2C1_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
     i2c_objs[I2C1_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config I2C1_dma_rx = I2C1_RX_DMA_CONFIG;
+    static const struct stm32_dma_config I2C1_dma_rx = I2C1_RX_DMA_CONFIG;
     i2c_config[I2C1_INDEX].dma_rx = &I2C1_dma_rx;
     i2c_config[I2C1_INDEX].dma_rx = &I2C1_dma_rx;
 #endif /* defined (BSP_I2C1_RX_USING_DMA) */
 #endif /* defined (BSP_I2C1_RX_USING_DMA) */
 
 
@@ -676,7 +613,7 @@ static void stm32_get_info(void)
 #endif /* defined (BSP_I2C2_TX_USING_INT) */
 #endif /* defined (BSP_I2C2_TX_USING_INT) */
 #if defined(BSP_I2C2_TX_USING_DMA)
 #if defined(BSP_I2C2_TX_USING_DMA)
     i2c_objs[I2C2_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
     i2c_objs[I2C2_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config I2C2_dma_tx = I2C2_TX_DMA_CONFIG;
+    static const struct stm32_dma_config I2C2_dma_tx = I2C2_TX_DMA_CONFIG;
     i2c_config[I2C2_INDEX].dma_tx = &I2C2_dma_tx;
     i2c_config[I2C2_INDEX].dma_tx = &I2C2_dma_tx;
 #endif /* defined (BSP_I2C2_TX_USING_DMA) */
 #endif /* defined (BSP_I2C2_TX_USING_DMA) */
 
 
@@ -685,7 +622,7 @@ static void stm32_get_info(void)
 #endif /* defined (BSP_I2C2_RX_USING_INT) */
 #endif /* defined (BSP_I2C2_RX_USING_INT) */
 #if defined(BSP_I2C2_RX_USING_DMA)
 #if defined(BSP_I2C2_RX_USING_DMA)
     i2c_objs[I2C2_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
     i2c_objs[I2C2_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config I2C2_dma_rx = I2C2_RX_DMA_CONFIG;
+    static const struct stm32_dma_config I2C2_dma_rx = I2C2_RX_DMA_CONFIG;
     i2c_config[I2C2_INDEX].dma_rx = &I2C2_dma_rx;
     i2c_config[I2C2_INDEX].dma_rx = &I2C2_dma_rx;
 #endif /* defined (BSP_I2C2_RX_USING_DMA) */
 #endif /* defined (BSP_I2C2_RX_USING_DMA) */
 
 
@@ -699,7 +636,7 @@ static void stm32_get_info(void)
 #endif /* defined (BSP_I2C3_TX_USING_INT) */
 #endif /* defined (BSP_I2C3_TX_USING_INT) */
 #if defined(BSP_I2C3_TX_USING_DMA)
 #if defined(BSP_I2C3_TX_USING_DMA)
     i2c_objs[I2C3_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
     i2c_objs[I2C3_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config I2C3_dma_tx = I2C3_TX_DMA_CONFIG;
+    static const struct stm32_dma_config I2C3_dma_tx = I2C3_TX_DMA_CONFIG;
     i2c_config[I2C3_INDEX].dma_tx = &I2C3_dma_tx;
     i2c_config[I2C3_INDEX].dma_tx = &I2C3_dma_tx;
 #endif /* defined (BSP_I2C3_TX_USING_DMA) */
 #endif /* defined (BSP_I2C3_TX_USING_DMA) */
 
 
@@ -708,7 +645,7 @@ static void stm32_get_info(void)
 #endif /* defined (BSP_I2C3_RX_USING_INT) */
 #endif /* defined (BSP_I2C3_RX_USING_INT) */
 #if defined(BSP_I2C3_RX_USING_DMA)
 #if defined(BSP_I2C3_RX_USING_DMA)
     i2c_objs[I2C3_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
     i2c_objs[I2C3_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config I2C3_dma_rx = I2C3_RX_DMA_CONFIG;
+    static const struct stm32_dma_config I2C3_dma_rx = I2C3_RX_DMA_CONFIG;
     i2c_config[I2C3_INDEX].dma_rx = &I2C3_dma_rx;
     i2c_config[I2C3_INDEX].dma_rx = &I2C3_dma_rx;
 #endif /* defined (BSP_I2C3_RX_USING_DMA) */
 #endif /* defined (BSP_I2C3_RX_USING_DMA) */
 
 
@@ -722,7 +659,7 @@ static void stm32_get_info(void)
 #endif /* defined (BSP_I2C4_TX_USING_INT) */
 #endif /* defined (BSP_I2C4_TX_USING_INT) */
 #if defined(BSP_I2C4_TX_USING_DMA)
 #if defined(BSP_I2C4_TX_USING_DMA)
     i2c_objs[I2C4_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
     i2c_objs[I2C4_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config I2C4_dma_tx = I2C4_TX_DMA_CONFIG;
+    static const struct stm32_dma_config I2C4_dma_tx = I2C4_TX_DMA_CONFIG;
     i2c_config[I2C4_INDEX].dma_tx = &I2C4_dma_tx;
     i2c_config[I2C4_INDEX].dma_tx = &I2C4_dma_tx;
 #endif /* defined (BSP_I2C4_TX_USING_DMA) */
 #endif /* defined (BSP_I2C4_TX_USING_DMA) */
 
 
@@ -731,7 +668,7 @@ static void stm32_get_info(void)
 #endif /* defined (BSP_I2C4_RX_USING_INT) */
 #endif /* defined (BSP_I2C4_RX_USING_INT) */
 #if defined(BSP_I2C4_RX_USING_DMA)
 #if defined(BSP_I2C4_RX_USING_DMA)
     i2c_objs[I2C4_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
     i2c_objs[I2C4_INDEX].i2c_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config I2C4_dma_rx = I2C4_RX_DMA_CONFIG;
+    static const struct stm32_dma_config I2C4_dma_rx = I2C4_RX_DMA_CONFIG;
     i2c_config[I2C4_INDEX].dma_rx = &I2C4_dma_rx;
     i2c_config[I2C4_INDEX].dma_rx = &I2C4_dma_rx;
 #endif /* defined (BSP_I2C4_RX_USING_DMA) */
 #endif /* defined (BSP_I2C4_RX_USING_DMA) */
 
 

+ 2 - 2
bsp/stm32/libraries/HAL_Drivers/drivers/drv_hard_i2c.h

@@ -136,10 +136,10 @@ struct stm32_i2c_config
     IRQn_Type               evirq_type;
     IRQn_Type               evirq_type;
     IRQn_Type               erirq_type;
     IRQn_Type               erirq_type;
 #ifdef BSP_I2C_RX_USING_DMA
 #ifdef BSP_I2C_RX_USING_DMA
-    struct dma_config       *dma_rx;
+    const struct stm32_dma_config *dma_rx;
 #endif /* BSP_I2C_RX_USING_DMA */
 #endif /* BSP_I2C_RX_USING_DMA */
 #ifdef BSP_I2C_TX_USING_DMA
 #ifdef BSP_I2C_TX_USING_DMA
-    struct dma_config       *dma_tx;
+    const struct stm32_dma_config *dma_tx;
 #endif /* BSP_I2C_TX_USING_DMA */
 #endif /* BSP_I2C_TX_USING_DMA */
 };
 };
 
 

+ 7 - 20
bsp/stm32/libraries/HAL_Drivers/drivers/drv_qspi.c

@@ -11,6 +11,7 @@
 
 
 #include "board.h"
 #include "board.h"
 #include "drv_qspi.h"
 #include "drv_qspi.h"
+#include "drv_dma.h"
 #include "drv_config.h"
 #include "drv_config.h"
 
 
 #ifdef RT_USING_QSPI
 #ifdef RT_USING_QSPI
@@ -32,6 +33,9 @@ struct stm32_qspi_bus
 
 
 struct rt_spi_bus _qspi_bus1;
 struct rt_spi_bus _qspi_bus1;
 struct stm32_qspi_bus _stm32_qspi_bus;
 struct stm32_qspi_bus _stm32_qspi_bus;
+#ifdef BSP_QSPI_USING_DMA
+static const struct stm32_dma_config qspi_dma_config = QSPI_DMA_CONFIG;
+#endif
 
 
 static int stm32_qspi_init(struct rt_qspi_device *device, struct rt_qspi_configuration *qspi_cfg)
 static int stm32_qspi_init(struct rt_qspi_device *device, struct rt_qspi_configuration *qspi_cfg)
 {
 {
@@ -92,29 +96,12 @@ static int stm32_qspi_init(struct rt_qspi_device *device, struct rt_qspi_configu
     /* QSPI interrupts must be enabled when using the HAL_QSPI_Receive_DMA */
     /* QSPI interrupts must be enabled when using the HAL_QSPI_Receive_DMA */
     HAL_NVIC_SetPriority(QSPI_IRQn, 0, 0);
     HAL_NVIC_SetPriority(QSPI_IRQn, 0, 0);
     HAL_NVIC_EnableIRQ(QSPI_IRQn);
     HAL_NVIC_EnableIRQ(QSPI_IRQn);
-    HAL_NVIC_SetPriority(QSPI_DMA_IRQ, 0, 0);
-    HAL_NVIC_EnableIRQ(QSPI_DMA_IRQ);
-
     /* init QSPI DMA */
     /* init QSPI DMA */
-    if(QSPI_DMA_RCC  == RCC_AHB1ENR_DMA1EN)
-    {
-        __HAL_RCC_DMA1_CLK_ENABLE();
-    }
-    else
+    if (stm32_dma_setup(&qspi_bus->hdma_quadspi, &qspi_bus->QSPI_Handler, &qspi_bus->QSPI_Handler.hdma, &qspi_dma_config) != RT_EOK)
     {
     {
-        __HAL_RCC_DMA2_CLK_ENABLE();
+        LOG_E("qspi dma init failed");
+        return -RT_ERROR;
     }
     }
-
-    HAL_DMA_DeInit(qspi_bus->QSPI_Handler.hdma);
-    DMA_HandleTypeDef hdma_quadspi_config = QSPI_DMA_CONFIG;
-    qspi_bus->hdma_quadspi = hdma_quadspi_config;
-
-    if (HAL_DMA_Init(&qspi_bus->hdma_quadspi) != HAL_OK)
-    {
-        LOG_E("qspi dma init failed (%d)!", result);
-    }
-
-    __HAL_LINKDMA(&qspi_bus->QSPI_Handler, hdma, qspi_bus->hdma_quadspi);
 #endif /* BSP_QSPI_USING_DMA */
 #endif /* BSP_QSPI_USING_DMA */
 
 
     return result;
     return result;

+ 52 - 134
bsp/stm32/libraries/HAL_Drivers/drivers/drv_sdio.c

@@ -680,133 +680,66 @@ struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des)
 }
 }
 
 
 /**
 /**
-  * @brief  This function configures the DMATX.
-  * @param  BufferSRC: pointer to the source buffer
-  * @param  BufferSize: buffer size
-  * @retval None
+  * @brief  Configure the SDIO DMA TX transfer.
+  * @param  src Pointer to the source buffer.
+  * @param  dst Pointer to the destination address.
+  * @param  BufferSize Number of DMA data units to transfer.
+  * @retval RT_EOK DMA TX transfer is configured and started successfully.
+  * @retval -RT_ERROR DMA TX initialization or start failed.
   */
   */
-void SD_LowLevel_DMA_TxConfig(uint32_t *src, uint32_t *dst, uint32_t BufferSize)
+static rt_err_t SD_LowLevel_DMA_TxConfig(uint32_t *src, uint32_t *dst, uint32_t BufferSize)
 {
 {
-#if defined(SOC_SERIES_STM32F1)
-    static uint32_t size = 0;
-    size += BufferSize * 4;
-    sdio_obj.cfg = &sdio_config;
-    sdio_obj.dma.handle_tx.Instance = sdio_config.dma_tx.Instance;
-    sdio_obj.dma.handle_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
-    sdio_obj.dma.handle_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
-    sdio_obj.dma.handle_tx.Init.MemInc              = DMA_MINC_ENABLE;
-    sdio_obj.dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
-    sdio_obj.dma.handle_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
-    sdio_obj.dma.handle_tx.Init.Priority            = DMA_PRIORITY_MEDIUM;
-    /* DMA_PFCTRL */
-    HAL_DMA_DeInit(&sdio_obj.dma.handle_tx);
-    HAL_DMA_Init(&sdio_obj.dma.handle_tx);
-
-    HAL_DMA_Start(&sdio_obj.dma.handle_tx, (uint32_t)src, (uint32_t)dst, BufferSize);
-
-#elif defined(SOC_SERIES_STM32L4)
-    static uint32_t size = 0;
-    size += BufferSize * 4;
     sdio_obj.cfg = &sdio_config;
     sdio_obj.cfg = &sdio_config;
-    sdio_obj.dma.handle_tx.Instance = sdio_config.dma_tx.Instance;
-    sdio_obj.dma.handle_tx.Init.Request             = sdio_config.dma_tx.request;
-    sdio_obj.dma.handle_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
-    sdio_obj.dma.handle_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
-    sdio_obj.dma.handle_tx.Init.MemInc              = DMA_MINC_ENABLE;
-    sdio_obj.dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
-    sdio_obj.dma.handle_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
-    sdio_obj.dma.handle_tx.Init.Mode                = DMA_NORMAL;
-    sdio_obj.dma.handle_tx.Init.Priority            = DMA_PRIORITY_MEDIUM;
-
-    HAL_DMA_DeInit(&sdio_obj.dma.handle_tx);
-    HAL_DMA_Init(&sdio_obj.dma.handle_tx);
-
-    HAL_DMA_Start(&sdio_obj.dma.handle_tx, (uint32_t)src, (uint32_t)dst, BufferSize);
-#else
-    static uint32_t size = 0;
-    size += BufferSize * 4;
-    sdio_obj.cfg = &sdio_config;
-    sdio_obj.dma.handle_tx.Instance = sdio_config.dma_tx.Instance;
-    sdio_obj.dma.handle_tx.Init.Channel = sdio_config.dma_tx.channel;
-    sdio_obj.dma.handle_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
-    sdio_obj.dma.handle_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
-    sdio_obj.dma.handle_tx.Init.MemInc              = DMA_MINC_ENABLE;
-    sdio_obj.dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
-    sdio_obj.dma.handle_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
-    sdio_obj.dma.handle_tx.Init.Mode                = DMA_PFCTRL;
-    sdio_obj.dma.handle_tx.Init.Priority            = DMA_PRIORITY_MEDIUM;
-    sdio_obj.dma.handle_tx.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
-    sdio_obj.dma.handle_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
-    sdio_obj.dma.handle_tx.Init.MemBurst            = DMA_MBURST_INC4;
-    sdio_obj.dma.handle_tx.Init.PeriphBurst         = DMA_PBURST_INC4;
-    /* DMA_PFCTRL */
-    HAL_DMA_DeInit(&sdio_obj.dma.handle_tx);
-    HAL_DMA_Init(&sdio_obj.dma.handle_tx);
-
-    HAL_DMA_Start(&sdio_obj.dma.handle_tx, (uint32_t)src, (uint32_t)dst, BufferSize);
-#endif
+
+    if (stm32_dma_init(&sdio_obj.dma.handle_tx, &sdio_config.dma_tx) != RT_EOK)
+    {
+        LOG_E("sdio dma tx init failed");
+        return -RT_ERROR;
+    }
+
+    if (HAL_DMA_Start(&sdio_obj.dma.handle_tx, (uint32_t)src, (uint32_t)dst, BufferSize) != HAL_OK)
+    {
+        LOG_E("sdio dma tx start failed");
+        if (stm32_dma_deinit(&sdio_obj.dma.handle_tx, &sdio_config.dma_tx, RT_FALSE) != RT_EOK)
+        {
+            LOG_E("sdio dma tx rollback failed");
+        }
+        return -RT_ERROR;
+    }
+
+    return RT_EOK;
 }
 }
 
 
 /**
 /**
-  * @brief  This function configures the DMARX.
-  * @param  BufferDST: pointer to the destination buffer
-  * @param  BufferSize: buffer size
-  * @retval None
+  * @brief  Configure the SDIO DMA RX transfer.
+  * @param  src Pointer to the source address.
+  * @param  dst Pointer to the destination buffer.
+  * @param  BufferSize Number of DMA data units to transfer.
+  * @retval RT_EOK DMA RX transfer is configured and started successfully.
+  * @retval -RT_ERROR DMA RX initialization or start failed.
   */
   */
-void SD_LowLevel_DMA_RxConfig(uint32_t *src, uint32_t *dst, uint32_t BufferSize)
+static rt_err_t SD_LowLevel_DMA_RxConfig(uint32_t *src, uint32_t *dst, uint32_t BufferSize)
+static rt_err_t SD_LowLevel_DMA_RxConfig(uint32_t *src, uint32_t *dst, uint32_t BufferSize)
 {
 {
-#if defined(SOC_SERIES_STM32F1)
-    sdio_obj.cfg = &sdio_config;
-    sdio_obj.dma.handle_rx.Instance = sdio_config.dma_tx.Instance;
-    sdio_obj.dma.handle_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
-    sdio_obj.dma.handle_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
-    sdio_obj.dma.handle_rx.Init.MemInc              = DMA_MINC_ENABLE;
-    sdio_obj.dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
-    sdio_obj.dma.handle_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
-    sdio_obj.dma.handle_rx.Init.Priority            = DMA_PRIORITY_MEDIUM;
-
-    HAL_DMA_DeInit(&sdio_obj.dma.handle_rx);
-    HAL_DMA_Init(&sdio_obj.dma.handle_rx);
-
-    HAL_DMA_Start(&sdio_obj.dma.handle_rx, (uint32_t)src, (uint32_t)dst, BufferSize);
-#elif defined(SOC_SERIES_STM32L4)
     sdio_obj.cfg = &sdio_config;
     sdio_obj.cfg = &sdio_config;
-    sdio_obj.dma.handle_rx.Instance = sdio_config.dma_tx.Instance;
-    sdio_obj.dma.handle_rx.Init.Request             = sdio_config.dma_tx.request;
-    sdio_obj.dma.handle_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
-    sdio_obj.dma.handle_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
-    sdio_obj.dma.handle_rx.Init.MemInc              = DMA_MINC_ENABLE;
-    sdio_obj.dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
-    sdio_obj.dma.handle_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
-    sdio_obj.dma.handle_rx.Init.Mode                = DMA_NORMAL;
-    sdio_obj.dma.handle_rx.Init.Priority            = DMA_PRIORITY_LOW;
-
-    HAL_DMA_DeInit(&sdio_obj.dma.handle_rx);
-    HAL_DMA_Init(&sdio_obj.dma.handle_rx);
-
-    HAL_DMA_Start(&sdio_obj.dma.handle_rx, (uint32_t)src, (uint32_t)dst, BufferSize);
-#else
-    sdio_obj.cfg = &sdio_config;
-    sdio_obj.dma.handle_rx.Instance = sdio_config.dma_tx.Instance;
-    sdio_obj.dma.handle_rx.Init.Channel = sdio_config.dma_tx.channel;
-    sdio_obj.dma.handle_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
-    sdio_obj.dma.handle_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
-    sdio_obj.dma.handle_rx.Init.MemInc              = DMA_MINC_ENABLE;
-    sdio_obj.dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
-    sdio_obj.dma.handle_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
-    sdio_obj.dma.handle_rx.Init.Mode                = DMA_PFCTRL;
-    sdio_obj.dma.handle_rx.Init.Priority            = DMA_PRIORITY_MEDIUM;
-    sdio_obj.dma.handle_rx.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
-    sdio_obj.dma.handle_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
-    sdio_obj.dma.handle_rx.Init.MemBurst            = DMA_MBURST_INC4;
-    sdio_obj.dma.handle_rx.Init.PeriphBurst         = DMA_PBURST_INC4;
-
-    HAL_DMA_DeInit(&sdio_obj.dma.handle_rx);
-    HAL_DMA_Init(&sdio_obj.dma.handle_rx);
-
-    HAL_DMA_Start(&sdio_obj.dma.handle_rx, (uint32_t)src, (uint32_t)dst, BufferSize);
-#endif
 
 
+    if (stm32_dma_init(&sdio_obj.dma.handle_rx, &sdio_config.dma_rx) != RT_EOK)
+    {
+        LOG_E("sdio dma rx init failed");
+        return -RT_ERROR;
+    }
+
+    if (HAL_DMA_Start(&sdio_obj.dma.handle_rx, (uint32_t)src, (uint32_t)dst, BufferSize) != HAL_OK)
+    {
+        LOG_E("sdio dma rx start failed");
+        if (stm32_dma_deinit(&sdio_obj.dma.handle_rx, &sdio_config.dma_rx, RT_FALSE) != RT_EOK)
+        {
+            LOG_E("sdio dma rx rollback failed");
+        }
+        return -RT_ERROR;
+    }
+
+    return RT_EOK;
 }
 }
 
 
 /**
 /**
@@ -821,14 +754,12 @@ static rt_uint32_t stm32_sdio_clock_get(struct stm32_sdio *hw_sdio)
 
 
 static rt_err_t DMA_TxConfig(rt_uint32_t *src, rt_uint32_t *dst, int Size)
 static rt_err_t DMA_TxConfig(rt_uint32_t *src, rt_uint32_t *dst, int Size)
 {
 {
-    SD_LowLevel_DMA_TxConfig((uint32_t *)src, (uint32_t *)dst, Size / 4);
-    return RT_EOK;
+    return SD_LowLevel_DMA_TxConfig((uint32_t *)src, (uint32_t *)dst, Size / 4);
 }
 }
 
 
 static rt_err_t DMA_RxConfig(rt_uint32_t *src, rt_uint32_t *dst, int Size)
 static rt_err_t DMA_RxConfig(rt_uint32_t *src, rt_uint32_t *dst, int Size)
 {
 {
-    SD_LowLevel_DMA_RxConfig((uint32_t *)src, (uint32_t *)dst, Size / 4);
-    return RT_EOK;
+    return SD_LowLevel_DMA_RxConfig((uint32_t *)src, (uint32_t *)dst, Size / 4);
 }
 }
 
 
 void SDIO_IRQHandler(void)
 void SDIO_IRQHandler(void)
@@ -847,19 +778,6 @@ int rt_hw_sdio_init(void)
     struct stm32_sdio_des sdio_des;
     struct stm32_sdio_des sdio_des;
     SD_HandleTypeDef hsd;
     SD_HandleTypeDef hsd;
     hsd.Instance = SDCARD_INSTANCE;
     hsd.Instance = SDCARD_INSTANCE;
-    {
-        rt_uint32_t tmpreg = 0x00U;
-#if defined(SOC_SERIES_STM32F1)
-        /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
-        SET_BIT(RCC->AHBENR, sdio_config.dma_rx.dma_rcc);
-        tmpreg = READ_BIT(RCC->AHBENR, sdio_config.dma_rx.dma_rcc);
-#elif defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F2)
-        SET_BIT(RCC->AHB1ENR, sdio_config.dma_rx.dma_rcc);
-        /* Delay after an RCC peripheral clock enabling */
-        tmpreg = READ_BIT(RCC->AHB1ENR, sdio_config.dma_rx.dma_rcc);
-#endif
-        UNUSED(tmpreg); /* To avoid compiler warnings */
-    }
     HAL_NVIC_SetPriority(SDIO_IRQn, 2, 0);
     HAL_NVIC_SetPriority(SDIO_IRQn, 2, 0);
     HAL_NVIC_EnableIRQ(SDIO_IRQn);
     HAL_NVIC_EnableIRQ(SDIO_IRQn);
     HAL_SD_MspInit(&hsd);
     HAL_SD_MspInit(&hsd);

+ 2 - 2
bsp/stm32/libraries/HAL_Drivers/drivers/drv_sdio.h

@@ -77,7 +77,7 @@
 #define HW_SDIO_IT_RXDAVL                      (0x01U << 21)
 #define HW_SDIO_IT_RXDAVL                      (0x01U << 21)
 #define HW_SDIO_IT_SDIOIT                      (0x01U << 22)
 #define HW_SDIO_IT_SDIOIT                      (0x01U << 22)
 
 
-#define HW_SDIO_ERRORS \
+#define HW_SDIO_ERRORS                           \
     (HW_SDIO_IT_CCRCFAIL | HW_SDIO_IT_CTIMEOUT | \
     (HW_SDIO_IT_CCRCFAIL | HW_SDIO_IT_CTIMEOUT | \
      HW_SDIO_IT_DCRCFAIL | HW_SDIO_IT_DTIMEOUT | \
      HW_SDIO_IT_DCRCFAIL | HW_SDIO_IT_DTIMEOUT | \
      HW_SDIO_IT_RXOVERR  | HW_SDIO_IT_TXUNDERR)
      HW_SDIO_IT_RXOVERR  | HW_SDIO_IT_TXUNDERR)
@@ -169,7 +169,7 @@ struct stm32_sdio_des
 struct stm32_sdio_config
 struct stm32_sdio_config
 {
 {
     SDCARD_INSTANCE_TYPE *Instance;
     SDCARD_INSTANCE_TYPE *Instance;
-    struct dma_config dma_rx, dma_tx;
+    struct stm32_dma_config dma_rx, dma_tx;
 };
 };
 
 
 /* stm32 sdio dirver class */
 /* stm32 sdio dirver class */

+ 45 - 114
bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c

@@ -81,6 +81,23 @@ static struct stm32_spi_config 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};
 
 
+static void stm32_spi_dma_rollback(struct stm32_spi *spi_drv, rt_uint16_t dma_flags)
+{
+    if ((dma_flags & SPI_USING_RX_DMA_FLAG) && (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;
+    }
+
+    if ((dma_flags & SPI_USING_TX_DMA_FLAG) && (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;
+    }
+}
+
 static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configuration *cfg)
 static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configuration *cfg)
 {
 {
     RT_ASSERT(spi_drv != RT_NULL);
     RT_ASSERT(spi_drv != RT_NULL);
@@ -255,24 +272,26 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur
     /* DMA configuration */
     /* DMA configuration */
     if (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG)
     if (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG)
     {
     {
-        HAL_DMA_Init(&spi_drv->dma.handle_rx);
-
-        __HAL_LINKDMA(&spi_drv->handle, hdmarx, spi_drv->dma.handle_rx);
-
-        /* NVIC configuration for DMA transfer complete interrupt */
-        HAL_NVIC_SetPriority(spi_drv->config->dma_rx->dma_irq, 0, 0);
-        HAL_NVIC_EnableIRQ(spi_drv->config->dma_rx->dma_irq);
+        if (stm32_dma_setup(&spi_drv->dma.handle_rx,
+                            &spi_drv->handle,
+                            &spi_drv->handle.hdmarx,
+                            spi_drv->config->dma_rx) != RT_EOK)
+        {
+            stm32_spi_dma_rollback(spi_drv, SPI_USING_RX_DMA_FLAG);
+            return -RT_EIO;
+        }
     }
     }
 
 
     if (spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG)
     if (spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG)
     {
     {
-        HAL_DMA_Init(&spi_drv->dma.handle_tx);
-
-        __HAL_LINKDMA(&spi_drv->handle, hdmatx, spi_drv->dma.handle_tx);
-
-        /* NVIC configuration for DMA transfer complete interrupt */
-        HAL_NVIC_SetPriority(spi_drv->config->dma_tx->dma_irq, 1, 0);
-        HAL_NVIC_EnableIRQ(spi_drv->config->dma_tx->dma_irq);
+        if (stm32_dma_setup(&spi_drv->dma.handle_tx,
+                            &spi_drv->handle,
+                            &spi_drv->handle.hdmatx,
+                            spi_drv->config->dma_tx) != RT_EOK)
+        {
+            stm32_spi_dma_rollback(spi_drv, SPI_USING_TX_DMA_FLAG | (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG));
+            return -RT_EIO;
+        }
     }
     }
 
 
     if(spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG || spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG)
     if(spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG || spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG)
@@ -565,94 +584,6 @@ static int rt_hw_spi_bus_init(void)
         spi_bus_obj[i].spi_bus.parent.user_data = &spi_config[i];
         spi_bus_obj[i].spi_bus.parent.user_data = &spi_config[i];
         spi_bus_obj[i].handle.Instance = spi_config[i].Instance;
         spi_bus_obj[i].handle.Instance = spi_config[i].Instance;
 
 
-        if (spi_bus_obj[i].spi_dma_flag & SPI_USING_RX_DMA_FLAG)
-        {
-            /* Configure the DMA handler for Transmission process */
-            spi_bus_obj[i].dma.handle_rx.Instance = spi_config[i].dma_rx->Instance;
-#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
-            spi_bus_obj[i].dma.handle_rx.Init.Channel = spi_config[i].dma_rx->channel;
-#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
-            spi_bus_obj[i].dma.handle_rx.Init.Request = spi_config[i].dma_rx->request;
-#endif
-#ifndef SOC_SERIES_STM32U5
-            spi_bus_obj[i].dma.handle_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
-            spi_bus_obj[i].dma.handle_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
-            spi_bus_obj[i].dma.handle_rx.Init.MemInc              = DMA_MINC_ENABLE;
-            spi_bus_obj[i].dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
-            spi_bus_obj[i].dma.handle_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
-            spi_bus_obj[i].dma.handle_rx.Init.Mode                = DMA_NORMAL;
-            spi_bus_obj[i].dma.handle_rx.Init.Priority            = DMA_PRIORITY_HIGH;
-#endif
-#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7)
-            spi_bus_obj[i].dma.handle_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
-            spi_bus_obj[i].dma.handle_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
-            spi_bus_obj[i].dma.handle_rx.Init.MemBurst            = DMA_MBURST_INC4;
-            spi_bus_obj[i].dma.handle_rx.Init.PeriphBurst         = DMA_PBURST_INC4;
-#endif
-
-            {
-                rt_uint32_t tmpreg = 0x00U;
-#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0)
-                /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
-                SET_BIT(RCC->AHBENR, spi_config[i].dma_rx->dma_rcc);
-                tmpreg = READ_BIT(RCC->AHBENR, spi_config[i].dma_rx->dma_rcc);
-#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
-                SET_BIT(RCC->AHB1ENR, spi_config[i].dma_rx->dma_rcc);
-                /* Delay after an RCC peripheral clock enabling */
-                tmpreg = READ_BIT(RCC->AHB1ENR, spi_config[i].dma_rx->dma_rcc);
-#elif defined(SOC_SERIES_STM32MP1)
-                __HAL_RCC_DMAMUX_CLK_ENABLE();
-                SET_BIT(RCC->MP_AHB2ENSETR, spi_config[i].dma_rx->dma_rcc);
-                tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, spi_config[i].dma_rx->dma_rcc);
-#endif
-                UNUSED(tmpreg); /* To avoid compiler warnings */
-            }
-        }
-
-        if (spi_bus_obj[i].spi_dma_flag & SPI_USING_TX_DMA_FLAG)
-        {
-            /* Configure the DMA handler for Transmission process */
-            spi_bus_obj[i].dma.handle_tx.Instance = spi_config[i].dma_tx->Instance;
-#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
-            spi_bus_obj[i].dma.handle_tx.Init.Channel = spi_config[i].dma_tx->channel;
-#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
-            spi_bus_obj[i].dma.handle_tx.Init.Request = spi_config[i].dma_tx->request;
-#endif
-#ifndef SOC_SERIES_STM32U5
-            spi_bus_obj[i].dma.handle_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
-            spi_bus_obj[i].dma.handle_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
-            spi_bus_obj[i].dma.handle_tx.Init.MemInc              = DMA_MINC_ENABLE;
-            spi_bus_obj[i].dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
-            spi_bus_obj[i].dma.handle_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
-            spi_bus_obj[i].dma.handle_tx.Init.Mode                = DMA_NORMAL;
-            spi_bus_obj[i].dma.handle_tx.Init.Priority            = DMA_PRIORITY_LOW;
-#endif
-#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7)
-            spi_bus_obj[i].dma.handle_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
-            spi_bus_obj[i].dma.handle_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
-            spi_bus_obj[i].dma.handle_tx.Init.MemBurst            = DMA_MBURST_INC4;
-            spi_bus_obj[i].dma.handle_tx.Init.PeriphBurst         = DMA_PBURST_INC4;
-#endif
-
-            {
-                rt_uint32_t tmpreg = 0x00U;
-#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0)
-                /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
-                SET_BIT(RCC->AHBENR, spi_config[i].dma_tx->dma_rcc);
-                tmpreg = READ_BIT(RCC->AHBENR, spi_config[i].dma_tx->dma_rcc);
-#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7)
-                SET_BIT(RCC->AHB1ENR, spi_config[i].dma_tx->dma_rcc);
-                /* Delay after an RCC peripheral clock enabling */
-                tmpreg = READ_BIT(RCC->AHB1ENR, spi_config[i].dma_tx->dma_rcc);
-#elif defined(SOC_SERIES_STM32MP1)
-                __HAL_RCC_DMAMUX_CLK_ENABLE();
-                SET_BIT(RCC->MP_AHB2ENSETR, spi_config[i].dma_tx->dma_rcc);
-                tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, spi_config[i].dma_tx->dma_rcc);
-#endif
-                UNUSED(tmpreg); /* To avoid compiler warnings */
-            }
-        }
-
         /* initialize completion object */
         /* initialize completion object */
         rt_completion_init(&spi_bus_obj[i].cpt);
         rt_completion_init(&spi_bus_obj[i].cpt);
 
 
@@ -1019,67 +950,67 @@ static void stm32_get_dma_info(void)
 {
 {
 #ifdef BSP_SPI1_RX_USING_DMA
 #ifdef BSP_SPI1_RX_USING_DMA
     spi_bus_obj[SPI1_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
     spi_bus_obj[SPI1_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
-    static struct dma_config spi1_dma_rx = SPI1_RX_DMA_CONFIG;
+    static const struct stm32_dma_config spi1_dma_rx = SPI1_RX_DMA_CONFIG;
     spi_config[SPI1_INDEX].dma_rx = &spi1_dma_rx;
     spi_config[SPI1_INDEX].dma_rx = &spi1_dma_rx;
 #endif
 #endif
 #ifdef BSP_SPI1_TX_USING_DMA
 #ifdef BSP_SPI1_TX_USING_DMA
     spi_bus_obj[SPI1_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
     spi_bus_obj[SPI1_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
-    static struct dma_config spi1_dma_tx = SPI1_TX_DMA_CONFIG;
+    static const struct stm32_dma_config spi1_dma_tx = SPI1_TX_DMA_CONFIG;
     spi_config[SPI1_INDEX].dma_tx = &spi1_dma_tx;
     spi_config[SPI1_INDEX].dma_tx = &spi1_dma_tx;
 #endif
 #endif
 
 
 #ifdef BSP_SPI2_RX_USING_DMA
 #ifdef BSP_SPI2_RX_USING_DMA
     spi_bus_obj[SPI2_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
     spi_bus_obj[SPI2_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
-    static struct dma_config spi2_dma_rx = SPI2_RX_DMA_CONFIG;
+    static const struct stm32_dma_config spi2_dma_rx = SPI2_RX_DMA_CONFIG;
     spi_config[SPI2_INDEX].dma_rx = &spi2_dma_rx;
     spi_config[SPI2_INDEX].dma_rx = &spi2_dma_rx;
 #endif
 #endif
 #ifdef BSP_SPI2_TX_USING_DMA
 #ifdef BSP_SPI2_TX_USING_DMA
     spi_bus_obj[SPI2_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
     spi_bus_obj[SPI2_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
-    static struct dma_config spi2_dma_tx = SPI2_TX_DMA_CONFIG;
+    static const struct stm32_dma_config spi2_dma_tx = SPI2_TX_DMA_CONFIG;
     spi_config[SPI2_INDEX].dma_tx = &spi2_dma_tx;
     spi_config[SPI2_INDEX].dma_tx = &spi2_dma_tx;
 #endif
 #endif
 
 
 #ifdef BSP_SPI3_RX_USING_DMA
 #ifdef BSP_SPI3_RX_USING_DMA
     spi_bus_obj[SPI3_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
     spi_bus_obj[SPI3_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
-    static struct dma_config spi3_dma_rx = SPI3_RX_DMA_CONFIG;
+    static const struct stm32_dma_config spi3_dma_rx = SPI3_RX_DMA_CONFIG;
     spi_config[SPI3_INDEX].dma_rx = &spi3_dma_rx;
     spi_config[SPI3_INDEX].dma_rx = &spi3_dma_rx;
 #endif
 #endif
 #ifdef BSP_SPI3_TX_USING_DMA
 #ifdef BSP_SPI3_TX_USING_DMA
     spi_bus_obj[SPI3_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
     spi_bus_obj[SPI3_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
-    static struct dma_config spi3_dma_tx = SPI3_TX_DMA_CONFIG;
+    static const struct stm32_dma_config spi3_dma_tx = SPI3_TX_DMA_CONFIG;
     spi_config[SPI3_INDEX].dma_tx = &spi3_dma_tx;
     spi_config[SPI3_INDEX].dma_tx = &spi3_dma_tx;
 #endif
 #endif
 
 
 #ifdef BSP_SPI4_RX_USING_DMA
 #ifdef BSP_SPI4_RX_USING_DMA
     spi_bus_obj[SPI4_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
     spi_bus_obj[SPI4_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
-    static struct dma_config spi4_dma_rx = SPI4_RX_DMA_CONFIG;
+    static const struct stm32_dma_config spi4_dma_rx = SPI4_RX_DMA_CONFIG;
     spi_config[SPI4_INDEX].dma_rx = &spi4_dma_rx;
     spi_config[SPI4_INDEX].dma_rx = &spi4_dma_rx;
 #endif
 #endif
 #ifdef BSP_SPI4_TX_USING_DMA
 #ifdef BSP_SPI4_TX_USING_DMA
     spi_bus_obj[SPI4_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
     spi_bus_obj[SPI4_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
-    static struct dma_config spi4_dma_tx = SPI4_TX_DMA_CONFIG;
+    static const struct stm32_dma_config spi4_dma_tx = SPI4_TX_DMA_CONFIG;
     spi_config[SPI4_INDEX].dma_tx = &spi4_dma_tx;
     spi_config[SPI4_INDEX].dma_tx = &spi4_dma_tx;
 #endif
 #endif
 
 
 #ifdef BSP_SPI5_RX_USING_DMA
 #ifdef BSP_SPI5_RX_USING_DMA
     spi_bus_obj[SPI5_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
     spi_bus_obj[SPI5_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
-    static struct dma_config spi5_dma_rx = SPI5_RX_DMA_CONFIG;
+    static const struct stm32_dma_config spi5_dma_rx = SPI5_RX_DMA_CONFIG;
     spi_config[SPI5_INDEX].dma_rx = &spi5_dma_rx;
     spi_config[SPI5_INDEX].dma_rx = &spi5_dma_rx;
 #endif
 #endif
 #ifdef BSP_SPI5_TX_USING_DMA
 #ifdef BSP_SPI5_TX_USING_DMA
     spi_bus_obj[SPI5_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
     spi_bus_obj[SPI5_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
-    static struct dma_config spi5_dma_tx = SPI5_TX_DMA_CONFIG;
+    static const struct stm32_dma_config spi5_dma_tx = SPI5_TX_DMA_CONFIG;
     spi_config[SPI5_INDEX].dma_tx = &spi5_dma_tx;
     spi_config[SPI5_INDEX].dma_tx = &spi5_dma_tx;
 #endif
 #endif
 
 
 #ifdef BSP_SPI6_RX_USING_DMA
 #ifdef BSP_SPI6_RX_USING_DMA
     spi_bus_obj[SPI6_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
     spi_bus_obj[SPI6_INDEX].spi_dma_flag |= SPI_USING_RX_DMA_FLAG;
-    static struct dma_config spi6_dma_rx = SPI6_RX_DMA_CONFIG;
+    static const struct stm32_dma_config spi6_dma_rx = SPI6_RX_DMA_CONFIG;
     spi_config[SPI6_INDEX].dma_rx = &spi6_dma_rx;
     spi_config[SPI6_INDEX].dma_rx = &spi6_dma_rx;
 #endif
 #endif
 #ifdef BSP_SPI6_TX_USING_DMA
 #ifdef BSP_SPI6_TX_USING_DMA
     spi_bus_obj[SPI6_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
     spi_bus_obj[SPI6_INDEX].spi_dma_flag |= SPI_USING_TX_DMA_FLAG;
-    static struct dma_config spi6_dma_tx = SPI6_TX_DMA_CONFIG;
+    static const struct stm32_dma_config spi6_dma_tx = SPI6_TX_DMA_CONFIG;
     spi_config[SPI6_INDEX].dma_tx = &spi6_dma_tx;
     spi_config[SPI6_INDEX].dma_tx = &spi6_dma_tx;
 #endif
 #endif
 }
 }

+ 1 - 1
bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h

@@ -34,7 +34,7 @@ struct stm32_spi_config
     SPI_TypeDef *Instance;
     SPI_TypeDef *Instance;
     char *bus_name;
     char *bus_name;
     IRQn_Type irq_type;
     IRQn_Type irq_type;
-    struct dma_config *dma_rx, *dma_tx;
+    const struct stm32_dma_config *dma_rx, *dma_tx;
 };
 };
 
 
 struct stm32_spi_device
 struct stm32_spi_device

+ 52 - 109
bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart.c

@@ -31,7 +31,7 @@
 #endif
 #endif
 
 
 #ifdef RT_SERIAL_USING_DMA
 #ifdef RT_SERIAL_USING_DMA
-static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag);
+static rt_err_t stm32_uart_dma_config(struct rt_serial_device *serial, rt_ubase_t flag);
 #endif
 #endif
 
 
 enum
 enum
@@ -262,23 +262,16 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar
         /* disable DMA */
         /* disable DMA */
         if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX)
         if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX)
         {
         {
-            HAL_NVIC_DisableIRQ(uart->config->dma_rx->dma_irq);
-            if (HAL_DMA_Abort(&(uart->dma_rx.handle)) != HAL_OK)
+            if (stm32_dma_deinit(&(uart->dma_rx.handle), uart->config->dma_rx, RT_TRUE) != RT_EOK)
             {
             {
-                RT_ASSERT(0);
-            }
-
-            if (HAL_DMA_DeInit(&(uart->dma_rx.handle)) != HAL_OK)
-            {
-                RT_ASSERT(0);
+                LOG_E("%s dma rx deinit failed", uart->config->name);
             }
             }
         }
         }
         else if(ctrl_arg == RT_DEVICE_FLAG_DMA_TX)
         else if(ctrl_arg == RT_DEVICE_FLAG_DMA_TX)
         {
         {
-            HAL_NVIC_DisableIRQ(uart->config->dma_tx->dma_irq);
-            if (HAL_DMA_DeInit(&(uart->dma_tx.handle)) != HAL_OK)
+            if (stm32_dma_deinit(&(uart->dma_tx.handle), uart->config->dma_tx, RT_FALSE) != RT_EOK)
             {
             {
-                RT_ASSERT(0);
+                LOG_E("%s dma tx deinit failed", uart->config->name);
             }
             }
         }
         }
 #endif
 #endif
@@ -303,8 +296,7 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar
 #ifdef RT_SERIAL_USING_DMA
 #ifdef RT_SERIAL_USING_DMA
     case RT_DEVICE_CTRL_CONFIG:
     case RT_DEVICE_CTRL_CONFIG:
     {
     {
-        stm32_dma_config(serial, ctrl_arg);
-        break;
+        return stm32_uart_dma_config(serial, ctrl_arg);
     }
     }
 #endif
 #endif
 
 
@@ -312,7 +304,7 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar
     {
     {
         if (HAL_UART_DeInit(&(uart->handle)) != HAL_OK )
         if (HAL_UART_DeInit(&(uart->handle)) != HAL_OK )
         {
         {
-            RT_ASSERT(0)
+            LOG_E("%s uart deinit failed", uart->config->name);
         }
         }
         break;
         break;
     }
     }
@@ -927,12 +919,12 @@ static void stm32_uart_get_dma_config(void)
     uart_obj[UART1_INDEX].uart_dma_flag = 0;
     uart_obj[UART1_INDEX].uart_dma_flag = 0;
 #ifdef BSP_UART1_RX_USING_DMA
 #ifdef BSP_UART1_RX_USING_DMA
     uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
     uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart1_dma_rx = UART1_DMA_RX_CONFIG;
+    static const struct stm32_dma_config uart1_dma_rx = UART1_DMA_RX_CONFIG;
     uart_config[UART1_INDEX].dma_rx = &uart1_dma_rx;
     uart_config[UART1_INDEX].dma_rx = &uart1_dma_rx;
 #endif
 #endif
 #ifdef BSP_UART1_TX_USING_DMA
 #ifdef BSP_UART1_TX_USING_DMA
     uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
     uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart1_dma_tx = UART1_DMA_TX_CONFIG;
+    static const struct stm32_dma_config uart1_dma_tx = UART1_DMA_TX_CONFIG;
     uart_config[UART1_INDEX].dma_tx = &uart1_dma_tx;
     uart_config[UART1_INDEX].dma_tx = &uart1_dma_tx;
 #endif
 #endif
 #endif
 #endif
@@ -941,12 +933,12 @@ static void stm32_uart_get_dma_config(void)
     uart_obj[UART2_INDEX].uart_dma_flag = 0;
     uart_obj[UART2_INDEX].uart_dma_flag = 0;
 #ifdef BSP_UART2_RX_USING_DMA
 #ifdef BSP_UART2_RX_USING_DMA
     uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
     uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart2_dma_rx = UART2_DMA_RX_CONFIG;
+    static const struct stm32_dma_config uart2_dma_rx = UART2_DMA_RX_CONFIG;
     uart_config[UART2_INDEX].dma_rx = &uart2_dma_rx;
     uart_config[UART2_INDEX].dma_rx = &uart2_dma_rx;
 #endif
 #endif
 #ifdef BSP_UART2_TX_USING_DMA
 #ifdef BSP_UART2_TX_USING_DMA
     uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
     uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart2_dma_tx = UART2_DMA_TX_CONFIG;
+    static const struct stm32_dma_config uart2_dma_tx = UART2_DMA_TX_CONFIG;
     uart_config[UART2_INDEX].dma_tx = &uart2_dma_tx;
     uart_config[UART2_INDEX].dma_tx = &uart2_dma_tx;
 #endif
 #endif
 #endif
 #endif
@@ -955,12 +947,12 @@ static void stm32_uart_get_dma_config(void)
     uart_obj[UART3_INDEX].uart_dma_flag = 0;
     uart_obj[UART3_INDEX].uart_dma_flag = 0;
 #ifdef BSP_UART3_RX_USING_DMA
 #ifdef BSP_UART3_RX_USING_DMA
     uart_obj[UART3_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
     uart_obj[UART3_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart3_dma_rx = UART3_DMA_RX_CONFIG;
+    static const struct stm32_dma_config uart3_dma_rx = UART3_DMA_RX_CONFIG;
     uart_config[UART3_INDEX].dma_rx = &uart3_dma_rx;
     uart_config[UART3_INDEX].dma_rx = &uart3_dma_rx;
 #endif
 #endif
 #ifdef BSP_UART3_TX_USING_DMA
 #ifdef BSP_UART3_TX_USING_DMA
     uart_obj[UART3_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
     uart_obj[UART3_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart3_dma_tx = UART3_DMA_TX_CONFIG;
+    static const struct stm32_dma_config uart3_dma_tx = UART3_DMA_TX_CONFIG;
     uart_config[UART3_INDEX].dma_tx = &uart3_dma_tx;
     uart_config[UART3_INDEX].dma_tx = &uart3_dma_tx;
 #endif
 #endif
 #endif
 #endif
@@ -969,12 +961,12 @@ static void stm32_uart_get_dma_config(void)
     uart_obj[UART4_INDEX].uart_dma_flag = 0;
     uart_obj[UART4_INDEX].uart_dma_flag = 0;
 #ifdef BSP_UART4_RX_USING_DMA
 #ifdef BSP_UART4_RX_USING_DMA
     uart_obj[UART4_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
     uart_obj[UART4_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart4_dma_rx = UART4_DMA_RX_CONFIG;
+    static const struct stm32_dma_config uart4_dma_rx = UART4_DMA_RX_CONFIG;
     uart_config[UART4_INDEX].dma_rx = &uart4_dma_rx;
     uart_config[UART4_INDEX].dma_rx = &uart4_dma_rx;
 #endif
 #endif
 #ifdef BSP_UART4_TX_USING_DMA
 #ifdef BSP_UART4_TX_USING_DMA
     uart_obj[UART4_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
     uart_obj[UART4_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart4_dma_tx = UART4_DMA_TX_CONFIG;
+    static const struct stm32_dma_config uart4_dma_tx = UART4_DMA_TX_CONFIG;
     uart_config[UART4_INDEX].dma_tx = &uart4_dma_tx;
     uart_config[UART4_INDEX].dma_tx = &uart4_dma_tx;
 #endif
 #endif
 #endif
 #endif
@@ -983,12 +975,12 @@ static void stm32_uart_get_dma_config(void)
     uart_obj[UART5_INDEX].uart_dma_flag = 0;
     uart_obj[UART5_INDEX].uart_dma_flag = 0;
 #ifdef BSP_UART5_RX_USING_DMA
 #ifdef BSP_UART5_RX_USING_DMA
     uart_obj[UART5_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
     uart_obj[UART5_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart5_dma_rx = UART5_DMA_RX_CONFIG;
+    static const struct stm32_dma_config uart5_dma_rx = UART5_DMA_RX_CONFIG;
     uart_config[UART5_INDEX].dma_rx = &uart5_dma_rx;
     uart_config[UART5_INDEX].dma_rx = &uart5_dma_rx;
 #endif
 #endif
 #ifdef BSP_UART5_TX_USING_DMA
 #ifdef BSP_UART5_TX_USING_DMA
     uart_obj[UART5_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
     uart_obj[UART5_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart5_dma_tx = UART5_DMA_TX_CONFIG;
+    static const struct stm32_dma_config uart5_dma_tx = UART5_DMA_TX_CONFIG;
     uart_config[UART5_INDEX].dma_tx = &uart5_dma_tx;
     uart_config[UART5_INDEX].dma_tx = &uart5_dma_tx;
 #endif
 #endif
 #endif
 #endif
@@ -997,12 +989,12 @@ static void stm32_uart_get_dma_config(void)
     uart_obj[UART6_INDEX].uart_dma_flag = 0;
     uart_obj[UART6_INDEX].uart_dma_flag = 0;
 #ifdef BSP_UART6_RX_USING_DMA
 #ifdef BSP_UART6_RX_USING_DMA
     uart_obj[UART6_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
     uart_obj[UART6_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart6_dma_rx = UART6_DMA_RX_CONFIG;
+    static const struct stm32_dma_config uart6_dma_rx = UART6_DMA_RX_CONFIG;
     uart_config[UART6_INDEX].dma_rx = &uart6_dma_rx;
     uart_config[UART6_INDEX].dma_rx = &uart6_dma_rx;
 #endif
 #endif
 #ifdef BSP_UART6_TX_USING_DMA
 #ifdef BSP_UART6_TX_USING_DMA
     uart_obj[UART6_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
     uart_obj[UART6_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart6_dma_tx = UART6_DMA_TX_CONFIG;
+    static const struct stm32_dma_config uart6_dma_tx = UART6_DMA_TX_CONFIG;
     uart_config[UART6_INDEX].dma_tx = &uart6_dma_tx;
     uart_config[UART6_INDEX].dma_tx = &uart6_dma_tx;
 #endif
 #endif
 #endif
 #endif
@@ -1011,12 +1003,12 @@ static void stm32_uart_get_dma_config(void)
     uart_obj[UART7_INDEX].uart_dma_flag = 0;
     uart_obj[UART7_INDEX].uart_dma_flag = 0;
 #ifdef BSP_UART7_RX_USING_DMA
 #ifdef BSP_UART7_RX_USING_DMA
     uart_obj[UART7_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
     uart_obj[UART7_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart7_dma_rx = UART7_DMA_RX_CONFIG;
+    static const struct stm32_dma_config uart7_dma_rx = UART7_DMA_RX_CONFIG;
     uart_config[UART7_INDEX].dma_rx = &uart7_dma_rx;
     uart_config[UART7_INDEX].dma_rx = &uart7_dma_rx;
 #endif
 #endif
 #ifdef BSP_UART7_TX_USING_DMA
 #ifdef BSP_UART7_TX_USING_DMA
     uart_obj[UART7_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
     uart_obj[UART7_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart7_dma_tx = UART7_DMA_TX_CONFIG;
+    static const struct stm32_dma_config uart7_dma_tx = UART7_DMA_TX_CONFIG;
     uart_config[UART7_INDEX].dma_tx = &uart7_dma_tx;
     uart_config[UART7_INDEX].dma_tx = &uart7_dma_tx;
 #endif
 #endif
 #endif
 #endif
@@ -1025,12 +1017,12 @@ static void stm32_uart_get_dma_config(void)
     uart_obj[UART8_INDEX].uart_dma_flag = 0;
     uart_obj[UART8_INDEX].uart_dma_flag = 0;
 #ifdef BSP_UART8_RX_USING_DMA
 #ifdef BSP_UART8_RX_USING_DMA
     uart_obj[UART8_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
     uart_obj[UART8_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart8_dma_rx = UART8_DMA_RX_CONFIG;
+    static const struct stm32_dma_config uart8_dma_rx = UART8_DMA_RX_CONFIG;
     uart_config[UART8_INDEX].dma_rx = &uart8_dma_rx;
     uart_config[UART8_INDEX].dma_rx = &uart8_dma_rx;
 #endif
 #endif
 #ifdef BSP_UART8_TX_USING_DMA
 #ifdef BSP_UART8_TX_USING_DMA
     uart_obj[UART8_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
     uart_obj[UART8_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart8_dma_tx = UART8_DMA_TX_CONFIG;
+    static const struct stm32_dma_config uart8_dma_tx = UART8_DMA_TX_CONFIG;
     uart_config[UART8_INDEX].dma_tx = &uart8_dma_tx;
     uart_config[UART8_INDEX].dma_tx = &uart8_dma_tx;
 #endif
 #endif
 #endif
 #endif
@@ -1039,18 +1031,18 @@ static void stm32_uart_get_dma_config(void)
     uart_obj[LPUART1_INDEX].uart_dma_flag = 0;
     uart_obj[LPUART1_INDEX].uart_dma_flag = 0;
 #ifdef BSP_LPUART1_RX_USING_DMA
 #ifdef BSP_LPUART1_RX_USING_DMA
     uart_obj[LPUART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
     uart_obj[LPUART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config lpuart1_dma_rx = LPUART1_DMA_CONFIG;
+    static const struct stm32_dma_config lpuart1_dma_rx = LPUART1_DMA_CONFIG;
     uart_config[LPUART1_INDEX].dma_rx = &lpuart1_dma_rx;
     uart_config[LPUART1_INDEX].dma_rx = &lpuart1_dma_rx;
 #endif
 #endif
 #endif
 #endif
 }
 }
 
 
 #ifdef RT_SERIAL_USING_DMA
 #ifdef RT_SERIAL_USING_DMA
-static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
+static rt_err_t stm32_uart_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
 {
 {
     struct rt_serial_rx_fifo *rx_fifo;
     struct rt_serial_rx_fifo *rx_fifo;
     DMA_HandleTypeDef *DMA_Handle;
     DMA_HandleTypeDef *DMA_Handle;
-    struct dma_config *dma_config;
+    const struct stm32_dma_config *dma_config;
     struct stm32_uart *uart;
     struct stm32_uart *uart;
 
 
     RT_ASSERT(serial != RT_NULL);
     RT_ASSERT(serial != RT_NULL);
@@ -1069,81 +1061,27 @@ static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
     }
     }
     LOG_D("%s dma config start", uart->config->name);
     LOG_D("%s dma config start", uart->config->name);
 
 
-    {
-        rt_uint32_t tmpreg = 0x00U;
-#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)
-        /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
-        SET_BIT(RCC->AHBENR, dma_config->dma_rcc);
-        tmpreg = READ_BIT(RCC->AHBENR, dma_config->dma_rcc);
-#elif 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)
-        /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
-        SET_BIT(RCC->AHB1ENR, dma_config->dma_rcc);
-        tmpreg = READ_BIT(RCC->AHB1ENR, dma_config->dma_rcc);
-#elif defined(SOC_SERIES_STM32MP1)
-        /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
-        SET_BIT(RCC->MP_AHB2ENSETR, dma_config->dma_rcc);
-        tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, dma_config->dma_rcc);
-#endif
-
-#if (defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)) && defined(DMAMUX1)
-        /* enable DMAMUX clock for L4+ and G4 */
-        __HAL_RCC_DMAMUX1_CLK_ENABLE();
-#elif defined(SOC_SERIES_STM32MP1)
-        __HAL_RCC_DMAMUX_CLK_ENABLE();
-#endif
-
-        UNUSED(tmpreg);   /* To avoid compiler warnings */
-    }
-
     if (RT_DEVICE_FLAG_DMA_RX == flag)
     if (RT_DEVICE_FLAG_DMA_RX == flag)
     {
     {
-        __HAL_LINKDMA(&(uart->handle), hdmarx, uart->dma_rx.handle);
-    }
-    else if (RT_DEVICE_FLAG_DMA_TX == flag)
-    {
-        __HAL_LINKDMA(&(uart->handle), hdmatx, uart->dma_tx.handle);
-    }
-
-#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L0)|| defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32L1) || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5)
-    DMA_Handle->Instance                 = dma_config->Instance;
-#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
-    DMA_Handle->Instance                 = dma_config->Instance;
-    DMA_Handle->Init.Channel             = dma_config->channel;
-#elif 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)
-    DMA_Handle->Instance                 = dma_config->Instance;
-    DMA_Handle->Init.Request             = dma_config->request;
-#endif
-    DMA_Handle->Init.PeriphInc           = DMA_PINC_DISABLE;
-    DMA_Handle->Init.MemInc              = DMA_MINC_ENABLE;
-    DMA_Handle->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
-    DMA_Handle->Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
-
-    if (RT_DEVICE_FLAG_DMA_RX == flag)
-    {
-        DMA_Handle->Init.Direction           = DMA_PERIPH_TO_MEMORY;
-        DMA_Handle->Init.Mode                = DMA_CIRCULAR;
+        if (stm32_dma_setup(DMA_Handle,
+                            &(uart->handle),
+                            &uart->handle.hdmarx,
+                            dma_config) != RT_EOK)
+        {
+            LOG_E("%s dma rx config failed", uart->config->name);
+            return -RT_ERROR;
+        }
     }
     }
     else if (RT_DEVICE_FLAG_DMA_TX == flag)
     else if (RT_DEVICE_FLAG_DMA_TX == flag)
     {
     {
-        DMA_Handle->Init.Direction           = DMA_MEMORY_TO_PERIPH;
-        DMA_Handle->Init.Mode                = DMA_NORMAL;
-    }
-
-    DMA_Handle->Init.Priority            = DMA_PRIORITY_MEDIUM;
-#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1)
-    DMA_Handle->Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
-#endif
-    if (HAL_DMA_DeInit(DMA_Handle) != HAL_OK)
-    {
-        RT_ASSERT(0);
-    }
-
-    if (HAL_DMA_Init(DMA_Handle) != HAL_OK)
-    {
-        RT_ASSERT(0);
+        if (stm32_dma_setup(DMA_Handle,
+                            &(uart->handle),
+                            &uart->handle.hdmatx,
+                            dma_config) != RT_EOK)
+        {
+            LOG_E("%s dma tx config failed", uart->config->name);
+            return -RT_ERROR;
+        }
     }
     }
 
 
     /* enable interrupt */
     /* enable interrupt */
@@ -1154,21 +1092,26 @@ static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
         if (HAL_UART_Receive_DMA(&(uart->handle), rx_fifo->buffer, serial->config.bufsz) != HAL_OK)
         if (HAL_UART_Receive_DMA(&(uart->handle), rx_fifo->buffer, serial->config.bufsz) != HAL_OK)
         {
         {
             /* Transfer error in reception process */
             /* Transfer error in reception process */
-            RT_ASSERT(0);
+            LOG_E("%s uart dma rx start failed", uart->config->name);
+            if (stm32_dma_deinit(DMA_Handle, dma_config, RT_FALSE) != RT_EOK)
+            {
+                LOG_E("%s uart dma rx rollback failed", uart->config->name);
+            }
+            uart->handle.hdmarx = RT_NULL;
+            DMA_Handle->Parent = RT_NULL;
+            return -RT_ERROR;
         }
         }
         CLEAR_BIT(uart->handle.Instance->CR3, USART_CR3_EIE);
         CLEAR_BIT(uart->handle.Instance->CR3, USART_CR3_EIE);
         __HAL_UART_ENABLE_IT(&(uart->handle), UART_IT_IDLE);
         __HAL_UART_ENABLE_IT(&(uart->handle), UART_IT_IDLE);
     }
     }
 
 
-    /* DMA irq should set in DMA TX mode, or HAL_UART_TxCpltCallback function will not be called */
-    HAL_NVIC_SetPriority(dma_config->dma_irq, 0, 0);
-    HAL_NVIC_EnableIRQ(dma_config->dma_irq);
-
     HAL_NVIC_SetPriority(uart->config->irq_type, 1, 0);
     HAL_NVIC_SetPriority(uart->config->irq_type, 1, 0);
     HAL_NVIC_EnableIRQ(uart->config->irq_type);
     HAL_NVIC_EnableIRQ(uart->config->irq_type);
 
 
     LOG_D("%s dma %s instance: %x", uart->config->name, flag == RT_DEVICE_FLAG_DMA_RX ? "RX" : "TX", DMA_Handle->Instance);
     LOG_D("%s dma %s instance: %x", uart->config->name, flag == RT_DEVICE_FLAG_DMA_RX ? "RX" : "TX", DMA_Handle->Instance);
     LOG_D("%s dma config done", uart->config->name);
     LOG_D("%s dma config done", uart->config->name);
+
+    return RT_EOK;
 }
 }
 
 
 /**
 /**

+ 2 - 10
bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart.h

@@ -21,14 +21,6 @@
 
 
 int rt_hw_usart_init(void);
 int rt_hw_usart_init(void);
 
 
-#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) \
-    || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)|| defined(SOC_SERIES_STM32F3)
-#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_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) */
-
 #if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32WL) \
 #if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32WL) \
     || defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) \
     || defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) \
     || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)|| defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32U5) \
     || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)|| defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32U5) \
@@ -51,8 +43,8 @@ struct stm32_uart_config
     const char *name;
     const char *name;
     USART_TypeDef *Instance;
     USART_TypeDef *Instance;
     IRQn_Type irq_type;
     IRQn_Type irq_type;
-    struct dma_config *dma_rx;
-    struct dma_config *dma_tx;
+    const struct stm32_dma_config *dma_rx;
+    const struct stm32_dma_config *dma_tx;
 };
 };
 
 
 /* stm32 uart dirver class */
 /* stm32 uart dirver class */

+ 81 - 139
bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart_v2.c

@@ -28,7 +28,7 @@
 #endif
 #endif
 
 
 #ifdef RT_SERIAL_USING_DMA
 #ifdef RT_SERIAL_USING_DMA
-static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag);
+static rt_err_t stm32_uart_dma_config(struct rt_serial_device *serial, rt_ubase_t flag);
 #endif
 #endif
 
 
 enum
 enum
@@ -237,28 +237,18 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar
         {
         {
             __HAL_UART_DISABLE_IT(&(uart->handle), UART_IT_RXNE);
             __HAL_UART_DISABLE_IT(&(uart->handle), UART_IT_RXNE);
 
 
-            HAL_NVIC_DisableIRQ(uart->config->dma_rx->dma_irq);
-            if (HAL_DMA_Abort(&(uart->dma_rx.handle)) != HAL_OK)
+            if (stm32_dma_deinit(&(uart->dma_rx.handle), uart->config->dma_rx, RT_TRUE) != RT_EOK)
             {
             {
-                RT_ASSERT(0);
-            }
-
-            if (HAL_DMA_DeInit(&(uart->dma_rx.handle)) != HAL_OK)
-            {
-                RT_ASSERT(0);
+                LOG_E("%s dma rx deinit failed", uart->config->name);
             }
             }
         }
         }
         else if (ctrl_arg == RT_DEVICE_FLAG_DMA_TX)
         else if (ctrl_arg == RT_DEVICE_FLAG_DMA_TX)
         {
         {
             __HAL_UART_DISABLE_IT(&(uart->handle), UART_IT_TC);
             __HAL_UART_DISABLE_IT(&(uart->handle), UART_IT_TC);
 
 
-            HAL_NVIC_DisableIRQ(uart->config->dma_tx->dma_irq);
-
-            HAL_DMA_Abort(&(uart->dma_tx.handle));
-
-            if (HAL_DMA_DeInit(&(uart->dma_tx.handle)) != HAL_OK)
+            if (stm32_dma_deinit(&(uart->dma_tx.handle), uart->config->dma_tx, RT_TRUE) != RT_EOK)
             {
             {
-                RT_ASSERT(0);
+                LOG_E("%s dma tx deinit failed", uart->config->name);
             }
             }
         }
         }
 #endif
 #endif
@@ -279,7 +269,7 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar
         if (ctrl_arg & (RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX))
         if (ctrl_arg & (RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX))
         {
         {
 #ifdef RT_SERIAL_USING_DMA
 #ifdef RT_SERIAL_USING_DMA
-            stm32_dma_config(serial, ctrl_arg);
+            stm32_uart_dma_config(serial, ctrl_arg);
 #else
 #else
             return -RT_ENOSYS;
             return -RT_ENOSYS;
 #endif
 #endif
@@ -300,9 +290,10 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar
     case RT_DEVICE_CTRL_CLOSE:
     case RT_DEVICE_CTRL_CLOSE:
     {
     {
         uart->error_indicate = RT_NULL;
         uart->error_indicate = RT_NULL;
-        if (HAL_UART_DeInit(&(uart->handle)) != HAL_OK)
+        HAL_StatusTypeDef status = HAL_UART_DeInit(&uart->handle);
+        if (status != HAL_OK)
         {
         {
-            RT_ASSERT(0)
+            LOG_E("(%s) serial deinit error %d!", serial->parent.parent.name, status);
         }
         }
         break;
         break;
     }
     }
@@ -941,15 +932,15 @@ static void stm32_uart_get_config(void)
 
 
 #ifdef BSP_UART1_RX_USING_DMA
 #ifdef BSP_UART1_RX_USING_DMA
     uart_obj[UART1_INDEX].serial.config.dma_ping_bufsz  = BSP_UART1_DMA_PING_BUFSIZE;
     uart_obj[UART1_INDEX].serial.config.dma_ping_bufsz  = BSP_UART1_DMA_PING_BUFSIZE;
-    uart_obj[UART1_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart1_dma_rx               = UART1_DMA_RX_CONFIG;
+    uart_obj[UART1_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_RX;
+    static const struct stm32_dma_config uart1_dma_rx   = UART1_DMA_RX_CONFIG;
     uart_config[UART1_INDEX].dma_rx                     = &uart1_dma_rx;
     uart_config[UART1_INDEX].dma_rx                     = &uart1_dma_rx;
 #endif
 #endif
 
 
 #ifdef BSP_UART1_TX_USING_DMA
 #ifdef BSP_UART1_TX_USING_DMA
-    uart_obj[UART1_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart1_dma_tx  = UART1_DMA_TX_CONFIG;
-    uart_config[UART1_INDEX].dma_tx        = &uart1_dma_tx;
+    uart_obj[UART1_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_TX;
+    static const struct stm32_dma_config uart1_dma_tx   = UART1_DMA_TX_CONFIG;
+    uart_config[UART1_INDEX].dma_tx                     = &uart1_dma_tx;
 #endif
 #endif
 #endif
 #endif
 
 
@@ -962,15 +953,15 @@ static void stm32_uart_get_config(void)
 
 
 #ifdef BSP_UART2_RX_USING_DMA
 #ifdef BSP_UART2_RX_USING_DMA
     uart_obj[UART2_INDEX].serial.config.dma_ping_bufsz  = BSP_UART2_DMA_PING_BUFSIZE;
     uart_obj[UART2_INDEX].serial.config.dma_ping_bufsz  = BSP_UART2_DMA_PING_BUFSIZE;
-    uart_obj[UART2_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart2_dma_rx               = UART2_DMA_RX_CONFIG;
+    uart_obj[UART2_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_RX;
+    static const struct stm32_dma_config uart2_dma_rx   = UART2_DMA_RX_CONFIG;
     uart_config[UART2_INDEX].dma_rx                     = &uart2_dma_rx;
     uart_config[UART2_INDEX].dma_rx                     = &uart2_dma_rx;
 #endif
 #endif
 
 
 #ifdef BSP_UART2_TX_USING_DMA
 #ifdef BSP_UART2_TX_USING_DMA
-    uart_obj[UART2_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart2_dma_tx  = UART2_DMA_TX_CONFIG;
-    uart_config[UART2_INDEX].dma_tx        = &uart2_dma_tx;
+    uart_obj[UART2_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_TX;
+    static const struct stm32_dma_config uart2_dma_tx   = UART2_DMA_TX_CONFIG;
+    uart_config[UART2_INDEX].dma_tx                     = &uart2_dma_tx;
 #endif
 #endif
 #endif
 #endif
 
 
@@ -983,15 +974,15 @@ static void stm32_uart_get_config(void)
 
 
 #ifdef BSP_UART3_RX_USING_DMA
 #ifdef BSP_UART3_RX_USING_DMA
     uart_obj[UART3_INDEX].serial.config.dma_ping_bufsz  = BSP_UART3_DMA_PING_BUFSIZE;
     uart_obj[UART3_INDEX].serial.config.dma_ping_bufsz  = BSP_UART3_DMA_PING_BUFSIZE;
-    uart_obj[UART3_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart3_dma_rx               = UART3_DMA_RX_CONFIG;
+    uart_obj[UART3_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_RX;
+    static const struct stm32_dma_config uart3_dma_rx   = UART3_DMA_RX_CONFIG;
     uart_config[UART3_INDEX].dma_rx                     = &uart3_dma_rx;
     uart_config[UART3_INDEX].dma_rx                     = &uart3_dma_rx;
 #endif
 #endif
 
 
 #ifdef BSP_UART3_TX_USING_DMA
 #ifdef BSP_UART3_TX_USING_DMA
-    uart_obj[UART3_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart3_dma_tx  = UART3_DMA_TX_CONFIG;
-    uart_config[UART3_INDEX].dma_tx        = &uart3_dma_tx;
+    uart_obj[UART3_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_TX;
+    static const struct stm32_dma_config uart3_dma_tx   = UART3_DMA_TX_CONFIG;
+    uart_config[UART3_INDEX].dma_tx                     = &uart3_dma_tx;
 #endif
 #endif
 #endif
 #endif
 
 
@@ -1004,15 +995,15 @@ static void stm32_uart_get_config(void)
 
 
 #ifdef BSP_UART4_RX_USING_DMA
 #ifdef BSP_UART4_RX_USING_DMA
     uart_obj[UART4_INDEX].serial.config.dma_ping_bufsz  = BSP_UART4_DMA_PING_BUFSIZE;
     uart_obj[UART4_INDEX].serial.config.dma_ping_bufsz  = BSP_UART4_DMA_PING_BUFSIZE;
-    uart_obj[UART4_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart4_dma_rx               = UART4_DMA_RX_CONFIG;
+    uart_obj[UART4_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_RX;
+    static const struct stm32_dma_config uart4_dma_rx   = UART4_DMA_RX_CONFIG;
     uart_config[UART4_INDEX].dma_rx                     = &uart4_dma_rx;
     uart_config[UART4_INDEX].dma_rx                     = &uart4_dma_rx;
 #endif
 #endif
 
 
 #ifdef BSP_UART4_TX_USING_DMA
 #ifdef BSP_UART4_TX_USING_DMA
-    uart_obj[UART4_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart4_dma_tx  = UART4_DMA_TX_CONFIG;
-    uart_config[UART4_INDEX].dma_tx        = &uart4_dma_tx;
+    uart_obj[UART4_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_TX;
+    static const struct stm32_dma_config uart4_dma_tx   = UART4_DMA_TX_CONFIG;
+    uart_config[UART4_INDEX].dma_tx                     = &uart4_dma_tx;
 #endif
 #endif
 #endif
 #endif
 
 
@@ -1025,15 +1016,15 @@ static void stm32_uart_get_config(void)
 
 
 #ifdef BSP_UART5_RX_USING_DMA
 #ifdef BSP_UART5_RX_USING_DMA
     uart_obj[UART5_INDEX].serial.config.dma_ping_bufsz  = BSP_UART5_DMA_PING_BUFSIZE;
     uart_obj[UART5_INDEX].serial.config.dma_ping_bufsz  = BSP_UART5_DMA_PING_BUFSIZE;
-    uart_obj[UART5_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart5_dma_rx               = UART5_DMA_RX_CONFIG;
+    uart_obj[UART5_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_RX;
+    static const struct stm32_dma_config uart5_dma_rx   = UART5_DMA_RX_CONFIG;
     uart_config[UART5_INDEX].dma_rx                     = &uart5_dma_rx;
     uart_config[UART5_INDEX].dma_rx                     = &uart5_dma_rx;
 #endif
 #endif
 
 
 #ifdef BSP_UART5_TX_USING_DMA
 #ifdef BSP_UART5_TX_USING_DMA
-    uart_obj[UART5_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart5_dma_tx  = UART5_DMA_TX_CONFIG;
-    uart_config[UART5_INDEX].dma_tx        = &uart5_dma_tx;
+    uart_obj[UART5_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_TX;
+    static const struct stm32_dma_config uart5_dma_tx   = UART5_DMA_TX_CONFIG;
+    uart_config[UART5_INDEX].dma_tx                     = &uart5_dma_tx;
 #endif
 #endif
 #endif
 #endif
 
 
@@ -1046,15 +1037,15 @@ static void stm32_uart_get_config(void)
 
 
 #ifdef BSP_UART6_RX_USING_DMA
 #ifdef BSP_UART6_RX_USING_DMA
     uart_obj[UART6_INDEX].serial.config.dma_ping_bufsz  = BSP_UART6_DMA_PING_BUFSIZE;
     uart_obj[UART6_INDEX].serial.config.dma_ping_bufsz  = BSP_UART6_DMA_PING_BUFSIZE;
-    uart_obj[UART6_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart6_dma_rx               = UART6_DMA_RX_CONFIG;
+    uart_obj[UART6_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_RX;
+    static const struct stm32_dma_config uart6_dma_rx   = UART6_DMA_RX_CONFIG;
     uart_config[UART6_INDEX].dma_rx                     = &uart6_dma_rx;
     uart_config[UART6_INDEX].dma_rx                     = &uart6_dma_rx;
 #endif
 #endif
 
 
 #ifdef BSP_UART6_TX_USING_DMA
 #ifdef BSP_UART6_TX_USING_DMA
-    uart_obj[UART6_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart6_dma_tx  = UART6_DMA_TX_CONFIG;
-    uart_config[UART6_INDEX].dma_tx        = &uart6_dma_tx;
+    uart_obj[UART6_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_TX;
+    static const struct stm32_dma_config uart6_dma_tx   = UART6_DMA_TX_CONFIG;
+    uart_config[UART6_INDEX].dma_tx                     = &uart6_dma_tx;
 #endif
 #endif
 #endif
 #endif
 
 
@@ -1067,15 +1058,15 @@ static void stm32_uart_get_config(void)
 
 
 #ifdef BSP_UART7_RX_USING_DMA
 #ifdef BSP_UART7_RX_USING_DMA
     uart_obj[UART7_INDEX].serial.config.dma_ping_bufsz  = BSP_UART7_DMA_PING_BUFSIZE;
     uart_obj[UART7_INDEX].serial.config.dma_ping_bufsz  = BSP_UART7_DMA_PING_BUFSIZE;
-    uart_obj[UART7_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart7_dma_rx               = UART7_DMA_RX_CONFIG;
+    uart_obj[UART7_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_RX;
+    static const struct stm32_dma_config uart7_dma_rx   = UART7_DMA_RX_CONFIG;
     uart_config[UART7_INDEX].dma_rx                     = &uart7_dma_rx;
     uart_config[UART7_INDEX].dma_rx                     = &uart7_dma_rx;
 #endif
 #endif
 
 
 #ifdef BSP_UART7_TX_USING_DMA
 #ifdef BSP_UART7_TX_USING_DMA
-    uart_obj[UART7_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart7_dma_tx  = UART7_DMA_TX_CONFIG;
-    uart_config[UART7_INDEX].dma_tx        = &uart7_dma_tx;
+    uart_obj[UART7_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_TX;
+    static const struct stm32_dma_config uart7_dma_tx   = UART7_DMA_TX_CONFIG;
+    uart_config[UART7_INDEX].dma_tx                     = &uart7_dma_tx;
 #endif
 #endif
 #endif
 #endif
 
 
@@ -1087,15 +1078,15 @@ static void stm32_uart_get_config(void)
     uart_obj[UART8_INDEX].serial.config.tx_bufsz = BSP_UART8_TX_BUFSIZE;
     uart_obj[UART8_INDEX].serial.config.tx_bufsz = BSP_UART8_TX_BUFSIZE;
 
 
 #ifdef BSP_UART8_RX_USING_DMA
 #ifdef BSP_UART8_RX_USING_DMA
-    uart_obj[UART8_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart8_dma_rx  = UART8_DMA_RX_CONFIG;
-    uart_config[UART8_INDEX].dma_rx        = &uart8_dma_rx;
+    uart_obj[UART8_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_RX;
+    static const struct stm32_dma_config uart8_dma_rx   = UART8_DMA_RX_CONFIG;
+    uart_config[UART8_INDEX].dma_rx                     = &uart8_dma_rx;
 #endif
 #endif
 
 
 #ifdef BSP_UART8_TX_USING_DMA
 #ifdef BSP_UART8_TX_USING_DMA
     uart_obj[UART8_INDEX].serial.config.dma_ping_bufsz  = BSP_UART8_DMA_PING_BUFSIZE;
     uart_obj[UART8_INDEX].serial.config.dma_ping_bufsz  = BSP_UART8_DMA_PING_BUFSIZE;
-    uart_obj[UART8_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart8_dma_tx               = UART8_DMA_TX_CONFIG;
+    uart_obj[UART8_INDEX].uart_dma_flag                 |= RT_DEVICE_FLAG_DMA_TX;
+    static const struct stm32_dma_config uart8_dma_tx   = UART8_DMA_TX_CONFIG;
     uart_config[UART8_INDEX].dma_tx                     = &uart8_dma_tx;
     uart_config[UART8_INDEX].dma_tx                     = &uart8_dma_tx;
 #endif
 #endif
 #endif
 #endif
@@ -1108,19 +1099,19 @@ static void stm32_uart_get_config(void)
     uart_obj[LPUART1_INDEX].serial.config.tx_bufsz = BSP_LPUART1_TX_BUFSIZE;
     uart_obj[LPUART1_INDEX].serial.config.tx_bufsz = BSP_LPUART1_TX_BUFSIZE;
 
 
 #ifdef BSP_LPUART1_RX_USING_DMA
 #ifdef BSP_LPUART1_RX_USING_DMA
-    uart_obj[LPUART1_INDEX].serial.config.dma_ping_bufsz  = BSP_LPUART1_DMA_PING_BUFSIZE;
-    uart_obj[LPUART1_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config lpuart1_dma_rx               = LPUART1_DMA_CONFIG;
-    uart_config[LPUART1_INDEX].dma_rx                     = &lpuart1_dma_rx;
+    uart_obj[LPUART1_INDEX].serial.config.dma_ping_bufsz    = BSP_LPUART1_DMA_PING_BUFSIZE;
+    uart_obj[LPUART1_INDEX].uart_dma_flag                   |= RT_DEVICE_FLAG_DMA_RX;
+    static const struct stm32_dma_config lpuart1_dma_rx     = LPUART1_DMA_CONFIG;
+    uart_config[LPUART1_INDEX].dma_rx                       = &lpuart1_dma_rx;
 #endif
 #endif
 #endif
 #endif
 }
 }
 
 
 #ifdef RT_SERIAL_USING_DMA
 #ifdef RT_SERIAL_USING_DMA
-static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
+static rt_err_t stm32_uart_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
 {
 {
     DMA_HandleTypeDef *DMA_Handle;
     DMA_HandleTypeDef *DMA_Handle;
-    struct dma_config *dma_config;
+    const struct stm32_dma_config *dma_config;
     struct stm32_uart *uart;
     struct stm32_uart *uart;
 
 
     RT_ASSERT(serial != RT_NULL);
     RT_ASSERT(serial != RT_NULL);
@@ -1139,81 +1130,27 @@ static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
     }
     }
     LOG_D("%s dma config start", uart->config->name);
     LOG_D("%s dma config start", uart->config->name);
 
 
-    {
-        rt_uint32_t tmpreg = 0x00U;
-#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) \
-    || defined(SOC_SERIES_STM32L0)
-        /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
-        SET_BIT(RCC->AHBENR, dma_config->dma_rcc);
-        tmpreg = READ_BIT(RCC->AHBENR, dma_config->dma_rcc);
-#elif 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)
-        /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
-        SET_BIT(RCC->AHB1ENR, dma_config->dma_rcc);
-        tmpreg = READ_BIT(RCC->AHB1ENR, dma_config->dma_rcc);
-#elif defined(SOC_SERIES_STM32MP1)
-        /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
-        SET_BIT(RCC->MP_AHB2ENSETR, dma_config->dma_rcc);
-        tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, dma_config->dma_rcc);
-#endif
-
-#if defined(DMAMUX1) && (defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB))
-        /* enable DMAMUX clock for L4+ and G4 */
-        __HAL_RCC_DMAMUX1_CLK_ENABLE();
-#elif defined(SOC_SERIES_STM32MP1)
-        __HAL_RCC_DMAMUX_CLK_ENABLE();
-#endif
-
-        UNUSED(tmpreg); /* To avoid compiler warnings */
-    }
-
-    if (RT_DEVICE_FLAG_DMA_RX == flag)
-    {
-        __HAL_LINKDMA(&(uart->handle), hdmarx, uart->dma_rx.handle);
-    }
-    else if (RT_DEVICE_FLAG_DMA_TX == flag)
-    {
-        __HAL_LINKDMA(&(uart->handle), hdmatx, uart->dma_tx.handle);
-    }
-
-#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32L1) || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5)
-    DMA_Handle->Instance = dma_config->Instance;
-#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
-    DMA_Handle->Instance     = dma_config->Instance;
-    DMA_Handle->Init.Channel = dma_config->channel;
-#elif 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)
-    DMA_Handle->Instance     = dma_config->Instance;
-    DMA_Handle->Init.Request = dma_config->request;
-#endif
-    DMA_Handle->Init.PeriphInc           = DMA_PINC_DISABLE;
-    DMA_Handle->Init.MemInc              = DMA_MINC_ENABLE;
-    DMA_Handle->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
-    DMA_Handle->Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
-
     if (RT_DEVICE_FLAG_DMA_RX == flag)
     if (RT_DEVICE_FLAG_DMA_RX == flag)
     {
     {
-        DMA_Handle->Init.Direction = DMA_PERIPH_TO_MEMORY;
-        DMA_Handle->Init.Mode      = DMA_CIRCULAR;
+        if (stm32_dma_setup(DMA_Handle,
+                            &(uart->handle),
+                            &uart->handle.hdmarx,
+                            dma_config) != RT_EOK)
+        {
+            LOG_E("%s dma rx config failed", uart->config->name);
+            return -RT_ERROR;
+        }
     }
     }
     else if (RT_DEVICE_FLAG_DMA_TX == flag)
     else if (RT_DEVICE_FLAG_DMA_TX == flag)
     {
     {
-        DMA_Handle->Init.Direction = DMA_MEMORY_TO_PERIPH;
-        DMA_Handle->Init.Mode      = DMA_NORMAL;
-    }
-
-    DMA_Handle->Init.Priority = DMA_PRIORITY_MEDIUM;
-#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1)
-    DMA_Handle->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
-#endif
-    if (HAL_DMA_DeInit(DMA_Handle) != HAL_OK)
-    {
-        RT_ASSERT(0);
-    }
-
-    if (HAL_DMA_Init(DMA_Handle) != HAL_OK)
-    {
-        RT_ASSERT(0);
+        if (stm32_dma_setup(DMA_Handle,
+                            &(uart->handle),
+                            &uart->handle.hdmatx,
+                            dma_config) != RT_EOK)
+        {
+            LOG_E("%s dma tx config failed", uart->config->name);
+            return -RT_ERROR;
+        }
     }
     }
 
 
     /* enable interrupt */
     /* enable interrupt */
@@ -1226,21 +1163,26 @@ static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
         if (HAL_UART_Receive_DMA(&(uart->handle), ptr, serial->config.dma_ping_bufsz) != HAL_OK)
         if (HAL_UART_Receive_DMA(&(uart->handle), ptr, serial->config.dma_ping_bufsz) != HAL_OK)
         {
         {
             /* Transfer error in reception process */
             /* Transfer error in reception process */
-            RT_ASSERT(0);
+            LOG_E("%s uart dma rx start failed", uart->config->name);
+            if (stm32_dma_deinit(DMA_Handle, dma_config, RT_FALSE) != RT_EOK)
+            {
+                LOG_E("%s uart dma rx rollback failed", uart->config->name);
+            }
+            uart->handle.hdmarx = RT_NULL;
+            DMA_Handle->Parent = RT_NULL;
+            return -RT_ERROR;
         }
         }
         CLEAR_BIT(uart->handle.Instance->CR3, USART_CR3_EIE);
         CLEAR_BIT(uart->handle.Instance->CR3, USART_CR3_EIE);
         __HAL_UART_ENABLE_IT(&(uart->handle), UART_IT_IDLE);
         __HAL_UART_ENABLE_IT(&(uart->handle), UART_IT_IDLE);
     }
     }
 
 
-    /* DMA irq should set in DMA TX mode, or HAL_UART_TxCpltCallback function will not be called */
-    HAL_NVIC_SetPriority(dma_config->dma_irq, 0, 0);
-    HAL_NVIC_EnableIRQ(dma_config->dma_irq);
-
     HAL_NVIC_SetPriority(uart->config->irq_type, 1, 0);
     HAL_NVIC_SetPriority(uart->config->irq_type, 1, 0);
     HAL_NVIC_EnableIRQ(uart->config->irq_type);
     HAL_NVIC_EnableIRQ(uart->config->irq_type);
 
 
     LOG_D("%s dma %s instance: %x", uart->config->name, flag == RT_DEVICE_FLAG_DMA_RX ? "RX" : "TX", DMA_Handle->Instance);
     LOG_D("%s dma %s instance: %x", uart->config->name, flag == RT_DEVICE_FLAG_DMA_RX ? "RX" : "TX", DMA_Handle->Instance);
     LOG_D("%s dma config done", uart->config->name);
     LOG_D("%s dma config done", uart->config->name);
+
+    return RT_EOK;
 }
 }
 
 
 /**
 /**

+ 2 - 2
bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart_v2.h

@@ -57,8 +57,8 @@ struct stm32_uart_config
     IRQn_Type irq_type;
     IRQn_Type irq_type;
 
 
 #ifdef RT_SERIAL_USING_DMA
 #ifdef RT_SERIAL_USING_DMA
-    struct dma_config *dma_rx;
-    struct dma_config *dma_tx;
+    const struct stm32_dma_config *dma_rx;
+    const struct stm32_dma_config *dma_tx;
 #endif
 #endif
 };
 };