diff options
Diffstat (limited to 'wirish/HardwareTimer.cpp')
-rw-r--r-- | wirish/HardwareTimer.cpp | 167 |
1 files changed, 107 insertions, 60 deletions
diff --git a/wirish/HardwareTimer.cpp b/wirish/HardwareTimer.cpp index 6fbad8b..354663e 100644 --- a/wirish/HardwareTimer.cpp +++ b/wirish/HardwareTimer.cpp @@ -22,22 +22,17 @@ * THE SOFTWARE. *****************************************************************************/ -/** - * @brief wirish timer class to manage the four 16-bit timer peripherals - * - * This implementation is not very efficient (lots of duplicated functions) +/* + * wirish timer class to manage the four 16-bit timer peripherals */ #include "wirish.h" #include "HardwareTimer.h" -HardwareTimer::HardwareTimer(uint8 timerNum) { - ASSERT(timerNum <= NR_TIMERS && timerNum != 6 && timerNum != 7); +HardwareTimer::HardwareTimer(timer_dev_num timerNum) { + ASSERT(timerNum != TIMER_INVALID); this->timerNum = timerNum; - - // Need to remember over flow for bounds checking - this->overflow = 0xFFFF; } void HardwareTimer::resume(void) { @@ -48,126 +43,158 @@ void HardwareTimer::pause(void) { timer_pause(this->timerNum); } +uint16 HardwareTimer::getPrescaleFactor(void) { + return timer_get_prescaler(this->timerNum) + 1; +} + void HardwareTimer::setPrescaleFactor(uint16 factor) { // The prescaler register is zero-indexed timer_set_prescaler(this->timerNum, factor-1); } -void HardwareTimer::setOverflow(uint16 val) { - this->overflow = val; - timer_set_reload(this->timerNum, val); +uint16 HardwareTimer::getOverflow() { + return timer_get_reload(this->timerNum); } -void HardwareTimer::setCount(uint16 val) { - if(val > this->overflow) { - val = this->overflow; - } - timer_set_count(this->timerNum, val); +void HardwareTimer::setOverflow(uint16 val) { + timer_set_reload(this->timerNum, val); } uint16 HardwareTimer::getCount(void) { return timer_get_count(this->timerNum); } -/* This function will set the prescaler and overflow to get a period - * of the given length with the most resolution; the return value is - * the overflow value and thus the largest value that can be set as a - * compare. */ -uint16 HardwareTimer::setPeriod(uint32 microseconds) { - // XXX: 72MHz shouldn't be hard coded in here... global define? +void HardwareTimer::setCount(uint16 val) { + uint16 ovf = this->getOverflow(); + timer_set_count(this->timerNum, min(val, ovf)); +} +uint16 HardwareTimer::setPeriod(uint32 microseconds) { // Not the best way to handle this edge case? if(!microseconds) { setPrescaleFactor(1); setOverflow(1); - return this->overflow; + return this->getOverflow(); } + uint32 cycles = microseconds * CYCLES_PER_MICROSECOND; - // With a prescale factor of 1, there are 72counts/ms - uint16 ps = ((microseconds*72)/65536) + 1; + // With a prescale factor of 1, there are CYCLES_PER_MICROSECOND + // counts/ms + uint16 ps = (uint16)((cycles >> 16) + 1); setPrescaleFactor(ps); // Finally, this overflow will always be less than 65536 - setOverflow(((microseconds*72)/ps) - 1); - return this->overflow; + setOverflow((cycles/ps) - 1); + + return this->getOverflow(); +} + +inline void HardwareTimer::setChannelMode(int channel, TimerMode mode) { + timer_set_mode(this->timerNum, channel, mode); +} + +void HardwareTimer::setChannel1Mode(TimerMode mode) { + this->setChannelMode(1, mode); +} + +void HardwareTimer::setChannel2Mode(TimerMode mode) { + this->setChannelMode(2, mode); +} + +void HardwareTimer::setChannel3Mode(TimerMode mode) { + this->setChannelMode(3, mode); +} + +void HardwareTimer::setChannel4Mode(TimerMode mode) { + this->setChannelMode(4, mode); } -void HardwareTimer::setChannel1Mode(uint8 mode) { - timer_set_mode(this->timerNum,1,mode); +inline uint16 HardwareTimer::getCompare(int channel) { + return timer_get_compare_value(this->timerNum, channel); } -void HardwareTimer::setChannel2Mode(uint8 mode) { - timer_set_mode(this->timerNum,2,mode); +uint16 HardwareTimer::getCompare1() { + return this->getCompare(1); } -void HardwareTimer::setChannel3Mode(uint8 mode) { - timer_set_mode(this->timerNum,3,mode); +uint16 HardwareTimer::getCompare2() { + return this->getCompare(2); } -void HardwareTimer::setChannel4Mode(uint8 mode) { - timer_set_mode(this->timerNum,4,mode); +uint16 HardwareTimer::getCompare3() { + return this->getCompare(3); +} + +uint16 HardwareTimer::getCompare4() { + return this->getCompare(4); +} + +inline void HardwareTimer::setCompare(int channel, uint16 val) { + uint16 ovf = this->getOverflow(); + timer_set_compare_value(this->timerNum, channel, min(val, ovf)); } void HardwareTimer::setCompare1(uint16 val) { - if(val > this->overflow) { - val = this->overflow; - } - timer_set_compare_value(this->timerNum,1,val); + this->setCompare(1, val); } void HardwareTimer::setCompare2(uint16 val) { - if(val > this->overflow) { - val = this->overflow; - } - timer_set_compare_value(this->timerNum,2,val); + this->setCompare(2, val); } void HardwareTimer::setCompare3(uint16 val) { - if(val > this->overflow) { - val = this->overflow; - } - timer_set_compare_value(this->timerNum,3,val); + this->setCompare(3, val); } void HardwareTimer::setCompare4(uint16 val) { - if(val > this->overflow) { - val = this->overflow; - } - timer_set_compare_value(this->timerNum,4,val); + this->setCompare(4, val); +} + +inline void HardwareTimer::attachInterrupt(int channel, voidFuncPtr handler) { + timer_attach_interrupt(this->timerNum, channel, handler); } void HardwareTimer::attachCompare1Interrupt(voidFuncPtr handler) { - timer_attach_interrupt(this->timerNum,1,handler); + this->attachInterrupt(1, handler); } void HardwareTimer::attachCompare2Interrupt(voidFuncPtr handler) { - timer_attach_interrupt(this->timerNum,2,handler); + this->attachInterrupt(2, handler); } void HardwareTimer::attachCompare3Interrupt(voidFuncPtr handler) { - timer_attach_interrupt(this->timerNum,3,handler); + this->attachInterrupt(3, handler); } void HardwareTimer::attachCompare4Interrupt(voidFuncPtr handler) { - timer_attach_interrupt(this->timerNum,4,handler); + this->attachInterrupt(4, handler); +} + +inline void HardwareTimer::detachInterrupt(int channel) { + timer_detach_interrupt(this->timerNum, channel); } void HardwareTimer::detachCompare1Interrupt(void) { - timer_detach_interrupt(this->timerNum,1); + this->detachInterrupt(1); } void HardwareTimer::detachCompare2Interrupt(void) { - timer_detach_interrupt(this->timerNum,2); + this->detachInterrupt(2); } void HardwareTimer::detachCompare3Interrupt(void) { - timer_detach_interrupt(this->timerNum,3); + this->detachInterrupt(3); } void HardwareTimer::detachCompare4Interrupt(void) { - timer_detach_interrupt(this->timerNum,4); + this->detachInterrupt(4); +} + +void HardwareTimer::generateUpdate(void) { + timer_generate_update(this->timerNum); } + HardwareTimer Timer1(TIMER1); HardwareTimer Timer2(TIMER2); HardwareTimer Timer3(TIMER3); @@ -177,3 +204,23 @@ HardwareTimer Timer5(TIMER5); // High-density devices only HardwareTimer Timer8(TIMER8); // High-density devices only #endif +HardwareTimer* getTimer(timer_dev_num timerNum) { + switch (timerNum) { + case TIMER1: + return &Timer1; + case TIMER2: + return &Timer2; + case TIMER3: + return &Timer3; + case TIMER4: + return &Timer4; +#if NR_TIMERS >= 8 + case TIMER5: + return &Timer5; + case TIMER8: + return &Timer8; +#endif + default: + return 0; + } +} |