Making frequent calls to PwmOut.pulsewidth_us(); noting annomalies in the output wave

20 Jun 2015

Example scenario:

  • STM32F103RB target
  • PwmOut pin
  • PWM period set to 20ms
  • Calls to PwmOut.pulsewidth_us(); made every 20ms

Every so often, I see the attached waveform. The low pulse propagates through the high pulsewave on each subsequent high pulse until it disappears outright. It will inevitably reappear in some amount of time and exhibit the same behavior.

Presumably, some of the calls to pulsewidth_us() are interrupting the pulsewave while it's high and the mcu is immediately reconfiguring the PWM registers, which results in the malformed waveform.

Is there any way to make these frequent calls to change the duration of the pin without malforming the wave?

/media/uploads/chris1seto/pwmfault.png

20 Jun 2015

You might need to attach an interrupt for when the pulse ends, and change the registers at that point, or just see what the pulsewidth_us() function does in code, if it is just resetting the timer/state?

https://developer.mbed.org/users/mbed_official/code/mbed-src/file/536c9fb088a0/targets/hal/TARGET_STM/TARGET_STM32F1/pwmout_api.c Might be a starting point?

20 Jun 2015

You can also have a look at: https://developer.mbed.org/users/Sissors/code/FastPWM/. That does not disable the PWM when reloading a new value like the official code does for some reason. It also enables buffering for its period register, so that can be changed glitch free, however I just had a look at the datasheet, and that buffer is also available for the compare registers, and is not set yet, while it should be set. Without it being set you can get problems when reducing the pulsewidth.

Currently I don't have access to a Nucleo device, so I sadly cannot test it to change it myself. You can try it by importing it, going to this file: https://developer.mbed.org/users/Sissors/code/FastPWM/docs/ed690a19dc55/FastPWM__STM__TIM_8cpp_source.html, and after the PWM period glitch free code add:

PWM_TIMER->CCMR1 |= TIM_CCMR1_OC2PE | TIM_CCMR1_OC1PE;
PWM_TIMER->CCMR2 |= TIM_CCMR2_OC4PE | TIM_CCMR2_OC3PE;

Then it should have enabled the hardware buffering for the 4 compare outputs of the timer, and it should be completely glitch free. If you can try it and report back if it works (especially if you want try multiple times what happens when you significantly reduce the pulsewidth when it is running).

20 Jun 2015

Hi Erik,

I actually saw your library, but I was getting compile errors on the STM32F103RB with it. the compiler was complaining about incorrect return type in this function:

  1. if defined TARGET_NUCLEO_F103RB IO uint16_t* getChannel(TIM_TypeDef* pwm, PinName pin) {

Have you tested this library on this target lately?

20 Jun 2015

I am not in a position to test them all for each target everytime STM messes something up :P. They also changed other registers for IO breaking another lib of mine, but here they apparantly modified a 16-bit register to 32-bit for some reason. I didn't see the error at that function, but at the pinout. Changing that file solved it, even though the definition which you copied still had 16-bit. However out of fear it would then truncate values I also changed that one to 32-bit. (It was actually a special situation where it was used as 16-bit while the others were 32-bit).

I hope it now work properly, but besides that I don't have a Nucleo device that I can use currently, I don't have a Nucleo F103 at all. So I can't really test it, but I did modify it and commited it. So if you update your lib you have the latest version: I did not yet do the modifications I mentioned above, since they affect all STM targets without me being able to test it now.

If you would test it, and it works fine, you are welcome to make a pull request :).

Erik

20 Jun 2015

Hi Erik,

Thanks for the fix, I'll test it tonight. I actually have a number of stm targets, so please let me know if you have other stuff to test; I'd be happy to do it for you :)

21 Jun 2015

Hi Erik,

Just wanted to follow up that the update worked great! Thanks so much. Please let me know if you need random stuff tested on an STM platform, I'd be glad to do it. Just PM me.

21 Jun 2015

Good to know. Just to be sure: That is with those two lines added? Because then I also add them to the FastPWM code base :).

(Imo the official code should have used this from the beginning, instead of resetting the PWM output each time you change something).

Also I do have a bunch of STM boards (F030, F401 and F407), but I will send you a PM when I need something tested on another board :).

21 Jun 2015

Hey Erik,

I actually just hit update on your library, so I was directly testing your libs. And I totally agree, I have no idea why they'd reset the PWM output like this. The whole point of PWM is for it to be easily changed!

Thanks again for the quick fix!!!