You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/05/24 05:59:11 UTC

(nuttx) 02/03: esp32[c3|c6|h2]: Add RWDT support

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

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

commit aa0bb55529bdcbbb62c3cfbbb61a51ad95a9d220
Author: Eren Terzioglu <er...@espressif.com>
AuthorDate: Fri May 17 14:37:33 2024 +0300

    esp32[c3|c6|h2]: Add RWDT support
---
 arch/risc-v/src/common/espressif/Kconfig           |  23 ++
 arch/risc-v/src/common/espressif/Make.defs         |   2 +-
 arch/risc-v/src/common/espressif/esp_wdt.c         | 278 ++++++++++++++++-----
 arch/risc-v/src/common/espressif/esp_wdt.h         |  18 +-
 .../esp32c3-generic/configs/watchdog/defconfig     |   2 +-
 .../esp32c3/esp32c3-generic/src/esp32c3_bringup.c  |  12 +-
 .../esp32c6-devkitc/configs/watchdog/defconfig     |   2 +-
 .../esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c  |  12 +-
 .../esp32c6-devkitm/configs/watchdog/defconfig     |   2 +-
 .../esp32c6/esp32c6-devkitm/src/esp32c6_bringup.c  |  12 +-
 .../esp32h2-devkit/configs/watchdog/defconfig      |   2 +-
 .../esp32h2/esp32h2-devkit/src/esp32h2_bringup.c   |  12 +-
 12 files changed, 299 insertions(+), 78 deletions(-)

diff --git a/arch/risc-v/src/common/espressif/Kconfig b/arch/risc-v/src/common/espressif/Kconfig
index f4dd88ece0..ee516053ef 100644
--- a/arch/risc-v/src/common/espressif/Kconfig
+++ b/arch/risc-v/src/common/espressif/Kconfig
@@ -328,6 +328,29 @@ config ESPRESSIF_HR_TIMER
 		The HR Timer is built on top of the System Timer (SYSTIMER) peripheral.
 		Timer callbacks are dispatched from a high-priority kernel task.
 
+config ESPRESSIF_WDT
+	bool
+	default n
+	select WATCHDOG
+
+config ESPRESSIF_MWDT
+	bool "Main System Watchdog Timer"
+	default n
+	select ESPRESSIF_WDT
+	---help---
+		Includes MWDT.
+
+config ESPRESSIF_RWDT
+	bool "RTC Watchdog Timer"
+	default n
+	select ESPRESSIF_WDT
+	---help---
+		Includes RWDT. This watchdog timer is from the RTC module.
+		When it is selected, if the developer sets it to reset on expiration
+		it will reset Main System and the RTC module. If you don't want
+		to have the RTC module reset, please, use the Timers' Module WDTs.
+		They will only reset Main System.
+
 config ESPRESSIF_BROWNOUT_DET
 	bool "Brownout Detector"
 	default y
diff --git a/arch/risc-v/src/common/espressif/Make.defs b/arch/risc-v/src/common/espressif/Make.defs
index c902fa8a98..a0ca100eb5 100644
--- a/arch/risc-v/src/common/espressif/Make.defs
+++ b/arch/risc-v/src/common/espressif/Make.defs
@@ -41,7 +41,7 @@ else
 	CHIP_CSRCS += esp_timerisr.c
 endif
 
-ifeq ($(CONFIG_WATCHDOG),y)
+ifeq ($(CONFIG_ESPRESSIF_WDT),y)
 	CHIP_CSRCS += esp_wdt.c
 endif
 
diff --git a/arch/risc-v/src/common/espressif/esp_wdt.c b/arch/risc-v/src/common/espressif/esp_wdt.c
index 4d68987ba4..dcf4492544 100644
--- a/arch/risc-v/src/common/espressif/esp_wdt.c
+++ b/arch/risc-v/src/common/espressif/esp_wdt.c
@@ -32,9 +32,13 @@
 
 #include "esp_irq.h"
 #include "esp_wdt.h"
+#include "esp_clk.h"
+#include "esp_rtc_gpio.h"
 
 #include "hal/mwdt_ll.h"
+#include "hal/rwdt_ll.h"
 #include "hal/wdt_hal.h"
+#include "soc/rtc.h"
 #include "periph_ctrl.h"
 
 /****************************************************************************
@@ -43,24 +47,52 @@
 
 /* MWDT clock period in microseconds */
 
