Merge branch 'feature/esp32h21_gpio_support' into 'master'

feat(esp32h21): support GPIO on esp32h21

Closes IDF-11611

See merge request espressif/esp-idf!36781
This commit is contained in:
Gao Xu
2025-02-25 11:12:54 +08:00
35 changed files with 878 additions and 237 deletions

View File

@@ -604,13 +604,7 @@ esp_err_t gpio_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags,
{
GPIO_CHECK(fn, "GPIO ISR null", ESP_ERR_INVALID_ARG);
gpio_isr_alloc_t p;
#if CONFIG_IDF_TARGET_ESP32P4 //TODO: IDF-7995
p.source = ETS_GPIO_INTR0_SOURCE;
#elif CONFIG_IDF_TARGET_ESP32H21 // TODO: IDF-11611
p.source = ETS_GPIO_INTERRUPT_PRO_SOURCE;
#else
p.source = ETS_GPIO_INTR_SOURCE;
#endif
p.source = GPIO_LL_INTR_SOURCE0;
p.intr_alloc_flags = intr_alloc_flags;
#if SOC_ANA_CMPR_INTR_SHARE_WITH_GPIO
p.intr_alloc_flags |= ESP_INTR_FLAG_SHARED;

View File

@@ -3,11 +3,6 @@
components/esp_driver_gpio/test_apps:
depends_components:
- esp_driver_gpio
disable:
- if: IDF_TARGET in ["esp32h21"]
temporary: true
reason: not support yet # TODO: [esp32h21] IDF-11611
components/esp_driver_gpio/test_apps/gpio_extensions:
enable:
- if: SOC_DEDICATED_GPIO_SUPPORTED == 1

View File

@@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -561,6 +561,9 @@ TEST_CASE("GPIO_get_level_from_fixed_voltage_test", "[gpio]")
TEST_ASSERT_EQUAL_INT_MESSAGE(0, level2, "get level error! the level should be low!");
}
#if !CONFIG_IDF_ENV_FPGA
// On FPGA do not support GPIO pull down
TEST_CASE("GPIO_io_pull_up/down_function", "[gpio]")
{
// First, ensure that the output IO will not affect the level
@@ -662,6 +665,8 @@ TEST_CASE("GPIO_mode_test", "[gpio]")
TEST_ASSERT_EQUAL_INT_MESSAGE(!level, gpio_get_level(TEST_GPIO_EXT_IN_IO), "direction GPIO_MODE_INPUT_OUTPUT set error, it gives incorrect output");
}
#endif //!CONFIG_IDF_ENV_FPGA
static void prompt_to_continue(const char *str)
{
printf("%s , please press \"Enter\" to go on!\n", str);

View File

@@ -1,8 +1,77 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
//TODO: [ESP32H21] IDF-11611
#include "freertos/FreeRTOS.h"
#include "esp_private/io_mux.h"
#include "esp_private/periph_ctrl.h"
#include "hal/gpio_ll.h"
#include "hal/rtc_io_ll.h"
#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
static soc_module_clk_t s_io_mux_clk_src = 0; // by default, the clock source is not set explicitly by any consumer (e.g. SDM, Filter)
static uint8_t s_rtc_io_enabled_cnt[MAX_RTC_GPIO_NUM] = { 0 };
static uint32_t s_rtc_io_using_mask = 0;
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
{
bool clk_conflict = false;
// check is the IO MUX has been set to another clock source
portENTER_CRITICAL(&s_io_mux_spinlock);
if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) {
clk_conflict = true;
} else {
s_io_mux_clk_src = clk_src;
}
portEXIT_CRITICAL(&s_io_mux_spinlock);
if (clk_conflict) {
return ESP_ERR_INVALID_STATE;
}
gpio_ll_iomux_set_clk_src(clk_src);
return ESP_OK;
}
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
{
portENTER_CRITICAL(&s_io_mux_spinlock);
if (enable) {
if (s_rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_using_mask |= (1ULL << gpio_num);
}
s_rtc_io_enabled_cnt[gpio_num]++;
} else if (!enable && (s_rtc_io_enabled_cnt[gpio_num] > 0)) {
s_rtc_io_enabled_cnt[gpio_num]--;
if (s_rtc_io_enabled_cnt[gpio_num] == 0) {
s_rtc_io_using_mask &= ~(1ULL << gpio_num);
}
}
RTCIO_RCC_ATOMIC() {
if (s_rtc_io_using_mask == 0) {
rtcio_ll_enable_io_clock(false);
} else {
rtcio_ll_enable_io_clock(true);
}
}
portEXIT_CRITICAL(&s_io_mux_spinlock);
}
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
{
portENTER_CRITICAL(&s_io_mux_spinlock);
s_rtc_io_enabled_cnt[gpio_num] = 0;
s_rtc_io_using_mask &= ~(1ULL << gpio_num);
if (s_rtc_io_using_mask == 0) {
RTCIO_RCC_ATOMIC() {
rtcio_ll_enable_io_clock(false);
}
}
portEXIT_CRITICAL(&s_io_mux_spinlock);
}

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
*/
@@ -10,8 +10,6 @@
#include <stdbool.h>
#include "soc/gpio_reg.h"
//TODO: [ESP32H21] IDF-11611
#ifdef __cplusplus
extern "C" {
#endif
@@ -30,7 +28,6 @@ extern "C" {
#define GPIO_ID_PIN(n) (GPIO_ID_PIN0+(n))
#define GPIO_PIN_ADDR(i) (GPIO_PIN0_REG + i*4)
//TODO: [ESP32H21] IDF-11611, need check
#define GPIO_FUNC_IN_HIGH 0x20
#define GPIO_FUNC_IN_LOW 0x30
@@ -50,7 +47,7 @@ typedef enum {
/**
* @brief Change GPIO(0-27) pin output by setting, clearing, or disabling pins, GPIO0<->BIT(0).
* @brief Change GPIO(0-25) 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.
*
@@ -67,7 +64,7 @@ typedef enum {
void gpio_output_set(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-27) and returns a bitmask.
* @brief Sample the value of GPIO input pins(0-25) and returns a bitmask.
*
* @param None
*
@@ -76,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 ESP32H21.
* Please do not call this function in SDK.
*
* @param uint32_t i: gpio number.
@@ -88,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 ESP32H21.
* Please do not call this function in SDK.
*
* @param None
@@ -100,10 +97,9 @@ void gpio_pin_wakeup_disable(void);
/**
* @brief set gpio input to a signal, one gpio can input to several signals.
*
* @param uint32_t gpio : gpio number, 0~27
* gpio == 0x3C, input 0 to signal
* gpio == 0x3A, input nothing to signal
* gpio == 0x38, input 1 to signal
* @param uint32_t gpio : gpio number, 0~25
* gpio == 0x30, input 0 to signal
* gpio == 0x20, input 1 to signal
*
* @param uint32_t signal_idx : signal index.
*
@@ -116,7 +112,7 @@ void gpio_matrix_in(uint32_t gpio, uint32_t signal_idx, bool inv);
/**
* @brief set signal output to gpio, one signal can output to several gpios.
*
* @param uint32_t gpio : gpio number, 0~27
* @param uint32_t gpio : gpio number, 0~25
*
* @param uint32_t signal_idx : signal index.
* signal_idx == 0x80, cancel output put to the gpio
@@ -132,7 +128,7 @@ void gpio_matrix_out(uint32_t gpio, uint32_t signal_idx, bool out_inv, bool oen_
/**
* @brief Select pad as a gpio function from IOMUX.
*
* @param uint32_t gpio_num : gpio number, 0~27
* @param uint32_t gpio_num : gpio number, 0~25
*
* @return None
*/
@@ -141,7 +137,7 @@ void gpio_pad_select_gpio(uint32_t gpio_num);
/**
* @brief Set pad driver capability.
*
* @param uint32_t gpio_num : gpio number, 0~27
* @param uint32_t gpio_num : gpio number, 0~25
*
* @param uint32_t drv : 0-3
*
@@ -152,7 +148,7 @@ void gpio_pad_set_drv(uint32_t gpio_num, uint32_t drv);
/**
* @brief Pull up the pad from gpio number.
*
* @param uint32_t gpio_num : gpio number, 0~27
* @param uint32_t gpio_num : gpio number, 0~25
*
* @return None
*/
@@ -161,7 +157,7 @@ void gpio_pad_pullup(uint32_t gpio_num);
/**
* @brief Pull down the pad from gpio number.
*
* @param uint32_t gpio_num : gpio number, 0~27
* @param uint32_t gpio_num : gpio number, 0~25
*
* @return None
*/
@@ -170,7 +166,7 @@ void gpio_pad_pulldown(uint32_t gpio_num);
/**
* @brief Unhold the pad from gpio number.
*
* @param uint32_t gpio_num : gpio number, 0~27
* @param uint32_t gpio_num : gpio number, 0~25
*
* @return None
*/
@@ -179,7 +175,7 @@ void gpio_pad_unhold(uint32_t gpio_num);
/**
* @brief Hold the pad from gpio number.
*
* @param uint32_t gpio_num : gpio number, 0~27
* @param uint32_t gpio_num : gpio number, 0~25
*
* @return None
*/
@@ -188,7 +184,7 @@ void gpio_pad_hold(uint32_t gpio_num);
/**
* @brief enable gpio pad input.
*
* @param uint32_t gpio_num : gpio number, 0~27
* @param uint32_t gpio_num : gpio number, 0~25
*
* @return None
*/
@@ -197,7 +193,7 @@ void gpio_pad_input_enable(uint32_t gpio_num);
/**
* @brief disable gpio pad input.
*
* @param uint32_t gpio_num : gpio number, 0~27
* @param uint32_t gpio_num : gpio number, 0~25
*
* @return None
*/

View File

@@ -42,6 +42,8 @@ extern const uint8_t GPIO_PIN_MUX_REG_OFFSET[SOC_GPIO_PIN_COUNT];
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(3))
#define GPIO_LL_SDIO_EXT_INTR_ENA (BIT(4))
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
/**
* @brief Get the configuration for an IO
*

View File

@@ -33,6 +33,8 @@ extern "C" {
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
/**
* @brief Get the configuration for an IO
*

View File

@@ -35,6 +35,8 @@ extern "C" {
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
/**
* @brief Enable pull-up on GPIO.
*

View File

@@ -37,6 +37,8 @@ extern "C" {
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
/**
* @brief Get the configuration for an IO
*
@@ -259,7 +261,7 @@ static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num)
static inline void gpio_ll_pin_input_hysteresis_enable(gpio_dev_t *hw, uint32_t gpio_num)
{
// On ESP32C5, there is an efuse bit that controls the hysteresis enable or not for all IOs.
// We are not going to use the hardware control in IDF for C5.
// We are not going to use the hardware control for C5.
// Therefore, we need to always switch to use software control first.
// i.e. Swt hys_sel to 1, so that hys_en determines whether hysteresis is enabled or not
IO_MUX.gpio[gpio_num].hys_sel = 1;

View File

@@ -38,6 +38,8 @@ extern "C" {
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
/**
* @brief Get the configuration for an IO
*

View File

@@ -38,6 +38,8 @@ extern "C" {
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
/**
* @brief Get the configuration for an IO
*

View File

@@ -38,6 +38,8 @@ extern "C" {
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
/**
* @brief Get the configuration for an IO
*

View File

@@ -80,10 +80,10 @@ uint32_t clk_hal_xtal_get_freq_mhz(void)
void clk_hal_clock_output_setup(soc_clkout_sig_id_t clk_sig, clock_out_channel_t channel_id)
{
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id));
abort(); // TODO: IDF-11582
}
void clk_hal_clock_output_teardown(clock_out_channel_t channel_id)
{
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_id), CLKOUT_CHANNEL_SHIFT(channel_id));
abort(); // TODO: IDF-11582
}

View File

@@ -21,15 +21,14 @@
#include "soc/gpio_struct.h"
#include "soc/lp_aon_struct.h"
#include "soc/pmu_struct.h"
#include "soc/usb_serial_jtag_reg.h"
#include "soc/pcr_struct.h"
#include "soc/clk_tree_defs.h"
#include "soc/io_mux_struct.h"
#include "soc/usb_serial_jtag_struct.h"
#include "hal/gpio_types.h"
#include "hal/misc.h"
#include "hal/assert.h"
//TODO: [ESP32H21] IDF-11611, inherit from h2
#ifdef __cplusplus
extern "C" {
#endif
@@ -40,6 +39,8 @@ extern "C" {
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTERRUPT_PRO_SOURCE
/**
* @brief Get the configuration for an IO
*
@@ -50,18 +51,17 @@ extern "C" {
static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config)
{
uint32_t bit_mask = 1 << gpio_num;
uint32_t iomux_reg_val = REG_READ(IO_MUX_GPIO0_REG + (gpio_num * 4));
io_config->pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S;
io_config->pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S;
io_config->ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S;
io_config->pu = IO_MUX.gpio[gpio_num].fun_wpu;
io_config->pd = IO_MUX.gpio[gpio_num].fun_wpd;
io_config->ie = IO_MUX.gpio[gpio_num].fun_ie;
io_config->oe = (hw->enable.val & bit_mask) >> gpio_num;
io_config->oe_ctrl_by_periph = !(hw->funcn_out_sel_cfg[gpio_num].funcn_oe_sel);
io_config->oe_inv = hw->funcn_out_sel_cfg[gpio_num].funcn_oe_inv_sel;
io_config->od = hw->pinn[gpio_num].pinn_pad_driver;
io_config->drv = (gpio_drive_cap_t)((iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S);
io_config->fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S;
io_config->drv = (gpio_drive_cap_t)IO_MUX.gpio[gpio_num].fun_drv;
io_config->fun_sel = IO_MUX.gpio[gpio_num].mcu_sel;
io_config->sig_out = hw->funcn_out_sel_cfg[gpio_num].funcn_out_sel;
io_config->slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S;
io_config->slp_sel = IO_MUX.gpio[gpio_num].slp_sel;
}
/**
@@ -72,7 +72,7 @@ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio
*/
static inline void gpio_ll_pullup_en(gpio_dev_t *hw, gpio_num_t gpio_num)
{
REG_SET_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU);
IO_MUX.gpio[gpio_num].fun_wpu = 1;
}
/**
@@ -90,10 +90,10 @@ static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
// which should be checked is USB_INT_PHY0_DM_GPIO_NUM instead.
// TODO: read the specific efuse with efuse_ll.h
if (gpio_num == USB_INT_PHY0_DP_GPIO_NUM) {
SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE);
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP);
USB_SERIAL_JTAG.serial_jtag_conf0.serial_jtag_pad_pull_override = 1;
USB_SERIAL_JTAG.serial_jtag_conf0.serial_jtag_dp_pullup = 0;
}
REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU);
IO_MUX.gpio[gpio_num].fun_wpu = 0;
}
/**
@@ -104,7 +104,7 @@ static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
*/
static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, gpio_num_t gpio_num)
{
REG_SET_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD);
IO_MUX.gpio[gpio_num].fun_wpd = 1;
}
/**
@@ -116,8 +116,7 @@ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, gpio_num_t gpio_num)
__attribute__((always_inline))
static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
{
REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD);
IO_MUX.gpio[gpio_num].fun_wpd = 0;
}
/**
@@ -218,7 +217,7 @@ static inline void gpio_ll_intr_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
__attribute__((always_inline))
static inline void gpio_ll_input_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
{
PIN_INPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].fun_ie = 0;
}
/**
@@ -230,7 +229,7 @@ static inline void gpio_ll_input_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
__attribute__((always_inline))
static inline void gpio_ll_input_enable(gpio_dev_t *hw, gpio_num_t gpio_num)
{
PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].fun_ie = 1;
}
/**
@@ -241,7 +240,7 @@ static inline void gpio_ll_input_enable(gpio_dev_t *hw, gpio_num_t gpio_num)
*/
static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num)
{
PIN_FILTER_EN(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].filter_en = 1;
}
/**
@@ -252,29 +251,7 @@ static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num)
*/
static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num)
{
PIN_FILTER_DIS(IO_MUX_GPIO0_REG + (gpio_num * 4));
}
/**
* @brief Select gpio hysteresis control by efuse.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number
*/
static inline void gpio_ll_pin_input_hysteresis_ctrl_sel_efuse(gpio_dev_t *hw, uint32_t gpio_num)
{
PIN_HYS_EN_SEL_EFUSE(IO_MUX_GPIO0_REG + (gpio_num * 4));
}
/**
* @brief Select gpio hysteresis control by software.
*
* @param hw Peripheral GPIO hardware instance address.
* @param gpio_num GPIO number
*/
static inline void gpio_ll_pin_input_hysteresis_ctrl_sel_soft(gpio_dev_t *hw, uint32_t gpio_num)
{
PIN_HYS_EN_SEL_SOFT(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].filter_en = 0;
}
/**
@@ -285,7 +262,12 @@ static inline void gpio_ll_pin_input_hysteresis_ctrl_sel_soft(gpio_dev_t *hw, ui
*/
static inline void gpio_ll_pin_input_hysteresis_enable(gpio_dev_t *hw, uint32_t gpio_num)
{
PIN_HYS_SOFT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
// On ESP32H21, there is an efuse bit that controls the hysteresis enable or not for all IOs.
// We are not going to use the hardware control for H21.
// Therefore, we need to always switch to use software control first.
// i.e. Swt hys_sel to 1, so that hys_en determines whether hysteresis is enabled or not
IO_MUX.gpio[gpio_num].hys_sel = 1;
IO_MUX.gpio[gpio_num].hys_en = 1;
}
/**
@@ -296,7 +278,8 @@ static inline void gpio_ll_pin_input_hysteresis_enable(gpio_dev_t *hw, uint32_t
*/
static inline void gpio_ll_pin_input_hysteresis_disable(gpio_dev_t *hw, uint32_t gpio_num)
{
PIN_HYS_SOFT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].hys_sel = 1;
IO_MUX.gpio[gpio_num].hys_en = 0;
}
/**
@@ -309,8 +292,6 @@ __attribute__((always_inline))
static inline void gpio_ll_output_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
{
hw->enable_w1tc.enable_w1tc = (0x1 << gpio_num);
// Ensure no other output signal is routed via GPIO matrix to this pin
REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG + (gpio_num * 4), SIG_GPIO_OUT_IDX);
}
/**
@@ -356,10 +337,10 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, gpio_num_t gpio_num)
__attribute__((always_inline))
static inline void gpio_ll_matrix_out_default(gpio_dev_t *hw, uint32_t gpio_num)
{
// gpio_func_out_sel_cfg_reg_t reg = {
// .out_sel = SIG_GPIO_OUT_IDX,
// };
// hw->func_out_sel_cfg[gpio_num].val = reg.val;
gpio_funcn_out_sel_cfg_reg_t reg = {
.funcn_out_sel = SIG_GPIO_OUT_IDX,
};
hw->funcn_out_sel_cfg[gpio_num].val = reg.val;
}
/**
@@ -429,7 +410,7 @@ static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
*/
static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, gpio_num_t gpio_num, gpio_drive_cap_t strength)
{
SET_PERI_REG_BITS(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, strength, FUN_DRV_S);
IO_MUX.gpio[gpio_num].fun_drv = strength;
}
/**
@@ -441,7 +422,7 @@ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, gpio_num_t gpio_
*/
static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, gpio_num_t gpio_num, gpio_drive_cap_t *strength)
{
*strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S);
*strength = (gpio_drive_cap_t)(IO_MUX.gpio[gpio_num].fun_drv);
}
/**
@@ -523,24 +504,11 @@ static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_n
__attribute__((always_inline))
static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func)
{
// Disable USB Serial JTAG if pins 26 or pins 27 needs to select an IOMUX function
// Disable USB Serial JTAG if pins 17 or pins 18 needs to select an IOMUX function
if (gpio_num == USB_INT_PHY0_DM_GPIO_NUM || gpio_num == USB_INT_PHY0_DP_GPIO_NUM) {
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE);
USB_SERIAL_JTAG.serial_jtag_conf0.serial_jtag_usb_pad_enable = 0;
}
PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func);
}
/**
* @brief Control the pin in the IOMUX
*
* @param bmap write mask of control value
* @param val Control value
* @param shift write mask shift of control value
*/
__attribute__((always_inline))
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
{
SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift);
IO_MUX.gpio[gpio_num].mcu_sel = func;
}
/**
@@ -554,6 +522,9 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src)
case SOC_MOD_CLK_XTAL:
PCR.iomux_clk_conf.iomux_func_clk_sel = 0;
break;
case SOC_MOD_CLK_RC_FAST:
PCR.iomux_clk_conf.iomux_func_clk_sel = 1;
break;
case SOC_MOD_CLK_PLL_F48M:
PCR.iomux_clk_conf.iomux_func_clk_sel = 2;
break;
@@ -575,8 +546,9 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src)
*/
static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx)
{
uint32_t val = REG_GET_BIT(GPIO_FUNC0_IN_SEL_CFG_REG + in_sig_idx * 4, GPIO_SIG0_IN_SEL);
return (val ? val : -1);
gpio_func_in_sel_cfg_reg_t reg;
reg.val = hw->func_in_sel_cfg[in_sig_idx].val;
return (reg.sig_in_sel ? reg.func_in_sel : -1);
}
/**
@@ -609,7 +581,7 @@ static inline void gpio_ll_force_unhold_all(void)
*/
static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, gpio_num_t gpio_num)
{
PIN_SLP_SEL_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].slp_sel = 1;
}
/**
@@ -621,7 +593,7 @@ static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, gpio_num_t gpio_num)
*/
static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
{
PIN_SLP_SEL_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].slp_sel = 0;
}
/**
@@ -632,7 +604,7 @@ static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
*/
static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
{
PIN_SLP_PULLUP_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].mcu_wpu = 0;
}
/**
@@ -643,7 +615,7 @@ static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
*/
static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, gpio_num_t gpio_num)
{
PIN_SLP_PULLUP_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].mcu_wpu = 1;
}
/**
@@ -654,7 +626,7 @@ static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, gpio_num_t gpio_num)
*/
static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, gpio_num_t gpio_num)
{
PIN_SLP_PULLDOWN_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].mcu_wpd = 1;
}
/**
@@ -665,9 +637,8 @@ static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, gpio_num_t gpio_num
*/
static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, gpio_num_t gpio_num)
{
PIN_SLP_PULLDOWN_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].mcu_wpd = 0;
}
/**
* @brief Disable GPIO input in sleep mode.
*
@@ -676,7 +647,7 @@ static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, gpio_num_t gpio_nu
*/
static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
{
PIN_SLP_INPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].mcu_ie = 0;
}
/**
@@ -687,7 +658,7 @@ static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, gpio_num_t gpio_n
*/
static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, gpio_num_t gpio_num)
{
PIN_SLP_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].mcu_ie = 1;
}
/**
@@ -698,7 +669,7 @@ static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, gpio_num_t gpio_nu
*/
static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
{
PIN_SLP_OUTPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].mcu_oe = 0;
}
/**
@@ -709,7 +680,7 @@ static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, gpio_num_t gpio_
*/
static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, gpio_num_t gpio_num)
{
PIN_SLP_OUTPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
IO_MUX.gpio[gpio_num].mcu_oe = 1;
}
/**
@@ -721,21 +692,21 @@ static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, gpio_num_t gpio_n
*/
static inline void gpio_ll_deepsleep_wakeup_enable(gpio_dev_t *hw, gpio_num_t gpio_num, gpio_int_type_t intr_type)
{
HAL_ASSERT((gpio_num >= GPIO_NUM_7 && gpio_num <= GPIO_NUM_14) &&
"only gpio7~14 support deep sleep wake-up function");
HAL_ASSERT((gpio_num >= GPIO_NUM_5 && gpio_num <= GPIO_NUM_11) &&
"only gpio5~11 support deep sleep wake-up function");
LP_AON.ext_wakeup_cntl.aon_ext_wakeup_filter = 1;
uint32_t wakeup_sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, aon_ext_wakeup_sel);
wakeup_sel_mask |= BIT(gpio_num - 7);
wakeup_sel_mask |= BIT(gpio_num - 5);
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, aon_ext_wakeup_sel, wakeup_sel_mask);
bool trigger_level = (intr_type == GPIO_INTR_LOW_LEVEL) ? 0 : 1;
uint32_t wakeup_level_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, aon_ext_wakeup_lv);
if (trigger_level) {
wakeup_level_mask |= BIT(gpio_num - 7);
wakeup_level_mask |= BIT(gpio_num - 5);
} else {
wakeup_level_mask &= ~BIT(gpio_num - 7);
wakeup_level_mask &= ~BIT(gpio_num - 5);
}
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, aon_ext_wakeup_lv, wakeup_level_mask);
}
@@ -748,11 +719,11 @@ static inline void gpio_ll_deepsleep_wakeup_enable(gpio_dev_t *hw, gpio_num_t gp
*/
static inline void gpio_ll_deepsleep_wakeup_disable(gpio_dev_t *hw, gpio_num_t gpio_num)
{
HAL_ASSERT((gpio_num >= GPIO_NUM_7 && gpio_num <= GPIO_NUM_14) &&
"only gpio7~14 support deep sleep wake-up function");
HAL_ASSERT((gpio_num >= GPIO_NUM_5 && gpio_num <= GPIO_NUM_11) &&
"only gpio5~11 support deep sleep wake-up function");
uint32_t wakeup_sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, aon_ext_wakeup_sel);
wakeup_sel_mask &= ~BIT(gpio_num - 7);
wakeup_sel_mask &= ~BIT(gpio_num - 5);
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, aon_ext_wakeup_sel, wakeup_sel_mask);
}
@@ -765,11 +736,11 @@ static inline void gpio_ll_deepsleep_wakeup_disable(gpio_dev_t *hw, gpio_num_t g
*/
static inline bool gpio_ll_deepsleep_wakeup_is_enabled(gpio_dev_t *hw, uint32_t gpio_num)
{
HAL_ASSERT((gpio_num >= GPIO_NUM_7 && gpio_num <= GPIO_NUM_14) &&
"only gpio7~14 support deep sleep wake-up function");
HAL_ASSERT((gpio_num >= GPIO_NUM_5 && gpio_num <= GPIO_NUM_11) &&
"only gpio5~11 support deep sleep wake-up function");
uint32_t wakeup_sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, aon_ext_wakeup_sel);
return wakeup_sel_mask & BIT(gpio_num - 7);
return wakeup_sel_mask & BIT(gpio_num - 5);
}
#ifdef __cplusplus

