timer_gettick(): Rename to timer_ticks() and add backwards compatibility inline.
[bertos.git] / drv / timer.h
1 /*!
2  * \file
3  * <!--
4  * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
5  * Copyright 2000 Bernardo Innocenti <bernie@develer.com>
6  * This file is part of DevLib - See devlib/README for information.
7  * -->
8  *
9  * \version $Id$
10  *
11  * \author Bernardo Innocenti <bernie@develer.com>
12  *
13  * \brief Hardware independent timer driver (interface)
14  */
15
16 /*
17  * $Log$
18  * Revision 1.15  2004/08/10 06:59:09  bernie
19  * timer_gettick(): Rename to timer_ticks() and add backwards compatibility inline.
20  *
21  * Revision 1.12  2004/07/30 14:34:10  rasky
22  * Vari fix per documentazione e commenti
23  * Aggiunte PP_CATn e STATIC_ASSERT
24  *
25  * Revision 1.11  2004/07/29 22:40:12  bernie
26  * Spelling fix.
27  *
28  * Revision 1.10  2004/07/21 00:13:57  bernie
29  * Put timer driver on diet.
30  *
31  * Revision 1.9  2004/07/20 23:45:01  bernie
32  * Finally remove redundant protos.
33  *
34  * Revision 1.8  2004/07/18 21:57:32  bernie
35  * timer_gettick(): Rename to timer_tick() and document better.
36  *
37  * Revision 1.7  2004/06/27 15:26:17  aleph
38  * Declaration fix for build with GCC 3.4
39  *
40  * Revision 1.6  2004/06/07 18:10:06  aleph
41  * Remove free pool of timers; use user-provided Timer structure instead
42  *
43  * Revision 1.5  2004/06/07 15:57:12  aleph
44  * Add function prototypes
45  *
46  * Revision 1.4  2004/06/06 18:25:44  bernie
47  * Rename event macros to look like regular functions.
48  *
49  * Revision 1.3  2004/06/06 16:57:18  bernie
50  * Mark some functions INLINE instead of 'extern inline'.
51  *
52  * Revision 1.2  2004/06/03 11:27:09  bernie
53  * Add dual-license information.
54  *
55  * Revision 1.1  2004/05/23 18:23:30  bernie
56  * Import drv/timer module.
57  *
58  */
59 #ifndef DRV_TIMER_H
60 #define DRV_TIMER_H
61
62 #include "cpu.h"
63 #include "compiler.h"
64 #include <config.h>
65 #include <mware/list.h>
66
67 /*! Number of timer ticks per second. */
68 #define TICKS_PER_SEC  ((time_t)1000)
69
70 /* Function protos */
71 extern void timer_init(void);
72 extern void timer_delay(time_t time);
73
74 #ifndef CONFIG_TIMER_DISABLE_UDELAY
75 extern void timer_udelay(utime_t utime);
76 #endif
77
78
79 #ifndef CONFIG_TIMER_DISABLE_EVENTS
80
81 #ifdef CONFIG_KERNEL
82         #include <kern/event.h>
83 #else
84         #include <mware/event.h>
85 #endif
86
87 /*!
88  * The timer driver supports multiple synchronous timers
89  * that can trigger an event when they expire.
90  *
91  * \sa timer_add()
92  * \sa timer_abort()
93  */
94 typedef struct Timer
95 {
96         Node   link;      /*!< Link into timers queue */
97         time_t delay;     /*!< Timer delay in ms */
98         time_t tick;      /*!< Timer will expire at this tick */
99         Event  expire;    /*!< Event to execute when the timer expires */
100 } Timer;
101
102 extern void timer_add(Timer *timer);
103 extern Timer *timer_abort(Timer *timer);
104
105 #if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
106
107 /*! Set the timer so that it sends a signal when it expires */
108 INLINE void timer_set_event_signal(Timer* timer, struct Process* proc, sigset_t sigs)
109 {
110         event_initSignal(&timer->expire, proc, sigs);
111 }
112
113 #endif /* CONFIG_KERN_SIGNALS */
114
115 /*! Set the timer so that it calls an user hook when it expires */
116 INLINE void timer_set_event_softint(Timer* timer, Hook func, void* user_data)
117 {
118         event_initSoftInt(&timer->expire, func, user_data);
119 }
120
121 /*! Set the timer delay (the time before the event will be triggered) */
122 INLINE void timer_set_delay(Timer* timer, time_t delay)
123 {
124         timer->delay = delay;
125 }
126
127 #endif /* CONFIG_TIMER_DISABLE_EVENTS */
128
129 extern volatile time_t _clock;
130
131 /*!
132  * \brief Return the system tick counter (expressed in ms)
133  *
134  * The result is guaranteed to increment monotonically,
135  * but client code must be tolerant with respect to overflows.
136  *
137  * The following code is safe:
138  *
139  * \code
140  *   time_t tea_start_time = get_tick();
141  *
142  *   boil_water();
143  *
144  *   if (get_tick() - tea_start_time > TEAPOT_DELAY)
145  *       printf("Your tea, Sir.\n");
146  * \endcode
147  *
148  * When the tick counter increments every millisecond and time_t
149  * is 32bit wide, the tick count will overflow every 49.7 days.
150  *
151  * \note This function must disable interrupts on 8/16bit CPUs because the
152  * clock variable is larger than the processor word size and can't
153  * be copied atomically.
154  */
155 INLINE time_t timer_ticks(void)
156 {
157         time_t result;
158         cpuflags_t flags;
159
160         DISABLE_IRQSAVE(flags);
161         result = _clock;
162         ENABLE_IRQRESTORE(flags);
163
164         return result;
165 }
166
167 DEPRECATED INLINE time_t timer_gettick(void)
168 {
169         return timer_ticks();
170 }
171
172
173 /*!
174  * Faster version of timer_ticks(), to be called only when the timer
175  * interrupt is disabled (DISABLE_INTS) or overridden by a
176  * higher-priority or non-nesting interrupt.
177  *
178  * \sa timer_ticks
179  */
180 INLINE time_t timer_ticks_unlocked(void)
181 {
182         return _clock;
183 }
184
185 DEPRECATED INLINE time_t timer_gettick_irq(void)
186 {
187         return timer_ticks_unlocked();
188 }
189
190
191 /*!
192  * Return the minutes passed since timer start.
193  *
194  * The minutes uptime is computed directly from system tick counter:
195  * in case of a 4 bytes time_t after 71582 minutes the value will
196  * wrap around.
197  */
198 INLINE time_t timer_minutes(void)
199 {
200         return timer_ticks() / (TICKS_PER_SEC * 60);
201 }
202
203 #endif /* DRV_TIMER_H */
204