-#define MWDT_CLK_PERIOD_US        (500)
+#define MWDT_CLK_PERIOD_US               (500)
 
 /* Number of MWDT cycles per microseconds */
 
-#define MWDT_CYCLES_PER_MS        (USEC_PER_MSEC / MWDT_CLK_PERIOD_US)
+#define MWDT_CYCLES_PER_MS               (USEC_PER_MSEC / MWDT_CLK_PERIOD_US)
 
 /* Convert MWDT timeout cycles to milliseconds */
 
-#define MWDT_TIMEOUT_MS(t)        ((t) * MWDT_CYCLES_PER_MS)
+#define MWDT_TIMEOUT_MS(t)               ((t) * MWDT_CYCLES_PER_MS)
 
 /* Maximum number of MWDT cycles supported for timeout */
 
-#define MWDT_MAX_TIMEOUT_MS       (UINT32_MAX / MWDT_CYCLES_PER_MS)
+#define MWDT_MAX_TIMEOUT_MS              (UINT32_MAX / MWDT_CYCLES_PER_MS)
+
+/* Maximum number of cycles supported for a RWDT stage timeout */
+
+#define RWDT_FULL_STAGE                  (UINT32_MAX)
+
+/* Convert RWDT timeout cycles to milliseconds */
+
+#define RWDT_TIMEOUT_MS(t)               (t * rtc_clk_slow_freq_get_hz() / 1000ULL)
+
+#define WDT_INTR_ENABLE(timer, ctx, en)  (timer == RTC ?                               \
+                                          rwdt_ll_set_intr_enable(ctx->rwdt_dev, en) : \
+                                          mwdt_ll_set_intr_enable(ctx->mwdt_dev, en))
+
+/* Helpers for converting from Q13.19 fixed-point format to float */
+
+#define N             19
+#define Q_TO_FLOAT(x) ((float)x/(float)(1<<N))
+
+#if defined(CONFIG_ARCH_CHIP_ESP32C6) || defined(CONFIG_ARCH_CHIP_ESP32H2)
+#define RTC_CORE_INTR_SOURCE  LP_WDT_INTR_SOURCE
+#define ESP_IRQ_RTC_CORE      ESP_IRQ_LP_WDT
+#endif
 
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
+typedef enum
+{
+    RTC,
+    TIMER,
+} wdt_peripherals_t;
+
 /* This structure provides the private representation of the "lower-half"
  * driver state structure. This structure must be cast-compatible with the
  * well-known watchdog_lowerhalf_s structure.
@@ -68,13 +100,17 @@
 
 struct esp_wdt_lowerhalf_s
 {
-  const struct watchdog_ops_s *ops;       /* Lower half operations */
-  uint32_t                     timeout;   /* The current timeout */
-  wdt_stage_action_t           action;    /* The current action */
-  uint32_t                     lastreset; /* The last reset time */
-  bool                         started;   /* True: Timer has been started */
-  xcpt_t                       handler;   /* User Handler */
-  void                        *upper;     /* Pointer to watchdog_upperhalf_s */
+  const struct watchdog_ops_s *ops;        /* Lower half operations */
+  uint32_t                     timeout;    /* The current timeout */
+  wdt_stage_action_t           action;     /* The current action */
+  uint32_t                     lastreset;  /* The last reset time */
+  bool                         started;    /* True: Timer has been started */
+  wdt_peripherals_t            peripheral; /* Indicates if it is from RTC or Timer Module */
+  xcpt_t                       handler;    /* User Handler */
+  void                        *upper;      /* Pointer to watchdog_upperhalf_s */
+  uint8_t                      periph;     /* Peripheral ID */
+  uint8_t                      irq;        /* Interrupt ID */
+  wdt_hal_context_t           *ctx;        /* Watchdog HAL context */
 };
 
 /****************************************************************************
@@ -114,17 +150,41 @@ static const struct watchdog_ops_s g_esp_wdg_ops =
   .ioctl      = NULL
 };
 
+#ifdef CONFIG_ESPRESSIF_MWDT
+/* Watchdog HAL context */
+
+static wdt_hal_context_t mwdt_hal_ctx;
+
 /* MWDT0 lower-half */
 
