]> granicus.if.org Git - esp-idf/commitdiff
soc/rtc_wdt: Add API functions for rtc_wdt
authorKonstantin Kondrashov <konstantin@espressif.com>
Mon, 23 Jul 2018 10:59:37 +0000 (15:59 +0500)
committerKonstantin Kondrashov <konstantin@espressif.com>
Tue, 14 Aug 2018 12:48:02 +0000 (17:48 +0500)
Added functions:
rtc_wdt_protect_off/on
rtc_wdt_set_length_of_reset_signal
rtc_wdt_set_stage
rtc_wdt_set_time
rtc_wdt_feed
rtc_wdt_disable/enable

components/bootloader_support/src/bootloader_init.c
components/esp32/cpu_start.c
components/esp32/include/esp_panic.h
components/esp32/panic.c
components/esp32/sleep_modes.c
components/esp32/system_api.c
components/soc/esp32/rtc_wdt.c [new file with mode: 0644]
components/soc/include/soc/rtc_wdt.h [new file with mode: 0644]

index 73a79956252764e4eb8fb7c8e4850ceccec9e6d2..fe0d756fb599b861c0eecaad58aeae4cb90c8f26 100644 (file)
@@ -39,6 +39,7 @@
 #include "soc/timer_group_reg.h"
 #include "soc/gpio_reg.h"
 #include "soc/gpio_sig_map.h"
+#include "soc/rtc_wdt.h"
 
 #include "sdkconfig.h"
 #include "esp_image_format.h"
@@ -143,7 +144,7 @@ static esp_err_t bootloader_main()
     ets_set_appcpu_boot_addr(0);
 
     /* disable watch dog here */
-    REG_CLR_BIT( RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN );
+    rtc_wdt_disable();
     REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
 
 #ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
index 4d907f333c805253e139d305f9e057c72d185d00..1c9ca73976a63e537351b8cf1b5f7b36f6f9156c 100644 (file)
@@ -29,6 +29,7 @@
 #include "soc/io_mux_reg.h"
 #include "soc/rtc_cntl_reg.h"
 #include "soc/timer_group_reg.h"
+#include "soc/rtc_wdt.h"
 
 #include "driver/rtc_io.h"
 
@@ -136,7 +137,7 @@ void IRAM_ATTR call_start_cpu0()
         || rst_reas[1] == RTCWDT_SYS_RESET || rst_reas[1] == TG0WDT_SYS_RESET
 #endif
     ) {
-        esp_panic_wdt_stop();
+        rtc_wdt_disable();
     }
 
     //Clear BSS. Please do not attempt to do any complex stuff (like early logging) before this.
@@ -435,7 +436,7 @@ static void main_task(void* args)
 {
     // Now that the application is about to start, disable boot watchdogs
     REG_CLR_BIT(TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN_S);
-    REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN);
+    rtc_wdt_disable();
 #if !CONFIG_FREERTOS_UNICORE
     // Wait for FreeRTOS initialization to finish on APP CPU, before replacing its startup stack
     while (port_xSchedulerRunning[1] == 0) {
index 4e0630a24581031c514d2a109d6504a6875b2c28..b9e192f04629b062e5e438a4b0b93409895ece94 100644 (file)
@@ -61,12 +61,6 @@ esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags);
  */
 void esp_clear_watchpoint(int no);
 
-
-/**
- * @brief Stops panic WDT
- */
-void esp_panic_wdt_stop(void);
-
 /**
  * @brief Checks stack pointer
  */
index 8edb70b23329c9384d33d9ea87b6ddb4adf8fca1..5a000574be081b3044b44eba7fcb06928fd87ec1 100644 (file)
@@ -30,6 +30,7 @@
 #include "soc/timer_group_reg.h"
 #include "soc/cpu.h"
 #include "soc/rtc.h"
+#include "soc/rtc_wdt.h"
 
 #include "esp_gdbstub.h"
 #include "esp_panic.h"
@@ -374,32 +375,6 @@ static inline void disableAllWdts()
     TIMERG1.wdt_wprotect = 0;
 }
 
-static void esp_panic_wdt_start()
-{
-    if (REG_GET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN)) {
-        return;
-    }
-    WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
-    WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1);
-    REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_SYS_RESET_LENGTH, 7);
-    REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_CPU_RESET_LENGTH, 7);
-    REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_RESET_SYSTEM);
-    // 64KB of core dump data (stacks of about 30 tasks) will produce ~85KB base64 data.
-    // @ 115200 UART speed it will take more than 6 sec to print them out.
-    WRITE_PERI_REG(RTC_CNTL_WDTCONFIG1_REG, rtc_clk_slow_freq_get_hz() * 7);
-    REG_SET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN);
-    WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
-}
-
-void esp_panic_wdt_stop()
-{
-    WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
-    WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1);
-    REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_OFF);
-    REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN);
-    WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
-}
-
 static void esp_panic_dig_reset() __attribute__((noreturn));
 
 static void esp_panic_dig_reset()
