Thanks for your help!
I think I can finally wrap my head around this enough to edit hwdef.dat and get the desired changes in DMA mapping. Can someone take a look and verify this all makes sense?
Here is the edited hwdef.dat I made for my MatekF405 board to: add bi-directional DSHOT to M6, add PWM S7, enable full DMA on USART1, USART3, and UART5.
# Need to free TIM4 for S7 (Pin B8, PWM 7, GPIO 56). Move system timer to TIM14, which should be equivalent.
- define STM32_ST_USE_TIMER 4
+ define STM32_ST_USE_TIMER 14
# Don't assign DMA to TIM3 to free up DMA1 Stream 2 for SPI3_RX
- PC6 TIM3_CH1 TIM3 PWM(1) GPIO(50)
+ PC6 TIM3_CH1 TIM3 PWM(1) GPIO(50) NODMA
# Don't assign DMA to TIM2 to free up DMA1 Stream 1 for USART3_RX
- PA15 TIM2_CH1 TIM2 PWM(5) GPIO(54)
+ PA15 TIM2_CH1 TIM2 PWM(5) GPIO(54) NODMA
# Enable bidirectional DShot on M6
- PA8 TIM1_CH1 TIM1 PWM(6) GPIO(55)
+ PA8 TIM1_CH1 TIM1 PWM(6) GPIO(55) BIDIR
# Enable PWM output on S7 (Pin B8)
+ PB8 TIM4_CH3 TIM4 PWM(7) GPIO(56)
# Make sure USART3_RX and UART5_RX are assigned DMA streams to enable full DMA
+ DMA_PRIORITY USART3_RX UART5_RX
And the resulting hwdef.h: hwdef.h (62.7 KB)
Relevant hwdef.h code snippet:
// GPIO config
#define HAL_GPIO_LINE_GPIO0 PAL_LINE(GPIOB,9U)
#define HAL_GPIO_LINE_GPIO1 PAL_LINE(GPIOA,14U)
#define HAL_GPIO_LINE_GPIO50 PAL_LINE(GPIOC,6U)
#define HAL_GPIO_LINE_GPIO51 PAL_LINE(GPIOC,7U)
#define HAL_GPIO_LINE_GPIO52 PAL_LINE(GPIOC,8U)
#define HAL_GPIO_LINE_GPIO53 PAL_LINE(GPIOC,9U)
#define HAL_GPIO_LINE_GPIO54 PAL_LINE(GPIOA,15U)
#define HAL_GPIO_LINE_GPIO55 PAL_LINE(GPIOA,8U)
#define HAL_GPIO_LINE_GPIO56 PAL_LINE(GPIOB,8U)
#define HAL_GPIO_LINE_GPIO80 PAL_LINE(GPIOC,13U)
#define HAL_GPIO_PINS { \
{ 0, true, 0, PAL_LINE(GPIOB,9U)}, /* PB9 LED_BLUE OUTPUT */ \
{ 1, true, 0, PAL_LINE(GPIOA,14U)}, /* PA14 LED_GREEN OUTPUT */ \
{ 50, true, 1, PAL_LINE(GPIOC,6U)}, /* PC6 TIM3_CH1 TIM3 AF2 PWM1 */ \
{ 51, true, 2, PAL_LINE(GPIOC,7U)}, /* PC7 TIM8_CH2 TIM8 AF3 PWM2 */ \
{ 52, true, 3, PAL_LINE(GPIOC,8U)}, /* PC8 TIM8_CH3 TIM8 AF3 PWM3 */ \
{ 53, true, 4, PAL_LINE(GPIOC,9U)}, /* PC9 TIM8_CH4 TIM8 AF3 PWM4 */ \
{ 54, true, 5, PAL_LINE(GPIOA,15U)}, /* PA15 TIM2_CH1 TIM2 AF1 PWM5 */ \
{ 55, true, 6, PAL_LINE(GPIOA,8U)}, /* PA8 TIM1_CH1 TIM1 AF1 PWM6 */ \
{ 56, true, 7, PAL_LINE(GPIOB,8U)}, /* PB8 TIM4_CH3 TIM4 AF2 PWM7 */ \
{ 80, true, 0, PAL_LINE(GPIOC,13U)}, /* PC13 BUZZER OUTPUT */ \
}
// full pin define list
#define HAL_GPIO_PIN_BATT_CURRENT_SENS PAL_LINE(GPIOC,4U)
#define HAL_GPIO_PIN_BATT_VOLTAGE_SENS PAL_LINE(GPIOC,5U)
#define HAL_GPIO_PIN_BUZZER PAL_LINE(GPIOC,13U)
#define HAL_GPIO_PIN_I2C1_SCL PAL_LINE(GPIOB,6U)
#define HAL_GPIO_PIN_I2C1_SDA PAL_LINE(GPIOB,7U)
#define HAL_GPIO_PIN_I2C1_SCL PAL_LINE(GPIOB,6U)
#define HAL_GPIO_PIN_LED_BLUE PAL_LINE(GPIOB,9U)
#define HAL_GPIO_PIN_LED_GREEN PAL_LINE(GPIOA,14U)
#define HAL_GPIO_PIN_M25P16_CS PAL_LINE(GPIOC,0U)
#define HAL_GPIO_PIN_MAX7456_CS PAL_LINE(GPIOB,10U)
#define HAL_GPIO_PIN_MPU6000_CS PAL_LINE(GPIOC,2U)
#define HAL_GPIO_PIN_OTG_FS_DM PAL_LINE(GPIOA,11U)
#define HAL_GPIO_PIN_OTG_FS_DP PAL_LINE(GPIOA,12U)
#define HAL_GPIO_PIN_RSSI_ADC_PIN PAL_LINE(GPIOB,1U)
#define HAL_GPIO_PIN_SDCARD_CS PAL_LINE(GPIOC,1U)
#define HAL_GPIO_PIN_SPI1_MISO PAL_LINE(GPIOA,6U)
#define HAL_GPIO_PIN_SPI1_MOSI PAL_LINE(GPIOA,7U)
#define HAL_GPIO_PIN_SPI1_SCK PAL_LINE(GPIOA,5U)
#define HAL_GPIO_PIN_SPI2_MISO PAL_LINE(GPIOB,14U)
#define HAL_GPIO_PIN_SPI2_MOSI PAL_LINE(GPIOB,15U)
#define HAL_GPIO_PIN_SPI2_SCK PAL_LINE(GPIOB,13U)
#define HAL_GPIO_PIN_SPI3_MISO PAL_LINE(GPIOB,4U)
#define HAL_GPIO_PIN_SPI3_MOSI PAL_LINE(GPIOB,5U)
#define HAL_GPIO_PIN_SPI3_SCK PAL_LINE(GPIOB,3U)
#define HAL_GPIO_PIN_TIM1_CH1 PAL_LINE(GPIOA,8U)
#define HAL_GPIO_PIN_TIM2_CH1 PAL_LINE(GPIOA,15U)
#define HAL_GPIO_PIN_TIM3_CH1 PAL_LINE(GPIOC,6U)
#define HAL_GPIO_PIN_TIM4_CH3 PAL_LINE(GPIOB,8U)
#define HAL_GPIO_PIN_TIM8_CH2 PAL_LINE(GPIOC,7U)
#define HAL_GPIO_PIN_TIM8_CH3 PAL_LINE(GPIOC,8U)
#define HAL_GPIO_PIN_TIM8_CH4 PAL_LINE(GPIOC,9U)
#define HAL_GPIO_PIN_TIM9_CH2 PAL_LINE(GPIOA,3U)
#define HAL_GPIO_PIN_UART4_RX PAL_LINE(GPIOA,1U)
#define HAL_GPIO_PIN_UART4_TX PAL_LINE(GPIOA,0U)
#define HAL_GPIO_PIN_UART5_RX PAL_LINE(GPIOD,2U)
#define HAL_GPIO_PIN_UART5_TX PAL_LINE(GPIOC,12U)
#define HAL_GPIO_PIN_USART1_RX PAL_LINE(GPIOA,10U)
#define HAL_GPIO_PIN_USART1_TX PAL_LINE(GPIOA,9U)
#define HAL_GPIO_PIN_USART2_TX PAL_LINE(GPIOA,2U)
#define HAL_GPIO_PIN_USART3_RX PAL_LINE(GPIOC,11U)
#define HAL_GPIO_PIN_USART3_TX PAL_LINE(GPIOC,10U)
#define HAL_GPIO_PIN_VBUS PAL_LINE(GPIOB,12U)
#define HAL_INS_PROBE1 ADD_BACKEND(AP_InertialSensor_Invensense::probe(*this,hal.spi->get_device("mpu6000"),ROTATION_YAW_180))
#define INS_MAX_INSTANCES 1
#define HAL_INS_PROBE_LIST HAL_INS_PROBE1
#define HAL_BARO_PROBE1 ADD_BACKEND(AP_Baro_BMP280::probe(*this,GET_I2C_DEVICE(0,0x76)))
#define HAL_BARO_PROBE_LIST HAL_BARO_PROBE1
// peripherals enabled
#define STM32_I2C_USE_I2C1 TRUE
#define STM32_USB_USE_OTG1 TRUE
#define STM32_SPI_USE_SPI1 TRUE
#define STM32_SPI_USE_SPI2 TRUE
#define STM32_SPI_USE_SPI3 TRUE
#ifndef STM32_SERIAL_USE_UART4
#define STM32_SERIAL_USE_UART4 TRUE
#endif
#ifndef STM32_SERIAL_USE_UART5
#define STM32_SERIAL_USE_UART5 TRUE
#endif
#ifndef STM32_SERIAL_USE_USART1
#define STM32_SERIAL_USE_USART1 TRUE
#endif
#ifndef STM32_SERIAL_USE_USART2
#define STM32_SERIAL_USE_USART2 TRUE
#endif
#ifndef STM32_SERIAL_USE_USART2
#define STM32_SERIAL_USE_USART2 TRUE
#endif
#ifndef STM32_SERIAL_USE_USART3
#define STM32_SERIAL_USE_USART3 TRUE
#endif
// auto-generated DMA mapping from dma_resolver.py
// Note: The following peripherals can't be resolved for DMA: ['UART4_RX']
#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
#define STM32_ADC_ADC1_DMA_CHAN 0
#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
#define STM32_I2C_I2C1_RX_DMA_CHAN 1
#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) // shared I2C1_TX,TIM4_UP
#define STM32_I2C_I2C1_TX_DMA_CHAN 1
#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0)
#define STM32_SPI_SPI1_RX_DMA_CHAN 3
#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
#define STM32_SPI_SPI1_TX_DMA_CHAN 3
#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
#define STM32_SPI_SPI2_RX_DMA_CHAN 0
#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) // shared SPI2_TX,USART3_TX,UART4_TX
#define STM32_SPI_SPI2_TX_DMA_CHAN 0
#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
#define STM32_SPI_SPI3_RX_DMA_CHAN 0
#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) // shared SPI3_TX,UART5_TX
#define STM32_SPI_SPI3_TX_DMA_CHAN 0
#define STM32_TIM_TIM1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 6)
#define STM32_TIM_TIM1_CH1_DMA_CHAN 0
#define STM32_TIM_TIM1_UP_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
#define STM32_TIM_TIM1_UP_DMA_CHAN 6
#define STM32_TIM_TIM4_UP_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) // shared I2C1_TX,TIM4_UP
#define STM32_TIM_TIM4_UP_DMA_CHAN 2
#define STM32_TIM_TIM8_UP_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
#define STM32_TIM_TIM8_UP_DMA_CHAN 7
#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) // shared SPI2_TX,USART3_TX,UART4_TX
#define STM32_UART_UART4_TX_DMA_CHAN 4
#define STM32_UART_UART5_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
#define STM32_UART_UART5_RX_DMA_CHAN 4
#define STM32_UART_UART5_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) // shared SPI3_TX,UART5_TX
#define STM32_UART_UART5_TX_DMA_CHAN 4
#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
#define STM32_UART_USART1_RX_DMA_CHAN 4
#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
#define STM32_UART_USART1_TX_DMA_CHAN 4
#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1)
#define STM32_UART_USART3_RX_DMA_CHAN 4
#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) // shared SPI2_TX,USART3_TX,UART4_TX
#define STM32_UART_USART3_TX_DMA_CHAN 7
// Mask of DMA streams which are shared
#define SHARED_DMA_MASK ((1U<<STM32_DMA_STREAM_ID(1,6))|(1U<<STM32_DMA_STREAM_ID(1,7))|(1U<<STM32_DMA_STREAM_ID(1,4)))
// generated UART DMA configuration lines
#define STM32_USART1_RX_DMA_CONFIG true, STM32_UART_USART1_RX_DMA_STREAM, STM32_UART_USART1_RX_DMA_CHAN
#define STM32_USART1_TX_DMA_CONFIG true, STM32_UART_USART1_TX_DMA_STREAM, STM32_UART_USART1_TX_DMA_CHAN
#define STM32_USART2_RX_DMA_CONFIG false, 0, 0
#define STM32_USART2_TX_DMA_CONFIG false, 0, 0
#define STM32_USART3_RX_DMA_CONFIG true, STM32_UART_USART3_RX_DMA_STREAM, STM32_UART_USART3_RX_DMA_CHAN
#define STM32_USART3_TX_DMA_CONFIG true, STM32_UART_USART3_TX_DMA_STREAM, STM32_UART_USART3_TX_DMA_CHAN
#define STM32_UART4_RX_DMA_CONFIG false, 0, 0
#define STM32_UART4_TX_DMA_CONFIG true, STM32_UART_UART4_TX_DMA_STREAM, STM32_UART_UART4_TX_DMA_CHAN
#define STM32_UART5_RX_DMA_CONFIG true, STM32_UART_UART5_RX_DMA_STREAM, STM32_UART_UART5_RX_DMA_CHAN
#define STM32_UART5_TX_DMA_CONFIG true, STM32_UART_UART5_TX_DMA_STREAM, STM32_UART_UART5_TX_DMA_CHAN
// generated SPI DMA configuration lines
#define STM32_SPI_SPI1_DMA_STREAMS STM32_SPI_SPI1_TX_DMA_STREAM, STM32_SPI_SPI1_RX_DMA_STREAM
#define STM32_SPI_SPI2_DMA_STREAMS STM32_SPI_SPI2_TX_DMA_STREAM, STM32_SPI_SPI2_RX_DMA_STREAM
#define STM32_SPI_SPI3_DMA_STREAMS STM32_SPI_SPI3_TX_DMA_STREAM, STM32_SPI_SPI3_RX_DMA_STREAM
#define HAL_PWM_COUNT 7
// RC input config
#define HAL_USE_EICU TRUE
#define STM32_EICU_USE_TIM9 TRUE
#define RCININT_EICU_TIMER EICUD9
#define RCININT_EICU_CHANNEL EICU_CHANNEL_2
// No Alarm output pin defined
#undef HAL_PWM_ALARM
// PWM timer config
#define HAL_WITH_BIDIR_DSHOT
#define STM32_PWM_USE_TIM4 TRUE
#define STM32_TIM4_SUPPRESS_ISR
#define STM32_PWM_USE_TIM8 TRUE
#define STM32_TIM8_SUPPRESS_ISR
#define STM32_PWM_USE_TIM1 TRUE
#define STM32_TIM1_SUPPRESS_ISR
#define STM32_PWM_USE_TIM3 TRUE
#define STM32_TIM3_SUPPRESS_ISR
#define STM32_PWM_USE_TIM2 TRUE
#define STM32_TIM2_SUPPRESS_ISR
Finally, here is the table I made to visualize the DMA stream assignments, with the assignments for the MatekF405 target and my new target (which I called MatekF405-bdM7). Duplicate resources are highlighted. My approach was to first assign the required resources that are only available on a single stream (eg SPIx_RX, I2C), then the resources I wanted to add (eg USART3_RX), then try to make the remaining assignments work minimizing the number of TIMx_UP resources I had to disable.
Simplified DMA Resources Table for STM32F4xx MCUs