BetaFlight统一硬件配置文件研读之dma命令

统一硬件配置文件的设计是一种非常好的设计模式,可以将硬件和软件的工作进行解耦。

1. 源由

cli命令中dma是对硬件DMA资源进行分配的一个操作。

DMA是SOC架构提供的功能,它能使数据:1)从设备直接发送到SOC内存;2)从内存直接发送到设备;3)从一个内存位置直接发送到另一个内存位置。

其最重要的一个特色就是当数据进行移动的时候,不需要CPU介入。而通常我们理解的CPU介入数据传输,不仅需要消耗CPU资源,还需要消耗总线和内存资源(任务切换),这样对于系统整体的性能就大大降低了。严重的时候会导致CPU频繁的在搬数据,而真正需要运算的业务就得不到及时处理,从而影响应用。

飞控对于系统实时性的要求是非常高。目前BetaFlight飞控设计中也大量配置和使用了DMA来提升性能。

注1:除了这个以外,STM32H7的DMA配置非常的灵活,对于习惯查表(以前很多DMA大部分都是和硬件端口绑定,因此可以找到Datasheet查表)的嵌入式朋友来说,确实也折腾了一段时间。为此整理下,希望后续能更进一步深入了解相关设计。

注2:本次看的配置是一块STM32H743芯片,具体datasheet,可以网上下载。

2. 代码分析

DMA这部分配置的代码看似很多,其实逻辑简单,其复杂的部分在于理解硬件和DMA配置之间的关系。早期MCU的DMA是可以通过查表配置的,目前H7的DMA多路复用的灵活性更高了。也就是说可以更好的灵活配置。此时这张DMA配置表就没有了。

主要可以配置的外设为pin和dmaoptEntryTable:

dmaoptEntry_t dmaoptEntryTable[] = {
    DEFW("SPI_SDO", DMA_PERIPH_SPI_SDO, PG_SPI_PIN_CONFIG,     spiPinConfig_t,     txDmaopt, SPIDEV_COUNT,                    MASK_IGNORED),
    DEFW("SPI_SDI", DMA_PERIPH_SPI_SDI, PG_SPI_PIN_CONFIG,     spiPinConfig_t,     rxDmaopt, SPIDEV_COUNT,                    MASK_IGNORED),
    // SPI_TX/SPI_RX for backwards compatibility with unified configs defined for 4.2.x
    DEFW("SPI_TX",   DMA_PERIPH_SPI_SDO, PG_SPI_PIN_CONFIG,     spiPinConfig_t,     txDmaopt, SPIDEV_COUNT,                    MASK_IGNORED),
    DEFW("SPI_RX",   DMA_PERIPH_SPI_SDI, PG_SPI_PIN_CONFIG,     spiPinConfig_t,     rxDmaopt, SPIDEV_COUNT,                    MASK_IGNORED),
    DEFA("ADC",      DMA_PERIPH_ADC,      PG_ADC_CONFIG,         adcConfig_t,        dmaopt,   ADCDEV_COUNT,                    MASK_IGNORED),
    DEFS("SDIO",     DMA_PERIPH_SDIO,     PG_SDIO_CONFIG,        sdioConfig_t,       dmaopt),
    DEFW("UART_TX",  DMA_PERIPH_UART_TX,  PG_SERIAL_UART_CONFIG, serialUartConfig_t, txDmaopt, UARTDEV_CONFIG_MAX,              MASK_IGNORED),
    DEFW("UART_RX",  DMA_PERIPH_UART_RX,  PG_SERIAL_UART_CONFIG, serialUartConfig_t, rxDmaopt, UARTDEV_CONFIG_MAX,              MASK_IGNORED),
#if defined(STM32H7) || defined(STM32G4)
    DEFW("TIMUP",    DMA_PERIPH_TIMUP,    PG_TIMER_UP_CONFIG,    timerUpConfig_t,    dmaopt,   HARDWARE_TIMER_DEFINITION_COUNT, TIMUP_TIMERS),
#endif
};

2.1 cliDma

直接将dma资源分配命令切分为两部分:

  1. showDma //外设DMA配置情况
  2. cliDmaopt //配置DMA
cliDma
 ├──> "show"
 │   └──> showDma()
 └──> cliDmaopt(cmdName, cmdline)

注:常见情况USE_DMA_SPEC已定义。

2.2 showDma

这里以外设owner的角度给出DMA资源配置情况。

showDma
 ├──> cliPrintLinefeed()
 ├──> cliPrintLine("Currently active DMA:")
 └──> loop DMA_LAST_HANDLER
     ├──> const resourceOwner_t *owner = dmaGetOwner(i)
     ├──> cliPrintf(DMA_OUTPUT_STRING, DMA_DEVICE_NO(i), DMA_DEVICE_INDEX(i))
     ├──> <owner->resourceIndex > 0>
     │   └──> cliPrintLinef(" %s %d", ownerNames[owner->owner], owner->resourceIndex)
     └──> <owner->resourceIndex <= 0>cliPrintLinef(" %s", ownerNames[owner->owner])
         └──> cliPrintLinef(" %s", ownerNames[owner->owner])

