Class implementation for the STM32 watchdog timer.

Files at this revision

API Documentation at this revision

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 &copy; 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