From ee12581a3545c6e950b4a2b5322167eb73326928 Mon Sep 17 00:00:00 2001 From: puuu Date: Sat, 4 Jun 2016 00:21:26 +0900 Subject: [PATCH] esp8266: Let RTC work correctly after deepsleep. By design, at wake up from deepsleep, the RTC timer will be reset, but the data stored in RTC memory will not [1]. Therefore, we have to adjust delta in RTC memory before going into deepsleep to get almost correct time after waking up. [1] http://bbs.espressif.com/viewtopic.php?t=1184#p4082 --- esp8266/modesp.c | 6 +++++- esp8266/modmachine.c | 2 ++ esp8266/modpybrtc.c | 6 ++++++ esp8266/modpybrtc.h | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/esp8266/modesp.c b/esp8266/modesp.c index 0c6cc423e1..99f063a756 100644 --- a/esp8266/modesp.c +++ b/esp8266/modesp.c @@ -46,6 +46,7 @@ #include "espneopixel.h" #include "espapa102.h" #include "modpyb.h" +#include "modpybrtc.h" #define MODESP_ESPCONN (0) @@ -540,8 +541,11 @@ STATIC mp_obj_t esp_sleep_type(mp_uint_t n_args, const mp_obj_t *args) { STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_sleep_type_obj, 0, 1, esp_sleep_type); STATIC mp_obj_t esp_deepsleep(mp_uint_t n_args, const mp_obj_t *args) { + uint32_t sleep_us = n_args > 0 ? mp_obj_get_int(args[0]) : 0; + // prepare for RTC reset at wake up + rtc_prepare_deepsleep(sleep_us); system_deep_sleep_set_option(n_args > 1 ? mp_obj_get_int(args[1]) : 0); - system_deep_sleep(n_args > 0 ? mp_obj_get_int(args[0]) : 0); + system_deep_sleep(sleep_us); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_deepsleep_obj, 0, 2, esp_deepsleep); diff --git a/esp8266/modmachine.c b/esp8266/modmachine.c index 36872c9dff..80ae7ac2a0 100644 --- a/esp8266/modmachine.c +++ b/esp8266/modmachine.c @@ -103,6 +103,8 @@ STATIC mp_obj_t machine_deepsleep(void) { } } + // prepare for RTC reset at wake up + rtc_prepare_deepsleep(sleep_us); // put the device in a deep-sleep state system_deep_sleep_set_option(0); // default power down mode; TODO check this system_deep_sleep(sleep_us); diff --git a/esp8266/modpybrtc.c b/esp8266/modpybrtc.c index 484d0d82fd..9685248034 100644 --- a/esp8266/modpybrtc.c +++ b/esp8266/modpybrtc.c @@ -120,6 +120,12 @@ uint64_t pyb_rtc_get_us_since_2000() { return (((uint64_t)rtc_ticks * cal) >> 12) + delta; }; +void rtc_prepare_deepsleep(uint64_t sleep_us) { + // RTC time will reset at wake up. Let's be preared for this. + int64_t delta = pyb_rtc_get_us_since_2000() + sleep_us; + system_rtc_mem_write(MEM_DELTA_ADDR, &delta, sizeof(delta)); +} + STATIC mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) { if (n_args == 1) { // Get time diff --git a/esp8266/modpybrtc.h b/esp8266/modpybrtc.h index b4ca780712..5b9d9fc766 100644 --- a/esp8266/modpybrtc.h +++ b/esp8266/modpybrtc.h @@ -30,3 +30,5 @@ extern uint64_t pyb_rtc_alarm0_expiry; void pyb_rtc_set_us_since_2000(uint64_t nowus); uint64_t pyb_rtc_get_us_since_2000(); + +void rtc_prepare_deepsleep(uint64_t sleep_us);