Skip to main content
Robmar
Senior II
Oct 16, 2026 12:49 PM UTC
Solved

Why enabling a timer via DMA write to the CR1 register fails

I have many timers working on out H743VIT6 board, so only have Tim2, 5, 12 and above available.

I have many forms of of timer triggered DMA working, but in this case as the system is near to max capacity, I need a DMA event scheduled for 52uS in the future WITHOUT using IRQs which are not time-stable enough for the purpose.

So I found that timer 16 in table 98 of the RM0433 manual is show connecting to timer 2, but in CubeMX timer 15 shows no trigger source!

So I though I would set up timer 5 to count down 52uS and trigger its DMA stream to write a half word to CR1 of Timer 15, that was setup to pace its own DMA stream.  Now I can get tier 15 triggering and DMA transfering it I enable it via the end of event cllback for timer 5, but DMAing to CR1 of an diabled timer doesn’t seem to work.

It’s a very complicated problem!
 

// Arm one amplitude bank, started by a TIM5 countdown delay to trigger DMA write to enable a target timer with DMA stream
HAL_StatusTypeDef ArmOneBank(uint32_t *pwm_values, uint32_t DataLength, uint32_t delay_ticks)
{
HAL_StatusTypeDef status; // Free timers 2, 5 and 12-up: Timer 15 does not map to Tim5 or Tim2 in Table 98 RM0433 manual inteconnect matrix
// Timers 16 and 17 are interconnected in table 98 to timer 15, but timers 1-17 do not have trigger sources
// TIM15 in normal up-counter mode, NOT waiting for an ITR trigger
__HAL_TIM_DISABLE(&htim15);
__HAL_TIM_DISABLE_DMA(&htim15, TIM_DMA_UPDATE);

__HAL_TIM_SET_COUNTER(&htim15, 0);
__HAL_TIM_CLEAR_FLAG(&htim15, TIM_FLAG_UPDATE);

// Arm amplitude DMA while TIM15 is stopped
status = HAL_DMA_Start_IT(&hdma_tim15_up,
(uint32_t)pwm_values,
(uint32_t)&TIM8->CCR3,
DataLength);

if (status != HAL_OK)
return status;

// Prepare target timer CR1 value to enable it, preserving existing bits
tim15_cr1_start_word = (uint16_t)(TIM15->CR1 | TIM_CR1_CEN); // 0x81 Check correct!!

// Enable amplitude requests before starting TIM15
__HAL_TIM_ENABLE_DMA(&htim15, TIM_DMA_UPDATE);
///__HAL_TIM_ENABLE(&htim15); // <---- THIS LINE ENABLED THE DMA TRANSFER IMMEDIATELY - NOT DESIRED!

// Prepare TIM5 one-shot delay
__HAL_TIM_DISABLE(&htim5);
__HAL_TIM_DISABLE_DMA(&htim5, TIM_DMA_UPDATE);

__HAL_TIM_SET_COUNTER(&htim5, 0);
__HAL_TIM_SET_AUTORELOAD(&htim5, delay_ticks);
__HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE);

// Arm one DMA transfer: TIM5 update -> write TIM15 CR1
status = HAL_DMA_Start_IT(&hdma_tim5_up,
(uint32_t)&tim15_cr1_start_word,
(uint32_t)&TIM15->CR1,
1);

if (status != HAL_OK)
{
__HAL_TIM_DISABLE_DMA(&htim15, TIM_DMA_UPDATE);
HAL_DMA_Abort(&hdma_tim15_up);
return status;
}

// Enable TIM5 update DMA requests only after its stream is armed
__HAL_TIM_ENABLE_DMA(&htim5, TIM_DMA_UPDATE);

// Start the one-shot countdown - when tim5 expires it will trigger its DMA
// to write the tim15_cr1_start_word to enable timer 15 but timer 15 does not pave its DMA stream for some reason
__HAL_TIM_ENABLE(&htim5);

return HAL_OK;
}

 

Robmar
RobmarBest answer
Senior II
Oct 21, 2026 12:58 PM UTC

If you look in the RM0433 manual, all 3500+ pages, around page 595 Taable 98 onwards, and especially the DMAMUX tables showing what sources can be used for synchronizing each DMA trnsfer word by word, you will see only timer 12 TRGO is listed, and othe rch events, its very limited, looks like they ran out of space to more connections in silicon!
I need the DMA to run word per word at 320 KHz, so to do that I havae the use DMAMUX to sync the transfer with timer 12, but I also have to start the transfer in teh future from the Audio IRQ to synchronize phase transfer over slow I2C bus (800KHz).
I do have it working now, but it was not easy to arrive at a configuration that worked given all the limitations of trigger and sync sources.
 

20 replies

ST Employee
Oct 22, 2026 4:11 PM UTC

Hello ​@Robmar , 

One clarification about the CubeMX point: the timer-to-timer connection is supported in hardware; it is documented in the reference manual as an ITR route. For the STM32H742/743/753/750 devices covered by RM0433, Rev. 9 Table 349 (p. 1804) maps TIM5_TRGO to TIM15_ITR3. CubeMX represents that connection through the timer’s ITR trigger source.

So, if the route in question is TIM5 to TIM15, it is not correct to conclude that the connection is unavailable just because it is shown as an ITRx source rather than as a direct timer name. The ITR mapping describes timer synchronization, though; it does not by itself establish whether a DMA write to CR1.CEN will start the target timer. Those are separate points.

If you’re new to CubeMX, the examples included in the STM32CubeH7 firmware package, available from ST’s website, are a helpful way to learn how timer trigger sources are configured.

Kind regards, 

DK

 

"Please mark my answer as best by clicking on the “Accept as solution"" button if it fully answered your question. This will help other users find this solution faster.​"
Robmar
RobmarAuthor
Senior II
Oct 22, 2026 4:26 PM UTC

I u sed tim5 to tim12, then tim12 to trigger each DMA word