timer.h
Go to the documentation of this file.00001
00052 #ifndef DRV_TIMER_H
00053 #define DRV_TIMER_H
00054
00055 #include <cfg/os.h>
00056 #include <cfg/macros.h>
00057
00058 #include <cpu/attr.h>
00059 #include <cpu/irq.h>
00060
00061
00062
00063
00064
00065
00066 #if OS_HOSTED
00067
00068 #include <emul/timer_posix.h>
00069 #else
00070 #include CPU_HEADER(timer)
00071 #endif
00072
00073 STATIC_ASSERT(sizeof(hptime_t) == SIZEOF_HPTIME_T);
00074
00075 #include "cfg/cfg_timer.h"
00076 #include <cfg/debug.h>
00077 #include <cfg/compiler.h>
00078
00079 #include <struct/list.h>
00080
00081
00082
00083
00084 #if !defined(CONFIG_TIMER_EVENTS) || ((CONFIG_TIMER_EVENTS != 0) && CONFIG_TIMER_EVENTS != 1)
00085 #error CONFIG_TIMER_EVENTS must be set to either 0 or 1 in cfg_timer.h
00086 #endif
00087 #if !defined(CONFIG_TIMER_UDELAY) || ((CONFIG_TIMER_UDELAY != 0) && CONFIG_TIMER_EVENTS != 1)
00088 #error CONFIG_TIMER_UDELAY must be set to either 0 or 1 in cfg_timer.h
00089 #endif
00090 #if defined(CONFIG_TIMER_DISABLE_UDELAY)
00091 #error Obosolete config option CONFIG_TIMER_DISABLE_UDELAY. Use CONFIG_TIMER_UDELAY
00092 #endif
00093 #if defined(CONFIG_TIMER_DISABLE_EVENTS)
00094 #error Obosolete config option CONFIG_TIMER_DISABLE_EVENTS. Use CONFIG_TIMER_EVENTS
00095 #endif
00096
00097 extern volatile ticks_t _clock;
00098
00127 INLINE ticks_t timer_clock(void)
00128 {
00129 ticks_t result;
00130
00131 ATOMIC(result = _clock);
00132
00133 return result;
00134 }
00135
00143 INLINE ticks_t timer_clock_unlocked(void)
00144 {
00145 return _clock;
00146 }
00147
00148
00150 INLINE ticks_t ms_to_ticks(mtime_t ms)
00151 {
00152 #if TIMER_TICKS_PER_SEC < 1000
00153
00154 return (ms * TIMER_TICKS_PER_SEC) / 1000;
00155 #else
00156
00157 return ms * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000);
00158 #endif
00159 }
00160
00162 INLINE ticks_t us_to_ticks(utime_t us)
00163 {
00164 #if TIMER_TICKS_PER_SEC < 1000
00165
00166 return ((us / 1000) * TIMER_TICKS_PER_SEC) / 1000;
00167 #else
00168
00169 return (us * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000)) / 1000;
00170 #endif
00171 }
00172
00174 INLINE mtime_t ticks_to_ms(ticks_t ticks)
00175 {
00176 #if TIMER_TICKS_PER_SEC < 1000
00177
00178 return (ticks * 1000) / TIMER_TICKS_PER_SEC;
00179 #else
00180
00181 return ticks / (TIMER_TICKS_PER_SEC / 1000);
00182 #endif
00183 }
00184
00186 INLINE utime_t ticks_to_us(ticks_t ticks)
00187 {
00188 #if TIMER_TICKS_PER_SEC < 1000
00189
00190 return ((ticks * 1000) / TIMER_TICKS_PER_SEC) * 1000;
00191 #else
00192
00193 return (ticks / (TIMER_TICKS_PER_SEC / 1000)) * 1000;
00194 #endif
00195 }
00196
00198 INLINE hptime_t us_to_hptime(utime_t us)
00199 {
00200 #if TIMER_HW_HPTICKS_PER_SEC > 10000000UL
00201 return us * DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000000UL);
00202 #else
00203 return (us * ((TIMER_HW_HPTICKS_PER_SEC + 500) / 1000UL) + 500) / 1000UL;
00204 #endif
00205 }
00206
00208 INLINE utime_t hptime_to_us(hptime_t hpticks)
00209 {
00210 #if TIMER_HW_HPTICKS_PER_SEC < 100000UL
00211 return hpticks * DIV_ROUND(1000000UL, TIMER_HW_HPTICKS_PER_SEC);
00212 #else
00213 return (hpticks * 1000UL) / DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000UL);
00214 #endif
00215 }
00216
00217 void timer_delayTicks(ticks_t delay);
00224 INLINE void timer_delay(mtime_t delay)
00225 {
00226 timer_delayTicks(ms_to_ticks(delay));
00227 }
00228
00229 void timer_init(void);
00230 void timer_cleanup(void);
00231
00232 int timer_testSetup(void);
00233 int timer_testRun(void);
00234 int timer_testTearDown(void);
00235
00236 #if CONFIG_TIMER_UDELAY
00237 void timer_busyWait(hptime_t delay);
00238 void timer_delayHp(hptime_t delay);
00239 INLINE void timer_udelay(utime_t delay)
00240 {
00241 timer_delayHp(us_to_hptime(delay));
00242 }
00243 #endif
00244
00245 #if CONFIG_TIMER_EVENTS
00246
00247 #include <mware/event.h>
00248
00256 typedef struct Timer
00257 {
00258 Node link;
00259 ticks_t _delay;
00260 ticks_t tick;
00261 Event expire;
00262 DB(uint16_t magic;)
00263 } Timer;
00264
00265
00266 #define TIMER_MAGIC_ACTIVE 0xABBA
00267 #define TIMER_MAGIC_INACTIVE 0xBAAB
00268
00269 void timer_add(Timer *timer);
00270 Timer *timer_abort(Timer *timer);
00271
00282 INLINE void timer_setSoftint(Timer *timer, Hook func, iptr_t user_data)
00283 {
00284 event_initSoftint(&timer->expire, func, user_data);
00285 }
00286
00288 INLINE void timer_setDelay(Timer *timer, ticks_t delay)
00289 {
00290 timer->_delay = delay;
00291 }
00292
00293
00294 void synctimer_add(Timer *timer, List* q);
00295
00297 #define synctimer_abort(t) timer_abort(t)
00298
00299 void synctimer_poll(List* q);
00300
00301
00302 #endif
00303
00304 #if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
00305
00307 INLINE void timer_setSignal(Timer *timer, struct Process *proc, sigmask_t sigs)
00308 {
00309 event_initSignal(&timer->expire, proc, sigs);
00310 }
00311
00312 #define timer_set_event_signal timer_setSignal
00313
00314 #endif
00315
00316 #endif