注:常见情况MINIMAL_CLI无定义。

2.3 cliDmaopt

cliDmaopt
 ├──> [Peripheral name or command option]
 │   ├──> pch = strtok_r(cmdline, " ", &saveptr);
 │   ├──> <!pch> //无命令
 │   │   └──> printDmaopt(DUMP_MASTER | HIDE_UNUSED, NULL); return
 │   └──> <"list"> //有命令  
 │       └──> "dma: NOT IMPLEMENTED YET"
 ├──> [Get peripheral name or pin]
 │   ├──> <search dmaoptEntryTable for peripheral: SPI_SDO/SPI_SDI/SPI_TX/SPI_RX/ADC/SDIO/UART_TX/UART_RX/TIMUP> 
 │   │   └──> [assign dmaoptEntry_t *entry]
 │   └──> "pin" //如果是pin引脚
 │       └──> [dmaoptEntry_t *entry = NULL]
 ├──> [default settings]
 │   └──> dmaoptValue_t orgval = DMA_OPT_UNUSED; dmaoptValue_t *optaddr = NULL; timerIOConfig_t *timerIoConfig = NULL; timerHardware_t *timer = NULL;
 ├──> <entry> //Peripheral
 │   ├──> index = pch ? (atoi(pch) - 1) : -1;  //index赋值及边界检查
 │   └──> orgval = *optaddr; //获取设备index的原始optval
 ├──> <pin> //pin
 │   ├──> orgval = dmaoptByTag(ioTag); //通过dmaoptByTag获取pin引脚原始optval
 │   └──> timerIoConfig = timerIoConfigByTag(ioTag); timer = timerGetConfiguredByTag(ioTag); //引脚对应的timer配置
 └──> [opt or list]
     ├──> <!pch> //无optval参数
     │   ├──> <entry> printPeripheralDmaoptDetails(entry, index, *optaddr, true, DUMP_MASTER, cliDumpPrintLinef) // peripheral dma配置打印输出
     │   └──> <!entry> printTimerDmaoptDetails(ioTag, timer, orgval, true, DUMP_MASTER, cliDumpPrintLinef) //pin dma配置打印输出
     ├──> "list"
     │   ├──> <entry> printPeripheralDmaoptDetails(entry, index, *optaddr, true, DUMP_MASTER, cliDumpPrintLinef) // peripheral dma可配置 打印输出
     │   └──> <!entry> printTimerDmaoptDetails(ioTag, timer, orgval, true, DUMP_MASTER, cliDumpPrintLinef) //pin dma可配置 打印输出
     └──> <pch> //资源分配
         ├──> <"none"> optval = DMA_OPT_UNUSED;
         └──> <not "none"> optval = atoi(pch);
             ├──> <entry> dmaGetChannelSpecByPeripheral(entry->peripheral, index, optval)  // 检查设备optval有效性
             ├──> <!entry> dmaGetChannelSpecByTimerValue(timer->tim, timer->channel, optval)  // 检查引脚optval有效性
             ├──> <optval == orgval>
             │   ├──> <entry> *optaddr = optval;  // 设备optval赋值
             │   └──> <!entry> timerIoConfig->dmaopt = optval;  // 引脚optval赋值
             └──> <optval != orgval>  "no change" 打印命令执行结果

注:常见情况USE_TIMER_MGMT已定义。

3. 实例分析

# dma
dma ADC 1 8
# ADC 1: DMA2 Stream 0 Request 9
dma ADC 3 9
# ADC 3: DMA2 Stream 1 Request 115
dma TIMUP 1 0
# TIMUP 1: DMA1 Stream 0 Request 15
dma TIMUP 3 2
# TIMUP 3: DMA1 Stream 2 Request 27
dma TIMUP 4 1
# TIMUP 4: DMA1 Stream 1 Request 32
dma TIMUP 5 0
# TIMUP 5: DMA1 Stream 0 Request 59
dma pin A10 0
# pin A10: DMA1 Stream 0 Request 13
dma pin B00 0
# pin B00: DMA1 Stream 0 Request 25
dma pin B01 1
# pin B01: DMA1 Stream 1 Request 26
dma pin A00 2
# pin A00: DMA1 Stream 2 Request 55
dma pin A01 3
# pin A01: DMA1 Stream 3 Request 56
dma pin A02 4
# pin A02: DMA1 Stream 4 Request 57
dma pin A03 5
# pin A03: DMA1 Stream 5 Request 58
dma pin D12 6
# pin D12: DMA1 Stream 6 Request 29
dma pin D13 7
# pin D13: DMA1 Stream 7 Request 30
dma pin D14 12
# pin D14: DMA2 Stream 4 Request 31
dma pin E05 0
# pin E05: DMA1 Stream 0 Request 105
dma pin A08 14
# pin A08: DMA2 Stream 6 Request 11

4. 配置情况

# help dma
dma - show/set DMA assignments
	<> | <device> <index> list | <device> <index> [<option>|none] | list | show

