diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2015-01-02 09:41:34 -0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-01-03 17:13:18 +0000 |
commit | c268f2eee300bb56adcf8ff942325469a936a5d6 (patch) | |
tree | 750d5897d40849569948932f04ed5876ee4fa512 /board/zinger | |
parent | 1f55eea80994538350588eb27dce0ee791144e2e (diff) | |
download | chrome-ec-c268f2eee300bb56adcf8ff942325469a936a5d6.tar.gz |
zinger: maintain a 64-bit time counter
Keep track of the high 32-bit of the microsecond time counter to avoid
rollback issues.
Just activate the timer "update" interrupt (aka UIE) and increment the
high word on every update interrupt.
Also disable STOP mode when we are going to roll-over during sleep to
avoid missing the event. Given that's only happening every hour, we
should not waste too much power.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=samus
BUG=chrome-os-partner:34159
TEST=patch the code to set the initial TIM2 value to 0xFC000000,
wait for 67s, see the counter rolling and the high word incrementing,
then verify that Zinger is still functional.
Change-Id: I3a2f8fc09104d8ac75c581b2abcbcef99344def7
Reviewed-on: https://chromium-review.googlesource.com/238220
Trybot-Ready: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'board/zinger')
-rw-r--r-- | board/zinger/hardware.c | 5 | ||||
-rw-r--r-- | board/zinger/runtime.c | 28 |
2 files changed, 23 insertions, 10 deletions
diff --git a/board/zinger/hardware.c b/board/zinger/hardware.c index 54a92aaccd..1713ca342e 100644 --- a/board/zinger/hardware.c +++ b/board/zinger/hardware.c @@ -146,11 +146,12 @@ static void timers_init(void) /* TIM2 is a 32-bit free running counter with 1Mhz frequency */ STM32_TIM_CR2(2) = 0x0000; STM32_TIM32_ARR(2) = 0xFFFFFFFF; - STM32_TIM32_CNT(2) = 0; STM32_TIM_PSC(2) = CPU_CLOCK / 1000000 - 1; STM32_TIM_EGR(2) = 0x0001; /* Reload the pre-scaler */ STM32_TIM_CR1(2) = 1; - STM32_TIM_DIER(2) = 0; + STM32_TIM32_CNT(2) = 0x00000000; + STM32_TIM_SR(2) = 0; /* Clear pending interrupts */ + STM32_TIM_DIER(2) = 1; /* Overflow interrupt */ task_enable_irq(STM32_IRQ_TIM2); } diff --git a/board/zinger/runtime.c b/board/zinger/runtime.c index 186480f3e9..9d644e763a 100644 --- a/board/zinger/runtime.c +++ b/board/zinger/runtime.c @@ -17,12 +17,15 @@ volatile uint32_t last_event; uint32_t sleep_mask; +/* High word of the 64-bit timestamp counter */ +static volatile uint32_t clksrc_high; + timestamp_t get_time(void) { timestamp_t t; t.le.lo = STM32_TIM32_CNT(2); - t.le.hi = 0; + t.le.hi = clksrc_high; return t; } @@ -62,9 +65,18 @@ uint32_t task_set_event(task_id_t tskid, uint32_t event, int wait) void tim2_interrupt(void) { - STM32_TIM_DIER(2) = 0; /* disable match interrupt */ + uint32_t stat = STM32_TIM_SR(2); + + if (stat & 2) { /* Event match */ + /* disable match interrupt but keep update interrupt */ + STM32_TIM_DIER(2) = 1; + last_event = TASK_EVENT_TIMER; + } + if (stat & 1) /* Counter overflow */ + clksrc_high++; + + STM32_TIM_SR(2) = ~stat & 3; /* clear interrupt flags */ task_clear_pending_irq(STM32_IRQ_TIM2); - last_event = TASK_EVENT_TIMER; } DECLARE_IRQ(STM32_IRQ_TIM2, tim2_interrupt, 1); @@ -115,6 +127,7 @@ void runtime_init(void) */ #define STOP_MODE_LATENCY 300 /* us */ #define SET_RTC_MATCH_DELAY 200 /* us */ +#define MAX_LATENCY (STOP_MODE_LATENCY + SET_RTC_MATCH_DELAY) uint32_t task_wait_event(int timeout_us) { @@ -140,16 +153,15 @@ uint32_t task_wait_event(int timeout_us) /* set timeout on timer */ if (timeout_us < 0) { asm volatile ("wfi"); - } else if (timeout_us <= - (STOP_MODE_LATENCY + SET_RTC_MATCH_DELAY) || + } else if (timeout_us <= MAX_LATENCY || + t1.le.lo - timeout_us > t1.le.lo + MAX_LATENCY || !DEEP_SLEEP_ALLOWED) { STM32_TIM32_CCR1(2) = STM32_TIM32_CNT(2) + timeout_us; - STM32_TIM_SR(2) = 0; /* clear match flag */ - STM32_TIM_DIER(2) = 2; /* match interrupt */ + STM32_TIM_DIER(2) = 3; /* match interrupt and UIE */ asm volatile("wfi"); - STM32_TIM_DIER(2) = 0; /* disable match interrupt */ + STM32_TIM_DIER(2) = 1; /* disable match, keep UIE */ } else { t0 = get_time(); |