Skip to content

[stm32][drivers] Add BDMA support for SPI - #11689

Open
moment-NEW wants to merge 2 commits into
RT-Thread:masterfrom
moment-NEW:feat/spi-bdma
Open

[stm32][drivers] Add BDMA support for SPI#11689
moment-NEW wants to merge 2 commits into
RT-Thread:masterfrom
moment-NEW:feat/spi-bdma

Conversation

@moment-NEW

@moment-NEW moment-NEW commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

拉取/合并请求描述:(PR description)

[

为什么提交这份PR (why to submit this PR)

对于H7系列的SPI,其缺失BDMA驱动,因此制作了相关驱动使其正常工作

你的解决方案是什么 (what is your solution)

仿照drv_dma的设计,在驱动层单独设计了一套bdma驱动,而上层spi处基本复用dma逻辑。

请提供验证的bsp和config (provide the config and bsp)

已在DM-MC02 上完成验证工作,验证使用自行编写的WS2812驱动软件包,测试正常点亮,效果与阻塞一致,且不影响串口等其他外设。该BSP以及相关软件包会稍后进行格式清理等后推送。此外进行了scons -j8等编译均通过。

  • BSP:bsp/stm32/stm32h723-DM-MC02
  • .config:
  • action:

]

当前拉取/合并请求的状态 Intent for your PR

必须选择一项 Choose one (Mandatory):

  • 本拉取/合并请求是一个草稿版本 This PR is for a code-review and is intended to get feedback
  • 本拉取/合并请求是一个成熟版本 This PR is mature, and ready to be integrated into the repo

代码质量 Code Quality:

我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:

  • 已经仔细查看过代码改动的对比 Already check the difference between PR and old code
  • 代码风格正确,包括缩进空格,命名及其他风格 Style guide is adhered to, including spacing, naming and other styles
  • 没有垃圾代码,代码尽量精简,不包含#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up
  • 所有变更均有原因及合理的,并且不会影响到其他软件组件代码或BSP All modifications are justified and not affect other components or BSP
  • 对难懂代码均提供对应的注释 I've commented appropriately where code is tricky
  • 代码是高质量的 Code in this PR is of high quality
  • 已经使用clang-format 源码格式化工具确保格式符合RT-Thread代码规范 This PR has been formatted with clang-format and complies with RT-Thread code specification
  • 如果是新增bsp, 已经添加ci检查到.github/ALL_BSP_COMPILE.json 详细请参考链接BSP自查

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

👋 感谢您对 RT-Thread 的贡献!Thank you for your contribution to RT-Thread!

为确保代码符合 RT-Thread 的编码规范,请在你的仓库中执行以下步骤运行代码格式化工作流(如果格式化CI运行失败)。
To ensure your code complies with RT-Thread's coding style, please run the code formatting workflow by following the steps below (If the formatting of CI fails to run).


🛠 操作步骤 | Steps

  1. 前往 Actions 页面 | Go to the Actions page
    点击进入工作流 → | Click to open workflow →

  2. 点击 Run workflow | Click Run workflow

  • 设置需排除的文件/目录(目录请以"/"结尾)
    Set files/directories to exclude (directories should end with "/")
  • 将目标分支设置为 \ Set the target branch to:feat/spi-bdma
  • 设置PR number为 \ Set the PR number to:11689
  1. 等待工作流完成 | Wait for the workflow to complete
    格式化后的代码将自动推送至你的分支。
    The formatted code will be automatically pushed to your branch.

完成后,提交将自动更新至 feat/spi-bdma 分支,关联的 Pull Request 也会同步更新。
Once completed, commits will be pushed to the feat/spi-bdma branch automatically, and the related Pull Request will be updated.

如有问题欢迎联系我们,再次感谢您的贡献!💐
If you have any questions, feel free to reach out. Thanks again for your contribution!

@github-actions github-actions Bot added BSP: STM32 BSP related with ST/STM32 BSP labels Aug 9, 2026
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

📌 Code Review Assignment

🏷️ Tag: bsp_stm32

Reviewers: @Liang1795 @hamburger-os @wdfk-prog

Changed Files (Click to expand)
  • bsp/stm32/libraries/HAL_Drivers/drivers/SConscript
  • bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/dma_config.h
  • bsp/stm32/libraries/HAL_Drivers/drivers/config/h7/spi_config.h
  • bsp/stm32/libraries/HAL_Drivers/drivers/drv_bdma.c
  • bsp/stm32/libraries/HAL_Drivers/drivers/drv_bdma.h
  • bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.c
  • bsp/stm32/libraries/HAL_Drivers/drivers/drv_dma.h
  • bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c
  • bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h

📊 Current Review Status (Last Updated: 2026-08-09 16:30 CST)


📝 Review Instructions

  1. 维护者可以通过单击此处来刷新审查状态: 🔄 刷新状态
    Maintainers can refresh the review status by clicking here: 🔄 Refresh Status

  2. 确认审核通过后评论 LGTM/lgtm
    Comment LGTM/lgtm after confirming approval

  3. PR合并前需至少一位维护者确认
    PR must be confirmed by at least one maintainer before merging

ℹ️ 刷新CI状态操作需要具备仓库写入权限。
ℹ️ Refresh CI status operation requires repository Write permission.

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@moment-NEW

Copy link
Copy Markdown
Contributor Author