4.1 dma

当前配置情况列表。

# dma
dma ADC 1 8
# ADC 1: DMA2 Stream 0 Request 9
dma ADC 3 9
# ADC 3: DMA2 Stream 1 Request 115
dma TIMUP 1 0
# TIMUP 1: DMA1 Stream 0 Request 15
dma TIMUP 3 2
# TIMUP 3: DMA1 Stream 2 Request 27
dma TIMUP 4 1
# TIMUP 4: DMA1 Stream 1 Request 32
dma TIMUP 5 0
# TIMUP 5: DMA1 Stream 0 Request 59
dma pin A10 0
# pin A10: DMA1 Stream 0 Request 13
dma pin B00 0
# pin B00: DMA1 Stream 0 Request 25
dma pin B01 1
# pin B01: DMA1 Stream 1 Request 26
dma pin A00 2
# pin A00: DMA1 Stream 2 Request 55
dma pin A01 3
# pin A01: DMA1 Stream 3 Request 56
dma pin A02 4
# pin A02: DMA1 Stream 4 Request 57
dma pin A03 5
# pin A03: DMA1 Stream 5 Request 58
dma pin D12 6
# pin D12: DMA1 Stream 6 Request 29
dma pin D13 7
# pin D13: DMA1 Stream 7 Request 30
dma pin D14 12
# pin D14: DMA2 Stream 4 Request 31
dma pin E05 0
# pin E05: DMA1 Stream 0 Request 105
dma pin A08 14
# pin A08: DMA2 Stream 6 Request 11

4.2 dma show

按照DMA stream上的各外设分配情况。

\# dma show

Currently active DMA:
--------------------
DMA1 Stream 0: DSHOT_BITBANG 2
DMA1 Stream 1: DSHOT_BITBANG 1
DMA1 Stream 2: SPI_MOSI 1
DMA1 Stream 3: SPI_MISO 1
DMA1 Stream 4: SPI_MOSI 2
DMA1 Stream 5: SPI_MISO 2
DMA1 Stream 6: SPI_MOSI 3
DMA1 Stream 7: SPI_MISO 3
DMA2 Stream 0: ADC 1
DMA2 Stream 1: ADC 3
DMA2 Stream 2: SPI_MOSI 4
DMA2 Stream 3: SPI_MISO 4
DMA2 Stream 4: FREE
DMA2 Stream 5: FREE
DMA2 Stream 6: LED_STRIP
DMA2 Stream 7: FREE

4.3 dma device list

设备可分配DMA资源列表。

# dma adc 1 list
# 0: DMA1 Stream 0 Request 9
# 1: DMA1 Stream 1 Request 9
# 2: DMA1 Stream 2 Request 9
# 3: DMA1 Stream 3 Request 9
# 4: DMA1 Stream 4 Request 9
# 5: DMA1 Stream 5 Request 9
# 6: DMA1 Stream 6 Request 9
# 7: DMA1 Stream 7 Request 9
# 8: DMA2 Stream 0 Request 9
# 9: DMA2 Stream 1 Request 9
# 10: DMA2 Stream 2 Request 9
# 11: DMA2 Stream 3 Request 9
# 12: DMA2 Stream 4 Request 9
# 13: DMA2 Stream 5 Request 9
# 14: DMA2 Stream 6 Request 9
# 15: DMA2 Stream 7 Request 9

# dma adc 2 list
# 0: DMA1 Stream 0 Request 10
# 1: DMA1 Stream 1 Request 10
# 2: DMA1 Stream 2 Request 10
# 3: DMA1 Stream 3 Request 10
# 4: DMA1 Stream 4 Request 10
# 5: DMA1 Stream 5 Request 10
# 6: DMA1 Stream 6 Request 10
# 7: DMA1 Stream 7 Request 10
# 8: DMA2 Stream 0 Request 10
# 9: DMA2 Stream 1 Request 10
# 10: DMA2 Stream 2 Request 10
# 11: DMA2 Stream 3 Request 10
# 12: DMA2 Stream 4 Request 10
# 13: DMA2 Stream 5 Request 10
# 14: DMA2 Stream 6 Request 10
# 15: DMA2 Stream 7 Request 10

# dma adc 3 list
# 0: DMA1 Stream 0 Request 115
# 1: DMA1 Stream 1 Request 115
# 2: DMA1 Stream 2 Request 115
# 3: DMA1 Stream 3 Request 115
# 4: DMA1 Stream 4 Request 115
# 5: DMA1 Stream 5 Request 115
# 6: DMA1 Stream 6 Request 115
# 7: DMA1 Stream 7 Request 115
# 8: DMA2 Stream 0 Request 115
# 9: DMA2 Stream 1 Request 115
# 10: DMA2 Stream 2 Request 115
# 11: DMA2 Stream 3 Request 115
# 12: DMA2 Stream 4 Request 115
# 13: DMA2 Stream 5 Request 115
# 14: DMA2 Stream 6 Request 115
# 15: DMA2 Stream 7 Request 115

