diff --git a/src/rp2_common/pico_aon_timer/BUILD.bazel b/src/rp2_common/pico_aon_timer/BUILD.bazel index 6ceaf2e52..45ef4f3cc 100644 --- a/src/rp2_common/pico_aon_timer/BUILD.bazel +++ b/src/rp2_common/pico_aon_timer/BUILD.bazel @@ -6,10 +6,14 @@ cc_library( name = "pico_aon_timer", srcs = ["aon_timer.c"], hdrs = ["include/pico/aon_timer.h"], + defines = [ + "LIB_PICO_AON_TIMER=1", + ], includes = ["include"], target_compatible_with = compatible_with_rp2(), deps = [ "//src/common/pico_util", + "//src/common/pico_time", "//src/rp2_common:hardware_regs", "//src/rp2_common:pico_platform", "//src/rp2_common/hardware_irq", diff --git a/src/rp2_common/pico_aon_timer/CMakeLists.txt b/src/rp2_common/pico_aon_timer/CMakeLists.txt index 0d2a2d657..c1abe98f3 100644 --- a/src/rp2_common/pico_aon_timer/CMakeLists.txt +++ b/src/rp2_common/pico_aon_timer/CMakeLists.txt @@ -12,6 +12,7 @@ pico_mirrored_target_link_libraries(pico_aon_timer INTERFACE pico_util) if (TARGET hardware_rtc) pico_mirrored_target_link_libraries(pico_aon_timer INTERFACE hardware_rtc) + target_link_libraries(pico_aon_timer_headers INTERFACE pico_time_headers) endif() if (TARGET hardware_powman) diff --git a/src/rp2_common/pico_aon_timer/aon_timer.c b/src/rp2_common/pico_aon_timer/aon_timer.c index a4d594f63..62ef6c27a 100644 --- a/src/rp2_common/pico_aon_timer/aon_timer.c +++ b/src/rp2_common/pico_aon_timer/aon_timer.c @@ -13,6 +13,8 @@ static aon_timer_alarm_handler_t aon_timer_alarm_handler; #if HAS_RP2040_RTC #include "hardware/rtc.h" #include "pico/util/datetime.h" +#include "pico/time.h" +#include "hardware/clocks.h" #elif HAS_POWMAN_TIMER #include "hardware/powman.h" @@ -56,6 +58,10 @@ bool aon_timer_set_time_calendar(const struct tm *tm) { datetime_t dt; tm_to_datetime(tm, &dt); rtc_set_datetime(&dt); + + // Writing to the RTC will take 2 clk_rtc clock periods to arrive + uint rtc_freq = clock_get_hz(clk_rtc); + busy_wait_us(((1000000 + rtc_freq - 1) / rtc_freq) * 2); return true; #elif HAS_POWMAN_TIMER struct timespec ts; diff --git a/test/pico_time_test/BUILD.bazel b/test/pico_time_test/BUILD.bazel index b7a437629..038738601 100644 --- a/test/pico_time_test/BUILD.bazel +++ b/test/pico_time_test/BUILD.bazel @@ -12,6 +12,7 @@ cc_binary( target_compatible_with = compatible_with_rp2(), deps = [ "//src/rp2_common/pico_stdlib", + "//src/rp2_common/pico_aon_timer", "//test/pico_test", ], ) diff --git a/test/pico_time_test/CMakeLists.txt b/test/pico_time_test/CMakeLists.txt index d36a3da07..20a5608bd 100644 --- a/test/pico_time_test/CMakeLists.txt +++ b/test/pico_time_test/CMakeLists.txt @@ -4,5 +4,8 @@ if (NOT PICO_TIME_NO_ALARM_SUPPORT) PICO_TIME_DEFAULT_ALARM_POOL_MAX_TIMERS=250 ) target_link_libraries(pico_time_test PRIVATE pico_test) + if (PICO_RP2040) + target_link_libraries(pico_time_test PRIVATE pico_aon_timer) + endif() pico_add_extra_outputs(pico_time_test) endif() \ No newline at end of file diff --git a/test/pico_time_test/pico_time_test.c b/test/pico_time_test/pico_time_test.c index 82c3d825f..b8f4cba3c 100644 --- a/test/pico_time_test/pico_time_test.c +++ b/test/pico_time_test/pico_time_test.c @@ -13,6 +13,11 @@ #endif #include "pico/stdlib.h" #include "pico/test.h" + +#if LIB_PICO_AON_TIMER +#include "pico/aon_timer.h" +#endif + // Include sys/types.h before inttypes.h to work around issue with // certain versions of GCC and newlib which causes omission of PRIi64 #include @@ -74,11 +79,12 @@ static bool repeating_timer_callback(struct repeating_timer *t) { #define RESOLUTION_ALLOWANCE PICO_HARDWARE_TIMER_RESOLUTION_US #endif -int issue_195_test(void); -int issue_1812_test(void); -int issue_1953_test(void); -int issue_2118_test(void); -int issue_2186_test(void); +static int issue_195_test(void); +static int issue_1812_test(void); +static int issue_1953_test(void); +static int issue_2118_test(void); +static int issue_2148_test(void); +static int issue_2186_test(void); int main() { setup_default_uart(); @@ -253,6 +259,8 @@ int main() { issue_2118_test(); + issue_2148_test(); + issue_2186_test(); PICOTEST_END_TEST(); @@ -265,7 +273,7 @@ int64_t issue_195_callback(alarm_id_t id, void *user_data) { return -ISSUE_195_TIMER_DELAY; } -int issue_195_test(void) { +static int issue_195_test(void) { PICOTEST_START_SECTION("Issue #195 race condition - without fix may hang on gcc 10.2.1 release builds"); absolute_time_t t1 = get_absolute_time(); int id = add_alarm_in_us(ISSUE_195_TIMER_DELAY, issue_195_callback, NULL, true); @@ -284,7 +292,7 @@ int issue_195_test(void) { } // Setting an alarm should not swallow a sev -int issue_1812_test(void) { +static int issue_1812_test(void) { PICOTEST_START_SECTION("Issue #1812 defect - Setting an alarm should not ignore a sev"); __sev(); // Make sure the call below does not ignore this @@ -308,7 +316,7 @@ static void alarm_pool_stuck_issue_1953(uint alarm) { hard_assert(false); } -int issue_1953_test(void) { +static int issue_1953_test(void) { PICOTEST_START_SECTION("Issue #1953 defect - Alarm can be set in the past"); int alarm = hardware_alarm_claim_unused(true); hardware_alarm_set_callback(alarm, alarm_pool_stuck_issue_1953); @@ -341,7 +349,7 @@ static bool timer_callback_issue_2118(repeating_timer_t *rt) { return true; } -int issue_2118_test(void) { +static int issue_2118_test(void) { PICOTEST_START_SECTION("Issue #2118 defect - failure to set an alarm"); #if PICO_ON_DEVICE @@ -373,7 +381,7 @@ int issue_2118_test(void) { return 0; } -int issue_2186_test(void) { +static int issue_2186_test(void) { PICOTEST_START_SECTION("Issue #2186 defect - ta_wakes_up_on_or_before"); hard_assert(best_effort_wfe_or_timeout(get_absolute_time() - 1)); @@ -382,3 +390,34 @@ int issue_2186_test(void) { PICOTEST_END_SECTION(); return 0; } + +static int issue_2148_test(void) { +#if HAS_RP2040_RTC + PICOTEST_START_SECTION("Issue #2148 defect - get time after rtc start"); + struct tm tm = { 0 }; + struct tm tm_check = { 0 }; + + tm.tm_sec = 55; + tm.tm_min = 36; + tm.tm_hour = 20; + tm.tm_mday = 21; + tm.tm_mon = 10; + tm.tm_year = 124; + tm.tm_wday = 4; + tm.tm_yday = 325; + tm.tm_isdst = 0; + hard_assert(aon_timer_start_calendar(&tm)); + hard_assert(aon_timer_get_time_calendar(&tm_check)); + + PICOTEST_CHECK(tm.tm_sec == tm_check.tm_sec || tm.tm_sec == tm_check.tm_sec - 1, "failed to get seconds"); + PICOTEST_CHECK(tm.tm_min == tm_check.tm_min, "failed to get minutes"); + PICOTEST_CHECK(tm.tm_hour == tm_check.tm_hour, "failed to get hour"); + PICOTEST_CHECK(tm.tm_mday == tm_check.tm_mday, "failed to get day"); + PICOTEST_CHECK(tm.tm_mon == tm_check.tm_mon, "failed to get month"); + PICOTEST_CHECK(tm.tm_year == tm_check.tm_year, "failed to get year"); + + aon_timer_stop(); + PICOTEST_END_SECTION(); +#endif + return 0; +}