-static struct esp_wdt_lowerhalf_s g_esp_wdt_lowerhalf =
+static struct esp_wdt_lowerhalf_s g_esp_mwdt_lowerhalf =
 {
   .ops = &g_esp_wdg_ops,
-  .timeout = MWDT_MAX_TIMEOUT_MS
+  .timeout = MWDT_MAX_TIMEOUT_MS,
+  .periph = TG0_WDT_LEVEL_INTR_SOURCE,
+  .peripheral = TIMER,
+  .irq = ESP_IRQ_TG0_WDT_LEVEL,
+  .ctx = &mwdt_hal_ctx
 };
+#endif
 
+#ifdef CONFIG_ESPRESSIF_RWDT
 /* Watchdog HAL context */
 
-static wdt_hal_context_t wdt_hal_ctx;
+static wdt_hal_context_t rwdt_hal_ctx = RWDT_HAL_CONTEXT_DEFAULT();
+
+/* RWDT lower-half */
+
+static struct esp_wdt_lowerhalf_s g_esp_rwdt_lowerhalf =
+{
+  .ops = &g_esp_wdg_ops,
+  .timeout = RWDT_FULL_STAGE,
+  .periph = RTC_CORE_INTR_SOURCE,
+  .peripheral = RTC,
+  .irq  = ESP_IRQ_RTC_CORE,
+  .ctx = &rwdt_hal_ctx
+};
+#endif
 
 /****************************************************************************
  * Private Functions
@@ -152,6 +212,7 @@ static int wdt_start(struct watchdog_lowerhalf_s *lower)
   struct esp_wdt_lowerhalf_s *priv = (struct esp_wdt_lowerhalf_s *)lower;
   int ret = OK;
   irqstate_t flags;
+  uint32_t timeout;
 
   wdinfo("Entry: started\n");
 
@@ -166,39 +227,57 @@ static int wdt_start(struct watchdog_lowerhalf_s *lower)
 
   priv->started = true;
 
-  wdt_hal_write_protect_disable(&wdt_hal_ctx);
+  wdt_hal_write_protect_disable(priv->ctx);
 
   if (priv->handler == NULL)
     {
       /* No user handler, so configure WDT to reset on timeout */
 
-      priv->action = WDT_STAGE_ACTION_RESET_SYSTEM;
+      if (priv->peripheral == TIMER)
+        {
+          priv->action = WDT_STAGE_ACTION_RESET_SYSTEM;
+          timeout = MWDT_TIMEOUT_MS(priv->timeout);
+        }
+      else
+        {
+          priv->action = WDT_STAGE_ACTION_RESET_RTC;
+          timeout = RWDT_TIMEOUT_MS(priv->timeout);
+        }
 
-      wdt_hal_config_stage(&wdt_hal_ctx, WDT_STAGE0,
-                           MWDT_TIMEOUT_MS(priv->timeout),
+      wdt_hal_config_stage(priv->ctx, WDT_STAGE0,
+                           timeout,
                            priv->action);
     }
   else
     {
       /* Configure WDT to call the user handler on timeout */
 
-      priv->action = WDT_STAGE_ACTION_INT;
+      if (priv->peripheral == TIMER)
+        {
+          priv->action = WDT_STAGE_ACTION_INT;
+          timeout = MWDT_TIMEOUT_MS(priv->timeout);
+        }
+      else
+        {
+          priv->action = WDT_STAGE_ACTION_INT;
+          timeout = RWDT_TIMEOUT_MS(priv->timeout);
+        }
 
-      wdt_hal_config_stage(&wdt_hal_ctx, WDT_STAGE0,
-                           MWDT_TIMEOUT_MS(priv->timeout),
+      wdt_hal_config_stage(priv->ctx, WDT_STAGE0,
+                           timeout,
                            priv->action);
 
       /* Enable interrupt */
 
-      mwdt_ll_set_intr_enable(wdt_hal_ctx.mwdt_dev, true);
+      WDT_INTR_ENABLE(priv->peripheral, priv->ctx, true);
     }
 
   flags = enter_critical_section();
   priv->lastreset = clock_systime_ticks();
-  wdt_hal_enable(&wdt_hal_ctx);
+  wdt_hal_enable(priv->ctx);
   leave_critical_section(flags);
 
-  wdt_hal_write_protect_enable(&wdt_hal_ctx);
+  wdt_hal_write_protect_enable(priv->ctx);
 
   return ret;
 }