View File

@@ -0,0 +1,123 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*******************************************************************************
* NOTICE
* The ll is not public api, don't use in application code.
* See readme.md in hal/readme.md
******************************************************************************/
#pragma once
#include <stdbool.h>
#include "soc/soc_caps.h"
#include "soc/lp_aon_struct.h"
#include "soc/lpperi_struct.h"
#include "soc/pmu_struct.h"
#include "hal/misc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RTCIO_LL_GPIO_NUM_OFFSET 5 // rtcio 0-6 correspond to gpio 5-11
typedef enum {
RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */
RTCIO_LL_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */
} rtcio_ll_func_t;
/**
* @brief Enable/Disable LP_IO peripheral clock.
*
* @param enable true to enable the clock / false to disable the clock
*/
static inline void _rtcio_ll_enable_io_clock(bool enable)
{
LPPERI.clk_en.lp_io_ck_en = enable;
while (LPPERI.clk_en.lp_io_ck_en != enable) {
;
}
}
#define rtcio_ll_enable_io_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _rtcio_ll_enable_io_clock(__VA_ARGS__)
/**
* @brief Select the rtcio function.
*
* @note The RTC function must be selected before the pad analog function is enabled.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param func Select pin function.
*/
static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
{
if (func == RTCIO_LL_FUNC_RTC) {
// 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module.
uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, aon_gpio_mux_sel);
sel_mask |= BIT(rtcio_num);
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, aon_gpio_mux_sel, sel_mask);
} else if (func == RTCIO_LL_FUNC_DIGITAL) {
// Clear the bit to use digital GPIO module
uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, aon_gpio_mux_sel);
sel_mask &= ~BIT(rtcio_num);
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, aon_gpio_mux_sel, sel_mask);
}
}
/**
* Enable force hold function for an RTC IO pad.
*
* Enabling HOLD function will cause the pad to lock current status, such as,
* input/output enable, input/output value, function, drive strength values.
* This function is useful when going into light or deep sleep mode to prevent
* the pin configuration from changing.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_force_hold_enable(int rtcio_num)
{
LP_AON.gpio_hold0.gpio_hold0 |= BIT(rtcio_num + RTCIO_LL_GPIO_NUM_OFFSET);
}
/**
* Disable hold function on an RTC IO pad
*
* @note If disable the pad hold, the status of pad maybe changed in sleep mode.
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
*/
static inline void rtcio_ll_force_hold_disable(int rtcio_num)
{
LP_AON.gpio_hold0.gpio_hold0 &= ~BIT(rtcio_num + RTCIO_LL_GPIO_NUM_OFFSET);
}
/**
* Enable force hold function for all RTC IO pads
*
* Enabling HOLD function will cause the pad to lock current status, such as,
* input/output enable, input/output value, function, drive strength values.
* This function is useful when going into light or deep sleep mode to prevent
* the pin configuration from changing.
*/
static inline void rtcio_ll_force_hold_all(void)
{
PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1;
}
/**
* Disable hold function fon all RTC IO pads
*
* @note If disable the pad hold, the status of pad maybe changed in sleep mode.
*/
static inline void rtcio_ll_force_unhold_all(void)
{
PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1;
}
#ifdef __cplusplus
}
#endif

