mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-03 10:30:58 +02:00
Merge branch 'bugfix/gpio_esp32_workaround_v5.2' into 'release/v5.2'
fix(gpio): fix ESP32 GPIO sleep mode handling (v5.2) See merge request espressif/esp-idf!41259
This commit is contained in:
@@ -441,11 +441,12 @@ esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)
|
|||||||
esp_err_t gpio_reset_pin(gpio_num_t gpio_num)
|
esp_err_t gpio_reset_pin(gpio_num_t gpio_num)
|
||||||
{
|
{
|
||||||
assert(GPIO_IS_VALID_GPIO(gpio_num));
|
assert(GPIO_IS_VALID_GPIO(gpio_num));
|
||||||
|
bool pu_en = GPIO_IS_VALID_OUTPUT_GPIO(gpio_num);
|
||||||
gpio_config_t cfg = {
|
gpio_config_t cfg = {
|
||||||
.pin_bit_mask = BIT64(gpio_num),
|
.pin_bit_mask = BIT64(gpio_num),
|
||||||
.mode = GPIO_MODE_DISABLE,
|
.mode = GPIO_MODE_DISABLE,
|
||||||
//for powersave reasons, the GPIO should not be floating, select pullup
|
//for powersave reasons, the GPIO should not be floating, select pullup
|
||||||
.pull_up_en = true,
|
.pull_up_en = pu_en,
|
||||||
.pull_down_en = false,
|
.pull_down_en = false,
|
||||||
.intr_type = GPIO_INTR_DISABLE,
|
.intr_type = GPIO_INTR_DISABLE,
|
||||||
};
|
};
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -9,12 +9,13 @@
|
|||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "soc/soc.h"
|
#include "soc/soc.h"
|
||||||
#include "hal/gpio_hal.h"
|
#include "hal/gpio_hal.h"
|
||||||
|
#include "hal/rtc_io_ll.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
|
|
||||||
#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||||
typedef struct gpio_slp_mode_cfg {
|
typedef struct gpio_slp_mode_cfg {
|
||||||
volatile uint16_t fun_pu[((SOC_GPIO_PIN_COUNT-1) >> 4) + 1];
|
volatile uint32_t fun_pu;
|
||||||
volatile uint16_t fun_pd[((SOC_GPIO_PIN_COUNT-1) >> 4) + 1];
|
volatile uint32_t fun_pd;
|
||||||
} gpio_slp_mode_cfg_t;
|
} gpio_slp_mode_cfg_t;
|
||||||
|
|
||||||
static void gpio_hal_sleep_mode_setup_wrapper(
|
static void gpio_hal_sleep_mode_setup_wrapper(
|
||||||
@@ -37,35 +38,35 @@ static void gpio_hal_sleep_mode_setup_wrapper(
|
|||||||
*/
|
*/
|
||||||
static void gpio_hal_fun_pupd_backup(gpio_hal_context_t *hal, uint32_t gpio_num, void *args)
|
static void gpio_hal_fun_pupd_backup(gpio_hal_context_t *hal, uint32_t gpio_num, void *args)
|
||||||
{
|
{
|
||||||
/* On ESP32, setting SLP_PU, SLP_PD couldn`t change GPIO status
|
/* On ESP32, setting SLP_PU, SLP_PD couldn't change GPIO status
|
||||||
* from FUN_PU, FUN_PD to SLP_PU, SLP_PD at sleep.
|
* from FUN_PU, FUN_PD to SLP_PU, SLP_PD at sleep.
|
||||||
* On the ESP32S2, it does.
|
* On the ESP32S2, it does.
|
||||||
* The following code emulates ESP32S2`s behavior:
|
* The following code emulates ESP32S2`s behavior:
|
||||||
*/
|
*/
|
||||||
gpio_slp_mode_cfg_t *pcfg = (gpio_slp_mode_cfg_t *)args;
|
gpio_slp_mode_cfg_t *pcfg = (gpio_slp_mode_cfg_t *)args;
|
||||||
|
|
||||||
if (gpio_ll_sleep_sel_is_enabled(hal->dev, gpio_num)) {
|
int rtcio_num = rtc_io_num_map[gpio_num];
|
||||||
/* Record fun_pu and fun_pd state in bitmap */
|
if (rtcio_num >= 0 && gpio_ll_sleep_sel_is_enabled(hal->dev, gpio_num)) {
|
||||||
if (gpio_ll_pullup_is_enabled(hal->dev, gpio_num)) {
|
if (rtcio_ll_is_pullup_enabled(rtcio_num)) {
|
||||||
pcfg->fun_pu[gpio_num >> 4] |= BIT(gpio_num & 0xf);
|
pcfg->fun_pu |= BIT(rtcio_num);
|
||||||
} else {
|
} else {
|
||||||
pcfg->fun_pu[gpio_num >> 4] &= ~BIT(gpio_num & 0xf);
|
pcfg->fun_pu &= ~BIT(rtcio_num);
|
||||||
}
|
}
|
||||||
if (gpio_ll_pulldown_is_enabled(hal->dev, gpio_num)) {
|
if (rtcio_ll_is_pulldown_enabled(rtcio_num)) {
|
||||||
pcfg->fun_pd[gpio_num >> 4] |= BIT(gpio_num & 0xf);
|
pcfg->fun_pd |= BIT(rtcio_num);
|
||||||
} else {
|
} else {
|
||||||
pcfg->fun_pd[gpio_num >> 4] &= ~BIT(gpio_num & 0xf);
|
pcfg->fun_pd &= ~BIT(rtcio_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gpio_ll_sleep_pullup_is_enabled(hal->dev, gpio_num)) {
|
if (gpio_ll_sleep_pullup_is_enabled(hal->dev, gpio_num)) {
|
||||||
gpio_ll_pullup_en(hal->dev, gpio_num);
|
rtcio_ll_pullup_enable(rtcio_num);
|
||||||
} else {
|
} else {
|
||||||
gpio_ll_pullup_dis(hal->dev, gpio_num);
|
rtcio_ll_pullup_disable(rtcio_num);
|
||||||
}
|
}
|
||||||
if (gpio_ll_sleep_pulldown_is_enabled(hal->dev, gpio_num)) {
|
if (gpio_ll_sleep_pulldown_is_enabled(hal->dev, gpio_num)) {
|
||||||
gpio_ll_pulldown_en(hal->dev, gpio_num);
|
rtcio_ll_pulldown_enable(rtcio_num);
|
||||||
} else {
|
} else {
|
||||||
gpio_ll_pulldown_dis(hal->dev, gpio_num);
|
rtcio_ll_pulldown_disable(rtcio_num);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,23 +79,24 @@ static void gpio_hal_fun_pupd_backup(gpio_hal_context_t *hal, uint32_t gpio_num,
|
|||||||
*/
|
*/
|
||||||
static void gpio_hal_fun_pupd_restore(gpio_hal_context_t *hal, uint32_t gpio_num, void *args)
|
static void gpio_hal_fun_pupd_restore(gpio_hal_context_t *hal, uint32_t gpio_num, void *args)
|
||||||
{
|
{
|
||||||
/* On ESP32, setting SLP_PU, SLP_PD couldn`t change GPIO status
|
/* 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.
|
* from SLP_PU, SLP_PD to FUN_PU, FUN_PD when it wakes up.
|
||||||
* On the ESP32S2, it does.
|
* On the ESP32S2, it does.
|
||||||
* The following code emulates ESP32S2`s behavior:
|
* The following code emulates ESP32S2`s behavior:
|
||||||
*/
|
*/
|
||||||
gpio_slp_mode_cfg_t *pcfg = (gpio_slp_mode_cfg_t *)args;
|
gpio_slp_mode_cfg_t *pcfg = (gpio_slp_mode_cfg_t *)args;
|
||||||
|
|
||||||
if (gpio_ll_sleep_sel_is_enabled(hal->dev, gpio_num)) {
|
int rtcio_num = rtc_io_num_map[gpio_num];
|
||||||
if (pcfg->fun_pu[gpio_num >> 4] & BIT(gpio_num & 0xf)) {
|
if (rtcio_num >= 0 && gpio_ll_sleep_sel_is_enabled(hal->dev, gpio_num)) {
|
||||||
gpio_ll_pullup_en(hal->dev, gpio_num);
|
if (pcfg->fun_pu & BIT(rtcio_num)) {
|
||||||
|
rtcio_ll_pullup_enable(rtcio_num);
|
||||||
} else {
|
} else {
|
||||||
gpio_ll_pullup_dis(hal->dev, gpio_num);
|
rtcio_ll_pullup_disable(rtcio_num);
|
||||||
}
|
}
|
||||||
if (pcfg->fun_pd[gpio_num >> 4] & BIT(gpio_num & 0xf)) {
|
if (pcfg->fun_pd & BIT(rtcio_num)) {
|
||||||
gpio_ll_pulldown_en(hal->dev, gpio_num);
|
rtcio_ll_pulldown_enable(rtcio_num);
|
||||||
} else {
|
} else {
|
||||||
gpio_ll_pulldown_dis(hal->dev, gpio_num);
|
rtcio_ll_pulldown_disable(rtcio_num);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -173,7 +173,7 @@ static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
|||||||
*/
|
*/
|
||||||
static inline bool gpio_ll_sleep_sel_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
|
static inline bool gpio_ll_sleep_sel_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
|
||||||
{
|
{
|
||||||
return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], SLP_SEL) ? true : false;
|
return REG_GET_BIT(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio_num], SLP_SEL) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -207,7 +207,7 @@ static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
|
|||||||
*/
|
*/
|
||||||
static inline bool gpio_ll_sleep_pullup_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
|
static inline bool gpio_ll_sleep_pullup_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
|
||||||
{
|
{
|
||||||
return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], SLP_PU) ? true : false;
|
return REG_GET_BIT(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio_num], SLP_PU) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -241,7 +241,7 @@ static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
|||||||
*/
|
*/
|
||||||
static inline bool gpio_ll_sleep_pulldown_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
|
static inline bool gpio_ll_sleep_pulldown_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
|
||||||
{
|
{
|
||||||
return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], SLP_PD) ? true : false;
|
return REG_GET_BIT(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio_num], SLP_PD) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -172,10 +172,11 @@ static inline void rtcio_ll_output_mode_set(int rtcio_num, rtcio_ll_out_mode_t m
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RTC GPIO pullup enable.
|
* @brief RTC GPIO pullup enable.
|
||||||
*
|
*
|
||||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||||
*/
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
static inline void rtcio_ll_pullup_enable(int rtcio_num)
|
static inline void rtcio_ll_pullup_enable(int rtcio_num)
|
||||||
{
|
{
|
||||||
if (rtc_io_desc[rtcio_num].pullup) {
|
if (rtc_io_desc[rtcio_num].pullup) {
|
||||||
@@ -184,10 +185,11 @@ static inline void rtcio_ll_pullup_enable(int rtcio_num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RTC GPIO pullup disable.
|
* @brief RTC GPIO pullup disable.
|
||||||
*
|
*
|
||||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||||
*/
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
static inline void rtcio_ll_pullup_disable(int rtcio_num)
|
static inline void rtcio_ll_pullup_disable(int rtcio_num)
|
||||||
{
|
{
|
||||||
if (rtc_io_desc[rtcio_num].pullup) {
|
if (rtc_io_desc[rtcio_num].pullup) {
|
||||||
@@ -201,6 +203,7 @@ static inline void rtcio_ll_pullup_disable(int rtcio_num)
|
|||||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||||
* @return Whether the pullup of the pad is enabled or not.
|
* @return Whether the pullup of the pad is enabled or not.
|
||||||
*/
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num)
|
static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num)
|
||||||
{
|
{
|
||||||
if (rtc_io_desc[rtcio_num].pullup) {
|
if (rtc_io_desc[rtcio_num].pullup) {
|
||||||
@@ -211,10 +214,11 @@ static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RTC GPIO pulldown enable.
|
* @brief RTC GPIO pulldown enable.
|
||||||
*
|
*
|
||||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||||
*/
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
static inline void rtcio_ll_pulldown_enable(int rtcio_num)
|
static inline void rtcio_ll_pulldown_enable(int rtcio_num)
|
||||||
{
|
{
|
||||||
if (rtc_io_desc[rtcio_num].pulldown) {
|
if (rtc_io_desc[rtcio_num].pulldown) {
|
||||||
@@ -223,10 +227,11 @@ static inline void rtcio_ll_pulldown_enable(int rtcio_num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RTC GPIO pulldown disable.
|
* @brief RTC GPIO pulldown disable.
|
||||||
*
|
*
|
||||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||||
*/
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
static inline void rtcio_ll_pulldown_disable(int rtcio_num)
|
static inline void rtcio_ll_pulldown_disable(int rtcio_num)
|
||||||
{
|
{
|
||||||
if (rtc_io_desc[rtcio_num].pulldown) {
|
if (rtc_io_desc[rtcio_num].pulldown) {
|
||||||
@@ -240,6 +245,7 @@ static inline void rtcio_ll_pulldown_disable(int rtcio_num)
|
|||||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||||
* @return Whether the pulldown of the pad is enabled or not.
|
* @return Whether the pulldown of the pad is enabled or not.
|
||||||
*/
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num)
|
static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num)
|
||||||
{
|
{
|
||||||
if (rtc_io_desc[rtcio_num].pulldown) {
|
if (rtc_io_desc[rtcio_num].pulldown) {
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
#include "soc/rtc_periph.h"
|
#include "soc/rtc_periph.h"
|
||||||
#include "soc/rtc_io_reg.h"
|
#include "soc/rtc_io_reg.h"
|
||||||
|
|
||||||
const int rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
|
const int8_t rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
|
||||||
RTCIO_GPIO0_CHANNEL, //GPIO0
|
RTCIO_GPIO0_CHANNEL, //GPIO0
|
||||||
-1,//GPIO1
|
-1,//GPIO1
|
||||||
RTCIO_GPIO2_CHANNEL, //GPIO2
|
RTCIO_GPIO2_CHANNEL, //GPIO2
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "soc/rtc_io_periph.h"
|
#include "soc/rtc_io_periph.h"
|
||||||
|
|
||||||
const int rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
|
const int8_t rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
|
||||||
RTCIO_GPIO0_CHANNEL, //GPIO0
|
RTCIO_GPIO0_CHANNEL, //GPIO0
|
||||||
RTCIO_GPIO1_CHANNEL, //GPIO1
|
RTCIO_GPIO1_CHANNEL, //GPIO1
|
||||||
RTCIO_GPIO2_CHANNEL, //GPIO2
|
RTCIO_GPIO2_CHANNEL, //GPIO2
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "soc/rtc_io_periph.h"
|
#include "soc/rtc_io_periph.h"
|
||||||
|
|
||||||
const int rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
|
const int8_t rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
|
||||||
-1,//GPIO0
|
-1,//GPIO0
|
||||||
-1,//GPIO1
|
-1,//GPIO1
|
||||||
-1,//GPIO2
|
-1,//GPIO2
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "soc/rtc_periph.h"
|
#include "soc/rtc_periph.h"
|
||||||
|
|
||||||
const int rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
|
const int8_t rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
|
||||||
RTCIO_GPIO0_CHANNEL, //GPIO0
|
RTCIO_GPIO0_CHANNEL, //GPIO0
|
||||||
RTCIO_GPIO1_CHANNEL, //GPIO1
|
RTCIO_GPIO1_CHANNEL, //GPIO1
|
||||||
RTCIO_GPIO2_CHANNEL, //GPIO2
|
RTCIO_GPIO2_CHANNEL, //GPIO2
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
#include "soc/rtc_periph.h"
|
#include "soc/rtc_periph.h"
|
||||||
#include "soc/rtc_io_reg.h"
|
#include "soc/rtc_io_reg.h"
|
||||||
|
|
||||||
const int rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
|
const int8_t rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
|
||||||
RTCIO_GPIO0_CHANNEL, //GPIO0
|
RTCIO_GPIO0_CHANNEL, //GPIO0
|
||||||
RTCIO_GPIO1_CHANNEL, //GPIO1
|
RTCIO_GPIO1_CHANNEL, //GPIO1
|
||||||
RTCIO_GPIO2_CHANNEL, //GPIO2
|
RTCIO_GPIO2_CHANNEL, //GPIO2
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
#include "soc/rtc_periph.h"
|
#include "soc/rtc_periph.h"
|
||||||
#include "soc/rtc_io_reg.h"
|
#include "soc/rtc_io_reg.h"
|
||||||
|
|
||||||
const int rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
|
const int8_t rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
|
||||||
RTCIO_GPIO0_CHANNEL, //GPIO0
|
RTCIO_GPIO0_CHANNEL, //GPIO0
|
||||||
RTCIO_GPIO1_CHANNEL, //GPIO1
|
RTCIO_GPIO1_CHANNEL, //GPIO1
|
||||||
RTCIO_GPIO2_CHANNEL, //GPIO2
|
RTCIO_GPIO2_CHANNEL, //GPIO2
|
||||||
|
@@ -66,7 +66,7 @@ extern const rtc_io_desc_t rtc_io_desc[SOC_RTCIO_PIN_COUNT];
|
|||||||
* This is an internal function of the driver, and is not usually useful
|
* This is an internal function of the driver, and is not usually useful
|
||||||
* for external use.
|
* for external use.
|
||||||
*/
|
*/
|
||||||
extern const int rtc_io_num_map[SOC_GPIO_PIN_COUNT];
|
extern const int8_t rtc_io_num_map[SOC_GPIO_PIN_COUNT];
|
||||||
#endif //SOC_RTCIO_PIN_COUNT > 0
|
#endif //SOC_RTCIO_PIN_COUNT > 0
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Reference in New Issue
Block a user