From 5357dad52efbe5773f4beda7ad014dc62ad8e44f Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 22 May 2019 15:05:03 +1000 Subject: [PATCH] esp8266: Fix ticks_ms to correctly handle wraparound of system counter. Fixes issue #4795. --- ports/esp8266/esp_mphal.c | 4 +++- ports/esp8266/ets_alt_task.c | 23 ++++++++++++++--------- ports/esp8266/ets_alt_task.h | 2 ++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/ports/esp8266/esp_mphal.c b/ports/esp8266/esp_mphal.c index df97a73430..351bf522c8 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 b724b8f14a..0b1615d658 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; +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 e7a15c3ad5..7eb8ff3a54 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