diff options
Diffstat (limited to 'esp8266/modpybrtc.c')
-rw-r--r-- | esp8266/modpybrtc.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/esp8266/modpybrtc.c b/esp8266/modpybrtc.c index e62dc8817..484d0d82f 100644 --- a/esp8266/modpybrtc.c +++ b/esp8266/modpybrtc.c @@ -53,6 +53,9 @@ STATIC const pyb_rtc_obj_t pyb_rtc_obj = {{&pyb_rtc_type}}; uint32_t pyb_rtc_alarm0_wake; // see MACHINE_WAKE_xxx constants uint64_t pyb_rtc_alarm0_expiry; // in microseconds +// RTC overflow checking +STATIC uint32_t rtc_last_ticks; + void mp_hal_rtc_init(void) { uint32_t magic; @@ -64,7 +67,11 @@ void mp_hal_rtc_init(void) { int64_t delta = 0; system_rtc_mem_write(MEM_CAL_ADDR, &cal, sizeof(cal)); system_rtc_mem_write(MEM_DELTA_ADDR, &delta, sizeof(delta)); + uint32_t len = 0; + system_rtc_mem_write(MEM_USER_LEN_ADDR, &len, sizeof(len)); } + // system_get_rtc_time() is always 0 after reset/deepsleep + rtc_last_ticks = system_get_rtc_time(); // reset ALARM0 state pyb_rtc_alarm0_wake = 0; @@ -79,13 +86,11 @@ STATIC mp_obj_t pyb_rtc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp return (mp_obj_t)&pyb_rtc_obj; } -STATIC uint64_t pyb_rtc_raw_us(uint64_t cal) { - return (system_get_rtc_time() * cal) >> 12; -}; - void pyb_rtc_set_us_since_2000(uint64_t nowus) { uint32_t cal = system_rtc_clock_cali_proc(); - int64_t delta = nowus - pyb_rtc_raw_us(cal); + // Save RTC ticks for overflow detection. + rtc_last_ticks = system_get_rtc_time(); + int64_t delta = nowus - (((uint64_t)rtc_last_ticks * cal) >> 12); // As the calibration value jitters quite a bit, to make the // clock at least somewhat practially usable, we need to store it @@ -96,11 +101,23 @@ void pyb_rtc_set_us_since_2000(uint64_t nowus) { uint64_t pyb_rtc_get_us_since_2000() { uint32_t cal; int64_t delta; + uint32_t rtc_ticks; system_rtc_mem_read(MEM_CAL_ADDR, &cal, sizeof(cal)); system_rtc_mem_read(MEM_DELTA_ADDR, &delta, sizeof(delta)); - return pyb_rtc_raw_us(cal) + delta; + // ESP-SDK system_get_rtc_time() only returns uint32 and therefore + // overflow about every 7:45h. Thus, we have to check for + // overflow and handle it. + rtc_ticks = system_get_rtc_time(); + if (rtc_ticks < rtc_last_ticks) { + // Adjust delta because of RTC overflow. + delta += (uint64_t)cal << 20; + system_rtc_mem_write(MEM_DELTA_ADDR, &delta, sizeof(delta)); + } + rtc_last_ticks = rtc_ticks; + + return (((uint64_t)rtc_ticks * cal) >> 12) + delta; }; STATIC mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) { @@ -145,20 +162,17 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_datetime_obj, 1, 2, pyb_rtc_d STATIC mp_obj_t pyb_rtc_memory(mp_uint_t n_args, const mp_obj_t *args) { uint8_t rtcram[MEM_USER_MAXLEN]; uint32_t len; - uint32_t magic; if (n_args == 1) { - - system_rtc_mem_read(MEM_USER_MAGIC_ADDR, &magic, sizeof(magic)); - if (magic != MEM_MAGIC) { - return mp_const_none; - } + // read RTC memory system_rtc_mem_read(MEM_USER_LEN_ADDR, &len, sizeof(len)); system_rtc_mem_read(MEM_USER_DATA_ADDR, rtcram, len + (4 - len % 4)); return mp_obj_new_bytes(rtcram, len); } else { + // write RTC memory + mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); @@ -167,8 +181,6 @@ STATIC mp_obj_t pyb_rtc_memory(mp_uint_t n_args, const mp_obj_t *args) { "buffer too long")); } - magic = MEM_MAGIC; - system_rtc_mem_write(MEM_USER_MAGIC_ADDR, &magic, sizeof(magic)); len = bufinfo.len; system_rtc_mem_write(MEM_USER_LEN_ADDR, &len, sizeof(len)); |