summaryrefslogtreecommitdiff
path: root/esp8266/modpybrtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'esp8266/modpybrtc.c')
-rw-r--r--esp8266/modpybrtc.c40
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));