cancel
Showing results for 
Search instead for 
Did you mean: 

Timer PWM output with DMA on STM32H563

CClau.1
Associate II

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:

CClau1_0-1761211144951.png

 

The unmodified example works and outputs a PWM on PE9 (50% DC).

 

No I configure DMA as well:

 

CClau1_2-1761211363333.png

 

In the main.c, I add the DMA:

CClau1_3-1761211568659.png

 

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?

1 ACCEPTED SOLUTION

Accepted Solutions

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).

View solution in original post

5 REPLIES 5
CClau.1
Associate II

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)

CClau1_0-1761237767389.png

The destination address is 0x40012c34. Looking at the timer register it is still 0x00, but the source address at the moment contains 0xFFFF:

 

CClau1_1-1761237896775.png

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.

 

 

mƎALLEm
ST Employee

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

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Maybe a bit similar, but different problem. This is the source address:

CClau1_0-1761238738529.png

So the DMA copies 0x00 from the address 0x20000000 instead of 0xFFFF into the timer register.

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).

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.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.