2025-10-17 5:35 AM - edited 2025-10-17 7:33 AM
Is it possible to re-trigger HAL_TIM_DMABurst_MultiWriteStart() from software? Currently it works only once (the first time) for me. Using TIM1 freq/duty-cycle:
HAL_TIM_DMABurst_MultiWriteStart(
&htim1,
TIM_DMABASE_ARR, // Base = ARR
TIM_DMA_UPDATE, // Trigger = update event
(uint32_t*)rampBurst, // Source buffer
TIM_DMABURSTLENGTH_3TRANSFERS,// ARR + RCR + CCR1
N_STEPS*3 // Number of bursts
);
__HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_UPDATE);This produces a duty-cycle and frequency change over a certain amount of time, let's say 10ms, after the 10ms, I would like to disable the PWM output by setting the duty-cycle to 0:
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0);Then, I would like to re-trigger this each 100ms from software. My DMA setting is set to "Normal". The value of RCR is always 0 in the rampBurst array.
Solved! Go to Solution.
2025-10-17 7:55 AM
Hello,
Not sure it works but it might be worth trying this:
Once the first transfer is completed (triggered by hw) update the DMA transfer descriptor then re-start the DMA transfer when needed.
DMA descriptor update: replace DMA_REQUEST_TIM1_UP by DMA_REQUEST_MEM2MEM
Re-start DMA transfer: call HAL_DMA_Start_IT(htim1->hdma[TIM_DMA_ID_CC1], (uint32_t)ramBurst,
(uint32_t)&htim1->Instance->DMAR, DataLength)
Hope this helps.
2025-10-17 7:55 AM
Hello,
Not sure it works but it might be worth trying this:
Once the first transfer is completed (triggered by hw) update the DMA transfer descriptor then re-start the DMA transfer when needed.
DMA descriptor update: replace DMA_REQUEST_TIM1_UP by DMA_REQUEST_MEM2MEM
Re-start DMA transfer: call HAL_DMA_Start_IT(htim1->hdma[TIM_DMA_ID_CC1], (uint32_t)ramBurst,
(uint32_t)&htim1->Instance->DMAR, DataLength)
Hope this helps.
2025-10-19 12:06 PM
Thanks, this works :)
2026-01-23 1:19 AM - edited 2026-01-26 12:16 AM
Unfortunately, I still have issues when re-triggering the DMA, it does not seem to re-trigger properly each time.
So in short, what I'm trying to achieve, I would like to start TIM1 in PWM operation, changing frequency and duty cycle over time. I calculate the frequencies and duty cycles upfront, they are stored in the memory like this:
static uint32_t ramp_array[WORDS_PER_RAMP] __attribute__((aligned(4)));Then I would like to start the DMA operation, this DMA job takes approx. 100ms. I have another ISR which fires ~100ms (can be a bit less, can be a bit more). At this ISR, I can make two descissions for the DMA operation:
1. Stop DMA and stop PWM
2. Retrigger DMA to start over from the beginning
The issue is that the DMA might still be running, or can be finished at this moment when doing 1 or 2.
Can you provide a minimal working example perhaps?