I'm using PWM on the i.MX53 as an LCD Backlight Driver control.
When the brightness is ramped up it all works fine. When it is ramped down there are glitches.
That happens a lot on old and cheap PWM timers. What it means is that the Comparison Count register was reloaded just as the counter was approaching the previous value in that register and about to get a match. But the reload jumped the comparison value "back over" the counter, and so it ran to the end of the cycle without getting a match and without turning the output off. Hence you get one full cycle at 100%, causing a one-cycle "glitch".
Better PWM controllers keep a copy of the Sample/Comparison value, and only replace it at the end of a cycle so there are no glitches. With cheaper controllers you have to write code to take an interrupt at the end of a cycle and load the new value then. This goes badly wrong at low duty-cycles when the PWM counter beats the interrupt routine, or the interrupt gets delayed.
Here's an example of the glitch happening on a controller that doesn't buffer the sample value. The Yellow line is a falling ramp value which is the brightness of the screen. The Pink is the PWM output. You can see one full-length cycle when it missed the comparison.
Except that's the PWM controller in the i.MX53. It has a four-deep FIFO that is MEANT to stop this from happening. Except the Data Sheet is contradictory on how it works.
This bit implies "there's a FIFO and it works like you'd expect so as to prevent glitches":
51.7.5 PWM Sample Register (PWMx_PWMSAR)
The PWM will run at the last set duty-cycle setting if all the values of
the FIFO has been utilized, until the FIFO is reloaded or the PWM is disabled. When a
new value is written, the duty cycle changes after the current period is over.
But the HIGHLIGHTED bit in the following implies it uses the LIVE value in the FIFO and not a copy that it took at the start of the cycle (which it would have to do if it was to work properly):
At the beginning of a count period cycle, the PWMO pin is set to one (default) and the
counter begins counting up from 0x0000. The sample value in the sample FIFO is
compared on each count of prescaler clock. When the sample and count values match, the
PWMO signal is cleared to zero (default). The counter continues counting until the period
match occurs and subsequently another period cycle begins.
From the flashing on my screen and the oscilloscope trace above it looks like it doesn't work properly. If the FIFO is empty it takes the new value immediately. It only seems to buffer the sample when the FIFO is "loaded". That may be the case when sending a continuous waveform (music) through the PWM, but not when changing it intermittently when controlling a backlight.
I have found a work-around that proves my assertion.
If I read the FIFO then write the same value back (to load a value) and THEN load a new value in, it doesn't flash any more. Having the second value in the FIFO makes it wait until the end of the cycle. Of course the driver could keep a copy of the previous value and always write previous/next on an update.
That looks like a silicon bug to me. I've checked the i.MX53 and i.MX6 Errata and the PWM isn't listed. At the very least the chip isn't doing what the first quote from the manual above states.
Edit: I've just found the following Forum post which shows the same problem on the i.MX6"
There are two fixes listed there. First invert the PWM signal so it glitches DOWN instead of glitching UP (but it still glitches). Secondly, setting the REPEAT bits seems to fix this as well.