Revised for integration

Dependents:   Integrated wheelchairControlSumer2019 wheelchairControlSumer2019 wheelchaircontrol5 ... more

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 /// @note Copyright © 2011 by Smartware Computing, all rights reserved.
00011 ///     This software may be used to derive new software, as long as
00012 ///     this copyright statement remains in the source file.
00013 /// @author David Smart
00014 ///
00015 /// @note Copyright © 2015 by NBRemond, all rights reserved.
00016 ///     This software may be used to derive new software, as long as
00017 ///     this copyright statement remains in the source file.
00018 ///
00019 ///     Added support for STM32 Nucleo platforms
00020 ///
00021 /// @author Bernaérd Remond
00022 ///
00023 
00024 //#define LPC
00025 #define ST_NUCLEO
00026 
00027 
00028 #include "mbed.h"
00029 #include "Watchdog.h"
00030 
00031 
00032 /// Watchdog gets instantiated at the module level
00033 Watchdog::Watchdog() {
00034 #ifdef LPC    
00035     wdreset = (LPC_WDT->WDMOD >> 2) & 1;    // capture the cause of the previous reset
00036 #endif
00037 #ifdef ST_NUCLEO
00038     // capture the cause of the previous reset
00039     /* Check if the system has resumed from IWDG reset */
00040 /*
00041     if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST)) {
00042         wdreset = true;
00043     }
00044     else {
00045         wdreset = false; 
00046     }
00047 */       
00048         printf("in constructor\r\n");
00049         wdreset = false; 
00050 #endif
00051 
00052 }
00053 
00054 /// Load timeout value in watchdog timer and enable
00055 void Watchdog::Configure(float timeout) {
00056 #ifdef LPC    
00057     LPC_WDT->WDCLKSEL = 0x1;                // Set CLK src to PCLK
00058     uint32_t clk = SystemCoreClock / 16;    // WD has a fixed /4 prescaler, PCLK default is /4
00059     LPC_WDT->WDTC = (uint32_t)(timeout * (float)clk);
00060     LPC_WDT->WDMOD = 0x3;                   // Enabled and Reset
00061 #endif  
00062  
00063 #ifdef ST_NUCLEO
00064     // see http://embedded-lab.com/blog/?p=9662    
00065     #define LsiFreq (45000)
00066     uint16_t PrescalerCode;
00067     uint16_t Prescaler;
00068     uint16_t ReloadValue;
00069     float Calculated_timeout;
00070     
00071     if ((timeout * (LsiFreq/4)) < 0x7FF) {
00072         PrescalerCode = IWDG_PRESCALER_4;
00073         Prescaler = 4;
00074     }
00075     else if ((timeout * (LsiFreq/8)) < 0xFF0) {
00076         PrescalerCode = IWDG_PRESCALER_8;
00077         Prescaler = 8;
00078     }
00079     else if ((timeout * (LsiFreq/16)) < 0xFF0) {
00080         PrescalerCode = IWDG_PRESCALER_16;
00081         Prescaler = 16;
00082     }
00083     else if ((timeout * (LsiFreq/32)) < 0xFF0) {
00084         PrescalerCode = IWDG_PRESCALER_32;
00085         Prescaler = 32;
00086     }
00087     else if ((timeout * (LsiFreq/64)) < 0xFF0) {
00088         PrescalerCode = IWDG_PRESCALER_64;
00089         Prescaler = 64;
00090     }
00091     else if ((timeout * (LsiFreq/128)) < 0xFF0) {
00092         PrescalerCode = IWDG_PRESCALER_128;
00093         Prescaler = 128;
00094     }
00095     else {
00096         PrescalerCode = IWDG_PRESCALER_256;
00097         Prescaler = 256;
00098     }
00099     
00100     // specifies the IWDG Reload value. This parameter must be a number between 0 and 0x0FFF.
00101     ReloadValue = (uint32_t)(timeout * (LsiFreq/Prescaler));
00102     
00103     Calculated_timeout = ((float)(Prescaler * ReloadValue)) / LsiFreq;
00104     printf("WATCHDOG set with prescaler:%d reload value: 0x%X - timeout:%f\n",Prescaler, ReloadValue, Calculated_timeout);
00105     
00106     IWDG->KR = 0x5555; //Disable write protection of IWDG registers      
00107     IWDG->PR = PrescalerCode;      //Set PR value      
00108     IWDG->RLR = ReloadValue;      //Set RLR value      
00109     IWDG->KR = 0xAAAA;    //Reload IWDG      
00110     IWDG->KR = 0xCCCC;    //Start IWDG - See more at: http://embedded-lab.com/blog/?p=9662#sthash.6VNxVSn0.dpuf       
00111 #endif
00112  
00113     Service();
00114 }
00115 
00116 /// "Service", "kick" or "feed" the dog - reset the watchdog timer
00117 /// by writing this required bit pattern
00118 void Watchdog::Service() {
00119 #ifdef LPC    
00120     LPC_WDT->WDFEED = 0xAA;
00121     LPC_WDT->WDFEED = 0x55;
00122 #endif    
00123 #ifdef ST_NUCLEO
00124     IWDG->KR = 0xAAAA;         //Reload IWDG - See more at: http://embedded-lab.com/blog/?p=9662#sthash.6VNxVSn0.dpuf
00125 #endif
00126 }
00127 
00128 /// get the flag to indicate if the watchdog causes the reset
00129 bool Watchdog::WatchdogCausedReset() {
00130     return wdreset;
00131 }