From 571f3d952e5d3944830ac37a427f4a4ff13ff702 Mon Sep 17 00:00:00 2001 From: Frank Benkert Date: Thu, 6 Apr 2017 09:43:07 -0600 Subject: [PATCH] SAMV7: Watchdog: fix Forbidden Window Value According the Datasheet the WDD Value is the lower bound of a so called Forbidden Window and to disable this we have to set the WDD Value greater than or equal to the WDV Value. This seems to be a bug in the datasheet. It looks like we have to set it to a greater value than the WDV to realy disable this Thing. When triggering the Watchdog faster than the (very slow) clock source of the Watchdog fires, this Forbidden Window Feature resets the System if WDD equals to WDV. This Changeset disables the Forbidden Window by setting the WDD Value to the Maximum (0xfff) Value possible. --- arch/arm/src/samv7/sam_wdt.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/arm/src/samv7/sam_wdt.c b/arch/arm/src/samv7/sam_wdt.c index e662146077..c3921df2fd 100644 --- a/arch/arm/src/samv7/sam_wdt.c +++ b/arch/arm/src/samv7/sam_wdt.c @@ -495,9 +495,22 @@ static int sam_settimeout(FAR struct watchdog_lowerhalf_s *lower, * NOTE: The Watchdog Mode Register (WDT_MR) can be written only once. Only * a processor reset resets it. Writing the WDT_MR register reloads the * timer with the newly programmed mode parameters. + * + * NOTE: The WDD Value is the lower bound of a so called Forbidden Window + * (see Datasheet for further Informations). To disable this Forbidden + * Window we have to set the WDD Value greater than or equal to WDV + * (according the Datasheet). + * + * When setting the WDD Value equal to WDV we have to wait at least one clock + * pulse of the (very slow) watchdog clock source between two resets (or the + * configuration and the first reset) of the watchdog. + * + * On fast systems this can lead to a direct hit of the WDD boundary and + * thus to a reset of the system. This is why we program the WDD Value toi + * 0xfff to truly disable this Forbidden Window Feature. */ - regval = WDT_MR_WDV(reload) | WDT_MR_WDD(reload); + regval = WDT_MR_WDV(reload) | WDT_MR_WDD(0xfff); #ifdef CONFIG_SAMV7_WDT_INTERRUPT /* Generate an interrupt whent he watchdog timer expires */