From de915a034bffc8d1612a742fdb2e683f06fcacc0 Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Wed, 29 Jan 2020 15:28:20 +0200 Subject: [PATCH] Correct SysTimer absolute time calculations `SysTimer::set_wake_time` incorrectly assumed that the `SysTimer`s tick count and the underlying HAL timer had the same zero base. This normally holds, at least approximately, in RTOS builds where the HAL timer starts from zero at the same time the SysTimer is initialised. But in bare metal builds, the HAL timer could be started some time before the SysTimer, giving a significant discrepancy. Beyond that, there's no requirement for HAL timers to start from zero in the spec. Record the HAL timer start time to get the conversion right. --- platform/source/SysTimer.cpp | 8 +++++--- platform/source/SysTimer.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/source/SysTimer.cpp b/platform/source/SysTimer.cpp index 0803849e25..1513a30169 100644 --- a/platform/source/SysTimer.cpp +++ b/platform/source/SysTimer.cpp @@ -52,7 +52,8 @@ SysTimer::SysTimer() : #else TimerEvent(get_us_ticker_data()), #endif - _time_us(ticker_read_us(_ticker_data)), + _epoch(ticker_read_us(_ticker_data)), + _time_us(_epoch), _tick(0), _unacknowledged_ticks(0), _wake_time_set(false), @@ -66,7 +67,8 @@ SysTimer::SysTimer() : template SysTimer::SysTimer(const ticker_data_t *data) : TimerEvent(data), - _time_us(ticker_read_us(_ticker_data)), + _epoch(ticker_read_us(_ticker_data)), + _time_us(_epoch), _tick(0), _unacknowledged_ticks(0), _wake_time_set(false), @@ -104,7 +106,7 @@ void SysTimer::set_wake_time(uint64_t at) } uint64_t ticks_to_sleep = at - _tick; - uint64_t wake_time = at * US_IN_TICK; + uint64_t wake_time = _epoch + at * US_IN_TICK; /* Set this first, before attaching the interrupt that can unset it */ _wake_time_set = true; diff --git a/platform/source/SysTimer.h b/platform/source/SysTimer.h index 8149f66d78..e285c600ec 100644 --- a/platform/source/SysTimer.h +++ b/platform/source/SysTimer.h @@ -225,6 +225,7 @@ protected: uint64_t _elapsed_ticks() const; static void _set_irq_pending(); static void _clear_irq_pending(); + const us_timestamp_t _epoch; us_timestamp_t _time_us; uint64_t _tick; uint8_t _unacknowledged_ticks;