From a6c2c52fb21d94c1dcf43d1c14234e12221f1d26 Mon Sep 17 00:00:00 2001 From: Hyungsin Date: Thu, 4 Jan 2018 17:45:23 -0800 Subject: [PATCH] properly sync different timers --- cpu/samd21/periph/pm.c | 2 ++ sys/include/xtimer/implementation.h | 33 ++++++++++++++++++----------- sys/xtimer/xtimer_core.c | 8 +++++++ 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/cpu/samd21/periph/pm.c b/cpu/samd21/periph/pm.c index e99babfbf5a6..4577278c64cc 100644 --- a/cpu/samd21/periph/pm.c +++ b/cpu/samd21/periph/pm.c @@ -24,6 +24,7 @@ */ #include "periph/pm.h" +#include "xtimer.h" #define ENABLE_DEBUG (0) #include "debug.h" @@ -61,6 +62,7 @@ void pm_set(unsigned mode) * Potential Wake Up sources: asynchronous */ deep = 1; + xtimer_sync = false; break; case 1: /* Sleep mode Idle 2 diff --git a/sys/include/xtimer/implementation.h b/sys/include/xtimer/implementation.h index f9bc40bfbba7..15ff7529a4a6 100644 --- a/sys/include/xtimer/implementation.h +++ b/sys/include/xtimer/implementation.h @@ -36,6 +36,7 @@ extern volatile uint32_t _xtimer_high_cnt; #if (XTIMER_HZ < 1000000ul) && (STIMER_HZ >= 1000000ul) extern volatile uint32_t prev_s; extern volatile uint32_t prev_x; +extern volatile bool xtimer_sync; #endif @@ -123,19 +124,26 @@ static inline uint32_t _xtimer_now(void) return latched_high_cnt | now; #else #if (XTIMER_HZ < 1000000ul) && (STIMER_HZ >= 1000000ul) - uint64_t diff_s; - uint32_t now_s; + if (!xtimer_sync) { + prev_x = _xtimer_lltimer_now(); + prev_s = _stimer_lltimer_now(); + xtimer_sync = true; + return prev_x; + } else { + uint64_t diff_s; + uint32_t now_s; - do { - now_s = _stimer_lltimer_now(); - if (now_s >= prev_s) { - diff_s = now_s - prev_s; - } else { - diff_s = (0xFFFFFFFF-prev_s) + now_s; - } - } while (diff_s < STIMER_HZ/XTIMER_HZ); - - return _xtimer_lltimer_mask(prev_x + (uint32_t)(diff_s*XTIMER_HZ/STIMER_HZ)); + do { + now_s = _stimer_lltimer_now(); + if (now_s >= prev_s) { + diff_s = now_s - prev_s; + } else { + diff_s = (0xFFFFFFFF-prev_s) + now_s; + } + } while (diff_s < STIMER_HZ/XTIMER_HZ); + + return _xtimer_lltimer_mask(prev_x + (uint32_t)(diff_s*XTIMER_HZ/STIMER_HZ)); + } #else return _xtimer_lltimer_now(); #endif @@ -177,6 +185,7 @@ static inline void _xtimer_spin(uint32_t offset) { #if (XTIMER_HZ < 1000000ul) && (STIMER_HZ >= 1000000ul) prev_x = _xtimer_lltimer_now(); prev_s = _stimer_lltimer_now(); + xtimer_sync = true; #endif } diff --git a/sys/xtimer/xtimer_core.c b/sys/xtimer/xtimer_core.c index 0271d5c422a6..653ba0f52617 100644 --- a/sys/xtimer/xtimer_core.c +++ b/sys/xtimer/xtimer_core.c @@ -39,6 +39,7 @@ volatile uint32_t _xtimer_high_cnt = 0; #if (XTIMER_HZ < 1000000ul) && (STIMER_HZ >= 1000000ul) volatile uint32_t prev_s = 0xffffffff; volatile uint32_t prev_x = 0xffffffff; +volatile bool xtimer_sync = false; #endif static inline void xtimer_spin_until(uint32_t value); @@ -73,6 +74,7 @@ static inline void xtimer_spin_until(uint32_t target) { #if (XTIMER_HZ < 1000000ul) && (STIMER_HZ >= 1000000ul) prev_s = _stimer_lltimer_now(); prev_x = _xtimer_lltimer_now(); + xtimer_sync = true; #endif } @@ -88,6 +90,7 @@ void xtimer_init(void) timer_init(STIMER_DEV, STIMER_HZ, _periph_timer_callback, NULL); prev_s = _stimer_lltimer_now(); prev_x = _xtimer_lltimer_now(); + xtimer_sync = true; #endif /* register initial overflow tick */ _lltimer_set(0xFFFFFFFF); @@ -511,6 +514,7 @@ static void _timer_callback(void) now = reference; #if (XTIMER_HZ < 1000000ul) && (STIMER_HZ >= 1000000ul) prev_x = now; + xtimer_sync = true; #endif overflow: @@ -570,6 +574,7 @@ static void _timer_callback(void) now = _xtimer_lltimer_now(); #if (XTIMER_HZ < 1000000ul) && (STIMER_HZ >= 1000000ul) prev_x = now; + xtimer_sync = true; #endif goto overflow; } @@ -586,6 +591,7 @@ static void _timer_callback(void) now = _xtimer_lltimer_now(); #if (XTIMER_HZ < 1000000ul) && (STIMER_HZ >= 1000000ul) prev_x = now; + xtimer_sync = true; #endif goto overflow; } @@ -614,6 +620,7 @@ static void _timer_callback(void) now = _xtimer_lltimer_now(); #if (XTIMER_HZ < 1000000ul) && (STIMER_HZ >= 1000000ul) prev_x = now; + xtimer_sync = true; #endif goto overflow; } @@ -630,6 +637,7 @@ static void _timer_callback(void) now = _xtimer_lltimer_now(); #if (XTIMER_HZ < 1000000ul) && (STIMER_HZ >= 1000000ul) prev_x = now; + xtimer_sync = true; #endif goto overflow; }