aboutsummaryrefslogtreecommitdiffstats
path: root/wirish/HardwareTimer.cpp
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2010-07-20 15:34:22 -0400
committerbnewbold <bnewbold@robocracy.org>2010-07-20 15:37:44 -0400
commit895d2a48fa30fa3fb3d6897834f838e25f8a2c58 (patch)
tree46f400e30d5388fdff87540d07bd43156bbac008 /wirish/HardwareTimer.cpp
parent94fa3a7705bd67f9ec39da16016182362e3756a0 (diff)
downloadlibrambutan-895d2a48fa30fa3fb3d6897834f838e25f8a2c58.tar.gz
librambutan-895d2a48fa30fa3fb3d6897834f838e25f8a2c58.zip
wirish implementation of timers plus test
Diffstat (limited to 'wirish/HardwareTimer.cpp')
-rw-r--r--wirish/HardwareTimer.cpp149
1 files changed, 149 insertions, 0 deletions
diff --git a/wirish/HardwareTimer.cpp b/wirish/HardwareTimer.cpp
new file mode 100644
index 0000000..3c8e9f4
--- /dev/null
+++ b/wirish/HardwareTimer.cpp
@@ -0,0 +1,149 @@
+/* *****************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2010 Bryan Newbold.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * ****************************************************************************/
+
+/**
+ * @brief wirish timer class to manage the four 16-bit timer peripherals
+ *
+ * This implementation is not very efficient (lots of duplicated functions)
+ */
+
+#include "wirish.h"
+#include "HardwareTimer.h"
+
+HardwareTimer::HardwareTimer(uint8 timerNum) {
+ ASSERT(timerNum == 1 ||
+ timerNum == 2 ||
+ timerNum == 3 ||
+ timerNum == 4);
+ this->timerNum = timerNum;
+ // Need to remember over flow for bounds checking
+ this->overflow = 0xFFFF;
+}
+
+void HardwareTimer::resume(void) {
+ timer_resume(this->timerNum);
+}
+void HardwareTimer::pause(void) {
+ timer_pause(this->timerNum);
+}
+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);
+}
+void HardwareTimer::setCount(uint16 val) {
+ if(val > this->overflow)
+ val = this->overflow;
+ timer_set_count(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?
+
+ // Not the best way to handle this edge case?
+ if(!microseconds) {
+ setPrescaleFactor(1);
+ setOverflow(1);
+ return this->overflow;
+ }
+ // With a prescale factor of 1, there are 72counts/ms
+ uint16 ps = ((microseconds*72)/65536) + 1;
+ setPrescaleFactor(ps);
+ // Find this overflow will always be less than 65536
+ setOverflow((microseconds*72)/ps);
+ return this->overflow;
+}
+void HardwareTimer::setChannel1Mode(uint8 mode) {
+ timer_set_mode(this->timerNum,1,mode);
+}
+void HardwareTimer::setChannel2Mode(uint8 mode) {
+ timer_set_mode(this->timerNum,2,mode);
+}
+void HardwareTimer::setChannel3Mode(uint8 mode) {
+ timer_set_mode(this->timerNum,3,mode);
+}
+void HardwareTimer::setChannel4Mode(uint8 mode) {
+ timer_set_mode(this->timerNum,4,mode);
+}
+void HardwareTimer::setCompare1(uint16 val) {
+ if(val > this->overflow)
+ val = this->overflow;
+ timer_set_compare_value(this->timerNum,1,val);
+}
+void HardwareTimer::setCompare2(uint16 val) {
+ if(val > this->overflow)
+ val = this->overflow;
+ timer_set_compare_value(this->timerNum,2,val);
+}
+void HardwareTimer::setCompare3(uint16 val) {
+ ASSERT(this->timerNum);
+ if(val > this->overflow)
+ val = this->overflow;
+ timer_set_compare_value(this->timerNum,3,val);
+}
+void HardwareTimer::setCompare4(uint16 val) {
+ if(val > this->overflow)
+ val = this->overflow;
+ timer_set_compare_value(this->timerNum,4,val);
+}
+void HardwareTimer::attachCompare1Interrupt(voidFuncPtr handler) {
+ timer_attach_interrupt(this->timerNum,1,handler);
+}
+void HardwareTimer::attachCompare2Interrupt(voidFuncPtr handler) {
+ timer_attach_interrupt(this->timerNum,2,handler);
+}
+void HardwareTimer::attachCompare3Interrupt(voidFuncPtr handler) {
+ timer_attach_interrupt(this->timerNum,3,handler);
+}
+void HardwareTimer::attachCompare4Interrupt(voidFuncPtr handler) {
+ timer_attach_interrupt(this->timerNum,4,handler);
+}
+void HardwareTimer::detachCompare1Interrupt(void) {
+ timer_detach_interrupt(this->timerNum,1);
+}
+void HardwareTimer::detachCompare2Interrupt(void) {
+ timer_detach_interrupt(this->timerNum,2);
+}
+void HardwareTimer::detachCompare3Interrupt(void) {
+ timer_detach_interrupt(this->timerNum,3);
+}
+void HardwareTimer::detachCompare4Interrupt(void) {
+ timer_detach_interrupt(this->timerNum,4);
+}
+
+HardwareTimer Timer1(1);
+HardwareTimer Timer2(2);
+HardwareTimer Timer3(3);
+HardwareTimer Timer4(4);
+