Tomonori Kuroki / MuWatchdog

Fork of Watchdog by David Smart

Revision:
30:c02c2a15ce8f
Parent:
29:d84c025e8c8e
diff -r d84c025e8c8e -r c02c2a15ce8f Watchdog.cpp
--- a/Watchdog.cpp	Sun Jun 09 16:58:02 2019 +0000
+++ b/Watchdog.cpp	Wed Jan 15 01:22:53 2020 +0000
@@ -14,9 +14,11 @@
 ///
 /// \li v2.10 - 20160914: Changed TARGET_STM by mutech, t.kuroki
 
+/// 2020-01-15 mbed-os5 compatible routones added. by mutech, t.luroki
+
 #include "Watchdog.h"
 
-//-----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 #if defined( TARGET_LPC1768 )
 /// Watchdog gets instantiated at the module level
 Watchdog::Watchdog()
@@ -24,41 +26,54 @@
     _wdreset = (LPC_WDT->WDMOD >> 2) & 1;    // capture the cause of the previous reset
 }
 
-/// Load timeout value in watchdog timer and enable
-void Watchdog::begin(float sec)
-{
-    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)(sec * (float)clk);
-    LPC_WDT->WDMOD = 0x3;                   // Enabled and Reset
-    restart();
-}
-
-void Watchdog::begin(uint32_t ms)
+// mbed-os5 compatible routines
+bool Watchdog::start(uint32_t timeout_ms)
 {
     LPC_WDT->WDCLKSEL = 0x1;                // Set CLK src to PCLK
     uint32_t clk = SystemCoreClock / 1000;  // 
-    LPC_WDT->WDTC = (ms * clk) / 16;        // WD has a fixed /4 prescaler, PCLK default is /4
+    LPC_WDT->WDTC = (timeout_ms * clk) / 16; // WD has a fixed /4 prescaler, PCLK default is /4
     LPC_WDT->WDMOD = 0x3;                   // Enabled and Reset
-    restart();
+    kick();
+    return true;
 }
 
-/// "Service", "kick" or "feed" the dog - reset the watchdog timer
-/// by writing this required bit pattern
-void Watchdog::restart()
+bool Watchdog::stop(void)
+{
+    return false;
+}
+
+void Watchdog::kick(void)
 {
     LPC_WDT->WDFEED = 0xAA;
     LPC_WDT->WDFEED = 0x55;
 }
 
+// deprecated routines
+/// Load timeout value in watchdog timer and enable
+void Watchdog::Configure(float s)
+{
+    start((uint32_t)(s * 1000.0f));
+}
+
+void Watchdog::Configure(int ms)
+{
+    start(static_cast<uint32_t>(ms));
+}
+
+/// "Service", "kick" or "feed" the dog - reset the watchdog timer
+/// by writing this required bit pattern
+void Watchdog::Service(void)
+{
+    kick();
+}
+
 /// get the flag to indicate if the watchdog causes the reset
-bool Watchdog::WatchdogCausedReset()
+bool Watchdog::WatchdogCausedReset(void)
 {
     return _wdreset;
 }
 
-//-----------------------------------------------------------------------------
-#elif defined( TARGET_LPC4088 )
+#elif defined(TARGET_LPC4088)
 // from Gesotec Gesotec
 /// Watchdog gets instantiated at the module level
 Watchdog::Watchdog()
@@ -66,40 +81,53 @@
     _wdreset = (LPC_WDT->MOD >> 2) & 1;    // capture the cause of the previous reset
 }
  
-/// Load timeout value in watchdog timer and enable
-void Watchdog::begin(float sec)
+// mbed-os5 compatible routines
+bool Watchdog::start(uint32_t timeout_ms)
 {
     //LPC_WDT->CLKSEL = 0x1;                // Set CLK src to PCLK
     uint32_t clk = 500000 / 4;    // WD has a fixed /4 prescaler, and a 500khz oscillator
-    LPC_WDT->TC = (uint32_t)(sec * (float)clk);
+    LPC_WDT->TC = (timeout_ms * clk) / 1000;
     LPC_WDT->MOD = 0x3;                   // Enabled and Reset
-    restart();
+    kick();
+    return true;
+}
+
+bool Watchdog::stop(void)
+{
+    return false;
 }
 
