feat(pm/ext1): support esp_sleep_enable_io_ext1_wakeup and esp_sleep_disable_io_ext1_wakeup

squash! feat(pm/ext1): support esp_sleep_enable_io_ext1_wakeup and esp_sleep_disable_io_ext1_wakeup
This commit is contained in:
Lou Tianhao 2023-11-09 18:20:35 +08:00
parent 7469df6c14
commit cc0e73a11f
5 changed files with 159 additions and 9 deletions

View File

@ -267,6 +267,61 @@ 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_set_ext1_wakeup_io` and `esp_sleep_clear_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_clear_ext1_wakeup_io with the io_mask.
* To reset all the enabled IOs, call esp_sleep_clear_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.
*
* @note this func allows to increase the configuration for ext1 without resetting the previous configuration.
*
* @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 +341,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_ALLOWED 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_set_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_clear_ext1_wakeup_io(uint64_t io_mask);
#if SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN
/**
@ -328,6 +403,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

View File

@ -1476,7 +1476,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_clear_ext1_wakeup_io(0);
return esp_sleep_set_ext1_wakeup_io(io_mask, level_mode);
}
esp_err_t esp_sleep_set_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
@ -1491,16 +1503,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_ALLOWED;
}
#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_clear_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)
{

View File

@ -248,11 +248,15 @@ 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_append_ext1_wakeup` function can be used to append ext1 wakeup IO and set corresponding wakeup level.
:cpp:func:`esp_sleep_remove_ext1_wakeup` function can be used to remove ext1 wakeup IO.
:cpp:func:`esp_sleep_enable_ext1_wakeup` function can be used to reset all previous ext1 wakeup configurations and enable new ext1 wakeup IO and set corresponding wakeup level.
.. 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_append_ext1_wakeup`.
.. warning::

View File

@ -0,0 +1,9 @@
System
======
:link_to_translation:`zh_CN:[中文]`
Power Management
-----------------------
* ``esp_sleep_enable_ext1_wakeup_with_level_mask`` is deprecated, use ``esp_sleep_append_ext1_wakeup`` and ``esp_sleep_remove_ext1_wakeup`` instead.

View File

@ -248,11 +248,15 @@ RTC 控制器中内嵌定时器,可用于在预定义的时间到达后唤醒
gpio_pullup_dis(gpio_num);
gpio_pulldown_en(gpio_num);
可调用 :cpp:func:`esp_sleep_enable_ext1_wakeup` 函数来启用普通 ext1 唤醒。
可调用 :cpp:func:`esp_sleep_append_ext1_wakeup` 函数可用于增加 ext1 唤醒 IO 并设置相应的唤醒电平。
可调用 :cpp:func:`esp_sleep_remove_ext1_wakeup` 函数可用于移除 ext1 唤醒 IO。
可调用 :cpp:func:`esp_sleep_enable_ext1_wakeup` 函数可用于重置所有先前的 ext1 唤醒配置,并启用新的 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_append_ext1_wakeup` 函数来进行配置。
.. warning::