View File

@@ -44,6 +44,8 @@ extern "C" {
#define GPIO_LL_INTR2_ENA (BIT(3))
#define GPIO_LL_INTR3_ENA (BIT(4))
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR0_SOURCE
/**
* @brief Get the configuration for an IO
*

View File

@@ -32,6 +32,8 @@ extern "C" {
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
/**
* @brief Get the configuration for an IO
*

View File

@@ -33,6 +33,8 @@ extern "C" {
#define GPIO_LL_INTR_ENA (BIT(0))
#define GPIO_LL_NMI_INTR_ENA (BIT(1))
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
/**
* @brief Enable pull-up on GPIO.
*

View File

@@ -129,7 +129,6 @@ extern "C" {
#define GPIO_PAD_PULLUP(num) do{PIN_PULLDWN_DIS(IOMUX_REG_GPIO##num);PIN_PULLUP_EN(IOMUX_REG_GPIO##num);}while(0)
#define GPIO_PAD_PULLDOWN(num) do{PIN_PULLUP_DIS(IOMUX_REG_GPIO##num);PIN_PULLDWN_EN(IOMUX_REG_GPIO##num);}while(0)
#define GPIO_PAD_SET_DRV(num, drv) PIN_SET_DRV(IOMUX_REG_GPIO##num, drv)
#define SPI_HD_GPIO_NUM 20
#define SPI_WP_GPIO_NUM 18

View File

@@ -1,15 +1,11 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/gpio_periph.h"
//TODO: [ESP32H21] IDF-11611
_Static_assert(sizeof(GPIO_PIN_MUX_REG) == SOC_GPIO_PIN_COUNT * sizeof(uint32_t), "Invalid size of GPIO_PIN_MUX_REG");
const uint32_t GPIO_HOLD_MASK[] = {
BIT(0), //GPIO0 // LP_AON_GPIO_HOLD0_REG
BIT(1), //GPIO1
@@ -37,8 +33,6 @@ const uint32_t GPIO_HOLD_MASK[] = {
BIT(23), //GPIO23
BIT(24), //GPIO24
BIT(25), //GPIO25
BIT(26), //GPIO26
BIT(27), //GPIO27
};
_Static_assert(sizeof(GPIO_HOLD_MASK) == SOC_GPIO_PIN_COUNT * sizeof(uint32_t), "Invalid size of GPIO_HOLD_MASK");

View File

@@ -237,7 +237,11 @@ config SOC_GPIO_PORT
config SOC_GPIO_PIN_COUNT
int
default 28
default 26
config SOC_GPIO_SUPPORT_PIN_HYS_FILTER
bool
default y
config SOC_GPIO_SUPPORT_RTC_INDEPENDENT
bool
@@ -249,15 +253,35 @@ config SOC_LP_IO_CLOCK_IS_INDEPENDENT
config SOC_GPIO_IN_RANGE_MAX
int
default 27
default 25
config SOC_GPIO_OUT_RANGE_MAX
int
default 27
default 25
config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK
hex
default 0x000000000FFF807F
default 0x0000000003FFF81F
config SOC_GPIO_SUPPORT_FORCE_HOLD
bool
default y
config SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP
bool
default y
config SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
bool
default y
config SOC_RTCIO_PIN_COUNT
int
default 7
config SOC_RTCIO_HOLD_SUPPORTED
bool
default y
config SOC_DEDIC_GPIO_OUT_CHANNELS_NUM
int

View File

@@ -41,8 +41,6 @@ typedef enum {
GPIO_NUM_23 = 23, /*!< GPIO23, input and output */
GPIO_NUM_24 = 24, /*!< GPIO24, input and output */
GPIO_NUM_25 = 25, /*!< GPIO25, input and output */
GPIO_NUM_26 = 26, /*!< GPIO26, input and output */
GPIO_NUM_27 = 27, /*!< GPIO27, input and output */
GPIO_NUM_MAX,
} gpio_num_t;

