2025-11-06 7:38 AM - last edited on 2025-11-06 11:22 AM by Imen.D
Hello, I have a problem with a STM32L431CC generating a circular PWM burst with the DMA. I am using the Timer1 to generate 4 PWM signals on the Pins PA8, PA9, PA10, PA11. The systemclock of the Timer 1 is 80 MHz. The frequency of the PWM signal should be 20kHz. I have attached the code snipped were i configured the GPIO, Timer and DMA in the software. I get no PWM signal from the GPIO pins. When I manipulate the CCRx registers of the Timer1 with the ST Link debugger, I am able to generate PWM signals with the correct frequency and duty cycle. I suspect that the Timer1 do not make a DMA request and I am not able to find the failure. The DMA do not set any interrupt flags. Also when I manipulate the DMAR register of Timer1, I can see a valid PWM signal.
Would be great when someone can support me
Thanks Patrick
#define TIM1_PSC_INIT 0u
#define TIM1_ARR_INIT 3999u /* ~20 kHz at 80MHz systemclock frequency */
#define TIM1_RCR_INIT 0u
uint16_t volatile tim1_dma_buffer[] = {
555, /* CCR1 */
1111, /* CCR2 */
2222, /* CCR3 */
3333 /* CCR4 */
};
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
LL_GPIO_InitTypeDef gpio = {0};
gpio.Pin = LL_GPIO_PIN_8 | LL_GPIO_PIN_9 | LL_GPIO_PIN_10 | LL_GPIO_PIN_11;
gpio.Mode = LL_GPIO_MODE_ALTERNATE;
gpio.Speed = LL_GPIO_SPEED_FAST;
gpio.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
gpio.Pull = LL_GPIO_PULL_NO;
gpio.Alternate = LL_GPIO_AF_1;
LL_GPIO_Init(GPIOA, &gpio);
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
LL_TIM_SetPrescaler(TIM1, TIM1_PSC_INIT);
LL_TIM_SetAutoReload(TIM1, TIM1_ARR_INIT);
LL_TIM_SetRepetitionCounter(TIM1, TIM1_RCR_INIT);
LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP);
LL_TIM_SetClockDivision(TIM1, LL_TIM_CLOCKDIVISION_DIV1);
LL_TIM_OC_InitTypeDef oc = {0};
oc.OCMode = LL_TIM_OCMODE_PWM1;
oc.OCState = LL_TIM_OCSTATE_DISABLE;
oc.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
oc.OCIdleState = LL_TIM_OCIDLESTATE_LOW;
oc.CompareValue = 0;
LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &oc);
oc.CompareValue = 0;
LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH2, &oc);
oc.CompareValue = 0;
LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH3, &oc);
oc.CompareValue = 0;
LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH4, &oc);
LL_TIM_BDTR_InitTypeDef bdtr = {0};
bdtr.OSSRState = LL_TIM_OSSR_DISABLE;
bdtr.OSSIState = LL_TIM_OSSI_DISABLE;
bdtr.LockLevel = LL_TIM_LOCKLEVEL_OFF;
bdtr.DeadTime = 0;
bdtr.BreakState= LL_TIM_BREAK_DISABLE;
bdtr.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE;
LL_TIM_BDTR_Init(TIM1, &bdtr);
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_6);
LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_6, (uint32_t)tim1_dma_buffer, (uint32_t)&TIM1->DMAR, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_6, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_6, 4);
LL_DMA_SetMemoryIncMode (DMA1, LL_DMA_CHANNEL_6, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphIncMode (DMA1, LL_DMA_CHANNEL_6, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_6, LL_DMA_MODE_CIRCULAR);
LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_6, LL_DMA_PRIORITY_HIGH);
LL_DMA_SetPeriphSize (DMA1, LL_DMA_CHANNEL_6, LL_DMA_PDATAALIGN_HALFWORD);
LL_DMA_SetMemorySize (DMA1, LL_DMA_CHANNEL_6, LL_DMA_MDATAALIGN_HALFWORD);
LL_TIM_ConfigDMABurst(TIM1, LL_TIM_DMABURST_BASEADDR_CCR1, LL_TIM_DMABURST_LENGTH_4TRANSFERS);
LL_TIM_EnableDMAReq_UPDATE(TIM1);
LL_TIM_EnableAllOutputs(TIM1);
LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1 | LL_TIM_CHANNEL_CH2 |
LL_TIM_CHANNEL_CH3 | LL_TIM_CHANNEL_CH4);
LL_TIM_EnableARRPreload(TIM1);
LL_TIM_OC_DisablePreload(TIM1, LL_TIM_CHANNEL_CH1);
LL_TIM_OC_DisablePreload(TIM1, LL_TIM_CHANNEL_CH2);
LL_TIM_OC_DisablePreload(TIM1, LL_TIM_CHANNEL_CH3);
LL_TIM_OC_DisablePreload(TIM1, LL_TIM_CHANNEL_CH4);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_6);
LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_6);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_6);
LL_TIM_EnableCounter(TIM1);
Solved! Go to Solution.
2025-11-06 10:14 AM
Debug as usually: read out and check/post TIM and DMA registers content.
Where do you set the DMA request selector? I don't understand the Cube/LL gobbledygook.
JW
2025-11-06 10:14 AM
Debug as usually: read out and check/post TIM and DMA registers content.
Where do you set the DMA request selector? I don't understand the Cube/LL gobbledygook.
JW
2025-11-06 12:09 PM
Thanks a lot for the hint with the DMA request selector. This was missing