STM32H747 (M7) – TIM3 CH4 PWM with DMA produces discontinuous/glitchy waveform for addressable LEDs
hello everybody
I am programming 10 addressable Leds with PWM with DMA using the M7 cortex of an STM32H747 in a custom board.
Characteristics:
- Clocks: SysClk 480 MHz, TIM kernel clock 240 MHz
- Timer: TIM3, Channel 4, internal clock
- PWM base frequency: ~770 kHz (period ≈ 1.3 µs).
- ARR: 312‑1 (312 ticks → 240 MHz/312 ≈ 769.23 kHz).
- DMA: Peripheral = TIM3_CCR4, Memory in RAM_D2, half‑word alignment (16‑bit duty), MemInc enabled, PeriphInc disabled, Mode = Normal.
What works
If I run the timer alone (fixed duty), the PWM is correct and stable.
The problem
When I enable PWM + DMA, the waveform becomes random/discontinuous. On the oscilloscope I see “splits” and gaps; the PWM is not continuous. For example, the first 8 bits might be high and the following 16 low (intended to represent RED), but the stream breaks unpredictably. The data buffer looks correct when inspected in the debugger.
The configuration


I am using channel 4 timer 3. with internal clock source.
and DMA is configured as:

where data width is half word since the pulse of the PWM generator channel 4 is 16 bit value.
Here is my code. All IRQs are activated.
#define NUMTOTALLEDS 10
#define NUMCOLORS 24 //< 8 BYTESxCOLOUR
#define STARTSAFEBUFFER 50
#define ENDSAFEBUFFER 50
// Placed in RAM_D2
uint16_t pwmData[NUMCOLORS*NUMTOTALLEDS+STARTSAFEBUFFER+ENDSAFEBUFFER];
const
uint16_t ALLRED [340] = {
// Start safe buffer
PWM_RESET, PWM_RESET, PWM_RESET ...
// 8 bits high + 8 bits low + 8 bits low (Red, gren, blue)
PWM_HIGH, PWM_HIGH, PWM_HIGH, PWM_HIGH, PWM_HIGH, PWM_HIGH, PWM_HIGH, PWM_HIGH, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW,
// End safe buffer
... PWM_RESET, PWM_LOW, PWM_LOW};
// First of all i cpy a static buffer with all the information to fill 10 leds in red
memcpy(pwmData, ALLRED, sizeof(pwmData));
// Then
if (HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_4 , (uint32_t *)pwmData, sizeof(pwmData)) == HAL_OK) {
// It returns Ok always
}
// Callback
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
HAL_TIM_PWM_Stop_DMA(&htim3, TIM_CHANNEL_4);
}Everything is normal to me, but this is what my oscilloscope gets:

with zoom (the first 8 bits are high, and the 16 folowing are low, meaning red colour (RGB)):

My problem is that the PWM is random, and never correct.
What can I do?
Thanks in advance,
