Page 1 of 2

Supporting other prescaling factors in the PWM module

Posted: Wed Nov 22, 2017 10:16 pm
by orion
Hi there,

The AVR port of the PWM module uses a fixed prescaler factor in pwm_lld_start() which divides the clock frequency by 1024. This gives, for an arduino Uno board, a timer frequency of approximately 16 kHz. Since the timer period is also fixed in 10 bits, this is too low a frequency. Using a low duty cycle value to drive a led makes the led blink noticeably, instead of just dimming.

The GPT module, on the other hand, is flexible on this regard, allowing for any prescaler value, among those configurable, to be used.

Is there an interest in porting this functionality back to the PWM module? I can do that, but only if this were to be merged to the Chibios source tree.

Thanks.

Re: Supporting other prescaling factors in the PWM module

Posted: Thu Nov 23, 2017 9:20 am
by tfAteba
Hi Orion,

I'm aware of all your remarks, last year I have played with this driver for my Self-balencing robot.

Ofcorse, you can implement, that flexibility and send me back your work and it will be merged.

I'm happy to see interrest on AVR support :D .

But just notice that, you have to use trunk for that.

Every contribution us welcome.

Thanks

Re: Supporting other prescaling factors in the PWM module

Posted: Thu Nov 23, 2017 9:23 am
by tfAteba
Here is a link to help you if you want to contribute:

http://www.chibios.com/forum/viewtopic.php?f=38&t=4243

Re: Supporting other prescaling factors in the PWM module

Posted: Thu Nov 23, 2017 10:11 am
by orion
OK, will work on it.

Cheers.

Re: Supporting other prescaling factors in the PWM module

Posted: Thu Nov 23, 2017 10:15 am
by tfAteba
Thanks you in advance.

Re: Supporting other prescaling factors in the PWM module

Posted: Thu Nov 23, 2017 6:20 pm
by orion
Should I post the patch here or should I push to the subversion repository?

Re: Supporting other prescaling factors in the PWM module

Posted: Thu Nov 23, 2017 6:57 pm
by Giovanni
Hi,

A patch is fine, the repository needs permission.

Giovanni

Re: Supporting other prescaling factors in the PWM module

Posted: Thu Nov 23, 2017 8:22 pm
by orion
OK, I've pretty much finished it.

Attached is the patch to make the AVR port of the PWM module work with different prescaler factors for all timers. Furthermore, if a 16-bit timer is being used (i.e., all except timer2), one can also set the pwm period, and that will be loaded in the ICR. Since I've changed the timer mode of operation to fast pwm using ICR as the top value, this will give any period you want from 1 to ICR+1 timer clock pulses. Note that Timer2 does not have this capability, and hence the period is fixed at 0xFF (the maximum). In order to specify a frequency up to F_CPU, I had to change the frequency variable from uint16_t to uint32_t, so the driver struct now takes 2 bytes more. I hope this is not a problem.

When I have time I'll look at how to configure the timer to use phase-correct pwm and frequency-correct pwm. For now, as I said, it only use fast pwm.

I've also changed the main.c file in the testhal PWM directory to exercise not only timer 3, but also timer 1 and 2. This is also in attached patch file.

I don't have an arduino mega board to test but I've tested with an arduino nano using both timer 1 and timer 2. For timer 1 I set the frequency equal to F_CPU (=16MHz) and the period to 0x7FFF, translating to a period of 2.048 ms. Channel 1 was enabled with a 75% duty cycle and channel 2 with a 25% duty cycle. For timer 2, the frequency is F_CPU/32 (500 kHz) and the period is fixed to 0xFF, as noted above. Channel 1 was enabled with a 80% duty cycle, and channel with a 20% duty cycle.

To be able to compile to the nano board, I had to modify the makefile, which I saved as Makefile_nano. I also had to change the mcuconf.h file to use timer 1 and 2 and disable timer 3 (since the ATMega328p in the nano doesn't have it). Finally, to use timer 1 I had to disable the tickless mode in chconf.h.

Attached you can find the patch and 8 screenshots from a scope measuring the pwm waves. They show the module is working correctly as programmed by the test program.

During the tests I found a bug in the old code in the pwm_lld_enable_channel() function handling timer2, where the timer channels were not being enabled if a null channel callback was passed. I've also fixed this, but I wonder if I should also open a ticket in sourceforge for the 17.6.3 branch.

Re: Supporting other prescaling factors in the PWM module

Posted: Thu Nov 23, 2017 10:19 pm
by tfAteba
Hi,

Thanks for your work, I will take a close look to it.

It is not a problem if for the moment, just the fast mode is implemented.

You had a nice idea to also attach example code. I will also test it on the arduino mega board and also other atmega boards.

For the bug you found, you can open a ticket in sourceforge or another topic here as you want.

I hope to have time this weekend to work on the project but not sure.

Thanks you for your contribution.

Re: Supporting other prescaling factors in the PWM module

Posted: Sun Nov 26, 2017 12:50 am
by tfAteba
Hi,

How did you generate your patch? Can you plese use git or svn tout generate your patch so that I Can apply it withougth any error.

Thanks