Fork of Erik Olieman's FastPWM library created to add the targets I need.

Fork of FastPWM by Erik -

FastPWM_common.cpp

Committer:
Sissors
Date:
2013-08-13
Revision:
4:a7b9f778c4b4
Child:
6:0f57969697b6

File content as of revision 4:a7b9f778c4b4:

#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;
}