39.1 初学者重要提示
DMAMUX其实就是DMA控制器前一级的多路选择器,有了这个选择器就不用再像F1,F4系列那样每个通道(数据流)要固定选择指定的外设,有了多路选择器就可以任意选择,外设使用DMA方式时无需再选择指定的DMA通道(数据流),任意通道(数据流)都可以。
39.2 DMAMUX基础知识
当前STM32H7有两路DMAMUX,分别是DMAMUX1和DMAMUX2,其中DMAMUX1负责DMA1和DMA2,而DMAMUX2负责BDMA。
39.2.1 DMAMUX和DMA的连接关系
认识一个外设,最好的方式就是看它的框图,方便我们快速的了解DMAMUX的基本功能,然后再看手册了解细节。首先来看下DMAMUX与DMA之间的连接方式,从整体上把握下,可以更好的理解DMAMUX的作用。
DMAMUX1有16个输出通道,前8个通道分别连接DMA1 Stream0到Stream7,而后8个通道分别连接DMA2 Stream0到Stream7。上面DMAMUX1的前8路接到DMA1的8路数据流通道Stream0到Stream7中。
DMAMUX2有8个输出通道,连接BDMA的8个输入通道:
39.2.2 DMAMUX的硬件框图
这个框图对于理解DMAMUX至关重要。
通过这个框图,我们可以得到如下信息:
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。
39.2.3 请求发生器(Request Generator)
请求触发器最大的优势就是可以让不支持DMA传输的外设也可以通过Trigger inputs接口触发DMA传输,比如我们可以将RAM中的数据通过定时器触发直接输出到GPIO,这样就可以产生各种脉冲效果,这样就比较灵活了。
这里我们再进一步的认识下请求发生器,通过下面框图可以看出请求发生器有n个通道,并且每个通道都支持t个触发。这里有一个关键知识点,所有这些通道可以选择同一个触发源。
了解了这些之后,我们要对它的工作过程有一个简单的认识,看下面的时序图:
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信号是触发源。
39.2.4 同步触发和请求复用器(Request multiplexer)
同步输入接口可以用来控制DMAMUX的输入端的DMA外设请求到输出端的同步控制,其实就是控制何时输出。
这里我们再进一步的认识下请求复用器,从下面的框图中可以看出请求发生器有m个通道,并且每个通道都支持n+p+2个DMA请求,但是每个通道不可以选择相同的DMA请求。
特别注意红色方框的地方,请求发生器的n个DMA请求和p个DMA外设请求全都汇集于此,可供这里的多路选择器选择。
了解了这些之后,我们要对它的工作过程有一个简单的认识,看下面的时序图:
下面连续同步三次的效果,每次产生4次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信号是输出事件。
39.2.5 正常的DMA请求方式
除了前面说的请求发生器产生的DMA请求和同步触发产生的DMA请求,关闭了这两种方式后也可以通过DMAMUX正常发出DMA请求的,这种情况和之前使用F1和F4系列是一样的。