From 752e952096815adc2e418967e4b056680924a584 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 1 Jun 2016 11:33:04 +0100 Subject: esp8266/rtc: Set RTC user memory length to 0 on first boot. So that RTC.memory() returns b'' on power up if it was never set. Fixes issue #2138. --- esp8266/modpybrtc.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'esp8266/modpybrtc.c') diff --git a/esp8266/modpybrtc.c b/esp8266/modpybrtc.c index e62dc88175..4fdd5367d8 100644 --- a/esp8266/modpybrtc.c +++ b/esp8266/modpybrtc.c @@ -64,6 +64,8 @@ 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)); } // reset ALARM0 state @@ -145,20 +147,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 +166,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)); -- cgit v1.2.3 From cafdfb7af3628aac5110770097b6cb4fdd70b9d5 Mon Sep 17 00:00:00 2001 From: puuu Date: Tue, 24 May 2016 22:31:50 +0900 Subject: 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. --- esp8266/modpybrtc.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'esp8266/modpybrtc.c') diff --git a/esp8266/modpybrtc.c b/esp8266/modpybrtc.c index 4fdd5367d8..484d0d82fd 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; @@ -67,6 +70,8 @@ void mp_hal_rtc_init(void) { 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; @@ -81,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 @@ -98,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) { -- cgit v1.2.3