Merge branch 'bugfix/gpio_esp32_workaround_v5.4' into 'release/v5.4'

fix(gpio): fix ESP32 GPIO sleep mode handling (v5.4)

See merge request espressif/esp-idf!41216
This commit is contained in:
morris
2025-08-15 18:13:44 +08:00
31 changed files with 145 additions and 370 deletions

View File

@@ -436,11 +436,12 @@ esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)
esp_err_t gpio_reset_pin(gpio_num_t gpio_num)
{
assert(GPIO_IS_VALID_GPIO(gpio_num));
bool pu_en = GPIO_IS_VALID_OUTPUT_GPIO(gpio_num);
gpio_config_t cfg = {
.pin_bit_mask = BIT64(gpio_num),
.mode = GPIO_MODE_DISABLE,
//for powersave reasons, the GPIO should not be floating, select pullup
.pull_up_en = true,
.pull_up_en = pu_en,
.pull_down_en = false,
.intr_type = GPIO_INTR_DISABLE,
};

View File

@@ -12,7 +12,7 @@
#include "driver/gpio_etm.h"
#include "driver/gpio.h"
TEST_CASE("gpio_etm_self_trigger", "[etm]")
TEST_CASE("gpio_etm_self_trigger", "[gpio_etm]")
{
// GPIO any edge ---> EMT channel ---> GPIO toggle
const uint32_t input_gpio = 0;
@@ -91,7 +91,7 @@ TEST_CASE("gpio_etm_self_trigger", "[etm]")
TEST_ESP_OK(esp_etm_del_channel(etm_channel_a));
}
TEST_CASE("gpio_etm_self_trigger_multi_action", "[etm]")
TEST_CASE("gpio_etm_self_trigger_multi_action", "[gpio_etm]")
{
// GPIO 0 pos edge event ---> GPIO 1 set level task
// GPIO 2 pos edge event ---> GPIO 1 clear level task

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded_idf import IdfDut
@@ -37,3 +37,14 @@ def test_gpio_filter(dut: IdfDut) -> None:
@pytest.mark.parametrize('config', CONFIGS, indirect=True)
def test_dedic_gpio(dut: IdfDut) -> None:
dut.run_all_single_board_cases(group='dedic_gpio')
@pytest.mark.esp32c5
@pytest.mark.esp32c6
@pytest.mark.esp32c61
@pytest.mark.esp32h2
@pytest.mark.esp32p4
@pytest.mark.generic
@pytest.mark.parametrize('config', CONFIGS, indirect=True)
def test_gpio_etm(dut: IdfDut) -> None:
dut.run_all_single_board_cases(group='gpio_etm')

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -36,15 +36,6 @@ extern "C" {
#define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0)
typedef enum {
GPIO_PIN_INTR_DISABLE = 0,
GPIO_PIN_INTR_POSEDGE = 1,
GPIO_PIN_INTR_NEGEDGE = 2,
GPIO_PIN_INTR_ANYEDGE = 3,
GPIO_PIN_INTR_LOLEVEL = 4,
GPIO_PIN_INTR_HILEVEL = 5
} GPIO_INT_TYPE;
#define GPIO_OUTPUT_SET(gpio_no, bit_value) \
((gpio_no < 32) ? gpio_output_set(bit_value<<gpio_no, (bit_value ? 0 : 1)<<gpio_no, 1<<gpio_no,0) : \
gpio_output_set_high(bit_value<<(gpio_no - 32), (bit_value ? 0 : 1)<<(gpio_no - 32), 1<<(gpio_no -32),0))
@@ -103,28 +94,6 @@ uint32_t gpio_input_get(void);
*/
uint32_t gpio_input_get_high(void);
/**
* @brief Set GPIO to wakeup the ESP32.
* Please do not call this function in SDK.
*
* @param uint32_t i: gpio number.
*
* @param GPIO_INT_TYPE intr_state : only GPIO_PIN_INTR_LOLEVEL\GPIO_PIN_INTR_HILEVEL can be used
*
* @return None
*/
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
/**
* @brief disable GPIOs to wakeup the ESP32.
* Please do not call this function in SDK.
*
* @param None
*
* @return None
*/
void gpio_pin_wakeup_disable(void);
/**
* @brief set gpio input to a signal, one gpio can input to several signals.
*

View File

@@ -73,7 +73,7 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas
uint32_t gpio_input_get(void);
/**
* @brief Set GPIO to wakeup the ESP32.
* @brief Set GPIO to wakeup the chip.
* Please do not call this function in SDK.
*
* @param uint32_t i: gpio number.
@@ -85,7 +85,7 @@ uint32_t gpio_input_get(void);
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
/**
* @brief disable GPIOs to wakeup the ESP32.
* @brief disable GPIOs to wakeup the chip.
* Please do not call this function in SDK.
*
* @param None

View File

@@ -73,7 +73,7 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas
uint32_t gpio_input_get(void);
/**
* @brief Set GPIO to wakeup the ESP32.
* @brief Set GPIO to wakeup the chip.
* Please do not call this function in SDK.
*
* @param uint32_t i: gpio number.
@@ -85,7 +85,7 @@ uint32_t gpio_input_get(void);
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
/**
* @brief disable GPIOs to wakeup the ESP32.
* @brief disable GPIOs to wakeup the chip.
* Please do not call this function in SDK.
*
* @param None

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -33,62 +33,23 @@ extern "C" {
#define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0)
typedef enum {
GPIO_PIN_INTR_DISABLE = 0,
GPIO_PIN_INTR_POSEDGE = 1,
GPIO_PIN_INTR_NEGEDGE = 2,
GPIO_PIN_INTR_ANYEDGE = 3,
GPIO_PIN_INTR_LOLEVEL = 4,
GPIO_PIN_INTR_HILEVEL = 5
} GPIO_INT_TYPE;
/**
* @brief Change GPIO(0-30) pin output by setting, clearing, or disabling pins, GPIO0<->BIT(0).
* There is no particular ordering guaranteed; so if the order of writes is significant,
* calling code should divide a single call into multiple calls.
* @brief Set GPIO output level
*
* @param uint32_t set_mask : the gpios that need high level.
*
* @param uint32_t clear_mask : the gpios that need low level.
*
* @param uint32_t enable_mask : the gpios that need be changed.
*
* @param uint32_t disable_mask : the gpios that need disable output.
*
* @return None
* @param gpio_num GPIO number
* @param level Output level, 0:low; 1:high
*/
void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask);
void gpio_set_output_level(uint32_t gpio_num, uint32_t level);
/**
* @brief Sample the value of GPIO input pins(0-30) and returns a bitmask.
* @param None
* @brief Get GPIO input level
*
* @return uint32_t : bitmask for GPIO input pins, BIT(0) for GPIO0.
* @param gpio_num GPIO number
*
* @return 0:the GPIO_input level is low; 1:the GPIO input level is high
*/
uint32_t gpio_input_get(void);
/**
* @brief Set GPIO to wakeup the ESP32.
* Please do not call this function in SDK.
*
* @param uint32_t i: gpio number.
*
* @param GPIO_INT_TYPE intr_state : only GPIO_PIN_INTR_LOLEVEL\GPIO_PIN_INTR_HILEVEL can be used
*
* @return None
*/
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
/**
* @brief disable GPIOs to wakeup the ESP32.
* Please do not call this function in SDK.
*
* @param None
*
* @return None
*/
void gpio_pin_wakeup_disable(void);
uint32_t gpio_get_input_level(uint32_t gpio_num);
/**
* @brief set gpio input to a signal, one gpio can input to several signals.

View File

@@ -72,7 +72,7 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas
uint32_t gpio_input_get(void);
/**
* @brief Set GPIO to wakeup the ESP32.
* @brief Set GPIO to wakeup the chip.
* Please do not call this function in SDK.
*
* @param uint32_t i: gpio number.
@@ -84,7 +84,7 @@ uint32_t gpio_input_get(void);
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
/**
* @brief disable GPIOs to wakeup the ESP32.
* @brief disable GPIOs to wakeup the chip.
* Please do not call this function in SDK.
*
* @param None

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -33,62 +33,23 @@ extern "C" {
#define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0)
typedef enum {
GPIO_PIN_INTR_DISABLE = 0,
GPIO_PIN_INTR_POSEDGE = 1,
GPIO_PIN_INTR_NEGEDGE = 2,
GPIO_PIN_INTR_ANYEDGE = 3,
GPIO_PIN_INTR_LOLEVEL = 4,
GPIO_PIN_INTR_HILEVEL = 5
} GPIO_INT_TYPE;
/**
* @brief Change GPIO(0-30) pin output by setting, clearing, or disabling pins, GPIO0<->BIT(0).
* There is no particular ordering guaranteed; so if the order of writes is significant,
* calling code should divide a single call into multiple calls.
* @brief Set GPIO output level
*
* @param uint32_t set_mask : the gpios that need high level.
*
* @param uint32_t clear_mask : the gpios that need low level.
*
* @param uint32_t enable_mask : the gpios that need be changed.
*
* @param uint32_t disable_mask : the gpios that need disable output.
*
* @return None
* @param gpio_num GPIO number
* @param level Output level, 0:low; 1:high
*/
void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask);
void gpio_set_output_level(uint32_t gpio_num, uint32_t level);
/**
* @brief Sample the value of GPIO input pins(0-30) and returns a bitmask.
* @param None
* @brief Get GPIO input level
*
* @return uint32_t : bitmask for GPIO input pins, BIT(0) for GPIO0.
* @param gpio_num GPIO number
*
* @return 0:the GPIO_input level is low; 1:the GPIO input level is high
*/
uint32_t gpio_input_get(void);
/**
* @brief Set GPIO to wakeup the ESP32.
* Please do not call this function in SDK.
*
* @param uint32_t i: gpio number.
*
* @param GPIO_INT_TYPE intr_state : only GPIO_PIN_INTR_LOLEVEL\GPIO_PIN_INTR_HILEVEL can be used
*
* @return None
*/
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
/**
* @brief disable GPIOs to wakeup the ESP32.
* Please do not call this function in SDK.
*
* @param None
*
* @return None
*/
void gpio_pin_wakeup_disable(void);
uint32_t gpio_get_input_level(uint32_t gpio_num);
/**
* @brief set gpio input to a signal, one gpio can input to several signals.

View File

@@ -73,7 +73,7 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas
uint32_t gpio_input_get(void);
/**
* @brief Set GPIO to wakeup the ESP32.
* @brief Set GPIO to wakeup the chip.
* Please do not call this function in SDK.
*
* @param uint32_t i: gpio number.
@@ -85,7 +85,7 @@ uint32_t gpio_input_get(void);
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
/**
* @brief disable GPIOs to wakeup the ESP32.
* @brief disable GPIOs to wakeup the chip.
* Please do not call this function in SDK.
*
* @param None

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -38,161 +38,22 @@ extern "C" {
#define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0)
typedef enum {
GPIO_PIN_INTR_DISABLE = 0,
GPIO_PIN_INTR_POSEDGE = 1,
GPIO_PIN_INTR_NEGEDGE = 2,
GPIO_PIN_INTR_ANYEDGE = 3,
GPIO_PIN_INTR_LOLEVEL = 4,
GPIO_PIN_INTR_HILEVEL = 5
} GPIO_INT_TYPE;
#define GPIO_OUTPUT_SET(gpio_no, bit_value) \
((gpio_no < 32) ? gpio_output_set(bit_value<<gpio_no, (bit_value ? 0 : 1)<<gpio_no, 1<<gpio_no,0) : \
gpio_output_set_high(bit_value<<(gpio_no - 32), (bit_value ? 0 : 1)<<(gpio_no - 32), 1<<(gpio_no -32),0))
#define GPIO_DIS_OUTPUT(gpio_no) ((gpio_no < 32) ? gpio_output_set(0,0,0, 1<<gpio_no) : gpio_output_set_high(0,0,0, 1<<(gpio_no - 32)))
#define GPIO_INPUT_GET(gpio_no) ((gpio_no < 32) ? ((gpio_input_get()>>gpio_no)&BIT0) : ((gpio_input_get_high()>>(gpio_no - 32))&BIT0))
/* GPIO interrupt handler, registered through gpio_intr_handler_register */
typedef void (* gpio_intr_handler_fn_t)(uint32_t intr_mask, bool high, void *arg);
/**
* @brief Set GPIO output level
*
* @param gpio_num GPIO number
* @param level Output level, 0:low; 1:high
*/
void gpio_set_output_level(uint32_t gpio_num, uint32_t level);
/**
* @brief Initialize GPIO. This includes reading the GPIO Configuration DataSet
* to initialize "output enables" and pin configurations for each gpio pin.
* Please do not call this function in SDK.
* @brief Get GPIO input level
*
* @param None
* @param gpio_num GPIO number
*
* @return None
* @return 0:the GPIO_input level is low; 1:the GPIO input level is high
*/
void gpio_init(void);
/**
* @brief Change GPIO(0-31) pin output by setting, clearing, or disabling pins, GPIO0<->BIT(0).
* There is no particular ordering guaranteed; so if the order of writes is significant,
* calling code should divide a single call into multiple calls.
*
* @param uint32_t set_mask : the gpios that need high level.
*
* @param uint32_t clear_mask : the gpios that need low level.
*
* @param uint32_t enable_mask : the gpios that need be changed.
*
* @param uint32_t disable_mask : the gpios that need disable output.
*
* @return None
*/
void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask);
/**
* @brief Change GPIO(32-54) pin output by setting, clearing, or disabling pins, GPIO32<->BIT(0).
* There is no particular ordering guaranteed; so if the order of writes is significant,
* calling code should divide a single call into multiple calls.
*
* @param uint32_t set_mask : the gpios that need high level.
*
* @param uint32_t clear_mask : the gpios that need low level.
*
* @param uint32_t enable_mask : the gpios that need be changed.
*
* @param uint32_t disable_mask : the gpios that need disable output.
*
* @return None
*/
void gpio_output_set_high(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask);
/**
* @brief Sample the value of GPIO input pins(0-31) and returns a bitmask.
*
* @param None
*
* @return uint32_t : bitmask for GPIO input pins, BIT(0) for GPIO0.
*/
uint32_t gpio_input_get(void);
/**
* @brief Sample the value of GPIO input pins(32-54) and returns a bitmask.
*
* @param None
*
* @return uint32_t : bitmask for GPIO input pins, BIT(0) for GPIO32.
*/
uint32_t gpio_input_get_high(void);
/**
* @brief Register an application-specific interrupt handler for GPIO pin interrupts.
* Once the interrupt handler is called, it will not be called again until after a call to gpio_intr_ack.
* Please do not call this function in SDK.
*
* @param gpio_intr_handler_fn_t fn : gpio application-specific interrupt handler
*
* @param void *arg : gpio application-specific interrupt handler argument.
*
* @return None
*/
void gpio_intr_handler_register(gpio_intr_handler_fn_t fn, void *arg);
/**
* @brief Get gpio interrupts which happens but not processed.
* Please do not call this function in SDK.
*
* @param None
*
* @return uint32_t : bitmask for GPIO pending interrupts, BIT(0) for GPIO0.
*/
uint32_t gpio_intr_pending(void);
/**
* @brief Get gpio interrupts which happens but not processed.
* Please do not call this function in SDK.
*
* @param None
*
* @return uint32_t : bitmask for GPIO pending interrupts, BIT(0) for GPIO32.
*/
uint32_t gpio_intr_pending_high(void);
/**
* @brief Ack gpio interrupts to process pending interrupts.
* Please do not call this function in SDK.
*
* @param uint32_t ack_mask: bitmask for GPIO ack interrupts, BIT(0) for GPIO0.
*
* @return None
*/
void gpio_intr_ack(uint32_t ack_mask);
/**
* @brief Ack gpio interrupts to process pending interrupts.
* Please do not call this function in SDK.
*
* @param uint32_t ack_mask: bitmask for GPIO ack interrupts, BIT(0) for GPIO32.
*
* @return None
*/
void gpio_intr_ack_high(uint32_t ack_mask);
/**
* @brief Set GPIO to wakeup the ESP32P4.
* Please do not call this function in SDK.
*
* @param uint32_t i: gpio number.
*
* @param GPIO_INT_TYPE intr_state : only GPIO_PIN_INTR_LOLEVEL\GPIO_PIN_INTR_HILEVEL can be used
*
* @return None
*/
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
/**
* @brief disable GPIOs to wakeup the ESP32P4.
* Please do not call this function in SDK.
*
* @param None
*
* @return None
*/
void gpio_pin_wakeup_disable(void);
uint32_t gpio_get_input_level(uint32_t gpio_num);
/**
* @brief set gpio input to a signal, one gpio can input to several signals.

View File

@@ -104,7 +104,7 @@ uint32_t gpio_input_get(void);
uint32_t gpio_input_get_high(void);
/**
* @brief Set GPIO to wakeup the ESP32.
* @brief Set GPIO to wakeup the chip.
* Please do not call this function in SDK.
*
* @param uint32_t i: gpio number.
@@ -116,7 +116,7 @@ uint32_t gpio_input_get_high(void);
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
/**
* @brief disable GPIOs to wakeup the ESP32.
* @brief disable GPIOs to wakeup the chip.
* Please do not call this function in SDK.
*
* @param None

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -63,6 +63,7 @@ typedef enum {
*/
void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask);
// gpio_output_set_high does not show in ESP32S3 ROM
/**
* @brief Sample the value of GPIO input pins(0-31) and returns a bitmask.
@@ -73,8 +74,10 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas
*/
uint32_t gpio_input_get(void);
// gpio_input_get_high does not show in ESP32S3 ROM
/**
* @brief Set GPIO to wakeup the ESP32.
* @brief Set GPIO to wakeup the chip.
* Please do not call this function in SDK.
*
* @param uint32_t i: gpio number.
@@ -86,7 +89,7 @@ uint32_t gpio_input_get(void);
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
/**
* @brief disable GPIOs to wakeup the ESP32.
* @brief disable GPIOs to wakeup the chip.
* Please do not call this function in SDK.
*
* @param None

View File

@@ -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
*/
@@ -9,12 +9,13 @@
#include "esp_attr.h"
#include "soc/soc.h"
#include "hal/gpio_hal.h"
#include "hal/rtc_io_ll.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];
volatile uint32_t fun_pu;
volatile uint32_t fun_pd;
} gpio_slp_mode_cfg_t;
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)
{
/* 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.
* 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);
int rtcio_num = rtc_io_num_map[gpio_num];
if (rtcio_num >= 0 && gpio_ll_sleep_sel_is_enabled(hal->dev, gpio_num)) {
if (rtcio_ll_is_pullup_enabled(rtcio_num)) {
pcfg->fun_pu |= BIT(rtcio_num);
} 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)) {
pcfg->fun_pd[gpio_num >> 4] |= BIT(gpio_num & 0xf);
if (rtcio_ll_is_pulldown_enabled(rtcio_num)) {
pcfg->fun_pd |= BIT(rtcio_num);
} 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)) {
gpio_ll_pullup_en(hal->dev, gpio_num);
rtcio_ll_pullup_enable(rtcio_num);
} 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)) {
gpio_ll_pulldown_en(hal->dev, gpio_num);
rtcio_ll_pulldown_enable(rtcio_num);
} 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)
{
/* 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.
* 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);
int rtcio_num = rtc_io_num_map[gpio_num];
if (rtcio_num >= 0 && gpio_ll_sleep_sel_is_enabled(hal->dev, gpio_num)) {
if (pcfg->fun_pu & BIT(rtcio_num)) {
rtcio_ll_pullup_enable(rtcio_num);
} 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)) {
gpio_ll_pulldown_en(hal->dev, gpio_num);
if (pcfg->fun_pd & BIT(rtcio_num)) {
rtcio_ll_pulldown_enable(rtcio_num);
} else {
gpio_ll_pulldown_dis(hal->dev, gpio_num);
rtcio_ll_pulldown_disable(rtcio_num);
}
}
}

View File

@@ -183,7 +183,7 @@ static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, uint32_t gpio_num)
__attribute__((always_inline))
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;
}
/**
@@ -220,7 +220,7 @@ static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
__attribute__((always_inline))
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;
}
/**
@@ -257,7 +257,7 @@ static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
__attribute__((always_inline))
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;
}
/**

View File

@@ -77,7 +77,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/
static inline void rtcio_ll_output_enable(int rtcio_num)
{
RTCIO.enable_w1ts.w1ts = (1U << rtcio_num);
RTCIO.enable_w1ts.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TS_S));
}
/**
@@ -87,7 +87,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/
static inline void rtcio_ll_output_disable(int rtcio_num)
{
RTCIO.enable_w1tc.w1tc = (1U << rtcio_num);
RTCIO.enable_w1tc.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TC_S));
}
/**
@@ -99,9 +99,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{
if (level) {
RTCIO.out_w1ts.w1ts = (1U << rtcio_num);
RTCIO.out_w1ts.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TS_S));
} else {
RTCIO.out_w1tc.w1tc = (1U << rtcio_num);
RTCIO.out_w1tc.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TC_S));
}
}
@@ -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).
*/
__attribute__((always_inline))
static inline void rtcio_ll_pullup_enable(int rtcio_num)
{
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).
*/
__attribute__((always_inline))
static inline void rtcio_ll_pullup_disable(int rtcio_num)
{
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).
* @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)
{
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).
*/
__attribute__((always_inline))
static inline void rtcio_ll_pulldown_enable(int rtcio_num)
{
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).
*/
__attribute__((always_inline))
static inline void rtcio_ll_pulldown_disable(int rtcio_num)
{
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).
* @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)
{
if (rtc_io_desc[rtcio_num].pulldown) {

View File

@@ -115,7 +115,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/
static inline void rtcio_ll_output_enable(int rtcio_num)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1ts, out_enable_w1ts, BIT(rtcio_num));
LP_GPIO.enable_w1ts.val = BIT(rtcio_num);
}
/**
@@ -125,7 +125,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/
static inline void rtcio_ll_output_disable(int rtcio_num)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1tc, out_enable_w1tc, BIT(rtcio_num));
LP_GPIO.enable_w1tc.val = BIT(rtcio_num);
}
/**
@@ -137,9 +137,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{
if (level) {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.out_w1ts, out_data_w1ts, BIT(rtcio_num));
LP_GPIO.out_w1ts.val = BIT(rtcio_num);
} else {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.out_w1tc, out_data_w1tc, BIT(rtcio_num));
LP_GPIO.out_w1tc.val = BIT(rtcio_num);
}
}
@@ -450,7 +450,7 @@ static inline uint32_t rtcio_ll_get_interrupt_status(void)
*/
static inline void rtcio_ll_clear_interrupt_status(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.status_w1tc, status_intr_w1tc, 0xff);
LP_GPIO.status_w1tc.val = 0xFF;
}
#ifdef __cplusplus