@@ -223,11 +302,11 @@ static int wdt_stop(struct watchdog_lowerhalf_s *lower)
 {
   struct esp_wdt_lowerhalf_s *priv = (struct esp_wdt_lowerhalf_s *)lower;
 
-  wdt_hal_write_protect_disable(&wdt_hal_ctx);
+  wdt_hal_write_protect_disable(priv->ctx);
 
   /* Disable the WDT */
 
-  wdt_hal_disable(&wdt_hal_ctx);
+  wdt_hal_disable(priv->ctx);
 
   /* In case there is a callback registered, ensure WDT interrupts are
    * disabled.
@@ -235,10 +314,10 @@ static int wdt_stop(struct watchdog_lowerhalf_s *lower)
 
   if (priv->handler != NULL)
     {
-      mwdt_ll_set_intr_enable(wdt_hal_ctx.mwdt_dev, false);
+      WDT_INTR_ENABLE(priv->peripheral, priv->ctx, false);
     }
 
-  wdt_hal_write_protect_enable(&wdt_hal_ctx);
+  wdt_hal_write_protect_enable(priv->ctx);
 
   priv->started = false;
 
@@ -267,16 +346,16 @@ static int wdt_keepalive(struct watchdog_lowerhalf_s *lower)
   struct esp_wdt_lowerhalf_s *priv = (struct esp_wdt_lowerhalf_s *)lower;
   irqstate_t flags;
 
-  wdt_hal_write_protect_disable(&wdt_hal_ctx);
+  wdt_hal_write_protect_disable(priv->ctx);
 
   /* Feed the dog and update the time of last reset */
 
   flags = enter_critical_section();
   priv->lastreset = clock_systime_ticks();
-  wdt_hal_feed(&wdt_hal_ctx);
+  wdt_hal_feed(priv->ctx);
   leave_critical_section(flags);
 
-  wdt_hal_write_protect_enable(&wdt_hal_ctx);
+  wdt_hal_write_protect_enable(priv->ctx);
 
   return OK;
 }
