summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2012-08-23 09:36:25 -0700
committerGerrit <chrome-bot@google.com>2012-08-23 14:40:01 -0700
commita8402a53ea89e69ef6463a5a8bc033c42c163926 (patch)
treeccac59f561609a69f7815d01128833f7abf5f2ed
parent40cab432565239e6228082f6c59ad0cacb6cfe2f (diff)
downloadchrome-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.c33
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)