cancel
Showing results for 
Search instead for 
Did you mean: 

DMA Weirdness

arolsen
Associate II
Posted on October 21, 2014 at 01:57

Hello all,  I'm trying to run a ws2812 strip using a timer and DMA.  I'm using the stm32f303vct6 chip at 48MHz.  

The Timer is running with no prescaler, and no clock division in PWM1 mode, with a period of 60 (1.25us), for a data rate of 800kHz.

For ws2812, the data is sent with 1 being longer than 0 - basically I modify the compare value with dma to get the correct output.

Currently it works, for the most part, if I use a compare value of 26 for HIGH, and a compare value of 16 for LOW.  However, this timing isn't perfect, and doesn't seem to work with all ws2812 LEDs.  

If I try to make the LOW shorter, say, 14, or the HIGH longer, say 28, weird things start happening in the output.  The 1s have spikes in them.

This picture shows what I see if I use 16 and 26:

0690X00000605BXQAY.png

This is what it looks like if I change HIGH to 28:

0690X00000605BiQAI.png

And here's a closer view of that weird spike:

0690X000006057qQAA.png

My code can be found here:   https://github.com/synic/ws2812_test/blob/master/src/main.c

What am I doing wrong here?  As I understand, in PWM1 mode, the signal will remain HIGH until the compare value is reached, and then it should go LOW.  How can it suddenly go back HIGH again like that?

#stm32f3 #ws2813 #dma
6 REPLIES 6
Posted on October 21, 2014 at 02:26

I'm not sure what the period has to do with the length of the DMA transfer.

I'd have the DMA hit on the UPDATE, having it use CC4 means you could have it hit multiple times during one period.

Period = N-1

100% Pulse N

50% Pulse N/2

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 21, 2014 at 02:32

Drop this to 1 or 2MHz, it will ring less

GPIO_InitStructure

.

GPIO_Speed

=

GPIO_Speed_50MHz

;

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
arolsen
Associate II
Posted on October 21, 2014 at 04:35

So, 

TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);

doesn't work (I'm not really sure what's going on.  There's a quick pulse every period, but that's all).  However,

TIM_DMACmd(TIM2, TIM_DMA_CC2, ENABLE);

does work.  However, I'm not sure why.  TIM_DMA_CC4 definitely isn't what I thought it was.  I don't see an explanation of what TIM_DMA_x is in either the datasheet or the reference manual.  Where do you usually find these things?

Thank you!  

arolsen
Associate II
Posted on October 22, 2014 at 21:27

Nevermind, it seems that it was a bit of a fluke that TIM_DMA_CC2 worked (I'm still not sure why that worked.  It shouldn't have).  I tried using a different timer/port/pin and it did not work.  It seems that I was right about what TIM_DMA_CC4 is; it means interrupt when the capture value has been reached on channel 4.  I say seems, because I still can't find any real documentation on what the different values you can pass to TIM_DMACmd() are, let alone documentation for TIM_DMACmd itself.

What does work is enabling preload for that channel:

TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);

Posted on October 22, 2014 at 22:33

There is typically a Windows Help .CHM file for the library, and there is documentation in-line with the functions.

For the chip the Reference Manual covers DMA function/connectivity, and the Data Sheet the pin availability.

http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/DM000435pdf

This table should illustrate the TIM to DMA channel associativity.

0690X0000060MmmQAE.gif

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
bl001lighting
Associate
Posted on November 24, 2016 at 06:26

I want to know if those can work with

http://www.szledcolor.com

led ,the updated version of ws2812b