cancel
Showing results for 
Search instead for 
Did you mean: 

Size of buffer, used by DMA

Khetag Goiaev
Associate II
Posted on February 17, 2018 at 08:05

Hello there!

I want to create a library to maintain work of led-strip based on SK6812

The fastest way to make it work (according to some resources: 

https://geektimes.ru/post/255548/

 (Russian)) is to use PWM timer with DMA.

So, currently, I'm trying to start properly work of led on stm32f4discovery in the following way:

- I used timer TIM4 with PWM on channel 1 (PD12 pin)

0690X00000609iVQAQ.png

- I configured DMA by next way

0690X00000609ifQAA.png

- I created buffer with data to compare in timer and transmitted it to properly register

int k = 125;

uint32_t buf[k];

uint16_t i;

for(uint16_t i =0; i<k; i++){

buf[i] = i*3;

}

HAL_TIM_PWM_Start_DMA(&htim4, TIM_CHANNEL_1, (uint32_t *)buf, sizeof(buf));

There are some problems, but PWM lighting exists.

The main problem is that I can't use a buffer with a size bigger than 125. When I try to use bigger buffer led didn't work.

Is there any fundamental error I don't see? I tried to use other settings in DMA and Timer, but nothing changed.

Thank you for answers!

#timer #stm32f4 #cube #keil #pwm #dma #buffer #stm32f4discovery
5 REPLIES 5
S.Ma
Principal
Posted on February 17, 2018 at 11:59

Is the compiler giving warnings when compiling?

#define MAX_COUNT 125

int k = MAX_COUNT;

uint32_t buf[MAX_COUNT];

uint16_t i;

for(uint16_t i =0; i<k; i++){

buf[i] = (uint32_t) (i*3);

}

and here we assume the linker will naturally align the start memory of buf with even byte address.

The dynamic memory allocation should not be assumed by default.

Alternate way would be to dynamically allocate memory with malloc() which is unusual for bare metal MCUs.

See if this helps or not...

John Craven
Senior
Posted on February 17, 2018 at 14:54

Your using uint32_t buffer. Try changing the data width on DMA config dialog from Byte to WORD.

John Craven
Senior
Posted on February 17, 2018 at 16:59

Make the data width change and try this;

#define BUFFERSIZE 5

uint32_t buffer32[BUFFERSIZE] __attribute__((aligned(4))) = {0, 10,100,1000,10000};

HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, buffer32, BUFFERSIZE);

works on DISCO-411

Your output will start high with your initial channel1 pulse setting of 30000. 

If you set that initial value to 0, the cycle will start up cleanly.

gbm
Lead III
Posted on February 17, 2018 at 18:37

I can see many problems here.

First, it's easier and less memory-hungry to control the WS2812/SKxx using SPI rateher than timer. With SPI sing;e bit sent to WS2812 is encoded using 3 bits.

If you still want to use timer:

1. Set timer period to 3, set prescaler to obtain 2.4 MHz clock after prescaler. Encode one bit using one byte, value 1 or 2.

2. Transfer only one byte to timer CCR register.

3. Declare the byte vector of FIXED size at external level, not in the function, because:

a) variable-size vectors are not quite standard

b) you don't have that much stack space unless you increase it explicitly

c) the vector disappears as soon as you exit the function (and DMA is probably still transferring it)

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
Posted on February 20, 2018 at 23:08

Hello! Thank you for the answer.

I have tried this code and it works. However the max. size has changed to something like 230-240.