View File

@@ -10,10 +10,8 @@
extern "C" {
#endif
//TODO: [ESP32H21] IDF-11611
#define GPIO_MATRIX_CONST_ONE_INPUT (0x20)
#define GPIO_MATRIX_CONST_ZERO_INPUT (0x30)
#define GPIO_MATRIX_INVALID (0x3A)
#ifdef __cplusplus
}

View File

@@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#define RTCIO_GPIO5_CHANNEL 0 //RTCIO_CHANNEL_0
#define RTCIO_CHANNEL_0_GPIO_NUM 5
#define RTCIO_GPIO6_CHANNEL 1 //RTCIO_CHANNEL_1
#define RTCIO_CHANNEL_1_GPIO_NUM 6
#define RTCIO_GPIO7_CHANNEL 2 //RTCIO_CHANNEL_2
#define RTCIO_CHANNEL_2_GPIO_NUM 7
#define RTCIO_GPIO8_CHANNEL 3 //RTCIO_CHANNEL_3
#define RTCIO_CHANNEL_3_GPIO_NUM 8
#define RTCIO_GPIO9_CHANNEL 4 //RTCIO_CHANNEL_4
#define RTCIO_CHANNEL_4_GPIO_NUM 9
#define RTCIO_GPIO10_CHANNEL 5 //RTCIO_CHANNEL_5
#define RTCIO_CHANNEL_5_GPIO_NUM 10
#define RTCIO_GPIO11_CHANNEL 6 //RTCIO_CHANNEL_6
#define RTCIO_CHANNEL_6_GPIO_NUM 11