现在还是草稿阶段...稍后整理一下BSP部分,开启一个BSP的PR再推上来吧

@wdfk-prog

wdfk-prog commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

现在还是草稿阶段...稍后整理一下BSP部分,开启一个BSP的PR再推上来吧

  • 这个bdma没有必要单独开展一个文件的;
struct stm32_bdma_config
{
    void *Instance;                      /**< BDMA channel instance pointer. */
    rt_uint32_t dma_rcc;                 /**< RCC enable bit for the BDMA controller. */
    IRQn_Type dma_irq;                   /**< NVIC IRQ number for the BDMA channel. */
    rt_uint32_t priority;                /**< BDMA transfer priority. */
    rt_uint8_t preempt_priority;         /**< NVIC preempt priority for the BDMA IRQ. */
    rt_uint8_t sub_priority;             /**< NVIC sub priority for the BDMA IRQ. */
    rt_uint32_t request;                 /**< BDMA request selector. */
    rt_uint32_t direction;               /**< BDMA transfer direction. */
    rt_uint32_t periph_inc;              /**< Peripheral address increment mode. */
    rt_uint32_t mem_inc;                 /**< Memory address increment mode. */
    rt_uint32_t periph_data_alignment;   /**< Peripheral data alignment. */
    rt_uint32_t mem_data_alignment;      /**< Memory data alignment. */
    rt_uint32_t mode;                    /**< BDMA transfer mode. */
};
  • 就像stm32_dma_config中关于GPDMA的特殊处理这样对BDMA进行处理就好了
  • stm32_dma_config中也有channel
  • 你可以看看BDMA中有什么特殊的结构体添加到stm32_dma_config中用宏隔开即可.
  • 这样子可以不再需要一个BDMA的文件了
  • 虽然这样子还是不够简洁,但是把dma逻辑散落到不同文件里面也是更难维护的
/**
 * @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) */
};
  • 我看了一些结构体的不同之处,好像并没有不同的地方?所有bdma可以使用Koconfig选择后把STM32_DMA_USES_REQUEST宏一并选择即可;这样BDMA的结构体就完成定义了
  • 至于具体的函数代码还有什么不同,我还没有查看;我认为应该可以在现有的dma代码中进行通过宏定义?或者flag?方案进行对于不同逻辑的使用和转接

@moment-NEW

moment-NEW commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

现在还是草稿阶段...稍后整理一下BSP部分,开启一个BSP的PR再推上来吧

  • 这个bdma没有必要单独开展一个文件的;
struct stm32_bdma_config
{
    void *Instance;                      /**< BDMA channel instance pointer. */
    rt_uint32_t dma_rcc;                 /**< RCC enable bit for the BDMA controller. */
    IRQn_Type dma_irq;                   /**< NVIC IRQ number for the BDMA channel. */
    rt_uint32_t priority;                /**< BDMA transfer priority. */
    rt_uint8_t preempt_priority;         /**< NVIC preempt priority for the BDMA IRQ. */
    rt_uint8_t sub_priority;             /**< NVIC sub priority for the BDMA IRQ. */
    rt_uint32_t request;                 /**< BDMA request selector. */
    rt_uint32_t direction;               /**< BDMA transfer direction. */
    rt_uint32_t periph_inc;              /**< Peripheral address increment mode. */
    rt_uint32_t mem_inc;                 /**< Memory address increment mode. */
    rt_uint32_t periph_data_alignment;   /**< Peripheral data alignment. */
    rt_uint32_t mem_data_alignment;      /**< Memory data alignment. */
    rt_uint32_t mode;                    /**< BDMA transfer mode. */
};
  • 就像stm32_dma_config中关于GPDMA的特殊处理这样对BDMA进行处理就好了
  • stm32_dma_config中也有channel
  • 你可以看看BDMA中有什么特殊的结构体添加到stm32_dma_config中用宏隔开即可.
  • 这样子可以不再需要一个BDMA的文件了
  • 虽然这样子还是不够简洁,但是把dma逻辑散落到不同文件里面也是更难维护的
/**
 * @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) */
};
  • 我看了一些结构体的不同之处,好像并没有不同的地方?所有bdma可以使用Koconfig选择后把STM32_DMA_USES_REQUEST宏一并选择即可;这样BDMA的结构体就完成定义了
  • 至于具体的函数代码还有什么不同,我还没有查看;我认为应该可以在现有的dma代码中进行通过宏定义?或者flag?方案进行对于不同逻辑的使用和转接
  • 关于重复的配置:
    确实是如此。BDMA绝大部分配置都是在HAL库上和DMA通用的。但是我还是没有采取dma加宏定义的方式,因为DMA里面宏定义太多了,FIFO,Channel,等等有大量的宏编译分支(重新看了一下其实也不算很多,把下游SPI的条件编译看进去了),虽然BDMA基本上不用考虑这些,但是再加进去,我觉得会让DMA的可读性大大下降,此外我不是很清楚改动会对其他使用DMA的产生什么影响,比如uart等。
  • 关于结构体不同之处:
    也是正因如此,我觉得如果要合并,更合适的可能是单独开一个bdma类型,其能复用setup等逻辑,作为没有FIFO等特殊功能的普通DMA使用,不需要单独走编译分支

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

BSP: STM32 BSP related with ST/STM32 BSP

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants