STM32 DMA burst write.... TIM4 DMA, burst write into TIM3? (Update: Nope!) - Page 1
Forum section: electronics / general

author: DavidAlfa
author_rank: Super Contributor
timestamp: September 07, 2025, 03:36:40 pm
content: Ideally this would be done using the Repetition counter, but it's only available in TIM1 and it's already being used.So, I'm using TIM4 to count TIM3 events, and trying to perform a burst write into TIM3, updating CCR1 and CCR2 registers.I guess this can't be done, normally this is done by a timer DMA writing on its own timer regs.I tried:- Set TIM4 DMA to point at TIM3->DMAR.- Set TIM3 DCR to indicate a burst of 3 transfers to CCR1 base address.- I also tried setting TIM3 DCR in the same way.Code:uint16_t tim3_dmar[] = { // Just an example// CCR1, CCR2100, 200,200, 300,};HAL_DMA_Start(&hdma_tim4_ch1, (uint32_t)tim3_dmar, (uint32_t)&TIM3->DMAR, sizeof(tim3_dmar)/sizeof(tim3_dmar)); // DMA cfg: Cicular mode, half word, memory to periph.TIM4->DCR = TIM_DMABASE_CCR1 | TIM_DMABURSTLENGTH_2TRANSFERS;TIM3->DCR = TIM_DMABASE_CCR1 | TIM_DMABURSTLENGTH_2TRANSFERS; // This doesn't work either_HAL_TIM_ENABLE_DMA(&htim4, TIM_DMA_CC1);Unsurprisingly, burst transfers aren't working.I'm getting only one transfer on each event, though DMAR is working, every transfer is updating a different register.Is Burst mode limited to the own timer's DMA and DMAR?Any thoughts?

author: wek
author_rank: Frequent Contributor
timestamp: September 08, 2025, 07:31:04 am
content: Which STM32?> Is Burst mode limited to the own timer's DMA and DMAR?Yes.The way it works is, that every access to TIMx_DMAR both increments the internal "pointer" changing the register accessed through TIMx_DMAR, and also automatically generates a DMA request from the timer in which that TIMx_DMAR is.Maybe you could use two DMA channes/streams, though, one triggered by TIM4, which would initiate the first transfer through TIM3_DMAR to TIM3_CCR1, and the other triggered by TIM3 through that TIMx_DMAR-triggered mechanism, which would transfer the second datum through TIM3_DMAR to TIM3_CCR2. You would need to trigger the second DMA by a signal which won't get normally active in that timer, e.g. an unused CC channel set to capture, or if there's no connection to the slave-mode controller, the Trigger event (as enabled by TIMx_DIER.TDE). I am not completely sure this would work, though.JW

author: DavidAlfa
author_rank: Super Contributor
timestamp: September 08, 2025, 07:58:58 am
content: It 's a 32F411.In the end I used a large buffer with a DMA transfer on every update, repeating the same values for a couple hundred times. (I would only need 10 values or so if I had Repetition counter).Thanks to GCC I could do that very easily:Code:uint16_t large_array[] = {[0 ... 250] = 100,[251 ... 255] = 200, = 300,};The big issue is toggling gpio, only timer 1 DMA can access the entire memory.I wonder if this was solved/improved in U/H series, I had a peek to the datasheet, the system looked quite complicated!

author: ahsrabrifat
author_rank: Regular Contributor
timestamp: September 26, 2025, 01:38:14 pm
content: Quote from: DavidAlfa on September 07, 2025, 03:36:40 pm

author: DavidAlfa
author_rank: Super Contributor
timestamp: September 26, 2025, 05:18:04 pm
content: ?

author: aae30
author_rank: Contributor
timestamp: September 26, 2025, 06:55:13 pm
content: I think the reply you might have missed is there in the code within quote.