@@ -528,7 +503,18 @@ static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame)
 
     int core_id = xPortGetCoreID();
     // start panic WDT to restart system if we hang in this handler
-    esp_panic_wdt_start();
+    if (!rtc_wdt_is_on()) {
+        rtc_wdt_protect_off();
+        rtc_wdt_disable();
+        rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_3_2us);
+        rtc_wdt_set_length_of_reset_signal(RTC_WDT_CPU_RESET_SIG, RTC_WDT_LENGTH_3_2us);
+        rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_SYSTEM);
+        // 64KB of core dump data (stacks of about 30 tasks) will produce ~85KB base64 data.
+        // @ 115200 UART speed it will take more than 6 sec to print them out.
+        rtc_wdt_set_time(RTC_WDT_STAGE0, 7000);
+        rtc_wdt_enable();
+        rtc_wdt_protect_on();
+    }
 
     //Feed the watchdogs, so they will give us time to print out debug info
     reconfigureAllWdts();
@@ -553,7 +539,7 @@ static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame)
 
 #if CONFIG_ESP32_PANIC_GDBSTUB
     disableAllWdts();
-    esp_panic_wdt_stop();
+    rtc_wdt_disable();
     panicPutStr("Entering gdb stub now.\r\n");
     esp_gdbstub_panic_handler(frame);
 #else
@@ -574,7 +560,7 @@ static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame)
         reconfigureAllWdts();
     }
 #endif /* CONFIG_ESP32_ENABLE_COREDUMP */
-    esp_panic_wdt_stop();
+    rtc_wdt_disable();
 #if CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT
     panicPutStr("Rebooting...\r\n");
     if (frame->exccause != PANIC_RSN_CACHEERR) {
index f4cefb98b621ecb619d3e81aa549d715c7d5a34c..91713ad6bb1640e7da4b1e4756a49c454d28736f 100644 (file)
@@ -32,6 +32,7 @@
 #include "soc/spi_reg.h"
 #include "soc/sens_reg.h"
 #include "soc/dport_reg.h"
+#include "soc/rtc_wdt.h"
 #include "driver/rtc_io.h"
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
@@ -238,27 +239,6 @@ void IRAM_ATTR esp_deep_sleep_start()
     }
 }
 
