FastPWM clone

Committer:
Sissors
Date:
Sun Sep 03 16:26:07 2017 +0000
Revision:
33:2ca2e47f9650
Parent:
18:d91c0629e4e6
Child:
34:c0b2265cff9c
KSDK (K64F) update
; Now it should properly synchronize PWM updates again
;
; Serious @mbed, clearing the timer is not a proper synchronisation mechanic for PWM!

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 4:a7b9f778c4b4 1 #include "FastPWM.h"
Sissors 4:a7b9f778c4b4 2
Sissors 4:a7b9f778c4b4 3 FastPWM::FastPWM(PinName pin, int prescaler) : PwmOut(pin) {
Sissors 12:4600daab8a83 4 fast_obj = NULL;
Sissors 4:a7b9f778c4b4 5 initFastPWM();
Sissors 4:a7b9f778c4b4 6 this->prescaler(prescaler);
Sissors 4:a7b9f778c4b4 7
Sissors 4:a7b9f778c4b4 8 //Set duty cycle on 0%, period on 20ms
Sissors 4:a7b9f778c4b4 9 period(0.02);
Sissors 6:0f57969697b6 10 write(0);
Sissors 4:a7b9f778c4b4 11
Sissors 4:a7b9f778c4b4 12
Sissors 4:a7b9f778c4b4 13 }
Sissors 4:a7b9f778c4b4 14
Sissors 12:4600daab8a83 15 FastPWM::~FastPWM( void ) {
Sissors 12:4600daab8a83 16 if (fast_obj != NULL)
Sissors 12:4600daab8a83 17 delete(fast_obj);
Sissors 12:4600daab8a83 18 }
Sissors 12:4600daab8a83 19
Sissors 4:a7b9f778c4b4 20 void FastPWM::period(double seconds) {
Sissors 4:a7b9f778c4b4 21 if (dynamicPrescaler)
Sissors 4:a7b9f778c4b4 22 calcPrescaler((uint64_t)(seconds * (double) SystemCoreClock));
Sissors 4:a7b9f778c4b4 23
Sissors 4:a7b9f778c4b4 24 period_ticks(seconds * dticks + 0.5);
Sissors 4:a7b9f778c4b4 25 }
Sissors 4:a7b9f778c4b4 26
Sissors 4:a7b9f778c4b4 27 void FastPWM::period_ms(int ms) {
Sissors 4:a7b9f778c4b4 28 if (dynamicPrescaler)
Sissors 4:a7b9f778c4b4 29 calcPrescaler(ms * (SystemCoreClock / 1000));
Sissors 4:a7b9f778c4b4 30
Sissors 4:a7b9f778c4b4 31 period_ticks(ms * iticks_ms);
Sissors 4:a7b9f778c4b4 32 }
Sissors 4:a7b9f778c4b4 33
Sissors 4:a7b9f778c4b4 34 void FastPWM::period_us(int us) {
Sissors 4:a7b9f778c4b4 35 if (dynamicPrescaler)
Sissors 4:a7b9f778c4b4 36 calcPrescaler(us * (SystemCoreClock / 1000000));
Sissors 4:a7b9f778c4b4 37
Sissors 4:a7b9f778c4b4 38 period_ticks(us * iticks_us);
Sissors 4:a7b9f778c4b4 39 }
Sissors 4:a7b9f778c4b4 40
Sissors 4:a7b9f778c4b4 41 void FastPWM::period_us(double us) {
Sissors 4:a7b9f778c4b4 42 if (dynamicPrescaler)
Sissors 4:a7b9f778c4b4 43 calcPrescaler((uint64_t)(us * (double)(SystemCoreClock / 1000000)));
Sissors 4:a7b9f778c4b4 44
Sissors 4:a7b9f778c4b4 45 period_ticks(us * dticks_us + 0.5);
Sissors 4:a7b9f778c4b4 46 }
Sissors 4:a7b9f778c4b4 47
Sissors 4:a7b9f778c4b4 48 void FastPWM::pulsewidth(double seconds) {
Sissors 4:a7b9f778c4b4 49 pulsewidth_ticks(seconds * dticks + 0.5);
Sissors 4:a7b9f778c4b4 50 }
Sissors 4:a7b9f778c4b4 51
Sissors 4:a7b9f778c4b4 52 void FastPWM::pulsewidth_ms(int ms) {
Sissors 4:a7b9f778c4b4 53 pulsewidth_ticks(ms * iticks_ms);
Sissors 4:a7b9f778c4b4 54 }
Sissors 4:a7b9f778c4b4 55
Sissors 4:a7b9f778c4b4 56 void FastPWM::pulsewidth_us(int us) {
Sissors 4:a7b9f778c4b4 57 pulsewidth_ticks(us * iticks_us);
Sissors 4:a7b9f778c4b4 58 }
Sissors 4:a7b9f778c4b4 59
Sissors 4:a7b9f778c4b4 60 void FastPWM::pulsewidth_us(double us) {
Sissors 4:a7b9f778c4b4 61 pulsewidth_ticks(us * dticks_us + 0.5);
Sissors 4:a7b9f778c4b4 62 }
Sissors 4:a7b9f778c4b4 63
Sissors 4:a7b9f778c4b4 64 void FastPWM::write(double duty) {
Sissors 4:a7b9f778c4b4 65 _duty=duty;
Sissors 33:2ca2e47f9650 66 wait_ms(100);
Sissors 4:a7b9f778c4b4 67 pulsewidth_ticks(duty*getPeriod());
Sissors 4:a7b9f778c4b4 68 }
Sissors 4:a7b9f778c4b4 69
Sissors 4:a7b9f778c4b4 70 double FastPWM::read( void ) {
Sissors 4:a7b9f778c4b4 71 return _duty;
Sissors 4:a7b9f778c4b4 72 }
Sissors 4:a7b9f778c4b4 73
Sissors 4:a7b9f778c4b4 74 FastPWM & FastPWM::operator= (double value) {
Sissors 4:a7b9f778c4b4 75 write(value);
Sissors 4:a7b9f778c4b4 76 return(*this);
Sissors 4:a7b9f778c4b4 77 }
Sissors 4:a7b9f778c4b4 78
Sissors 4:a7b9f778c4b4 79 FastPWM::operator double() {
Sissors 4:a7b9f778c4b4 80 return _duty;
Sissors 4:a7b9f778c4b4 81 }
Sissors 4:a7b9f778c4b4 82
Sissors 4:a7b9f778c4b4 83 int FastPWM::prescaler(int value) {
Sissors 4:a7b9f778c4b4 84 int retval;
Sissors 4:a7b9f778c4b4 85 if (value == -1) {
Sissors 4:a7b9f778c4b4 86 dynamicPrescaler = true;
Sissors 4:a7b9f778c4b4 87 value = 0;
Sissors 4:a7b9f778c4b4 88 }
Sissors 4:a7b9f778c4b4 89 else
Sissors 4:a7b9f778c4b4 90 dynamicPrescaler = false;
Sissors 4:a7b9f778c4b4 91
Sissors 4:a7b9f778c4b4 92 retval = setPrescaler(value);
Sissors 4:a7b9f778c4b4 93 updateTicks(retval);
Sissors 4:a7b9f778c4b4 94 return retval;
Sissors 4:a7b9f778c4b4 95 }
Sissors 4:a7b9f778c4b4 96
Sissors 4:a7b9f778c4b4 97 void FastPWM::updateTicks( uint32_t prescaler ) {
Sissors 4:a7b9f778c4b4 98 dticks = SystemCoreClock / (double)prescaler;
jocis 18:d91c0629e4e6 99 dticks_us = dticks / 1000000.0f;
jocis 18:d91c0629e4e6 100 iticks_us = (int)(dticks_us + 0.5);
jocis 18:d91c0629e4e6 101 iticks_ms = (int)(dticks_us * 1000.0 + 0.5);
Sissors 4:a7b9f778c4b4 102 }
Sissors 4:a7b9f778c4b4 103
Sissors 4:a7b9f778c4b4 104 int FastPWM::calcPrescaler(uint64_t clocks) {
Sissors 4:a7b9f778c4b4 105 uint32_t scale = (clocks >> bits) + 1;
Sissors 4:a7b9f778c4b4 106 uint32_t retval = setPrescaler(scale);
Sissors 4:a7b9f778c4b4 107 updateTicks(retval);
Sissors 4:a7b9f778c4b4 108 return retval;
Sissors 4:a7b9f778c4b4 109 }