@@ -376,24 +455,47 @@ static int wdt_settimeout(struct watchdog_lowerhalf_s *lower,
 
   DEBUGASSERT(priv != NULL);
 
-  wdt_hal_write_protect_disable(&wdt_hal_ctx);
+  wdt_hal_write_protect_disable(priv->ctx);
 
   priv->timeout = timeout;
 
-  if (timeout == 0 || timeout > MWDT_MAX_TIMEOUT_MS)
+  if (priv->peripheral == TIMER)
+    {
+      if (timeout == 0 || timeout > MWDT_MAX_TIMEOUT_MS)
+        {
+          wderr("ERROR: Cannot represent timeout=%"PRIu32" > %"PRIu32"\n",
+                timeout, MWDT_MAX_TIMEOUT_MS);
+          return -ERANGE;
+        }
+
+      timeout = MWDT_TIMEOUT_MS(priv->timeout);
+    }
+  else
     {
-      wderr("ERROR: Cannot represent timeout=%" PRIu32 " > %" PRIu32 "\n",
-            timeout, MWDT_MAX_TIMEOUT_MS);
-      return -ERANGE;
+      uint32_t period_13q19 = esp_clk_slowclk_cal_get();
+      float period = Q_TO_FLOAT(period_13q19);
+      rtc_cycles = 1000.0f / period;
+      rtc_ms_max = (RWDT_FULL_STAGE / (uint32_t)rtc_cycles);
+
+      /* Is this timeout a valid value for RTC WDT? */
+
+      if (timeout == 0 || timeout > rtc_ms_max)
+        {
+          wderr("ERROR: Cannot represent timeout=%"PRIu32" > %"PRIu32"\n",
+                timeout, rtc_ms_max);
+          return -ERANGE;
+        }
+
+      timeout = timeout * rtc_cycles;
     }
 
-  wdt_hal_config_stage(&wdt_hal_ctx, WDT_STAGE0,
-                       MWDT_TIMEOUT_MS(priv->timeout),
+  wdt_hal_config_stage(priv->ctx, WDT_STAGE0,
+                       timeout,
                        priv->action);
 
-  wdt_hal_feed(&wdt_hal_ctx);
+  wdt_hal_feed(priv->ctx);
 
-  wdt_hal_write_protect_enable(&wdt_hal_ctx);
+  wdt_hal_write_protect_enable(priv->ctx);
 
   return OK;
 }
@@ -425,6 +527,7 @@ static xcpt_t wdt_capture(struct watchdog_lowerhalf_s *lower, xcpt_t handler)
   struct esp_wdt_lowerhalf_s *priv = (struct esp_wdt_lowerhalf_s *)lower;
   irqstate_t flags;
   xcpt_t oldhandler;
+  uint32_t timeout;
 
   DEBUGASSERT(priv != NULL);
 
@@ -432,7 +535,7 @@ static xcpt_t wdt_capture(struct watchdog_lowerhalf_s *lower, xcpt_t handler)
 
   oldhandler = priv->handler;
 
-  wdt_hal_write_protect_disable(&wdt_hal_ctx);
+  wdt_hal_write_protect_disable(priv->ctx);
 
   flags = enter_critical_section();
 
@@ -453,34 +556,52 @@ static xcpt_t wdt_capture(struct watchdog_lowerhalf_s *lower, xcpt_t handler)
            * then change to interrupt.
            */
 
+          if (priv->peripheral == TIMER)
+            {
+              timeout = MWDT_TIMEOUT_MS(priv->timeout);
+            }
+          else
+            {
+              timeout = RWDT_TIMEOUT_MS(priv->timeout);
+            }
+
           priv->action = WDT_STAGE_ACTION_INT;
 
-          wdt_hal_config_stage(&wdt_hal_ctx, WDT_STAGE0,
-                               MWDT_TIMEOUT_MS(priv->timeout),
+          wdt_hal_config_stage(priv->ctx, WDT_STAGE0,
+                               timeout,
                                priv->action);
         }
 
-      mwdt_ll_set_intr_enable(wdt_hal_ctx.mwdt_dev, true);
+      WDT_INTR_ENABLE(priv->peripheral, priv->ctx, true);
     }
 
   /* In case the user wants to disable the callback */
 
   else
     {
-      mwdt_ll_set_intr_enable(wdt_hal_ctx.mwdt_dev, false);
+      if (priv->peripheral == TIMER)
+        {
+          timeout = MWDT_TIMEOUT_MS(priv->timeout);
+          priv->action = WDT_STAGE_ACTION_RESET_SYSTEM;
+        }
+      else
+        {
+          timeout = RWDT_TIMEOUT_MS(priv->timeout);
+          priv->action = WDT_STAGE_ACTION_RESET_RTC;
+        }
 
-      /* Then configure it to reset on WDT expiration */
+      WDT_INTR_ENABLE(priv->peripheral, priv->ctx, false);
 
-      priv->action = WDT_STAGE_ACTION_RESET_SYSTEM;
+      /* Then configure it to reset on WDT expiration */
 
-      wdt_hal_config_stage(&wdt_hal_ctx, WDT_STAGE0,
-                           MWDT_TIMEOUT_MS(priv->timeout),
+      wdt_hal_config_stage(priv->ctx, WDT_STAGE0,
+                           timeout,
                            priv->action);
     }
 
   leave_critical_section(flags);
 
-  wdt_hal_write_protect_enable(&wdt_hal_ctx);
+  wdt_hal_write_protect_enable(priv->ctx);
 
   return oldhandler;
 }
@@ -513,9 +634,9 @@ static int wdt_handler(int irq, void *context, void *arg)
 
   /* Clear the Interrupt */
 
-  wdt_hal_write_protect_disable(&wdt_hal_ctx);
-  wdt_hal_handle_intr(&wdt_hal_ctx);
-  wdt_hal_write_protect_enable(&wdt_hal_ctx);
+  wdt_hal_write_protect_disable(priv->ctx);
+  wdt_hal_handle_intr(priv->ctx);
+  wdt_hal_write_protect_enable(priv->ctx);
 
   return OK;
 }
@@ -531,7 +652,9 @@ static int wdt_handler(int irq, void *context, void *arg)
  *   Initialize the watchdog timer.
  *
  * Input Parameters:
- *   None.
+ *   devpath - The full path to the watchdog.  This should
+ *             be of the form /dev/watchdogX
+ *   wdt_id  - A Watchdog Timer instance to be initialized.
  *
  * Returned Values:
  *   Zero (OK) is returned on success; a negated errno value is returned on
@@ -539,18 +662,47 @@ static int wdt_handler(int irq, void *context, void *arg)
  *
  ****************************************************************************/
 