4.4 dma pin list

pin脚可分配DMA资源列表。

# dma pin A10 list
# 0: DMA1 Stream 0 Request 13
# 1: DMA1 Stream 1 Request 13
# 2: DMA1 Stream 2 Request 13
# 3: DMA1 Stream 3 Request 13
# 4: DMA1 Stream 4 Request 13
# 5: DMA1 Stream 5 Request 13
# 6: DMA1 Stream 6 Request 13
# 7: DMA1 Stream 7 Request 13
# 8: DMA2 Stream 0 Request 13
# 9: DMA2 Stream 1 Request 13
# 10: DMA2 Stream 2 Request 13
# 11: DMA2 Stream 3 Request 13
# 12: DMA2 Stream 4 Request 13
# 13: DMA2 Stream 5 Request 13
# 14: DMA2 Stream 6 Request 13
# 15: DMA2 Stream 7 Request 13

4.5 dma device id

设备DMA资源配置情况。

4.5.1 dma adc id

# dma adc 1
dma ADC 1 8
# ADC 1: DMA2 Stream 0 Request 9

4.5.2 dma TIMUP id

# dma timup 5
dma TIMUP 5 0
# TIMUP 5: DMA1 Stream 0 Request 59

4.5.3 dma pin id

# dma pin A10
dma pin A10 0
# pin A10: DMA1 Stream 0 Request 13

4.6 dma device id stream

设备DMA资源配置,因为多路复用可以随意配置(不考虑优先级/冲突)。

4.6.1 dma adc id stream

# dma adc 1
dma ADC 1 8
# ADC 1: DMA2 Stream 0 Request 9

# dma adc 1 10
# dma ADC 1: changed from 8 to 10

# dma adc 1
dma ADC 1 10
# ADC 1: DMA2 Stream 2 Request 9

4.6.2 dma TIMUP id stream

# dma timup 5
dma TIMUP 5 0
# TIMUP 5: DMA1 Stream 0 Request 59

# dma TIMUP 5 1
# dma TIMUP 5: changed from 0 to 1

# dma TIMUP 5
dma TIMUP 5 1
# TIMUP 5: DMA1 Stream 1 Request 59

4.6.3 dma pin id stream

# dma pin A10
dma pin A10 0
# pin A10: DMA1 Stream 0 Request 13

# dma pin A10 1
# dma pin A10: changed from 0 to 1

# dma pin A10
dma pin A10 1
# pin A10: DMA1 Stream 1 Request 13

5. STM32 H743

5.1 DMA简介

大体上,通过RM0433资料:

  1. H743 DMA控制器 x 2
  2. 每个DMA控制器 有 stream x 8
  3. DMA stream由 DMAMUX信号来驱动(Request)
  4. Request信号可以是115种可用信号的其中一种
    在这里插入图片描述

DMA主要功能不在这里展开,希望更多了解请下载RM0433资料,更深入的了解DMA技术细节,可以对工作原理,优先级、带宽、工作模式优化提供帮助,但这不是本章节重点。有兴趣的朋友可以自行研究先,有时间我们会在后续驱动方面的文章中进行探讨。

在这里插入图片描述

从这里我们就可以理解request信号源来自17.3.2章节,这里给出BF里面用到的DMA表格。

在这里插入图片描述

5.2 DMAMUX1 关联

这些定义已被HAL打包定义,详见:\lib\main\STM32H7\Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma.h

/** @defgroup DMA_Request_selection DMA Request selection
  * @brief    DMA Request selection
  * @{
  */
/* DMAMUX1 requests */
#define DMA_REQUEST_MEM2MEM          0U  /*!< memory to memory transfer   */

#define DMA_REQUEST_GENERATOR0       1U  /*!< DMAMUX1 request generator 0 */
#define DMA_REQUEST_GENERATOR1       2U  /*!< DMAMUX1 request generator 1 */
#define DMA_REQUEST_GENERATOR2       3U  /*!< DMAMUX1 request generator 2 */
#define DMA_REQUEST_GENERATOR3       4U  /*!< DMAMUX1 request generator 3 */
#define DMA_REQUEST_GENERATOR4       5U  /*!< DMAMUX1 request generator 4 */
#define DMA_REQUEST_GENERATOR5       6U  /*!< DMAMUX1 request generator 5 */
#define DMA_REQUEST_GENERATOR6       7U  /*!< DMAMUX1 request generator 6 */
#define DMA_REQUEST_GENERATOR7       8U  /*!< DMAMUX1 request generator 7 */

#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_TIM2_CH1         18U  /*!< DMAMUX1 TIM2 CH1 request  */
#define DMA_REQUEST_TIM2_CH2         19U  /*!< DMAMUX1 TIM2 CH2 request  */
#define DMA_REQUEST_TIM2_CH3         20U  /*!< DMAMUX1 TIM2 CH3 request  */
#define DMA_REQUEST_TIM2_CH4         21U  /*!< DMAMUX1 TIM2 CH4 request  */
#define DMA_REQUEST_TIM2_UP          22U  /*!< DMAMUX1 TIM2 UP request   */

