Tomonori Kuroki / MuWatchdog

Fork of Watchdog by David Smart

Revision:
11:a1611543c454
Parent:
10:673dff2b0ee6
Child:
12:c1640aef1db5
--- a/Watchdog.cpp	Wed Sep 14 07:14:43 2016 +0000
+++ b/Watchdog.cpp	Wed Sep 14 14:25:34 2016 +0000
@@ -1,4 +1,4 @@
-/// @file Watchdog.cpp provides the interface to the Watchdog module
+    /// @file Watchdog.cpp provides the interface to the Watchdog module
 ///
 /// This provides basic Watchdog service for the mbed. You can configure
 /// various timeout intervals that meet your system needs. Additionally,
@@ -85,17 +85,20 @@
 bool Watchdog::WatchdogCausedReset() {
     return wdreset;
 }
-
 #elif defined(TARGET_STM)
-
 Watchdog::Watchdog()
 {
     wdreset = (RCC->CSR & (1<<29)) ? true : false;  // read the IWDGRSTF (Independent WD, not the windows WD)
 }
 
+// 整数Xを含む最小のべき乗指数
+int Watchdog::calcExponent16bit(uint16_t v)
+{
+//  return (v == 0) ? 0 : MSB16bit(v - 1) + 1;
+    if (!v)
+        return 0;
+    --v;
 // 最大有効ビット数(MSB:Most Significant Bit)
-int Watchdog::MSB16bit(uint16_t v)
-{
     v |= (v >> 1);
     v |= (v >> 2);
     v |= (v >> 4);
@@ -105,44 +108,32 @@
     v = (v & 0x5555) + ((v >> 1) & 0x5555);
     v = (v & 0x3333) + ((v >> 2) & 0x3333);
     v = (v & 0x0f0f) + ((v >> 4) & 0x0f0f);
-    return  (v & 0x00ff) + ((v >> 8) & 0x00ff) - 1;
+    return  (v & 0x00ff) + ((v >> 8) & 0x00ff);
 }
 
-// 整数Xを含む最小のべき乗指数
-int Watchdog::calcExponent16bit(uint16_t v)
-{
-    return (v == 0) ? 0 : MSB16bit(v - 1) + 1;
-}
-
-#define WDT_CLOCK     32768       // 32.768 kHz
-//#define WDT_CLOCK       40000       // 40 kHz
+//#define WDT_CLOCK     32768U      // 32.768 kHz
+#define WDT_CLOCK       40000U      // 40 kHz
 
 /// Load timeout value in watchdog timer and enable
 void Watchdog::Configure(float s)
 {
     // http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf
 
-    s = s * WDT_CLOCK;          // Newer Nucleo boards have 32.768 kHz crystal. Without it, the internal 
+    // 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)
-    int scale = calcExponent16bit(((int)s + 4095) / 4096);
-    int residual;               // The value for the RLR register
-
+    uint32_t tick = (uint32_t)(s * WDT_CLOCK + 0.5f);
+    // 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;
-        residual = 1;
-    }
     else if (scale > 8)         // STM32 allows a maximum time of around 26.2 seconds for the Watchdog timer
-    {
         scale = 8;
+
+    int residual = tick / (1 << scale);   // The value for the RLR register
+    if (residual < 1)
+        residual = 1;
+    else if (residual > 4096)
         residual = 4096;
-    }
-    else
-    {
-        residual = s / (1 << scale);   // The value for the RLR register
-        if (residual < 1)
-            residual = 1;
-    }
 
     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
@@ -154,28 +145,23 @@
 void Watchdog::Configure(int ms)
 {
     // http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf
-    ms = (ms * WDT_CLOCK) / 1000;   // 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)
 
-    int scale = calcExponent16bit((ms + 4095) >> 12);
-    int residual;               // The value for the RLR register
+    // 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;
 
-    if (scale < 2)
-    {
-        scale = 2;
+    int residual = tick / (1 << scale);   // The value for the RLR register
+    if (residual < 1)
         residual = 1;
-    }
-    else if (scale > 8)         // STM32 allows a maximum time of around 26.2 seconds for the Watchdog timer
-    {
-        scale = 8;
+    else if (residual > 4096)
         residual = 4096;
-    }
-    else
-    {
-        residual = ms / (1 << scale);   // The value for the RLR register
-        if (residual < 1)
-            residual = 1;
-    }
 
     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