FastPWM clone
Diff: FastPWM_common.cpp
- Revision:
- 4:a7b9f778c4b4
- Child:
- 6:0f57969697b6
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FastPWM_common.cpp Tue Aug 13 16:54:06 2013 +0000 @@ -0,0 +1,106 @@ +#include "FastPWM.h" + +FastPWM::FastPWM(PinName pin, int prescaler) : PwmOut(pin) { + initFastPWM(); + this->prescaler(prescaler); + + //Set duty cycle on 0%, period on 20ms + _duty=0; + period(0.02); + + +} + +void FastPWM::period(double seconds) { + if (dynamicPrescaler) + calcPrescaler((uint64_t)(seconds * (double) SystemCoreClock)); + + period_ticks(seconds * dticks + 0.5); + pulsewidth_ticks(getPeriod() * _duty); +} + +void FastPWM::period_ms(int ms) { + if (dynamicPrescaler) + calcPrescaler(ms * (SystemCoreClock / 1000)); + + period_ticks(ms * iticks_ms); + pulsewidth_ticks(getPeriod() * _duty); +} + +void FastPWM::period_us(int us) { + if (dynamicPrescaler) + calcPrescaler(us * (SystemCoreClock / 1000000)); + + period_ticks(us * iticks_us); + pulsewidth_ticks(getPeriod() * _duty); +} + +void FastPWM::period_us(double us) { + if (dynamicPrescaler) + calcPrescaler((uint64_t)(us * (double)(SystemCoreClock / 1000000))); + + period_ticks(us * dticks_us + 0.5); + pulsewidth_ticks(getPeriod() * _duty); +} + +void FastPWM::pulsewidth(double seconds) { + pulsewidth_ticks(seconds * dticks + 0.5); +} + +void FastPWM::pulsewidth_ms(int ms) { + pulsewidth_ticks(ms * iticks_ms); +} + +void FastPWM::pulsewidth_us(int us) { + pulsewidth_ticks(us * iticks_us); +} + +void FastPWM::pulsewidth_us(double us) { + pulsewidth_ticks(us * dticks_us + 0.5); +} + +void FastPWM::write(double duty) { + _duty=duty; + pulsewidth_ticks(duty*getPeriod()); +} + +double FastPWM::read( void ) { + return _duty; + } + +FastPWM & FastPWM::operator= (double value) { + write(value); + return(*this); + } + +FastPWM::operator double() { + return _duty; +} + +int FastPWM::prescaler(int value) { + int retval; + if (value == -1) { + dynamicPrescaler = true; + value = 0; + } + else + dynamicPrescaler = false; + + retval = setPrescaler(value); + updateTicks(retval); + return retval; +} + +void FastPWM::updateTicks( uint32_t prescaler ) { + dticks = SystemCoreClock / (double)prescaler; + dticks_us = SystemCoreClock / (double)prescaler / 1000000.0f; + iticks_ms = SystemCoreClock / prescaler / 1000; + iticks_us = SystemCoreClock / prescaler / 1000000; +} + +int FastPWM::calcPrescaler(uint64_t clocks) { + uint32_t scale = (clocks >> bits) + 1; + uint32_t retval = setPrescaler(scale); + updateTicks(retval); + return retval; +} \ No newline at end of file