View File

@@ -114,7 +114,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/
static inline void rtcio_ll_output_enable(int rtcio_num)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_enable_w1ts, enable_w1ts, BIT(rtcio_num));
LP_IO.out_enable_w1ts.val = BIT(rtcio_num);
}
/**
@@ -124,7 +124,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/
static inline void rtcio_ll_output_disable(int rtcio_num)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_enable_w1tc, enable_w1tc, BIT(rtcio_num));
LP_IO.out_enable_w1tc.val = BIT(rtcio_num);
}
/**
@@ -136,9 +136,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{
if (level) {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_data_w1ts, out_w1ts, BIT(rtcio_num));
LP_IO.out_data_w1ts.val = BIT(rtcio_num);
} else {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.out_data_w1tc, out_w1tc, BIT(rtcio_num));
LP_IO.out_data_w1tc.val = BIT(rtcio_num);
}
}
@@ -457,7 +457,7 @@ static inline uint32_t rtcio_ll_get_interrupt_status(void)
*/
static inline void rtcio_ll_clear_interrupt_status(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_IO.status_w1tc, status_intr_w1tc, 0xff);
LP_IO.status_w1tc.val = 0xFF;
}
#ifdef __cplusplus

View File

@@ -115,7 +115,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/
static inline void rtcio_ll_output_enable(int rtcio_num)
{
LP_GPIO.enable_w1ts.enable_w1ts = BIT(rtcio_num);
LP_GPIO.enable_w1ts.val = BIT(rtcio_num);
}
/**
@@ -125,7 +125,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/
static inline void rtcio_ll_output_disable(int rtcio_num)
{
LP_GPIO.enable_w1tc.enable_w1tc = BIT(rtcio_num);
LP_GPIO.enable_w1tc.val = BIT(rtcio_num);
}
/**
@@ -137,9 +137,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{
if (level) {
LP_GPIO.out_w1ts.out_w1ts = BIT(rtcio_num);
LP_GPIO.out_w1ts.val = BIT(rtcio_num);
} else {
LP_GPIO.out_w1tc.out_w1tc = BIT(rtcio_num);
LP_GPIO.out_w1tc.val = BIT(rtcio_num);
}
}
@@ -450,7 +450,7 @@ static inline uint32_t rtcio_ll_get_interrupt_status(void)
*/
static inline void rtcio_ll_clear_interrupt_status(void)
{
LP_GPIO.status_w1tc.status_w1tc = 0x7F;
LP_GPIO.status_w1tc.val = 0x7F;
}
#ifdef __cplusplus

