summaryrefslogtreecommitdiff
path: root/chip/stm32/hwtimer32.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/stm32/hwtimer32.c')
-rw-r--r--chip/stm32/hwtimer32.c333
1 files changed, 0 insertions, 333 deletions
diff --git a/chip/stm32/hwtimer32.c b/chip/stm32/hwtimer32.c
deleted file mode 100644
index 963fa44e51..0000000000
--- a/chip/stm32/hwtimer32.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/* Copyright 2014 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Hardware 32-bit timer driver */
-
-#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"
-
-#define IRQ_TIM(n) CONCAT2(STM32_IRQ_TIM, n)
-
-void __hw_clock_event_set(uint32_t deadline)
-{
- /* set the match on the deadline */
- STM32_TIM32_CCR1(TIM_CLOCK32) = deadline;
- /* Clear the match flags */
- STM32_TIM_SR(TIM_CLOCK32) = ~2;
- /* Set the match interrupt */
- STM32_TIM_DIER(TIM_CLOCK32) |= 2;
-}
-
-uint32_t __hw_clock_event_get(void)
-{
- return STM32_TIM32_CCR1(TIM_CLOCK32);
-}
-
-void __hw_clock_event_clear(void)
-{
- /* Disable the match interrupts */
- STM32_TIM_DIER(TIM_CLOCK32) &= ~2;
-}
-
-uint32_t __hw_clock_source_read(void)
-{
- return STM32_TIM32_CNT(TIM_CLOCK32);
-}
-
-void __hw_clock_source_set(uint32_t ts)
-{
- STM32_TIM32_CNT(TIM_CLOCK32) = ts;
-}
-
-void __hw_clock_source_irq(void)
-{
- uint32_t stat_tim = STM32_TIM_SR(TIM_CLOCK32);
-
- /* Clear status */
- STM32_TIM_SR(TIM_CLOCK32) = 0;
-
- /*
- * Find expired timers and set the new timer deadline
- * signal overflow if the update interrupt flag is set.
- */
- process_timers(stat_tim & 0x01);
-}
-DECLARE_IRQ(IRQ_TIM(TIM_CLOCK32), __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) || defined(CHIP_FAMILY_STM32H7)
- 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) || defined(CHIP_FAMILY_STM32H7)
- 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) || \
-defined(CHIP_FAMILY_STM32H7)
- if (n == 14) {
- reg = &STM32_RCC_APB1ENR;
- mask = STM32_RCC_PB1_TIM14;
- }
-#endif
-
-#if defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32H7)
- if (n == 12 || n == 13) {
- reg = &STM32_RCC_APB1ENR;
- mask = STM32_RCC_PB1_TIM12 << (n - 12);
- }
-#endif
-#if defined(CHIP_FAMILY_STM32F3)
- 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 defined(CHIP_FAMILY_STM32G4)
- reg = &STM32_RCC_APB2ENR;
- if (n == 1)
- mask = STM32_RCC_APB2ENR_TIM1;
- else if (n == 8)
- mask = STM32_RCC_APB2ENR_TIM8;
- else if (n == 20)
- mask = STM32_RCC_APB2ENR_TIM20;
- else if (n >= 15 && n <= 17)
- mask = STM32_RCC_APB2ENR_TIM15 << (n - 15);
-#endif
-#if defined(CHIP_FAMILY_STM32L4)
- if (n >= 2 && n <= 7) {
- reg = &STM32_RCC_APB1ENR1;
- mask = STM32_RCC_PB1_TIM2 << (n - 2);
- } else if (n == 1 || n == 15 || n == 16) {
- reg = &STM32_RCC_APB2ENR;
- mask = (n == 1) ? STM32_RCC_APB2ENR_TIM1EN :
- (n == 15) ? STM32_RCC_APB2ENR_TIM15EN :
- STM32_RCC_APB2ENR_TIM16EN;
- }
-#else
- if (n >= 2 && n <= 7) {
- reg = &STM32_RCC_APB1ENR;
- mask = STM32_RCC_PB1_TIM2 << (n - 2);
- }
-#endif
-
- if (!mask)
- return;
-
- if (enable)
- *reg |= mask;
- else
- *reg &= ~mask;
-}
-
-#if defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32L4) || \
- defined(CHIP_FAMILY_STM32F4) || defined(CHIP_FAMILY_STM32H7)
-/* for families using a variable clock feeding the timer */
-static void update_prescaler(void)
-{
- uint32_t t;
- /*
- * Pre-scaler value :
- * the timer is incrementing every microsecond
- */
- STM32_TIM_PSC(TIM_CLOCK32) = (clock_get_timer_freq() / SECOND) - 1;
- /*
- * Forcing reloading the pre-scaler,
- * but try to maintain a sensible time-keeping while triggering
- * the update event.
- */
- interrupt_disable();
- /* Ignore the next update */
- STM32_TIM_DIER(TIM_CLOCK32) &= ~0x0001;
- /*
- * prepare to reload the counter with the current value
- * to avoid rolling backward the microsecond counter.
- */
- t = STM32_TIM32_CNT(TIM_CLOCK32) + 1;
- /* issue an update event, reloads the pre-scaler and the counter */
- STM32_TIM_EGR(TIM_CLOCK32) = 0x0001;
- /* clear the 'spurious' update unless we were going to roll-over */
- if (t)
- STM32_TIM_SR(TIM_CLOCK32) = ~1;
- /* restore a sensible time value */
- STM32_TIM32_CNT(TIM_CLOCK32) = t;
- /* restore roll-over events */
- STM32_TIM_DIER(TIM_CLOCK32) |= 0x0001;
- interrupt_enable();
-
-#ifdef CONFIG_WATCHDOG_HELP
- /* Watchdog timer runs at 1KHz */
- STM32_TIM_PSC(TIM_WATCHDOG) =
- (clock_get_timer_freq() / SECOND * MSEC)- 1;
-#endif /* CONFIG_WATCHDOG_HELP */
-}
-DECLARE_HOOK(HOOK_FREQ_CHANGE, update_prescaler, HOOK_PRIO_DEFAULT);
-#endif /* CHIP_FAMILY_STM32L || CHIP_FAMILY_STM32L4 || */
- /* CHIP_FAMILY_STM32F4 || CHIP_FAMILY_STM32H7 */
-
-int __hw_clock_source_init(uint32_t start_t)
-{
- /* Enable TIM peripheral block clocks */
- __hw_timer_enable_clock(TIM_CLOCK32, 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_CLOCK32) = 0x0004;
- /* No special configuration */
- STM32_TIM_CR2(TIM_CLOCK32) = 0x0000;
- STM32_TIM_SMCR(TIM_CLOCK32) = 0x0000;
-
- /* Auto-reload value : 32-bit free-running counter */
- STM32_TIM32_ARR(TIM_CLOCK32) = 0xffffffff;
-
- /* Update prescaler to increment every microsecond */
- STM32_TIM_PSC(TIM_CLOCK32) = (clock_get_timer_freq() / SECOND) - 1;
-
- /* Reload the pre-scaler */
- STM32_TIM_EGR(TIM_CLOCK32) = 0x0001;
-
- /* Set up the overflow interrupt */
- STM32_TIM_DIER(TIM_CLOCK32) = 0x0001;
-
- /* Start counting */
- STM32_TIM_CR1(TIM_CLOCK32) |= 1;
-
- /* Override the count with the start value now that counting has
- * started. */
- __hw_clock_source_set(start_t);
-
- /* Enable timer interrupts */
- task_enable_irq(IRQ_TIM(TIM_CLOCK32));
-
- return IRQ_TIM(TIM_CLOCK32);
-}
-
-#ifdef CONFIG_WATCHDOG_HELP
-
-#define IRQ_WD IRQ_TIM(TIM_WATCHDOG)
-
-void __keep watchdog_check(uint32_t excep_lr, uint32_t excep_sp)
-{
- /* clear status */
- STM32_TIM_SR(TIM_WATCHDOG) = 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)
-{
- int freq;
-
- /* 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 : Up counter, counter disabled, update
- * event only on overflow.
- */
- STM32_TIM_CR1(TIM_WATCHDOG) = 0x0004;
- /* No special configuration */
- STM32_TIM_CR2(TIM_WATCHDOG) = 0x0000;
- STM32_TIM_SMCR(TIM_WATCHDOG) = 0x0000;
-
- /*
- * all timers has 16-bit prescale.
- * For clock freq > 64MHz, 16bit prescale cannot meet 1KHz.
- * set prescale as 10KHz and 10 times arr value instead.
- * For clock freq < 64MHz, timer runs at 1KHz.
- */
- freq = clock_get_timer_freq();
-
- if (freq <= 64000000 || !IS_ENABLED(CHIP_FAMILY_STM32L4)) {
- /* AUto-reload value */
- STM32_TIM_ARR(TIM_WATCHDOG) = CONFIG_AUX_TIMER_PERIOD_MS;
-
- /* Update prescaler: watchdog timer runs at 1KHz */
- STM32_TIM_PSC(TIM_WATCHDOG) =
- (freq / SECOND * MSEC) - 1;
- }
-#ifdef CHIP_FAMILY_STM32L4
- else {
- /* 10 times ARR value with 10KHz timer */
- STM32_TIM_ARR(TIM_WATCHDOG) = CONFIG_AUX_TIMER_PERIOD_MS * 10;
-
- /* Update prescaler: watchdog timer runs at 10KHz */
- STM32_TIM_PSC(TIM_WATCHDOG) = (freq / SECOND / 10 * MSEC) - 1;
- }
-#endif
- /* Reload the pre-scaler */
- STM32_TIM_EGR(TIM_WATCHDOG) = 0x0001;
-
- /* setup the overflow interrupt */
- STM32_TIM_DIER(TIM_WATCHDOG) = 0x0001;
- STM32_TIM_SR(TIM_WATCHDOG) = 0;
-
- /* Start counting */
- STM32_TIM_CR1(TIM_WATCHDOG) |= 1;
-
- /* Enable timer interrupts */
- task_enable_irq(IRQ_WD);
-}
-
-void hwtimer_reset_watchdog(void)
-{
- STM32_TIM_CNT(TIM_WATCHDOG) = 0x0000;
-}
-
-#endif /* CONFIG_WATCHDOG_HELP */