2021-03-21 07:16 AM
I want to generate waveform for 8 channel WS2812 leds using STM32F103. This device uses pulse with to transfer bits.. The longer pulse means 1, the shorter means 0..
Because I want to generate 8 channel wavefrm, I configured 3 DMA's, one moves 0xFF to GPIO, one moves value from RAM to GPIO, and the third one moves 0x00 to GPIO.. The timing is generated by TIM2's CC1, CC2 and TIM2's update events.. That way, CC1 moves 1s to GPIO, CC2 moves Data to GPIO, update moves 0s to GPIO.
TIM3 is connected as slave to the TIM2. In each TIM2 update, TIM3 counts up. It is configured as oen pulse, so that when TIM3 reaches ARR, it disables it self.. TIM2 is connected as slave to TIM3 as gated mode.. When TIM3 starts/stops TIM2 starts/stops as well.. This way I limit the transfers, and after final TIM2 update, which moves 0 to the GPIO, system stops until I reenable the timer.
Waveform for 8 channels is generated correctly but the very first pulse is generated wrong.. It looks like TIM2 generates request for all 3 DMA's as soon as it is enabled, even before CC1, CC2 and update is generated. That casues very first transfers be done with respect to DMA's priorities. The remaining pulses are generated as expected..
To make it easier, I made a waveform with 5 pulses.. ARR of TIM3 is set to 4..
This is correct transfer of 11011
This is the very first transfer whose first bit is scrambled because of initial DMA request:
When I do not enable DMA requests, enable the TIM3, disable it, reset TIM2->CNT and TIM3->CNT, enabling DMA request, reanable TIM3 the very first pulse is also generated correctly.. As I mentined the remaining cycles are correct.. Like the following code:
I am using my own library. However, I think the names are self evident..
I've a workaround, but I want to understand why TIM2 generates DMA request when it is enabled even if the counter has not reached configured state..
Solved! Go to Solution.
2021-03-21 11:28 PM
Ok, it's definitely the prescaler.. When I write the following code, first pulse is generated correctly as well..
Enabling disabling the timer caused TIM2 to run at full speed and reload the prescaler, which is done here by setting EGR's UG bit..
I need to update my HAL code such that it will force prescaler to be updated for the first run if the prescaler is different from the current value and the timer is not running and the CNT is 0..
2021-03-21 08:18 AM
Details matter so unless you show exactly the sequence of steps leading to the incorrect waveform it's hard to tell exactly what has happened, but generally, single-step through your code and look at TIM2_SR. Whenever a flag gets set there, it also set a latch for respective DMA trigger (this is invisible to user), provided that the respective DIER.xxDE bit is enabled.
A common misconception is, that TIMx_CR1.CEN stops/resets/prevents activity of the whole TIM module, whereas it only gates the clock to the counter (prescaler, more precisely), that's all it does.
JW
2021-03-21 11:21 PM
This is the initial configuration just before dataTim's enable..
If the compare's are set to 2 and 3 how can they generate DMA request at start?
My mistake might be prescaler is being updated after first cycle.. It looks like TIM2 runs at full speed for first cycle, but recovers after the second..
2021-03-21 11:28 PM
Ok, it's definitely the prescaler.. When I write the following code, first pulse is generated correctly as well..
Enabling disabling the timer caused TIM2 to run at full speed and reload the prescaler, which is done here by setting EGR's UG bit..
I need to update my HAL code such that it will force prescaler to be updated for the first run if the prescaler is different from the current value and the timer is not running and the CNT is 0..