mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/rtc_wdt_api' into 'master'
soc/rtc_wdt: Add API functions for rtc_wdt See merge request idf/esp-idf!2837
This commit is contained in:
commit
ccd0c61ea1
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
125
components/soc/esp32/rtc_wdt.c
Normal file
125
components/soc/esp32/rtc_wdt.c
Normal file
@ -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);
|
||||
}
|
181
components/soc/include/soc/rtc_wdt.h
Normal file
181
components/soc/include/soc/rtc_wdt.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user