STM32H7的DMAMUX
- 什么是DMAMUX
- DMA架构框图
- DMA requests from peripherals接口
- Trigger inputs 接口
- Interrupt 接口
- Synchronization inputs接口
- DMA Channels event接口
- DMA requests to DMA controllers接口
- 请求发生器
- 同步触发和请求复用器(Request multiplexer)
什么是DMAMUX
DMAMUX 其实就是 DMA 控制器前一级的多路选择器,有了这个选择器就不用再像 F1,F4 系列那样每个通道(数据流)要固定选择指定的外设,有了多路选择器就可以任意选择,外设使用 DMA 方式时无需再选择指定的 DMA 通道(数据流),任意通道(数据流)都可以。
当前STM32H7有两路DMAMUX,分别是DMAMUX1和DMAMUX2,其中DMAMUX1负责DMA1和 DMA2,而 DMAMUX2 负责 BDMA。
这张图反过来就好看多了。
DMAMUX2有8个输出通道,链接BDMA的8个输入通道。
DMA架构框图
DMA requests from peripherals接口
对于 DMAMUX1 来说,这个接口支持 107 个 DMA 外设请求,供 DMA1 和 DMA2 的数据流使用:
#define DMA_REQUEST_ADC1 9U /*!< DMAMUX1 ADC1 request */
#define DMA_REQUEST_ADC2 10U /*!< DMAMUX1 ADC2 request */
#define DMA_REQUEST_TIM1_CH1 11U /*!< DMAMUX1 TIM1 CH1 request */
#define DMA_REQUEST_TIM1_CH2 12U /*!< DMAMUX1 TIM1 CH2 request */
#define DMA_REQUEST_TIM1_CH3 13U /*!< DMAMUX1 TIM1 CH3 request */
#define DMA_REQUEST_TIM1_CH4 14U /*!< DMAMUX1 TIM1 CH4 request */
#define DMA_REQUEST_TIM1_UP 15U /*!< DMAMUX1 TIM1 UP request */
#define DMA_REQUEST_TIM1_TRIG 16U /*!< DMAMUX1 TIM1 TRIG request */
#define DMA_REQUEST_TIM1_COM 17U /*!< DMAMUX1 TIM1 COM request */
中间部分省略未写
#define DMA_REQUEST_TIM16_CH1 109U /*!< DMAMUX1 TIM16 CH1 request */
#define DMA_REQUEST_TIM16_UP 110U /*!< DMAMUX1 TIM16 UP request */
#define DMA_REQUEST_TIM17_CH1 111U /*!< DMAMUX1 TIM17 CH1 request */
#define DMA_REQUEST_TIM17_UP 112U /*!< DMAMUX1 TIM17 UP request */
#define DMA_REQUEST_SAI3_A 113U /*!< DMAMUX1 SAI3 A request */
#define DMA_REQUEST_SAI3_B 114U /*!< DMAMUX1 SAI3 B request */
#define DMA_REQUEST_ADC3 115U /*!< DMAMUX1 ADC3 request */
对于 DMAMUX2 来说,这个接口支持 9 个 DMA 外设请求,供 BDMA 通道使用:
#define BDMA_REQUEST_LPUART1_RX 9U /*!< DMAMUX2 LP_UART1_RX request */
#define BDMA_REQUEST_LPUART1_TX 10U /*!< DMAMUX2 LP_UART1_TX request */
#define BDMA_REQUEST_SPI6_RX 11U /*!< DMAMUX2 SPI6 RX request */
#define BDMA_REQUEST_SPI6_TX 12U /*!< DMAMUX2 SPI6 TX request */
#define BDMA_REQUEST_I2C4_RX 13U /*!< DMAMUX2 I2C4 RX request */
#define BDMA_REQUEST_I2C4_TX 14U /*!< DMAMUX2 I2C4 TX request */
#define BDMA_REQUEST_SAI4_A 15U /*!< DMAMUX2 SAI4 A request */
#define BDMA_REQUEST_SAI4_B 16U /*!< DMAMUX2 SAI4 B request */
#define BDMA_REQUEST_ADC3 17U /*!< DMAMUX2 ADC3 request */
这里特别注意一点,DMA1,DMA2 和 BDMA 都支持存储区到存储区的传输。
Trigger inputs 接口
除了正常的 DMA 请求可以输入到 DMAMUX 里面,通过设置触发条件也可以生成 DMA 触发请求。
这样就比较灵活了,不支持 DMA 的外设也可以通过 Trigger inputs 接口触发 DMA 传输,比如我们可以将 RAM 中的数据通过定时器触发直接输出到 GPIO,这样就可以产生各种脉冲效果。
DMAMUX1 支持 8 种触发输入,供 DMA1 和 DMA2 使用:
#define HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH0_EVT 0U
#define HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH1_EVT 1U
#define HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH2_EVT 2U
#define HAL_DMAMUX1_REQ_GEN_LPTIM1_OUT 3U
#define HAL_DMAMUX1_REQ_GEN_LPTIM2_OUT 4U
#define HAL_DMAMUX1_REQ_GEN_LPTIM3_OUT 5U
#define HAL_DMAMUX1_REQ_GEN_EXTI0 6U
#define HAL_DMAMUX1_REQ_GEN_TIM12_TRGO 7U
DMAMUX2 支持的 30 种触发输入,供 BDMA 使用:
#define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH0_EVT 0U
#define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH1_EVT 1U
#define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH2_EVT 2U
#define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH3_EVT 3U
#define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH4_EVT 4U
#define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH5_EVT 5U
#define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH6_EVT 6U
#define HAL_DMAMUX2_REQ_GEN_LPUART1_RX_WKUP 7U
#define HAL_DMAMUX2_REQ_GEN_LPUART1_TX_WKUP 8U
#define HAL_DMAMUX2_REQ_GEN_LPTIM2_WKUP 9U
#define HAL_DMAMUX2_REQ_GEN_LPTIM2_OUT 10U
#define HAL_DMAMUX2_REQ_GEN_LPTIM3_WKUP 11U
#define HAL_DMAMUX2_REQ_GEN_LPTIM3_OUT 12U
#define HAL_DMAMUX2_REQ_GEN_LPTIM4_WKUP 13U
#define HAL_DMAMUX2_REQ_GEN_LPTIM5_WKUP 14U
#define HAL_DMAMUX2_REQ_GEN_I2C4_WKUP 15U
#define HAL_DMAMUX2_REQ_GEN_SPI6_WKUP 16U
#define HAL_DMAMUX2_REQ_GEN_COMP1_OUT 17U
#define HAL_DMAMUX2_REQ_GEN_COMP2_OUT 18U
#define HAL_DMAMUX2_REQ_GEN_RTC_WKUP 19U
#define HAL_DMAMUX2_REQ_GEN_EXTI0 20U
#define HAL_DMAMUX2_REQ_GEN_EXTI2 21U
#define HAL_DMAMUX2_REQ_GEN_I2C4_IT_EVT 22U
#define HAL_DMAMUX2_REQ_GEN_SPI6_IT 23U
#define HAL_DMAMUX2_REQ_GEN_LPUART1_TX_IT 24U
#define HAL_DMAMUX2_REQ_GEN_LPUART1_RX_IT 25U
#define HAL_DMAMUX2_REQ_GEN_ADC3_IT 26U
#define HAL_DMAMUX2_REQ_GEN_ADC3_AWD1_OUT 27U
#define HAL_DMAMUX2_REQ_GEN_BDMA_CH0_IT 28U
#define HAL_DMAMUX2_REQ_GEN_BDMA_CH1_IT 29U
Interrupt 接口
用于触发中断。
Synchronization inputs接口
同步输入接口可以用来控制 DMAMUX 的输入端的 DMA 外设请求到输出端的同步控制,其实就是控制何时输出。
DMAMUX1 支持的 8 种同步输入,供 DMA1 和 DMA2 使用:
#define HAL_DMAMUX1_SYNC_DMAMUX1_CH0_EVT 0U
#define HAL_DMAMUX1_SYNC_DMAMUX1_CH1_EVT 1U
#define HAL_DMAMUX1_SYNC_DMAMUX1_CH2_EVT 2U
#define HAL_DMAMUX1_SYNC_LPTIM1_OUT 3U
#define HAL_DMAMUX1_SYNC_LPTIM2_OUT 4U
#define HAL_DMAMUX1_SYNC_LPTIM3_OUT 5U
#define HAL_DMAMUX1_SYNC_EXTI0 6U
#define HAL_DMAMUX1_SYNC_TIM12_TRGO 7U
DMAMUX2 支持的 16 种同步输入,供 BDMA 使用:
#define HAL_DMAMUX2_SYNC_DMAMUX2_CH0_EVT 0U
#define HAL_DMAMUX2_SYNC_DMAMUX2_CH1_EVT 1U
#define HAL_DMAMUX2_SYNC_DMAMUX2_CH2_EVT 2U
#define HAL_DMAMUX2_SYNC_DMAMUX2_CH3_EVT 3U
#define HAL_DMAMUX2_SYNC_DMAMUX2_CH4_EVT 4U
#define HAL_DMAMUX2_SYNC_DMAMUX2_CH5_EVT 5U
#define HAL_DMAMUX2_SYNC_LPUART1_RX_WKUP 6U
#define HAL_DMAMUX2_SYNC_LPUART1_TX_WKUP 7U
#define HAL_DMAMUX2_SYNC_LPTIM2_OUT 8U
#define HAL_DMAMUX2_SYNC_LPTIM3_OUT 9U
#define HAL_DMAMUX2_SYNC_I2C4_WKUP 10U
#define HAL_DMAMUX2_SYNC_SPI6_WKUP 11U
#define HAL_DMAMUX2_SYNC_COMP1_OUT 12U
#define HAL_DMAMUX2_SYNC_RTC_WKUP 13U
#define HAL_DMAMUX2_SYNC_EXTI0 14U
#define HAL_DMAMUX2_SYNC_EXTI2 15U
DMA Channels event接口
DMAMUX的事件输出
DMA requests to DMA controllers接口
DMAMUX的输出,发往DMA1、DMA2或者BDMA。
请求发生器
请求触发器最大的优势就是可以让不支持 DMA 传输的外设也可以通过 Trigger inputs 接口触发DMA 传输,比如我们可以将 RAM 中的数据通过定时器触发直接输出到 GPIO,这样就可以产生各种脉冲效果,这样就比较灵活了。
了解了之后,我们简单看一下它的时序图
- dmamux_req_gen 信号请求发生器生成的 DMA 请求。
- dmamux_req_out 信号是 DMAMUX 的输出,供 DMA1,DMA2 或者 BDMA 使用。
- Request generator counter 这个计数器比较重要,它的意思是一次 dmamux_trg 触发信号,可以连续执行的 DMA 请求,最大 32 次。这里是以 DMA 可以执行的最快速度进行响应的。每执行一次,计数器减 1,减到 0 后自动加载用户设置的最大次数,等待下次触发,依次进行。如果计数器还没有减到 0 就再次触发,请求发生器的中断状态寄存器 DMAMUX_RGSR 的标志将被置位,如果使能了中断,将会被触发。
- dmamux_trg 信号是触发源。
同步触发和请求复用器(Request multiplexer)
同步输入接口可以用来控制 DMAMUX 的输入端的 DMA 外设请求到输出端的同步控制,其实就是控制何时输出。
这里我们再进一步的认识下请求复用器,从下面的框图中可以看出请求发生器有 m 个通道,并且每个通道都支持 n+p+2 个 DMA 请求,但是每个通道不可以选择相同的 DMA 请求。
特别注意红色方框的地方,请求发生器的 n 个 DMA 请求和 p 个 DMA 外设请求全都汇集于此,可供这里的多路选择器选择。
dmamux_reqx 信号是请求复用器的输入端。
dmamux_syncx 是同步触发信号。
dmamux_req_outx 信号是 DMAMUX 的输出,供 DMA1,DMA2 或者 BDMA 使用。
DMA request counter 这个计数器比较重要,他的意思是一次dmamux_syncx 触发信号,可以连续执行的 DMA 请求,最大 32 次。这里是以 DMA 请求可以执行的最快速度进行响应的。每执行一次,计数器减 1,减到 0 后自动加载用户设置的最大次数,等待下次触发,依次进行。如果计数器还没有减到 0 就再次触发,请求发生器的中断状态寄存器 DMAMUX_CSR 的标志将被置位,如果使能了中断,将会被触发。
dmamux_evt 信号是输出事件。