diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2012-08-23 09:36:25 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-08-23 14:40:01 -0700 |
commit | a8402a53ea89e69ef6463a5a8bc033c42c163926 (patch) | |
tree | ccac59f561609a69f7815d01128833f7abf5f2ed | |
parent | 40cab432565239e6228082f6c59ad0cacb6cfe2f (diff) | |
download | chrome-ec-a8402a53ea89e69ef6463a5a8bc033c42c163926.tar.gz |
stm32: fix missed event on MSB hardware timer
When we set the TIM3 hardware timer match interrupt (used for 16-bit MSB
of the 32-bit microsecond counter), as the STM32 hardware block is not
triggering an interrupt on an exact match (only on the transition from
N-1 to match value N), we need to check whether the counter has been
incremented to the match value before we set the interrupt enable bit.
In that case, we simply fallback to the existing code to set the LSB
match interrupt.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BUG=chrome-os-partner:12715
TEST=use Snow board and see we are no longer getting EC watchdog in the
idle task.
BRANCH=snow
Change-Id: I4ceeb46425c799e328603ae0e99b678547d88fbe
Reviewed-on: https://gerrit.chromium.org/gerrit/31228
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: David Hendricks <dhendrix@chromium.org>
Commit-Ready: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | chip/stm32/hwtimer.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/chip/stm32/hwtimer.c b/chip/stm32/hwtimer.c index 1dbf2b5606..0fe2168f55 100644 --- a/chip/stm32/hwtimer.c +++ b/chip/stm32/hwtimer.c @@ -35,6 +35,23 @@ void __hw_clock_event_set(uint32_t deadline) { last_deadline = deadline; + if ((deadline >> 16) > STM32_TIM_CNT(3)) { + /* first set a match on the MSB */ + STM32_TIM_CCR1(3) = deadline >> 16; + /* disable LSB match */ + STM32_TIM_DIER(4) &= ~2; + /* Clear the match flags */ + STM32_TIM_SR(3) = ~2; + STM32_TIM_SR(4) = ~2; + /* Set the match interrupt */ + STM32_TIM_DIER(3) |= 2; + } + /* + * In the unlikely case where the MSB on TIM3 has increased and + * matched the deadline MSB before we set the match interrupt, + * as the STM hardware timer won't trigger an interrupt, we fall back + * to the following LSB event code to set another interrupt. + */ if ((deadline >> 16) == STM32_TIM_CNT(3)) { /* we can set a match on the LSB only */ STM32_TIM_CCR1(4) = deadline & 0xffff; @@ -45,17 +62,13 @@ void __hw_clock_event_set(uint32_t deadline) STM32_TIM_SR(4) = ~2; /* Set the match interrupt */ STM32_TIM_DIER(4) |= 2; - } else if ((deadline >> 16) > STM32_TIM_CNT(3)) { - /* first set a match on the MSB */ - STM32_TIM_CCR1(3) = deadline >> 16; - /* disable LSB match */ - STM32_TIM_DIER(4) &= ~2; - /* Clear the match flags */ - STM32_TIM_SR(3) = ~2; - STM32_TIM_SR(4) = ~2; - /* Set the match interrupt */ - STM32_TIM_DIER(3) |= 2; } + /* + * if the LSB deadline is already in the past and won't trigger + * an interrupt, the common code in process_timers will deal with + * the expired timer and automatically set the next deadline, we + * don't need to do anything here. + */ } uint32_t __hw_clock_event_get(void) |