2018-02-16 11:05 PM
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)
- I configured DMA by next way
- 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 #stm32f4discovery2018-02-17 02:59 AM
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...
2018-02-17 05:54 AM
Your using uint32_t buffer. Try changing the data width on DMA config dialog from Byte to WORD.
2018-02-17 07:59 AM
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.
2018-02-17 09:37 AM
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)
2018-02-20 03:08 PM
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.