a
Fork of Watchdog by
Diff: Watchdog.cpp
- Revision:
- 5:ea5595e2698b
- Parent:
- 3:5959d3d35221
- Child:
- 6:40f189c7795b
--- a/Watchdog.cpp Sat Oct 11 17:28:07 2014 +0000 +++ b/Watchdog.cpp Mon Mar 02 21:33:58 2015 +0000 @@ -12,29 +12,116 @@ /// this copyright statement remains in the source file. /// @author David Smart /// +/// @note Copyright © 2015 by NBRemond, all rights reserved. +/// This software may be used to derive new software, as long as +/// this copyright statement remains in the source file. +/// +/// Added support for STM32 Nucleo platforms +/// +/// @author Bernaérd Remond +/// + +//#define LPC +#define ST_NUCLEO + + #include "mbed.h" #include "Watchdog.h" /// Watchdog gets instantiated at the module level Watchdog::Watchdog() { +#ifdef LPC wdreset = (LPC_WDT->WDMOD >> 2) & 1; // capture the cause of the previous reset +#endif +#ifdef ST_NUCLEO + // capture the cause of the previous reset + /* Check if the system has resumed from IWDG reset */ +/* + if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST)) { + wdreset = true; + } + else { + wdreset = false; + } +*/ + wdreset = false; +#endif + } /// Load timeout value in watchdog timer and enable -void Watchdog::Configure(float s) { +void Watchdog::Configure(float timeout) { +#ifdef LPC LPC_WDT->WDCLKSEL = 0x1; // Set CLK src to PCLK uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4 - LPC_WDT->WDTC = (uint32_t)(s * (float)clk); + LPC_WDT->WDTC = (uint32_t)(timeout * (float)clk); LPC_WDT->WDMOD = 0x3; // Enabled and Reset +#endif +#ifdef ST_NUCLEO + // see http://embedded-lab.com/blog/?p=9662 + #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; + printf("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 +#endif + Service(); } /// "Service", "kick" or "feed" the dog - reset the watchdog timer /// by writing this required bit pattern void Watchdog::Service() { +#ifdef LPC LPC_WDT->WDFEED = 0xAA; LPC_WDT->WDFEED = 0x55; +#endif +#ifdef ST_NUCLEO + IWDG->KR = 0xAAAA; //Reload IWDG - See more at: http://embedded-lab.com/blog/?p=9662#sthash.6VNxVSn0.dpuf +#endif } /// get the flag to indicate if the watchdog causes the reset