diff --git a/ports/esp8266/esp_mphal.c b/ports/esp8266/esp_mphal.c
index df97a73430235979fb8fdb8524bda4a341f2a79f..351bf522c82954074d111ee619b76c476aab6750 100644
--- a/ports/esp8266/esp_mphal.c
+++ b/ports/esp8266/esp_mphal.c
@@ -120,7 +120,9 @@ void mp_hal_debug_tx_strn_cooked(void *env, const char *str, uint32_t len) {
 }
 
 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 b724b8f14a18319c9f2636ca090eb48bca63bc73..0b1615d6580ea06ec5b895c0893ecb9b4a15883b 100644
--- a/ports/esp8266/ets_alt_task.c
+++ b/ports/esp8266/ets_alt_task.c
@@ -112,22 +112,27 @@ int ets_loop_iter_disable = 0;
 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;
 
-bool ets_loop_iter(void) {
-    if (ets_loop_iter_disable) {
-        return false;
-    }
-
-    // handle overflow of system microsecond counter
+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_prev) {
+    if (system_time_cur < system_time_low_word) {
         system_time_high_word += 1; // record overflow of low 32-bits
     }
-    system_time_prev = system_time_cur;
+    system_time_low_word = system_time_cur;
     ets_intr_unlock();
+}
+
+bool ets_loop_iter(void) {
+    if (ets_loop_iter_disable) {
+        return false;
+    }
+
+    // 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 e7a15c3ad57f5ec013d1a2e000bbcc475883e87b..7eb8ff3a548161156cdd70609b3dd7e37d651f0b 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