diff options
| author | Marti Bolivar <mbolivar@mit.edu> | 2010-12-08 23:39:37 -0500 | 
|---|---|---|
| committer | Marti Bolivar <mbolivar@mit.edu> | 2010-12-08 23:39:37 -0500 | 
| commit | b67d281d85bd59a9738a9a43c4db1027f81d9208 (patch) | |
| tree | 1940b4743a945160d21eb37c8578fa46e9118d4e /wirish/HardwareTimer.cpp | |
| parent | b34f826ae1470aaa791bd8ed8dd66ccd4d96d82c (diff) | |
| download | librambutan-b67d281d85bd59a9738a9a43c4db1027f81d9208.tar.gz librambutan-b67d281d85bd59a9738a9a43c4db1027f81d9208.zip | |
Servo library tested and debugged.
Some additional HardwareTimer methods introduced to make this
convenient; ancillary libmaple/timers.h changes resulted.
Diffstat (limited to 'wirish/HardwareTimer.cpp')
| -rw-r--r-- | wirish/HardwareTimer.cpp | 150 | 
1 files changed, 102 insertions, 48 deletions
| diff --git a/wirish/HardwareTimer.cpp b/wirish/HardwareTimer.cpp index 5b80ec1..92c6adf 100644 --- a/wirish/HardwareTimer.cpp +++ b/wirish/HardwareTimer.cpp @@ -29,13 +29,10 @@  #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) { @@ -46,122 +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);  } -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) { -    timer_set_mode(this->timerNum,1,mode); +    this->setChannelMode(1, mode);  }  void HardwareTimer::setChannel2Mode(TimerMode mode) { -    timer_set_mode(this->timerNum,2,mode); +    this->setChannelMode(2, mode);  }  void HardwareTimer::setChannel3Mode(TimerMode mode) { -    timer_set_mode(this->timerNum,3,mode); +    this->setChannelMode(3, mode);  }  void HardwareTimer::setChannel4Mode(TimerMode mode) { -    timer_set_mode(this->timerNum,4,mode); +    this->setChannelMode(4, mode); +} + +inline uint16 HardwareTimer::getCompare(int channel) { +    return timer_get_compare_value(this->timerNum, channel); +} + +uint16 HardwareTimer::getCompare1() { +    return this->getCompare(1); +} + +uint16 HardwareTimer::getCompare2() { +    return this->getCompare(2); +} + +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); @@ -171,3 +204,24 @@ 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: +        ASSERT(0); +        return 0; +    } +} | 
