time.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _PICO_TIME_H
8 #define _PICO_TIME_H
9 
10 #include "pico.h"
11 #include "hardware/timer.h"
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
32 // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_TIME, Enable/disable assertions in the time module, type=bool, default=0, group=pico_time
33 #ifndef PARAM_ASSERTIONS_ENABLED_TIME
34 #define PARAM_ASSERTIONS_ENABLED_TIME 0
35 #endif
36 
37 // PICO_CONFIG: PICO_TIME_SLEEP_OVERHEAD_ADJUST_US, How many microseconds to wake up early (and then busy_wait) to account for timer overhead when sleeping in low power mode, type=int, default=6, group=pico_time
38 #ifndef PICO_TIME_SLEEP_OVERHEAD_ADJUST_US
39 #define PICO_TIME_SLEEP_OVERHEAD_ADJUST_US 6
40 #endif
61 static inline absolute_time_t get_absolute_time(void) {
64  return t;
65 }
66 
67 static inline uint32_t us_to_ms(uint64_t us) {
68  if (us >> 32u) {
69  return (uint32_t)(us / 1000u);
70  } else {
71  return ((uint32_t)us) / 1000u;
72  }
73 }
74 
82 static inline uint32_t to_ms_since_boot(absolute_time_t t) {
83  uint64_t us = to_us_since_boot(t);
84  return us_to_ms(us);
85 }
86 
94 static inline absolute_time_t delayed_by_us(const absolute_time_t t, uint64_t us) {
95  absolute_time_t t2;
96  uint64_t base = to_us_since_boot(t);
97  uint64_t delayed = base + us;
98  if (delayed < base) {
99  delayed = (uint64_t)-1;
100  }
101  update_us_since_boot(&t2, delayed);
102  return t2;
103 }
104 
112 static inline absolute_time_t delayed_by_ms(const absolute_time_t t, uint32_t ms) {
113  absolute_time_t t2;
114  uint64_t base = to_us_since_boot(t);
115  uint64_t delayed = base + ms * 1000ull;
116  if (delayed < base) {
117  delayed = (uint64_t)-1;
118  }
119  update_us_since_boot(&t2, delayed);
120  return t2;
121 }
122 
129 static inline absolute_time_t make_timeout_time_us(uint64_t us) {
130  return delayed_by_us(get_absolute_time(), us);
131 }
132 
139 static inline absolute_time_t make_timeout_time_ms(uint32_t ms) {
140  return delayed_by_ms(get_absolute_time(), ms);
141 }
142 
154 static inline int64_t absolute_time_diff_us(absolute_time_t from, absolute_time_t to) {
155  return (int64_t)(to_us_since_boot(to) - to_us_since_boot(from));
156 }
157 
164 
171 static inline bool is_at_the_end_of_time(absolute_time_t t) {
173 }
174 
178 extern const absolute_time_t nil_time;
179 
186 static inline bool is_nil_time(absolute_time_t t) {
187  return !to_us_since_boot(t);
188 }
189 
219 void sleep_until(absolute_time_t target);
220 
229 void sleep_us(uint64_t us);
230 
238 void sleep_ms(uint32_t ms);
239 
273 bool best_effort_wfe_or_timeout(absolute_time_t timeout_timestamp);
274 
293 // PICO_CONFIG: PICO_TIME_DEFAULT_ALARM_POOL_DISABLED, Disable the default alarm pool, type=bool, default=0, advanced=true, group=pico_time
294 #ifndef PICO_TIME_DEFAULT_ALARM_POOL_DISABLED
307 #define PICO_TIME_DEFAULT_ALARM_POOL_DISABLED 0
308 #endif
309 
310 // PICO_CONFIG: PICO_TIME_DEFAULT_ALARM_POOL_HARDWARE_ALARM_NUM, Select which HW alarm is used for the default alarm pool, min=0, max=3, default=3, advanced=true, group=pico_time
311 #ifndef PICO_TIME_DEFAULT_ALARM_POOL_HARDWARE_ALARM_NUM
317 #define PICO_TIME_DEFAULT_ALARM_POOL_HARDWARE_ALARM_NUM 3
318 #endif
319 
320 // PICO_CONFIG: PICO_TIME_DEFAULT_ALARM_POOL_MAX_TIMERS, Selects the maximum number of concurrent timers in the default alarm pool, min=0, max=255, default=16, advanced=true, group=pico_time
321 #ifndef PICO_TIME_DEFAULT_ALARM_POOL_MAX_TIMERS
330 #define PICO_TIME_DEFAULT_ALARM_POOL_MAX_TIMERS 16
331 #endif
332 
346 typedef int32_t alarm_id_t; // note this is signed because we use -1 as a meaningful error value
347 
357 typedef int64_t (*alarm_callback_t)(alarm_id_t id, void *user_data);
358 
359 typedef struct alarm_pool alarm_pool_t;
360 
365 void alarm_pool_init_default(void);
366 
367 #if !PICO_TIME_DEFAULT_ALARM_POOL_DISABLED
376 #endif
377 
396 alarm_pool_t *alarm_pool_create(uint hardware_alarm_num, uint max_timers);
397 
405 
412 void alarm_pool_destroy(alarm_pool_t *pool);
413 
437 alarm_id_t alarm_pool_add_alarm_at(alarm_pool_t *pool, absolute_time_t time, alarm_callback_t callback, void *user_data, bool fire_if_past);
438 
462 static inline alarm_id_t alarm_pool_add_alarm_in_us(alarm_pool_t *pool, uint64_t us, alarm_callback_t callback, void *user_data, bool fire_if_past) {
463  return alarm_pool_add_alarm_at(pool, delayed_by_us(get_absolute_time(), us), callback, user_data, fire_if_past);
464 }
465 
489 static inline alarm_id_t alarm_pool_add_alarm_in_ms(alarm_pool_t *pool, uint32_t ms, alarm_callback_t callback, void *user_data, bool fire_if_past) {
490  return alarm_pool_add_alarm_at(pool, delayed_by_ms(get_absolute_time(), ms), callback, user_data, fire_if_past);
491 }
492 
501 bool alarm_pool_cancel_alarm(alarm_pool_t *pool, alarm_id_t alarm_id);
502 
503 #if !PICO_TIME_DEFAULT_ALARM_POOL_DISABLED
526 static inline alarm_id_t add_alarm_at(absolute_time_t time, alarm_callback_t callback, void *user_data, bool fire_if_past) {
527  return alarm_pool_add_alarm_at(alarm_pool_get_default(), time, callback, user_data, fire_if_past);
528 }
529 
552 static inline alarm_id_t add_alarm_in_us(uint64_t us, alarm_callback_t callback, void *user_data, bool fire_if_past) {
553  return alarm_pool_add_alarm_in_us(alarm_pool_get_default(), us, callback, user_data, fire_if_past);
554 }
555 
578 static inline alarm_id_t add_alarm_in_ms(uint32_t ms, alarm_callback_t callback, void *user_data, bool fire_if_past) {
579  return alarm_pool_add_alarm_in_ms(alarm_pool_get_default(), ms, callback, user_data, fire_if_past);
580 }
588 static inline bool cancel_alarm(alarm_id_t alarm_id) {
590 }
591 
592 #endif
593 
604 typedef struct repeating_timer repeating_timer_t;
605 
613 
620  int64_t delay_us;
621  alarm_pool_t *pool;
622  alarm_id_t alarm_id;
624  void *user_data;
625 };
626 
645 bool alarm_pool_add_repeating_timer_us(alarm_pool_t *pool, int64_t delay_us, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out);
646 
665 static inline bool alarm_pool_add_repeating_timer_ms(alarm_pool_t *pool, int32_t delay_ms, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out) {
666  return alarm_pool_add_repeating_timer_us(pool, delay_ms * (int64_t)1000, callback, user_data, out);
667 }
668 
669 #if !PICO_TIME_DEFAULT_ALARM_POOL_DISABLED
687 static inline bool add_repeating_timer_us(int64_t delay_us, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out) {
688  return alarm_pool_add_repeating_timer_us(alarm_pool_get_default(), delay_us, callback, user_data, out);
689 }
690 
708 static inline bool add_repeating_timer_ms(int32_t delay_ms, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out) {
709  return alarm_pool_add_repeating_timer_us(alarm_pool_get_default(), delay_ms * (int64_t)1000, callback, user_data, out);
710 }
711 #endif
712 
721 
722 #ifdef __cplusplus
723 }
724 #endif
725 
726 #endif
bool alarm_pool_cancel_alarm(alarm_pool_t *pool, alarm_id_t alarm_id)
Cancel an alarm.
Definition: time.c:261
static alarm_id_t alarm_pool_add_alarm_in_us(alarm_pool_t *pool, uint64_t us, alarm_callback_t callback, void *user_data, bool fire_if_past)
Add an alarm callback to be called after a delay specified in microseconds.
Definition: time.h:462
uint alarm_pool_hardware_alarm_num(alarm_pool_t *pool)
Return the hardware alarm used by an alarm pool.
Definition: time.c:285
alarm_pool_t * alarm_pool_create(uint hardware_alarm_num, uint max_timers)
Create an alarm pool.
Definition: time.c:178
alarm_pool_t * alarm_pool_get_default(void)
The default alarm pool used when alarms are added without specifying an alarm pool,...
Definition: time.c:91
static alarm_id_t add_alarm_in_us(uint64_t us, alarm_callback_t callback, void *user_data, bool fire_if_past)
Add an alarm callback to be called after a delay specified in microseconds.
Definition: time.h:552
static alarm_id_t alarm_pool_add_alarm_in_ms(alarm_pool_t *pool, uint32_t ms, alarm_callback_t callback, void *user_data, bool fire_if_past)
Add an alarm callback to be called after a delay specified in milliseconds.
Definition: time.h:489
static alarm_id_t add_alarm_in_ms(uint32_t ms, alarm_callback_t callback, void *user_data, bool fire_if_past)
Add an alarm callback to be called after a delay specified in milliseconds.
Definition: time.h:578
int32_t alarm_id_t
The identifier for an alarm.
Definition: time.h:346
void alarm_pool_init_default(void)
Create the default alarm pool (if not already created or disabled)
Definition: time.c:77
alarm_id_t alarm_pool_add_alarm_at(alarm_pool_t *pool, absolute_time_t time, alarm_callback_t callback, void *user_data, bool fire_if_past)
Add an alarm callback to be called at a specific time.
Definition: time.c:214
int64_t(* alarm_callback_t)(alarm_id_t id, void *user_data)
User alarm callback.
Definition: time.h:357
void alarm_pool_destroy(alarm_pool_t *pool)
Destroy the alarm pool, cancelling all alarms and freeing up the underlying hardware alarm.
Definition: time.c:196
static alarm_id_t add_alarm_at(absolute_time_t time, alarm_callback_t callback, void *user_data, bool fire_if_past)
Add an alarm callback to be called at a specific time.
Definition: time.h:526
static bool cancel_alarm(alarm_id_t alarm_id)
Cancel an alarm from the default alarm pool.
Definition: time.h:588
uint64_t time_us_64(void)
Return the current 64 bit timestamp value in microseconds.
Definition: timer.c:37
static bool add_repeating_timer_ms(int32_t delay_ms, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out)
Add a repeating timer that is called repeatedly at the specified interval in milliseconds.
Definition: time.h:708
bool(* repeating_timer_callback_t)(repeating_timer_t *rt)
Callback for a repeating timer.
Definition: time.h:612
bool alarm_pool_add_repeating_timer_us(alarm_pool_t *pool, int64_t delay_us, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out)
Add a repeating timer that is called repeatedly at the specified interval in microseconds.
Definition: time.c:309
static bool add_repeating_timer_us(int64_t delay_us, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out)
Add a repeating timer that is called repeatedly at the specified interval in microseconds.
Definition: time.h:687
bool cancel_repeating_timer(repeating_timer_t *timer)
Cancel a repeating timer.
Definition: time.c:322
static bool alarm_pool_add_repeating_timer_ms(alarm_pool_t *pool, int32_t delay_ms, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out)
Add a repeating timer that is called repeatedly at the specified interval in milliseconds.
Definition: time.h:665
void sleep_until(absolute_time_t target)
Wait until after the given timestamp to return.
Definition: time.c:345
void sleep_ms(uint32_t ms)
Wait for the given number of milliseconds before returning.
Definition: time.c:392
bool best_effort_wfe_or_timeout(absolute_time_t timeout_timestamp)
Helper method for blocking on a timeout.
Definition: time.c:396
void sleep_us(uint64_t us)
Wait for the given number of microseconds before returning.
Definition: time.c:375
static bool is_nil_time(absolute_time_t t)
Determine if the given timestamp is nil.
Definition: time.h:186
static uint64_t to_us_since_boot(absolute_time_t t)
convert an absolute_time_t into a number of microseconds since boot.
Definition: types.h:44
static int64_t absolute_time_diff_us(absolute_time_t from, absolute_time_t to)
Return the difference in microseconds between two timestamps.
Definition: time.h:154
static bool is_at_the_end_of_time(absolute_time_t t)
Determine if the given timestamp is "at_the_end_of_time".
Definition: time.h:171
static absolute_time_t get_absolute_time(void)
Return a representation of the current time.
Definition: time.h:61
static absolute_time_t make_timeout_time_us(uint64_t us)
Convenience method to get the timestamp a number of microseconds from the current time.
Definition: time.h:129
static absolute_time_t delayed_by_us(const absolute_time_t t, uint64_t us)
Return a timestamp value obtained by adding a number of microseconds to another timestamp.
Definition: time.h:94
static absolute_time_t delayed_by_ms(const absolute_time_t t, uint32_t ms)
Return a timestamp value obtained by adding a number of milliseconds to another timestamp.
Definition: time.h:112
const absolute_time_t nil_time
The timestamp representing a null timestamp.
static absolute_time_t make_timeout_time_ms(uint32_t ms)
Convenience method to get the timestamp a number of milliseconds from the current time.
Definition: time.h:139
static uint32_t to_ms_since_boot(absolute_time_t t)
Convert a timestamp into a number of milliseconds since boot.
Definition: time.h:82
const absolute_time_t at_the_end_of_time
The timestamp representing the end of time; this is actually not the maximum possible timestamp,...
static void update_us_since_boot(absolute_time_t *t, uint64_t us_since_boot)
update an absolute_time_t value to represent a given number of microseconds since boot
Definition: types.h:59
Definition: types.h:33
Definition: time.c:25
Information about a repeating timer.
Definition: time.h:619