Skip to content

Commit

Permalink
Merge branch 'bringup/esp32h2_deep_sleep_for_rebase_v5.1' into 'relea…
Browse files Browse the repository at this point in the history
…se/v5.1'

esp32h2: support deep_sleep(backport v5.1)

See merge request espressif/esp-idf!24962
  • Loading branch information
jack0c committed Aug 23, 2023
2 parents 6e3c700 + 830a627 commit b638cb3
Show file tree
Hide file tree
Showing 41 changed files with 802 additions and 220 deletions.
2 changes: 1 addition & 1 deletion components/driver/gpio/gpio.c
Expand Up @@ -361,7 +361,7 @@ esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)
if (((gpio_pin_mask >> io_num) & BIT(0))) {
assert(io_reg != (intptr_t)NULL);

#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
#if SOC_RTCIO_PIN_COUNT > 0
if (rtc_gpio_is_valid_gpio(io_num)) {
rtc_gpio_deinit(io_num);
}
Expand Down
45 changes: 25 additions & 20 deletions components/driver/gpio/include/driver/rtc_io.h
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -28,7 +28,7 @@ bool rtc_gpio_is_valid_gpio(gpio_num_t gpio_num);

#define RTC_GPIO_IS_VALID_GPIO(gpio_num) rtc_gpio_is_valid_gpio(gpio_num)

#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
#if SOC_RTCIO_PIN_COUNT > 0
/**
* @brief Get RTC IO index number by gpio number.
*
Expand Down Expand Up @@ -63,6 +63,7 @@ esp_err_t rtc_gpio_init(gpio_num_t gpio_num);
*/
esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num);

#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
/**
* @brief Get the RTC IO input level
*
Expand Down Expand Up @@ -231,24 +232,6 @@ esp_err_t rtc_gpio_hold_en(gpio_num_t gpio_num);
*/
esp_err_t rtc_gpio_hold_dis(gpio_num_t gpio_num);

/**
* @brief Helper function to disconnect internal circuits from an RTC IO
* This function disables input, output, pullup, pulldown, and enables
* hold feature for an RTC IO.
* Use this function if an RTC IO needs to be disconnected from internal
* circuits in deep sleep, to minimize leakage current.
*
* In particular, for ESP32-WROVER module, call
* rtc_gpio_isolate(GPIO_NUM_12) before entering deep sleep, to reduce
* deep sleep current.
*
* @param gpio_num GPIO number (e.g. GPIO_NUM_12).
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if GPIO is not an RTC IO
*/
esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num);

/**
* @brief Enable force hold signal for all RTC IOs
*
Expand All @@ -267,6 +250,26 @@ esp_err_t rtc_gpio_force_hold_dis_all(void);

#endif // SOC_RTCIO_HOLD_SUPPORTED

#if SOC_RTCIO_HOLD_SUPPORTED && SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
/**
* @brief Helper function to disconnect internal circuits from an RTC IO
* This function disables input, output, pullup, pulldown, and enables
* hold feature for an RTC IO.
* Use this function if an RTC IO needs to be disconnected from internal
* circuits in deep sleep, to minimize leakage current.
*
* In particular, for ESP32-WROVER module, call
* rtc_gpio_isolate(GPIO_NUM_12) before entering deep sleep, to reduce
* deep sleep current.
*
* @param gpio_num GPIO number (e.g. GPIO_NUM_12).
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if GPIO is not an RTC IO
*/
esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num);
#endif // SOC_RTCIO_HOLD_SUPPORTED && SOC_RTCIO_INPUT_OUTPUT_SUPPORTED

#if SOC_RTCIO_WAKE_SUPPORTED

/**
Expand All @@ -292,6 +295,8 @@ esp_err_t rtc_gpio_wakeup_disable(gpio_num_t gpio_num);

#endif // SOC_RTCIO_WAKE_SUPPORTED

#endif // SOC_RTCIO_PIN_COUNT > 0

#ifdef __cplusplus
}
#endif
54 changes: 28 additions & 26 deletions components/driver/gpio/rtc_io.c
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -13,6 +13,7 @@
#include "freertos/timers.h"
#include "driver/rtc_io.h"
#include "hal/rtc_io_hal.h"
#include "soc/rtc_io_periph.h"
#include "soc/soc_caps.h"

static const char __attribute__((__unused__)) *RTCIO_TAG = "RTCIO";
Expand All @@ -21,11 +22,24 @@ extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate posi
#define RTCIO_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
#define RTCIO_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)

#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
bool rtc_gpio_is_valid_gpio(gpio_num_t gpio_num)
{
#if SOC_RTCIO_PIN_COUNT > 0
return (gpio_num < GPIO_PIN_COUNT && rtc_io_num_map[gpio_num] >= 0);
#else
return false;
#endif
}

#if SOC_RTCIO_PIN_COUNT > 0
/*---------------------------------------------------------------
RTC IO
---------------------------------------------------------------*/
int rtc_io_number_get(gpio_num_t gpio_num)
{
return rtc_io_num_map[gpio_num];
}