View File

@@ -148,7 +148,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/
static inline void rtcio_ll_output_enable(int rtcio_num)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1ts, reg_gpio_enable_data_w1ts, BIT(rtcio_num));
LP_GPIO.enable_w1ts.val = BIT(rtcio_num);
}
/**
@@ -158,7 +158,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/
static inline void rtcio_ll_output_disable(int rtcio_num)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1tc, reg_gpio_enable_data_w1tc, BIT(rtcio_num));
LP_GPIO.enable_w1tc.val = BIT(rtcio_num);
// Ensure no other output signal is routed via LP_GPIO matrix to this pin
LP_GPIO.func_out_sel_cfg[rtcio_num].func_out_sel = SIG_LP_GPIO_OUT_IDX;
}
@@ -172,9 +172,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{
if (level) {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.out_w1ts, reg_gpio_out_data_w1ts, BIT(rtcio_num));
LP_GPIO.out_w1ts.val = BIT(rtcio_num);
} else {
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.out_w1tc, reg_gpio_out_data_w1tc, BIT(rtcio_num));
LP_GPIO.out_w1tc.val = BIT(rtcio_num);
}
}
@@ -485,7 +485,7 @@ static inline uint32_t rtcio_ll_get_interrupt_status(void)
*/
static inline void rtcio_ll_clear_interrupt_status(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.status_w1tc, reg_gpio_status_data_w1tc, 0xFFFF);
LP_GPIO.status_w1tc.val = 0xFFFF;
}
#ifdef __cplusplus

