Multiple DMAs conflicts
Posted: Sun Apr 06, 2025 1:48 pm
OS : ChibiOS-21.11.3
MCU : STM32F405VGT6
BUZZER : PB0 TIM1_CH2N STM32_DMA2_STREAM5
I use pwm in combination with dma to drive the buzzer, but it conflicts with I2C until I disable I2C's DMA(see viewtopic.php?t=4167), the buzzer works fine, why?
1.Why does I2C use DMA by default? Isn't there an option?
2.How to avoid conflicts and make them work?
MCU : STM32F405VGT6
BUZZER : PB0 TIM1_CH2N STM32_DMA2_STREAM5
I use pwm in combination with dma to drive the buzzer, but it conflicts with I2C until I disable I2C's DMA(see viewtopic.php?t=4167), the buzzer works fine, why?
Code: Select all
void buzzer_init(void)
{
// Configure pin as AF output. Initialize the output low.
palSetPadMode(PORT_BUZZER, PIN_BUZZER, PAL_MODE_ALTERNATE(BUZZER_AF) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_PUPDR_PULLDOWN);
// Initialize frame buffer
last_buzzer_dutycycle = BUZZER_DUTYCYCLE;
uint32_t i;
for (i = 0; i < BUZZER_DATA_BIT_N; i++) buzzer_frame_buffer[i] = last_buzzer_dutycycle; // All bits are zero duty cycle
for (i = 0; i < BUZZER_RESET_BIT_N; i++) buzzer_frame_buffer[i + BUZZER_DATA_BIT_N] = 0; // All bits are zero duty cycle
rccEnableDMA_buzzer(false);
(BUZZER_DMA_STREAM)->stream->PAR = (uint32_t)(&(BUZZER_PWMD.tim->CCR[BUZZER_TIM_CH]));
(BUZZER_DMA_STREAM)->stream->M0AR = (uint32_t)(&buzzer_frame_buffer);//uint32_t match STM32_DMA_CR_MSIZE_WORD
(BUZZER_DMA_STREAM)->stream->NDTR = (uint32_t)(BUZZER_BUFF_BIT_N);//sizeof(buzzer_frame_buffer)/sizeof(uint8_t));//
(BUZZER_DMA_STREAM)->stream->CR = 0;
(BUZZER_DMA_STREAM)->stream->CR |= (uint32_t)( STM32_DMA_CR_PL(BUZZER_DMA_PRIORITY) | STM32_DMA_CR_CHSEL(BUZZER_DMA_CHANNEL) |
STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | //0x00000000U |//STM32_DMA_CR_RESET_VALUE |
STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE );//| STM32_DMA_CR_CIRC );//
// Start DMA
(BUZZER_DMA_STREAM)->stream->CR |= ((uint32_t)0x00000001);//STM32_DMA_CR_EN;//dmaStreamEnable(BUZZER_DMA_STREAM);
nvicEnableVector(BUZZER_DMA_STREAM_IRQ, BUZZER_PWM_IRQ_PRIORITY);
pwmStart(&BUZZER_PWMD, &buzzer_pwm_config);
pwmEnableChannel(&BUZZER_PWMD, BUZZER_TIM_CH, 5000); // Initial period is 0; output will be low until first duty cycle is DMA'd in
//pwmEnableChannel(&BUZZER_PWMD, BUZZER_TIM_CH, PWM_PERCENTAGE_TO_WIDTH(&BUZZER_PWMD, 5000));
}1.Why does I2C use DMA by default? Isn't there an option?
2.How to avoid conflicts and make them work?