#define DMA_REQUEST_TIM3_CH1         23U  /*!< DMAMUX1 TIM3 CH1 request  */
#define DMA_REQUEST_TIM3_CH2         24U  /*!< DMAMUX1 TIM3 CH2 request  */
#define DMA_REQUEST_TIM3_CH3         25U  /*!< DMAMUX1 TIM3 CH3 request  */
#define DMA_REQUEST_TIM3_CH4         26U  /*!< DMAMUX1 TIM3 CH4 request  */
#define DMA_REQUEST_TIM3_UP          27U  /*!< DMAMUX1 TIM3 UP request   */
#define DMA_REQUEST_TIM3_TRIG        28U  /*!< DMAMUX1 TIM3 TRIG request */

#define DMA_REQUEST_TIM4_CH1         29U  /*!< DMAMUX1 TIM4 CH1 request  */
#define DMA_REQUEST_TIM4_CH2         30U  /*!< DMAMUX1 TIM4 CH2 request  */
#define DMA_REQUEST_TIM4_CH3         31U  /*!< DMAMUX1 TIM4 CH3 request  */
#define DMA_REQUEST_TIM4_UP          32U  /*!< DMAMUX1 TIM4 UP request   */

#define DMA_REQUEST_I2C1_RX          33U  /*!< DMAMUX1 I2C1 RX request   */
#define DMA_REQUEST_I2C1_TX          34U  /*!< DMAMUX1 I2C1 TX request   */
#define DMA_REQUEST_I2C2_RX          35U  /*!< DMAMUX1 I2C2 RX request   */
#define DMA_REQUEST_I2C2_TX          36U  /*!< DMAMUX1 I2C2 TX request   */

#define DMA_REQUEST_SPI1_RX          37U  /*!< DMAMUX1 SPI1 RX request   */
#define DMA_REQUEST_SPI1_TX          38U  /*!< DMAMUX1 SPI1 TX request   */
#define DMA_REQUEST_SPI2_RX          39U  /*!< DMAMUX1 SPI2 RX request   */
#define DMA_REQUEST_SPI2_TX          40U  /*!< DMAMUX1 SPI2 TX request   */

#define DMA_REQUEST_USART1_RX        41U  /*!< DMAMUX1 USART1 RX request */
#define DMA_REQUEST_USART1_TX        42U  /*!< DMAMUX1 USART1 TX request */
#define DMA_REQUEST_USART2_RX        43U  /*!< DMAMUX1 USART2 RX request */
#define DMA_REQUEST_USART2_TX        44U  /*!< DMAMUX1 USART2 TX request */
#define DMA_REQUEST_USART3_RX        45U  /*!< DMAMUX1 USART3 RX request */
#define DMA_REQUEST_USART3_TX        46U  /*!< DMAMUX1 USART3 TX request */

#define DMA_REQUEST_TIM8_CH1         47U  /*!< DMAMUX1 TIM8 CH1 request  */
#define DMA_REQUEST_TIM8_CH2         48U  /*!< DMAMUX1 TIM8 CH2 request  */
#define DMA_REQUEST_TIM8_CH3         49U  /*!< DMAMUX1 TIM8 CH3 request  */
#define DMA_REQUEST_TIM8_CH4         50U  /*!< DMAMUX1 TIM8 CH4 request  */
#define DMA_REQUEST_TIM8_UP          51U  /*!< DMAMUX1 TIM8 UP request   */
#define DMA_REQUEST_TIM8_TRIG        52U  /*!< DMAMUX1 TIM8 TRIG request */
#define DMA_REQUEST_TIM8_COM         53U  /*!< DMAMUX1 TIM8 COM request  */

#define DMA_REQUEST_TIM5_CH1         55U  /*!< DMAMUX1 TIM5 CH1 request  */
#define DMA_REQUEST_TIM5_CH2         56U  /*!< DMAMUX1 TIM5 CH2 request  */
#define DMA_REQUEST_TIM5_CH3         57U  /*!< DMAMUX1 TIM5 CH3 request  */
#define DMA_REQUEST_TIM5_CH4         58U  /*!< DMAMUX1 TIM5 CH4 request  */
#define DMA_REQUEST_TIM5_UP          59U  /*!< DMAMUX1 TIM5 UP request   */
#define DMA_REQUEST_TIM5_TRIG        60U  /*!< DMAMUX1 TIM5 TRIG request */

#define DMA_REQUEST_SPI3_RX          61U  /*!< DMAMUX1 SPI3 RX request   */
#define DMA_REQUEST_SPI3_TX          62U  /*!< DMAMUX1 SPI3 TX request   */

#define DMA_REQUEST_UART4_RX         63U  /*!< DMAMUX1 UART4 RX request */
#define DMA_REQUEST_UART4_TX         64U  /*!< DMAMUX1 UART4 TX request */
#define DMA_REQUEST_UART5_RX         65U  /*!< DMAMUX1 UART5 RX request */
#define DMA_REQUEST_UART5_TX         66U  /*!< DMAMUX1 UART5 TX request */

