From 4725d750546b5bb2c6abf20fa213b06742eb9766 Mon Sep 17 00:00:00 2001 From: Bob Cousins Date: Sun, 27 Jul 2014 13:01:40 +0100 Subject: [PATCH 1/3] Add watchdog routines for Due. --- .../sam/variants/arduino_due_x/variant.cpp | 50 ++++++++++++++++++- .../sam/variants/arduino_due_x/variant.h | 20 ++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/hardware/arduino/sam/variants/arduino_due_x/variant.cpp b/hardware/arduino/sam/variants/arduino_due_x/variant.cpp index 4cbe0df80..999b5d4f7 100644 --- a/hardware/arduino/sam/variants/arduino_due_x/variant.cpp +++ b/hardware/arduino/sam/variants/arduino_due_x/variant.cpp @@ -358,6 +358,52 @@ void serialEventRun(void) if (Serial3.available()) serialEvent3(); } +// ---------------------------------------------------------------------------- +extern "C" { + +/** + * Watchdog enable + * + * Enable the watchdog timer with the specified settings. + * WDTO_xxx macros provide standard settings. + * Should only be called once. + */ +void wdt_enable (uint32_t mode) +{ + WDT_Enable (WDT, mode); +} + +/** + * Watchdog disable + * + * Disable the watchdog timer. + * Should only be called once. + */ +void wdt_disable(void) +{ + WDT_Disable (WDT); +} + +/** + * Watchdog reset + * + * Resets the watchdog counter + */ +void wdt_reset(void) +{ + WDT_Restart (WDT); +} + +} // extern "C" + +/** + * Watchdog initialize hook + * + * This function is called from init(). + * Default action is to disable watchdog. + */ +void wdt_initialize(void) __attribute__ ((weak, alias("wdt_disable"))); + // ---------------------------------------------------------------------------- #ifdef __cplusplus @@ -377,8 +423,8 @@ void init( void ) while (true); } - // Disable watchdog - WDT_Disable(WDT); + // Initialize watchdog + wdt_initialize(); // Initialize C library __libc_init_array(); diff --git a/hardware/arduino/sam/variants/arduino_due_x/variant.h b/hardware/arduino/sam/variants/arduino_due_x/variant.h index 6725a139c..d265255e4 100644 --- a/hardware/arduino/sam/variants/arduino_due_x/variant.h +++ b/hardware/arduino/sam/variants/arduino_due_x/variant.h @@ -232,6 +232,25 @@ static const uint8_t CAN1TX = 89; #define TC_MIN_DUTY_CYCLE 0 #define TC_RESOLUTION 8 +// Watchdog routines + +#define WDTO_15MS WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(4) | WDT_MR_WDD(4) +#define WDTO_30MS WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(8) | WDT_MR_WDD(8) +#define WDTO_60MS WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(15) | WDT_MR_WDD(15) +#define WDTO_120MS WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(31) | WDT_MR_WDD(31) +#define WDTO_250MS WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(64) | WDT_MR_WDD(64) +#define WDTO_500MS WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(128) | WDT_MR_WDD(128) +#define WDTO_1S WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(256) | WDT_MR_WDD(256) +#define WDTO_2S WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(512) | WDT_MR_WDD(512) +#define WDTO_4S WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(1024) | WDT_MR_WDD(1024) +#define WDTO_8S WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(2048) | WDT_MR_WDD(2048) + +void wdt_enable (uint32_t mode); + +void wdt_disable(void); + +void wdt_reset(void); + #ifdef __cplusplus } #endif @@ -274,5 +293,6 @@ extern USARTClass Serial3; #define SERIAL_PORT_HARDWARE2 Serial2 #define SERIAL_PORT_HARDWARE3 Serial3 + #endif /* _VARIANT_ARDUINO_DUE_X_ */ From d2c510d16686d16baf97534f1dc93ac949ecac44 Mon Sep 17 00:00:00 2001 From: Bob Cousins Date: Thu, 15 Jan 2015 19:02:25 +0000 Subject: [PATCH 2/3] Add Due watchdog functions; modified according to feedback supplied --- hardware/arduino/sam/cores/arduino/Arduino.h | 2 + hardware/arduino/sam/cores/arduino/main.cpp | 3 + .../arduino/sam/cores/arduino/watchdog.cpp | 55 +++++++++++++++++++ hardware/arduino/sam/cores/arduino/watchdog.h | 52 ++++++++++++++++++ .../sam/variants/arduino_due_x/variant.cpp | 49 ----------------- .../sam/variants/arduino_due_x/variant.h | 20 ------- 6 files changed, 112 insertions(+), 69 deletions(-) create mode 100644 hardware/arduino/sam/cores/arduino/watchdog.cpp create mode 100644 hardware/arduino/sam/cores/arduino/watchdog.h diff --git a/hardware/arduino/sam/cores/arduino/Arduino.h b/hardware/arduino/sam/cores/arduino/Arduino.h index ba63d6c71..f074d5b27 100644 --- a/hardware/arduino/sam/cores/arduino/Arduino.h +++ b/hardware/arduino/sam/cores/arduino/Arduino.h @@ -194,6 +194,8 @@ extern const PinDescription g_APinDescription[] ; #include "wiring_shift.h" #include "WInterrupts.h" +#include "watchdog.h" + // USB Device #define USB_VID 0x2341 // arduino LLC vid #define USB_PID_LEONARDO 0x0034 diff --git a/hardware/arduino/sam/cores/arduino/main.cpp b/hardware/arduino/sam/cores/arduino/main.cpp index ab125365d..9b0250bfb 100644 --- a/hardware/arduino/sam/cores/arduino/main.cpp +++ b/hardware/arduino/sam/cores/arduino/main.cpp @@ -41,6 +41,9 @@ void initVariant() { } */ int main( void ) { + // Initialize watchdog + watchdogSetup(); + init(); initVariant(); diff --git a/hardware/arduino/sam/cores/arduino/watchdog.cpp b/hardware/arduino/sam/cores/arduino/watchdog.cpp new file mode 100644 index 000000000..6516631e2 --- /dev/null +++ b/hardware/arduino/sam/cores/arduino/watchdog.cpp @@ -0,0 +1,55 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include "watchdog.h" + + +void watchdogEnable (uint32_t timeout) +{ + /* this assumes the slow clock is running at 32.768 kHz + watchdog frequency is therefore 32768 / 128 = 256 Hz */ + timeout = timeout * 256 / 1000; + if (timeout == 0) + timeout = 1; + else if (timeout > 0xFFF) + timeout = 0xFFF; + timeout = WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(timeout) | WDT_MR_WDD(timeout); + WDT_Enable (WDT, timeout); +} + +void watchdogDisable(void) +{ + WDT_Disable (WDT); +} + +void watchdogReset(void) +{ + WDT_Restart (WDT); +} + + +extern "C" +void _watchdogDefaultSetup (void) +{ + WDT_Disable (WDT); +} +void watchdogSetup (void) __attribute__ ((weak, alias("_watchdogDefaultSetup"))); + + diff --git a/hardware/arduino/sam/cores/arduino/watchdog.h b/hardware/arduino/sam/cores/arduino/watchdog.h new file mode 100644 index 000000000..eecdb8974 --- /dev/null +++ b/hardware/arduino/sam/cores/arduino/watchdog.h @@ -0,0 +1,52 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WATCHDOG_ +#define _WATCHDOG_ + +#include + +// Watchdog functions + +/* + * \brief Enable the watchdog with the specified timeout. Should only be called once. + * + * \param timeount in milliseconds. + */ +void watchdogEnable (uint32_t timeout); + +/* + * \brief Disable the watchdog timer. Should only be called once. + * + */ +void watchdogDisable (void); + +/* + * \brief Reset the watchdog counter. + * + */ +void watchdogReset (void); + +/* + * \brief Watchdog initialize hook. This function is called from init(). If the user does not provide + * this function, then the default action is to disable watchdog. + */ +void watchdogSetup (void); + +#endif /* _WATCHDOG_ */ + diff --git a/hardware/arduino/sam/variants/arduino_due_x/variant.cpp b/hardware/arduino/sam/variants/arduino_due_x/variant.cpp index 999b5d4f7..f95d85017 100644 --- a/hardware/arduino/sam/variants/arduino_due_x/variant.cpp +++ b/hardware/arduino/sam/variants/arduino_due_x/variant.cpp @@ -358,52 +358,6 @@ void serialEventRun(void) if (Serial3.available()) serialEvent3(); } -// ---------------------------------------------------------------------------- -extern "C" { - -/** - * Watchdog enable - * - * Enable the watchdog timer with the specified settings. - * WDTO_xxx macros provide standard settings. - * Should only be called once. - */ -void wdt_enable (uint32_t mode) -{ - WDT_Enable (WDT, mode); -} - -/** - * Watchdog disable - * - * Disable the watchdog timer. - * Should only be called once. - */ -void wdt_disable(void) -{ - WDT_Disable (WDT); -} - -/** - * Watchdog reset - * - * Resets the watchdog counter - */ -void wdt_reset(void) -{ - WDT_Restart (WDT); -} - -} // extern "C" - -/** - * Watchdog initialize hook - * - * This function is called from init(). - * Default action is to disable watchdog. - */ -void wdt_initialize(void) __attribute__ ((weak, alias("wdt_disable"))); - // ---------------------------------------------------------------------------- #ifdef __cplusplus @@ -423,9 +377,6 @@ void init( void ) while (true); } - // Initialize watchdog - wdt_initialize(); - // Initialize C library __libc_init_array(); diff --git a/hardware/arduino/sam/variants/arduino_due_x/variant.h b/hardware/arduino/sam/variants/arduino_due_x/variant.h index d265255e4..6725a139c 100644 --- a/hardware/arduino/sam/variants/arduino_due_x/variant.h +++ b/hardware/arduino/sam/variants/arduino_due_x/variant.h @@ -232,25 +232,6 @@ static const uint8_t CAN1TX = 89; #define TC_MIN_DUTY_CYCLE 0 #define TC_RESOLUTION 8 -// Watchdog routines - -#define WDTO_15MS WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(4) | WDT_MR_WDD(4) -#define WDTO_30MS WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(8) | WDT_MR_WDD(8) -#define WDTO_60MS WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(15) | WDT_MR_WDD(15) -#define WDTO_120MS WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(31) | WDT_MR_WDD(31) -#define WDTO_250MS WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(64) | WDT_MR_WDD(64) -#define WDTO_500MS WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(128) | WDT_MR_WDD(128) -#define WDTO_1S WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(256) | WDT_MR_WDD(256) -#define WDTO_2S WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(512) | WDT_MR_WDD(512) -#define WDTO_4S WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(1024) | WDT_MR_WDD(1024) -#define WDTO_8S WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(2048) | WDT_MR_WDD(2048) - -void wdt_enable (uint32_t mode); - -void wdt_disable(void); - -void wdt_reset(void); - #ifdef __cplusplus } #endif @@ -293,6 +274,5 @@ extern USARTClass Serial3; #define SERIAL_PORT_HARDWARE2 Serial2 #define SERIAL_PORT_HARDWARE3 Serial3 - #endif /* _VARIANT_ARDUINO_DUE_X_ */ From 7f8cba667def55bb80d9f5957c89d51611fceb46 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 5 Mar 2015 11:30:00 +0100 Subject: [PATCH 3/3] Due watchdog: change flags to effectively reset board --- hardware/arduino/sam/cores/arduino/watchdog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware/arduino/sam/cores/arduino/watchdog.cpp b/hardware/arduino/sam/cores/arduino/watchdog.cpp index 6516631e2..942ba1372 100644 --- a/hardware/arduino/sam/cores/arduino/watchdog.cpp +++ b/hardware/arduino/sam/cores/arduino/watchdog.cpp @@ -30,7 +30,7 @@ void watchdogEnable (uint32_t timeout) timeout = 1; else if (timeout > 0xFFF) timeout = 0xFFF; - timeout = WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(timeout) | WDT_MR_WDD(timeout); + timeout = WDT_MR_WDRSTEN | WDT_MR_WDV(timeout) | WDT_MR_WDD(timeout); WDT_Enable (WDT, timeout); }