Skip to content

Commit 7dfbb3c

Browse files
Add a delay after rtc_set_datetime (#2156)
If you call rtc_get_datetime immediately after rtc_set_datetime you get junk back. According to the datasheet "Writing to the RTC will take 2 clk_rtc clock periods to arrive". So add a delay after calling rtc_set_datetime in aon_timer_set_time_calendar. Fixes #2148
1 parent 111fa7d commit 7dfbb3c

File tree

6 files changed

+64
-10
lines changed

6 files changed

+64
-10
lines changed

src/rp2_common/pico_aon_timer/BUILD.bazel

+4
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ cc_library(
66
name = "pico_aon_timer",
77
srcs = ["aon_timer.c"],
88
hdrs = ["include/pico/aon_timer.h"],
9+
defines = [
10+
"LIB_PICO_AON_TIMER=1",
11+
],
912
includes = ["include"],
1013
target_compatible_with = compatible_with_rp2(),
1114
deps = [
1215
"//src/common/pico_util",
16+
"//src/common/pico_time",
1317
"//src/rp2_common:hardware_regs",
1418
"//src/rp2_common:pico_platform",
1519
"//src/rp2_common/hardware_irq",

src/rp2_common/pico_aon_timer/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pico_mirrored_target_link_libraries(pico_aon_timer INTERFACE pico_util)
1212

1313
if (TARGET hardware_rtc)
1414
pico_mirrored_target_link_libraries(pico_aon_timer INTERFACE hardware_rtc)
15+
target_link_libraries(pico_aon_timer_headers INTERFACE pico_time_headers)
1516
endif()
1617

1718
if (TARGET hardware_powman)

src/rp2_common/pico_aon_timer/aon_timer.c

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ static aon_timer_alarm_handler_t aon_timer_alarm_handler;
1313
#if HAS_RP2040_RTC
1414
#include "hardware/rtc.h"
1515
#include "pico/util/datetime.h"
16+
#include "pico/time.h"
17+
#include "hardware/clocks.h"
1618

1719
#elif HAS_POWMAN_TIMER
1820
#include "hardware/powman.h"
@@ -56,6 +58,10 @@ bool aon_timer_set_time_calendar(const struct tm *tm) {
5658
datetime_t dt;
5759
tm_to_datetime(tm, &dt);
5860
rtc_set_datetime(&dt);
61+
62+
// Writing to the RTC will take 2 clk_rtc clock periods to arrive
63+
uint rtc_freq = clock_get_hz(clk_rtc);
64+
busy_wait_us(((1000000 + rtc_freq - 1) / rtc_freq) * 2);
5965
return true;
6066
#elif HAS_POWMAN_TIMER
6167
struct timespec ts;

test/pico_time_test/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ cc_binary(
1212
target_compatible_with = compatible_with_rp2(),
1313
deps = [
1414
"//src/rp2_common/pico_stdlib",
15+
"//src/rp2_common/pico_aon_timer",
1516
"//test/pico_test",
1617
],
1718
)

test/pico_time_test/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@ if (NOT PICO_TIME_NO_ALARM_SUPPORT)
44
PICO_TIME_DEFAULT_ALARM_POOL_MAX_TIMERS=250
55
)
66
target_link_libraries(pico_time_test PRIVATE pico_test)
7+
if (PICO_RP2040)
8+
target_link_libraries(pico_time_test PRIVATE pico_aon_timer)
9+
endif()
710
pico_add_extra_outputs(pico_time_test)
811
endif()

test/pico_time_test/pico_time_test.c

+49-10
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
#endif
1414
#include "pico/stdlib.h"
1515
#include "pico/test.h"
16+
17+
#if LIB_PICO_AON_TIMER
18+
#include "pico/aon_timer.h"
19+
#endif
20+
1621
// Include sys/types.h before inttypes.h to work around issue with
1722
// certain versions of GCC and newlib which causes omission of PRIi64
1823
#include <sys/types.h>
@@ -74,11 +79,12 @@ static bool repeating_timer_callback(struct repeating_timer *t) {
7479
#define RESOLUTION_ALLOWANCE PICO_HARDWARE_TIMER_RESOLUTION_US
7580
#endif
7681

77-
int issue_195_test(void);
78-
int issue_1812_test(void);
79-
int issue_1953_test(void);
80-
int issue_2118_test(void);
81-
int issue_2186_test(void);
82+
static int issue_195_test(void);
83+
static int issue_1812_test(void);
84+
static int issue_1953_test(void);
85+
static int issue_2118_test(void);
86+
static int issue_2148_test(void);
87+
static int issue_2186_test(void);
8288

8389
int main() {
8490
setup_default_uart();
@@ -253,6 +259,8 @@ int main() {
253259

254260
issue_2118_test();
255261

262+
issue_2148_test();
263+
256264
issue_2186_test();
257265

258266
PICOTEST_END_TEST();
@@ -265,7 +273,7 @@ int64_t issue_195_callback(alarm_id_t id, void *user_data) {
265273
return -ISSUE_195_TIMER_DELAY;
266274
}
267275

268-
int issue_195_test(void) {
276+
static int issue_195_test(void) {
269277
PICOTEST_START_SECTION("Issue #195 race condition - without fix may hang on gcc 10.2.1 release builds");
270278
absolute_time_t t1 = get_absolute_time();
271279
int id = add_alarm_in_us(ISSUE_195_TIMER_DELAY, issue_195_callback, NULL, true);
@@ -284,7 +292,7 @@ int issue_195_test(void) {
284292
}
285293

286294
// Setting an alarm should not swallow a sev
287-
int issue_1812_test(void) {
295+
static int issue_1812_test(void) {
288296
PICOTEST_START_SECTION("Issue #1812 defect - Setting an alarm should not ignore a sev");
289297

290298
__sev(); // Make sure the call below does not ignore this
@@ -308,7 +316,7 @@ static void alarm_pool_stuck_issue_1953(uint alarm) {
308316
hard_assert(false);
309317
}
310318

311-
int issue_1953_test(void) {
319+
static int issue_1953_test(void) {
312320
PICOTEST_START_SECTION("Issue #1953 defect - Alarm can be set in the past");
313321
int alarm = hardware_alarm_claim_unused(true);
314322
hardware_alarm_set_callback(alarm, alarm_pool_stuck_issue_1953);
@@ -341,7 +349,7 @@ static bool timer_callback_issue_2118(repeating_timer_t *rt) {
341349
return true;
342350
}
343351

344-
int issue_2118_test(void) {
352+
static int issue_2118_test(void) {
345353
PICOTEST_START_SECTION("Issue #2118 defect - failure to set an alarm");
346354

347355
#if PICO_ON_DEVICE
@@ -373,7 +381,7 @@ int issue_2118_test(void) {
373381
return 0;
374382
}
375383

376-
int issue_2186_test(void) {
384+
static int issue_2186_test(void) {
377385
PICOTEST_START_SECTION("Issue #2186 defect - ta_wakes_up_on_or_before");
378386

379387
hard_assert(best_effort_wfe_or_timeout(get_absolute_time() - 1));
@@ -382,3 +390,34 @@ int issue_2186_test(void) {
382390
PICOTEST_END_SECTION();
383391
return 0;
384392
}
393+
394+
static int issue_2148_test(void) {
395+
#if HAS_RP2040_RTC
396+
PICOTEST_START_SECTION("Issue #2148 defect - get time after rtc start");
397+
struct tm tm = { 0 };
398+
struct tm tm_check = { 0 };
399+
400+
tm.tm_sec = 55;
401+
tm.tm_min = 36;
402+
tm.tm_hour = 20;
403+
tm.tm_mday = 21;
404+
tm.tm_mon = 10;
405+
tm.tm_year = 124;
406+
tm.tm_wday = 4;
407+
tm.tm_yday = 325;
408+
tm.tm_isdst = 0;
409+
hard_assert(aon_timer_start_calendar(&tm));
410+
hard_assert(aon_timer_get_time_calendar(&tm_check));
411+
412+
PICOTEST_CHECK(tm.tm_sec == tm_check.tm_sec || tm.tm_sec == tm_check.tm_sec - 1, "failed to get seconds");
413+
PICOTEST_CHECK(tm.tm_min == tm_check.tm_min, "failed to get minutes");
414+
PICOTEST_CHECK(tm.tm_hour == tm_check.tm_hour, "failed to get hour");
415+
PICOTEST_CHECK(tm.tm_mday == tm_check.tm_mday, "failed to get day");
416+
PICOTEST_CHECK(tm.tm_mon == tm_check.tm_mon, "failed to get month");
417+
PICOTEST_CHECK(tm.tm_year == tm_check.tm_year, "failed to get year");
418+
419+
aon_timer_stop();
420+
PICOTEST_END_SECTION();
421+
#endif
422+
return 0;
423+
}

0 commit comments

Comments
 (0)