diff options
Diffstat (limited to 'wirish/HardwareTimer.cpp')
-rw-r--r-- | wirish/HardwareTimer.cpp | 228 |
1 files changed, 74 insertions, 154 deletions
diff --git a/wirish/HardwareTimer.cpp b/wirish/HardwareTimer.cpp index 354663e..d0e32c3 100644 --- a/wirish/HardwareTimer.cpp +++ b/wirish/HardwareTimer.cpp @@ -22,205 +22,125 @@ * THE SOFTWARE. *****************************************************************************/ -/* - * wirish timer class to manage the four 16-bit timer peripherals - */ - -#include "wirish.h" #include "HardwareTimer.h" +#include "boards.h" // for CYCLES_PER_MICROSECOND +#include "wirish_math.h" -HardwareTimer::HardwareTimer(timer_dev_num timerNum) { - ASSERT(timerNum != TIMER_INVALID); +// TODO [0.1.0] Remove deprecated pieces - this->timerNum = timerNum; -} +#ifdef STM32_MEDIUM_DENSITY +#define NR_TIMERS 4 +#elif defined(STM32_HIGH_DENSITY) +#define NR_TIMERS 8 +#else +#error "Unsupported density" +#endif -void HardwareTimer::resume(void) { - timer_resume(this->timerNum); +#define MAX_RELOAD ((1 << 16) - 1) + +HardwareTimer::HardwareTimer(uint8 timerNum) { + if (timerNum > NR_TIMERS) { + ASSERT(0); + } + timer_dev *devs[] = { + TIMER1, + TIMER2, + TIMER3, + TIMER4, +#ifdef STM32_HIGH_DENSITY + TIMER5, + TIMER6, + TIMER7, + TIMER8, +#endif + }; + this->dev = devs[timerNum - 1]; } void HardwareTimer::pause(void) { - timer_pause(this->timerNum); + timer_pause(this->dev); } -uint16 HardwareTimer::getPrescaleFactor(void) { - return timer_get_prescaler(this->timerNum) + 1; +void HardwareTimer::resume(void) { + timer_resume(this->dev); +} + +uint32 HardwareTimer::getPrescaleFactor(void) { + return timer_get_prescaler(this->dev) + 1; } -void HardwareTimer::setPrescaleFactor(uint16 factor) { - // The prescaler register is zero-indexed - timer_set_prescaler(this->timerNum, factor-1); +void HardwareTimer::setPrescaleFactor(uint32 factor) { + timer_set_prescaler(this->dev, (uint16)(factor - 1)); } uint16 HardwareTimer::getOverflow() { - return timer_get_reload(this->timerNum); + return timer_get_reload(this->dev); } void HardwareTimer::setOverflow(uint16 val) { - timer_set_reload(this->timerNum, val); + timer_set_reload(this->dev, val); } uint16 HardwareTimer::getCount(void) { - return timer_get_count(this->timerNum); + return timer_get_count(this->dev); } void HardwareTimer::setCount(uint16 val) { uint16 ovf = this->getOverflow(); - timer_set_count(this->timerNum, min(val, ovf)); + timer_set_count(this->dev, min(val, ovf)); } +// FIXME [0.0.10 beta] test! uint16 HardwareTimer::setPeriod(uint32 microseconds) { // Not the best way to handle this edge case? - if(!microseconds) { - setPrescaleFactor(1); - setOverflow(1); + if (!microseconds) { + this->setPrescaleFactor(1); + this->setOverflow(1); return this->getOverflow(); } - uint32 cycles = microseconds * CYCLES_PER_MICROSECOND; - - // 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((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); -} - -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); + uint32 period_cyc = microseconds * CYCLES_PER_MICROSECOND; + uint16 prescaler = (uint16)(period_cyc / MAX_RELOAD); + uint16 overflow = (uint16)round(period_cyc / prescaler); + this->setPrescaleFactor(prescaler); + this->setOverflow(overflow); + return overflow; } -uint16 HardwareTimer::getCompare3() { - return this->getCompare(3); +void HardwareTimer::setMode(int channel, timer_mode mode) { + timer_set_mode(this->dev, (uint8)channel, (timer_mode)mode); } -uint16 HardwareTimer::getCompare4() { - return this->getCompare(4); +uint16 HardwareTimer::getCompare(int channel) { + return timer_get_compare(this->dev, (uint8)channel); } -inline void HardwareTimer::setCompare(int channel, uint16 val) { +void HardwareTimer::setCompare(int channel, uint16 val) { uint16 ovf = this->getOverflow(); - timer_set_compare_value(this->timerNum, channel, min(val, ovf)); + timer_set_compare(this->dev, (uint8)channel, min(val, ovf)); } -void HardwareTimer::setCompare1(uint16 val) { - this->setCompare(1, val); +void HardwareTimer::attachInterrupt(int channel, voidFuncPtr handler) { + timer_attach_interrupt(this->dev, (uint8)channel, handler); } -void HardwareTimer::setCompare2(uint16 val) { - this->setCompare(2, val); +void HardwareTimer::detachInterrupt(int channel) { + timer_detach_interrupt(this->dev, (uint8)channel); } -void HardwareTimer::setCompare3(uint16 val) { - this->setCompare(3, val); +void HardwareTimer::refresh(void) { + timer_generate_update(this->dev); } -void HardwareTimer::setCompare4(uint16 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) { - this->attachInterrupt(1, handler); -} - -void HardwareTimer::attachCompare2Interrupt(voidFuncPtr handler) { - this->attachInterrupt(2, handler); -} - -void HardwareTimer::attachCompare3Interrupt(voidFuncPtr handler) { - this->attachInterrupt(3, handler); -} - -void HardwareTimer::attachCompare4Interrupt(voidFuncPtr handler) { - this->attachInterrupt(4, handler); -} - -inline void HardwareTimer::detachInterrupt(int channel) { - timer_detach_interrupt(this->timerNum, channel); -} - -void HardwareTimer::detachCompare1Interrupt(void) { - this->detachInterrupt(1); -} - -void HardwareTimer::detachCompare2Interrupt(void) { - this->detachInterrupt(2); -} - -void HardwareTimer::detachCompare3Interrupt(void) { - this->detachInterrupt(3); -} - -void HardwareTimer::detachCompare4Interrupt(void) { - this->detachInterrupt(4); -} +/* -- Deprecated predefined instances -------------------------------------- */ -void HardwareTimer::generateUpdate(void) { - timer_generate_update(this->timerNum); -} - - -HardwareTimer Timer1(TIMER1); -HardwareTimer Timer2(TIMER2); -HardwareTimer Timer3(TIMER3); -HardwareTimer Timer4(TIMER4); -#if NR_TIMERS >= 8 -HardwareTimer Timer5(TIMER5); // High-density devices only -HardwareTimer Timer8(TIMER8); // High-density devices only +HardwareTimer Timer1(1); +HardwareTimer Timer2(2); +HardwareTimer Timer3(3); +HardwareTimer Timer4(4); +#ifdef STM32_HIGH_DENSITY +HardwareTimer Timer5(5); +HardwareTimer Timer6(6); +HardwareTimer Timer7(7); +HardwareTimer Timer8(8); #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; - } -} |