diff options
author | Alec Berg <alecaberg@chromium.org> | 2014-10-31 09:20:46 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-11-18 05:20:46 +0000 |
commit | 7e7e82f2c1855a46f4cba2d4f08e4f8c2e842a5c (patch) | |
tree | f9129e383b9b83b3f70a090dd6b468f01cc58465 /board/zinger/runtime.c | |
parent | d64324ad4d2211f9326dbaaed873c66c390f6f5b (diff) | |
download | chrome-ec-7e7e82f2c1855a46f4cba2d4f08e4f8c2e842a5c.tar.gz |
zinger: fix task_wait_event() to only exit on event received
Fix task_wait_event() so that it only wakes when an event is received
or on timeout. Currently it wakes up on any interrupt, which can cause
subtle timing issues with PD communication.
BUG=none
BRANCH=samus
TEST=load onto samus, see it negotiate for 20V a few times
Change-Id: Ia1268a1ac902433433949269d779ef11403eeae3
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/226811
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'board/zinger/runtime.c')
-rw-r--r-- | board/zinger/runtime.c | 72 |
1 files changed, 45 insertions, 27 deletions
diff --git a/board/zinger/runtime.c b/board/zinger/runtime.c index 407daa5c54..d07139dbaf 100644 --- a/board/zinger/runtime.c +++ b/board/zinger/runtime.c @@ -117,10 +117,12 @@ void runtime_init(void) uint32_t task_wait_event(int timeout_us) { uint32_t evt; - timestamp_t t0; + timestamp_t t0, t1; uint32_t rtc0, rtc0ss, rtc1, rtc1ss; int rtc_diff; + t1.val = get_time().val + timeout_us; + asm volatile("cpsid i"); /* the event already happened */ if (last_event || !timeout_us) { @@ -131,42 +133,58 @@ uint32_t task_wait_event(int timeout_us) return evt; } - /* set timeout on timer */ - if (timeout_us < 0) { - asm volatile ("wfi"); - } else if (timeout_us <= (STOP_MODE_LATENCY + SET_RTC_MATCH_DELAY)) { - 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 */ + /* loop until an event is triggered */ + while (1) { + /* set timeout on timer */ + if (timeout_us < 0) { + asm volatile ("wfi"); + } else if (timeout_us <= + (STOP_MODE_LATENCY + SET_RTC_MATCH_DELAY)) { + 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 */ - asm volatile("wfi"); + asm volatile("wfi"); - STM32_TIM_DIER(2) = 0; /* disable match interrupt */ - } else { - t0 = get_time(); + STM32_TIM_DIER(2) = 0; /* disable match interrupt */ + } else { + t0 = get_time(); - /* set deep sleep bit */ - CPU_SCB_SYSCTRL |= 0x4; + /* set deep sleep bit */ + CPU_SCB_SYSCTRL |= 0x4; - set_rtc_alarm(0, timeout_us - STOP_MODE_LATENCY, - &rtc0, &rtc0ss); + set_rtc_alarm(0, timeout_us - STOP_MODE_LATENCY, + &rtc0, &rtc0ss); - asm volatile("wfi"); + asm volatile("wfi"); - CPU_SCB_SYSCTRL &= ~0x4; + CPU_SCB_SYSCTRL &= ~0x4; - config_hispeed_clock(); + config_hispeed_clock(); - /* fast forward timer according to RTC counter */ - reset_rtc_alarm(&rtc1, &rtc1ss); - rtc_diff = get_rtc_diff(rtc0, rtc0ss, rtc1, rtc1ss); - t0.val = t0.val + rtc_diff; - force_time(t0); - } + /* fast forward timer according to RTC counter */ + reset_rtc_alarm(&rtc1, &rtc1ss); + rtc_diff = get_rtc_diff(rtc0, rtc0ss, rtc1, rtc1ss); + t0.val = t0.val + rtc_diff; + force_time(t0); + } - asm volatile("cpsie i ; isb"); + asm volatile("cpsie i ; isb"); + /* note: interrupt that woke us up will run here */ - /* note: interrupt that woke us up will run here */ + t0 = get_time(); + /* check for timeout if timeout was set */ + if (timeout_us >= 0 && t0.val >= t1.val) + last_event = TASK_EVENT_TIMER; + /* break from loop when event has triggered */ + if (last_event) + break; + /* recalculate timeout if timeout was set */ + if (timeout_us >= 0) + timeout_us = t1.val - t0.val; + + asm volatile("cpsid i"); + } evt = last_event; last_event = 0; |