blob: 432bb280e1e3a5e56b48a9cd8463eac969038ce1 [file] [log] [blame]
/* 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 "common.h"
#include "gpio.h"
#include "hooks.h"
#include "hwtimer.h"
#include "registers.h"
#include "task.h"
#include "timer.h"
#include "util.h"
#include "watchdog.h"
/*
* LSI oscillator frequency is typically 38 kHz, but it may be between 28-56
* kHz and we don't calibrate it to know. Use 56 kHz so that we pick a counter
* value large enough that we reload before the worst-case watchdog delay
* (fastest LSI clock).
*/
#define LSI_CLOCK 56000
/*
* Use largest prescaler divider = /256. This gives a worst-case watchdog
* clock of 56000/256 = 218 Hz, and a maximum timeout period of (4095/218 Hz) =
* 18.7 sec.
*/
#define IWDG_PRESCALER 6
#define IWDG_PRESCALER_DIV (4 << IWDG_PRESCALER)
void watchdog_reload(void)
{
/* Reload the watchdog */
STM32_IWDG_KR = STM32_IWDG_KR_RELOAD;
#ifdef CONFIG_WATCHDOG_HELP
hwtimer_reset_watchdog();
#endif
}
DECLARE_HOOK(HOOK_TICK, watchdog_reload, HOOK_PRIO_DEFAULT);
int watchdog_init(void)
{
/* Unlock watchdog registers */
STM32_IWDG_KR = STM32_IWDG_KR_UNLOCK;
/* Set the prescaler between the LSI clock and the watchdog counter */
STM32_IWDG_PR = IWDG_PRESCALER & 7;
/* Set the reload value of the watchdog counter */
STM32_IWDG_RLR = MIN(STM32_IWDG_RLR_MAX, CONFIG_WATCHDOG_PERIOD_MS *
(LSI_CLOCK / IWDG_PRESCALER_DIV) / 1000);
/* Start the watchdog (and re-lock registers) */
STM32_IWDG_KR = STM32_IWDG_KR_START;
#ifdef CONFIG_WATCHDOG_HELP
/* Use a harder timer to warn about an impending watchdog reset */
hwtimer_setup_watchdog();
#endif
return EC_SUCCESS;
}