8000 esp8266/modpybrtc: Handle RTC overflow. · lapsule/micropython@cafdfb7 · GitHub
[go: up one dir, main page]

Skip to content

Commit cafdfb7

Browse files
puuudpgeorge
authored andcommitted
esp8266/modpybrtc: Handle RTC overflow.
ESP-SDK system_get_rtc_time() returns uint32 and therefore overflow about every 7:45h. Let's write the last state of system_get_rtc_time() in RTC mem and use it to check for overflow. This commit require running pyb_rtc_get_us_since_2000() at least once within 7 hours to avoid overflow.
1 parent 1191ec6 commit cafdfb7

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

esp8266/modpybrtc.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ STATIC const pyb_rtc_obj_t pyb_rtc_obj = {{&pyb_rtc_type}};
5353
uint32_t pyb_rtc_alarm0_wake; // see MACHINE_WAKE_xxx constants
5454
uint64_t pyb_rtc_alarm0_expiry; // in microseconds
5555

56+
// RTC overflow checking
57+
STATIC uint32_t rtc_last_ticks;
58+
5659
void mp_hal_rtc_init(void) {
5760
uint32_t magic;
5861

@@ -67,6 +70,8 @@ void mp_hal_rtc_init(void) {
6770
uint32_t len = 0;
6871
system_rtc_mem_write(MEM_USER_LEN_ADDR, &len, sizeof(len));
6972
}
73+
// system_get_rtc_time() is always 0 after reset/deepsleep
74+
rtc_last_ticks = system_get_rtc_time();
7075

7176
// reset ALARM0 state
7277
pyb_rtc_alarm0_wake = 0;
@@ -81,13 +86,11 @@ STATIC mp_obj_t pyb_rtc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp
8186
return (mp_obj_t)&pyb_rtc_obj;
8287
}
8388

84-
STATIC uint64_t pyb_rtc_raw_us(uint64_t cal) {
85-
return (system_get_rtc_time() * cal) >> 12;
86-
};
87-
8889
void pyb_rtc_set_us_since_2000(uint64_t nowus) {
8990
uint32_t cal = system_rtc_clock_cali_proc();
90-
int64_t delta = nowus - pyb_rtc_raw_us(cal);
91+
// Save RTC ticks for overflow detection.
92+
rtc_last_ticks = system_get_rtc_time();
93+
int64_t delta = nowus - (((uint64_t)rtc_last_ticks * cal) >> 12);
9194

9295
// As the calibration value jitters quite a bit, to make the
9396
// clock at least somewhat practially usable, we need to store it
@@ -98,11 +101,23 @@ void pyb_rtc_set_us_since_2000(uint64_t nowus) {
98101
uint64_t pyb_rtc_get_us_since_2000() {
99102
uint32_t cal;
100103
int64_t delta;
104+
uint32_t rtc_ticks;
101105

102106
system_rtc_mem_read(MEM_CAL_ADDR, &cal, sizeof(cal));
103107
system_rtc_mem_read(MEM_DELTA_ADDR, &delta, sizeof(delta));
104108

105-
return pyb_rtc_raw_us(cal) + delta;
109+
// ESP-SDK system_get_rtc_time() only returns uint32 and therefore
110+
// overflow about every 7:45h. Thus, we have to check for
111+
// overflow and handle it.
112+
rtc_ticks = system_get_rtc_time();
113+
if (rtc_ticks < rtc_last_ticks) {
114+
// Adjust delta because of RTC overflow.
115+
delta += (uint64_t)cal << 20;
116+
system_rtc_mem_write(MEM_DELTA_ADDR, &delta, sizeof(delta));
117+
}
118+
rtc_last_ticks = rtc_ticks;
119+
120+
return (((uint64_t)rtc_ticks * cal) >> 12) + delta;
106121
};
107122

108123
STATIC mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {

0 commit comments

Comments
 (0)
0