Skip to content

Instantly share code, notes, and snippets.

@shreyasbharath
Created November 6, 2019 21:51
Show Gist options
  • Save shreyasbharath/d9f91749001b5ddc8ad7f61634eff450 to your computer and use it in GitHub Desktop.
Save shreyasbharath/d9f91749001b5ddc8ad7f61634eff450 to your computer and use it in GitHub Desktop.
ESP32 RTC WDT API
void bsp_rtc_wdt_enable(uint32_t time_ms)
{
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_RTC);
rtc_wdt_set_time(RTC_WDT_STAGE0, 150000, time_ms); // Running off internal RC oscillator at 150 KHz
rtc_wdt_enable();
rtc_wdt_protect_on();
}
void bsp_rtc_wdt_disable()
{
rtc_wdt_protect_off();
rtc_wdt_disable();
rtc_wdt_protect_on();
}
void bsp_rtc_wdt_kick()
{
if (rtc_wdt_is_on())
{
rtc_wdt_protect_off();
rtc_wdt_feed();
rtc_wdt_protect_on();
}
}
#include "rtc_wdt.h"
#include <soc/timer_group_reg.h>
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);
}
esp_err_t rtc_wdt_set_stage(rtc_wdt_stage_t stage, rtc_wdt_stage_action_t stage_sel)
{
if (stage > RTC_WDT_STAGE3 || stage_sel > RTC_WDT_STAGE_ACTION_RESET_RTC)
{
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;
}
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()
{
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_EN);
}
void rtc_wdt_feed()
{
REG_SET_BIT(RTC_CNTL_WDTFEED_REG, RTC_CNTL_WDT_FEED);
}
esp_err_t rtc_wdt_set_time(rtc_wdt_stage_t stage, uint32_t clock_frequency, uint32_t timeout_ms)
{
if (stage > RTC_WDT_STAGE3)
{
return ESP_ERR_INVALID_ARG;
}
uint64_t time_tick = (uint64_t)clock_frequency * timeout_ms / ((uint64_t)1000);
if (time_tick > UINT32_MAX)
{
return ESP_ERR_INVALID_ARG;
}
uint32_t timeout = (uint32_t)time_tick;
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_get_timeout(rtc_wdt_stage_t stage, uint32_t clock_frequency, uint32_t *timeout_ms)
{
if (stage > RTC_WDT_STAGE3)
{
return ESP_ERR_INVALID_ARG;
}
uint32_t time_tick;
if (stage == RTC_WDT_STAGE0)
{
time_tick = READ_PERI_REG(RTC_CNTL_WDTCONFIG1_REG);
}
else if (stage == RTC_WDT_STAGE1)
{
time_tick = READ_PERI_REG(RTC_CNTL_WDTCONFIG2_REG);
}
else if (stage == RTC_WDT_STAGE2)
{
time_tick = READ_PERI_REG(RTC_CNTL_WDTCONFIG3_REG);
}
else
{
time_tick = READ_PERI_REG(RTC_CNTL_WDTCONFIG4_REG);
}
*timeout_ms = time_tick * 1000 / clock_frequency;
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 > RTC_WDT_CPU_RESET_SIG || reset_signal_length > RTC_WDT_LENGTH_3_2us)
{
return ESP_ERR_INVALID_ARG;
}
if (reset_src == RTC_WDT_SYS_RESET_SIG)
{
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment