This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

PWM Duty Cycle update best practices

Because of the limitation in the GPIOTE hardware that only one channel can be connected per GPIO, care must be taken when changing a PWM duty cycle. If for instance the compare events that each trigger a GPIOTE toggle happen in the same clock cycle, the task is only triggered once and suddenly the output duty cycle is inverted.

My question is: What is the best practice for changing a PWM value?

Stopping the timer, updating compare matches, and restarting it kinda works. Unfortunately it "pauses" the output waveform during the update. If the update is not done in an IRQ handler, there is a good chance an interrupt will inflate the "pause" which could have disastrous effect on certain hardware. This method has been implemented in the Simple PWM library that has been floating around here.

The other solution I've found is to use an unsued CC register to trigger an interrupt at exactly the right time in the overall timer period. With careful control of the IRQ Handler, and choice of the extra CC, the update of the CC which's event is mapped to the GPIOTE can happen at a predictable time in the timer cycle and thus you should be able to ensure glitch free output.

I have had both systems mostly working, with the major exception that I've still noticed some glitches or unintended output inversions, which has blown up some of the other components on my board. This is surely because I haven't quite fully taken care of the edge cases.

So, to ask a different way, does anyone else out there have any other ways of doing this?

Related