@@ -53,6 +53,9 @@ STATIC const pyb_rtc_obj_t pyb_rtc_obj = {{&pyb_rtc_type}};
5353uint32_t pyb_rtc_alarm0_wake ; // see MACHINE_WAKE_xxx constants
5454uint64_t pyb_rtc_alarm0_expiry ; // in microseconds
5555
56+ // RTC overflow checking
57+ STATIC uint32_t rtc_last_ticks ;
58+
5659void 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-
8889void 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) {
98101uint64_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
108123STATIC mp_obj_t pyb_rtc_datetime (mp_uint_t n_args , const mp_obj_t * args ) {
0 commit comments