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.
}