View File

@@ -188,17 +188,16 @@
/*-------------------------- GPIO CAPS ---------------------------------------*/
// ESP32-H21 has 1 GPIO peripheral
#define SOC_GPIO_PORT 1U
#define SOC_GPIO_PIN_COUNT 28
// #define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 1
// #define SOC_GPIO_FLEX_GLITCH_FILTER_NUM 8
// #define SOC_GPIO_SUPPORT_PIN_HYS_FILTER 1
// #define SOC_GPIO_SUPPORT_PIN_HYS_CTRL_BY_EFUSE 1 // By default, hysteresis enable/disable is controlled by efuse
#define SOC_GPIO_PORT 1U
#define SOC_GPIO_PIN_COUNT 26
// #define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 1
// #define SOC_GPIO_FLEX_GLITCH_FILTER_NUM 8
#define SOC_GPIO_SUPPORT_PIN_HYS_FILTER 1
// GPIO peripheral has the ETM extension
// #define SOC_GPIO_SUPPORT_ETM 1
// Target has no full LP IO subsystem, GPIO7~14 remain LP function (powered by VDD3V3_LP, and can be used as ext1 wakeup pins)
// Target has no full LP IO subsystem, GPIO5~11 remain LP function (powered by VDD3V3_LP, and can be used as ext1 wakeup pins)
// Digital IOs have their own registers to control pullup/down/capability
// However, there is no way to control pullup/down/capability for IOs under LP function since there is no LP_IOMUX registers
#define SOC_GPIO_SUPPORT_RTC_INDEPENDENT (1)
@@ -209,16 +208,18 @@
#define SOC_GPIO_VALID_GPIO_MASK ((1U << SOC_GPIO_PIN_COUNT) - 1)
#define SOC_GPIO_VALID_OUTPUT_GPIO_MASK SOC_GPIO_VALID_GPIO_MASK
#define SOC_GPIO_IN_RANGE_MAX 27
#define SOC_GPIO_OUT_RANGE_MAX 27
#define SOC_GPIO_IN_RANGE_MAX 25
#define SOC_GPIO_OUT_RANGE_MAX 25
// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_0~6. GPIO_NUM_15~27)
#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x000000000FFF807FULL
// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_0~4. GPIO_NUM_12~25)
#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x0000000003FFF81FULL
// Support to force hold all IOs
// #define SOC_GPIO_SUPPORT_FORCE_HOLD (1)
#define SOC_GPIO_SUPPORT_FORCE_HOLD (1)
// LP_IOs and DIG_IOs can be hold during deep sleep and after waking up
#define SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP (1)
// Support to hold a single digital I/O when the digital domain is powered off
// #define SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP (1)
#define SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP (1)
// The Clock Out signal is route to the pin by GPIO matrix
// #define SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX (1)
@@ -228,9 +229,8 @@
/*-------------------------- RTCIO CAPS --------------------------------------*/
/* No dedicated LP_IOMUX subsystem on ESP32-H2. LP functions are still supported
* for hold, wake & 32kHz crystal functions - via LP_AON registers */
// #define SOC_RTCIO_PIN_COUNT (8U)
// #define SOC_RTCIO_HOLD_SUPPORTED (1)
// #define SOC_RTCIO_VALID_RTCIO_MASK (0x7F80)
#define SOC_RTCIO_PIN_COUNT (7U)
#define SOC_RTCIO_HOLD_SUPPORTED (1)
/*-------------------------- Dedicated GPIO CAPS -----------------------------*/
#define SOC_DEDIC_GPIO_OUT_CHANNELS_NUM (8) /*!< 8 outward channels on each CPU core */

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
*/
@@ -352,8 +352,8 @@ typedef struct {
uint32_t reserved_0c8[3];
volatile gpio_pinn_reg_t pinn[30];
uint32_t reserved_14c[98];
volatile gpio_func_in_sel_cfg_reg_t func_in_sel_cfg[128]; //0-128. reserved: 0-6, 17-19, 19-28, 35-40, 42-45, 56-6, 73-77, 82-87, 95-97, 124-128;
uint32_t reserved_4ac[384];
volatile gpio_func_in_sel_cfg_reg_t func_in_sel_cfg[256]; //0-255. reserved: 0-6, 17-19, 19-28, 35-40, 42-45, 56-6, 73-77, 82-87, 95-97, 162-255;
uint32_t reserved_4ac[256];
volatile gpio_funcn_out_sel_cfg_reg_t funcn_out_sel_cfg[30];
uint32_t reserved_b4c[171];
volatile gpio_clock_gate_reg_t clock_gate;

View File

@@ -1,11 +1,16 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc.h"
#ifdef __cplusplus
extern "C" {
#endif
/* The following are the bit fields for PERIPHS_IO_MUX_x_U registers */
/* Output enable in sleep mode */
@@ -98,20 +103,14 @@
#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));
#define PIN_PULLUP_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PU)
#define PIN_PULLUP_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PU)
#define PIN_PULLDWN_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PD)
#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD)
#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC)
#define PIN_FILTER_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FILTER_EN)
#define PIN_FILTER_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FILTER_EN)
#define PIN_HYS_EN_SEL_EFUSE(PIN_NAME) REG_CLR_BIT(PIN_NAME, HYS_SEL)
#define PIN_HYS_EN_SEL_SOFT(PIN_NAME) REG_SET_BIT(PIN_NAME, HYS_SEL)
#define PIN_HYS_SOFT_ENABLE(PIN_NAME) REG_SET_BIT(PIN_NAME, HYS_EN)
#define PIN_HYS_SOFT_DISABLE(PIN_NAME) REG_CLR_BIT(PIN_NAME, HYS_EN)
#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));
#define PIN_PULLUP_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PU)
#define PIN_PULLUP_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PU)
#define PIN_PULLDWN_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PD)
#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD)
#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC)
#define IO_MUX_GPIO0_REG PERIPHS_IO_MUX_U_PAD_MTMS
#define IO_MUX_GPIO1_REG PERIPHS_IO_MUX_U_PAD_MTDO
@@ -140,27 +139,12 @@
#define IO_MUX_GPIO24_REG PERIPHS_IO_MUX_U_PAD_SPICLK
#define IO_MUX_GPIO25_REG PERIPHS_IO_MUX_U_PAD_SPID
#define FUNC_GPIO_GPIO 1
#define PIN_FUNC_GPIO 1
#define GPIO_PAD_PULLUP(num) do{PIN_PULLDWN_DIS(IOMUX_REG_GPIO##num);PIN_PULLUP_EN(IOMUX_REG_GPIO##num);}while(0)
#define GPIO_PAD_PULLDOWN(num) do{PIN_PULLUP_DIS(IOMUX_REG_GPIO##num);PIN_PULLDWN_EN(IOMUX_REG_GPIO##num);}while(0)
#define GPIO_PAD_SET_DRV(num, drv) PIN_SET_DRV(IOMUX_REG_GPIO##num, drv)
#define USB_INT_PHY0_DM_GPIO_NUM 17
#define USB_INT_PHY0_DP_GPIO_NUM 18
#define U0RXD_GPIO_NUM 15
#define U0TXD_GPIO_NUM 16
#define SPI_HD_GPIO_NUM 23
#define SPI_WP_GPIO_NUM 22
#define SPI_CS0_GPIO_NUM 20
#define SPI_CLK_GPIO_NUM 24
#define SPI_D_GPIO_NUM 25
#define SPI_Q_GPIO_NUM 21
#define USB_INT_PHY0_DM_GPIO_NUM 26
#define USB_INT_PHY0_DP_GPIO_NUM 27
#define EXT_OSC_SLOW_GPIO_NUM 13
#define EXT_OSC_SLOW_GPIO_NUM 6
#define MAX_RTC_GPIO_NUM 11 // GPIO5~11 are the pads with LP function
@@ -168,33 +152,7 @@
#define MAX_GPIO_NUM 29
#define HIGH_IO_HOLD_BIT_SHIFT 32
#define GPIO_NUM_IN_INVALID 0x28
#define REG_IO_MUX_BASE DR_REG_IO_MUX_BASE
#define PIN_CTRL (REG_IO_MUX_BASE +0x00)
#define PAD_POWER_SEL BIT(15)
#define PAD_POWER_SEL_V 0x1
#define PAD_POWER_SEL_M BIT(15)
#define PAD_POWER_SEL_S 15
#define PAD_POWER_SWITCH_DELAY 0x7
#define PAD_POWER_SWITCH_DELAY_V 0x7
#define PAD_POWER_SWITCH_DELAY_M (PAD_POWER_SWITCH_DELAY_V << PAD_POWER_SWITCH_DELAY_S)
#define PAD_POWER_SWITCH_DELAY_S 12
#define CLK_OUT3 IO_MUX_CLK_OUT3
#define CLK_OUT3_V IO_MUX_CLK_OUT3_V
#define CLK_OUT3_S IO_MUX_CLK_OUT3_S
#define CLK_OUT3_M IO_MUX_CLK_OUT3_M
#define CLK_OUT2 IO_MUX_CLK_OUT2
#define CLK_OUT2_V IO_MUX_CLK_OUT2_V
#define CLK_OUT2_S IO_MUX_CLK_OUT2_S
#define CLK_OUT2_M IO_MUX_CLK_OUT2_M
#define CLK_OUT1 IO_MUX_CLK_OUT1
#define CLK_OUT1_V IO_MUX_CLK_OUT1_V
#define CLK_OUT1_S IO_MUX_CLK_OUT1_S
#define CLK_OUT1_M IO_MUX_CLK_OUT1_M
// definitions above are inherited from previous version of code, should double check
// definitions below are generated from pin_txt.csv
#define PERIPHS_IO_MUX_U_PAD_MTMS (REG_IO_MUX_BASE + 0x0)
@@ -363,3 +321,7 @@
#define IO_MUX_REG_DATE_M ((IO_MUX_REG_DATE_V)<<(IO_MUX_REG_DATE_S))
#define IO_MUX_REG_DATE_V 0xFFFFFFF
#define IO_MUX_REG_DATE_S 0
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,142 @@
/**
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Group: Configuration Registers */
/** Type of gpio register
* IO MUX configuration register for gpio
*/
typedef union {
struct {
/** mcu_oe : R/W; bitpos: [0]; default: 0;
* Output enable of the pad in sleep mode.
* 1: output enabled.
* 0: output disabled.
*/
uint32_t mcu_oe:1;
/** slp_sel : R/W; bitpos: [1]; default: 0;
* Sleep mode selection of this pad. Set to 1 to put the pad in pad mode.
*/
uint32_t slp_sel:1;
/** mcu_wpd : R/W; bitpos: [2]; default: 0;
* Pull-down enable of the pad in sleep mode.
* 1: internal pull-down enabled.
* 0: internal pull-down disabled.
*/
uint32_t mcu_wpd:1;
/** mcu_wpu : R/W; bitpos: [3]; default: 0;
* Pull-up enable of the pad during sleep mode.
* 1: internal pull-up enabled.
* 0: internal pull-up disabled.
*/
uint32_t mcu_wpu:1;
/** mcu_ie : R/W; bitpos: [4]; default: 0;
* Input enable of the pad during sleep mode.
* 1: input enabled.
* 0: input disabled.
*/
uint32_t mcu_ie:1;
/** mcu_drv : R/W; bitpos: [6:5]; default: 0;
* Select the drive strength of the pad during sleep mode.
* 0: ~5 mA\\
* 1: ~10 mA\\
* 2: ~20 mA\\
* 3: ~40 mA\\
*/
uint32_t mcu_drv:2;
/** fun_wpd : R/W; bitpos: [7]; default: 0;
* Pull-down enable of the pad.
* 1: internal pull-down enabled.
* 0: internal pull-down disabled.
*/
uint32_t fun_wpd:1;
/** fun_wpu : R/W; bitpos: [8]; default: 0;
* Pull-up enable of the pad.
* 1: internal pull-up enabled.
* 0: internal pull-up disabled.
*/
uint32_t fun_wpu:1;
/** fun_ie : R/W; bitpos: [9]; default: 0;
* Input enable of the pad.
* 1: input enabled.
* 0: input disabled.
*/
uint32_t fun_ie:1;
/** fun_drv : R/W; bitpos: [11:10]; default: 2;
* Select the drive strength of the pad.
* 0: ~5 mA\\
* 1: ~10 mA\\
* 2: ~20 mA\\
* 3: ~40 mA\\
*/
uint32_t fun_drv:2;
/** mcu_sel : R/W; bitpos: [14:12]; default: 1;
* Select IO MUX function for this signal.
* 0: Select Function 1.
* 1: Select Function 2. etc.
* ......\\
*/
uint32_t mcu_sel:3;
/** filter_en : R/W; bitpos: [15]; default: 0;
* Enable filter for pin input signals.
* 1: Filter enabled.
* 0: Filter disabled.
*/
uint32_t filter_en:1;
/** hys_en : R/W; bitpos: [16]; default: 0;
* Software enables hysteresis function for the pad.
* 1: Filter enabled.
* 0: Filter disabled.
*/
uint32_t hys_en:1;
/** hys_sel : R/W; bitpos: [17]; default: 0;
* Select enabling signals of the pad from software and efuse hardware.
* 1: Hysteresis enabled.
* 0: Hysteresis disabled.
*/
uint32_t hys_sel:1;
uint32_t reserved_18:14;
};
uint32_t val;
} io_mux_gpio_reg_t;
/** Group: Version Register */
/** Type of date register
* Version control register
*/
typedef union {
struct {
/** reg_date : R/W; bitpos: [27:0]; default: 36770416;
* Version control register
*/
uint32_t reg_date:28;
uint32_t reserved_28:4;
};
uint32_t val;
} io_mux_date_reg_t;
typedef struct {
volatile io_mux_gpio_reg_t gpio[26];
uint32_t reserved_074[101];
volatile io_mux_date_reg_t date;
} io_mux_dev_t;
extern io_mux_dev_t IO_MUX;
#ifndef __cplusplus
_Static_assert(sizeof(io_mux_dev_t) == 0x200, "Invalid size of io_mux_dev_t structure");
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/rtc_io_periph.h"
const int rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
-1,//GPIO0
-1,//GPIO1
-1,//GPIO2
-1,//GPIO3
-1,//GPIO4
RTCIO_GPIO5_CHANNEL,//GPIO5
RTCIO_GPIO6_CHANNEL,//GPIO6
RTCIO_GPIO7_CHANNEL,//GPIO7
RTCIO_GPIO8_CHANNEL,//GPIO8
RTCIO_GPIO9_CHANNEL,//GPIO9
RTCIO_GPIO10_CHANNEL,//GPIO10
RTCIO_GPIO11_CHANNEL,//GPIO11
-1,//GPIO12
-1,//GPIO13
-1,//GPIO14
-1,//GPIO15
-1,//GPIO16
-1,//GPIO17
-1,//GPIO18
-1,//GPIO19
-1,//GPIO20
-1,//GPIO21
-1,//GPIO22
-1,//GPIO23
-1,//GPIO24
-1,//GPIO25
};