mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-02 12:14:32 +02:00
change(pm): add ext1 new api
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
|
* 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
|
* 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.
|
* 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
|
* @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.
|
* which have RTC functionality can be used in this bit map.
|
||||||
* For different SoCs, the related GPIOs are:
|
* 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_OK on success
|
||||||
* - ESP_ERR_INVALID_ARG if any of the selected GPIOs is not an RTC GPIO,
|
* - ESP_ERR_INVALID_ARG if any of the selected GPIOs is not an RTC GPIO,
|
||||||
* or mode is invalid
|
* 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
|
#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
|
* or mode is invalid
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_sleep_enable_ext1_wakeup_with_level_mask(uint64_t io_mask, uint64_t level_mask);
|
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_MODE_PER_PIN
|
||||||
#endif // SOC_PM_SUPPORT_EXT1_WAKEUP
|
#endif // SOC_PM_SUPPORT_EXT1_WAKEUP
|
||||||
|
|
||||||
|
@@ -1541,7 +1541,19 @@ static void ext0_wakeup_prepare(void)
|
|||||||
#if SOC_PM_SUPPORT_EXT1_WAKEUP
|
#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)
|
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;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
// Translate bit map of GPIO numbers into the bit map of RTC IO numbers
|
// 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));
|
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) {
|
if (level_mode) {
|
||||||
s_config.ext1_trigger_mode = rtc_gpio_mask;
|
ext1_trigger_mode = s_config.ext1_trigger_mode | rtc_gpio_mask;
|
||||||
} else {
|
} 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;
|
s_config.wakeup_triggers |= RTC_EXT1_TRIG_EN;
|
||||||
return ESP_OK;
|
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
|
#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)
|
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);
|
rtc_gpio_set_level(ext1_wakeup_gpio, 0);
|
||||||
|
|
||||||
/* Enable wakeup */
|
/* 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 */
|
/* To simplify test environment, we'll use a ULP program to set GPIO high */
|
||||||
ulp_insn_t ulp_code[] = {
|
ulp_insn_t ulp_code[] = {
|
||||||
|
@@ -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
|
* 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);
|
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
|
#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 | \
|
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(ext_wakeup_pin_1_mask, CONFIG_EXAMPLE_EXT1_WAKEUP_MODE_PIN_1));
|
||||||
CONFIG_EXAMPLE_EXT1_WAKEUP_MODE_PIN_2 << ext_wakeup_pin_2;
|
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(ext_wakeup_pin_2_mask, CONFIG_EXAMPLE_EXT1_WAKEUP_MODE_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));
|
|
||||||
#else
|
#else
|
||||||
const esp_sleep_ext1_wakeup_mode_t ext_wakeup_mode = CONFIG_EXAMPLE_EXT1_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));
|
||||||
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ext_wakeup_mode));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If there are no external pull-up/downs, tie wakeup pins to inactive level with internal pull-up/downs via RTC IO
|
/* 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