#define DMA_REQUEST_DAC1_CH1         67U  /*!< DMAMUX1 DAC1 Channel 1 request */
#define DMA_REQUEST_DAC1_CH2         68U  /*!< DMAMUX1 DAC1 Channel 2 request */

#define DMA_REQUEST_TIM6_UP          69U  /*!< DMAMUX1 TIM6 UP request   */
#define DMA_REQUEST_TIM7_UP          70U  /*!< DMAMUX1 TIM7 UP request   */

#define DMA_REQUEST_USART6_RX        71U  /*!< DMAMUX1 USART6 RX request */
#define DMA_REQUEST_USART6_TX        72U  /*!< DMAMUX1 USART6 TX request */

#define DMA_REQUEST_I2C3_RX          73U  /*!< DMAMUX1 I2C3 RX request   */
#define DMA_REQUEST_I2C3_TX          74U  /*!< DMAMUX1 I2C3 TX request   */

#if defined (PSSI)
#define DMA_REQUEST_DCMI_PSSI        75U  /*!< DMAMUX1 DCMI/PSSI request    */
#define DMA_REQUEST_DCMI             DMA_REQUEST_DCMI_PSSI /* Legacy define */
#else
#define DMA_REQUEST_DCMI             75U  /*!< DMAMUX1 DCMI request         */
#endif /* PSSI */

#define DMA_REQUEST_CRYP_IN          76U  /*!< DMAMUX1 CRYP IN request   */
#define DMA_REQUEST_CRYP_OUT         77U  /*!< DMAMUX1 CRYP OUT request  */

#define DMA_REQUEST_HASH_IN          78U  /*!< DMAMUX1 HASH IN request   */

#define DMA_REQUEST_UART7_RX         79U  /*!< DMAMUX1 UART7 RX request  */
#define DMA_REQUEST_UART7_TX         80U  /*!< DMAMUX1 UART7 TX request  */
#define DMA_REQUEST_UART8_RX         81U  /*!< DMAMUX1 UART8 RX request  */
#define DMA_REQUEST_UART8_TX         82U  /*!< DMAMUX1 UART8 TX request  */

#define DMA_REQUEST_SPI4_RX          83U  /*!< DMAMUX1 SPI4 RX request   */
#define DMA_REQUEST_SPI4_TX          84U  /*!< DMAMUX1 SPI4 TX request   */
#define DMA_REQUEST_SPI5_RX          85U  /*!< DMAMUX1 SPI5 RX request   */
#define DMA_REQUEST_SPI5_TX          86U  /*!< DMAMUX1 SPI5 TX request   */

#define DMA_REQUEST_SAI1_A           87U  /*!< DMAMUX1 SAI1 A request    */
#define DMA_REQUEST_SAI1_B           88U  /*!< DMAMUX1 SAI1 B request    */

#if defined(SAI2)
#define DMA_REQUEST_SAI2_A           89U  /*!< DMAMUX1 SAI2 A request    */
#define DMA_REQUEST_SAI2_B           90U  /*!< DMAMUX1 SAI2 B request    */
#endif /* SAI2 */

#define DMA_REQUEST_SWPMI_RX         91U  /*!< DMAMUX1 SWPMI RX request  */
#define DMA_REQUEST_SWPMI_TX         92U  /*!< DMAMUX1 SWPMI TX request  */

#define DMA_REQUEST_SPDIF_RX_DT      93U  /*!< DMAMUX1 SPDIF RXDT request*/
#define DMA_REQUEST_SPDIF_RX_CS      94U  /*!< DMAMUX1 SPDIF RXCS request*/

#if defined(HRTIM1)
#define DMA_REQUEST_HRTIM_MASTER     95U  /*!< DMAMUX1 HRTIM1 Master request 1 */
#define DMA_REQUEST_HRTIM_TIMER_A    96U  /*!< DMAMUX1 HRTIM1 TimerA request 2 */
#define DMA_REQUEST_HRTIM_TIMER_B    97U  /*!< DMAMUX1 HRTIM1 TimerB request 3 */
#define DMA_REQUEST_HRTIM_TIMER_C    98U  /*!< DMAMUX1 HRTIM1 TimerC request 4 */
#define DMA_REQUEST_HRTIM_TIMER_D    99U  /*!< DMAMUX1 HRTIM1 TimerD request 5 */
#define DMA_REQUEST_HRTIM_TIMER_E   100U  /*!< DMAMUX1 HRTIM1 TimerE request 6 */
#endif /* HRTIM1 */

#define DMA_REQUEST_DFSDM1_FLT0     101U  /*!< DMAMUX1 DFSDM Filter0 request */
#define DMA_REQUEST_DFSDM1_FLT1     102U  /*!< DMAMUX1 DFSDM Filter1 request */
#define DMA_REQUEST_DFSDM1_FLT2     103U  /*!< DMAMUX1 DFSDM Filter2 request */
#define DMA_REQUEST_DFSDM1_FLT3     104U  /*!< DMAMUX1 DFSDM Filter3 request */

