This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 14f2daaa2d3ae8f51979fd839a74de83ff03a751
Author: raiden00pl <[email protected]>
AuthorDate: Mon Oct 19 11:41:21 2026 +0200

    arch/arm/src/common/stm32: fix WWDG time left in WDIOC_GETSTATUS
    
    stm32_getstatus() returned the time elapsed since the last keepalive as
    timeleft. The counter runs from T_RESET | reload down to T_MAX, where
    the reset is generated, so the time left is the ticks above T_MAX
    scaled by the timeout. The debug print also showed the flags instead
    of the time left.
    
    Measured on NUCLEO-H533RE and NUCLEO-C562RE with a 98 ms timeout fed
    every 25 ms: timeleft read 0..39 ms before the fix.
    
    Signed-off-by: raiden00pl <[email protected]>
    Assisted-by: Claude Code
---
 arch/arm/src/common/stm32/stm32_wwdg.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/arch/arm/src/common/stm32/stm32_wwdg.c 
b/arch/arm/src/common/stm32/stm32_wwdg.c
index 23095f20c61..75ff6d8de44 100644
--- a/arch/arm/src/common/stm32/stm32_wwdg.c
+++ b/arch/arm/src/common/stm32/stm32_wwdg.c
@@ -438,8 +438,8 @@ static int stm32_getstatus(struct watchdog_lowerhalf_s 
*lower,
                            struct watchdog_status_s *status)
 {
   struct stm32_lowerhalf_s *priv = (struct stm32_lowerhalf_s *)lower;
-  uint32_t elapsed;
-  uint16_t reload;
+  uint32_t remaining;
+  uint32_t counter;
 
   wdinfo("Entry\n");
   DEBUGASSERT(priv);
@@ -461,16 +461,28 @@ static int stm32_getstatus(struct watchdog_lowerhalf_s 
*lower,
 
   status->timeout = priv->timeout;
 
-  /* Get the time remaining until the watchdog expires (in milliseconds) */
+  /* Get the time remaining until the watchdog expires (in milliseconds).
+   * The counter runs from T_RESET | reload down to T_MAX, where T6 clears
+   * and the reset is generated, so the ticks left are T[6:0] - T_MAX.
+   */
+
+  counter  = stm32_getreg(STM32_WWDG_CR) & WWDG_CR_T_MASK;
+  counter >>= WWDG_CR_T_SHIFT;
+  if (counter > WWDG_CR_T_MAX)
+    {
+      remaining = counter - WWDG_CR_T_MAX;
+    }
+  else
+    {
+      remaining = 0;
+    }
 
-  reload = (stm32_getreg(STM32_WWDG_CR) >> WWDG_CR_T_SHIFT) & 0x7f;
-  elapsed = (WWDG_CR_T_RESET | priv->reload) - reload;
-  status->timeleft = (priv->timeout * elapsed) / (priv->reload + 1);
+  status->timeleft = (priv->timeout * remaining) / (priv->reload + 1);
 
   wdinfo("Status     :\n");
   wdinfo("  flags    : %08x\n", (unsigned)status->flags);
   wdinfo("  timeout  : %u\n", (unsigned)status->timeout);
-  wdinfo("  timeleft : %u\n", (unsigned)status->flags);
+  wdinfo("  timeleft : %u\n", (unsigned)status->timeleft);
   return OK;
 }
 

Reply via email to