esp_err_t rtc_gpio_init(gpio_num_t gpio_num)
{
ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
Expand All @@ -47,6 +61,7 @@ esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num)
return ESP_OK;
}

#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level)
{
ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
Expand Down Expand Up @@ -167,34 +182,36 @@ esp_err_t rtc_gpio_hold_dis(gpio_num_t gpio_num)
return ESP_OK;
}

esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num)
esp_err_t rtc_gpio_force_hold_en_all(void)
{
ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
RTCIO_ENTER_CRITICAL();
rtcio_hal_isolate(rtc_io_number_get(gpio_num));
rtcio_hal_hold_all();
RTCIO_EXIT_CRITICAL();

return ESP_OK;
}

esp_err_t rtc_gpio_force_hold_en_all(void)
esp_err_t rtc_gpio_force_hold_dis_all(void)
{
RTCIO_ENTER_CRITICAL();
rtcio_hal_hold_all();
rtcio_hal_unhold_all();
RTCIO_EXIT_CRITICAL();

return ESP_OK;
}
#endif // SOC_RTCIO_HOLD_SUPPORTED

esp_err_t rtc_gpio_force_hold_dis_all(void)
#if SOC_RTCIO_HOLD_SUPPORTED && SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
esp_err_t rtc_gpio_isolate(gpio_num_t gpio_num)
{
ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
RTCIO_ENTER_CRITICAL();
rtcio_hal_unhold_all();
rtcio_hal_isolate(rtc_io_number_get(gpio_num));
RTCIO_EXIT_CRITICAL();

return ESP_OK;
}
#endif // SOC_RTCIO_HOLD_SUPPORTED
#endif // SOC_RTCIO_HOLD_SUPPORTED && SOC_RTCIO_INPUT_OUTPUT_SUPPORTED

#if SOC_RTCIO_WAKE_SUPPORTED

Expand All @@ -221,19 +238,4 @@ esp_err_t rtc_gpio_wakeup_disable(gpio_num_t gpio_num)

#endif // SOC_RTCIO_WAKE_SUPPORTED

bool rtc_gpio_is_valid_gpio(gpio_num_t gpio_num)
{
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
return (gpio_num < GPIO_PIN_COUNT && rtc_io_num_map[gpio_num] >= 0);
#else
return false;
#endif
}

#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
int rtc_io_number_get(gpio_num_t gpio_num)
{
return rtc_io_num_map[gpio_num];
}

#endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
#endif // SOC_RTCIO_PIN_COUNT > 0
2 changes: 1 addition & 1 deletion components/driver/test_apps/gpio/main/CMakeLists.txt
Expand Up @@ -5,7 +5,7 @@ if(CONFIG_SOC_SDM_SUPPORTED)
list(APPEND srcs "test_sigma_delta_legacy.c")
endif()

if(CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED)
if(CONFIG_SOC_RTCIO_PIN_COUNT GREATER 0)
list(APPEND srcs "test_rtcio.c")
endif()

Expand Down
32 changes: 23 additions & 9 deletions components/driver/test_apps/gpio/main/test_rtcio.c
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -17,12 +17,6 @@
#include "esp_log.h"
#include "soc/rtc_io_periph.h"

#define RTCIO_CHECK(condition) TEST_ASSERT_MESSAGE((condition == ESP_OK), "ret is not ESP_OK")
#define RTCIO_VERIFY(condition, msg) TEST_ASSERT_MESSAGE((condition), msg)

#define TEST_COUNT 10
static const char *TAG = "rtcio_test";

#ifdef CONFIG_IDF_TARGET_ESP32
// The input-only rtcio pins do not have pull-up/down resistors (not support pull-up/down)
#define RTCIO_SUPPORT_PU_PD(num) (rtc_io_desc[num].pullup != 0)
Expand Down Expand Up @@ -117,8 +111,27 @@ const int s_test_map[TEST_GPIO_PIN_COUNT] = {
GPIO_NUM_6, //GPIO6
GPIO_NUM_7, //GPIO7
};
#elif CONFIG_IDF_TARGET_ESP32H2
#define TEST_GPIO_PIN_COUNT 8
const int s_test_map[TEST_GPIO_PIN_COUNT] = {
GPIO_NUM_7, //GPIO7
GPIO_NUM_8, //GPIO8
GPIO_NUM_9, //GPIO9
GPIO_NUM_10, //GPIO10
GPIO_NUM_11, //GPIO11
GPIO_NUM_12, //GPIO12
GPIO_NUM_13, //GPIO13
GPIO_NUM_14, //GPIO14
};
#endif

#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
static const char *TAG = "rtcio_test";

#define RTCIO_CHECK(condition) TEST_ASSERT_MESSAGE((condition == ESP_OK), "ret is not ESP_OK")

