Просмотр исходного кода

bugfix: support GPIO current leakage workaround for esp32c6/esp32h2

wuzhenghui 2 лет назад
Родитель
Сommit
d3ec7880fe

+ 1 - 0
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()

+ 2 - 3
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
  *

+ 1 - 2
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 = {

+ 1 - 2
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
 

+ 49 - 0
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.
   *