diff --git a/sys/include/xtimer.h b/sys/include/xtimer.h index bd1e1c50a3..30ecf5cdae 100644 --- a/sys/include/xtimer.h +++ b/sys/include/xtimer.h @@ -436,6 +436,16 @@ void xtimer_set_timeout_flag(xtimer_t *t, uint32_t timeout); void xtimer_set_timeout_flag64(xtimer_t *t, uint64_t timeout); #endif +/** + * @brief Get remaining time of timer + * + * @param[in] timer timer struct to use + * + * @returns time in usec until timer triggers + * @returns 0 if timer is not set (or has already passed) + */ +uint64_t xtimer_left_usec(const xtimer_t *timer); + #if defined(MODULE_CORE_MSG) || defined(DOXYGEN) /** * @brief Set a timer that sends a message diff --git a/sys/xtimer/xtimer.c b/sys/xtimer/xtimer.c index 8022163923..a721431680 100644 --- a/sys/xtimer/xtimer.c +++ b/sys/xtimer/xtimer.c @@ -295,3 +295,26 @@ void xtimer_set_timeout_flag64(xtimer_t *t, uint64_t timeout) xtimer_set64(t, timeout); } #endif + +uint64_t xtimer_left_usec(const xtimer_t *timer) +{ + unsigned state = irq_disable(); + /* ensure we're working on valid data by making a local copy of timer */ + xtimer_t t = *timer; + uint64_t now_us = xtimer_now_usec64(); + irq_restore(state); + + uint64_t start_us = _xtimer_usec_from_ticks64( + ((uint64_t)t.long_start_time << 32) | t.start_time); + uint64_t target_us = start_us + _xtimer_usec_from_ticks64( + ((uint64_t)t.long_offset) << 32 | t.offset); + + /* Let's assume that 64bit won't overflow anytime soon. There'd be >580 + * years when counting nanoseconds. With microseconds, there are 580000 + * years of space in 2**64... */ + if (now_us > target_us) { + return 0; + } + + return target_us - now_us; +}