/** * \file * * * * \author Bernie Innocenti * * \brief Low-level timer module for Qt emulator (implementation). */ #include /* hptime.t */ // Qt headers #include #include #if CONFIG_KERN_IRQ #include #endif // The user interrupt server routine void timer_isr(void); /** * Singleton class for Qt-based hardware timer emulation. */ class EmulTimer : public QObject { private: Q_OBJECT; /// System timer (counts ms since application startup) QTime system_time; /// The 1ms "hardware" tick counter. QTimer timer; /** * We deliberately don't use RAII because the real hardware * we're simulating needs to be initialized manually. */ bool initialized; /// Private ctor (singleton) EmulTimer() : initialized(false) { } public: /// Return singleton instance static EmulTimer &instance() { static EmulTimer et; return et; } /// Start timer emulator. void init() { // Timer initialized twice? ASSERT(!initialized); // Record initial time system_time.start(); #if CONFIG_KERN_IRQ irq_register(SIGALRM, timer_isr); #endif // Activate timer interrupt connect(&timer, SIGNAL(timeout()), SLOT(timerInterrupt())); timer.start(1000 / TIMER_TICKS_PER_SEC); initialized = true; } void cleanup() { // Timer cleaned twice? ASSERT(initialized); timer.stop(); timer.disconnect(); initialized = false; } /// Return current time in high-precision format. hptime_t hpread() { ASSERT(initialized); return system_time.elapsed(); } public slots: void timerInterrupt(void) { // Just call user interrupt server, timer restarts automatically. #if CONFIG_KERN_IRQ irq_entry(SIGALRM); #else timer_isr(); #endif } }; #include "timer_qt_moc.cpp" /// HW dependent timer initialization. static void timer_hw_init(void) { EmulTimer::instance().init(); } static void timer_hw_cleanup(void) { EmulTimer::instance().cleanup(); } INLINE hptime_t timer_hw_hpread(void) { return EmulTimer::instance().hpread(); } /** Not needed, timer IRQ handler called only for timer source */ #define timer_hw_triggered() (true)