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

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

commit d2cbca275936ad72ec33e8850a6c9ef199458a4f
Author: Tiago Medicci Serrano <[email protected]>
AuthorDate: Tue May 26 13:27:16 2026 +0200

    xtensa/esp32: Fix divide-by-zero in RTC WDT clock calibration.
    
    Under the BOARD_LATE_INITIALIZE boot flow, rtc_clk_xtal_freq_get()
    may return 0 (SOC_XTAL_FREQ_AUTO) because the XTAL frequency has
    not yet been stored to the RTC register when the WDT driver is
    initialized. This causes rtc_clk_cal() to divide by zero
    internally (EXCCAUSE=0006) when computing the RTC slow clock
    period.
    
    Fix by explicitly calling rtc_clk_xtal_freq_update() with the
    board's configured crystal frequency if rtc_clk_xtal_freq_get()
    returns 0. Also add a guard in esp32_wdt_settimeout() to return
    -EIO if ESP32_RWDT_CLK() still returns 0 cycles/ms, preventing
    a subsequent divide-by-zero when computing the maximum timeout.
    
    Signed-off-by: Tiago Medicci Serrano <[email protected]>
---
 arch/xtensa/src/esp32/esp32_wdt.c           | 14 ++++++++++++++
 arch/xtensa/src/esp32/esp32_wdt_lowerhalf.c |  6 ++++++
 2 files changed, 20 insertions(+)

diff --git a/arch/xtensa/src/esp32/esp32_wdt.c 
b/arch/xtensa/src/esp32/esp32_wdt.c
index 02672c06a9b..b83772a3b01 100644
--- a/arch/xtensa/src/esp32/esp32_wdt.c
+++ b/arch/xtensa/src/esp32/esp32_wdt.c
@@ -554,6 +554,20 @@ static uint16_t esp32_rtc_clk(struct esp32_wdt_dev_s *dev)
 
   DEBUGASSERT(dev);
 
+  /* Ensure the XTAL frequency is known before calibration.
+   * rtc_clk_cal divides by xtal_freq internally and will crash
+   * with divide-by-zero if it hasn't been stored yet.
+   */
+
+  if (rtc_clk_xtal_freq_get() == 0)
+    {
+#ifdef CONFIG_ESP32_XTAL_26MHz
+      rtc_clk_xtal_freq_update(SOC_XTAL_FREQ_26M);
+#else
+      rtc_clk_xtal_freq_update(SOC_XTAL_FREQ_40M);
+#endif
+    }
+
   /* Check which clock is sourcing the slow_clk_rtc */
 
   slow_clk_rtc = rtc_clk_slow_src_get();
diff --git a/arch/xtensa/src/esp32/esp32_wdt_lowerhalf.c 
b/arch/xtensa/src/esp32/esp32_wdt_lowerhalf.c
index d071341c0d2..10741fbc94f 100644
--- a/arch/xtensa/src/esp32/esp32_wdt_lowerhalf.c
+++ b/arch/xtensa/src/esp32/esp32_wdt_lowerhalf.c
@@ -484,6 +484,12 @@ static int esp32_wdt_settimeout(struct 
watchdog_lowerhalf_s *lower,
   else
     {
       rtc_cycles = ESP32_RWDT_CLK(priv->wdt);
+      if (rtc_cycles == 0)
+        {
+          wderr("ERROR: RTC clock calibration returned 0 cycles/ms\n");
+          return -EIO;
+        }
+
       rtc_ms_max = (uint32_t)(FULL_STAGE / rtc_cycles);
 
       /* Is this timeout a valid value for RTC WDT? */

Reply via email to