diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 5a9a94b35f..e6ad10abd1 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -110,6 +110,7 @@ if(NOT BOOTLOADER_BUILD) "sleep_cpu.c" # TODO: IDF-6267 "sleep_modes.c" # TODO: IDF-6267 "sleep_wake_stub.c" # TODO: IDF-6267 + "sleep_gpio.c" # TODO: IDF-6267 ) endif() else() diff --git a/components/esp_hw_support/include/esp_private/esp_sleep_internal.h b/components/esp_hw_support/include/esp_private/esp_sleep_internal.h index 07af89ff9f..56a6b5fde1 100644 --- a/components/esp_hw_support/include/esp_private/esp_sleep_internal.h +++ b/components/esp_hw_support/include/esp_private/esp_sleep_internal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -21,8 +21,7 @@ extern "C" { */ void esp_sleep_enable_adc_tsens_monitor(bool enable); -// TODO: IDF-6051, IDF-6052 -#if !CONFIG_IDF_TARGET_ESP32H4 && !CONFIG_IDF_TARGET_ESP32C6 +#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP /** * @brief Isolate all digital IOs except those that are held during deep sleep * diff --git a/components/esp_hw_support/sleep_gpio.c b/components/esp_hw_support/sleep_gpio.c index 0b30f0b10d..3d2e6b52da 100644 --- a/components/esp_hw_support/sleep_gpio.c +++ b/components/esp_hw_support/sleep_gpio.c @@ -107,8 +107,7 @@ void esp_sleep_enable_gpio_switch(bool enable) } } -// TODO: IDF-6051, IDF-6052 -#if !CONFIG_IDF_TARGET_ESP32H4 && !CONFIG_IDF_TARGET_ESP32C6 && !CONFIG_IDF_TARGET_ESP32H2 +#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP IRAM_ATTR void esp_sleep_isolate_digital_gpio(void) { gpio_hal_context_t gpio_hal = { diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index a2edd0ddeb..14212f2e9e 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -533,8 +533,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo uint32_t result; if (deep_sleep) { -// TODO: IDF-6051, IDF-6052 -#if !CONFIG_IDF_TARGET_ESP32H4 && !CONFIG_IDF_TARGET_ESP32C6 && !CONFIG_IDF_TARGET_ESP32H2 +#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP esp_sleep_isolate_digital_gpio(); #endif diff --git a/components/hal/esp32h4/include/rev1/hal/gpio_ll.h b/components/hal/esp32h4/include/rev1/hal/gpio_ll.h index c57700fb8e..37c0bc928c 100644 --- a/components/hal/esp32h4/include/rev1/hal/gpio_ll.h +++ b/components/hal/esp32h4/include/rev1/hal/gpio_ll.h @@ -270,6 +270,22 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) hw->pin[gpio_num].pin_pad_driver = 1; } +/** + * @brief Select a function for the pin in the IOMUX + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @param func Function to assign to the pin + */ +static inline __attribute__((always_inline)) void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func) +{ + // Disable USB Serial JTAG if pins 18 or pins 19 needs to select an IOMUX function + if (gpio_num == USB_DM_GPIO_NUM || gpio_num == USB_DP_GPIO_NUM) { + CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE); + } + PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func); +} + /** * @brief GPIO set output level * @@ -383,6 +399,21 @@ static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw) SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD); } +/** + * @brief Get deep sleep hold status + * + * @param hw Peripheral GPIO hardware instance address. + * + * @return + * - true deep sleep hold is enabled + * - false deep sleep hold is disabled + */ +__attribute__((always_inline)) +static inline bool gpio_ll_deep_sleep_hold_is_en(gpio_dev_t *hw) +{ + return !GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD) && GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M); +} + /** * @brief Enable gpio pad hold function. * @@ -417,6 +448,24 @@ static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num) } } +/** + * @brief Get digital gpio pad hold status. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number, only support output GPIOs + * + * @note caller must ensure that gpio_num is a digital io pad + * + * @return + * - true digital gpio pad is held + * - false digital gpio pad is unheld + */ +__attribute__((always_inline)) +static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) +{ + return GET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, BIT(gpio_num)); +} + /** * @brief Set pad input to a peripheral signal through the IOMUX. *