#define DMA_REQUEST_TIM15_CH1       105U  /*!< DMAMUX1 TIM15 CH1 request  */
#define DMA_REQUEST_TIM15_UP        106U  /*!< DMAMUX1 TIM15 UP request   */
#define DMA_REQUEST_TIM15_TRIG      107U  /*!< DMAMUX1 TIM15 TRIG request */
#define DMA_REQUEST_TIM15_COM       108U  /*!< DMAMUX1 TIM15 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   */

#if defined(SAI3)
#define DMA_REQUEST_SAI3_A          113U  /*!< DMAMUX1 SAI3 A request  */
#define DMA_REQUEST_SAI3_B          114U  /*!< DMAMUX1 SAI3 B request  */
#endif /* SAI3 */

#if defined(ADC3)
#define DMA_REQUEST_ADC3            115U  /*!< DMAMUX1 ADC3 request  */
#endif /* ADC3 */

#if defined(UART9)
#define DMA_REQUEST_UART9_RX        116U  /*!< DMAMUX1 UART9 request  */
#define DMA_REQUEST_UART9_TX        117U  /*!< DMAMUX1 UART9 request  */
#endif /* UART9 */

#if defined(USART10)
#define DMA_REQUEST_USART10_RX      118U  /*!< DMAMUX1 USART10 request  */
#define DMA_REQUEST_USART10_TX      119U  /*!< DMAMUX1 USART10 request  */
#endif /* USART10 */

#if defined(FMAC)
#define DMA_REQUEST_FMAC_READ       120U  /*!< DMAMUX1 FMAC Read request  */
#define DMA_REQUEST_FMAC_WRITE      121U  /*!< DMAMUX1 FMAC Write request */
#endif /* FMAC */

#if defined(CORDIC)
#define DMA_REQUEST_CORDIC_READ     122U  /*!< DMAMUX1 CORDIC Read request  */
#define DMA_REQUEST_CORDIC_WRITE    123U  /*!< DMAMUX1 CORDIC Write request */
#endif /* CORDIC */

#if defined(I2C5)
#define DMA_REQUEST_I2C5_RX         124U  /*!< DMAMUX1 I2C5 RX request   */
#define DMA_REQUEST_I2C5_TX         125U  /*!< DMAMUX1 I2C5 TX request   */
#endif /* I2C5 */

#if defined(TIM23)
#define DMA_REQUEST_TIM23_CH1        126U  /*!< DMAMUX1 TIM23 CH1 request  */
#define DMA_REQUEST_TIM23_CH2        127U  /*!< DMAMUX1 TIM23 CH2 request  */
#define DMA_REQUEST_TIM23_CH3        128U  /*!< DMAMUX1 TIM23 CH3 request  */
#define DMA_REQUEST_TIM23_CH4        129U  /*!< DMAMUX1 TIM23 CH4 request  */
#define DMA_REQUEST_TIM23_UP         130U  /*!< DMAMUX1 TIM23 UP request   */
#define DMA_REQUEST_TIM23_TRIG       131U  /*!< DMAMUX1 TIM23 TRIG request */
#endif /* TIM23 */

#if defined(TIM24)
#define DMA_REQUEST_TIM24_CH1        132U  /*!< DMAMUX1 TIM24 CH1 request  */
#define DMA_REQUEST_TIM24_CH2        133U  /*!< DMAMUX1 TIM24 CH2 request  */
#define DMA_REQUEST_TIM24_CH3        134U  /*!< DMAMUX1 TIM24 CH3 request  */
#define DMA_REQUEST_TIM24_CH4        135U  /*!< DMAMUX1 TIM24 CH4 request  */
#define DMA_REQUEST_TIM24_UP         136U  /*!< DMAMUX1 TIM24 UP request   */
#define DMA_REQUEST_TIM24_TRIG       137U  /*!< DMAMUX1 TIM24 TRIG request */
#endif /* TIM24 */

5.3 dmaPeripheralMapping 关联