-void Watchdog::begin(uint32_t ms)
+void Watchdog::kick(void)
 {
-    //LPC_WDT->CLKSEL = 0x1;                // Set CLK src to PCLK
-    uint32_t clk = 500000 / 4;    // WD has a fixed /4 prescaler, and a 500khz oscillator
-    LPC_WDT->TC = (ms * clk) / 1000;
-    LPC_WDT->MOD = 0x3;                   // Enabled and Reset
-    restart();
+    LPC_WDT->FEED = 0xAA;
+    LPC_WDT->FEED = 0x55;
+}
+
+// deprecated routines
+/// Load timeout value in watchdog timer and enable
+void Watchdog::Configure(float s)
+{
+    start((uint32_t)(s * 1000.0f));
+}
+
+void Watchdog::Configure(int ms)
+{
+    start(static_cast<uint32_t>(ms));
 }
 
 /// "Service", "kick" or "feed" the dog - reset the watchdog timer
 /// by writing this required bit pattern
-void Watchdog::restart()
+void Watchdog::Service(void)
 {
-    LPC_WDT->FEED = 0xAA;
-    LPC_WDT->FEED = 0x55;
+    kick();
 }
  
 /// get the flag to indicate if the watchdog causes the reset
-bool Watchdog::WatchdogCausedReset()
+bool Watchdog::WatchdogCausedReset(void)
 {
     return _wdreset;
 }
 
-//-----------------------------------------------------------------------------
 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
 
 // from Gesotec Gesotec
@@ -109,31 +137,50 @@
     _wdreset = (LPC_WWDT->MOD >> 2) & 1;    // capture the cause of the previous reset
 }
  
-/// Load timeout value in watchdog timer and enable
-void Watchdog::begin(float sec)
-{
-    begin((int)(s * 1000));
-}
-
-#define WDTOSCCTRL_Val(clk, div)    ((((uint32_t)(clk)) << 5) | (((div) >> 1) - 1))
-
-void Watchdog::begin(uint32_t ms)
+// mbed-os5 compatible routines
+bool Watchdog::start(uint32_t timeout_ms)
 {
 #if 0
     uint32_t clk = get_wdtclock() / 4;    // WD has a fixed /4 prescaler, and a 500khz oscillator
-    LPC_WWDT->TC = (ms * clk) / 1000;
+    LPC_WWDT->TC = (timeout_ms * clk) / 1000;
 #else
     LPC_SYSCON->WDTOSCCTRL = WDTOSCCTRL_Val(10, 2);    // wdt_osc_clk = Fclkana/2, Fclkana = 3.5MHz
     LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 17); // Enable Clock WWDT
     LPC_SYSCON->PDRUNCFG &= ~(1 << 6);      // Enable Power WDTOSC_PD
     uint32_t clk = ((3500000/2)/4);         // COUNT = wdt_osc_clk/4
-    LPC_WWDT->TC = (ms * clk) / 1000;
+    LPC_WWDT->TC = (timeout_ms * clk) / 1000;
 #endif
     LPC_WWDT->MOD = 0x3;                    // Enabled and Reset
-    restart();
+    kick();
+    return true;
+}
+
+bool Watchdog::stop(void)
+{
+    return false;
+}
+
+void Watchdog::kick(void)
+{
+    LPC_WWDT->FEED = 0xAA;
+    LPC_WWDT->FEED = 0x55;
 }
 
