timer.h
Go to the documentation of this file.00001
00056 #ifndef DRV_TIMER_H
00057 #define DRV_TIMER_H
00058
00059 #include <cfg/os.h>
00060 #include <cfg/macros.h>
00061
00062 #include <cpu/attr.h>
00063 #include <cpu/irq.h>
00064
00065
00066
00067
00068
00069
00070 #if OS_HOSTED
00071
00072 #include <emul/timer_posix.h>
00073 #else
00074 #include CPU_HEADER(timer)
00075 #endif
00076
00077 STATIC_ASSERT(sizeof(hptime_t) == SIZEOF_HPTIME_T);
00078
00079 #include "cfg/cfg_timer.h"
00080 #include <cfg/debug.h>
00081 #include <cfg/compiler.h>
00082
00083 #include <struct/list.h>
00084
00085
00086
00087
00088 #if !defined(CONFIG_TIMER_EVENTS) || ((CONFIG_TIMER_EVENTS != 0) && CONFIG_TIMER_EVENTS != 1)
00089 #error CONFIG_TIMER_EVENTS must be set to either 0 or 1 in cfg_timer.h
00090 #endif
00091 #if !defined(CONFIG_TIMER_UDELAY) || ((CONFIG_TIMER_UDELAY != 0) && CONFIG_TIMER_EVENTS != 1)
00092 #error CONFIG_TIMER_UDELAY must be set to either 0 or 1 in cfg_timer.h
00093 #endif
00094 #if defined(CONFIG_TIMER_DISABLE_UDELAY)
00095 #error Obosolete config option CONFIG_TIMER_DISABLE_UDELAY. Use CONFIG_TIMER_UDELAY
00096 #endif
00097 #if defined(CONFIG_TIMER_DISABLE_EVENTS)
00098 #error Obosolete config option CONFIG_TIMER_DISABLE_EVENTS. Use CONFIG_TIMER_EVENTS
00099 #endif
00100
00101 extern volatile ticks_t _clock;
00102
00103 #define TIMER_AFTER(x, y) ((long)(y) - (long)(x) < 0)
00104 #define TIMER_BEFORE(x, y) TIMER_AFTER(y, x)
00105
00134 INLINE ticks_t timer_clock(void)
00135 {
00136 ticks_t result;
00137
00138 ATOMIC(result = _clock);
00139
00140 return result;
00141 }
00142
00150 INLINE ticks_t timer_clock_unlocked(void)
00151 {
00152 return _clock;
00153 }
00154
00155
00157 INLINE ticks_t ms_to_ticks(mtime_t ms)
00158 {
00159 #if TIMER_TICKS_PER_SEC < 1000
00160
00161 return (ms * TIMER_TICKS_PER_SEC) / 1000;
00162 #else
00163
00164 return ms * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000);
00165 #endif
00166 }
00167
00169 INLINE ticks_t us_to_ticks(utime_t us)
00170 {
00171 #if TIMER_TICKS_PER_SEC < 1000
00172
00173 return ((us / 1000) * TIMER_TICKS_PER_SEC) / 1000;
00174 #else
00175
00176 return (us * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000)) / 1000;
00177 #endif
00178 }
00179
00181 INLINE mtime_t ticks_to_ms(ticks_t ticks)
00182 {
00183 #if TIMER_TICKS_PER_SEC < 1000
00184
00185 return (ticks * 1000) / TIMER_TICKS_PER_SEC;
00186 #else
00187
00188 return ticks / (TIMER_TICKS_PER_SEC / 1000);
00189 #endif
00190 }
00191
00193 INLINE utime_t ticks_to_us(ticks_t ticks)
00194 {
00195 #if TIMER_TICKS_PER_SEC < 1000
00196
00197 return ((ticks * 1000) / TIMER_TICKS_PER_SEC) * 1000;
00198 #else
00199
00200 return (ticks / (TIMER_TICKS_PER_SEC / 1000)) * 1000;
00201 #endif
00202 }
00203
00205 INLINE hptime_t us_to_hptime(utime_t us)
00206 {
00207 #if TIMER_HW_HPTICKS_PER_SEC > 10000000UL
00208 return us * DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000000UL);
00209 #else
00210 return (us * ((TIMER_HW_HPTICKS_PER_SEC + 500) / 1000UL) + 500) / 1000UL;
00211 #endif
00212 }
00213
00215 INLINE utime_t hptime_to_us(hptime_t hpticks)
00216 {
00217 #if TIMER_HW_HPTICKS_PER_SEC < 100000UL
00218 return hpticks * DIV_ROUND(1000000UL, TIMER_HW_HPTICKS_PER_SEC);
00219 #else
00220 return (hpticks * 1000UL) / DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000UL);
00221 #endif
00222 }
00223
00224 void timer_delayTicks(ticks_t delay);
00231 INLINE void timer_delay(mtime_t delay)
00232 {
00233 timer_delayTicks(ms_to_ticks(delay));
00234 }
00235
00236 void timer_init(void);
00237 void timer_cleanup(void);
00238
00239 int timer_testSetup(void);
00240 int timer_testRun(void);
00241 int timer_testTearDown(void);
00242
00243 #if CONFIG_TIMER_UDELAY
00244 void timer_busyWait(hptime_t delay);
00245 void timer_delayHp(hptime_t delay);
00246 INLINE void timer_udelay(utime_t delay)
00247 {
00248 timer_delayHp(us_to_hptime(delay));
00249 }
00250 #endif
00251
00252 #if CONFIG_TIMER_EVENTS
00253
00254 #include <mware/event.h>
00255
00263 typedef struct Timer
00264 {
00265 Node link;
00266 ticks_t _delay;
00267 ticks_t tick;
00268 Event expire;
00269 DB(uint16_t magic;)
00270 } Timer;
00271
00272
00273 #define TIMER_MAGIC_ACTIVE 0xABBA
00274 #define TIMER_MAGIC_INACTIVE 0xBAAB
00275
00276 void timer_add(Timer *timer);
00277 Timer *timer_abort(Timer *timer);
00278
00289 INLINE void timer_setSoftint(Timer *timer, Hook func, iptr_t user_data)
00290 {
00291 event_initSoftint(&timer->expire, func, user_data);
00292 }
00293
00300 INLINE void timer_setDelay(Timer *timer, ticks_t delay)
00301 {
00302 timer->_delay = delay;
00303 }
00304
00305
00306 void synctimer_add(Timer *timer, List* q);
00307
00309 #define synctimer_abort(t) timer_abort(t)
00310
00311 void synctimer_poll(List* q);
00312
00313
00314 #endif
00315
00316 #if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
00317
00319 INLINE void timer_setEvent(Timer *timer)
00320 {
00321 event_initGeneric(&timer->expire);
00322 }
00323
00325 INLINE void timer_waitEvent(Timer *timer)
00326 {
00327 event_wait(&timer->expire);
00328 }
00329
00331 INLINE void timer_setSignal(Timer *timer, struct Process *proc, sigmask_t sigs)
00332 {
00333 event_initSignal(&timer->expire, proc, sigs);
00334 }
00335
00336 #define timer_set_event_signal timer_setSignal
00337
00338 #endif
00339
00341
00342 #endif