static const dmaPeripheralMapping_t dmaPeripheralMapping[] = {
#ifdef USE_SPI
    REQMAP_DIR(SPI, 1, SDO),
    REQMAP_DIR(SPI, 1, SDI),
    REQMAP_DIR(SPI, 2, SDO),
    REQMAP_DIR(SPI, 2, SDI),
    REQMAP_DIR(SPI, 3, SDO),
    REQMAP_DIR(SPI, 3, SDI),
    REQMAP_DIR(SPI, 4, SDO),
    REQMAP_DIR(SPI, 4, SDI),
    REQMAP_DIR(SPI, 5, SDO), // Not available in smaller packages
    REQMAP_DIR(SPI, 5, SDI), // ditto
    // REQMAP_DIR(SPI, 6, SDO), // SPI6 is on BDMA (todo)
    // REQMAP_DIR(SPI, 6, SDO), // ditto
#endif // USE_SPI

#ifdef USE_ADC
    REQMAP(ADC, 1),
    REQMAP(ADC, 2),
#if defined(STM32H743xx) || defined(STM32H750xx) || defined(STM32H723xx) || defined(STM32H725xx) || defined(STM32H730xx)
    REQMAP(ADC, 3),
#endif
#endif

#ifdef USE_UART
    REQMAP_DIR(UART, 1, TX),
    REQMAP_DIR(UART, 1, RX),
    REQMAP_DIR(UART, 2, TX),
    REQMAP_DIR(UART, 2, RX),
    REQMAP_DIR(UART, 3, TX),
    REQMAP_DIR(UART, 3, RX),
    REQMAP_DIR(UART, 4, TX),
    REQMAP_DIR(UART, 4, RX),
    REQMAP_DIR(UART, 5, TX),
    REQMAP_DIR(UART, 5, RX),
    REQMAP_DIR(UART, 6, TX),
    REQMAP_DIR(UART, 6, RX),
    REQMAP_DIR(UART, 7, TX),
    REQMAP_DIR(UART, 7, RX),
    REQMAP_DIR(UART, 8, TX),
    REQMAP_DIR(UART, 8, RX),
#if defined(STM32H7A3xxQ)
    REQMAP_DIR(UART, 9, TX),
    REQMAP_DIR(UART, 9, RX),
    REQMAP_DIR(UART, 10, TX),
    REQMAP_DIR(UART, 10, RX),
#endif
#ifdef USE_LPUART1
    { DMA_PERIPH_UART_TX, LPUARTDEV_1, BDMA_REQUEST_LPUART1_TX },
    { DMA_PERIPH_UART_RX, LPUARTDEV_1, BDMA_REQUEST_LPUART1_RX },
#endif
#endif

#ifdef USE_TIMER
// Pseudo peripheral for TIMx_UP channel
    REQMAP_TIMUP(TIMUP, 1),
    REQMAP_TIMUP(TIMUP, 2),
    REQMAP_TIMUP(TIMUP, 3),
    REQMAP_TIMUP(TIMUP, 4),
    REQMAP_TIMUP(TIMUP, 5),
    REQMAP_TIMUP(TIMUP, 6),
    REQMAP_TIMUP(TIMUP, 7),
    REQMAP_TIMUP(TIMUP, 8),
    REQMAP_TIMUP(TIMUP, 15),
    REQMAP_TIMUP(TIMUP, 16),
    REQMAP_TIMUP(TIMUP, 17),
#endif
};

5.4 dmaTimerMapping关联

static const dmaTimerMapping_t dmaTimerMapping[] = {
    REQMAP_TIM(TIM1, CH1),
    REQMAP_TIM(TIM1, CH2),
    REQMAP_TIM(TIM1, CH3),
    REQMAP_TIM(TIM1, CH4),
    REQMAP_TIM(TIM2, CH1),
    REQMAP_TIM(TIM2, CH2),
    REQMAP_TIM(TIM2, CH3),
    REQMAP_TIM(TIM2, CH4),
    REQMAP_TIM(TIM3, CH1),
    REQMAP_TIM(TIM3, CH2),
    REQMAP_TIM(TIM3, CH3),
    REQMAP_TIM(TIM3, CH4),
    REQMAP_TIM(TIM4, CH1),
    REQMAP_TIM(TIM4, CH2),
    REQMAP_TIM(TIM4, CH3),
    REQMAP_TIM(TIM5, CH1),
    REQMAP_TIM(TIM5, CH2),
    REQMAP_TIM(TIM5, CH3),
    REQMAP_TIM(TIM5, CH4),
    REQMAP_TIM(TIM8, CH1),
    REQMAP_TIM(TIM8, CH2),
    REQMAP_TIM(TIM8, CH3),
    REQMAP_TIM(TIM8, CH4),
    REQMAP_TIM(TIM15, CH1),
    REQMAP_TIM(TIM16, CH1),
    REQMAP_TIM(TIM17, CH1),
};

5.5 dmaIdentifier_e关联

typedef enum {
    DMA_NONE = 0,
    DMA1_ST0_HANDLER = 1,
    DMA1_ST1_HANDLER,
    DMA1_ST2_HANDLER,
    DMA1_ST3_HANDLER,
    DMA1_ST4_HANDLER,
    DMA1_ST5_HANDLER,
    DMA1_ST6_HANDLER,
    DMA1_ST7_HANDLER,
    DMA2_ST0_HANDLER,
    DMA2_ST1_HANDLER,
    DMA2_ST2_HANDLER,
    DMA2_ST3_HANDLER,
    DMA2_ST4_HANDLER,
    DMA2_ST5_HANDLER,
    DMA2_ST6_HANDLER,
    DMA2_ST7_HANDLER,
    DMA_LAST_HANDLER = DMA2_ST7_HANDLER
} dmaIdentifier_e;

6. 参考资料

【1】BetaFlight开源代码框架简介
【2】BetaFlight统一硬件资源简单配置修改
【3】BetaFlight统一硬件配置文件研读

7. 附录-DMA on STM32介绍视频

DMA on STM32 HAL with 2 example projects

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值