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