Class to add reset supervision with a watchdog timer functionality
Dependents: Example_WatchDog_Timer
ResetSupervisor.cpp
- Committer:
- rlanders73
- Date:
- 2021-06-15
- Revision:
- 5:7af579ded04f
- Parent:
- 4:f31b32884780
File content as of revision 5:7af579ded04f:
/// @file Supervisor.cpp provides the interface to the Supervisor module /// /// This provides basic Supervisor service for the mbed. You can configure /// various timeout intervals that meet your system needs. Additionally, /// it is possible to identify if the Supervisor 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 "ResetSupervisor.h" #include "mbed_trace.h" #define TRACE_GROUP "WDT" /// Supervisor gets instantiated at the module level Supervisor::Supervisor() { // capture the cause of the previous reset if(__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST))// BOR reset rstRsn = RCC_FLAG_BORRST; // else if(__HAL_RCC_GET_FLAG(RCC_FLAG_OBLRST))// OBLRST reset // rstRsn = RCC_FLAG_OBLRST; else if(__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST))// Pin reset rstRsn = RCC_FLAG_PINRST; // else if(__HAL_RCC_GET_FLAG(RCC_FLAG_FWRST))// FIREWALL reset // rstRsn = RCC_FLAG_FWRST; else if(__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST))// Software reset rstRsn = RCC_FLAG_SFTRST; else if(__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST))// Independent Supervisor reset rstRsn = RCC_FLAG_IWDGRST; else if(__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST))// Window Supervisor reset rstRsn = RCC_FLAG_WWDGRST; else if(__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST))// Low Power reset rstRsn = RCC_FLAG_LPWRRST; //Clear source Reset Flag __HAL_RCC_CLEAR_RESET_FLAGS(); } /// Load timeout value in watchdog timer and enable void Supervisor::initWD(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 pingWD(); } /// "Ping", "kick" or "feed" the dog - reset the watchdog timer /// by writing this required bit pattern void Supervisor::pingWD() { IWDG->KR = 0xAAAA; //Reload IWDG - See more at: http://embedded-lab.com/blog/?p=9662#sthash.6VNxVSn0.dpuf } uint8_t Supervisor::resetReason(){ return rstRsn; } void Supervisor::doReset() { NVIC_SystemReset(); // pull the plug }