| /* Copyright 2012 The Chromium OS Authors. All rights reserved. |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| /* Timer module for Chrome EC operating system */ |
| |
| #ifndef __CROS_EC_TIMER_H |
| #define __CROS_EC_TIMER_H |
| |
| #include "common.h" |
| #include "task_id.h" |
| |
| /* Time units in microseconds */ |
| #define MSEC 1000 |
| #define SECOND 1000000 |
| #define SEC_UL 1000000ul |
| #define MINUTE 60000000 |
| #define HOUR 3600000000ull /* Too big to fit in a signed int */ |
| |
| /* Microsecond timestamp. */ |
| typedef union { |
| uint64_t val; |
| struct { |
| uint32_t lo; |
| uint32_t hi; |
| } le /* little endian words */; |
| } timestamp_t; |
| |
| /* Data type for POSIX style clock() implementation */ |
| typedef long clock_t; |
| |
| /** |
| * Initialize the timer module. |
| */ |
| void timer_init(void); |
| |
| /** |
| * Launch a one-shot timer for a task. |
| * |
| * Note that each task can have only a single active timer. |
| * |
| * @param tstamp Expiration timestamp for timer |
| * @param tskid Task to set timer for |
| * |
| * @return EC_SUCCESS, or non-zero if error. |
| */ |
| int timer_arm(timestamp_t tstamp, task_id_t tskid); |
| |
| /** |
| * Cancel a running timer for the specified task id. |
| */ |
| void timer_cancel(task_id_t tskid); |
| |
| /** |
| * Check if a timestamp has passed / expired |
| * |
| * @param deadline deadline timer value to check |
| * @param now pointer to value of time_now() if known, else NULL |
| * @return 0 if deadline has not yet passed, 1 if it has passed |
| */ |
| int timestamp_expired(timestamp_t deadline, const timestamp_t *now); |
| |
| /** |
| * Busy-wait. |
| * |
| * This may be called with interrupts disabled, at any time after timer_init() |
| * has been called. |
| * |
| * Note that calling this with us>1000 may impact system performance; use |
| * usleep() for longer delays. |
| * |
| * @param us Number of microseconds to delay. |
| */ |
| void udelay(unsigned us); |
| |
| /** |
| * Sleep. |
| * |
| * The current task will be de-scheduled for at least the specified delay (and |
| * perhaps longer, if a higher-priority task is running when the delay |
| * expires). |
| * |
| * This may only be called from a task function, with interrupts enabled. |
| * |
| * @param us Number of microseconds to sleep. |
| */ |
| void usleep(unsigned us); |
| |
| /** |
| * Sleep for milliseconds. |
| * |
| * Otherwise the same as usleep(). |
| * |
| * @param ms Number of milliseconds to sleep. |
| */ |
| static inline void msleep(unsigned ms) |
| { |
| usleep(ms * MSEC); |
| } |
| |
| /** |
| * Sleep for seconds |
| * |
| * Otherwise the same as usleep(). |
| * |
| * @param sec Number of seconds to sleep. |
| */ |
| static inline void sleep(unsigned sec) |
| { |
| usleep(sec * SECOND); |
| } |
| |
| /** |
| * Get the current timestamp from the system timer. |
| */ |
| timestamp_t get_time(void); |
| |
| /** |
| * Force the current value of the system timer. |
| * |
| * This function is for the power management implementation which wants to fix |
| * the system time when waking up from a mode with clocks turned off. |
| * |
| * Note: must be called with interrupts disabled. |
| */ |
| void force_time(timestamp_t ts); |
| |
| /** |
| * Print the current timer information using the command output channel. |
| * |
| * This may be called from interrupt level. |
| */ |
| void timer_print_info(void); |
| |
| /** |
| * Returns a free running millisecond clock counter, which matches tpm2 |
| * library expectations. |
| */ |
| clock_t clock(void); |
| |
| /** |
| * Compute how far to_time is from from_time with rollover taken into account |
| * |
| * Return us until to_time given from_time, if negative then to_time has |
| * passeed from_time. |
| */ |
| static inline int time_until(uint32_t from_time, uint32_t to_time) |
| { |
| return (int32_t)(to_time - from_time); |
| } |
| |
| /** |
| * Returns the number of microseconds that have elapsed from a start time. |
| * |
| * This function is for timing short delays typically of a few milliseconds |
| * or so. |
| * |
| * Note that this is limited to a maximum of 32 bits, which is around an |
| * hour. After that, the value returned will wrap. |
| * |
| * @param start Start time to compare against |
| * @return number of microseconds that have elapsed since that start time |
| */ |
| static inline unsigned time_since32(timestamp_t start) |
| { |
| return time_until(start.le.lo, get_time().le.lo); |
| } |
| |
| /** |
| * To compare time and deal with rollover |
| * |
| * Return true if a is after b. |
| */ |
| static inline int time_after(uint32_t a, uint32_t b) |
| { |
| return time_until(a, b) < 0; |
| } |
| |
| #endif /* __CROS_EC_TIMER_H */ |