diff options
-rw-r--r-- | wirish/HardwareTimer.cpp | 123 |
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); } |