-uint32_t Watchdog::get_wdtclock()
+// deprecated routines
+/// Load timeout value in watchdog timer and enable
+void Watchdog::Configure(float s)
+{
+    start((uint32_t)(s * 1000.0f));
+}
+
+#define WDTOSCCTRL_Val(clk, div)    ((((uint32_t)(clk)) << 5) | (((div) >> 1) - 1))
+
+void Watchdog::Configure(int ms)
+{
+    start(static_cast<uint32_t>(ms));
+}
+
+uint32_t Watchdog::get_wdtclock(void)
 {
 #if 0
     uint32_t wdt_osc = 0;
@@ -187,23 +234,26 @@
 
 /// "Service", "kick" or "feed" the dog - reset the watchdog timer
 /// by writing this required bit pattern
-void Watchdog::restart()
+void Watchdog::Service(void)
 {
-    LPC_WWDT->FEED = 0xAA;
-    LPC_WWDT->FEED = 0x55;
+    kick();
 }
  
 /// get the flag to indicate if the watchdog causes the reset
-bool Watchdog::WatchdogCausedReset()
+bool Watchdog::WatchdogCausedReset(void)
 {
     return _wdreset;
 }
 
-//-----------------------------------------------------------------------------
 #elif defined(TARGET_STM)
+Watchdog::Watchdog()
+{
+    _rcc_csr = RCC->CSR;
+    RCC->CSR |= RCC_CSR_RMVF; // clear reset flag
+}
 
 // 整数Xを含む最小のべき乗指数
-static int calcExponent16bit(uint16_t v)
+int Watchdog::calcExponent16bit(uint16_t v)
 {
 //  return (v == 0) ? 0 : MSB16bit(v - 1) + 1;
     if (!v)
@@ -222,12 +272,6 @@
     return  (v & 0x00ff) + ((v >> 8) & 0x00ff);
 }
 
-Watchdog::Watchdog()
-{
-    _rcc_csr = RCC->CSR;
-    RCC->CSR |= RCC_CSR_RMVF; // clear reset flag
-}
-
 #if defined(TARGET_STM32F0) || defined(TARGET_STM32F1) || defined(TARGET_STM32F3)
   #define WDT_CLOCK     40000U      // 40 kHz
 #else
@@ -235,14 +279,15 @@
   #define WDT_CLOCK     32768U      // 32.768 kHz
 #endif
 
-/// Load timeout value in watchdog timer and enable
-void Watchdog::begin(float sec)
+// mbed-os5 compatible routines
+bool Watchdog::start(uint32_t timeout_ms)
 {
     // http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf
 
     // Newer Nucleo boards have 32.768 kHz crystal. Without it, the internal 
-                                // RC clock would have an average frequency of 40 kHz (variable between 30 and 60 kHz)
-    uint32_t tick = (uint32_t)(sec * WDT_CLOCK + 0.5f);
+    // RC clock would have an average frequency of 40 kHz (variable between 30 and 60 kHz)
+//  tick = (ms / (1/WDT_CLOCK))/1000;
+    uint32_t tick = ((uint32_t)timeout_ms * WDT_CLOCK + 500U) / 1000U;
     // The RLR register is 12 bits and beyond that a prescaler should be used
     int scale = calcExponent16bit((tick + 4095) >> 12);
     if (scale < 2)
@@ -261,40 +306,35 @@
     IWDG->RLR = residual - 1;   // Init RLR
     IWDG->KR  = 0xAAAA;         // Reload the watchdog
     IWDG->KR  = 0xCCCC;         // Starts the WD
+    return true;
+}
+
+bool Watchdog::stop(void)
+{
+    return false;
 }
 
-void Watchdog::begin(uint32_t ms)
+void Watchdog::kick(void)
 {
-    // http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf
+    IWDG->KR  = 0xAAAA;
+}
 
-    // Newer Nucleo boards have 32.768 kHz crystal. Without it, the internal 
-    // RC clock would have an average frequency of 40 kHz (variable between 30 and 60 kHz)
-//  tick = (ms / (1/WDT_CLOCK))/1000;
-    uint32_t tick = ((uint32_t)ms * WDT_CLOCK + 500U) / 1000U;
-    // The RLR register is 12 bits and beyond that a prescaler should be used
-    int scale = calcExponent16bit((tick + 4095) >> 12);
-    if (scale < 2)
-        scale = 2;
-    else if (scale > 8)         // STM32 allows a maximum time of around 26.2 seconds for the Watchdog timer
-        scale = 8;
+// deprecated routines
+/// Load timeout value in watchdog timer and enable
+void Watchdog::Configure(float s)
+{
+    start((uint32_t)(s * 1000.0f));
+}
 
-    int residual = tick / (1 << scale);   // The value for the RLR register
-    if (residual < 1)
-        residual = 1;
-    else if (residual > 4096)
-        residual = 4096;
-
-    IWDG->KR  = 0x5555;         // enable write to PR, RLR
-    IWDG->PR  = scale - 2;      // Prescaler has values of multiples of 4 (i.e. 2 ^2), page 486 Reference Manual
-    IWDG->RLR = residual - 1;   // Init RLR
-    IWDG->KR  = 0xAAAA;         // Reload the watchdog
-    IWDG->KR  = 0xCCCC;         // Starts the WD
+void Watchdog::Configure(int ms)
+{
+    start(static_cast<uint32_t>(ms));
 }
 
 /// "Service", "kick" or "feed" the dog - reset the watchdog timer
-void Watchdog::restart()
+void Watchdog::Service()
 {
-    IWDG->KR  = 0xAAAA;
+    kick();
 }
 
 /// get the flag to indicate if the watchdog causes the reset
@@ -308,6 +348,5 @@
 #endif
 }
 
-//-----------------------------------------------------------------------------
 #endif
-
+//------------------------------------------------------------------------------