View File

@@ -89,7 +89,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/
static inline void rtcio_ll_output_enable(int rtcio_num)
{
RTCIO.enable_w1ts.w1ts = (1U << rtcio_num);
RTCIO.enable_w1ts.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TS_S));
}
/**
@@ -99,7 +99,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/
static inline void rtcio_ll_output_disable(int rtcio_num)
{
RTCIO.enable_w1tc.w1tc = (1U << rtcio_num);
RTCIO.enable_w1tc.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TC_S));
}
/**
@@ -111,9 +111,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{
if (level) {
RTCIO.out_w1ts.w1ts = (1U << rtcio_num);
RTCIO.out_w1ts.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TS_S));
} else {
RTCIO.out_w1tc.w1tc = (1U << rtcio_num);
RTCIO.out_w1tc.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TC_S));
}
}

View File

@@ -98,7 +98,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/
static inline void rtcio_ll_output_enable(int rtcio_num)
{
RTCIO.enable_w1ts.w1ts = (1U << rtcio_num);
RTCIO.enable_w1ts.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TS_S));
}
/**
@@ -108,7 +108,7 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/
static inline void rtcio_ll_output_disable(int rtcio_num)
{
RTCIO.enable_w1tc.w1tc = (1U << rtcio_num);
RTCIO.enable_w1tc.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TC_S));
}
/**
@@ -120,9 +120,9 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{
if (level) {
RTCIO.out_w1ts.w1ts = (1U << rtcio_num);
RTCIO.out_w1ts.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TS_S));
} else {
RTCIO.out_w1tc.w1tc = (1U << rtcio_num);
RTCIO.out_w1tc.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TC_S));
}
}

View File

@@ -7,7 +7,7 @@
#include "soc/rtc_periph.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
-1,//GPIO1
RTCIO_GPIO2_CHANNEL, //GPIO2

View File

@@ -6,7 +6,7 @@
#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_GPIO1_CHANNEL, //GPIO1
RTCIO_GPIO2_CHANNEL, //GPIO2

View File

@@ -6,7 +6,7 @@
#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_GPIO1_CHANNEL, //GPIO1
RTCIO_GPIO2_CHANNEL, //GPIO2

View File

@@ -6,7 +6,7 @@
#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_GPIO1_CHANNEL, //GPIO1
RTCIO_GPIO2_CHANNEL, //GPIO2

View File

@@ -5,7 +5,7 @@
*/
#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,//GPIO1
-1,//GPIO2

View File

@@ -6,7 +6,7 @@
#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_GPIO1_CHANNEL, //GPIO1
RTCIO_GPIO2_CHANNEL, //GPIO2

View File

@@ -7,7 +7,7 @@
#include "soc/rtc_periph.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_GPIO1_CHANNEL, //GPIO1
RTCIO_GPIO2_CHANNEL, //GPIO2

View File

@@ -7,7 +7,7 @@
#include "soc/rtc_periph.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_GPIO1_CHANNEL, //GPIO1
RTCIO_GPIO2_CHANNEL, //GPIO2

View File

@@ -63,7 +63,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
* 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
#ifdef __cplusplus