From 0df36d944a9b4d907cc759d680d5c7c4f5a7176d Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Wed, 20 Nov 2024 20:22:39 -0600 Subject: [PATCH 1/7] support both struct timespec and struct tm variants of the aon timer APIs since use of one type on RP2040 and the other on RP2350 require pulling in C library code. Provide weak pico_ wrappers for localtime_r and mktime so that the user can override the conversion functions --- src/common/pico_util/datetime.c | 45 ++++--- .../pico_util/include/pico/util/datetime.h | 25 +++- src/rp2_common/pico_aon_timer/aon_timer.c | 121 ++++++++++++++---- .../pico_aon_timer/include/pico/aon_timer.h | 36 +++++- 4 files changed, 180 insertions(+), 47 deletions(-) diff --git a/src/common/pico_util/datetime.c b/src/common/pico_util/datetime.c index c113ce466..857053944 100644 --- a/src/common/pico_util/datetime.c +++ b/src/common/pico_util/datetime.c @@ -2,6 +2,14 @@ #include +__weak struct tm *pico_localtime_r(const time_t *time, struct tm *tm) { + return localtime_r(time, tm); +} + +__weak time_t pico_mktime(struct tm *tm) { + return mktime(tm); +} + #if PICO_INCLUDE_RTC_DATETIME static const char *DATETIME_MONTHS[12] = { "January", @@ -41,17 +49,29 @@ void datetime_to_str(char *buf, uint buf_size, const datetime_t *t) { t->year); }; +void datetime_to_tm(const datetime_t *dt, struct tm *tm) { + tm->tm_year = dt->year - 1900; + tm->tm_mon = dt->month - 1; + tm->tm_mday = dt->day; + tm->tm_hour = dt->hour; + tm->tm_min = dt->min; + tm->tm_sec = dt->sec; +} + +void tm_to_datetime(const struct tm *tm, datetime_t *dt) { + dt->year = (int16_t) (tm->tm_year + 1900); // 0..4095 + dt->month = (int8_t) (tm->tm_mon + 1); // 1..12, 1 is January + dt->day = (int8_t) tm->tm_mday; // 1..28,29,30,31 depending on month + dt->dotw = (int8_t) tm->tm_wday; // 0..6, 0 is Sunday + dt->hour = (int8_t) tm->tm_hour; // 0..23 + dt->min = (int8_t) tm->tm_min; // 0..59 + dt->sec = (int8_t) tm->tm_sec; // 0..59 +} bool time_to_datetime(time_t time, datetime_t *dt) { struct tm local; - if (localtime_r(&time, &local)) { - dt->year = (int16_t) (local.tm_year + 1900); // 0..4095 - dt->month = (int8_t) (local.tm_mon + 1); // 1..12, 1 is January - dt->day = (int8_t) local.tm_mday; // 1..28,29,30,31 depending on month - dt->dotw = (int8_t) local.tm_wday; // 0..6, 0 is Sunday - dt->hour = (int8_t) local.tm_hour; // 0..23 - dt->min = (int8_t) local.tm_min; // 0..59 - dt->sec = (int8_t) local.tm_sec; // 0..59 + if (pico_localtime_r(&time, &local)) { + tm_to_datetime(&local, dt); return true; } return false; @@ -59,13 +79,8 @@ bool time_to_datetime(time_t time, datetime_t *dt) { bool datetime_to_time(const datetime_t *dt, time_t *time) { struct tm local; - local.tm_year = dt->year - 1900; - local.tm_mon = dt->month - 1; - local.tm_mday = dt->day; - local.tm_hour = dt->hour; - local.tm_min = dt->min; - local.tm_sec = dt->sec; - *time = mktime(&local); + datetime_to_tm(dt, &local); + *time = pico_mktime(&local); return *time >= 0; } diff --git a/src/common/pico_util/include/pico/util/datetime.h b/src/common/pico_util/include/pico/util/datetime.h index 92e6d6460..05dea5633 100644 --- a/src/common/pico_util/include/pico/util/datetime.h +++ b/src/common/pico_util/include/pico/util/datetime.h @@ -19,8 +19,10 @@ extern "C" { * \ingroup pico_util */ -#if PICO_INCLUDE_RTC_DATETIME #include +#include + +#if PICO_INCLUDE_RTC_DATETIME /*! \brief Convert a datetime_t structure to a string * \ingroup util_datetime @@ -33,14 +35,33 @@ void datetime_to_str(char *buf, uint buf_size, const datetime_t *t); bool time_to_datetime(time_t time, datetime_t *dt); bool datetime_to_time(const datetime_t *dt, time_t *time); + +void datetime_to_tm(const datetime_t *dt, struct tm *tm); +void tm_to_datetime(const struct tm *tm, datetime_t *dt); + #endif -#include uint64_t timespec_to_ms(const struct timespec *ts); uint64_t timespec_to_us(const struct timespec *ts); void ms_to_timespec(uint64_t ms, struct timespec *ts); void us_to_timespec(uint64_t ms, struct timespec *ts); +/*! \brief localtime_r implementation for use by the pico_util datetime functions + * \ingroup util_datetime + * + * This method calls localtime_r from the C library by default, + * but is declared as a weak implementation to allow user code to override it + */ +struct tm *pico_localtime_r(const time_t *time, struct tm *tm); + +/*! \brief mktime implementation for use by the pico_util datetime functions +* \ingroup util_datetime +* +* This method calls mktime from the C library by default, +* but is declared as a weak implementation to allow user code to override it +*/ +time_t pico_mktime(struct tm *tm); + #ifdef __cplusplus } #endif diff --git a/src/rp2_common/pico_aon_timer/aon_timer.c b/src/rp2_common/pico_aon_timer/aon_timer.c index 35173cf89..01f8ee09c 100644 --- a/src/rp2_common/pico_aon_timer/aon_timer.c +++ b/src/rp2_common/pico_aon_timer/aon_timer.c @@ -13,6 +13,10 @@ static aon_timer_alarm_handler_t aon_timer_alarm_handler; #if HAS_RP2040_RTC #include "hardware/rtc.h" #include "pico/util/datetime.h" + +static __force_inline bool ts_to_tm(const struct timespec *ts, struct tm *tm) { + return pico_localtime_r(&ts->tv_sec, tm) != NULL; +} #elif HAS_POWMAN_TIMER #include "hardware/powman.h" @@ -23,56 +27,89 @@ static void powman_timer_irq_handler(void) { irq_remove_handler(irq_num, powman_timer_irq_handler); if (aon_timer_alarm_handler) aon_timer_alarm_handler(); } + #endif -void aon_timer_set_time(const struct timespec *ts) { +static bool tm_to_ts(const struct tm *tm, struct timespec *ts) { + struct tm tm_clone = *tm; + ts->tv_sec = pico_mktime(&tm_clone); + ts->tv_nsec = 0; + return ts->tv_sec != -1; +} + +bool aon_timer_set_time(const struct timespec *ts) { #if HAS_RP2040_RTC - datetime_t dt; - bool ok = time_to_datetime(ts->tv_sec, &dt); - assert(ok); - if (ok) rtc_set_datetime(&dt); + struct tm tm; + bool ok = pico_localtime_r(&ts->tv_sec, &tm); + if (ok) aon_timer_set_time_calendar(&tm); + return ok; #elif HAS_POWMAN_TIMER powman_timer_set_ms(timespec_to_ms(ts)); + return true; #else panic_unsupported(); #endif } -void aon_timer_get_time(struct timespec *ts) { +bool aon_timer_set_time_calendar(const struct tm *tm) { #if HAS_RP2040_RTC datetime_t dt; - rtc_get_datetime(&dt); - time_t t; - bool ok = datetime_to_time(&dt, &t); - assert(ok); - ts->tv_nsec = 0; - if (ok) { - ts->tv_sec = t; - } else { - ts->tv_sec = -1; + tm_to_datetime(tm, &dt); + rtc_set_datetime(&dt); + return true; +#elif HAS_POWMAN_TIMER + struct timespec ts; + if (tm_to_ts(tm, &ts)) { + return aon_timer_set_time(&ts); } + return false; +#else + panic_unsupported(); +#endif +} + +bool aon_timer_get_time(struct timespec *ts) { +#if HAS_RP2040_RTC + struct tm tm; + bool ok = aon_timer_get_time_calendar(&tm); + return ok && tm_to_ts(&tm, ts); #elif HAS_POWMAN_TIMER ms_to_timespec(powman_timer_get_ms(), ts); + return true; #else panic_unsupported(); #endif } -aon_timer_alarm_handler_t aon_timer_enable_alarm(const struct timespec *ts, aon_timer_alarm_handler_t handler, bool wakeup_from_low_power) { - uint32_t save = save_and_disable_interrupts(); - aon_timer_alarm_handler_t old_handler = aon_timer_alarm_handler; - struct timespec ts_adjusted = *ts; +bool aon_timer_get_time_calendar(struct tm *tm) { #if HAS_RP2040_RTC - ((void)wakeup_from_low_power); // don't have a choice datetime_t dt; + rtc_get_datetime(&dt); + datetime_to_tm(&dt, tm); + return true; +#elif HAS_POWMAN_TIMER + struct timespec ts; + bool ok = tm_to_ts(tm, &ts); + return ok && aon_timer_get_time(&ts); +#else + panic_unsupported(); +#endif +} + +aon_timer_alarm_handler_t aon_timer_enable_alarm(const struct timespec *ts, aon_timer_alarm_handler_t handler, bool wakeup_from_low_power) { +#if HAS_RP2040_RTC + struct tm tm; // adjust to after the target time + struct timespec ts_adjusted = *ts; if (ts_adjusted.tv_nsec) ts_adjusted.tv_sec++; - bool ok = time_to_datetime(ts_adjusted.tv_sec, &dt); - assert(ok); - if (ok) { - rtc_set_alarm(&dt, handler); + if (!pico_localtime_r(&ts_adjusted.tv_sec, &tm)) { + return (aon_timer_alarm_handler_t)PICO_ERROR_INVALID_ARG; } + return aon_timer_enable_alarm_calendar(&tm, handler, wakeup_from_low_power); #elif HAS_POWMAN_TIMER + uint32_t save = save_and_disable_interrupts(); + aon_timer_alarm_handler_t old_handler = aon_timer_alarm_handler; + struct timespec ts_adjusted = *ts; uint irq_num = aon_timer_get_irq_num(); powman_timer_disable_alarm(); // adjust to after the target time @@ -92,12 +129,34 @@ aon_timer_alarm_handler_t aon_timer_enable_alarm(const struct timespec *ts, aon_ irq_set_exclusive_handler(irq_num, powman_timer_irq_handler); irq_set_enabled(irq_num, true); } + aon_timer_alarm_handler = handler; + restore_interrupts_from_disabled(save); + return old_handler; #else panic_unsupported(); #endif +} + +aon_timer_alarm_handler_t aon_timer_enable_alarm_calendar(const struct tm *tm, aon_timer_alarm_handler_t handler, bool wakeup_from_low_power) { +#if HAS_RP2040_RTC + ((void)wakeup_from_low_power); // don't have a choice + uint32_t save = save_and_disable_interrupts(); + aon_timer_alarm_handler_t old_handler = aon_timer_alarm_handler; + datetime_t dt; + tm_to_datetime(tm, &dt); + rtc_set_alarm(&dt, handler); aon_timer_alarm_handler = handler; restore_interrupts_from_disabled(save); return old_handler; +#elif HAS_POWMAN_TIMER + struct timespec ts; + if (!tm_to_ts(tm, &ts)) { + return (aon_timer_alarm_handler_t)PICO_ERROR_INVALID_ARG; + } + return aon_timer_enable_alarm(&ts, handler, wakeup_from_low_power); +#else + panic_unsupported(); +#endif } void aon_timer_disable_alarm(void) { @@ -134,6 +193,20 @@ void aon_timer_start(const struct timespec *ts) { #endif } +void aon_timer_start_calendar(const struct tm *tm) { +#if HAS_RP2040_RTC + rtc_init(); + aon_timer_set_time_calendar(tm); +#elif HAS_POWMAN_TIMER + // todo how best to allow different configurations; this should just be the default + powman_timer_set_1khz_tick_source_xosc(); + aon_timer_set_time_calendar(tm); + powman_timer_start(); +#else + panic_unsupported(); +#endif +} + void aon_timer_stop(void) { #if HAS_RP2040_RTC hw_clear_bits(&rtc_hw->ctrl, RTC_CTRL_RTC_ENABLE_BITS); diff --git a/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h b/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h index 49a7c2a5d..ebe55ebb7 100644 --- a/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h +++ b/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h @@ -23,6 +23,23 @@ * \if rp2350_specific * This library uses the Powman Timer on RP2350. * \endif + * + * This library supports both `aon_timer_xxx_calendar()` methods which take a calendar date/time (as struct tm), + * and `aon_timer_xxx()` methods which take a time since epoch (as struct timespec) + * + * \if rp2040_specific + * NOTE: On RP2040 the non date/time methods must convert the struct timespec to a date/time value which is handled via + * the \ref pico_localtime_r method. By default, this pulls in the C library local_time_r method which can lead to a big increase in binary size. + * `pico_localtime_r` is weak, so can be overridden if a better/smaller alternative is available, otherwise you might consider + * using the `aon_timer_xxx_calendar()` variants on RP2040 + * \endif + * + * \if rp2350_specific + * NOTE: On RP2350 the date/time methods must convert the struct tm to a struct timespec value which is handled via + * the \ref pico_mktime method. By default, this pulls in the C library mktime method which can lead to a big increase in binary size. + * `pico_mktime` is weak, so can be overridden if a better/smaller alternative is available, otherwise you might consider + * using the `aon_timer_xxx()` variants on RP2350 + * \endif */ #ifdef __cplusplus @@ -59,6 +76,7 @@ void aon_timer_start_with_timeofday(void); * \param ts the current time */ void aon_timer_start(const struct timespec *ts); +void aon_timer_start_calendar(const struct tm *tm); /** * \brief Stop the AON timer @@ -71,14 +89,16 @@ void aon_timer_stop(void); * \ingroup pico_aon_timer * \param ts the new current time */ -void aon_timer_set_time(const struct timespec *ts); +bool aon_timer_set_time(const struct timespec *ts); +bool aon_timer_set_time_calendar(const struct tm *tm); /** * \brief Get the current time of the AON timer * \ingroup pico_aon_timer * \param ts out value for the current time */ -void aon_timer_get_time(struct timespec *ts); +bool aon_timer_get_time(struct timespec *ts); +bool aon_timer_get_time_calendar(struct tm *tm); /** * \brief Get the resolution of the AON timer @@ -91,18 +111,22 @@ void aon_timer_get_resolution(struct timespec *ts); * \brief Enable an AON timer alarm for a specified time * \ingroup pico_aon_timer * - * \if rp2040_specific - * On RP2040 the alarm will not fire if it is in the past - * \endif * \if rp2350_specific * On RP2350 the alarm will fire if it is in the past * \endif + * \if rp2040_specific + * On RP2040 the alarm will not fire if it is in the past. + * \endif * * \param ts the alarm time - * \param handler a callback to call when the timer fires (may be NULL for wakeup_from_low_power = true) + * \param handler a callback to call when the timer fires (can be NULL for wakeup_from_low_power = true) * \param wakeup_from_low_power true if the AON timer is to be used to wake up from a DORMANT state + * \return on success the old handler (or NULL if there was none) + * on failure, PICO_ERROR_INVALID_ARG + * \sa pico_localtime_r */ aon_timer_alarm_handler_t aon_timer_enable_alarm(const struct timespec *ts, aon_timer_alarm_handler_t handler, bool wakeup_from_low_power); +aon_timer_alarm_handler_t aon_timer_enable_alarm_calendar(const struct tm *tm, aon_timer_alarm_handler_t handler, bool wakeup_from_low_power); /** * \brief Disable the currently enabled AON timer alarm if any From 109e01a57e61f0d9826efce85fc44c9599aa32cf Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Wed, 20 Nov 2024 20:31:57 -0600 Subject: [PATCH 2/7] oops __weak in the wrong place --- src/common/pico_util/datetime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/pico_util/datetime.c b/src/common/pico_util/datetime.c index 857053944..ec17c1bd7 100644 --- a/src/common/pico_util/datetime.c +++ b/src/common/pico_util/datetime.c @@ -2,11 +2,11 @@ #include -__weak struct tm *pico_localtime_r(const time_t *time, struct tm *tm) { +struct tm * __weak pico_localtime_r(const time_t *time, struct tm *tm) { return localtime_r(time, tm); } -__weak time_t pico_mktime(struct tm *tm) { +time_t __weak pico_mktime(struct tm *tm) { return mktime(tm); } From 9286c4f4a06fb704a99c02829045338d160f1b53 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Wed, 20 Nov 2024 21:03:23 -0600 Subject: [PATCH 3/7] blind change for macos from linux --- src/common/pico_util/datetime.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/common/pico_util/datetime.c b/src/common/pico_util/datetime.c index ec17c1bd7..45d619ee3 100644 --- a/src/common/pico_util/datetime.c +++ b/src/common/pico_util/datetime.c @@ -1,16 +1,23 @@ #include "pico/util/datetime.h" -#include +#if !PICO_ON_DEVICE && __APPLE__ +// if we're compiling with LLVM on Apple, __weak does something else, but we don't care about overriding these ayway +#define __datetime_weak +#else +#define __datetime_weak __weak +#endif -struct tm * __weak pico_localtime_r(const time_t *time, struct tm *tm) { +__datetime_weak struct tm * pico_localtime_r(const time_t *time, struct tm *tm) { return localtime_r(time, tm); } -time_t __weak pico_mktime(struct tm *tm) { +__datetime_weak time_t pico_mktime(struct tm *tm) { return mktime(tm); } #if PICO_INCLUDE_RTC_DATETIME +#include + static const char *DATETIME_MONTHS[12] = { "January", "February", From 1b7cca3202a84b6a15ba9d4c21078e2c8c822063 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 21 Nov 2024 18:59:23 -0600 Subject: [PATCH 4/7] better documentation; fix bug; thread return code thru all methods --- src/rp2_common/pico_aon_timer/aon_timer.c | 33 +++-- .../pico_aon_timer/include/pico/aon_timer.h | 132 ++++++++++++++++-- 2 files changed, 137 insertions(+), 28 deletions(-) diff --git a/src/rp2_common/pico_aon_timer/aon_timer.c b/src/rp2_common/pico_aon_timer/aon_timer.c index 01f8ee09c..a4d594f63 100644 --- a/src/rp2_common/pico_aon_timer/aon_timer.c +++ b/src/rp2_common/pico_aon_timer/aon_timer.c @@ -14,9 +14,6 @@ static aon_timer_alarm_handler_t aon_timer_alarm_handler; #include "hardware/rtc.h" #include "pico/util/datetime.h" -static __force_inline bool ts_to_tm(const struct timespec *ts, struct tm *tm) { - return pico_localtime_r(&ts->tv_sec, tm) != NULL; -} #elif HAS_POWMAN_TIMER #include "hardware/powman.h" @@ -28,6 +25,9 @@ static void powman_timer_irq_handler(void) { if (aon_timer_alarm_handler) aon_timer_alarm_handler(); } +static bool ts_to_tm(const struct timespec *ts, struct tm *tm) { + return pico_localtime_r(&ts->tv_sec, tm) != NULL; +} #endif static bool tm_to_ts(const struct tm *tm, struct timespec *ts) { @@ -89,8 +89,8 @@ bool aon_timer_get_time_calendar(struct tm *tm) { return true; #elif HAS_POWMAN_TIMER struct timespec ts; - bool ok = tm_to_ts(tm, &ts); - return ok && aon_timer_get_time(&ts); + aon_timer_get_time(&ts); + return ts_to_tm(&ts, tm); #else panic_unsupported(); #endif @@ -179,29 +179,36 @@ void aon_timer_start_with_timeofday(void) { aon_timer_start(&ts); } -void aon_timer_start(const struct timespec *ts) { +bool aon_timer_start(const struct timespec *ts) { #if HAS_RP2040_RTC rtc_init(); - aon_timer_set_time(ts); + return aon_timer_set_time(ts); #elif HAS_POWMAN_TIMER // todo how best to allow different configurations; this should just be the default powman_timer_set_1khz_tick_source_xosc(); - powman_timer_set_ms(timespec_to_ms(ts)); - powman_timer_start(); + bool ok = aon_timer_set_time(ts); + if (ok) { + powman_timer_set_ms(timespec_to_ms(ts)); + powman_timer_start(); + } + return ok; #else panic_unsupported(); #endif } -void aon_timer_start_calendar(const struct tm *tm) { +bool aon_timer_start_calendar(const struct tm *tm) { #if HAS_RP2040_RTC rtc_init(); - aon_timer_set_time_calendar(tm); + return aon_timer_set_time_calendar(tm); #elif HAS_POWMAN_TIMER // todo how best to allow different configurations; this should just be the default powman_timer_set_1khz_tick_source_xosc(); - aon_timer_set_time_calendar(tm); - powman_timer_start(); + bool ok = aon_timer_set_time_calendar(tm); + if (ok) { + powman_timer_start(); + } + return ok; #else panic_unsupported(); #endif diff --git a/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h b/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h index ebe55ebb7..1a3eb5037 100644 --- a/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h +++ b/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h @@ -24,21 +24,34 @@ * This library uses the Powman Timer on RP2350. * \endif * - * This library supports both `aon_timer_xxx_calendar()` methods which take a calendar date/time (as struct tm), - * and `aon_timer_xxx()` methods which take a time since epoch (as struct timespec) + * This library supports both `aon_timer_xxx_calendar()` methods which use a calendar date/time (as struct tm), + * and `aon_timer_xxx()` methods which use a linear time value relative an internal reference time (via struct timespec). * * \if rp2040_specific - * NOTE: On RP2040 the non date/time methods must convert the struct timespec to a date/time value which is handled via - * the \ref pico_localtime_r method. By default, this pulls in the C library local_time_r method which can lead to a big increase in binary size. - * `pico_localtime_r` is weak, so can be overridden if a better/smaller alternative is available, otherwise you might consider - * using the `aon_timer_xxx_calendar()` variants on RP2040 + * NOTE: On RP2040 the non 'calendar date/time' methods must convert the linear time value to a calendar date/time internally; these methods are: + * + * * \ref aon_timer_start_with_timeofday + * * \ref aon_timer_start + * * \ref aon_timer_set_time + * * \ref aon_timer_get_time + * * \ref aon_timer_enable_alarm + * + * This conversion is handled by the \ref pico_localtime_r method. By default, this pulls in the C library `local_time_r` method + * which can lead to a big increase in binary size. The default implementation of `pico_localtime_r` is weak, so it can be overridden + * if a better/smaller alternative is available, otherwise you might consider the method variants ending in `_calendar()` instead on RP2040. * \endif * * \if rp2350_specific - * NOTE: On RP2350 the date/time methods must convert the struct tm to a struct timespec value which is handled via - * the \ref pico_mktime method. By default, this pulls in the C library mktime method which can lead to a big increase in binary size. - * `pico_mktime` is weak, so can be overridden if a better/smaller alternative is available, otherwise you might consider - * using the `aon_timer_xxx()` variants on RP2350 + * NOTE: On RP2350 the 'calendar date/time' methods must convert the calendar date/time to a linear time value internally; these methods are: + * + * * \ref aon_timer_start_calendar + * * \ref aon_timer_set_time_calendar + * * \ref aon_timer_get_time_calendar + * * \ref aon_timer_enable_alarm_calendar + * + * This conversion is handled by the \ref pico_mktime method. By default, this pulls in the C library `mktime` method + * which can lead to a big increase in binary size. The default implementation of `pico_mktime` is weak, so it can be overridden + * if a better/smaller alternative is available, otherwise you might consider the method variants not ending in `_calendar()` instead on RP2350. * \endif */ @@ -66,6 +79,11 @@ typedef void (*aon_timer_alarm_handler_t)(void); /** * \brief Start the AON timer running using the result from the gettimeofday() function as the current time + * + * \if rp2040_specific + * See \ref pico_aon_timer for caveats with using this method on RP2040 + * \endif + * * \ingroup pico_aon_timer */ void aon_timer_start_with_timeofday(void); @@ -73,10 +91,30 @@ void aon_timer_start_with_timeofday(void); /** * \brief Start the AON timer running using the specified timespec as the current time * \ingroup pico_aon_timer - * \param ts the current time + * + * \if rp2040_specific + * See \ref pico_aon_timer for caveats with using this method on RP2040 + * \endif + * + * \param ts the time to set as 'now' + * \return true on success, false if internal time format conversion failed + * \sa aon_timer_start_calendar */ -void aon_timer_start(const struct timespec *ts); -void aon_timer_start_calendar(const struct tm *tm); +bool aon_timer_start(const struct timespec *ts); + +/** + * \brief Start the AON timer running using the specified calendar date/time as the current time + * + * \if rp2350_specific + * See \ref pico_aon_timer for caveats with using this method on RP2350 + * \endif + * + * \ingroup pico_aon_timer + * \param tm the calendar date/time to set as 'now' + * \return true on success, false if internal time format conversion failed + * \sa aon_timer_start + */ +bool aon_timer_start_calendar(const struct tm *tm); /** * \brief Stop the AON timer @@ -85,19 +123,59 @@ void aon_timer_start_calendar(const struct tm *tm); void aon_timer_stop(void); /** - * \brief Update the current time of the AON timer + * \brief Set the current time of the AON timer * \ingroup pico_aon_timer + * + * \if rp2040_specific + * See \ref pico_aon_timer for caveats with using this method on RP2040 + * \endif + * * \param ts the new current time + * \return true on success, false if internal time format conversion failed + * \sa aon_timer_set_time_calendar */ bool aon_timer_set_time(const struct timespec *ts); + +/** + * \brief Set the current time of the AON timer to the given calendar date/time + * \ingroup pico_aon_timer + * + * \if rp2350_specific + * See \ref pico_aon_timer for caveats with using this method on RP2350 + * \endif + * + * \param tm the new current time + * \return true on success, false if internal time format conversion failed + * \sa aon_timer_set_time + */ bool aon_timer_set_time_calendar(const struct tm *tm); /** * \brief Get the current time of the AON timer * \ingroup pico_aon_timer + * + * \if rp2040_specific + * See \ref pico_aon_timer for caveats with using this method on RP2040 + * \endif + * * \param ts out value for the current time + * \return true on success, false if internal time format conversion failed + * \sa aon_timer_get_time_calendar */ bool aon_timer_get_time(struct timespec *ts); + + /** + * \brief Get the current time of the AON timer as a calendar date/time + * \ingroup pico_aon_timer + * + * \if rp2350_specific + * See \ref pico_aon_timer for caveats with using this method on RP2350 + * \endif + * + * \param tm out value for the current calendar date/time + * \return true on success, false if internal time format conversion failed + * \sa aon_timer_get_time + */ bool aon_timer_get_time_calendar(struct tm *tm); /** @@ -116,16 +194,40 @@ void aon_timer_get_resolution(struct timespec *ts); * \endif * \if rp2040_specific * On RP2040 the alarm will not fire if it is in the past. + * + * See \ref pico_aon_timer for caveats with using this method on RP2040 * \endif * * \param ts the alarm time * \param handler a callback to call when the timer fires (can be NULL for wakeup_from_low_power = true) * \param wakeup_from_low_power true if the AON timer is to be used to wake up from a DORMANT state * \return on success the old handler (or NULL if there was none) - * on failure, PICO_ERROR_INVALID_ARG + * or PICO_ERROR_INVALID_ARG if internal time format conversion failed * \sa pico_localtime_r */ aon_timer_alarm_handler_t aon_timer_enable_alarm(const struct timespec *ts, aon_timer_alarm_handler_t handler, bool wakeup_from_low_power); + +/** + * \brief Enable an AON timer alarm for a specified calendar date/time + * \ingroup pico_aon_timer + * + * \if rp2350_specific + * On RP2350 the alarm will fire if it is in the past + * + * See \ref pico_aon_timer for caveats with using this method on RP2350 + * \endif + * + * \if rp2040_specific + * On RP2040 the alarm will not fire if it is in the past. + * \endif + * + * \param tm the alarm calendar date/time + * \param handler a callback to call when the timer fires (can be NULL for wakeup_from_low_power = true) + * \param wakeup_from_low_power true if the AON timer is to be used to wake up from a DORMANT state + * \return on success the old handler (or NULL if there was none) + * or PICO_ERROR_INVALID_ARG if internal time format conversion failed + * \sa pico_localtime_r + */ aon_timer_alarm_handler_t aon_timer_enable_alarm_calendar(const struct tm *tm, aon_timer_alarm_handler_t handler, bool wakeup_from_low_power); /** From 0ab0fc57aaf4f3a9a295a9ca66be0fa5751d0a55 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 21 Nov 2024 19:51:19 -0600 Subject: [PATCH 5/7] use \anchor tag for better doc experience --- .../pico_aon_timer/include/pico/aon_timer.h | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h b/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h index 1a3eb5037..8398cac70 100644 --- a/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h +++ b/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h @@ -28,7 +28,8 @@ * and `aon_timer_xxx()` methods which use a linear time value relative an internal reference time (via struct timespec). * * \if rp2040_specific - * NOTE: On RP2040 the non 'calendar date/time' methods must convert the linear time value to a calendar date/time internally; these methods are: + * \anchor rp2040_caveats + * On RP2040 the non 'calendar date/time' methods must convert the linear time value to a calendar date/time internally; these methods are: * * * \ref aon_timer_start_with_timeofday * * \ref aon_timer_start @@ -42,7 +43,8 @@ * \endif * * \if rp2350_specific - * NOTE: On RP2350 the 'calendar date/time' methods must convert the calendar date/time to a linear time value internally; these methods are: + * \anchor rp2350_caveats + * On RP2350 the 'calendar date/time' methods must convert the calendar date/time to a linear time value internally; these methods are: * * * \ref aon_timer_start_calendar * * \ref aon_timer_set_time_calendar @@ -81,7 +83,7 @@ typedef void (*aon_timer_alarm_handler_t)(void); * \brief Start the AON timer running using the result from the gettimeofday() function as the current time * * \if rp2040_specific - * See \ref pico_aon_timer for caveats with using this method on RP2040 + * See \ref rp2040_caveats "caveats" for using this method on RP2040 * \endif * * \ingroup pico_aon_timer @@ -93,7 +95,7 @@ void aon_timer_start_with_timeofday(void); * \ingroup pico_aon_timer * * \if rp2040_specific - * See \ref pico_aon_timer for caveats with using this method on RP2040 + * See \ref rp2040_caveats "caveats" for using this method on RP2040 * \endif * * \param ts the time to set as 'now' @@ -106,7 +108,7 @@ bool aon_timer_start(const struct timespec *ts); * \brief Start the AON timer running using the specified calendar date/time as the current time * * \if rp2350_specific - * See \ref pico_aon_timer for caveats with using this method on RP2350 + * See \ref rp2040_caveats "caveats" for using this method on RP2350 * \endif * * \ingroup pico_aon_timer @@ -127,7 +129,7 @@ void aon_timer_stop(void); * \ingroup pico_aon_timer * * \if rp2040_specific - * See \ref pico_aon_timer for caveats with using this method on RP2040 + * See \ref rp2040_caveats "caveats" for using this method on RP2040 * \endif * * \param ts the new current time @@ -141,7 +143,7 @@ bool aon_timer_set_time(const struct timespec *ts); * \ingroup pico_aon_timer * * \if rp2350_specific - * See \ref pico_aon_timer for caveats with using this method on RP2350 + * See \ref rp2040_caveats "caveats" for using this method on RP2350 * \endif * * \param tm the new current time @@ -155,7 +157,7 @@ bool aon_timer_set_time_calendar(const struct tm *tm); * \ingroup pico_aon_timer * * \if rp2040_specific - * See \ref pico_aon_timer for caveats with using this method on RP2040 + * See \ref rp2040_caveats "caveats" for using this method on RP2040 * \endif * * \param ts out value for the current time @@ -169,7 +171,7 @@ bool aon_timer_get_time(struct timespec *ts); * \ingroup pico_aon_timer * * \if rp2350_specific - * See \ref pico_aon_timer for caveats with using this method on RP2350 + * See \ref rp2040_caveats "caveats" for using this method on RP2350 * \endif * * \param tm out value for the current calendar date/time @@ -195,7 +197,7 @@ void aon_timer_get_resolution(struct timespec *ts); * \if rp2040_specific * On RP2040 the alarm will not fire if it is in the past. * - * See \ref pico_aon_timer for caveats with using this method on RP2040 + * See \ref rp2040_caveats "caveats" for using this method on RP2040 * \endif * * \param ts the alarm time @@ -214,7 +216,7 @@ aon_timer_alarm_handler_t aon_timer_enable_alarm(const struct timespec *ts, aon_ * \if rp2350_specific * On RP2350 the alarm will fire if it is in the past * - * See \ref pico_aon_timer for caveats with using this method on RP2350 + * See \ref rp2040_caveats "caveats" for using this method on RP2350 * \endif * * \if rp2040_specific From 66710e8d299a9b912441c7dff329dd9e5a693d21 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 21 Nov 2024 19:57:27 -0600 Subject: [PATCH 6/7] oops; fix rp2040/rp2350 mixups --- src/rp2_common/pico_aon_timer/include/pico/aon_timer.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h b/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h index 8398cac70..768c79827 100644 --- a/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h +++ b/src/rp2_common/pico_aon_timer/include/pico/aon_timer.h @@ -108,7 +108,7 @@ bool aon_timer_start(const struct timespec *ts); * \brief Start the AON timer running using the specified calendar date/time as the current time * * \if rp2350_specific - * See \ref rp2040_caveats "caveats" for using this method on RP2350 + * See \ref rp2350_caveats "caveats" for using this method on RP2350 * \endif * * \ingroup pico_aon_timer @@ -143,7 +143,7 @@ bool aon_timer_set_time(const struct timespec *ts); * \ingroup pico_aon_timer * * \if rp2350_specific - * See \ref rp2040_caveats "caveats" for using this method on RP2350 + * See \ref rp2350_caveats "caveats" for using this method on RP2350 * \endif * * \param tm the new current time @@ -171,7 +171,7 @@ bool aon_timer_get_time(struct timespec *ts); * \ingroup pico_aon_timer * * \if rp2350_specific - * See \ref rp2040_caveats "caveats" for using this method on RP2350 + * See \ref rp2350_caveats "caveats" for using this method on RP2350 * \endif * * \param tm out value for the current calendar date/time @@ -216,7 +216,7 @@ aon_timer_alarm_handler_t aon_timer_enable_alarm(const struct timespec *ts, aon_ * \if rp2350_specific * On RP2350 the alarm will fire if it is in the past * - * See \ref rp2040_caveats "caveats" for using this method on RP2350 + * See \ref rp2350_caveats "caveats" for using this method on RP2350 * \endif * * \if rp2040_specific From 84df9e2caa1e2bccc7a0bcd1689719e91c5ceb05 Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Fri, 22 Nov 2024 11:53:58 -0600 Subject: [PATCH 7/7] fix comment --- src/common/pico_util/datetime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/pico_util/datetime.c b/src/common/pico_util/datetime.c index 45d619ee3..130e2d5a6 100644 --- a/src/common/pico_util/datetime.c +++ b/src/common/pico_util/datetime.c @@ -1,7 +1,7 @@ #include "pico/util/datetime.h" #if !PICO_ON_DEVICE && __APPLE__ -// if we're compiling with LLVM on Apple, __weak does something else, but we don't care about overriding these ayway +// if we're compiling with LLVM on Apple, __weak does something else, but we don't care about overriding these anyway on host builds #define __datetime_weak #else #define __datetime_weak __weak