esp8266: Fix ticks_ms to correctly handle wraparound of system counter.
Fixes issue #4795.
diff --git a/ports/esp8266/esp_mphal.c b/ports/esp8266/esp_mphal.c
index df97a73..351bf52 100644
--- a/ports/esp8266/esp_mphal.c
+++ b/ports/esp8266/esp_mphal.c
@@ -120,7 +120,9 @@
}
uint32_t mp_hal_ticks_ms(void) {
- return ((uint64_t)system_time_high_word << 32 | (uint64_t)system_get_time()) / 1000;
+ // Compute milliseconds from 64-bit microsecond counter
+ system_time_update();
+ return ((uint64_t)system_time_high_word << 32 | (uint64_t)system_time_low_word) / 1000;
}
uint32_t mp_hal_ticks_us(void) {
diff --git a/ports/esp8266/ets_alt_task.c b/ports/esp8266/ets_alt_task.c
index b724b8f..0b1615d 100644
--- a/ports/esp8266/ets_alt_task.c
+++ b/ports/esp8266/ets_alt_task.c
@@ -112,22 +112,27 @@
int ets_loop_dont_feed_sw_wdt = 0;
// to implement a 64-bit wide microsecond counter
-static uint32_t system_time_prev = 0;
+uint32_t system_time_low_word = 0;
uint32_t system_time_high_word = 0;
+void system_time_update(void) {
+ // Handle overflow of system microsecond counter
+ ets_intr_lock();
+ uint32_t system_time_cur = system_get_time();
+ if (system_time_cur < system_time_low_word) {
+ system_time_high_word += 1; // record overflow of low 32-bits
+ }
+ system_time_low_word = system_time_cur;
+ ets_intr_unlock();
+}
+
bool ets_loop_iter(void) {
if (ets_loop_iter_disable) {
return false;
}
- // handle overflow of system microsecond counter
- ets_intr_lock();
- uint32_t system_time_cur = system_get_time();
- if (system_time_cur < system_time_prev) {
- system_time_high_word += 1; // record overflow of low 32-bits
- }
- system_time_prev = system_time_cur;
- ets_intr_unlock();
+ // Update 64-bit microsecond counter
+ system_time_update();
// 6 words before pend_flag_noise_check is a variable that is used by
// the software WDT. A 1.6 second period timer will increment this
diff --git a/ports/esp8266/ets_alt_task.h b/ports/esp8266/ets_alt_task.h
index e7a15c3..7eb8ff3 100644
--- a/ports/esp8266/ets_alt_task.h
+++ b/ports/esp8266/ets_alt_task.h
@@ -3,8 +3,10 @@
extern int ets_loop_iter_disable;
extern int ets_loop_dont_feed_sw_wdt;
+extern uint32_t system_time_low_word;
extern uint32_t system_time_high_word;
+void system_time_update(void);
bool ets_loop_iter(void);
#endif // MICROPY_INCLUDED_ESP8266_ETS_ALT_TASK_H