diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index 0264aeac0..cc3525015 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -202,6 +202,7 @@ void analogWriteRange(uint32_t range); unsigned long millis(void); unsigned long micros(void); +uint64_t micros64(void); void delay(unsigned long); void delayMicroseconds(unsigned int us); unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); diff --git a/cores/esp8266/core_esp8266_wiring.c b/cores/esp8266/core_esp8266_wiring.c index fbbb5bfcf..4b55a711e 100644 --- a/cores/esp8266/core_esp8266_wiring.c +++ b/cores/esp8266/core_esp8266_wiring.c @@ -71,6 +71,13 @@ unsigned long ICACHE_RAM_ATTR micros() { return system_get_time(); } +uint64_t ICACHE_RAM_ATTR micros64() { + uint32_t low32_us = system_get_time(); + uint32_t high32_us = micros_overflow_count + ((low32_us < micros_at_last_overflow_tick) ? 1 : 0); + uint64_t duration64_us = (uint64_t)high32_us << 32 | low32_us; + return duration64_us; +} + void ICACHE_RAM_ATTR delayMicroseconds(unsigned int us) { os_delay_us(us); } diff --git a/cores/esp8266/time.c b/cores/esp8266/time.c index 1c2fc719a..27f6640ca 100644 --- a/cores/esp8266/time.c +++ b/cores/esp8266/time.c @@ -31,23 +31,27 @@ struct timeval { extern char* sntp_asctime(const struct tm *t); extern struct tm* sntp_localtime(const time_t *clock); +extern uint64_t micros64(); // time gap in seconds from 01.01.1900 (NTP time) to 01.01.1970 (UNIX time) #define DIFF1900TO1970 2208988800UL static int s_daylightOffset_sec = 0; static long s_timezone_sec = 0; -static time_t s_bootTime = 0; +static bool s_bootTimeSet = false; +static uint64_t s_bootTime_us = 0; // calculate offset used in gettimeofday static void ensureBootTimeIsSet() { - if (!s_bootTime) + // Check just a bool flag instead of the full 64-bit s_bootTime for zero. + if (!s_bootTimeSet) { - time_t now = sntp_get_current_timestamp(); - if (now) + time_t now_s = sntp_get_current_timestamp(); + if (now_s) { - s_bootTime = now - millis() / 1000; + s_bootTime_us = now_s * 1000000ULL - micros64(); + s_bootTimeSet = true; } } } @@ -100,8 +104,9 @@ int _gettimeofday_r(struct _reent* unused, struct timeval *tp, void *tzp) if (tp) { ensureBootTimeIsSet(); - tp->tv_sec = s_bootTime + millis() / 1000; - tp->tv_usec = micros(); + uint64_t currentTime_us = s_bootTime_us + micros64(); + tp->tv_sec = currentTime_us / 1000000ULL; + tp->tv_usec = currentTime_us % 1000000ULL; } return 0; }