Skip to content

Commit bec3f5b

Browse files
committed
Add a delay after rtc_set_datetime
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 969f589 commit bec3f5b

File tree

3 files changed

+49
-9
lines changed

3 files changed

+49
-9
lines changed

src/rp2_common/pico_aon_timer/aon_timer.c

Lines changed: 6 additions & 0 deletions
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) * 2);
5965
return true;
6066
#elif HAS_POWMAN_TIMER
6167
struct timespec ts;

test/pico_time_test/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ if (NOT PICO_TIME_NO_ALARM_SUPPORT)
33
target_compile_definitions(pico_time_test PRIVATE
44
PICO_TIME_DEFAULT_ALARM_POOL_MAX_TIMERS=250
55
)
6-
target_link_libraries(pico_time_test PRIVATE pico_test)
6+
target_link_libraries(pico_time_test PRIVATE pico_test pico_aon_timer)
77
pico_add_extra_outputs(pico_time_test)
88
endif()

test/pico_time_test/pico_time_test.c

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "hardware/clocks.h"
1212
#include "pico/stdlib.h"
1313
#include "pico/test.h"
14+
#include "pico/aon_timer.h"
1415
// Include sys/types.h before inttypes.h to work around issue with
1516
// certain versions of GCC and newlib which causes omission of PRIi64
1617
#include <sys/types.h>
@@ -72,10 +73,11 @@ static bool repeating_timer_callback(struct repeating_timer *t) {
7273
#define RESOLUTION_ALLOWANCE PICO_HARDWARE_TIMER_RESOLUTION_US
7374
#endif
7475

75-
int issue_195_test(void);
76-
int issue_1812_test(void);
77-
int issue_1953_test(void);
78-
int issue_2118_test(void);
76+
static int issue_195_test(void);
77+
static int issue_1812_test(void);
78+
static int issue_1953_test(void);
79+
static int issue_2118_test(void);
80+
static int issue_2148_test(void);
7981

8082
int main() {
8183
setup_default_uart();
@@ -250,6 +252,8 @@ int main() {
250252

251253
issue_2118_test();
252254

255+
issue_2148_test();
256+
253257
PICOTEST_END_TEST();
254258
}
255259

@@ -260,7 +264,7 @@ int64_t issue_195_callback(alarm_id_t id, void *user_data) {
260264
return -ISSUE_195_TIMER_DELAY;
261265
}
262266

263-
int issue_195_test(void) {
267+
static int issue_195_test(void) {
264268
PICOTEST_START_SECTION("Issue #195 race condition - without fix may hang on gcc 10.2.1 release builds");
265269
absolute_time_t t1 = get_absolute_time();
266270
int id = add_alarm_in_us(ISSUE_195_TIMER_DELAY, issue_195_callback, NULL, true);
@@ -279,7 +283,7 @@ int issue_195_test(void) {
279283
}
280284

281285
// Setting an alarm should not swallow a sev
282-
int issue_1812_test(void) {
286+
static int issue_1812_test(void) {
283287
PICOTEST_START_SECTION("Issue #1812 defect - Setting an alarm should not ignore a sev");
284288

285289
__sev(); // Make sure the call below does not ignore this
@@ -303,7 +307,7 @@ static void alarm_pool_stuck_issue_1953(uint alarm) {
303307
hard_assert(false);
304308
}
305309

306-
int issue_1953_test(void) {
310+
static int issue_1953_test(void) {
307311
PICOTEST_START_SECTION("Issue #1953 defect - Alarm can be set in the past");
308312
int alarm = hardware_alarm_claim_unused(true);
309313
hardware_alarm_set_callback(alarm, alarm_pool_stuck_issue_1953);
@@ -336,7 +340,7 @@ static bool timer_callback_issue_2118(repeating_timer_t *rt) {
336340
return true;
337341
}
338342

339-
int issue_2118_test(void) {
343+
static int issue_2118_test(void) {
340344
PICOTEST_START_SECTION("Issue #2118 defect - failure to set an alarm");
341345

342346
// this problem only happens when running the clock fast as it requires the time between
@@ -364,3 +368,33 @@ int issue_2118_test(void) {
364368
PICOTEST_END_SECTION();
365369
return 0;
366370
}
371+
372+
static int issue_2148_test(void) {
373+
#if HAS_RP2040_RTC
374+
PICOTEST_START_SECTION("Issue #2148 defect - get time after rtc start");
375+
struct tm tm = { 0 };
376+
struct tm tm_check = { 0 };
377+
378+
tm.tm_sec = 55;
379+
tm.tm_min = 36;
380+
tm.tm_hour = 20;
381+
tm.tm_mday = 21;
382+
tm.tm_mon = 10;
383+
tm.tm_year = 124;
384+
tm.tm_wday = 4;
385+
tm.tm_yday = 325;
386+
tm.tm_isdst = 0;
387+
hard_assert(aon_timer_start_calendar(&tm));
388+
hard_assert(aon_timer_get_time_calendar(&tm_check));
389+
390+
PICOTEST_CHECK(tm.tm_sec == tm_check.tm_sec || tm.tm_sec == tm_check.tm_sec - 1, "failed to get seconds");
391+
PICOTEST_CHECK(tm.tm_min == tm_check.tm_min, "failed to get minutes");
392+
PICOTEST_CHECK(tm.tm_hour == tm_check.tm_hour, "failed to get hour");
393+
PICOTEST_CHECK(tm.tm_mday == tm_check.tm_mday, "failed to get day");
394+
PICOTEST_CHECK(tm.tm_mon == tm_check.tm_mon, "failed to get month");
395+
PICOTEST_CHECK(tm.tm_year == tm_check.tm_year, "failed to get year");
396+
397+
aon_timer_stop();
398+
PICOTEST_END_SECTION();
399+
#endif
400+
}

0 commit comments

Comments
 (0)