diff --git a/board/discovery/board.c b/board/discovery/board.c index ec18af63e3..560773d829 100644 --- a/board/discovery/board.c +++ b/board/discovery/board.c @@ -20,6 +20,9 @@ void configure_board(void) (0x7 << 12) | (0x7 << 8); STM32L_GPIO_MODER(B) = (STM32L_GPIO_MODER(B) & ~0x00F00000) | 0x00A00000; + + /* Green and blue LEDs : configure port 6 and 7 as output */ + STM32L_GPIO_MODER(B) |= (1 << (7 * 2)) | (1 << (6 * 2)); } /** @@ -28,6 +31,9 @@ void configure_board(void) */ int jtag_pre_init(void) { + /* stop TIM2, TIM3 and watchdogs when the JTAG stops the CPU */ + STM32L_DBGMCU_APB1FZ |= 0x00001803; + return EC_SUCCESS; } diff --git a/board/discovery/ec.tasklist b/board/discovery/ec.tasklist index 8e52f9f1c2..0e5992b96b 100644 --- a/board/discovery/ec.tasklist +++ b/board/discovery/ec.tasklist @@ -14,4 +14,5 @@ * 'd' in an opaque parameter passed to the routine at startup */ #define CONFIG_TASK_LIST \ + TASK(WATCHDOG, watchdog_task, NULL) \ TASK(CONSOLE, console_task, NULL) diff --git a/chip/stm32l/build.mk b/chip/stm32l/build.mk index e28b56d6c4..bb354c2f92 100644 --- a/chip/stm32l/build.mk +++ b/chip/stm32l/build.mk @@ -9,3 +9,4 @@ CORE:=cortex-m chip-y=uart.o clock.o hwtimer.o system.o +chip-$(CONFIG_TASK_WATCHDOG)+=watchdog.o diff --git a/chip/stm32l/registers.h b/chip/stm32l/registers.h index ad06983cc5..7fa8ec88d3 100644 --- a/chip/stm32l/registers.h +++ b/chip/stm32l/registers.h @@ -221,6 +221,15 @@ #define STM32L_RTC_TAFCR REG32(STM32L_RTC_BASE + 0x40) #define STM32L_RTC_BACKUP(n) REG32(STM32L_RTC_BASE + 0x50 + 4 * (n)) +/* --- Debug --- */ + +#define STM32L_DBGMCU_BASE 0xE0042000 + +#define STM32L_DBGMCU_IDCODE REG32(STM32L_DBGMCU_BASE + 0x00) +#define STM32L_DBGMCU_CR REG32(STM32L_DBGMCU_BASE + 0x04) +#define STM32L_DBGMCU_APB1FZ REG32(STM32L_DBGMCU_BASE + 0x08) +#define STM32L_DBGMCU_APB2FZ REG32(STM32L_DBGMCU_BASE + 0x0C) + /* --- MISC --- */ #define STM32L_RI_BASE 0x40007C04 diff --git a/chip/stm32l/watchdog.c b/chip/stm32l/watchdog.c new file mode 100644 index 0000000000..114c3e9211 --- /dev/null +++ b/chip/stm32l/watchdog.c @@ -0,0 +1,75 @@ +/* Copyright (c) 2012 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. + */ + +/* Watchdog driver */ + +#include + +#include "board.h" +#include "common.h" +#include "config.h" +#include "registers.h" +#include "gpio.h" +#include "task.h" +#include "timer.h" +#include "uart.h" +#include "util.h" + +/* LSI oscillator frequency is typically 38 kHz + * but might vary from 28 to 56kHz. + * So let's pick 56kHz to ensure we reload + * early enough. + */ +#define LSI_CLOCK 56000 + +/* Prescaler divider = /256 */ +#define IWDG_PRESCALER 6 +#define IWDG_PRESCALER_DIV (1 << ((IWDG_PRESCALER) + 2)) + +void watchdog_reload(void) +{ + /* Reload the watchdog */ + STM32L_IWDG_KR = 0xaaaa; +} + +int watchdog_init(int period_ms) +{ + uint32_t watchdog_period; + + /* set the time-out period */ + watchdog_period = period_ms * (LSI_CLOCK / IWDG_PRESCALER_DIV) / 1000; + + /* Unlock watchdog registers */ + STM32L_IWDG_KR = 0x5555; + + /* Set the prescaler between the LSI clock and the watchdog counter */ + STM32L_IWDG_PR = IWDG_PRESCALER & 7; + /* Set the reload value of the watchdog counter */ + STM32L_IWDG_RLR = watchdog_period & 0x7FF ; + + /* Start the watchdog (and re-lock registers) */ + STM32L_IWDG_KR = 0xcccc; + + return EC_SUCCESS; +} + +/* Low priority task to reload the watchdog */ +void watchdog_task(void) +{ + while (1) { +#ifdef BOARD_discovery + /* TODO use GPIO API: gpio_set_level(GPIO_GREEN_LED, 1); */ + STM32L_GPIO_ODR(B) |= (1 << 7) ; +#endif + usleep(500000); + watchdog_reload(); +#ifdef BOARD_discovery + /* TODO use GPIO API: gpio_set_level(GPIO_GREEN_LED, 0); */ + STM32L_GPIO_ODR(B) &= ~(1 << 7) ; +#endif + usleep(500000); + watchdog_reload(); + } +}