Enabling a timer PWM channels in-sync

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
nmz787
Posts: 26
Joined: Sun Jul 10, 2016 7:57 am

Enabling a timer PWM channels in-sync

Post by nmz787 » Tue Feb 28, 2017 10:10 am

In another post, I read about synchronizing timer channels should not be an issue, but I see if I have slow operations in between channel instantiation (i.e. a print statement), I can see the first channel toggling twice for example. My guess is a solution as indicated in this post might help, i.e. somehow setting up my channels then somehow enabling the timer all at once, perhaps from another timer:
viewtopic.php?t=2250#p12761

Here is my code:
https://gist.github.com/nmz787/edd964e9 ... c38bee9b8e

it basically just sets up a Timer at the very bottom, then two channels, and a callback which increments a variable-counter and after a number of times force-disables toggling and calls the Timer's deinit method to stop compare-events.

Any ideas why I seem to get glitchy behavior when I change the period from i.e. 1900 to 1200 (the channel that was first firing changes to become second to fire)?

Thanks!
-Nathan

nmz787
Posts: 26
Joined: Sun Jul 10, 2016 7:57 am

Re: Enabling a timer PWM channels in-sync

Post by nmz787 » Tue Feb 28, 2017 8:56 pm

What I really want to do is enable two PWM channels which are exactly 180 degrees out of phase.

Here is an example image from the previously-posted (glitch-prone) code:
https://cibolo.us/pipermail/open_electr ... t-0009.png

User avatar
dhylands
Posts: 2494
Joined: Mon Jan 06, 2014 6:08 pm
Location: Shuswap, BC, Canada
Contact:

Re: Enabling a timer PWM channels in-sync

Post by dhylands » Tue Feb 28, 2017 9:17 pm

If you really want them in sync then you should use 2 channels on the same timer.

I'm not sure exactly what you mean by 180 degrees out of phase. You can get the negative of a PWM signal by using PWM_INVERTED when you initialize the channel.

If you want to get 2 different timers synchronized, you could probably do something like this:
- initialize the timers, and then disable them by setting the CEN bit in CR1 to 0.
- initialize the counter registers in the 2 timers to get the phase relationship you want.
- Write a small inline assembler routine which sets the CEN bit in each of timers to 1. By using inline assembler both timers will be running at as close to the same time as you can get them.

Another method would be use a timer as the clock source and then slave 2 other timers off of it. Timer1 & 8 can both be slaved off of timers 2, 4, and 5. So lets say you picked timer 2. You setup timers 1 & 8 and disable them (using the CEN bit). Then set them up as slaves (this will require using stm.mem commands) and set the counter registers the way you want. Enabled them both, and then setup the master timer. Now both timer 1 and 8 will be exactly in phase with each since they're both being clocked by timer 2.

nmz787
Posts: 26
Joined: Sun Jul 10, 2016 7:57 am

Re: Enabling a timer PWM channels in-sync

Post by nmz787 » Wed Mar 01, 2017 9:29 pm

Does anyone around here take bounties? :?
I spent another night trying things with no phenomenal progress. Hopefully it doesn't take too many more of these kind of nights.

By out of phase, imagine a PWM pulse train (of constant period and pulse-width), then add the requirement that every-other pulse was being output on a different GPIO.

I saw somethings like "N-pulse waveform generation using one-pulse mode" which sounds like it could also be useful.. but with an attached interrupt and a counter and IF statement, I am able to terminate the timers after a set number of pulses/callbacks. Less software would be nice though, meaning more time for ADC read processing/offloading via serial/etc.

nmz787
Posts: 26
Joined: Sun Jul 10, 2016 7:57 am

Re: Enabling a timer PWM channels in-sync

Post by nmz787 » Wed Mar 01, 2017 9:37 pm

P.S. The problem with using PWM_INVERTED is that I actually care about the positive portions, while using INVERTED means the logic sees the pulse is actually "period - pulse_width"... but the portion I use is the wing/edge of this... so when I stop the timers, the last 'useful to me pulse' is cut in half (which is a glitch in my use case).

using inverted idea, single pulse:
NORMAL : ___|==|___
INVERTED:==|_____|=

inverted idea few pulses, with glitch at beginning and end of INVERTED output pin:
NORMAL : ___|==|______|==|______|==|______|==|______|==|__
INVERTED:==|_____|==|______|==|______|==|______|==|_____|=

nmz787
Posts: 26
Joined: Sun Jul 10, 2016 7:57 am

Re: Enabling a timer PWM channels in-sync

Post by nmz787 » Thu Mar 02, 2017 9:49 am

Ok, I think I got it working... I need to really clean things up, but here's what I've got as of now, and it seems glitch-free for startup and shutdown, as well as for adjusting the pulse width and period.

https://gist.github.com/nmz787/edd964e9 ... c38bee9b8e

Basically, TIM1 starts TIM2, TIM3, and TIM5... then after a number of interrupts on TIM2, it shuts itself down and attaches a shutdown-timer to TIM3, which forces TIM5's output to be low

I'm sure there is some refining, as there is some wonky code to workaround wonky behavior, likely because the micropython Timer calls are doing a lot more than I still understand... the cleanest operation might require getting rid of the micropython Timer calls altogether... but that sounds like more work :/ :D oh well... this seems like progress anyway!

Post Reply