#define TEST_COUNT 10

/*
* Test output/input function.
*/
Expand Down Expand Up @@ -325,10 +338,12 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]")
}
ESP_LOGI(TAG, "RTCIO hold test over");
}
#endif //SOC_RTCIO_HOLD_SUPPORTED
#endif //SOC_RTCIO_INPUT_OUTPUT_SUPPORTED

// It is not necessary to test every rtcio pin, it will take too much ci testing time for deep sleep
// Only tests on s_test_map[TEST_RTCIO_DEEP_SLEEP_PIN_INDEX] pin
// (ESP32: IO25, ESP32S2, S3: IO6, C6: IO5) these pads' default configuration is low level
// (ESP32: IO25, ESP32S2, S3: IO6, C6: IO5, H2: IO12) these pads' default configuration is low level
#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5

static void rtcio_deep_sleep_hold_test_first_stage(void)
Expand Down Expand Up @@ -374,4 +389,3 @@ static void rtcio_deep_sleep_hold_test_second_stage(void)
TEST_CASE_MULTIPLE_STAGES("RTCIO_deep_sleep_output_hold_test", "[rtcio]",
rtcio_deep_sleep_hold_test_first_stage,
rtcio_deep_sleep_hold_test_second_stage)
#endif //SOC_RTCIO_HOLD_SUPPORTED
1 change: 1 addition & 0 deletions components/driver/test_apps/gpio/pytest_gpio.py
Expand Up @@ -33,6 +33,7 @@ def test_legacy_sigma_delta(dut: IdfDut) -> None:
@pytest.mark.esp32s2
@pytest.mark.esp32s3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.generic
@pytest.mark.parametrize('config', CONFIGS, indirect=True)
def test_rtc_io(dut: IdfDut) -> None:
Expand Down
6 changes: 0 additions & 6 deletions components/esp_hw_support/CMakeLists.txt
Expand Up @@ -114,12 +114,6 @@ if(NOT BOOTLOADER_BUILD)
if(CONFIG_SOC_RTC_FAST_MEM_SUPPORTED)
list(APPEND srcs "sleep_wake_stub.c")
endif()

if(CONFIG_IDF_TARGET_ESP32H2)
list(REMOVE_ITEM srcs
"sleep_wake_stub.c" # TODO: IDF-6268
)
endif()
else()
# Requires "_esp_error_check_failed()" function
list(APPEND priv_requires "esp_system")
Expand Down
36 changes: 28 additions & 8 deletions components/esp_hw_support/include/esp_sleep.h
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -26,10 +26,21 @@ typedef void (*esp_deep_sleep_cb_t)(void);
/**
* @brief Logic function used for EXT1 wakeup mode.
*/
#if SOC_PM_SUPPORT_EXT1_WAKEUP
#if CONFIG_IDF_TARGET_ESP32
typedef enum {
ESP_EXT1_WAKEUP_ALL_LOW = 0, //!< Wake the chip when all selected GPIOs go low
ESP_EXT1_WAKEUP_ANY_HIGH = 1 //!< Wake the chip when any of the selected GPIOs go high
} esp_sleep_ext1_wakeup_mode_t;
#else
typedef enum {
ESP_EXT1_WAKEUP_ANY_LOW = 0, //!< Wake the chip when any of the selected GPIOs go low
ESP_EXT1_WAKEUP_ANY_HIGH = 1, //!< Wake the chip when any of the selected GPIOs go high
ESP_EXT1_WAKEUP_ALL_LOW __attribute__((deprecated("wakeup mode \"ALL_LOW\" is no longer supported after ESP32, \
please use ESP_EXT1_WAKEUP_ANY_LOW instead"))) = ESP_EXT1_WAKEUP_ANY_LOW
} esp_sleep_ext1_wakeup_mode_t;
#endif
#endif

#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
typedef enum {
Expand Down Expand Up @@ -250,18 +261,27 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
* @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.
* 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 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: 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 mode select logic function used to determine wakeup condition:
* - 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:
* - 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 any of the selected GPIOs is not an RTC GPIO,
Expand Down
3 changes: 3 additions & 0 deletions components/esp_hw_support/port/esp32h2/pmu_sleep.c
Expand Up @@ -14,6 +14,7 @@
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/pmu_struct.h"
#include "hal/lp_aon_hal.h"
#include "esp_private/esp_pmu.h"

#define HP(state) (PMU_MODE_HP_ ## state)
Expand Down Expand Up @@ -218,6 +219,8 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
{
assert(PMU_instance()->hal);

lp_aon_hal_inform_wakeup_type(dslp);

pmu_ll_hp_set_wakeup_enable(PMU_instance()->hal->dev, wakeup_opt);
pmu_ll_hp_set_reject_enable(PMU_instance()->hal->dev, reject_opt);

Expand Down

0 comments on commit b638cb3

Please sign in to comment.