Skip to content

Commit

Permalink
better documentation; fix bug; thread return code thru all methods
Browse files Browse the repository at this point in the history
  • Loading branch information
kilograham committed Nov 22, 2024
1 parent 9286c4f commit 1b7cca3
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 28 deletions.
33 changes: 20 additions & 13 deletions src/rp2_common/pico_aon_timer/aon_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
132 changes: 117 additions & 15 deletions src/rp2_common/pico_aon_timer/include/pico/aon_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/

Expand Down Expand Up @@ -66,17 +79,42 @@ 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);

/**
* \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
Expand All @@ -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);

/**
Expand All @@ -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);

/**
Expand Down

0 comments on commit 1b7cca3

Please sign in to comment.