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
00149 INLINE ticks_t ms_to_ticks(mtime_t ms)
00150 {
00151 #if TIMER_TICKS_PER_SEC < 1000
00152
00153 return (ms * TIMER_TICKS_PER_SEC) / 1000;
00154 #else
00155
00156 return ms * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000);
00157 #endif
00158 }
00159
00161 INLINE ticks_t us_to_ticks(utime_t us)
00162 {
00163 #if TIMER_TICKS_PER_SEC < 1000
00164
00165 return ((us / 1000) * TIMER_TICKS_PER_SEC) / 1000;
00166 #else
00167
00168 return (us * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000)) / 1000;
00169 #endif
00170 }
00171
00173 INLINE mtime_t ticks_to_ms(ticks_t ticks)
00174 {
00175 #if TIMER_TICKS_PER_SEC < 1000
00176
00177 return (ticks * 1000) / TIMER_TICKS_PER_SEC;
00178 #else
00179
00180 return ticks / (TIMER_TICKS_PER_SEC / 1000);
00181 #endif
00182 }
00183
00185 INLINE utime_t ticks_to_us(ticks_t ticks)
00186 {
00187 #if TIMER_TICKS_PER_SEC < 1000
00188
00189 return ((ticks * 1000) / TIMER_TICKS_PER_SEC) * 1000;
00190 #else
00191
00192 return (ticks / (TIMER_TICKS_PER_SEC / 1000)) * 1000;
00193 #endif
00194 }
00195
00197 INLINE hptime_t us_to_hptime(utime_t us)
00198 {
00199 #if TIMER_HW_HPTICKS_PER_SEC > 10000000UL
00200 return us * DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000000UL);
00201 #else
00202 return (us * ((TIMER_HW_HPTICKS_PER_SEC + 500) / 1000UL) + 500) / 1000UL;
00203 #endif
00204 }
00205
00207 INLINE utime_t hptime_to_us(hptime_t hpticks)
00208 {
00209 #if TIMER_HW_HPTICKS_PER_SEC < 100000UL
00210 return hpticks * DIV_ROUND(1000000UL, TIMER_HW_HPTICKS_PER_SEC);
00211 #else
00212 return (hpticks * 1000UL) / DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000UL);
00213 #endif
00214 }
00215
00216 void timer_delayTicks(ticks_t delay);
00223 INLINE void timer_delay(mtime_t delay)
00224 {
00225 timer_delayTicks(ms_to_ticks(delay));
00226 }
00227
00228 void timer_init(void);
00229 void timer_cleanup(void);
00230
00231 int timer_testSetup(void);
00232 int timer_testRun(void);
00233 int timer_testTearDown(void);
00234
00235 #if CONFIG_TIMER_UDELAY
00236 void timer_busyWait(hptime_t delay);
00237 void timer_delayHp(hptime_t delay);
00238 INLINE void timer_udelay(utime_t delay)
00239 {
00240 timer_delayHp(us_to_hptime(delay));
00241 }
00242 #endif
00243
00244 #if CONFIG_TIMER_EVENTS
00245
00246 #include <mware/event.h>
00247
00255 typedef struct Timer
00256 {
00257 Node link;
00258 ticks_t _delay;
00259 ticks_t tick;
00260 Event expire;
00261 DB(uint16_t magic;)
00262 } Timer;
00263
00264
00265 #define TIMER_MAGIC_ACTIVE 0xABBA
00266 #define TIMER_MAGIC_INACTIVE 0xBAAB
00267
00268 void timer_add(Timer *timer);
00269 Timer *timer_abort(Timer *timer);
00270
00281 INLINE void timer_setSoftint(Timer *timer, Hook func, iptr_t user_data)
00282 {
00283 event_initSoftint(&timer->expire, func, user_data);
00284 }
00285
00287 INLINE void timer_setDelay(Timer *timer, ticks_t delay)
00288 {
00289 timer->_delay = delay;
00290 }
00291
00292 #endif
00293
00294 #if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
00295
00297 INLINE void timer_setSignal(Timer *timer, struct Process *proc, sigmask_t sigs)
00298 {
00299 event_initSignal(&timer->expire, proc, sigs);
00300 }
00301
00302 #define timer_set_event_signal timer_setSignal
00303
00304 #endif
00305
00306 #endif