ESP32-C3 stability of wake up from deep sleep
Posted: Mon Oct 11, 2021 11:25 am
Hello.
I'm trying to make a custom board on ESP32C3 with wall socket power supply and 0.22F supercapacitor for RTC. So i want the chip to go to deep sleep when 220V power supply disappears and wake up when 220V appears back.
I've been successful with going to deep sleep (supercapacitor is not discharging fast when it goes to deep sleep), but i have problems with wake up from deep sleep.
At first i tried to use RC delay circuit directly with wake up gpio (i used IO5), so i would be able to wake up when voltage becomes stable. But this circuit didn't work at all, i guess because of curved edges of the signal. On osciloscope i've noticed that until some point it looks like IO pin has internal pull down, even during initialization i disable pull down.
May it be the reason of wake up fail? Here is the deep sleep init code:
So on some forum i read that wake up signal should have sharp edges and i tried next circuit. To make delay until 3V6 power source becomes available i use wake stubs. Now it doesn't wake up with supercapacitor voltage lower than 2.8V, but with higher voltages it gave me 80% of successful wake up cases, still i can't find the relationship between the signal and wake up fail. During failed wake ups the reset reason is POWERON in most cases, only some times i see BROWNOUT_RESET reset case.
Wake stub code:
I need to achieve about 100% successful wake up cases, please any help how could it be achieved on esp32c3?
I'm trying to make a custom board on ESP32C3 with wall socket power supply and 0.22F supercapacitor for RTC. So i want the chip to go to deep sleep when 220V power supply disappears and wake up when 220V appears back.
I've been successful with going to deep sleep (supercapacitor is not discharging fast when it goes to deep sleep), but i have problems with wake up from deep sleep.
At first i tried to use RC delay circuit directly with wake up gpio (i used IO5), so i would be able to wake up when voltage becomes stable. But this circuit didn't work at all, i guess because of curved edges of the signal. On osciloscope i've noticed that until some point it looks like IO pin has internal pull down, even during initialization i disable pull down.
May it be the reason of wake up fail? Here is the deep sleep init code:
Code: Select all
/*reset pin to default state to remove pull down resistance*/
#define WAKE_UP_GPIO 5
gpio_reset_pin(WAKE_UP_GPIO);
gpio_hold_dis(WAKE_UP_GPIO);
const gpio_config_t config = {
.pin_bit_mask = BIT(WAKE_UP_GPIO),
.pull_up_en = 0,
.pull_down_en = 0,
.mode = GPIO_MODE_INPUT,
};
ESP_ERROR_CHECK(gpio_config(&config));
ESP_ERROR_CHECK(esp_deep_sleep_enable_gpio_wakeup(BIT(WAKE_UP_GPIO), ESP_GPIO_WAKEUP_GPIO_HIGH));
for (gpio_num_t gpio_num = GPIO_NUM_2; gpio_num < GPIO_NUM_MAX; gpio_num++)
{
if (GPIO_IS_VALID_GPIO(gpio_num) && (gpio_num != WAKE_UP_GPIO))
{
gpio_sleep_set_direction(gpio_num, GPIO_MODE_DISABLE);
gpio_sleep_set_pull_mode(gpio_num, GPIO_FLOATING);
if (gpio_num <= GPIO_NUM_5)
{
REG_CLR_BIT(RTC_CNTL_PAD_HOLD_REG, BIT(gpio_num));
}
else
{
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
}
}
}
esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
esp_deep_sleep_start();
Code: Select all
RTC_DATA_ATTR int wake_count;
void RTC_IRAM_ATTR esp_wake_deep_sleep(void) {
wake_count = 0;
while (GPIO_INPUT_GET(WAKE_UP_GPIO)){
wake_count++;
if (wake_count > 2){ //wake up
//wait until 3.6V comes
ets_delay_us(150000);
return;
}
ets_delay_us(300);
}
// Set the pointer of the wake stub function.
REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)&esp_wake_deep_sleep);
// Go to sleep.
CLEAR_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
// A few CPU cycles may be necessary for the sleep to start...
while (true) {
;
}
// never reaches here.
}