-int esp_wdt_initialize(void)
+int esp_wdt_initialize(const char *devpath, enum esp_wdt_inst_e wdt_id)
 {
-  periph_module_enable(PERIPH_TIMG0_MODULE);
-  wdt_hal_init(&wdt_hal_ctx, WDT_MWDT0, MWDT_LL_DEFAULT_CLK_PRESCALER, true);
+  struct esp_wdt_lowerhalf_s *lower = NULL;
+
+  switch (wdt_id)
+    {
+#ifdef CONFIG_ESPRESSIF_MWDT
+      case ESP_WDT_MWDT:
+        {
+          lower = &g_esp_mwdt_lowerhalf;
+          periph_module_enable(PERIPH_TIMG0_MODULE);
+          wdt_hal_init(lower->ctx, WDT_MWDT0,
+                       MWDT_LL_DEFAULT_CLK_PRESCALER, true);
+
+          break;
+        }
 
-  struct esp_wdt_lowerhalf_s *lower = &g_esp_wdt_lowerhalf;
+#endif
+
+#ifdef CONFIG_ESPRESSIF_RWDT
+      case ESP_WDT_RWDT:
+        {
+          lower = &g_esp_rwdt_lowerhalf;
+          wdt_hal_init(lower->ctx, WDT_RWDT, 0, true);
+          esp_rtcioirqenable(lower->irq);
+          break;
+        }
+#endif
+
+      default:
+        {
+          wderr("ERROR: unsupported WDT %d\n", wdt_id);
+          return ERROR;
+        }
+    }
 
   /* Initialize the elements of lower half state structure */
 
   lower->handler = NULL;
   lower->timeout = 0;
-  lower->started = wdt_hal_is_enabled(&wdt_hal_ctx);
+  lower->started = wdt_hal_is_enabled(lower->ctx);
 
   /* Register the watchdog driver as /dev/watchdogX. If the registration goes
    * right the returned value from watchdog_register is a pointer to
@@ -558,7 +710,7 @@ int esp_wdt_initialize(void)
    * or with the handler's arg.
    */
 
-  lower->upper = watchdog_register(CONFIG_WATCHDOG_DEVPATH,
+  lower->upper = watchdog_register(devpath,
                                    (struct watchdog_lowerhalf_s *)lower);
   if (lower->upper == NULL)
     {
@@ -571,17 +723,17 @@ int esp_wdt_initialize(void)
       return -EEXIST;
     }
 
-  esp_setup_irq(TG0_WDT_LEVEL_INTR_SOURCE,
+  esp_setup_irq(lower->periph,
                 ESP_IRQ_PRIORITY_DEFAULT,
                 ESP_IRQ_TRIGGER_LEVEL);
 
   /* Attach the handler for the timer IRQ */
 
-  irq_attach(ESP_IRQ_TG0_WDT_LEVEL, (xcpt_t)wdt_handler, lower);
+  irq_attach(lower->irq, (xcpt_t)wdt_handler, lower);
 
   /* Enable the allocated CPU interrupt */
 
-  up_enable_irq(ESP_IRQ_TG0_WDT_LEVEL);
+  up_enable_irq(lower->irq);
 
   return OK;
 }
diff --git a/arch/risc-v/src/common/espressif/esp_wdt.h b/arch/risc-v/src/common/espressif/esp_wdt.h
index 57ac77a7ed..c58e291f7f 100644
--- a/arch/risc-v/src/common/espressif/esp_wdt.h
+++ b/arch/risc-v/src/common/espressif/esp_wdt.h
@@ -27,6 +27,18 @@
 
 #include <nuttx/config.h>
 
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* Instances of Watchdog Timer  */
+
+enum esp_wdt_inst_e
+{
+  ESP_WDT_MWDT = 0,  /* Main System Watchdog Timer (MWDT) of Timer Group 0 */
+  ESP_WDT_RWDT       /* RTC Watchdog Timer (RWDT) */
+};
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -38,7 +50,9 @@
  *   Initialize the watchdog timer.
  *
  * Input Parameters:
- *   None.
+ *   devpath - The full path to the watchdog.  This should
+ *             be of the form /dev/watchdogX
+ *   wdt_id  - A Watchdog Timer instance to be initialized.
  *
  * Returned Values:
  *   Zero (OK) is returned on success; a negated errno value is returned on
@@ -46,6 +60,6 @@
  *
  ****************************************************************************/
 
-int esp_wdt_initialize(void);
+int esp_wdt_initialize(const char *devpath, enum esp_wdt_inst_e wdt_id);
 
 #endif /* __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_WDT_H */
diff --git a/boards/risc-v/esp32c3/esp32c3-generic/configs/watchdog/defconfig b/boards/risc-v/esp32c3/esp32c3-generic/configs/watchdog/defconfig
index 73e0b126fd..e2900f822d 100644
--- a/boards/risc-v/esp32c3/esp32c3-generic/configs/watchdog/defconfig
+++ b/boards/risc-v/esp32c3/esp32c3-generic/configs/watchdog/defconfig
@@ -19,6 +19,7 @@ CONFIG_ARCH_STACKDUMP=y
 CONFIG_BOARD_LOOPSPERMSEC=15000
 CONFIG_BUILTIN=y
 CONFIG_DEV_ZERO=y
+CONFIG_ESPRESSIF_MWDT=y
 CONFIG_EXAMPLES_WATCHDOG=y
 CONFIG_FS_PROCFS=y
 CONFIG_IDLETHREAD_STACKSIZE=2048
@@ -44,4 +45,3 @@ CONFIG_SYSTEM_NSH=y
 CONFIG_TESTING_GETPRIME=y
 CONFIG_TESTING_OSTEST=y
 CONFIG_UART0_SERIAL_CONSOLE=y
-CONFIG_WATCHDOG=y
diff --git a/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c b/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c
index 04d4eaf771..abff6563d6 100644
--- a/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c
+++ b/boards/risc-v/esp32c3/esp32c3-generic/src/esp32c3_bringup.c
@@ -128,8 +128,16 @@ int esp_bringup(void)
     }
 #endif
 
-#ifdef CONFIG_WATCHDOG
-  ret = esp_wdt_initialize();
+#ifdef CONFIG_ESPRESSIF_MWDT
+  ret = esp_wdt_initialize("/dev/watchdog0", ESP_WDT_MWDT);
+  if (ret < 0)
+    {
+      _err("Failed to initialize WDT: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_ESPRESSIF_RWDT
+  ret = esp_wdt_initialize("/dev/watchdog1", ESP_WDT_RWDT);
   if (ret < 0)
     {
       _err("Failed to initialize WDT: %d\n", ret);
diff --git a/boards/risc-v/esp32c6/esp32c6-devkitc/configs/watchdog/defconfig b/boards/risc-v/esp32c6/esp32c6-devkitc/configs/watchdog/defconfig
index 5f8f895242..5f1ce9db53 100644
--- a/boards/risc-v/esp32c6/esp32c6-devkitc/configs/watchdog/defconfig
+++ b/boards/risc-v/esp32c6/esp32c6-devkitc/configs/watchdog/defconfig
@@ -21,6 +21,7 @@ CONFIG_BOARD_LOOPSPERMSEC=15000
 CONFIG_BUILTIN=y
 CONFIG_DEV_ZERO=y
 CONFIG_ESPRESSIF_ESP32C6=y
+CONFIG_ESPRESSIF_MWDT=y
 CONFIG_EXAMPLES_WATCHDOG=y
 CONFIG_FS_PROCFS=y
 CONFIG_IDLETHREAD_STACKSIZE=2048
@@ -46,4 +47,3 @@ CONFIG_SYSTEM_NSH=y
 CONFIG_TESTING_GETPRIME=y
 CONFIG_TESTING_OSTEST=y
 CONFIG_UART0_SERIAL_CONSOLE=y
-CONFIG_WATCHDOG=y
diff --git a/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c b/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c
index 1fb99d91f6..46a6a628ba 100644
--- a/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c
+++ b/boards/risc-v/esp32c6/esp32c6-devkitc/src/esp32c6_bringup.c
@@ -128,8 +128,16 @@ int esp_bringup(void)
     }
 #endif
 
-#ifdef CONFIG_WATCHDOG
-  ret = esp_wdt_initialize();
+#ifdef CONFIG_ESPRESSIF_MWDT
+  ret = esp_wdt_initialize("/dev/watchdog0", ESP_WDT_MWDT);
+  if (ret < 0)
+    {
+      _err("Failed to initialize WDT: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_ESPRESSIF_RWDT
+  ret = esp_wdt_initialize("/dev/watchdog1", ESP_WDT_RWDT);
   if (ret < 0)
     {
       _err("Failed to initialize WDT: %d\n", ret);
diff --git a/boards/risc-v/esp32c6/esp32c6-devkitm/configs/watchdog/defconfig b/boards/risc-v/esp32c6/esp32c6-devkitm/configs/watchdog/defconfig
index 3481b92459..7836f09f68 100644
--- a/boards/risc-v/esp32c6/esp32c6-devkitm/configs/watchdog/defconfig
+++ b/boards/risc-v/esp32c6/esp32c6-devkitm/configs/watchdog/defconfig
@@ -21,6 +21,7 @@ CONFIG_BOARD_LOOPSPERMSEC=15000
 CONFIG_BUILTIN=y
 CONFIG_DEV_ZERO=y
 CONFIG_ESPRESSIF_ESP32C6=y
+CONFIG_ESPRESSIF_MWDT=y
 CONFIG_EXAMPLES_WATCHDOG=y
 CONFIG_FS_PROCFS=y
 CONFIG_IDLETHREAD_STACKSIZE=2048
@@ -46,4 +47,3 @@ CONFIG_SYSTEM_NSH=y
 CONFIG_TESTING_GETPRIME=y
 CONFIG_TESTING_OSTEST=y
 CONFIG_UART0_SERIAL_CONSOLE=y
-CONFIG_WATCHDOG=y
diff --git a/boards/risc-v/esp32c6/esp32c6-devkitm/src/esp32c6_bringup.c b/boards/risc-v/esp32c6/esp32c6-devkitm/src/esp32c6_bringup.c
index 43a4847ac4..7d72fa2e8f 100644
--- a/boards/risc-v/esp32c6/esp32c6-devkitm/src/esp32c6_bringup.c
+++ b/boards/risc-v/esp32c6/esp32c6-devkitm/src/esp32c6_bringup.c
@@ -128,8 +128,16 @@ int esp_bringup(void)
     }
 #endif
 
-#ifdef CONFIG_WATCHDOG
-  ret = esp_wdt_initialize();
+#ifdef CONFIG_ESPRESSIF_MWDT
+  ret = esp_wdt_initialize("/dev/watchdog0", ESP_WDT_MWDT);
+  if (ret < 0)
+    {
+      _err("Failed to initialize WDT: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_ESPRESSIF_RWDT
+  ret = esp_wdt_initialize("/dev/watchdog1", ESP_WDT_RWDT);
   if (ret < 0)
     {
       _err("Failed to initialize WDT: %d\n", ret);
diff --git a/boards/risc-v/esp32h2/esp32h2-devkit/configs/watchdog/defconfig b/boards/risc-v/esp32h2/esp32h2-devkit/configs/watchdog/defconfig
index 891fe4c4fe..4e52443411 100644
--- a/boards/risc-v/esp32h2/esp32h2-devkit/configs/watchdog/defconfig
+++ b/boards/risc-v/esp32h2/esp32h2-devkit/configs/watchdog/defconfig
@@ -20,6 +20,7 @@ CONFIG_BOARD_LOOPSPERMSEC=15000
 CONFIG_BUILTIN=y
 CONFIG_DEV_ZERO=y
 CONFIG_ESPRESSIF_ESP32H2=y
+CONFIG_ESPRESSIF_MWDT=y
 CONFIG_EXAMPLES_WATCHDOG=y
 CONFIG_FS_PROCFS=y
 CONFIG_IDLETHREAD_STACKSIZE=2048
@@ -45,4 +46,3 @@ CONFIG_SYSTEM_NSH=y
 CONFIG_TESTING_GETPRIME=y
 CONFIG_TESTING_OSTEST=y
 CONFIG_UART0_SERIAL_CONSOLE=y
-CONFIG_WATCHDOG=y
diff --git a/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c b/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c
index a1076bc552..f9d652028e 100644
--- a/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c
+++ b/boards/risc-v/esp32h2/esp32h2-devkit/src/esp32h2_bringup.c
@@ -120,8 +120,16 @@ int esp_bringup(void)
     }
 #endif
 
-#ifdef CONFIG_WATCHDOG
-  ret = esp_wdt_initialize();
+#ifdef CONFIG_ESPRESSIF_MWDT
+  ret = esp_wdt_initialize("/dev/watchdog0", ESP_WDT_MWDT);
+  if (ret < 0)
+    {
+      _err("Failed to initialize WDT: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_ESPRESSIF_RWDT
+  ret = esp_wdt_initialize("/dev/watchdog1", ESP_WDT_RWDT);
   if (ret < 0)
     {
       _err("Failed to initialize WDT: %d\n", ret);