2025-10-23 2:29 AM
Hi,
I'm trying to get a PWM output that changes duty cycle on each period with DMA in circular mode. I have seen other similar posts (ultimately I'd like to control a WS28 LED with 800kHz), but they are for other MCUs and everything is different in the details. I tried this for quite a while in a bigger project, so reducing it here to the bare minimum.
To start with, I'm using a slower timer and just try to get the DMA to change the CCR1 at all on a dev kit (NULCEO-H563ZI)
Starting of with this example:
The unmodified example works and outputs a PWM on PE9 (50% DC).
No I configure DMA as well:
In the main.c, I add the DMA:
In my understanding, the CC event of timer1 ch1 should now trigger the DMA transfer of the samples from buf, one by one, so DC should be 10000, 50000, 10000, 50000, and so on (circular DMA).
The output on the scope is unchanged, the DMA never seems to transfer anything.
I also tried to use other trigger source for DMA (GPDMA1_REQUEST_TIM1_TRIG, GPDMA1_REQUEST_TIM1_UP) with no success either.
According to documentation I believe this should be supported on STM32H563, but I cannot find what I'm doing wrong. Any hints?
Solved! Go to Solution.
2025-10-24 1:14 AM
I found it, the DMA channel needs to be priviledged, which I don't understand as the timer is not priviledged. But then it works. Btw don't try the same with LPTIMER instead of the regular timer, the HAL is implemented wrong for LPTIM. The Start_PWM_DMA function tries to use CCx registers, but the technical reference manual states that those only generate events on input capture and not on PWM output. Using the update event (as it is correct) will generate code that hard faults because of nullptr dereference. Also writing to CCx only generates one request to the DMA, a second and so on event will only be generated when writing ARR with LPTIM as described in the TRM. @st I think that should be fixed for LPTIM (or remove the PWM output from HAL for LPTIM).
2025-10-23 9:46 AM
A few updates: The values in buf are higher then the interval, but fixing that does not help much. I'm using non circular mode now and the DMA actually seems to transfer values, I get a transfer complete interrupt. In that interrupt, the C0SAR is correct at 0x20000002 (2 bytes into my buffer, i adjusted the transfer to a single half word)
The destination address is 0x40012c34. Looking at the timer register it is still 0x00, but the source address at the moment contains 0xFFFF:
So looks like everything is configured correctly, and the DMA transfers the value to the correct register. Except that it goes to 0x00 (it is a different value then before the DMA transfer) instead of 0xFFFF from the source address. So either the DMA cannot read the memory at the source of the timer does not allow to be written from DMA. Any ideas how to find out which one it is? I'm not using secure zone or any memory protections, just the very basic example above from STM.
2025-10-23 9:51 AM - edited 2025-10-23 9:52 AM
Hello,
A WS28xx related topic: Nucleo STM32C071RB with WS2812b issue
PS: in next time please use </> button to share a code instead of a screen shot.
Thank you
2025-10-23 9:59 AM
Maybe a bit similar, but different problem. This is the source address:
So the DMA copies 0x00 from the address 0x20000000 instead of 0xFFFF into the timer register.
2025-10-24 1:14 AM
I found it, the DMA channel needs to be priviledged, which I don't understand as the timer is not priviledged. But then it works. Btw don't try the same with LPTIMER instead of the regular timer, the HAL is implemented wrong for LPTIM. The Start_PWM_DMA function tries to use CCx registers, but the technical reference manual states that those only generate events on input capture and not on PWM output. Using the update event (as it is correct) will generate code that hard faults because of nullptr dereference. Also writing to CCx only generates one request to the DMA, a second and so on event will only be generated when writing ARR with LPTIM as described in the TRM. @st I think that should be fixed for LPTIM (or remove the PWM output from HAL for LPTIM).
2025-10-24 1:30 AM
Hello @CClau.1 ,
Thank you for the feedback.
@CClau.1 wrote:
the HAL is implemented wrong for LPTIM. The Start_PWM_DMA function tries to use CCx registers, but the technical reference manual states that those only generate events on input capture and not on PWM output.
Better to open a separate thread regarding this issue in STM32 MCUs Embedded software forum board so it can be handled by the relevant people from ST.