mirror of
https://github.com/raspberrypi/pico-sdk.git
synced 2025-12-10 07:14:36 +01:00
support both struct timespec and struct tm variants of the aon timer APIs (#2079)
* 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
This commit is contained in:
parent
2692d9a4cb
commit
3dce58f21b
4 changed files with 312 additions and 61 deletions
|
|
@ -1,8 +1,23 @@
|
|||
#include "pico/util/datetime.h"
|
||||
|
||||
#include <stdio.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 anyway on host builds
|
||||
#define __datetime_weak
|
||||
#else
|
||||
#define __datetime_weak __weak
|
||||
#endif
|
||||
|
||||
__datetime_weak struct tm * pico_localtime_r(const time_t *time, struct tm *tm) {
|
||||
return localtime_r(time, tm);
|
||||
}
|
||||
|
||||
__datetime_weak time_t pico_mktime(struct tm *tm) {
|
||||
return mktime(tm);
|
||||
}
|
||||
|
||||
#if PICO_INCLUDE_RTC_DATETIME
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *DATETIME_MONTHS[12] = {
|
||||
"January",
|
||||
"February",
|
||||
|
|
@ -41,17 +56,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 +86,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,10 @@ extern "C" {
|
|||
* \ingroup pico_util
|
||||
*/
|
||||
|
||||
#if PICO_INCLUDE_RTC_DATETIME
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#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 <sys/time.h>
|
||||
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
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ static aon_timer_alarm_handler_t aon_timer_alarm_handler;
|
|||
#if HAS_RP2040_RTC
|
||||
#include "hardware/rtc.h"
|
||||
#include "pico/util/datetime.h"
|
||||
|
||||
#elif HAS_POWMAN_TIMER
|
||||
#include "hardware/powman.h"
|
||||
|
||||
|
|
@ -23,56 +24,92 @@ 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();
|
||||
}
|
||||
|
||||
static bool ts_to_tm(const struct timespec *ts, struct tm *tm) {
|
||||
return pico_localtime_r(&ts->tv_sec, tm) != NULL;
|
||||
}
|
||||
#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;
|
||||
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
|
||||
}
|
||||
|
||||
bool aon_timer_get_time_calendar(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;
|
||||
}
|
||||
datetime_to_tm(&dt, tm);
|
||||
return true;
|
||||
#elif HAS_POWMAN_TIMER
|
||||
ms_to_timespec(powman_timer_get_ms(), ts);
|
||||
struct timespec ts;
|
||||
aon_timer_get_time(&ts);
|
||||
return ts_to_tm(&ts, tm);
|
||||
#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++;
|
||||
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;
|
||||
#if HAS_RP2040_RTC
|
||||
((void)wakeup_from_low_power); // don't have a choice
|
||||
datetime_t dt;
|
||||
// adjust to after the target time
|
||||
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);
|
||||
}
|
||||
#elif HAS_POWMAN_TIMER
|
||||
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);
|
||||
}
|
||||
#else
|
||||
panic_unsupported();
|
||||
#endif
|
||||
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) {
|
||||
|
|
@ -120,15 +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
|
||||
}
|
||||
|
||||
bool aon_timer_start_calendar(const struct tm *tm) {
|
||||
#if HAS_RP2040_RTC
|
||||
rtc_init();
|
||||
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();
|
||||
bool ok = aon_timer_set_time_calendar(tm);
|
||||
if (ok) {
|
||||
powman_timer_start();
|
||||
}
|
||||
return ok;
|
||||
#else
|
||||
panic_unsupported();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,6 +23,38 @@
|
|||
* \if rp2350_specific
|
||||
* This library uses the Powman Timer on RP2350.
|
||||
* \endif
|
||||
*
|
||||
* 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
|
||||
* \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
|
||||
* * \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
|
||||
* \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
|
||||
* * \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
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -49,6 +81,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 rp2040_caveats "caveats" for using this method on RP2040
|
||||
* \endif
|
||||
*
|
||||
* \ingroup pico_aon_timer
|
||||
*/
|
||||
void aon_timer_start_with_timeofday(void);
|
||||
|
|
@ -56,9 +93,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 rp2040_caveats "caveats" for 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);
|
||||
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 rp2350_caveats "caveats" for 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
|
||||
|
|
@ -67,18 +125,60 @@ void aon_timer_start(const struct timespec *ts);
|
|||
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 rp2040_caveats "caveats" for 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
|
||||
*/
|
||||
void aon_timer_set_time(const struct timespec *ts);
|
||||
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 rp2350_caveats "caveats" for 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 rp2040_caveats "caveats" for 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
|
||||
*/
|
||||
void aon_timer_get_time(struct timespec *ts);
|
||||
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 rp2350_caveats "caveats" for 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);
|
||||
|
||||
/**
|
||||
* \brief Get the resolution of the AON timer
|
||||
|
|
@ -91,19 +191,47 @@ 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.
|
||||
*
|
||||
* See \ref rp2040_caveats "caveats" for using this method on RP2040
|
||||
* \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)
|
||||
* 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 rp2350_caveats "caveats" for 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);
|
||||
|
||||
/**
|
||||
* \brief Disable the currently enabled AON timer alarm if any
|
||||
* \ingroup pico_aon_timer
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue