From 4359d5985eba8ad9220fa7a4b3459197024f6e8c Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 12 Jun 2018 20:23:26 +0800 Subject: [PATCH] sleep: make sure input enable is set for EXT0/EXT1 wakeup Since commit 94250e4, EXT0 wakeup mechanism, when wakeup level was set to 0, started waking up chip immediately after entering deep sleep. This failure was triggered in that commit by a change of RTC_CNTL_MIN_SLP_VAL (i.e. minimum time in sleep mode until wakeup can happen) from 128 cycles to 2 cycles. The reason for this behaviour is related to the way input enable (IE) signal going into an RTC pad is obtained: PAD_IE = (SLP_SEL) ? SLP_IE & CHIP_SLEEP : IE, where SLP_IE, SLP_SEL, and IE are bits of an RTC_IO register related to the given pad. CHIP_SLEEP is the signal indicating that chip has entered sleep mode. The code in prepare_ext{0,1}_wakeup did not enable IE, but did enable SLP_SEL and SLP_IE. This meant that until CHIP_SLEEP went high, PAD_IE was 0, hence the input from the pad read 0 even if external signal was 1. CHIP_SLEEP went high on the 2nd cycle of sleep. So when RTC_CNTL_MIN_SLP_VAL was set to 2, the input signal from the pad was latched as 0 at the moment when CHIP_SLEEP went high, causing EXT0 wakeup with level 0 to trigger. This commit changes the way PAD_IE is enabled: SLP_SEL and SLP_IE are no longer used, and IE is set to 1. If EXT0 wakeup is used, RTC_IO is not powered down, so IE signal stays 1 both before CHIP_SLEEP goes high and after. If EXT1 wakeup is used, RTC_IO may be powered down. However prepare_ext1_wakeup enables Hold on the pad, locking states of all the control signals, including IE. Closes https://github.com/espressif/esp-idf/issues/1931 Closes https://github.com/espressif/esp-idf/issues/2043 --- components/esp32/sleep_modes.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/components/esp32/sleep_modes.c b/components/esp32/sleep_modes.c index a4cf33cfd..c5b31b350 100644 --- a/components/esp32/sleep_modes.c +++ b/components/esp32/sleep_modes.c @@ -465,8 +465,7 @@ static void ext0_wakeup_prepare() if (desc->rtc_num == rtc_gpio_num) { REG_SET_BIT(desc->reg, desc->mux); SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func); - REG_SET_BIT(desc->reg, desc->slpsel); - REG_SET_BIT(desc->reg, desc->slpie); + REG_SET_BIT(desc->reg, desc->ie); break; } } @@ -508,16 +507,13 @@ static void ext1_wakeup_prepare() // Route pad to RTC REG_SET_BIT(desc->reg, desc->mux); SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func); + // set input enable in sleep mode + REG_SET_BIT(desc->reg, desc->ie); // Pad configuration depends on RTC_PERIPH state in sleep mode - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_ON) { - // set input enable in sleep mode - REG_SET_BIT(desc->reg, desc->slpie); - // allow sleep status signal to control IE/SLPIE mux - REG_SET_BIT(desc->reg, desc->slpsel); - } else { - // RTC_PERIPH will be disabled, so need to enable input and - // lock pad configuration. Pullups/pulldowns also need to be disabled. - REG_SET_BIT(desc->reg, desc->ie); + if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { + // RTC_PERIPH will be powered down, so RTC_IO_ registers will + // loose their state. Lock pad configuration. + // Pullups/pulldowns also need to be disabled. REG_CLR_BIT(desc->reg, desc->pulldown); REG_CLR_BIT(desc->reg, desc->pullup); REG_SET_BIT(RTC_CNTL_HOLD_FORCE_REG, desc->hold_force);