Point Labs / STM_Watchdog
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Watchdog.cpp Source File

Watchdog.cpp

Go to the documentation of this file.
00001 /// @file Watchdog.cpp provides the interface to the Watchdog module
00002 ///
00003 /// This provides basic Watchdog service for the mbed. You can configure
00004 /// various timeout intervals that meet your system needs. Additionally,
00005 /// it is possible to identify if the Watchdog was the cause of any 
00006 /// system restart.
00007 /// 
00008 /// Adapted from Simon's Watchdog code from http://mbed.org/forum/mbed/topic/508/
00009 
00010 
00011 #include "mbed.h"
00012 #include "Watchdog.h"
00013 
00014 #ifdef FEATURE_COMMON_PAL
00015 #include "mbed_trace.h"
00016 #define TRACE_GROUP "WDT"
00017 #else
00018 #define tr_debug(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__)
00019 #define tr_info(format, ...)  debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__)
00020 #define tr_warn(format, ...)  debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__)
00021 #define tr_error(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__)
00022 #endif
00023 
00024 /// Watchdog gets instantiated at the module level
00025 Watchdog::Watchdog() {
00026     // capture the cause of the previous reset
00027     wdreset = __HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST);
00028     //Clear source Reset Flag
00029     __HAL_RCC_CLEAR_RESET_FLAGS();
00030 }
00031 
00032 /// Load timeout value in watchdog timer and enable
00033 void Watchdog::Configure(float timeout) {
00034        
00035     #define LsiFreq (45000)
00036     uint16_t PrescalerCode;
00037     uint16_t Prescaler;
00038     uint16_t ReloadValue;
00039     float Calculated_timeout;
00040     
00041     if ((timeout * (LsiFreq/4)) < 0x7FF) {
00042         PrescalerCode = IWDG_PRESCALER_4;
00043         Prescaler = 4;
00044     }
00045     else if ((timeout * (LsiFreq/8)) < 0xFF0) {
00046         PrescalerCode = IWDG_PRESCALER_8;
00047         Prescaler = 8;
00048     }
00049     else if ((timeout * (LsiFreq/16)) < 0xFF0) {
00050         PrescalerCode = IWDG_PRESCALER_16;
00051         Prescaler = 16;
00052     }
00053     else if ((timeout * (LsiFreq/32)) < 0xFF0) {
00054         PrescalerCode = IWDG_PRESCALER_32;
00055         Prescaler = 32;
00056     }
00057     else if ((timeout * (LsiFreq/64)) < 0xFF0) {
00058         PrescalerCode = IWDG_PRESCALER_64;
00059         Prescaler = 64;
00060     }
00061     else if ((timeout * (LsiFreq/128)) < 0xFF0) {
00062         PrescalerCode = IWDG_PRESCALER_128;
00063         Prescaler = 128;
00064     }
00065     else {
00066         PrescalerCode = IWDG_PRESCALER_256;
00067         Prescaler = 256;
00068     }
00069     
00070     // specifies the IWDG Reload value. This parameter must be a number between 0 and 0x0FFF.
00071     ReloadValue = (uint32_t)(timeout * (LsiFreq/Prescaler));
00072     
00073     Calculated_timeout = ((float)(Prescaler * ReloadValue)) / LsiFreq;
00074     tr_debug("WATCHDOG set with prescaler:%d reload value: 0x%X - timeout:%f\n",Prescaler, ReloadValue, Calculated_timeout);
00075     
00076     IWDG->KR = 0x5555; //Disable write protection of IWDG registers      
00077     IWDG->PR = PrescalerCode;      //Set PR value      
00078     IWDG->RLR = ReloadValue;      //Set RLR value      
00079     IWDG->KR = 0xAAAA;    //Reload IWDG      
00080     IWDG->KR = 0xCCCC;    //Start IWDG - See more at: http://embedded-lab.com/blog/?p=9662#sthash.6VNxVSn0.dpuf       
00081  
00082     Pet();
00083 }
00084 
00085 /// "Pet", "kick" or "feed" the dog - reset the watchdog timer
00086 /// by writing this required bit pattern
00087 void Watchdog::Pet() { 
00088     IWDG->KR = 0xAAAA;         //Reload IWDG - See more at: http://embedded-lab.com/blog/?p=9662#sthash.6VNxVSn0.dpuf
00089 }
00090 
00091 /// get the flag to indicate if the watchdog causes the reset
00092 bool Watchdog::WatchdogCausedReset() {
00093     return wdreset;
00094 }