aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--wirish/HardwareTimer.cpp123
1 files changed, 26 insertions, 97 deletions
diff --git a/wirish/HardwareTimer.cpp b/wirish/HardwareTimer.cpp
index ca8ea63..c35804c 100644
--- a/wirish/HardwareTimer.cpp
+++ b/wirish/HardwareTimer.cpp
@@ -25,7 +25,10 @@
*****************************************************************************/
#include <wirish/HardwareTimer.h>
-#include <wirish/boards.h> // for CYCLES_PER_MICROSECOND
+
+#include <libmaple/rcc.h> // for rcc_clk_id
+#include <wirish/boards.h> // for CYCLES_PER_MICROSECOND
+#include <wirish/ext_interrupts.h> // for noInterrupts(), interrupts()
#include <wirish/wirish_math.h>
// TODO [0.1.0] Remove deprecated pieces
@@ -33,110 +36,36 @@
#define MAX_RELOAD ((1 << 16) - 1)
/*
- * Big ugly table of timers available on the MCU. Needed by the
- * HardwareTimer constructor. Sigh; maybe predefined instances weren't
- * such a bad idea. Oh well, at least the HardwareTimer interface is
- * officially unstable since v0.0.12; we can always get rid of this
- * later.
+ * Evil hack to infer this->dev from timerNum in the HardwareTimer
+ * constructor. See:
+ *
+ * http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2
+ * http://yosefk.com/c++fqa/function.html#fqa-33.2
*/
-#define MAX_NR_TIMERS 17 // No STM32 I've ever heard of has higher than TIMER17
-
-static timer_dev *devs[MAX_NR_TIMERS] = {
-#if STM32_HAVE_TIMER(1)
- TIMER1,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(2)
- TIMER2,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(3)
- TIMER3,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(4)
- TIMER4,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(5)
- TIMER5,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(6)
- TIMER6,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(7)
- TIMER7,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(8)
- TIMER8,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(9)
- TIMER9,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(10)
- TIMER10,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(11)
- TIMER11,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(12)
- TIMER12,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(13)
- TIMER13,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(14)
- TIMER14,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(15)
- TIMER15,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(16)
- TIMER16,
-#else
- NULL,
-#endif
-#if STM32_HAVE_TIMER(17)
- TIMER17,
-#else
- NULL,
-#endif
-};
+extern "C" {
+ static timer_dev **this_devp;
+ static rcc_clk_id this_id;
+ static void set_this_dev(timer_dev *dev) {
+ if (dev->clk_id == this_id) {
+ *this_devp = dev;
+ }
+ }
+}
/*
* HardwareTimer routines
*/
HardwareTimer::HardwareTimer(uint8 timerNum) {
- ASSERT(timerNum <= MAX_NR_TIMERS);
- this->dev = devs[timerNum - 1];
+ rcc_clk_id timerID = (rcc_clk_id)(RCC_TIMER1 + (timerNum - 1));
+ this->dev = NULL;
+ noInterrupts(); // Hack to ensure we're the only ones using
+ // set_this_dev() and friends. TODO: use a lock.
+ this_id = timerID;
+ this_devp = &this->dev;
+ timer_foreach(set_this_dev);
+ interrupts();
ASSERT(this->dev != NULL);
}