From 312d887825325daf7561046bd31e3ec449c7a01c Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Thu, 6 Dec 2012 02:45:17 +1030 Subject: IWDG moved to common area --- lib/stm32/common/iwdg_common_all.c | 140 +++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 lib/stm32/common/iwdg_common_all.c (limited to 'lib/stm32/common') diff --git a/lib/stm32/common/iwdg_common_all.c b/lib/stm32/common/iwdg_common_all.c new file mode 100644 index 0000000..d3d9364 --- /dev/null +++ b/lib/stm32/common/iwdg_common_all.c @@ -0,0 +1,140 @@ +/** @addtogroup iwdg_file + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net + +@date 18 August 2012 + +This library supports the Independent Watchdog Timer System in the STM32F1xx +series of ARM Cortex Microcontrollers by ST Microelectronics. + +The watchdog timer uses the LSI (low speed internal) clock which is low power +and continues to operate during stop and standby modes. Its frequency is +nominally 32kHz (40kHz for the STM32F1xx series) but can vary from as low +as 17kHz up to 60kHz (refer to datasheet electrical characteristics). + +Note that the User Configuration option byte provides a means of automatically +enabling the IWDG timer at power on (with counter value 0xFFF). If the +relevant bit is not set, the IWDG timer must be enabled by software. + +@note: Tested: CPU STM32F103RET6, Board ET-ARM Stamp STM32 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +#define LSI_FREQUENCY 32000 +#define COUNT_LENGTH 12 +#define COUNT_MASK ((1 << COUNT_LENGTH)-1) + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG Enable Watchdog Timer + +The watchdog timer is started. The timeout period defaults to 512 milliseconds +unless it has been previously defined. + +*/ + +void iwdg_start(void) +{ + IWDG_KR = IWDG_KR_START; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG Set Period in Milliseconds + +The countdown period is converted into count and prescale values. The maximum +period is 32.76 seconds; values above this are truncated. Periods less than 1ms +are not supported by this library. + +A delay of up to 5 clock cycles of the LSI clock (about 156 microseconds) +can occasionally occur if the prescale or preload registers are currently busy +loading a previous value. + +@param[in] period u32 Period in milliseconds (< 32760) from a watchdog reset until +a system reset is issued. +*/ + +void iwdg_set_period_ms(u32 period) +{ +u32 count, prescale, reload, exponent; +/* Set the count to represent ticks of the 32kHz LSI clock */ + count = (period << 5); +/* Strip off the first 12 bits to get the prescale value required */ + prescale = (count >> 12); + if (prescale > 256) {exponent = IWDG_PR_DIV256; reload = COUNT_MASK;} + else if (prescale > 128) {exponent = IWDG_PR_DIV256; reload = (count >> 8);} + else if (prescale > 64) {exponent = IWDG_PR_DIV128; reload = (count >> 7);} + else if (prescale > 32) {exponent = IWDG_PR_DIV64; reload = (count >> 6);} + else if (prescale > 16) {exponent = IWDG_PR_DIV32; reload = (count >> 5);} + else if (prescale > 8) {exponent = IWDG_PR_DIV16; reload = (count >> 4);} + else if (prescale > 4) {exponent = IWDG_PR_DIV8; reload = (count >> 3);} + else {exponent = IWDG_PR_DIV4; reload = (count >> 2);} +/* Avoid the undefined situation of a zero count */ + if (count == 0) count = 1; + + while (iwdg_prescaler_busy()); + IWDG_KR = IWDG_KR_UNLOCK; + IWDG_PR = exponent; + while (iwdg_reload_busy()); + IWDG_KR = IWDG_KR_UNLOCK; + IWDG_RLR = (reload & COUNT_MASK); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG Get Reload Register Status + +@returns boolean: TRUE if the reload register is busy and unavailable for loading +a new count value. +*/ + +bool iwdg_reload_busy(void) +{ + return (IWDG_SR & IWDG_SR_RVU); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG Get Prescaler Register Status + +@returns boolean: TRUE if the prescaler register is busy and unavailable for loading +a new period value. +*/ + +bool iwdg_prescaler_busy(void) +{ + return (IWDG_SR & IWDG_SR_PVU); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG reset Watchdog Timer + +The watchdog timer is reset. The counter restarts from the value in the reload +register. +*/ + +void iwdg_reset(void) +{ + IWDG_KR = IWDG_KR_RESET; +} +/**@}*/ + -- cgit v1.2.3