summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Hughes <tomhughes@chromium.org>2022-01-13 13:08:23 -0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-11-10 22:44:10 +0000
commit74a8b26c76919744b930d2916d15258f7c5842f7 (patch)
treec4ea860b0922ed736302fb7e3ad0103e71d66655
parent03618e96ace3e95563af9476399b8f1f13266935 (diff)
downloadchrome-ec-74a8b26c76919744b930d2916d15258f7c5842f7.tar.gz
tree: Remove stm32/hwtimer.c
stm32/hwtimer.c simulates a 32-bit timer with two 16-bit timers. The only boards still using this file were "discovery" and "twinkie". "twinkie" is an STM32F072B, which has support for 32-bit timers (TIM2 and TIM3). See Section 18 "General-purpose Timers": https://www.st.com/resource/en/reference_manual/dm00031936-stm32f0x1-stm32f0x2-stm32f0x8-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf. "discovery" is an STM32L152RC, which is a "Category 3" product that has the 32-bit timer TIM5. See Section 17 "General-purpose Timers" and "Table 3. STM32L15xxx product categories": https://www.st.com/resource/en/reference_manual/cd00240193-stm32l100xx-stm32l151xx-stm32l152xx-and-stm32l162xx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf. BRANCH=none BUG=b:214423235 TEST=make buildall -j Signed-off-by: Tom Hughes <tomhughes@chromium.org> Change-Id: I41b3a54bbbbce5d0dfee178b6fa87ff492646ce1 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3388064 Reviewed-by: Patryk Duda <patrykd@google.com> Reviewed-by: Abe Levkoy <alevkoy@chromium.org> Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com>
-rw-r--r--board/discovery/board.h13
-rw-r--r--board/twinkie/board.h5
-rw-r--r--chip/stm32/config-stm32l15x.h15
-rw-r--r--chip/stm32/hwtimer.c481
4 files changed, 26 insertions, 488 deletions
diff --git a/board/discovery/board.h b/board/discovery/board.h
index e348454af1..0abb329285 100644
--- a/board/discovery/board.h
+++ b/board/discovery/board.h
@@ -17,6 +17,8 @@
#define CONFIG_STREAM_USART2
#define CONFIG_CMD_USART_INFO
+#define CONFIG_STM_HWTIMER32
+
/*
* Allow dangerous commands all the time, since we don't have a write protect
* switch.
@@ -25,9 +27,14 @@
#ifndef __ASSEMBLER__
-/* Timer selection */
-#define TIM_CLOCK_MSB 3
-#define TIM_CLOCK_LSB 4
+/* Timer selection
+ *
+ * "discovery" is an STM32L152RC, which is a "Category 3" product that
+ * has the 32-bit timer TIM5. See Section 17 "General-purpose Timers" and
+ * "Table 3. STM32L15xxx product categories":
+ * https://www.st.com/resource/en/reference_manual/cd00240193-stm32l100xx-stm32l151xx-stm32l152xx-and-stm32l162xx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf
+ */
+#define TIM_CLOCK32 5
#include "gpio_signal.h"
diff --git a/board/twinkie/board.h b/board/twinkie/board.h
index b1379fb15b..96aff32051 100644
--- a/board/twinkie/board.h
+++ b/board/twinkie/board.h
@@ -79,8 +79,7 @@ void trace_packets(void);
void set_trace_mode(int mode);
/* Timer selection */
-#define TIM_CLOCK_MSB 3
-#define TIM_CLOCK_LSB 15
+#define TIM_CLOCK32 2
#define TIM_ADC 16
#include "gpio_signal.h"
@@ -105,6 +104,8 @@ enum usb_strings {
USB_STR_COUNT
};
+#define CONFIG_STM_HWTIMER32
+
/* Standard-current Rp */
#define PD_SRC_VNC PD_SRC_DEF_VNC_MV
#define PD_SRC_RD_THRESHOLD PD_SRC_DEF_RD_THRESH_MV
diff --git a/chip/stm32/config-stm32l15x.h b/chip/stm32/config-stm32l15x.h
index ae069ed005..d35b3ccbcf 100644
--- a/chip/stm32/config-stm32l15x.h
+++ b/chip/stm32/config-stm32l15x.h
@@ -24,8 +24,19 @@
#define CONFIG_RAM_BASE 0x20000000
#define CONFIG_RAM_SIZE 0x00004000
-/* Number of IRQ vectors on the NVIC */
-#define CONFIG_IRQ_COUNT 45
+/* Number of IRQ vectors on the NVIC
+ *
+ * Section 10.1 "Nested vectored interrupt controller (NVIC)" states:
+ * 45 maskable interrupt channels in Cat.1 and Cat.2 devices (see Table 49)
+ * 54 maskable interrupt channels in Cat.3 devices (see Table 50) and 57
+ * channels in Cat.4, Cat.5 and Cat.6 devices (see Table 51).
+ *
+ * The only STM32L15 that we support is the "discovery" board is a "Category
+ * 3" device. See Section 1.5 "Product Category definition".
+ *
+ * https://www.st.com/resource/en/reference_manual/cd00240193-stm32l100xx-stm32l151xx-stm32l152xx-and-stm32l162xx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf
+ */
+#define CONFIG_IRQ_COUNT 54
/* Lots of RAM, so use bigger UART buffer */
#undef CONFIG_UART_TX_BUF_SIZE
diff --git a/chip/stm32/hwtimer.c b/chip/stm32/hwtimer.c
deleted file mode 100644
index 3521347f3f..0000000000
--- a/chip/stm32/hwtimer.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/* Copyright 2012 The ChromiumOS Authors
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Hardware timers driver */
-
-#include "builtin/assert.h"
-#include "clock.h"
-#include "clock-f.h"
-#include "common.h"
-#include "hooks.h"
-#include "hwtimer.h"
-#include "panic.h"
-#include "registers.h"
-#include "task.h"
-#include "timer.h"
-#include "watchdog.h"
-
-/*
- * Trigger select mapping for secondary timer from primary timer. This is
- * unfortunately not very straightforward; there's no tidy way to do this
- * algorithmically. To avoid burning memory for a lookup table, use macros to
- * compute the offset. This also has the benefit that compilation will fail if
- * an unsupported primary/secondary pairing is used.
- */
-#ifdef CHIP_FAMILY_STM32F0
-/*
- * Secondary Primary
- * 1 15 2 3 17
- * 2 1 15 3 14
- * 3 1 2 15 14
- * 15 2 3 16 17
- * --------------------
- * ts = 0 1 2 3
- */
-#define STM32_TIM_TS_SECONDARY_1_PRIMARY_15 0
-#define STM32_TIM_TS_SECONDARY_1_PRIMARY_2 1
-#define STM32_TIM_TS_SECONDARY_1_PRIMARY_3 2
-#define STM32_TIM_TS_SECONDARY_1_PRIMARY_17 3
-#define STM32_TIM_TS_SECONDARY_2_PRIMARY_1 0
-#define STM32_TIM_TS_SECONDARY_2_PRIMARY_15 1
-#define STM32_TIM_TS_SECONDARY_2_PRIMARY_3 2
-#define STM32_TIM_TS_SECONDARY_2_PRIMARY_14 3
-#define STM32_TIM_TS_SECONDARY_3_PRIMARY_1 0
-#define STM32_TIM_TS_SECONDARY_3_PRIMARY_2 1
-#define STM32_TIM_TS_SECONDARY_3_PRIMARY_15 2
-#define STM32_TIM_TS_SECONDARY_3_PRIMARY_14 3
-#define STM32_TIM_TS_SECONDARY_15_PRIMARY_2 0
-#define STM32_TIM_TS_SECONDARY_15_PRIMARY_3 1
-#define STM32_TIM_TS_SECONDARY_15_PRIMARY_16 2
-#define STM32_TIM_TS_SECONDARY_15_PRIMARY_17 3
-#elif defined(CHIP_FAMILY_STM32F3)
-/*
- * Secondary Primary
- * 2 19 15 3 14
- * 3 19 2 5 14
- * 4 19 2 3 15
- * 5 2 3 4 15
- * 12 4 5 13 14
- * 19 2 3 15 16
- * ---------------------
- * ts = 0 1 2 3
- */
-#define STM32_TIM_TS_SECONDARY_2_PRIMARY_19 0
-#define STM32_TIM_TS_SECONDARY_2_PRIMARY_15 1
-#define STM32_TIM_TS_SECONDARY_2_PRIMARY_3 2
-#define STM32_TIM_TS_SECONDARY_2_PRIMARY_14 3
-#define STM32_TIM_TS_SECONDARY_3_PRIMARY_19 0
-#define STM32_TIM_TS_SECONDARY_3_PRIMARY_2 1
-#define STM32_TIM_TS_SECONDARY_3_PRIMARY_5 2
-#define STM32_TIM_TS_SECONDARY_3_PRIMARY_14 3
-#define STM32_TIM_TS_SECONDARY_4_PRIMARY_19 0
-#define STM32_TIM_TS_SECONDARY_4_PRIMARY_2 1
-#define STM32_TIM_TS_SECONDARY_4_PRIMARY_3 2
-#define STM32_TIM_TS_SECONDARY_4_PRIMARY_15 3
-#define STM32_TIM_TS_SECONDARY_5_PRIMARY_2 0
-#define STM32_TIM_TS_SECONDARY_5_PRIMARY_3 1
-#define STM32_TIM_TS_SECONDARY_5_PRIMARY_4 2
-#define STM32_TIM_TS_SECONDARY_5_PRIMARY_15 3
-#define STM32_TIM_TS_SECONDARY_12_PRIMARY_4 0
-#define STM32_TIM_TS_SECONDARY_12_PRIMARY_5 1
-#define STM32_TIM_TS_SECONDARY_12_PRIMARY_13 2
-#define STM32_TIM_TS_SECONDARY_12_PRIMARY_14 3
-#define STM32_TIM_TS_SECONDARY_19_PRIMARY_2 0
-#define STM32_TIM_TS_SECONDARY_19_PRIMARY_3 1
-#define STM32_TIM_TS_SECONDARY_19_PRIMARY_15 2
-#define STM32_TIM_TS_SECONDARY_19_PRIMARY_16 3
-#else /* !CHIP_FAMILY_STM32F0 && !CHIP_FAMILY_STM32F3 */
-/*
- * Secondary Primary
- * 1 15 2 3 4 (STM32F100 only)
- * 2 9 10 3 4
- * 3 9 2 11 4
- * 4 10 2 3 9
- * 9 2 3 10 11 (STM32L15x only)
- * --------------------
- * ts = 0 1 2 3
- */
-#define STM32_TIM_TS_SECONDARY_1_PRIMARY_15 0
-#define STM32_TIM_TS_SECONDARY_1_PRIMARY_2 1
-#define STM32_TIM_TS_SECONDARY_1_PRIMARY_3 2
-#define STM32_TIM_TS_SECONDARY_1_PRIMARY_4 3
-#define STM32_TIM_TS_SECONDARY_2_PRIMARY_9 0
-#define STM32_TIM_TS_SECONDARY_2_PRIMARY_10 1
-#define STM32_TIM_TS_SECONDARY_2_PRIMARY_3 2
-#define STM32_TIM_TS_SECONDARY_2_PRIMARY_4 3
-#define STM32_TIM_TS_SECONDARY_3_PRIMARY_9 0
-#define STM32_TIM_TS_SECONDARY_3_PRIMARY_2 1
-#define STM32_TIM_TS_SECONDARY_3_PRIMARY_11 2
-#define STM32_TIM_TS_SECONDARY_3_PRIMARY_4 3
-#define STM32_TIM_TS_SECONDARY_4_PRIMARY_10 0
-#define STM32_TIM_TS_SECONDARY_4_PRIMARY_2 1
-#define STM32_TIM_TS_SECONDARY_4_PRIMARY_3 2
-#define STM32_TIM_TS_SECONDARY_4_PRIMARY_9 3
-#define STM32_TIM_TS_SECONDARY_9_PRIMARY_2 0
-#define STM32_TIM_TS_SECONDARY_9_PRIMARY_3 1
-#define STM32_TIM_TS_SECONDARY_9_PRIMARY_10 2
-#define STM32_TIM_TS_SECONDARY_9_PRIMARY_11 3
-#endif /* !CHIP_FAMILY_STM32F0 */
-#define TSMAP(secondary, primary) \
- CONCAT4(STM32_TIM_TS_SECONDARY_, secondary, _PRIMARY_, primary)
-
-/*
- * Timers are defined per board. This gives us flexibility to work around
- * timers which are dedicated to board-specific PWM sources.
- */
-#define IRQ_MSB IRQ_TIM(TIM_CLOCK_MSB)
-#define IRQ_LSB IRQ_TIM(TIM_CLOCK_LSB)
-#define IRQ_WD IRQ_TIM(TIM_WATCHDOG)
-
-/* TIM1 has fancy names for its IRQs; remap count-up IRQ for the macro above */
-#if defined TIM_WATCHDOG && (TIM_WATCHDOG == 1)
-#define STM32_IRQ_TIM1 STM32_IRQ_TIM1_BRK_UP_TRG
-#else /* !(TIM_WATCHDOG == 1) */
-#define STM32_IRQ_TIM1 STM32_IRQ_TIM1_CC
-#endif /* !(TIM_WATCHDOG == 1) */
-
-#define TIM_BASE(n) CONCAT3(STM32_TIM, n, _BASE)
-#define TIM_WD_BASE TIM_BASE(TIM_WATCHDOG)
-
-static uint32_t last_deadline;
-
-void __hw_clock_event_set(uint32_t deadline)
-{
- last_deadline = deadline;
-
- if ((deadline >> 16) > STM32_TIM_CNT(TIM_CLOCK_MSB)) {
- /* first set a match on the MSB */
- STM32_TIM_CCR1(TIM_CLOCK_MSB) = deadline >> 16;
- /* disable LSB match */
- STM32_TIM_DIER(TIM_CLOCK_LSB) &= ~2;
- /* Clear the match flags */
- STM32_TIM_SR(TIM_CLOCK_MSB) = ~2;
- STM32_TIM_SR(TIM_CLOCK_LSB) = ~2;
- /* Set the match interrupt */
- STM32_TIM_DIER(TIM_CLOCK_MSB) |= 2;
- }
- /*
- * In the unlikely case where the MSB 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(TIM_CLOCK_MSB)) {
- /* we can set a match on the LSB only */
- STM32_TIM_CCR1(TIM_CLOCK_LSB) = deadline & 0xffff;
- /* disable MSB match */
- STM32_TIM_DIER(TIM_CLOCK_MSB) &= ~2;
- /* Clear the match flags */
- STM32_TIM_SR(TIM_CLOCK_MSB) = ~2;
- STM32_TIM_SR(TIM_CLOCK_LSB) = ~2;
- /* Set the match interrupt */
- STM32_TIM_DIER(TIM_CLOCK_LSB) |= 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)
-{
- return last_deadline;
-}
-
-void __hw_clock_event_clear(void)
-{
- /* Disable the match interrupts */
- STM32_TIM_DIER(TIM_CLOCK_LSB) &= ~2;
- STM32_TIM_DIER(TIM_CLOCK_MSB) &= ~2;
-}
-
-uint32_t __hw_clock_source_read(void)
-{
- uint32_t hi;
- uint32_t lo;
-
- /* Ensure the two half-words are coherent */
- do {
- hi = STM32_TIM_CNT(TIM_CLOCK_MSB);
- lo = STM32_TIM_CNT(TIM_CLOCK_LSB);
- } while (hi != STM32_TIM_CNT(TIM_CLOCK_MSB));
-
- return (hi << 16) | lo;
-}
-
-void __hw_clock_source_set(uint32_t ts)
-{
- ASSERT(!is_interrupt_enabled());
-
- /* Stop counting (LSB first, then MSB) */
- STM32_TIM_CR1(TIM_CLOCK_LSB) &= ~1;
- STM32_TIM_CR1(TIM_CLOCK_MSB) &= ~1;
-
- /* Set new value to counters */
- STM32_TIM_CNT(TIM_CLOCK_MSB) = ts >> 16;
- STM32_TIM_CNT(TIM_CLOCK_LSB) = ts & 0xffff;
-
- /*
- * Clear status. We may clear information other than timer overflow
- * (eg. event timestamp was matched) but:
- * - Bits other than overflow are unused (see __hw_clock_source_irq())
- * - After setting timestamp software will trigger timer interrupt using
- * task_trigger_irq() (see force_time() in common/timer.c).
- * process_timers() is called from timer interrupt, so if "match" bit
- * was present in status (think: some task timers are expired)
- * process_timers() will handle that correctly.
- */
- STM32_TIM_SR(TIM_CLOCK_MSB) = 0;
- STM32_TIM_SR(TIM_CLOCK_LSB) = 0;
-
- /* Start counting (MSB first, then LSB) */
- STM32_TIM_CR1(TIM_CLOCK_MSB) |= 1;
- STM32_TIM_CR1(TIM_CLOCK_LSB) |= 1;
-}
-
-static void __hw_clock_source_irq(void)
-{
- uint32_t stat_tim_msb = STM32_TIM_SR(TIM_CLOCK_MSB);
-
- /* Clear status */
- STM32_TIM_SR(TIM_CLOCK_LSB) = 0;
- STM32_TIM_SR(TIM_CLOCK_MSB) = 0;
-
- /*
- * Find expired timers and set the new timer deadline
- * signal overflow if the 16-bit MSB counter has overflowed.
- */
- process_timers(stat_tim_msb & 0x01);
-}
-DECLARE_IRQ(IRQ_MSB, __hw_clock_source_irq, 1);
-DECLARE_IRQ(IRQ_LSB, __hw_clock_source_irq, 1);
-
-void __hw_timer_enable_clock(int n, int enable)
-{
- volatile uint32_t *reg;
- uint32_t mask = 0;
-
- /*
- * Mapping of timers to reg/mask is split into a few different ranges,
- * some specific to individual chips.
- */
-#if defined(CHIP_FAMILY_STM32F0)
- if (n == 1) {
- reg = &STM32_RCC_APB2ENR;
- mask = STM32_RCC_PB2_TIM1;
- }
-#elif defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32F4)
- if (n >= 9 && n <= 11) {
- reg = &STM32_RCC_APB2ENR;
- mask = STM32_RCC_PB2_TIM9 << (n - 9);
- }
-#endif
-
-#if defined(CHIP_FAMILY_STM32F0)
- if (n >= 15 && n <= 17) {
- reg = &STM32_RCC_APB2ENR;
- mask = STM32_RCC_PB2_TIM15 << (n - 15);
- }
-#endif
-
-#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
- if (n == 14) {
- reg = &STM32_RCC_APB1ENR;
- mask = STM32_RCC_PB1_TIM14;
- }
-#endif
-
-#if defined(CHIP_FAMILY_STM32F3)
- if (n == 12 || n == 13) {
- reg = &STM32_RCC_APB1ENR;
- mask = STM32_RCC_PB1_TIM12 << (n - 12);
- }
- if (n == 18) {
- reg = &STM32_RCC_APB1ENR;
- mask = STM32_RCC_PB1_TIM18;
- }
- if (n == 19) {
- reg = &STM32_RCC_APB2ENR;
- mask = STM32_RCC_PB2_TIM19;
- }
-#endif
-
- if (n >= 2 && n <= 7) {
- reg = &STM32_RCC_APB1ENR;
- mask = STM32_RCC_PB1_TIM2 << (n - 2);
- }
-
- if (!mask)
- return;
-
- if (enable)
- *reg |= mask;
- else
- *reg &= ~mask;
-}
-
-static void update_prescaler(void)
-{
- /*
- * Pre-scaler value :
- * TIM_CLOCK_LSB is counting microseconds;
- * TIM_CLOCK_MSB is counting every TIM_CLOCK_LSB overflow.
- *
- * This will take effect at the next update event (when the current
- * prescaler counter ticks down, or if forced via EGR).
- */
- STM32_TIM_PSC(TIM_CLOCK_MSB) = 0;
- STM32_TIM_PSC(TIM_CLOCK_LSB) = (clock_get_timer_freq() / SECOND) - 1;
-}
-DECLARE_HOOK(HOOK_FREQ_CHANGE, update_prescaler, HOOK_PRIO_DEFAULT);
-
-int __hw_clock_source_init(uint32_t start_t)
-{
- /*
- * we use 2 chained 16-bit counters to emulate a 32-bit one :
- * TIM_CLOCK_MSB is the MSB (Secondary)
- * TIM_CLOCK_LSB is the LSB (Primary)
- */
-
- /* Enable TIM_CLOCK_MSB and TIM_CLOCK_LSB clocks */
- __hw_timer_enable_clock(TIM_CLOCK_MSB, 1);
- __hw_timer_enable_clock(TIM_CLOCK_LSB, 1);
-
- /* Delay 1 APB clock cycle after the clock is enabled */
- clock_wait_bus_cycles(BUS_APB, 1);
-
- /*
- * Timer configuration : Upcounter, counter disabled, update event only
- * on overflow.
- */
- STM32_TIM_CR1(TIM_CLOCK_MSB) = 0x0004;
- STM32_TIM_CR1(TIM_CLOCK_LSB) = 0x0004;
- /*
- * TIM_CLOCK_LSB (primary mode) generates a periodic trigger signal on
- * each UEV
- */
- STM32_TIM_CR2(TIM_CLOCK_MSB) = 0x0000;
- STM32_TIM_CR2(TIM_CLOCK_LSB) = 0x0020;
-
- STM32_TIM_SMCR(TIM_CLOCK_MSB) =
- 0x0007 | (TSMAP(TIM_CLOCK_MSB, TIM_CLOCK_LSB) << 4);
- STM32_TIM_SMCR(TIM_CLOCK_LSB) = 0x0000;
-
- /* Auto-reload value : 16-bit free-running counters */
- STM32_TIM_ARR(TIM_CLOCK_MSB) = 0xffff;
- STM32_TIM_ARR(TIM_CLOCK_LSB) = 0xffff;
-
- /* Update prescaler */
- update_prescaler();
-
- /* Reload the pre-scaler */
- STM32_TIM_EGR(TIM_CLOCK_MSB) = 0x0001;
- STM32_TIM_EGR(TIM_CLOCK_LSB) = 0x0001;
-
- /* Set up the overflow interrupt on TIM_CLOCK_MSB */
- STM32_TIM_DIER(TIM_CLOCK_MSB) = 0x0001;
- STM32_TIM_DIER(TIM_CLOCK_LSB) = 0x0000;
-
- /* Override the count with the start value */
- STM32_TIM_CNT(TIM_CLOCK_MSB) = start_t >> 16;
- STM32_TIM_CNT(TIM_CLOCK_LSB) = start_t & 0xffff;
-
- /* Start counting */
- STM32_TIM_CR1(TIM_CLOCK_MSB) |= 1;
- STM32_TIM_CR1(TIM_CLOCK_LSB) |= 1;
-
- /* Enable timer interrupts */
- task_enable_irq(IRQ_MSB);
- task_enable_irq(IRQ_LSB);
-
- return IRQ_LSB;
-}
-
-#ifdef CONFIG_WATCHDOG_HELP
-
-void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp)
-{
- struct timer_ctlr *timer = (struct timer_ctlr *)TIM_WD_BASE;
-
- /* clear status */
- timer->sr = 0;
-
- watchdog_trace(excep_lr, excep_sp);
-}
-
-void IRQ_HANDLER(IRQ_WD)(void) __attribute__((naked));
-void IRQ_HANDLER(IRQ_WD)(void)
-{
- /* Naked call so we can extract raw LR and SP */
- asm volatile("mov r0, lr\n"
- "mov r1, sp\n"
- /* Must push registers in pairs to keep 64-bit aligned
- * stack for ARM EABI. */
- "push {r0, lr}\n"
- "bl watchdog_check\n"
- "pop {r0,pc}\n");
-}
-const struct irq_priority __keep IRQ_PRIORITY(IRQ_WD)
- __attribute__((section(".rodata.irqprio"))) = {
- IRQ_WD, 0
- }; /* put the watchdog
- at the highest
- priority
- */
-
-void hwtimer_setup_watchdog(void)
-{
- struct timer_ctlr *timer = (struct timer_ctlr *)TIM_WD_BASE;
-
- /* Enable clock */
- __hw_timer_enable_clock(TIM_WATCHDOG, 1);
-
- /* Delay 1 APB clock cycle after the clock is enabled */
- clock_wait_bus_cycles(BUS_APB, 1);
-
- /*
- * Timer configuration : Down counter, counter disabled, update
- * event only on overflow.
- */
- timer->cr1 = 0x0014 | BIT(7);
-
- /* TIM (secondary mode) uses TIM_CLOCK_LSB as internal trigger */
- timer->smcr = 0x0007 | (TSMAP(TIM_WATCHDOG, TIM_CLOCK_LSB) << 4);
-
- /*
- * The auto-reload value is based on the period between rollovers for
- * TIM_CLOCK_LSB. Since TIM_CLOCK_LSB runs at 1MHz, it will overflow
- * in 65.536ms. We divide our required watchdog period by this amount
- * to obtain the number of times TIM_CLOCK_LSB can overflow before we
- * generate an interrupt.
- */
- timer->arr = timer->cnt = CONFIG_AUX_TIMER_PERIOD_MS * MSEC / BIT(16);
-
- /* count on every TIM_CLOCK_LSB overflow */
- timer->psc = 0;
-
- /* Reload the pre-scaler from arr when it goes below zero */
- timer->egr = 0x0000;
-
- /* setup the overflow interrupt */
- timer->dier = 0x0001;
-
- /* Start counting */
- timer->cr1 |= 1;
-
- /* Enable timer interrupts */
- task_enable_irq(IRQ_WD);
-}
-
-void hwtimer_reset_watchdog(void)
-{
- struct timer_ctlr *timer = (struct timer_ctlr *)TIM_WD_BASE;
-
- timer->cnt = timer->arr;
-}
-
-#endif /* defined(CONFIG_WATCHDOG_HELP) */