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
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