From 2f4cd293248b012c87be34d4f45786b7f8c06770 Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Wed, 13 Jun 2012 22:14:53 +0930 Subject: Code for iwdg module STM32F series --- include/libopencm3/stm32/iwdg.h | 8 ++- lib/stm32/iwdg.c | 146 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 lib/stm32/iwdg.c diff --git a/include/libopencm3/stm32/iwdg.h b/include/libopencm3/stm32/iwdg.h index 2d24482..2a8ee9d 100644 --- a/include/libopencm3/stm32/iwdg.h +++ b/include/libopencm3/stm32/iwdg.h @@ -78,8 +78,12 @@ /* PVU: Watchdog prescaler value update */ #define IWDG_SR_PVU (1 << 0) -/* --- IWDG funtion prototypes---------------------------------------------- */ +/* --- IWDG function prototypes---------------------------------------------- */ -/* TODO */ +void iwdg_start(void); +void iwdg_set_period_ms(u32 period); +bool iwdg_reload_busy(void); +bool iwdg_prescaler_busy(void); +void iwdg_reset(void); #endif diff --git a/lib/stm32/iwdg.c b/lib/stm32/iwdg.c new file mode 100644 index 0000000..a4a15ec --- /dev/null +++ b/lib/stm32/iwdg.c @@ -0,0 +1,146 @@ +/** @file + +@ingroup STM32F + +@brief libopencm3 STM32F1xx Independent Watchdog Timer + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net + +@date 11 June 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. + +@bugs None known + +@note: Tested: CPU STM32F103RET6, Board ET-ARM Stamp STM32 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * 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 + +/*-----------------------------------------------------------------------------*/ +/** @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] u32 Period in milliseconds (< 32760) from a watchdog reset until +a system reset is issued. +*/ + +#define COUNT_LENGTH 12 +#define COUNT_MASK ((1 << COUNT_LENGTH)-1) + +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 From 0fabe4462b048fb453743754e9bc4969a01a4f9b Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Thu, 14 Jun 2012 19:45:46 +0930 Subject: Fix Typo --- lib/stm32/iwdg.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/stm32/iwdg.c b/lib/stm32/iwdg.c index a4a15ec..0968e7f 100644 --- a/lib/stm32/iwdg.c +++ b/lib/stm32/iwdg.c @@ -31,8 +31,6 @@ LGPL License Terms @ref lgpl_license /* * This file is part of the libopencm3 project. * - * Copyright (C) 2010 Thomas Otto - * * 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 -- cgit v1.2.3