mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
gpio: Fix IO hold function related problems
1. Fix deep sleep wakeup IOs can not be unhold issue 2. Correct hold related APIs' description 3. Fix gpio_force_hold_all API docs: Add GPIO wakeup source to sleep_modes doc for ESP32C3 and C2
This commit is contained in:
@@ -15,7 +15,7 @@ extern "C" {
|
||||
/**
|
||||
* @file sleep_gpio.h
|
||||
*
|
||||
* This file contains declarations of GPIO related functions in light sleep mode.
|
||||
* This file contains declarations of GPIO related functions in sleep modes.
|
||||
*/
|
||||
|
||||
#if SOC_GPIO_SUPPORT_SLP_SWITCH && CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
@@ -41,6 +41,11 @@ void gpio_sleep_mode_config_unapply(void);
|
||||
|
||||
#endif // SOC_GPIO_SUPPORT_SLP_SWITCH && CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
|
||||
/**
|
||||
* @brief Call once in startup to disable the wakeup IO pins and release their holding state after waking up from Deep-sleep
|
||||
*/
|
||||
void esp_deep_sleep_wakeup_io_reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -245,25 +245,25 @@ esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode
|
||||
* This function enables an IO pin to wake up the chip from deep sleep.
|
||||
*
|
||||
* @note This function does not modify pin configuration. The pins are
|
||||
* configured in esp_deep_sleep_start/esp_light_sleep_start,
|
||||
* immediately before entering sleep mode.
|
||||
* configured inside esp_deep_sleep_start, immediately before entering sleep mode.
|
||||
*
|
||||
* @note You don't need to care to pull-up or pull-down before using this
|
||||
* function, because this will be done in esp_deep_sleep_start/esp_light_sleep_start
|
||||
* based on param mask you give. BTW, when you use low level to wake up the
|
||||
* chip, we strongly recommand you to add external registors (pull-up).
|
||||
* function, because this will be set internally in esp_deep_sleep_start
|
||||
* based on the wakeup mode. BTW, when you use low level to wake up the
|
||||
* chip, we strongly recommend you to add external resistors (pull-up).
|
||||
*
|
||||
* @param gpio_pin_mask Bit mask of GPIO numbers which will cause wakeup. Only GPIOs
|
||||
* which are have RTC functionality can be used in this bit map.
|
||||
* which have RTC functionality (pads that powered by VDD3P3_RTC) can be used in this bit map.
|
||||
* @param mode Select logic function used to determine wakeup condition:
|
||||
* - ESP_GPIO_WAKEUP_GPIO_LOW: wake up when the gpio turn to low.
|
||||
* - ESP_GPIO_WAKEUP_GPIO_HIGH: wake up when the gpio turn to high.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if gpio num is more than 5 or mode is invalid,
|
||||
* - ESP_ERR_INVALID_ARG if the mask contains any invalid deep sleep wakeup pin or wakeup mode is invalid
|
||||
*/
|
||||
esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enable wakeup from light sleep using GPIOs
|
||||
*
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "hal/rtc_io_hal.h"
|
||||
#include "hal/rtc_hal.h"
|
||||
#include "esp_private/gpio.h"
|
||||
#include "esp_private/sleep_gpio.h"
|
||||
#include "esp_private/spi_flash_os.h"
|
||||
@@ -144,3 +146,37 @@ IRAM_ATTR void esp_sleep_isolate_digital_gpio(void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void esp_deep_sleep_wakeup_io_reset(void)
|
||||
{
|
||||
#if SOC_PM_SUPPORT_EXT_WAKEUP
|
||||
uint32_t rtc_io_mask = rtc_hal_ext1_get_wakeup_pins();
|
||||
// Disable ext1 wakeup before releasing hold, such that wakeup status can reflect the correct wakeup pin
|
||||
rtc_hal_ext1_clear_wakeup_pins();
|
||||
for (int gpio_num = 0; gpio_num < SOC_GPIO_PIN_COUNT && rtc_io_mask != 0; ++gpio_num) {
|
||||
int rtcio_num = rtc_io_num_map[gpio_num];
|
||||
if ((rtc_io_mask & BIT(rtcio_num)) == 0) {
|
||||
continue;
|
||||
}
|
||||
rtcio_hal_hold_disable(rtcio_num);
|
||||
rtc_io_mask &= ~BIT(rtcio_num);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
|
||||
uint32_t dl_io_mask = SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK;
|
||||
gpio_hal_context_t gpio_hal = {
|
||||
.dev = GPIO_HAL_GET_HW(GPIO_PORT_0)
|
||||
};
|
||||
while (dl_io_mask) {
|
||||
int gpio_num = __builtin_ffs(dl_io_mask) - 1;
|
||||
bool wakeup_io_enabled = gpio_hal_deepsleep_wakeup_is_enabled(&gpio_hal, gpio_num);
|
||||
if (wakeup_io_enabled) {
|
||||
// Disable the wakeup before releasing hold, such that wakeup status can reflect the correct wakeup pin
|
||||
gpio_hal_deepsleep_wakeup_disable(&gpio_hal, gpio_num);
|
||||
gpio_hal_hold_dis(&gpio_hal, gpio_num);
|
||||
}
|
||||
dl_io_mask &= ~BIT(gpio_num);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ static void timer_wakeup_prepare(void);
|
||||
static void touch_wakeup_prepare(void);
|
||||
#endif
|
||||
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
|
||||
static void esp_deep_sleep_wakeup_prepare(void);
|
||||
static void gpio_deep_sleep_wakeup_prepare(void);
|
||||
#endif
|
||||
|
||||
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
|
||||
@@ -431,8 +431,8 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
|
||||
#endif
|
||||
|
||||
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
|
||||
if (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN) {
|
||||
esp_deep_sleep_wakeup_prepare();
|
||||
if (deep_sleep && (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN)) {
|
||||
gpio_deep_sleep_wakeup_prepare();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1096,7 +1096,7 @@ static void ext1_wakeup_prepare(void)
|
||||
}
|
||||
|
||||
// Clear state from previous wakeup
|
||||
rtc_hal_ext1_clear_wakeup_pins();
|
||||
rtc_hal_ext1_clear_wakeup_status();
|
||||
// Set RTC IO pins and mode (any high, all low) to be used for wakeup
|
||||
rtc_hal_ext1_set_wakeup_pins(s_config.ext1_rtc_gpio_mask, s_config.ext1_trigger_mode);
|
||||
}
|
||||
@@ -1106,7 +1106,7 @@ uint64_t esp_sleep_get_ext1_wakeup_status(void)
|
||||
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_EXT1) {
|
||||
return 0;
|
||||
}
|
||||
uint32_t status = rtc_hal_ext1_get_wakeup_pins();
|
||||
uint32_t status = rtc_hal_ext1_get_wakeup_status();
|
||||
// Translate bit map of RTC IO numbers into the bit map of GPIO numbers
|
||||
uint64_t gpio_mask = 0;
|
||||
for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) {
|
||||
@@ -1131,10 +1131,10 @@ uint64_t esp_sleep_get_gpio_wakeup_status(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return rtc_hal_gpio_get_wakeup_pins();
|
||||
return rtc_hal_gpio_get_wakeup_status();
|
||||
}
|
||||
|
||||
static void esp_deep_sleep_wakeup_prepare(void)
|
||||
static void gpio_deep_sleep_wakeup_prepare(void)
|
||||
{
|
||||
for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++) {
|
||||
if (((1ULL << gpio_idx) & s_config.gpio_wakeup_mask) == 0) {
|
||||
@@ -1147,9 +1147,10 @@ static void esp_deep_sleep_wakeup_prepare(void)
|
||||
ESP_ERROR_CHECK(gpio_pullup_en(gpio_idx));
|
||||
ESP_ERROR_CHECK(gpio_pulldown_dis(gpio_idx));
|
||||
}
|
||||
rtc_hal_gpio_set_wakeup_pins();
|
||||
ESP_ERROR_CHECK(gpio_hold_en(gpio_idx));
|
||||
}
|
||||
// Clear state from previous wakeup
|
||||
rtc_hal_gpio_clear_wakeup_status();
|
||||
}
|
||||
|
||||
esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode)
|
||||
@@ -1165,7 +1166,7 @@ esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepslee
|
||||
continue;
|
||||
}
|
||||
if (!esp_sleep_is_valid_wakeup_gpio(gpio_idx)) {
|
||||
ESP_LOGE(TAG, "invalid mask, please ensure gpio number is no more than 5");
|
||||
ESP_LOGE(TAG, "gpio %d is an invalid deep sleep wakeup IO", gpio_idx);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
err = gpio_deep_sleep_wakeup_enable(gpio_idx, intr_type);
|
||||
@@ -1178,7 +1179,6 @@ esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepslee
|
||||
}
|
||||
}
|
||||
s_config.wakeup_triggers |= RTC_GPIO_TRIG_EN;
|
||||
rtc_hal_gpio_clear_wakeup_pins();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user