-static void rtc_wdt_enable(int time_ms)
-{
-    WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
-    WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1);
-    REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_SYS_RESET_LENGTH, 7);
-    REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_CPU_RESET_LENGTH, 7);
-    REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_RESET_RTC);
-    WRITE_PERI_REG(RTC_CNTL_WDTCONFIG1_REG, rtc_clk_slow_freq_get_hz() * time_ms / 1000);
-    SET_PERI_REG_MASK(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN | RTC_CNTL_WDT_PAUSE_IN_SLP);
-    WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
-}
-
-static void rtc_wdt_disable()
-{
-    WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
-    WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1);
-    REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_OFF);
-    REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN);
-    WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
-}
-
 /**
  * Helper function which handles entry to and exit from light sleep
  * Placed into IRAM as flash may need some time to be powered on.
@@ -326,7 +306,17 @@ esp_err_t esp_light_sleep_start()
     rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config();
 
     // Safety net: enable WDT in case exit from light sleep fails
-    rtc_wdt_enable(1000);
+    bool wdt_was_enabled = rtc_wdt_is_on(); // If WDT was enabled in the user code, then do not change it here.
+    if (!wdt_was_enabled) {
+        rtc_wdt_protect_off();
+        rtc_wdt_disable();
+        rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_3_2us);
+        rtc_wdt_set_length_of_reset_signal(RTC_WDT_CPU_RESET_SIG, RTC_WDT_LENGTH_3_2us);
+        rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_RTC);
+        rtc_wdt_set_time(RTC_WDT_STAGE0, 1000);
+        rtc_wdt_enable();
+        rtc_wdt_protect_on();
+    }
 
     // Enter sleep, then wait for flash to be ready on wakeup
     esp_err_t err = esp_light_sleep_inner(pd_flags,
@@ -352,7 +342,9 @@ esp_err_t esp_light_sleep_start()
 
     esp_timer_impl_unlock();
     DPORT_STALL_OTHER_CPU_END();
-    rtc_wdt_disable();
+    if (!wdt_was_enabled) {
+        rtc_wdt_disable();
+    }
     portEXIT_CRITICAL(&light_sleep_lock);
     return err;
 }
index 8068f3bc4f61e4b134ff625b081bd9b5627f8a53..f56bf622e2c0b5eae2c9852336f7044a5b0c66a0 100644 (file)
@@ -31,6 +31,7 @@
 #include "soc/timer_group_struct.h"
 #include "soc/cpu.h"
 #include "soc/rtc.h"
+#include "soc/rtc_wdt.h"
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
 #include "freertos/xtensa_api.h"
@@ -270,14 +271,15 @@ void IRAM_ATTR esp_restart_noos()
     xt_ints_off(0xFFFFFFFF);
 
     // Enable RTC watchdog for 1 second
-    REG_WRITE(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
-    REG_WRITE(RTC_CNTL_WDTCONFIG0_REG,
-            RTC_CNTL_WDT_FLASHBOOT_MOD_EN_M |
-            (RTC_WDT_STG_SEL_RESET_SYSTEM << RTC_CNTL_WDT_STG0_S) |
-            (RTC_WDT_STG_SEL_RESET_RTC << RTC_CNTL_WDT_STG1_S) |
-            (1 << RTC_CNTL_WDT_SYS_RESET_LENGTH_S) |
-            (1 << RTC_CNTL_WDT_CPU_RESET_LENGTH_S) );
-    REG_WRITE(RTC_CNTL_WDTCONFIG1_REG, rtc_clk_slow_freq_get_hz() * 1);
+    rtc_wdt_protect_off();
+    rtc_wdt_disable();
+    rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_RTC);
+    rtc_wdt_set_stage(RTC_WDT_STAGE1, RTC_WDT_STAGE_ACTION_RESET_SYSTEM);
+    rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_200ns);
+    rtc_wdt_set_length_of_reset_signal(RTC_WDT_CPU_RESET_SIG, RTC_WDT_LENGTH_200ns);
+    rtc_wdt_set_time(RTC_WDT_STAGE0, 1000);
+    rtc_wdt_enable();
+    rtc_wdt_protect_on();
 
     // Reset and stall the other CPU.
     // CPU must be reset before stalling, in case it was running a s32c1i
diff --git a/components/soc/esp32/rtc_wdt.c b/components/soc/esp32/rtc_wdt.c
new file mode 100644 (file)
index 0000000..8daa352
--- /dev/null
@@ -0,0 +1,125 @@
+// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "soc/rtc_wdt.h"
+#include "soc/rtc.h"
+
+
+bool rtc_wdt_get_protect_status()
+{
+    return READ_PERI_REG(RTC_CNTL_WDTWPROTECT_REG) != RTC_CNTL_WDT_WKEY_VALUE;
+}
+
+void rtc_wdt_protect_off()
+{
+    WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
+}
+
+void rtc_wdt_protect_on()
+{
+    WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
+}
+
+
+void rtc_wdt_enable()
+{
+    REG_SET_BIT(RTC_CNTL_WDTFEED_REG, RTC_CNTL_WDT_FEED);
+    SET_PERI_REG_MASK(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN | RTC_CNTL_WDT_PAUSE_IN_SLP);
+}
+
+void rtc_wdt_disable()
+{
+    bool protect = rtc_wdt_get_protect_status();
+    if (protect) {
+        rtc_wdt_protect_off();
+    }
+    REG_SET_BIT(RTC_CNTL_WDTFEED_REG, RTC_CNTL_WDT_FEED);
+    rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_OFF);
+    rtc_wdt_set_stage(RTC_WDT_STAGE1, RTC_WDT_STAGE_ACTION_OFF);
+    rtc_wdt_set_stage(RTC_WDT_STAGE2, RTC_WDT_STAGE_ACTION_OFF);
+    rtc_wdt_set_stage(RTC_WDT_STAGE3, RTC_WDT_STAGE_ACTION_OFF);
+    REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN);
+    REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN);
+    if (protect) {
+        rtc_wdt_protect_on();
+    }
+}
+
+void rtc_wdt_feed()
+{
+    bool protect = rtc_wdt_get_protect_status();
+    if (protect) {
+        rtc_wdt_protect_off();
+    }
+    REG_SET_BIT(RTC_CNTL_WDTFEED_REG, RTC_CNTL_WDT_FEED);
+    if (protect) {
+        rtc_wdt_protect_on();
+    }
+}
+
+esp_err_t rtc_wdt_set_time(rtc_wdt_stage_t stage, unsigned int timeout_ms)
+{
+    if (stage > 3) {
+        return ESP_ERR_INVALID_ARG;
+    }
+    uint32_t timeout = rtc_clk_slow_freq_get_hz() * timeout_ms / 1000;
+    if (stage == RTC_WDT_STAGE0) {
+        WRITE_PERI_REG(RTC_CNTL_WDTCONFIG1_REG, timeout);
+    } else if (stage == RTC_WDT_STAGE1) {
+        WRITE_PERI_REG(RTC_CNTL_WDTCONFIG2_REG, timeout);
+    } else if (stage == RTC_WDT_STAGE2) {
+        WRITE_PERI_REG(RTC_CNTL_WDTCONFIG3_REG, timeout);
+    } else {
+        WRITE_PERI_REG(RTC_CNTL_WDTCONFIG4_REG, timeout);
+    }
+
+    return ESP_OK;
+}
+
+esp_err_t rtc_wdt_set_stage(rtc_wdt_stage_t stage, rtc_wdt_stage_action_t stage_sel)
+{
+    if (stage > 3 || stage_sel > 4) {
+        return ESP_ERR_INVALID_ARG;
+    }
+    if (stage == RTC_WDT_STAGE0) {
+        REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, stage_sel);
+    } else if (stage == RTC_WDT_STAGE1) {
+        REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG1, stage_sel);
+    } else if (stage == RTC_WDT_STAGE2) {
+        REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG2, stage_sel);
+    } else {
+        REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG3, stage_sel);
+    }
+
+    return ESP_OK;
+}
+
+esp_err_t rtc_wdt_set_length_of_reset_signal(rtc_wdt_reset_sig_t reset_src, rtc_wdt_length_sig_t reset_signal_length)
+{
+    if (reset_src > 1 || reset_signal_length > 7) {
+        return ESP_ERR_INVALID_ARG;
+    }
+    if (reset_src == 0) {
+        REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_SYS_RESET_LENGTH, reset_signal_length);
+    } else {
+        REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_CPU_RESET_LENGTH, reset_signal_length);
+    }
+
+    return ESP_OK;
+}
+
+bool rtc_wdt_is_on()
+{
+    return (REG_GET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN) != 0) || (REG_GET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN) != 0);
+}
diff --git a/components/soc/include/soc/rtc_wdt.h b/components/soc/include/soc/rtc_wdt.h
new file mode 100644 (file)
index 0000000..9094a30
--- /dev/null
@@ -0,0 +1,181 @@
+// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/* Recommendation of using API RTC_WDT.
+1) Setting and enabling rtc_wdt:
+@code
+    rtc_wdt_protect_off();
+    rtc_wdt_disable();
+    rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_3_2us);
+    rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_SYSTEM); //RTC_WDT_STAGE_ACTION_RESET_SYSTEM or RTC_WDT_STAGE_ACTION_RESET_RTC
+    rtc_wdt_set_time(RTC_WDT_STAGE0, 7000);     // timeout rtd_wdt 7000ms.
+    rtc_wdt_enable();
+    rtc_wdt_protect_on();
+ @endcode
+
+* If you use this option RTC_WDT_STAGE_ACTION_RESET_SYSTEM then after reset you can see these messages.
+They can help to understand where the CPUs were when the WDT was triggered.
+    W (30) boot: PRO CPU has been reset by WDT.
+       W (30) boot: WDT reset info: PRO CPU PC=0x400xxxxx
+       ... function where it happened
+
+       W (31) boot: WDT reset info: APP CPU PC=0x400xxxxx
+       ... function where it happened
+
+* If you use this option RTC_WDT_STAGE_ACTION_RESET_RTC then you will see message (rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)) 
+without description where were CPUs when it happened.
+
+2) Reset counter of rtc_wdt:
+@code
+    rtc_wdt_feed();
+@endcode
+
+3) Disable rtc_wdt:
+@code
+    rtc_wdt_disable();
+@endcode
+ */
+
+#ifndef _SOC_RTC_WDT_H
+#define _SOC_RTC_WDT_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "soc/rtc_cntl_reg.h"
+#include "esp_err.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/// List of stage of rtc watchdog. WDT has 4 stage.
+typedef enum {
+    RTC_WDT_STAGE0 = 0,     /*!< Stage 0 */
+    RTC_WDT_STAGE1 = 1,     /*!< Stage 1 */
+    RTC_WDT_STAGE2 = 2,     /*!< Stage 2 */
+    RTC_WDT_STAGE3 = 3      /*!< Stage 3 */
+} rtc_wdt_stage_t;
+
+/// List of action. When the time of stage expires this action will be triggered.
+typedef enum {
+    RTC_WDT_STAGE_ACTION_OFF            = RTC_WDT_STG_SEL_OFF,          /*!< Disabled. This stage will have no effects on the system. */
+    RTC_WDT_STAGE_ACTION_INTERRUPT      = RTC_WDT_STG_SEL_INT,          /*!< Trigger an interrupt. When the stage expires an interrupt is triggered. */
+    RTC_WDT_STAGE_ACTION_RESET_CPU      = RTC_WDT_STG_SEL_RESET_CPU,    /*!< Reset a CPU core. */
+    RTC_WDT_STAGE_ACTION_RESET_SYSTEM   = RTC_WDT_STG_SEL_RESET_SYSTEM, /*!< Reset the main system includes the CPU and all peripherals. The RTC is an exception to this, and it will not be reset. */
+    RTC_WDT_STAGE_ACTION_RESET_RTC      = RTC_WDT_STG_SEL_RESET_RTC     /*!< Reset the main system and the RTC. */
+} rtc_wdt_stage_action_t;
+
+/// Type of reset signal
+typedef enum {
+    RTC_WDT_SYS_RESET_SIG = 0,     /*!< System reset signal length selection */
+    RTC_WDT_CPU_RESET_SIG = 1      /*!< CPU reset signal length selection */
+} rtc_wdt_reset_sig_t;
+
+/// Length of reset signal
+typedef enum {
+    RTC_WDT_LENGTH_100ns = 0,     /*!< 100 ns */
+    RTC_WDT_LENGTH_200ns = 1,     /*!< 200 ns */
+    RTC_WDT_LENGTH_300ns = 2,     /*!< 300 ns */
+    RTC_WDT_LENGTH_400ns = 3,     /*!< 400 ns */
+    RTC_WDT_LENGTH_500ns = 4,     /*!< 500 ns */
+    RTC_WDT_LENGTH_800ns = 5,     /*!< 800 ns */
+    RTC_WDT_LENGTH_1_6us = 6,     /*!< 1.6 us */
+    RTC_WDT_LENGTH_3_2us = 7      /*!< 3.2 us */
+} rtc_wdt_length_sig_t;
+
+/**
+ * @brief Get status of protect of rtc_wdt.
+ *
+ * @return
+ *         - True if the protect of RTC_WDT is set
+ */
+bool rtc_wdt_get_protect_status();
+
+/**
+ * @brief Set protect of rtc_wdt.
+ */
+void rtc_wdt_protect_on();
+
+/**
+ * @brief Reset protect of rtc_wdt.
+ */
+void rtc_wdt_protect_off();
+
+/**
+ * @brief Enable rtc_wdt.
+ */
+void rtc_wdt_enable();
+
+/**
+ * @brief Disable rtc_wdt.
+ */
+void rtc_wdt_disable();
+
+/**
+ * @brief Reset counter rtc_wdt.
+ *
+ * It returns to stage 0 and its expiry counter restarts from 0.
+ */
+void rtc_wdt_feed();
+
+/**
+ * @brief Set time for required stage.
+ *
+ * @param[in] stage Stage of rtc_wdt.
+ * @param[in] timeout_ms Timeout for this stage.
+ *
+ * @return
+ *         - ESP_OK In case of success
+ *         - ESP_ERR_INVALID_ARG If stage has invalid value
+ */
+esp_err_t rtc_wdt_set_time(rtc_wdt_stage_t stage, unsigned int timeout_ms);
+
+/**
+ * @brief Set an action for required stage.
+ *
+ * @param[in] stage Stage of rtc_wdt.
+ * @param[in] stage_sel Action for this stage. When the time of stage expires this action will be triggered.
+ *
+ * @return
+ *         - ESP_OK In case of success
+ *         - ESP_ERR_INVALID_ARG If stage or stage_sel have invalid value
+ */
+esp_err_t rtc_wdt_set_stage(rtc_wdt_stage_t stage, rtc_wdt_stage_action_t stage_sel);
+
+/**
+ * @brief Set a length of reset signal.
+ *
+ * @param[in] reset_src Type of reset signal.
+ * @param[in] reset_signal_length A length of reset signal.
+ *
+ * @return
+ *         - ESP_OK In case of success
+ *         - ESP_ERR_INVALID_ARG If reset_src  or reset_signal_length have invalid value
+ */
+esp_err_t rtc_wdt_set_length_of_reset_signal(rtc_wdt_reset_sig_t reset_src, rtc_wdt_length_sig_t reset_signal_length);
+
+/**
+ * @brief Return true if rtc_wdt is enabled.
+ *
+ * @return
+ *         - True rtc_wdt is enabled
+ */
+bool rtc_wdt_is_on();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _SOC_RTC_WDT_H