diff --git a/drivers/include/rtt_rtc.h b/drivers/include/rtt_rtc.h new file mode 100644 index 0000000000..d68c72a8af --- /dev/null +++ b/drivers/include/rtt_rtc.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 ML!PA Consulting GmbH + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @defgroup drivers_rtt_rtc RTC emulation on top of a RTT + * @ingroup drivers_periph_rtc + * + * @{ + * + * @file + * @brief Additional functions provided in addition to the normal RTC API. + * + * @author Benjamin Valentin + */ + +#ifndef RTT_RTC_H +#define RTT_RTC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set the time as epoch with sub-second precision + * This feature is an extension provided by the `rtt_rtc` module. + * + * @note The actual µs precision depends on the underlying hardware. + * The smallest time step will be 1 / @ref RTT_FREQUENCY. + * + * @param[in] s The new epoch timestamp + * @param[in] us Sub-Seconds + */ +void rtt_rtc_settimeofday(uint32_t s, uint32_t us); + +/** + * @brief Get the current epoch with sub-second precision + * This feature is an extension provided by the `rtt_rtc` module. + * + * @note The actual µs precision depends on the underlying hardware. + * The smallest time step will be 1 / @ref RTT_FREQUENCY. + * + * @param[out] s The current epoch timestamp + * @param[out] us Sub-Seconds + */ +void rtt_rtc_gettimeofday(uint32_t *s, uint32_t *us); + +#ifdef __cplusplus +} +#endif + +#endif /* RTT_RTC_H */ +/** @} */ diff --git a/drivers/rtt_rtc/rtt_rtc.c b/drivers/rtt_rtc/rtt_rtc.c index 2e16ac69c6..3fb2533ed6 100644 --- a/drivers/rtt_rtc/rtt_rtc.c +++ b/drivers/rtt_rtc/rtt_rtc.c @@ -7,7 +7,7 @@ */ /** - * @ingroup drivers_periph_rtc + * @ingroup drivers_rtt_rtc * @{ * * @file @@ -29,6 +29,7 @@ #include "periph/rtc.h" #include "periph/rtt.h" #include "timex.h" +#include "rtt_rtc.h" #define ENABLE_DEBUG 0 #include "debug.h" @@ -204,3 +205,27 @@ void rtc_poweroff(void) { rtt_poweroff(); } + +void rtt_rtc_settimeofday(uint32_t s, uint32_t us) +{ + /* disable alarm to prevent race condition */ + rtt_clear_alarm(); + uint32_t now = ((uint64_t)us * RTT_SECOND) / US_PER_SEC; + rtc_now = s; + rtt_set_counter(now); + /* calculate next wake-up period */ + _update_alarm(0); +} + +void rtt_rtc_gettimeofday(uint32_t *s, uint32_t *us) +{ + uint32_t now; + unsigned state = irq_disable(); + + now = rtt_get_counter(); + *s = _rtc_now(now); + *us = ((uint64_t)SUBSECONDS(now - last_alarm) * US_PER_SEC) + / RTT_SECOND; + + irq_restore(state); +}