timer.h
Go to the documentation of this file.00001
00039 #ifndef DRV_TIMER_H
00040 #define DRV_TIMER_H
00041
00042 #include <cfg/os.h>
00043 #include <cfg/macros.h>
00044
00045 #include <cpu/attr.h>
00046 #include <cpu/irq.h>
00047
00048
00049
00050
00051
00052
00053 #if OS_HOSTED
00054
00055 #include <emul/timer_posix.h>
00056 #else
00057 #include CPU_HEADER(timer)
00058 #endif
00059
00060 #include "cfg/cfg_timer.h"
00061 #include <cfg/debug.h>
00062 #include <cfg/compiler.h>
00063
00064 #include <struct/list.h>
00065
00066
00067
00068
00069 #if !defined(CONFIG_TIMER_EVENTS) || ((CONFIG_TIMER_EVENTS != 0) && CONFIG_TIMER_EVENTS != 1)
00070 #error CONFIG_TIMER_EVENTS must be set to either 0 or 1 in cfg_timer.h
00071 #endif
00072 #if !defined(CONFIG_TIMER_UDELAY) || ((CONFIG_TIMER_UDELAY != 0) && CONFIG_TIMER_EVENTS != 1)
00073 #error CONFIG_TIMER_UDELAY must be set to either 0 or 1 in cfg_timer.h
00074 #endif
00075 #if defined(CONFIG_TIMER_DISABLE_UDELAY)
00076 #error Obosolete config option CONFIG_TIMER_DISABLE_UDELAY. Use CONFIG_TIMER_UDELAY
00077 #endif
00078 #if defined(CONFIG_TIMER_DISABLE_EVENTS)
00079 #error Obosolete config option CONFIG_TIMER_DISABLE_EVENTS. Use CONFIG_TIMER_EVENTS
00080 #endif
00081
00082 extern volatile ticks_t _clock;
00083
00111 INLINE ticks_t timer_clock(void)
00112 {
00113 ticks_t result;
00114
00115 ATOMIC(result = _clock);
00116
00117 return result;
00118 }
00119
00127 INLINE ticks_t timer_clock_unlocked(void)
00128 {
00129 return _clock;
00130 }
00131
00133 INLINE ticks_t ms_to_ticks(mtime_t ms)
00134 {
00135 #if TIMER_TICKS_PER_SEC < 1000
00136
00137 return (ms * TIMER_TICKS_PER_SEC) / 1000;
00138 #else
00139
00140 return ms * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000);
00141 #endif
00142 }
00143
00145 INLINE ticks_t us_to_ticks(utime_t us)
00146 {
00147 #if TIMER_TICKS_PER_SEC < 1000
00148
00149 return ((us / 1000) * TIMER_TICKS_PER_SEC) / 1000;
00150 #else
00151
00152 return (us * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000)) / 1000;
00153 #endif
00154 }
00155
00157 INLINE mtime_t ticks_to_ms(ticks_t ticks)
00158 {
00159 #if TIMER_TICKS_PER_SEC < 1000
00160
00161 return (ticks * 1000) / TIMER_TICKS_PER_SEC;
00162 #else
00163
00164 return ticks / (TIMER_TICKS_PER_SEC / 1000);
00165 #endif
00166 }
00167
00169 INLINE utime_t ticks_to_us(ticks_t ticks)
00170 {
00171 #if TIMER_TICKS_PER_SEC < 1000
00172
00173 return ((ticks * 1000) / TIMER_TICKS_PER_SEC) * 1000;
00174 #else
00175
00176 return (ticks / (TIMER_TICKS_PER_SEC / 1000)) * 1000;
00177 #endif
00178 }
00179
00181 INLINE hptime_t us_to_hptime(utime_t us)
00182 {
00183 #if TIMER_HW_HPTICKS_PER_SEC > 10000000UL
00184 return us * DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000000UL);
00185 #else
00186 return (us * ((TIMER_HW_HPTICKS_PER_SEC + 500) / 1000UL) + 500) / 1000UL;
00187 #endif
00188 }
00189
00191 INLINE utime_t hptime_to_us(hptime_t hpticks)
00192 {
00193 #if TIMER_HW_HPTICKS_PER_SEC < 100000UL
00194 return hpticks * DIV_ROUND(1000000UL, TIMER_HW_HPTICKS_PER_SEC);
00195 #else
00196 return (hpticks * 1000UL) / DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000UL);
00197 #endif
00198 }
00199
00200 void timer_delayTicks(ticks_t delay);
00201 INLINE void timer_delay(mtime_t delay)
00202 {
00203 timer_delayTicks(ms_to_ticks(delay));
00204 }
00205
00206 void timer_init(void);
00207 void timer_cleanup(void);
00208
00209 int timer_testSetup(void);
00210 int timer_testRun(void);
00211 int timer_testTearDown(void);
00212
00213 #if CONFIG_TIMER_UDELAY
00214 void timer_busyWait(hptime_t delay);
00215 void timer_delayHp(hptime_t delay);
00216 INLINE void timer_udelay(utime_t delay)
00217 {
00218 timer_delayHp(us_to_hptime(delay));
00219 }
00220 #endif
00221
00222 #if CONFIG_TIMER_EVENTS
00223
00224 #include <mware/event.h>
00225
00233 typedef struct Timer
00234 {
00235 Node link;
00236 ticks_t _delay;
00237 ticks_t tick;
00238 Event expire;
00239 DB(uint16_t magic;)
00240 } Timer;
00241
00243 #define TIMER_MAGIC_ACTIVE 0xABBA
00244 #define TIMER_MAGIC_INACTIVE 0xBAAB
00245
00246 void timer_add(Timer *timer);
00247 Timer *timer_abort(Timer *timer);
00248
00250 INLINE void timer_setSoftint(Timer *timer, Hook func, iptr_t user_data)
00251 {
00252 event_initSoftint(&timer->expire, func, user_data);
00253 }
00254
00256 INLINE void timer_setDelay(Timer *timer, ticks_t delay)
00257 {
00258 timer->_delay = delay;
00259 }
00260
00261 #endif
00262
00263 #if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
00264
00266 INLINE void timer_setSignal(Timer *timer, struct Process *proc, sigmask_t sigs)
00267 {
00268 event_initSignal(&timer->expire, proc, sigs);
00269 }
00270
00271 #define timer_set_event_signal timer_setSignal
00272
00273 #endif
00274
00275 #endif