mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/gpio_slp_leakage_current_opt' into 'master'
components/pm: Add gpio configure workaround at slept status Closes IDF-2637 See merge request espressif/esp-idf!11292
This commit is contained in:
commit
46b29f8c6b
@ -114,4 +114,18 @@ menu "Driver configurations"
|
||||
|
||||
endmenu # RTCIO Configuration
|
||||
|
||||
menu "GPIO Configuration"
|
||||
visible if IDF_TARGET_ESP32
|
||||
|
||||
config GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
bool "Support light sleep GPIO pullup/pulldown configuration for ESP32"
|
||||
depends on IDF_TARGET_ESP32
|
||||
help
|
||||
This option is intended to fix the bug that ESP32 is not able to switch to configured
|
||||
pullup/pulldown mode in sleep.
|
||||
If this option is selected, chip will automatically emulate the behaviour of switching,
|
||||
and about 450B of source codes would be placed into IRAM.
|
||||
|
||||
endmenu # GPIO Configuration
|
||||
|
||||
endmenu # Driver configurations
|
||||
|
@ -704,3 +704,177 @@ void gpio_iomux_out(uint8_t gpio_num, int func, bool oen_inv)
|
||||
{
|
||||
gpio_hal_iomux_out(gpio_context.gpio_hal, gpio_num, func, (uint32_t)oen_inv);
|
||||
}
|
||||
|
||||
#if SOC_GPIO_SUPPORT_SLP_SWITCH
|
||||
static esp_err_t gpio_sleep_pullup_en(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
|
||||
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
gpio_hal_sleep_pullup_en(gpio_context.gpio_hal, gpio_num);
|
||||
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t gpio_sleep_pullup_dis(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
|
||||
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
gpio_hal_sleep_pullup_dis(gpio_context.gpio_hal, gpio_num);
|
||||
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t gpio_sleep_pulldown_en(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
|
||||
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
gpio_hal_sleep_pulldown_en(gpio_context.gpio_hal, gpio_num);
|
||||
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t gpio_sleep_pulldown_dis(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
|
||||
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
gpio_hal_sleep_pulldown_dis(gpio_context.gpio_hal, gpio_num);
|
||||
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t gpio_sleep_input_disable(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
gpio_hal_sleep_input_disable(gpio_context.gpio_hal, gpio_num);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t gpio_sleep_input_enable(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
gpio_hal_sleep_input_enable(gpio_context.gpio_hal, gpio_num);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t gpio_sleep_output_disable(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
gpio_hal_sleep_output_disable(gpio_context.gpio_hal, gpio_num);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t gpio_sleep_output_enable(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG);
|
||||
gpio_hal_sleep_output_enable(gpio_context.gpio_hal, gpio_num);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_sleep_set_direction(gpio_num_t gpio_num, gpio_mode_t mode)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
|
||||
if ((GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) != true) && (mode & GPIO_MODE_DEF_OUTPUT)) {
|
||||
ESP_LOGE(GPIO_TAG, "io_num=%d can only be input", gpio_num);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (mode & GPIO_MODE_DEF_INPUT) {
|
||||
gpio_sleep_input_enable(gpio_num);
|
||||
} else {
|
||||
gpio_sleep_input_disable(gpio_num);
|
||||
}
|
||||
|
||||
if (mode & GPIO_MODE_DEF_OUTPUT) {
|
||||
gpio_sleep_output_enable(gpio_num);
|
||||
} else {
|
||||
gpio_sleep_output_disable(gpio_num);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t gpio_sleep_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
GPIO_CHECK(pull <= GPIO_FLOATING, "GPIO pull mode error", ESP_ERR_INVALID_ARG);
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
switch (pull) {
|
||||
case GPIO_PULLUP_ONLY:
|
||||
gpio_sleep_pulldown_dis(gpio_num);
|
||||
gpio_sleep_pullup_en(gpio_num);
|
||||
break;
|
||||
|
||||
case GPIO_PULLDOWN_ONLY:
|
||||
gpio_sleep_pulldown_en(gpio_num);
|
||||
gpio_sleep_pullup_dis(gpio_num);
|
||||
break;
|
||||
|
||||
case GPIO_PULLUP_PULLDOWN:
|
||||
gpio_sleep_pulldown_en(gpio_num);
|
||||
gpio_sleep_pullup_en(gpio_num);
|
||||
break;
|
||||
|
||||
case GPIO_FLOATING:
|
||||
gpio_sleep_pulldown_dis(gpio_num);
|
||||
gpio_sleep_pullup_dis(gpio_num);
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull);
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t gpio_sleep_sel_en(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
|
||||
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
gpio_hal_sleep_sel_en(gpio_context.gpio_hal, gpio_num);
|
||||
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_sleep_sel_dis(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
|
||||
portENTER_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
gpio_hal_sleep_sel_dis(gpio_context.gpio_hal, gpio_num);
|
||||
portEXIT_CRITICAL(&gpio_context.gpio_spinlock);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
esp_err_t gpio_sleep_pupd_config_apply(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
gpio_hal_sleep_pupd_config_apply(gpio_context.gpio_hal, gpio_num);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_sleep_pupd_config_unapply(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
gpio_hal_sleep_pupd_config_unapply(gpio_context.gpio_hal, gpio_num);
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -445,6 +445,82 @@ esp_err_t gpio_force_hold_all(void);
|
||||
esp_err_t gpio_force_unhold_all(void);
|
||||
#endif
|
||||
|
||||
#if SOC_GPIO_SUPPORT_SLP_SWITCH
|
||||
/**
|
||||
* @brief Enable SLP_SEL to change GPIO status automantically in lightsleep.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_sleep_sel_en(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Disable SLP_SEL to change GPIO status automantically in lightsleep.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_sleep_sel_dis(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief GPIO set direction at sleep
|
||||
*
|
||||
* Configure GPIO direction,such as output_only,input_only,output_and_input
|
||||
*
|
||||
* @param gpio_num Configure GPIO pins number, it should be GPIO number. If you want to set direction of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @param mode GPIO direction
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG GPIO error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_sleep_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Configure GPIO pull-up/pull-down resistors at sleep
|
||||
*
|
||||
* Only pins that support both input & output have integrated pull-up and pull-down resistors. Input-only GPIOs 34-39 do not.
|
||||
*
|
||||
* @param gpio_num GPIO number. If you want to set pull up or down mode for e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @param pull GPIO pull up/down mode.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG : Parameter error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_sleep_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);
|
||||
|
||||
#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
/**
|
||||
* @brief Emulate ESP32S2 behaviour to backup FUN_PU, FUN_PD information
|
||||
*
|
||||
* @note Need to be called before sleep.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
*
|
||||
* */
|
||||
esp_err_t gpio_sleep_pupd_config_apply(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Emulate ESP32S2 behaviour to restore FUN_PU, FUN_PD information
|
||||
*
|
||||
* @note Need to be called after sleep.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
*
|
||||
* */
|
||||
esp_err_t gpio_sleep_pupd_config_unapply(gpio_num_t gpio_num);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -77,4 +77,17 @@ menu "Power Management"
|
||||
This feature is intended to be used when lower power consumption is needed
|
||||
while there is enough place in IRAM to place source code.
|
||||
|
||||
config PM_SLP_DISABLE_GPIO
|
||||
bool "Disable all GPIO when chip at sleep"
|
||||
depends on FREERTOS_USE_TICKLESS_IDLE
|
||||
help
|
||||
This feature is intended to disable all GPIO pins at automantic sleep to get a lower power mode.
|
||||
If enabled, chips will disable all GPIO pins at automantic sleep to reduce about 200~300 uA current.
|
||||
If you want to specifically use some pins normally as chip wakes when chip sleeps,
|
||||
you can call 'gpio_sleep_sel_dis' to disable this feature on those pins.
|
||||
You can also keep this feature on and call 'gpio_sleep_set_direction' and 'gpio_sleep_set_pull_mode'
|
||||
to have a different GPIO configuration at sleep.
|
||||
Waring: If you want to enable this option on ESP32, you should enable `GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL`
|
||||
at first, otherwise you will not be able to switch pullup/pulldown mode.
|
||||
|
||||
endmenu # "Power Management"
|
||||
|
@ -51,3 +51,22 @@ entries:
|
||||
esp_time_impl:esp_rtc_get_time_us (noflash)
|
||||
esp_time_impl:esp_clk_slowclk_cal_set (noflash)
|
||||
esp_time_impl:esp_set_time_from_rtc (noflash)
|
||||
|
||||
[mapping:driver_pm]
|
||||
archive: libdriver.a
|
||||
entries:
|
||||
if GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL = y:
|
||||
gpio:gpio_sleep_pupd_config_unapply (noflash)
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
gpio:gpio_sleep_pupd_config_apply (noflash)
|
||||
|
||||
[mapping:hal_pm]
|
||||
archive: libhal.a
|
||||
entries:
|
||||
if GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL = y:
|
||||
if PM_SLP_IRAM_OPT = y:
|
||||
gpio_hal_workaround (noflash)
|
||||
else:
|
||||
gpio_hal_workaround:gpio_hal_sleep_pupd_config_unapply (noflash)
|
||||
gpio_hal_workaround:gpio_hal_sleep_mode_setup_wrapper (noflash)
|
||||
gpio_hal_workaround:gpio_hal_fun_pupd_restore (noflash)
|
||||
|
@ -46,9 +46,11 @@
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/clk.h"
|
||||
#include "esp32/pm.h"
|
||||
#include "driver/gpio.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/clk.h"
|
||||
#include "esp32s2/pm.h"
|
||||
#include "driver/gpio.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/clk.h"
|
||||
#include "esp32s3/pm.h"
|
||||
@ -283,6 +285,10 @@ esp_err_t esp_pm_configure(const void* vconfig)
|
||||
s_config_changed = true;
|
||||
portEXIT_CRITICAL(&s_switch_lock);
|
||||
|
||||
#if CONFIG_PM_SLP_DISABLE_GPIO && SOC_GPIO_SUPPORT_SLP_SWITCH
|
||||
esp_sleep_gpio_status_switch_configure(config->light_sleep_enable);
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -697,6 +703,9 @@ void esp_pm_impl_init(void)
|
||||
esp_pm_trace_init();
|
||||
#endif
|
||||
|
||||
#if CONFIG_PM_SLP_DISABLE_GPIO && SOC_GPIO_SUPPORT_SLP_SWITCH
|
||||
esp_sleep_gpio_status_init();
|
||||
#endif
|
||||
ESP_ERROR_CHECK(esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "rtos0",
|
||||
&s_rtos_lock_handle[0]));
|
||||
ESP_ERROR_CHECK(esp_pm_lock_acquire(s_rtos_lock_handle[0]));
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "hal/touch_sensor_types.h"
|
||||
#include "hal/gpio_types.h"
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -382,6 +384,19 @@ void esp_default_wake_deep_sleep(void);
|
||||
*/
|
||||
void esp_deep_sleep_disable_rom_logging(void);
|
||||
|
||||
#if SOC_GPIO_SUPPORT_SLP_SWITCH
|
||||
/**
|
||||
* @brief Disable all GPIO pins at slept status.
|
||||
*
|
||||
*/
|
||||
void esp_sleep_gpio_status_init(void);
|
||||
|
||||
/**
|
||||
* @brief Configure GPIO pins status switching between slept status and waked status.
|
||||
* @param enable decide whether to switch status or not
|
||||
*/
|
||||
void esp_sleep_gpio_status_switch_configure(bool enable);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -53,11 +53,13 @@
|
||||
#include "esp32/rom/cache.h"
|
||||
#include "esp32/clk.h"
|
||||
#include "esp32/rom/rtc.h"
|
||||
#include "driver/gpio.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/clk.h"
|
||||
#include "esp32s2/rom/cache.h"
|
||||
#include "esp32s2/rom/rtc.h"
|
||||
#include "soc/extmem_reg.h"
|
||||
#include "driver/gpio.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/clk.h"
|
||||
#include "esp32s3/rom/cache.h"
|
||||
@ -273,6 +275,58 @@ static void IRAM_ATTR resume_uarts(void)
|
||||
|
||||
inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers);
|
||||
|
||||
#if SOC_GPIO_SUPPORT_SLP_SWITCH
|
||||
#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
static inline void gpio_sleep_mode_config_apply(void)
|
||||
{
|
||||
for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) {
|
||||
if (GPIO_IS_VALID_GPIO(gpio_num)) {
|
||||
gpio_sleep_pupd_config_apply(gpio_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void gpio_sleep_mode_config_unapply(void)
|
||||
{
|
||||
for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) {
|
||||
if (GPIO_IS_VALID_GPIO(gpio_num)) {
|
||||
gpio_sleep_pupd_config_unapply(gpio_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void esp_sleep_gpio_status_init(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Init to disable all pins at light sleep");
|
||||
for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) {
|
||||
if (GPIO_IS_VALID_GPIO(gpio_num)) {
|
||||
gpio_sleep_set_direction(gpio_num, GPIO_MODE_DISABLE);
|
||||
gpio_sleep_set_pull_mode(gpio_num, GPIO_FLOATING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void esp_sleep_gpio_status_switch_configure(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
ESP_LOGI(TAG, "Light sleep enabled, start GPIO status switching");
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Light sleep disabled, stop GPIO status switching");
|
||||
}
|
||||
for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) {
|
||||
if (GPIO_IS_VALID_GPIO(gpio_num)) {
|
||||
if (enable) {
|
||||
gpio_sleep_sel_en(gpio_num);
|
||||
} else {
|
||||
gpio_sleep_sel_dis(gpio_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
|
||||
{
|
||||
// Stop UART output so that output is not lost due to APB frequency change.
|
||||
@ -313,6 +367,9 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
|
||||
if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) {
|
||||
rtc_hal_ulp_wakeup_enable();
|
||||
}
|
||||
#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
gpio_sleep_mode_config_apply();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
@ -391,6 +448,9 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
|
||||
s_config.ccount_ticks_record = cpu_ll_get_cycle_count();
|
||||
}
|
||||
|
||||
#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
gpio_sleep_mode_config_unapply();
|
||||
#endif
|
||||
// re-enable UART output
|
||||
resume_uarts();
|
||||
|
||||
|
@ -43,7 +43,8 @@ if(NOT BOOTLOADER_BUILD)
|
||||
"esp32/adc_hal.c"
|
||||
"esp32/brownout_hal.c"
|
||||
"esp32/interrupt_descriptor_table.c"
|
||||
"esp32/touch_sensor_hal.c")
|
||||
"esp32/touch_sensor_hal.c"
|
||||
"esp32/gpio_hal_workaround.c")
|
||||
if(NOT BOOTLOADER_BUILD AND CONFIG_ETH_USE_ESP32_EMAC)
|
||||
list(APPEND srcs "esp32/emac_hal.c")
|
||||
endif()
|
||||
|
119
components/hal/esp32/gpio_hal_workaround.c
Normal file
119
components/hal/esp32/gpio_hal_workaround.c
Normal file
@ -0,0 +1,119 @@
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// The HAL layer for GPIO (common part)
|
||||
//
|
||||
#include "esp_attr.h"
|
||||
#include "soc/soc.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
typedef struct gpio_slp_mode_cfg {
|
||||
volatile uint16_t fun_pu[((SOC_GPIO_PIN_COUNT-1) >> 4) + 1];
|
||||
volatile uint16_t fun_pd[((SOC_GPIO_PIN_COUNT-1) >> 4) + 1];
|
||||
} gpio_slp_mode_cfg_t;
|
||||
|
||||
static void gpio_hal_sleep_mode_setup_wrapper(
|
||||
gpio_hal_context_t *hal,
|
||||
gpio_num_t gpio_num,
|
||||
void (*opt)(gpio_hal_context_t *, gpio_num_t, void *)
|
||||
)
|
||||
{
|
||||
static DRAM_ATTR gpio_slp_mode_cfg_t gpio_cfg;
|
||||
if (opt) {
|
||||
(*opt)(hal, gpio_num, (void *)&gpio_cfg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO pu/pd information backup function
|
||||
* @param hal gpio hal
|
||||
* @param gpio_num gpio num
|
||||
* @param args pointer for bitmap to backup GPIO pu/pd information
|
||||
*/
|
||||
static void gpio_hal_fun_pupd_backup(gpio_hal_context_t *hal, gpio_num_t gpio_num, void *args)
|
||||
{
|
||||
/* On ESP32, setting SLP_PU, SLP_PD couldn`t change GPIO status
|
||||
* from FUN_PU, FUN_PD to SLP_PU, SLP_PD at sleep.
|
||||
* On the ESP32S2, it does.
|
||||
* The following code emulates ESP32S2`s behavior:
|
||||
*/
|
||||
gpio_slp_mode_cfg_t *pcfg = (gpio_slp_mode_cfg_t *)args;
|
||||
|
||||
if (gpio_ll_sleep_sel_is_enabled(hal->dev, gpio_num)) {
|
||||
/* Record fun_pu and fun_pd state in bitmap */
|
||||
if (gpio_ll_pullup_is_enabled(hal->dev, gpio_num)) {
|
||||
pcfg->fun_pu[gpio_num >> 4] |= BIT(gpio_num & 0xf);
|
||||
} else {
|
||||
pcfg->fun_pu[gpio_num >> 4] &= ~BIT(gpio_num & 0xf);
|
||||
}
|
||||
if (gpio_ll_pulldown_is_enabled(hal->dev, gpio_num)) {
|
||||
pcfg->fun_pd[gpio_num >> 4] |= BIT(gpio_num & 0xf);
|
||||
} else {
|
||||
pcfg->fun_pd[gpio_num >> 4] &= ~BIT(gpio_num & 0xf);
|
||||
}
|
||||
|
||||
if (gpio_ll_sleep_pullup_is_enabled(hal->dev, gpio_num)) {
|
||||
gpio_ll_pullup_en(hal->dev, gpio_num);
|
||||
} else {
|
||||
gpio_ll_pullup_dis(hal->dev, gpio_num);
|
||||
}
|
||||
if (gpio_ll_sleep_pulldown_is_enabled(hal->dev, gpio_num)) {
|
||||
gpio_ll_pulldown_en(hal->dev, gpio_num);
|
||||
} else {
|
||||
gpio_ll_pulldown_dis(hal->dev, gpio_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO pu/pd information backup function
|
||||
* @param hal gpio hal
|
||||
* @param gpio_num gpio num
|
||||
* @param args pointer for bitmap to restore GPIO pu/pd information
|
||||
*/
|
||||
static void gpio_hal_fun_pupd_restore(gpio_hal_context_t *hal, gpio_num_t gpio_num, void *args)
|
||||
{
|
||||
/* On ESP32, setting SLP_PU, SLP_PD couldn`t change GPIO status
|
||||
* from SLP_PU, SLP_PD to FUN_PU, FUN_PD when it wakes up.
|
||||
* On the ESP32S2, it does.
|
||||
* The following code emulates ESP32S2`s behavior:
|
||||
*/
|
||||
gpio_slp_mode_cfg_t *pcfg = (gpio_slp_mode_cfg_t *)args;
|
||||
|
||||
if (gpio_ll_sleep_sel_is_enabled(hal->dev, gpio_num)) {
|
||||
if (pcfg->fun_pu[gpio_num >> 4] & BIT(gpio_num & 0xf)) {
|
||||
gpio_ll_pullup_en(hal->dev, gpio_num);
|
||||
} else {
|
||||
gpio_ll_pullup_dis(hal->dev, gpio_num);
|
||||
}
|
||||
if (pcfg->fun_pd[gpio_num >> 4] & BIT(gpio_num & 0xf)) {
|
||||
gpio_ll_pulldown_en(hal->dev, gpio_num);
|
||||
} else {
|
||||
gpio_ll_pulldown_dis(hal->dev, gpio_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gpio_hal_sleep_pupd_config_apply(gpio_hal_context_t *hal, gpio_num_t gpio_num)
|
||||
{
|
||||
gpio_hal_sleep_mode_setup_wrapper(hal, gpio_num, gpio_hal_fun_pupd_backup);
|
||||
}
|
||||
|
||||
void gpio_hal_sleep_pupd_config_unapply(gpio_hal_context_t *hal, gpio_num_t gpio_num)
|
||||
{
|
||||
gpio_hal_sleep_mode_setup_wrapper(hal, gpio_num, gpio_hal_fun_pupd_restore);
|
||||
}
|
||||
#endif
|
@ -22,6 +22,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
@ -63,6 +64,18 @@ static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return pull-up status on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
* @return if GPIO gpio_num`s FUN_PU is true
|
||||
*/
|
||||
static inline bool gpio_ll_pullup_is_enabled(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable pull-down on GPIO.
|
||||
*
|
||||
@ -85,6 +98,120 @@ static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return pull-down status on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
* @return if GPIO gpio_num`s FUN_PD is true
|
||||
*/
|
||||
static inline bool gpio_ll_pulldown_is_enabled(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin used for wakeup from sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_SEL_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin used for wakeup from sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_SEL_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return slp-sel status on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
* @return if GPIO gpio_num`s SLP_SEL is true
|
||||
*/
|
||||
static inline bool gpio_ll_sleep_sel_is_enabled(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], SLP_SEL) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pull-up in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLUP_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pull-up in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLUP_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return slp-pull-up status on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
* @return if GPIO gpio_num`s SLP_PU is true
|
||||
*/
|
||||
static inline bool gpio_ll_sleep_pullup_is_enabled(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], SLP_PU) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pull-down in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLDOWN_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pull-down in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLDOWN_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return slp-pull-down status on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
* @return if GPIO gpio_num`s SLP_PD is true
|
||||
*/
|
||||
static inline bool gpio_ll_sleep_pulldown_is_enabled(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], SLP_PD) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO set interrupt trigger type
|
||||
*
|
||||
@ -226,6 +353,50 @@ static inline void gpio_ll_output_enable(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO input in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO input in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO output in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_OUTPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO output in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_OUTPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable open-drain mode on GPIO.
|
||||
*
|
||||
|
@ -420,6 +420,117 @@ static inline void gpio_ll_force_unhold_all(gpio_dev_t *hw)
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin used for wakeup from sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_SEL_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin used for wakeup from sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_SEL_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pull-up in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLUP_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pull-up in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLUP_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pull-down in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLDOWN_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pull-down in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLDOWN_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO input in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO input in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO output in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_OUTPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO output in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, gpio_num_t gpio_num)
|
||||
{
|
||||
PIN_SLP_OUTPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -338,6 +338,105 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, gpio_num_t gpio_num);
|
||||
#define gpio_hal_force_unhold_all(hal) gpio_ll_force_unhold_all((hal)->dev)
|
||||
#endif
|
||||
|
||||
#if SOC_GPIO_SUPPORT_SLP_SWITCH
|
||||
/**
|
||||
* @brief Enable pull-up on GPIO when system sleep.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
#define gpio_hal_sleep_pullup_en(hal, gpio_num) gpio_ll_sleep_pullup_en((hal)->dev, gpio_num)
|
||||
|
||||
/**
|
||||
* @brief Disable pull-up on GPIO when system sleep.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
#define gpio_hal_sleep_pullup_dis(hal, gpio_num) gpio_ll_sleep_pullup_dis((hal)->dev, gpio_num)
|
||||
|
||||
/**
|
||||
* @brief Enable pull-down on GPIO when system sleep.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
#define gpio_hal_sleep_pulldown_en(hal, gpio_num) gpio_ll_sleep_pulldown_en((hal)->dev, gpio_num)
|
||||
|
||||
/**
|
||||
* @brief Disable pull-down on GPIO when system sleep.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
#define gpio_hal_sleep_pulldown_dis(hal, gpio_num) gpio_ll_sleep_pulldown_dis((hal)->dev, gpio_num)
|
||||
|
||||
/**
|
||||
* @brief Enable sleep select on GPIO.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
#define gpio_hal_sleep_sel_en(hal, gpio_num) gpio_ll_sleep_sel_en((hal)->dev, gpio_num)
|
||||
|
||||
/**
|
||||
* @brief Disable sleep select on GPIO.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
#define gpio_hal_sleep_sel_dis(hal, gpio_num) gpio_ll_sleep_sel_dis((hal)->dev, gpio_num)
|
||||
|
||||
/**
|
||||
* @brief Disable input mode on GPIO when system sleep.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
#define gpio_hal_sleep_input_disable(hal, gpio_num) gpio_ll_sleep_input_disable((hal)->dev, gpio_num)
|
||||
|
||||
/**
|
||||
* @brief Enable input mode on GPIO when system sleep.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
#define gpio_hal_sleep_input_enable(hal, gpio_num) gpio_ll_sleep_input_enable((hal)->dev, gpio_num)
|
||||
|
||||
/**
|
||||
* @brief Disable output mode on GPIO when system sleep.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
#define gpio_hal_sleep_output_disable(hal, gpio_num) gpio_ll_sleep_output_disable((hal)->dev, gpio_num)
|
||||
|
||||
/**
|
||||
* @brief Enable output mode on GPIO when system sleep.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
#define gpio_hal_sleep_output_enable(hal, gpio_num) gpio_ll_sleep_output_enable((hal)->dev, gpio_num)
|
||||
|
||||
#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
/**
|
||||
* @brief Apply slp_pu/slp_pd configuration to fun_pu/fun_pd when system sleep.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param gpio_num GPIO number.
|
||||
*/
|
||||
void gpio_hal_sleep_pupd_config_apply(gpio_hal_context_t *hal, gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Restore fun_pu/fun_pd configuration when system wakeup.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param gpio_num GPIO number.
|
||||
*/
|
||||
void gpio_hal_sleep_pupd_config_unapply(gpio_hal_context_t *hal, gpio_num_t gpio_num);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -73,6 +73,17 @@
|
||||
#define MCU_SEL_V 0x7
|
||||
#define MCU_SEL_S 12
|
||||
|
||||
#define PIN_SLP_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
#define PIN_SLP_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
#define PIN_SLP_OUTPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_OE)
|
||||
#define PIN_SLP_OUTPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_OE)
|
||||
#define PIN_SLP_PULLUP_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_PU)
|
||||
#define PIN_SLP_PULLUP_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_PU)
|
||||
#define PIN_SLP_PULLDOWN_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_PD)
|
||||
#define PIN_SLP_PULLDOWN_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_PD)
|
||||
#define PIN_SLP_SEL_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_SEL)
|
||||
#define PIN_SLP_SEL_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_SEL)
|
||||
|
||||
#define PIN_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,FUN_IE)
|
||||
#define PIN_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,FUN_IE)
|
||||
#define PIN_SET_DRV(PIN_NAME, drv) REG_SET_FIELD(PIN_NAME, FUN_DRV, (drv));
|
||||
|
@ -116,6 +116,9 @@
|
||||
// GPIO >= 34 are input only
|
||||
#define SOC_GPIO_VALID_OUTPUT_GPIO_MASK (SOC_GPIO_VALID_GPIO_MASK & ~(0ULL | BIT34 | BIT35 | BIT36 | BIT37 | BIT38 | BIT39))
|
||||
|
||||
// Support to configure slept status
|
||||
#define SOC_GPIO_SUPPORT_SLP_SWITCH (1)
|
||||
|
||||
/*-------------------------- I2C CAPS ----------------------------------------*/
|
||||
// ESP32 have 2 I2C.
|
||||
#define SOC_I2C_NUM (2)
|
||||
|
@ -73,6 +73,17 @@
|
||||
#define MCU_SEL_V 0x7
|
||||
#define MCU_SEL_S 12
|
||||
|
||||
#define PIN_SLP_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
#define PIN_SLP_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_IE)
|
||||
#define PIN_SLP_OUTPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_OE)
|
||||
#define PIN_SLP_OUTPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_OE)
|
||||
#define PIN_SLP_PULLUP_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_PU)
|
||||
#define PIN_SLP_PULLUP_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_PU)
|
||||
#define PIN_SLP_PULLDOWN_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_PD)
|
||||
#define PIN_SLP_PULLDOWN_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_PD)
|
||||
#define PIN_SLP_SEL_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_SEL)
|
||||
#define PIN_SLP_SEL_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_SEL)
|
||||
|
||||
#define PIN_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,FUN_IE)
|
||||
#define PIN_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,FUN_IE)
|
||||
#define PIN_SET_DRV(PIN_NAME, drv) REG_SET_FIELD(PIN_NAME, FUN_DRV, (drv));
|
||||
|
@ -99,6 +99,9 @@
|
||||
// GPIO 46, 47 are input only
|
||||
#define SOC_GPIO_VALID_OUTPUT_GPIO_MASK (SOC_GPIO_VALID_GPIO_MASK & ~(0ULL | BIT46 | BIT47))
|
||||
|
||||
// Support to configure slept status
|
||||
#define SOC_GPIO_SUPPORT_SLP_SWITCH (1)
|
||||
|
||||
/*-------------------------- Dedicated GPIO CAPS ---------------------------------------*/
|
||||
#define SOC_DEDIC_GPIO_OUT_CHANNELS_NUM (8) /*!< 8 outward channels on each CPU core */
|
||||
#define SOC_DEDIC_GPIO_IN_CHANNELS_NUM (8) /*!< 8 inward channels on each CPU core */
|
||||
|
@ -9,3 +9,6 @@ CONFIG_PM_USE_RTC_TIMER_REF=y
|
||||
# Put related source code in IRAM
|
||||
CONFIG_PM_SLP_IRAM_OPT=y
|
||||
CONFIG_PM_RTOS_IDLE_OPT=y
|
||||
# Disable all GPIO at light sleep
|
||||
CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL=y
|
||||
CONFIG_PM_SLP_DISABLE_GPIO=y
|
||||
|
Loading…
Reference in New Issue
Block a user