mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-01 03:34:32 +02:00
Merge branch 'support/esp_sleep_enable_ext1_wakeup_io_v5.2' into 'release/v5.2'
Support/esp sleep enable ext1 wakeup io(backport v5.2) See merge request espressif/esp-idf!30243
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -267,6 +267,59 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
|
||||
* the pins during sleep. HOLD feature will be acted on the pin internally
|
||||
* before the system entering sleep, and this can further reduce power consumption.
|
||||
*
|
||||
* @note Call this func will reset the previous ext1 configuration.
|
||||
*
|
||||
* @note This function will be deprecated in release/v6.0. Please switch to use `esp_sleep_enable_ext1_wakeup_io` and `esp_sleep_disable_ext1_wakeup_io`
|
||||
*
|
||||
* @param io_mask Bit mask of GPIO numbers which will cause wakeup. Only GPIOs
|
||||
* which have RTC functionality can be used in this bit map.
|
||||
* For different SoCs, the related GPIOs are:
|
||||
* - ESP32: 0, 2, 4, 12-15, 25-27, 32-39
|
||||
* - ESP32-S2: 0-21
|
||||
* - ESP32-S3: 0-21
|
||||
* - ESP32-C6: 0-7
|
||||
* - ESP32-H2: 7-14
|
||||
* @param level_mode Select logic function used to determine wakeup condition:
|
||||
* When target chip is ESP32:
|
||||
* - ESP_EXT1_WAKEUP_ALL_LOW: wake up when all selected GPIOs are low
|
||||
* - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high
|
||||
* When target chip is ESP32-S2, ESP32-S3, ESP32-C6 or ESP32-H2:
|
||||
* - ESP_EXT1_WAKEUP_ANY_LOW: wake up when any of the selected GPIOs is low
|
||||
* - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if io_mask is zero,
|
||||
* or mode is invalid
|
||||
*/
|
||||
esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t io_mask, esp_sleep_ext1_wakeup_mode_t level_mode);
|
||||
|
||||
/**
|
||||
* @brief Enable ext1 wakeup pins with IO masks.
|
||||
*
|
||||
* This will append selected IOs to the wakeup IOs, it will not reset previously enabled IOs.
|
||||
* To reset specific previously enabled IOs, call esp_sleep_disable_ext1_wakeup_io with the io_mask.
|
||||
* To reset all the enabled IOs, call esp_sleep_disable_ext1_wakeup_io(0).
|
||||
*
|
||||
* This function uses external wakeup feature of RTC controller.
|
||||
* It will work even if RTC peripherals are shut down during sleep.
|
||||
*
|
||||
* This feature can monitor any number of pins which are in RTC IOs.
|
||||
* Once selected pins go into the state given by level_mode argument,
|
||||
* the chip will be woken up.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @note Internal pullups and pulldowns don't work when RTC peripherals are
|
||||
* shut down. In this case, external resistors need to be added.
|
||||
* Alternatively, RTC peripherals (and pullups/pulldowns) may be
|
||||
* kept enabled using esp_sleep_pd_config function. If we turn off the
|
||||
* ``RTC_PERIPH`` domain or certain chips lack the ``RTC_PERIPH`` domain,
|
||||
* we will use the HOLD feature to maintain the pull-up and pull-down on
|
||||
* the pins during sleep. HOLD feature will be acted on the pin internally
|
||||
* before the system entering sleep, and this can further reduce power consumption.
|
||||
*
|
||||
* @param io_mask Bit mask of GPIO numbers which will cause wakeup. Only GPIOs
|
||||
* which have RTC functionality can be used in this bit map.
|
||||
* For different SoCs, the related GPIOs are:
|
||||
@@ -286,8 +339,28 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if any of the selected GPIOs is not an RTC GPIO,
|
||||
* or mode is invalid
|
||||
* - ESP_ERR_NOT_SUPPORTED when wakeup level will become different between
|
||||
* ext1 IOs if !SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN
|
||||
*/
|
||||
esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t io_mask, esp_sleep_ext1_wakeup_mode_t level_mode);
|
||||
esp_err_t esp_sleep_enable_ext1_wakeup_io(uint64_t io_mask, esp_sleep_ext1_wakeup_mode_t level_mode);
|
||||
|
||||
/**
|
||||
* @brief Disable ext1 wakeup pins with IO masks. This will remove selected IOs from the wakeup IOs.
|
||||
* @param io_mask Bit mask of GPIO numbers which will cause wakeup. Only GPIOs
|
||||
* which have RTC functionality can be used in this bit map.
|
||||
* If value is zero, this func will remove all previous ext1 configuration.
|
||||
* For different SoCs, the related GPIOs are:
|
||||
* - ESP32: 0, 2, 4, 12-15, 25-27, 32-39
|
||||
* - ESP32-S2: 0-21
|
||||
* - ESP32-S3: 0-21
|
||||
* - ESP32-C6: 0-7
|
||||
* - ESP32-H2: 7-14
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if any of the selected GPIOs is not an RTC GPIO.
|
||||
*/
|
||||
esp_err_t esp_sleep_disable_ext1_wakeup_io(uint64_t io_mask);
|
||||
|
||||
#if SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN
|
||||
/**
|
||||
@@ -328,6 +401,7 @@ esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t io_mask, esp_sleep_ext1_wakeup_m
|
||||
* or mode is invalid
|
||||
*/
|
||||
esp_err_t esp_sleep_enable_ext1_wakeup_with_level_mask(uint64_t io_mask, uint64_t level_mask);
|
||||
|
||||
#endif // SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN
|
||||
#endif // SOC_PM_SUPPORT_EXT1_WAKEUP
|
||||
|
||||
|
@@ -1541,7 +1541,19 @@ static void ext0_wakeup_prepare(void)
|
||||
#if SOC_PM_SUPPORT_EXT1_WAKEUP
|
||||
esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t io_mask, esp_sleep_ext1_wakeup_mode_t level_mode)
|
||||
{
|
||||
if (level_mode > ESP_EXT1_WAKEUP_ANY_HIGH) {
|
||||
if (io_mask == 0 && level_mode > ESP_EXT1_WAKEUP_ANY_HIGH) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
// Reset all EXT1 configs
|
||||
esp_sleep_disable_ext1_wakeup_io(0);
|
||||
|
||||
return esp_sleep_enable_ext1_wakeup_io(io_mask, level_mode);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_sleep_enable_ext1_wakeup_io(uint64_t io_mask, esp_sleep_ext1_wakeup_mode_t level_mode)
|
||||
{
|
||||
if (io_mask == 0 && level_mode > ESP_EXT1_WAKEUP_ANY_HIGH) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
// Translate bit map of GPIO numbers into the bit map of RTC IO numbers
|
||||
@@ -1556,16 +1568,61 @@ esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t io_mask, esp_sleep_ext1_wakeup_m
|
||||
}
|
||||
rtc_gpio_mask |= BIT(rtc_io_number_get(gpio));
|
||||
}
|
||||
s_config.ext1_rtc_gpio_mask = rtc_gpio_mask;
|
||||
|
||||
#if !SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN
|
||||
uint32_t ext1_rtc_gpio_mask = 0;
|
||||
uint32_t ext1_trigger_mode = 0;
|
||||
|
||||
ext1_rtc_gpio_mask = s_config.ext1_rtc_gpio_mask | rtc_gpio_mask;
|
||||
if (level_mode) {
|
||||
s_config.ext1_trigger_mode = rtc_gpio_mask;
|
||||
ext1_trigger_mode = s_config.ext1_trigger_mode | rtc_gpio_mask;
|
||||
} else {
|
||||
s_config.ext1_trigger_mode = 0;
|
||||
ext1_trigger_mode = s_config.ext1_trigger_mode & (~rtc_gpio_mask);
|
||||
}
|
||||
if (((ext1_rtc_gpio_mask & ext1_trigger_mode) != ext1_rtc_gpio_mask) &&
|
||||
((ext1_rtc_gpio_mask & ext1_trigger_mode) != 0)) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
s_config.ext1_rtc_gpio_mask |= rtc_gpio_mask;
|
||||
if (level_mode) {
|
||||
s_config.ext1_trigger_mode |= rtc_gpio_mask;
|
||||
} else {
|
||||
s_config.ext1_trigger_mode &= (~rtc_gpio_mask);
|
||||
}
|
||||
s_config.wakeup_triggers |= RTC_EXT1_TRIG_EN;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_sleep_disable_ext1_wakeup_io(uint64_t io_mask)
|
||||
{
|
||||
if (io_mask == 0) {
|
||||
s_config.ext1_rtc_gpio_mask = 0;
|
||||
s_config.ext1_trigger_mode = 0;
|
||||
} else {
|
||||
// Translate bit map of GPIO numbers into the bit map of RTC IO numbers
|
||||
uint32_t rtc_gpio_mask = 0;
|
||||
for (int gpio = 0; io_mask; ++gpio, io_mask >>= 1) {
|
||||
if ((io_mask & 1) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (!esp_sleep_is_valid_wakeup_gpio(gpio)) {
|
||||
ESP_LOGE(TAG, "Not an RTC IO Considering io_mask: GPIO%d", gpio);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
rtc_gpio_mask |= BIT(rtc_io_number_get(gpio));
|
||||
}
|
||||
s_config.ext1_rtc_gpio_mask &= (~rtc_gpio_mask);
|
||||
s_config.ext1_trigger_mode &= (~rtc_gpio_mask);
|
||||
}
|
||||
|
||||
if (s_config.ext1_rtc_gpio_mask == 0) {
|
||||
s_config.wakeup_triggers &= (~RTC_EXT1_TRIG_EN);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN
|
||||
esp_err_t esp_sleep_enable_ext1_wakeup_with_level_mask(uint64_t io_mask, uint64_t level_mask)
|
||||
{
|
||||
|
@@ -178,7 +178,7 @@ TEST_CASE("Can wake up from automatic light sleep by GPIO", "[pm][ignore]")
|
||||
rtc_gpio_set_level(ext1_wakeup_gpio, 0);
|
||||
|
||||
/* Enable wakeup */
|
||||
TEST_ESP_OK(esp_sleep_enable_ext1_wakeup(1ULL << ext1_wakeup_gpio, ESP_EXT1_WAKEUP_ANY_HIGH));
|
||||
TEST_ESP_OK(esp_sleep_enable_ext1_wakeup_io(1ULL << ext1_wakeup_gpio, ESP_EXT1_WAKEUP_ANY_HIGH));
|
||||
|
||||
/* To simplify test environment, we'll use a ULP program to set GPIO high */
|
||||
ulp_insn_t ulp_code[] = {
|
||||
|
@@ -220,7 +220,7 @@ RTC peripherals or RTC memories do not need to be powered on during sleep in thi
|
||||
External Wakeup (``ext1``)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The RTC controller contains the logic to trigger wakeup using multiple RTC GPIOs. One of the following two logic functions can be used to trigger general ext1 wakeup:
|
||||
The RTC controller contains the logic to trigger wakeup using multiple RTC GPIOs. One of the following two logic functions can be used to trigger ext1 wakeup:
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
@@ -248,11 +248,19 @@ RTC peripherals or RTC memories do not need to be powered on during sleep in thi
|
||||
gpio_pullup_dis(gpio_num);
|
||||
gpio_pulldown_en(gpio_num);
|
||||
|
||||
:cpp:func:`esp_sleep_enable_ext1_wakeup` function can be used to enable this wakeup source for general ext1 wakeup.
|
||||
:cpp:func:`esp_sleep_enable_ext1_wakeup_io` function can be used to append ext1 wakeup IO and set corresponding wakeup level.
|
||||
|
||||
:cpp:func:`esp_sleep_disable_ext1_wakeup_io` function can be used to remove ext1 wakeup IO.
|
||||
|
||||
.. only:: SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN
|
||||
|
||||
Besides the above mentioned general ext1 wakeup, the RTC controller also contains a more powerful logic to trigger wakeup using multiple RTC GPIOs with a customized RTC IO wakeup level bitmap. This can be configured with :cpp:func`esp_sleep_enable_ext1_wakeup_with_level_mask`.
|
||||
The RTC controller also supports triggering wakeup, allowing configurable IO to use different wakeup levels simultaneously. This can be configured with :cpp:func:`esp_sleep_enable_ext1_wakeup_io` or :cpp:func:`esp_sleep_enable_ext1_wakeup_with_level_mask`.
|
||||
|
||||
.. only:: not SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN
|
||||
|
||||
.. note::
|
||||
|
||||
Due to hardware limitation, when we use more than one IO for EXT1 wakeup, it is not allowed to configure different wakeup levels for the IOs, and there is corresponding inspection mechanism in :cpp:func:`esp_sleep_enable_ext1_wakeup_io`.
|
||||
|
||||
.. warning::
|
||||
|
||||
|
@@ -220,7 +220,7 @@ RTC 控制器中内嵌定时器,可用于在预定义的时间到达后唤醒
|
||||
外部唤醒 (``ext1``)
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
RTC 控制器中包含使用多个 RTC GPIO 触发唤醒的逻辑。从以下两个逻辑函数中任选其一,均可触发普通 ext1 唤醒:
|
||||
RTC 控制器中包含使用多个 RTC GPIO 触发唤醒的逻辑。从以下两个逻辑函数中任选其一,均可触发 ext1 唤醒:
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
@@ -248,11 +248,19 @@ RTC 控制器中内嵌定时器,可用于在预定义的时间到达后唤醒
|
||||
gpio_pullup_dis(gpio_num);
|
||||
gpio_pulldown_en(gpio_num);
|
||||
|
||||
可调用 :cpp:func:`esp_sleep_enable_ext1_wakeup` 函数来启用普通 ext1 唤醒。
|
||||
可调用 :cpp:func:`esp_sleep_enable_ext1_wakeup_io` 函数可用于增加 ext1 唤醒 IO 并设置相应的唤醒电平。
|
||||
|
||||
可调用 :cpp:func:`esp_sleep_disable_ext1_wakeup_io` 函数可用于移除 ext1 唤醒 IO。
|
||||
|
||||
.. only:: SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN
|
||||
|
||||
除了上述提到的普通 ext1 唤醒之外,当前的 RTC 控制器也包含更强大的逻辑,可以使用多个 RTC GPIO 并根据自定义的 RTC IO 唤醒电平位图来唤醒。这可以通过:cpp:func:`esp_sleep_enable_ext1_wakeup_with_level_mask` 函数来进行配置。
|
||||
当前的 RTC 控制器也包含更强大的逻辑,允许配置的 IO 同时使用不同的唤醒电平。这可以通过 :cpp:func:`esp_sleep_enable_ext1_wakeup_io` 或 :cpp:func:`esp_sleep_enable_ext1_wakeup_with_level_mask` 函数来进行配置。
|
||||
|
||||
.. only:: not SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN
|
||||
|
||||
.. note::
|
||||
|
||||
由于硬件限制,当我们将多个 IO 用于 EXT1 唤醒,此时不允许将这些 IO 的唤醒模式配置成不同的电平,在 :cpp:func:`esp_sleep_enable_ext1_wakeup_io` 已有相应的内部检查机制。
|
||||
|
||||
.. warning::
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -40,12 +40,10 @@ void example_deep_sleep_register_ext1_wakeup(void)
|
||||
printf("Enabling EXT1 wakeup on pins GPIO%d, GPIO%d\n", ext_wakeup_pin_1, ext_wakeup_pin_2);
|
||||
|
||||
#if SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN
|
||||
const uint64_t ext_wakeup_mode = CONFIG_EXAMPLE_EXT1_WAKEUP_MODE_PIN_1 << ext_wakeup_pin_1 | \
|
||||
CONFIG_EXAMPLE_EXT1_WAKEUP_MODE_PIN_2 << ext_wakeup_pin_2;
|
||||
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_with_level_mask(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ext_wakeup_mode));
|
||||
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(ext_wakeup_pin_1_mask, CONFIG_EXAMPLE_EXT1_WAKEUP_MODE_PIN_1));
|
||||
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(ext_wakeup_pin_2_mask, CONFIG_EXAMPLE_EXT1_WAKEUP_MODE_PIN_2));
|
||||
#else
|
||||
const esp_sleep_ext1_wakeup_mode_t ext_wakeup_mode = CONFIG_EXAMPLE_EXT1_WAKEUP_MODE;
|
||||
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ext_wakeup_mode));
|
||||
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, CONFIG_EXAMPLE_EXT1_WAKEUP_MODE));
|
||||
#endif
|
||||
|
||||
/* If there are no external pull-up/downs, tie wakeup pins to inactive level with internal pull-up/downs via RTC IO
|
||||
|
Reference in New Issue
Block a user