Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Watchdog by
Diff: Watchdog.cpp
- Revision:
- 7:3814d72b8166
- Parent:
- 5:2dad2a78ffbd
- Child:
- 8:ea82a76ca81f
diff -r e0f547e22dd5 -r 3814d72b8166 Watchdog.cpp
--- a/Watchdog.cpp Mon Mar 16 01:04:32 2015 +0000
+++ b/Watchdog.cpp Tue Sep 13 17:01:18 2016 +0000
@@ -12,7 +12,8 @@
/// this copyright statement remains in the source file.
/// @author David Smart
///
-#include "mbed.h"
+/// \li v2.10 - 20160914: Changed TARGET_STM by mutech, t.kuroki
+
#include "Watchdog.h"
#if defined( TARGET_LPC1768 )
@@ -30,6 +31,14 @@
Service();
}
+void Watchdog::Configure(int 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->WDMOD = 0x3; // Enabled and Reset
+ Service();
+}
+
/// "Service", "kick" or "feed" the dog - reset the watchdog timer
/// by writing this required bit pattern
void Watchdog::Service() {
@@ -56,7 +65,15 @@
LPC_WDT->MOD = 0x3; // Enabled and Reset
Service();
}
-
+
+void Watchdog::Configure(int 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 = (ms * clk) / 1000;
+ LPC_WDT->MOD = 0x3; // Enabled and Reset
+ Service();
+}
+
/// "Service", "kick" or "feed" the dog - reset the watchdog timer
/// by writing this required bit pattern
void Watchdog::Service() {
@@ -68,31 +85,100 @@
bool Watchdog::WatchdogCausedReset() {
return wdreset;
}
-#elif defined( TARGET_STM )
-// Derived from Chau Vo
-/// Watchdog gets instantiated at the module level
-Watchdog::Watchdog() {
+#elif defined(TARGET_STM)
+Watchdog::Watchdog()
+{
wdreset = (RCC->CSR & (1<<29)) ? true : false; // read the IWDGRSTF (Independent WD, not the windows WD)
}
+// 最大有効ビット数(MSB:Most Significant Bit)
+int Watchdog::MSB16bit(uint16_t v)
+{
+ v |= (v >> 1);
+ v |= (v >> 2);
+ v |= (v >> 4);
+ v |= (v >> 8);
+// return count16bit(v) - 1;
+// 立っているビットの数を数える
+ 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;
+}
+
+// 整数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
+
/// Load timeout value in watchdog timer and enable
-void Watchdog::Configure(int pr) {
+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
+ // RC clock would have an average frequency of 40 kHz (variable between 30 and 60 kHz)
+ int scale = calcExponent16bit(((int)s + 4095) / 4096);
+ if (scale < 2)
+ scale = 2;
+ int residual = s / (1 << scale); // The value for the RLR register
+ if (residual < 1)
+ residual = 1;
+
+ if (scale > 8) //STM32 allows a maximum time of around 26.2 seconds for the Watchdog timer
+ {
+ scale = 8;
+ residual = 4096;
+ }
+
IWDG->KR = 0x5555; // enable write to PR, RLR
- IWDG->PR = pr; // Init prescaler, page 486 Reference Manual
- IWDG->RLR = 0xFFF; // Init 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)
+{
+ // 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);
+ if (scale < 2)
+ scale = 2;
+ int residual = ms / (1 << scale); // The value for the RLR register
+ if (residual < 1)
+ residual = 1;
+
+ if (scale > 8) // STM32 allows a maximum time of around 26.2 seconds for the Watchdog timer
+ {
+ scale = 8;
+ 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
}
/// "Service", "kick" or "feed" the dog - reset the watchdog timer
-void Watchdog::Service() {
+void Watchdog::Service()
+{
IWDG->KR = 0xAAAA;
}
/// get the flag to indicate if the watchdog causes the reset
-bool Watchdog::WatchdogCausedReset() {
- if (wdreset) {
+bool Watchdog::WatchdogCausedReset()
+{
+ if (wdreset)
+ {
RCC->CSR |= (1<<24); // clear reset flag
}
return wdreset;
