New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks...
[bertos.git] / drv / timer_qt.c
1 /*!
2  * \file
3  * <!--
4  * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
5  * This file is part of DevLib - See README.devlib for information.
6  * -->
7  *
8  * \version $Id$
9  *
10  * \author Bernardo Innocenti <bernie@develer.com>
11  *
12  * \brief Low-level timer module for Qt emulator (implementation).
13  */
14
15 /*#*
16  *#* $Log$
17  *#* Revision 1.3  2006/02/21 21:28:02  bernie
18  *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
19  *#*
20  *#* Revision 1.2  2006/02/20 02:01:35  bernie
21  *#* Port to Qt 4.1.
22  *#*
23  *#* Revision 1.1  2005/11/27 03:06:36  bernie
24  *#* Qt timer emulation.
25  *#*
26  *#*/
27
28 #include <cfg/compiler.h> /* hptime.t */
29
30 // Qt headers
31 #if _QT < 4
32         #include <qdatetime.h>
33         #include <qtimer.h>
34 #else
35         #include <QtCore/QDateTime>
36         #include <QtCore/QTimer>
37 #endif
38
39
40 // The user interrupt server routine
41 void timer_isr(void);
42
43
44 /**
45  * Singleton class for Qt-based hardware timer emulation.
46  */
47 class EmulTimer : public QObject
48 {
49 private:
50         Q_OBJECT;
51
52         /// System timer (counts ms since application startup)
53         QTime system_time;
54
55         /// The 1ms "hardware" tick counter.
56         QTimer timer;
57
58         /**
59          * We deliberately don't use RAII because the real hardware
60          * we're simulating needs to be initialized manually.
61          */
62         bool initialized;
63
64         /// Private ctor (singleton)
65         EmulTimer() : initialized(false) { }
66
67 public:
68         /// Return singleton instance
69         static EmulTimer &instance()
70         {
71                 static EmulTimer et;
72                 return et;
73         }
74
75         /// Start timer emulator.
76         void init()
77         {
78                 // Timer initialized twice?
79                 ASSERT(!initialized);
80
81                 // Record initial time
82                 system_time.start();
83
84                 // Activate timer interrupt
85                 timer.connect(&timer, SIGNAL(timeout()), this, SLOT(timerInterrupt()));
86                 timer.start(1000 / TIMER_TICKS_PER_SEC);
87
88                 initialized = true;
89         }
90
91         /// Return current time in high-precision format.
92         hptime_t hpread()
93         {
94                 ASSERT(initialized);
95                 return system_time.elapsed();
96         }
97
98 public slots:
99         void timerInterrupt(void)
100         {
101                 // Just call user interrupt server, timer restarts automatically.
102                 timer_isr();
103         }
104
105 };
106
107 #include "timer_qt_moc.cpp"
108
109
110 /// HW dependent timer initialization.
111 extern "C" static void timer_hw_init(void)
112 {
113         // Kick EmulTimer initialization
114         EmulTimer::instance().init();
115 }
116
117 extern "C" INLINE hptime_t timer_hw_hpread(void)
118 {
119         return EmulTimer::instance().hpread();
120 }
121