mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-11 08:34:34 +02:00
gpio: Fix io hold functionality on esp32c6 and esp32h2
This commit is contained in:
committed by
wuzhenghui
parent
7ee64bd8e8
commit
51777a6862
@@ -734,6 +734,7 @@ esp_err_t gpio_hold_dis(gpio_num_t gpio_num)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
|
||||
void gpio_deep_sleep_hold_en(void)
|
||||
{
|
||||
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
@@ -747,9 +748,9 @@ void gpio_deep_sleep_hold_dis(void)
|
||||
gpio_hal_deep_sleep_hold_dis(gpio_context.gpio_hal);
|
||||
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
}
|
||||
#endif //!SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
|
||||
|
||||
#if SOC_GPIO_SUPPORT_FORCE_HOLD
|
||||
|
||||
esp_err_t IRAM_ATTR gpio_force_hold_all()
|
||||
{
|
||||
#if SOC_RTCIO_HOLD_SUPPORTED
|
||||
@@ -771,7 +772,7 @@ esp_err_t IRAM_ATTR gpio_force_unhold_all()
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
#endif //SOC_GPIO_SUPPORT_FORCE_HOLD
|
||||
|
||||
void gpio_iomux_in(uint32_t gpio, uint32_t signal_idx)
|
||||
{
|
||||
|
@@ -374,10 +374,9 @@ esp_err_t gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t *stren
|
||||
* in output mode: the output level of the GPIO will be locked and can not be changed.
|
||||
* in input mode: the input read value can still reflect the changes of the input signal.
|
||||
*
|
||||
* However, this function cannot be used to hold the state of a digital GPIO during Deep-sleep. Even if this
|
||||
* function is enabled, the digital GPIO will be reset to its default state when the chip wakes up from
|
||||
* Deep-sleep. If you want to hold the state of a digital GPIO during Deep-sleep, please call
|
||||
* `gpio_deep_sleep_hold_en`.
|
||||
* However, on ESP32/S2/C3/S3/C2, this function cannot be used to hold the state of a digital GPIO during Deep-sleep.
|
||||
* Even if this function is enabled, the digital GPIO will be reset to its default state when the chip wakes up from
|
||||
* Deep-sleep. If you want to hold the state of a digital GPIO during Deep-sleep, please call `gpio_deep_sleep_hold_en`.
|
||||
*
|
||||
* Power down or call `gpio_hold_dis` will disable this function.
|
||||
*
|
||||
@@ -408,6 +407,7 @@ esp_err_t gpio_hold_en(gpio_num_t gpio_num);
|
||||
*/
|
||||
esp_err_t gpio_hold_dis(gpio_num_t gpio_num);
|
||||
|
||||
#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
|
||||
/**
|
||||
* @brief Enable all digital gpio pads hold function during Deep-sleep.
|
||||
*
|
||||
@@ -426,6 +426,7 @@ void gpio_deep_sleep_hold_en(void);
|
||||
* @brief Disable all digital gpio pads hold function during Deep-sleep.
|
||||
*/
|
||||
void gpio_deep_sleep_hold_dis(void);
|
||||
#endif //!SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
|
||||
|
||||
/**
|
||||
* @brief Set pad input to a peripheral signal through the IOMUX.
|
||||
|
@@ -326,10 +326,9 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]")
|
||||
ESP_LOGI(TAG, "RTCIO hold test over");
|
||||
}
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6) // TODO: IDF-5349 Remove when deep sleep is supported on ESP32C6
|
||||
// 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) these pads' default configuration is low level
|
||||
// (ESP32: IO25, ESP32S2, S3: IO6, C6: IO5) 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)
|
||||
@@ -375,5 +374,4 @@ 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 // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2)
|
||||
#endif // #if SOC_RTCIO_HOLD_SUPPORTED
|
||||
#endif //SOC_RTCIO_HOLD_SUPPORTED
|
||||
|
@@ -541,10 +541,12 @@ void IRAM_ATTR call_start_cpu0(void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
|
||||
// Need to unhold the IOs that were hold right before entering deep sleep, which are used as wakeup pins
|
||||
if (rst_reas[0] == RESET_REASON_CORE_DEEP_SLEEP) {
|
||||
esp_deep_sleep_wakeup_io_reset();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
esp_cache_err_int_init();
|
||||
|
@@ -21,7 +21,7 @@
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "soc/lp_aon_struct.h"
|
||||
#include "soc/lp_io_struct.h"
|
||||
#include "soc/pmu_reg.h"
|
||||
#include "soc/pmu_struct.h"
|
||||
#include "soc/usb_serial_jtag_reg.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
@@ -355,26 +355,6 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu
|
||||
*strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable all digital gpio pads hold function during Deep-sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
*/
|
||||
static inline void gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw)
|
||||
{
|
||||
REG_SET_BIT(PMU_IMM_PAD_HOLD_ALL_REG, PMU_TIE_HIGH_HP_PAD_HOLD_ALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable all digital gpio pads hold function during Deep-sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
*/
|
||||
static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
|
||||
{
|
||||
REG_SET_BIT(PMU_IMM_PAD_HOLD_ALL_REG, PMU_TIE_LOW_HP_PAD_HOLD_ALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable gpio pad hold function.
|
||||
*
|
||||
@@ -497,6 +477,26 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force hold digital io pad.
|
||||
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
|
||||
*/
|
||||
static inline void gpio_ll_force_hold_all(void)
|
||||
{
|
||||
// WT flag, it gets self-cleared after the configuration is done
|
||||
PMU.imm.pad_hold_all.tie_high_hp_pad_hold_all = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force unhold digital io pad.
|
||||
* @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
|
||||
*/
|
||||
static inline void gpio_ll_force_unhold_all(void)
|
||||
{
|
||||
// WT flag, it gets self-cleared after the configuration is done
|
||||
PMU.imm.pad_hold_all.tie_low_hp_pad_hold_all = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin to use sleep mode pin functions during light sleep.
|
||||
*
|
||||
|
@@ -30,8 +30,6 @@ extern "C" {
|
||||
|
||||
#define RTCIO_LL_PIN_FUNC 0
|
||||
|
||||
#define RTCIO_LL_PIN_MASK_ALL ((1 << SOC_RTCIO_PIN_COUNT) - 1)
|
||||
|
||||
typedef enum {
|
||||
RTCIO_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */
|
||||
RTCIO_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */
|
||||
@@ -244,22 +242,6 @@ static inline void rtcio_ll_force_hold_disable(int rtcio_num)
|
||||
LP_AON.gpio_hold0.gpio_hold0 &= ~BIT(rtcio_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable all LP IO pads hold function during Deep-sleep
|
||||
*/
|
||||
static inline void rtcio_ll_deep_sleep_hold_en_all(void)
|
||||
{
|
||||
PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable all LP IO pads hold function during Deep-sleep
|
||||
*/
|
||||
static inline void rtcio_ll_deep_sleep_hold_dis_all(void)
|
||||
{
|
||||
PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable force hold function for all RTC IO pads
|
||||
*
|
||||
@@ -270,8 +252,7 @@ static inline void rtcio_ll_deep_sleep_hold_dis_all(void)
|
||||
*/
|
||||
static inline void rtcio_ll_force_hold_all(void)
|
||||
{
|
||||
// No such a 'hold_all' bit on C6, use bit hold instead
|
||||
LP_AON.gpio_hold0.gpio_hold0 |= RTCIO_LL_PIN_MASK_ALL;
|
||||
PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,8 +262,7 @@ static inline void rtcio_ll_force_hold_all(void)
|
||||
*/
|
||||
static inline void rtcio_ll_force_unhold_all(void)
|
||||
{
|
||||
// No such a 'hold_all' bit on C6, use bit hold instead
|
||||
LP_AON.gpio_hold0.gpio_hold0 &= ~RTCIO_LL_PIN_MASK_ALL;
|
||||
PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -20,7 +20,7 @@
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "soc/lp_aon_struct.h"
|
||||
#include "soc/pmu_reg.h"
|
||||
#include "soc/pmu_struct.h"
|
||||
#include "soc/usb_serial_jtag_reg.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
@@ -398,26 +398,6 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, gpio_num_t gpio_
|
||||
*strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable all digital gpio pad hold function during Deep-sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
*/
|
||||
static inline void gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw)
|
||||
{
|
||||
REG_SET_BIT(PMU_IMM_PAD_HOLD_ALL_REG, PMU_TIE_HIGH_HP_PAD_HOLD_ALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable all digital gpio pad hold function during Deep-sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
*/
|
||||
static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
|
||||
{
|
||||
REG_SET_BIT(PMU_IMM_PAD_HOLD_ALL_REG, PMU_TIE_LOW_HP_PAD_HOLD_ALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable gpio pad hold function.
|
||||
*
|
||||
@@ -522,6 +502,28 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force hold all digital(VDDPST2) and lp(VDDPST1) io pads.
|
||||
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
|
||||
*/
|
||||
static inline void gpio_ll_force_hold_all(void)
|
||||
{
|
||||
// WT flags, they get self-cleared after the configuration is done
|
||||
PMU.imm.pad_hold_all.tie_high_hp_pad_hold_all = 1;
|
||||
PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force unhold all digital(VDDPST2) and lp(VDDPST1) io pads.
|
||||
* @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
|
||||
*/
|
||||
static inline void gpio_ll_force_unhold_all(void)
|
||||
{
|
||||
// WT flags, they get self-cleared after the configuration is done
|
||||
PMU.imm.pad_hold_all.tie_low_hp_pad_hold_all = 1;
|
||||
PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin to use sleep mode pin functions during light sleep.
|
||||
*
|
||||
|
@@ -242,8 +242,8 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num);
|
||||
* in output mode: the output level of the pad will be force locked and can not be changed.
|
||||
* in input mode: the input value read will not change, regardless the changes of input signal.
|
||||
*
|
||||
* The state of digital gpio cannot be held during Deep-sleep, and it will resume the hold function
|
||||
* when the chip wakes up from Deep-sleep. If the digital gpio also needs to be held during Deep-sleep,
|
||||
* On ESP32/S2/C3/S3/C2, the state of digital gpio cannot be held during Deep-sleep, and it will resume the hold
|
||||
* function when the chip wakes up from Deep-sleep. If the digital gpio also needs to be held during Deep-sleep,
|
||||
* `gpio_deep_sleep_hold_en` should also be called.
|
||||
*
|
||||
* Power down or call gpio_hold_dis will disable this function.
|
||||
@@ -285,6 +285,7 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num);
|
||||
*/
|
||||
#define gpio_hal_is_digital_io_hold(hal, gpio_num) gpio_ll_is_digital_io_hold((hal)->dev, gpio_num)
|
||||
|
||||
#if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
|
||||
/**
|
||||
* @brief Enable all digital gpio pad hold function during Deep-sleep.
|
||||
*
|
||||
@@ -315,6 +316,7 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num);
|
||||
* - false deep sleep hold is disabled
|
||||
*/
|
||||
#define gpio_hal_deep_sleep_hold_is_en(hal) gpio_ll_deep_sleep_hold_is_en((hal)->dev)
|
||||
#endif //!SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
|
||||
|
||||
/**
|
||||
* @brief Set pad input to a peripheral signal through the IOMUX.
|
||||
|
@@ -403,6 +403,10 @@ config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK
|
||||
hex
|
||||
default 0x000000007FFFFF00
|
||||
|
||||
config SOC_GPIO_SUPPORT_FORCE_HOLD
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
|
||||
bool
|
||||
default y
|
||||
|
@@ -184,7 +184,9 @@
|
||||
// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_8~GPIO_NUM_30)
|
||||
#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x000000007FFFFF00ULL
|
||||
|
||||
// Support to hold a single GPIO when the digital domain is powered off
|
||||
// Support to force hold all IOs
|
||||
#define SOC_GPIO_SUPPORT_FORCE_HOLD (1)
|
||||
// Support to hold a single digital I/O when the digital domain is powered off
|
||||
#define SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP (1)
|
||||
|
||||
/*-------------------------- RTCIO CAPS --------------------------------------*/
|
||||
|
@@ -371,6 +371,10 @@ config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK
|
||||
hex
|
||||
default 0x000000000FFF807F
|
||||
|
||||
config SOC_GPIO_SUPPORT_FORCE_HOLD
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
|
||||
bool
|
||||
default y
|
||||
|
@@ -181,7 +181,9 @@
|
||||
// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_0~6. GPIO_NUM_15~27)
|
||||
#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x000000000FFF807FULL
|
||||
|
||||
// Support to hold a single GPIO when the digital domain is powered off
|
||||
// Support to force hold all IOs
|
||||
#define SOC_GPIO_SUPPORT_FORCE_HOLD (1)
|
||||
// Support to hold a single digital I/O when the digital domain is powered off
|
||||
#define SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP (1)
|
||||
|
||||
/*-------------------------- Dedicated GPIO CAPS -----------------------------*/
|
||||
|
@@ -133,7 +133,9 @@ void app_main(void)
|
||||
* during deepsleep. However, RTC IO relies on the RTC_PERIPH power domain. Keeping this power domain on will
|
||||
* increase some power comsumption. */
|
||||
# if CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS
|
||||
#if SOC_PM_SUPPORT_RTC_PERIPH_PD
|
||||
ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
|
||||
#endif
|
||||
ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_1));
|
||||
ESP_ERROR_CHECK(rtc_gpio_pulldown_en(ext_wakeup_pin_1));
|
||||
ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_2));
|
||||
|
Reference in New Issue
Block a user