From 85555cf6cfc8bd0491978d5d54277b0f6e2f39c9 Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Mon, 17 Aug 2015 11:02:06 -0600 Subject: [PATCH 1/4] Made cc26xx WDT reload configurable with macro CONTIKI_WATCHDOG_TIMER_TOP sets the reload value of the WDT --- cpu/cc26xx-cc13xx/dev/contiki-watchdog.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c index 471c6f3cb..401b5637e 100644 --- a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c +++ b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c @@ -42,9 +42,16 @@ * \file * Implementation of the CC13xx/CC26xx watchdog driver. */ -#include "watchdog.h" +#include "contiki.h" +#include "dev/watchdog.h" #include "ti-lib.h" /*---------------------------------------------------------------------------*/ +#ifdef CONTIKI_WATCHDOG_CONF_TIMER_TOP +#define CONTIKI_WATCHDOG_TIMER_TOP CONTIKI_WATCHDOG_CONF_TIMER_TOP +#else +#define CONTIKI_WATCHDOG_TIMER_TOP 0xFFFFF +#endif +/*---------------------------------------------------------------------------*/ /** * \brief Initialises the CC26xx WDT * @@ -54,7 +61,7 @@ void watchdog_init(void) { - ti_lib_watchdog_reload_set(0xFFFFF); + ti_lib_watchdog_reload_set(CONTIKI_WATCHDOG_TIMER_TOP); } /*---------------------------------------------------------------------------*/ /** From dfdb0a6487a7acca907af22eca515d3fd159c218 Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Mon, 17 Aug 2015 11:09:30 -0600 Subject: [PATCH 2/4] cc26xx - fixed WDT reloading According to the TRM, the WDT does not produce a reset until it expires twice. After expiring the WDT will set the INT flag if it is unset, and reset the MCU if INT is already set. Before this patch, watchdog_periodic() only un-sets the INT flag. This means that the behaviour of watchdog_periodic is underministic in that the value of the countdown timer will be different depending on when the function was called. This patch fixes this behaviour by also reloading the timout value. --- cpu/cc26xx-cc13xx/dev/contiki-watchdog.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c index 401b5637e..5b67df2e1 100644 --- a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c +++ b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c @@ -79,6 +79,7 @@ watchdog_start(void) void watchdog_periodic(void) { + ti_lib_watchdog_reload_set(CONTIKI_WATCHDOG_TIMER_TOP); ti_lib_watchdog_int_clear(); } /*---------------------------------------------------------------------------*/ From 22d8a8dd563c4c900005b987fa287b1314cb3667 Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Mon, 17 Aug 2015 11:11:30 -0600 Subject: [PATCH 3/4] cc26xx - implemented watchdog_stop Also modified watchdog_start so that if we stop and start again the watchdog timeout will be reset (by calling watchdog_periodic). --- cpu/cc26xx-cc13xx/dev/contiki-watchdog.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c index 5b67df2e1..e12561869 100644 --- a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c +++ b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c @@ -70,6 +70,7 @@ watchdog_init(void) void watchdog_start(void) { + watchdog_periodic(); ti_lib_watchdog_reset_enable(); } /*---------------------------------------------------------------------------*/ @@ -83,6 +84,15 @@ watchdog_periodic(void) ti_lib_watchdog_int_clear(); } /*---------------------------------------------------------------------------*/ +/** + * \brief Stops the WDT such that it won't timeout and cause MCU reset + */ +void +watchdog_stop(void) +{ + ti_lib_watchdog_reset_disable(); +} +/*---------------------------------------------------------------------------*/ /** * \brief Manually trigger a WDT reboot */ From fde3202a3f593641f879b27881ce5bcb44ba850c Mon Sep 17 00:00:00 2001 From: Billy Kozak Date: Mon, 17 Aug 2015 11:12:35 -0600 Subject: [PATCH 4/4] cc26xx - added optional locking mode for WDT Added a mode, configurable by the CONTIKI_WATCHDOG_CONF_LOCK_BETWEEN_USE macro, which locks the WDT register between uses so as to prevent any accidental modifications --- cpu/cc26xx-cc13xx/dev/contiki-watchdog.c | 55 ++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c index e12561869..f8eb4f666 100644 --- a/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c +++ b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c @@ -45,12 +45,58 @@ #include "contiki.h" #include "dev/watchdog.h" #include "ti-lib.h" + +#include +#include /*---------------------------------------------------------------------------*/ #ifdef CONTIKI_WATCHDOG_CONF_TIMER_TOP #define CONTIKI_WATCHDOG_TIMER_TOP CONTIKI_WATCHDOG_CONF_TIMER_TOP #else #define CONTIKI_WATCHDOG_TIMER_TOP 0xFFFFF #endif + +#ifdef CONTIKI_WATCHDOG_CONF_LOCK_CONFIG +#define CONTIKI_WATCHDOG_LOCK_CONFIG CONTIKI_WATCHDOG_CONF_LOCK_CONFIG +#else +#define CONTIKI_WATCHDOG_LOCK_CONFIG 1 +#endif + +#define LOCK_INTERRUPTS_DISABLED 0x01 +#define LOCK_REGISTERS_UNLOCKED 0x02 +/*---------------------------------------------------------------------------*/ +static uint32_t +unlock_config(void) +{ + uint32_t ret = 0; + bool int_status; + + if(CONTIKI_WATCHDOG_LOCK_CONFIG) { + int_status = ti_lib_int_master_disable(); + + if(ti_lib_watchdog_lock_state()) { + ret |= LOCK_REGISTERS_UNLOCKED; + ti_lib_watchdog_unlock(); + } + + ret |= (int_status) ? (0) : (LOCK_INTERRUPTS_DISABLED); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static void +lock_config(uint32_t status) +{ + if(CONTIKI_WATCHDOG_LOCK_CONFIG) { + + if(status & LOCK_REGISTERS_UNLOCKED) { + ti_lib_watchdog_lock(); + } + if(status & LOCK_INTERRUPTS_DISABLED) { + ti_lib_int_master_enable(); + } + } +} /*---------------------------------------------------------------------------*/ /** * \brief Initialises the CC26xx WDT @@ -62,6 +108,7 @@ void watchdog_init(void) { ti_lib_watchdog_reload_set(CONTIKI_WATCHDOG_TIMER_TOP); + lock_config(LOCK_REGISTERS_UNLOCKED); } /*---------------------------------------------------------------------------*/ /** @@ -70,8 +117,12 @@ watchdog_init(void) void watchdog_start(void) { + uint32_t lock_status = unlock_config(); + watchdog_periodic(); ti_lib_watchdog_reset_enable(); + + lock_config(lock_status); } /*---------------------------------------------------------------------------*/ /** @@ -90,7 +141,11 @@ watchdog_periodic(void) void watchdog_stop(void) { + uint32_t lock_status = unlock_config(); + ti_lib_watchdog_reset_disable(); + + lock_config(lock_status); } /*---------------------------------------------------------------------------*/ /**