Class implementation for the STM32 watchdog timer.
Revision 0:2d9d71938413, committed 2019-10-03
- Comitter:
- rlanders73
- Date:
- Thu Oct 03 18:04:23 2019 +0000
- Commit message:
- This is a class implementation for the STM32 watchdog timer.
Changed in this revision
Watchdog.cpp | Show annotated file Show diff for this revision Revisions of this file |
Watchdog.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r 2d9d71938413 Watchdog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Watchdog.cpp Thu Oct 03 18:04:23 2019 +0000 @@ -0,0 +1,94 @@ +/// @file Watchdog.cpp provides the interface to the Watchdog module +/// +/// This provides basic Watchdog service for the mbed. You can configure +/// various timeout intervals that meet your system needs. Additionally, +/// it is possible to identify if the Watchdog was the cause of any +/// system restart. +/// +/// Adapted from Simon's Watchdog code from http://mbed.org/forum/mbed/topic/508/ + + +#include "mbed.h" +#include "Watchdog.h" + +#ifdef FEATURE_COMMON_PAL +#include "mbed_trace.h" +#define TRACE_GROUP "WDT" +#else +#define tr_debug(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__) +#define tr_info(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__) +#define tr_warn(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__) +#define tr_error(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__) +#endif + +/// Watchdog gets instantiated at the module level +Watchdog::Watchdog() { + // capture the cause of the previous reset + wdreset = __HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST); + //Clear source Reset Flag + __HAL_RCC_CLEAR_RESET_FLAGS(); +} + +/// Load timeout value in watchdog timer and enable +void Watchdog::Configure(float timeout) { + + #define LsiFreq (45000) + uint16_t PrescalerCode; + uint16_t Prescaler; + uint16_t ReloadValue; + float Calculated_timeout; + + if ((timeout * (LsiFreq/4)) < 0x7FF) { + PrescalerCode = IWDG_PRESCALER_4; + Prescaler = 4; + } + else if ((timeout * (LsiFreq/8)) < 0xFF0) { + PrescalerCode = IWDG_PRESCALER_8; + Prescaler = 8; + } + else if ((timeout * (LsiFreq/16)) < 0xFF0) { + PrescalerCode = IWDG_PRESCALER_16; + Prescaler = 16; + } + else if ((timeout * (LsiFreq/32)) < 0xFF0) { + PrescalerCode = IWDG_PRESCALER_32; + Prescaler = 32; + } + else if ((timeout * (LsiFreq/64)) < 0xFF0) { + PrescalerCode = IWDG_PRESCALER_64; + Prescaler = 64; + } + else if ((timeout * (LsiFreq/128)) < 0xFF0) { + PrescalerCode = IWDG_PRESCALER_128; + Prescaler = 128; + } + else { + PrescalerCode = IWDG_PRESCALER_256; + Prescaler = 256; + } + + // specifies the IWDG Reload value. This parameter must be a number between 0 and 0x0FFF. + ReloadValue = (uint32_t)(timeout * (LsiFreq/Prescaler)); + + Calculated_timeout = ((float)(Prescaler * ReloadValue)) / LsiFreq; + tr_debug("WATCHDOG set with prescaler:%d reload value: 0x%X - timeout:%f\n",Prescaler, ReloadValue, Calculated_timeout); + + IWDG->KR = 0x5555; //Disable write protection of IWDG registers + IWDG->PR = PrescalerCode; //Set PR value + IWDG->RLR = ReloadValue; //Set RLR value + IWDG->KR = 0xAAAA; //Reload IWDG + IWDG->KR = 0xCCCC; //Start IWDG - See more at: http://embedded-lab.com/blog/?p=9662#sthash.6VNxVSn0.dpuf + + Pet(); +} + +/// "Pet", "kick" or "feed" the dog - reset the watchdog timer +/// by writing this required bit pattern +void Watchdog::Pet() { + IWDG->KR = 0xAAAA; //Reload IWDG - See more at: http://embedded-lab.com/blog/?p=9662#sthash.6VNxVSn0.dpuf +} + +/// get the flag to indicate if the watchdog causes the reset +bool Watchdog::WatchdogCausedReset() { + return wdreset; +}
diff -r 000000000000 -r 2d9d71938413 Watchdog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Watchdog.h Thu Oct 03 18:04:23 2019 +0000 @@ -0,0 +1,101 @@ +/// @file Watchdog.h provides the interface to the Watchdog module +/// +/// This provides basic Watchdog service for the mbed. You can configure +/// various timeout intervals that meet your system needs. Additionally, +/// it is possible to identify if the Watchdog was the cause of any +/// system restart, permitting the application code to take appropriate +/// behavior. +/// +/// Adapted from Simon's Watchdog code from http://mbed.org/forum/mbed/topic/508/ +/// +/// @note Copyright © 2011 by Smartware Computing, all rights reserved. +/// This software may be used to derive new software, as long as +/// this copyright statement remains in the source file. +/// @author David Smart +/// +/// History +/// \li v1.00 - 20110616: initial release with some documentation improvements +/// +#ifndef WATCHDOG_H +#define WATCHDOG_H +#include "mbed.h" + +/// The Watchdog class provides the interface to the Watchdog feature +/// +/// Embedded programs, by their nature, are usually unattended. If things +/// go wrong, it is usually important that the system attempts to recover. +/// Aside from robust software, a hardware watchdog can monitor the +/// system and initiate a system reset when appropriate. +/// +/// This Watchdog is patterned after one found elsewhere on the mbed site, +/// however this one also provides a method for the application software +/// to determine the cause of the reset - watchdog or otherwise. +/// +/// example: +/// @code +/// Watchdog wd; +/// +/// ... +/// main() { +/// if (wd.WatchdogCausedReset()) +/// pc.printf("Watchdog caused reset.\r\n"); +/// +/// wd.Configure(3.0); // sets the timeout interval +/// for (;;) { +/// wd.Service(); // kick the dog before the timeout +/// // do other work +/// } +/// } +/// @endcode +/// +class Watchdog { +public: + /// Create a Watchdog object + /// + /// example: + /// @code + /// Watchdog wd; // placed before main + /// @endcode + Watchdog(); + + /// Configure the timeout for the Watchdog + /// + /// This configures the Watchdog service and starts it. It must + /// be serviced before the timeout, or the system will be restarted. + /// + /// example: + /// @code + /// ... + /// wd.Configure(1.4); // configure for a 1.4 second timeout + /// ... + /// @endcode + /// + /// @param[in] timeout in seconds, as a floating point number + /// @returns none + /// + void Configure(float timeout); + + /// Service the Watchdog so it does not cause a system reset + /// + /// example: + /// @code + /// wd.Pet(); + /// @endcode + /// @returns none + void Pet(); + + /// WatchdogCausedReset identifies if the cause of the system + /// reset was the Watchdog + /// + /// example: + /// @code + /// if (wd.WatchdogCausedReset())) { + /// @endcode + /// + /// @returns true if the Watchdog was the cause of the reset + bool WatchdogCausedReset(); +private: + bool wdreset; +}; + +#endif // WATCHDOG_H \ No newline at end of file