diff --git a/components/esp_driver_gpio/test_apps/.build-test-rules.yml b/components/esp_driver_gpio/test_apps/.build-test-rules.yml index bf947b335c1..0b7bec787a2 100644 --- a/components/esp_driver_gpio/test_apps/.build-test-rules.yml +++ b/components/esp_driver_gpio/test_apps/.build-test-rules.yml @@ -5,12 +5,6 @@ components/esp_driver_gpio/test_apps: - esp_driver_gpio - esp_hal_gpio -components/esp_driver_gpio/test_apps/gpio: - disable: - - if: IDF_TARGET in ["esp32s31"] - temporary: true - reason: not support yet # TODO: [ESP32S31] IDF-14780 - components/esp_driver_gpio/test_apps/gpio_extensions: enable: - if: SOC_DEDICATED_GPIO_SUPPORTED == 1 diff --git a/components/esp_driver_gpio/test_apps/gpio/README.md b/components/esp_driver_gpio/test_apps/gpio/README.md index 44f3780f1d6..d76348d52c2 100644 --- a/components/esp_driver_gpio/test_apps/gpio/README.md +++ b/components/esp_driver_gpio/test_apps/gpio/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | diff --git a/components/esp_driver_gpio/test_apps/gpio/main/test_gpio.h b/components/esp_driver_gpio/test_apps/gpio/main/test_gpio.h index 3caa9c2001f..e8e22b0c2f3 100644 --- a/components/esp_driver_gpio/test_apps/gpio/main/test_gpio.h +++ b/components/esp_driver_gpio/test_apps/gpio/main/test_gpio.h @@ -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 */ @@ -46,6 +46,12 @@ extern "C" { #define TEST_GPIO_INPUT_LEVEL_LOW_PIN (1) #define TEST_GPIO_SIGNAL_IDX (SIG_IN_FUNC97_IDX) #define TEST_GPIO_DEEP_SLEEP_HOLD_PIN (25) +#elif CONFIG_IDF_TARGET_ESP32S31 +#define TEST_GPIO_EXT_OUT_IO (2) +#define TEST_GPIO_EXT_IN_IO (3) +#define TEST_GPIO_INPUT_LEVEL_LOW_PIN (1) +#define TEST_GPIO_SIGNAL_IDX (SIG_IN_FUNC251_IDX) +#define TEST_GPIO_DEEP_SLEEP_HOLD_PIN (28) #else #define TEST_GPIO_EXT_OUT_IO (2) #define TEST_GPIO_EXT_IN_IO (3) diff --git a/components/esp_hal_emac/esp32s31/include/hal/emac_ll.h b/components/esp_hal_emac/esp32s31/include/hal/emac_ll.h new file mode 100644 index 00000000000..01cf900517f --- /dev/null +++ b/components/esp_hal_emac/esp32s31/include/hal/emac_ll.h @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +// The LL layer for ESP32S31 GMAC register operations + +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void emac_ll_gpio_init(uint32_t gpio_num) +{ + (void)gpio_num; + // TODO: [ESP32S31] IDF-14730 + // GPIO13-19 are located in the CNNT domain and correspond to GMAC RX functionality. + // When the GMAC peripheral needs to use these pads, additional configuration is required: + // - Set CNNT_IO_MUX_CTRL_REG.CNNT_IO_MUX_GMAC_PAD_PIN_CTRL_DED_SEL to 1 + // - In this case, the pad configuration registers in cnnt_io_mux_reg take effect + // instead of hp_iomux_reg, which requires special handling +} + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_gpio/esp32s31/include/hal/gpio_ll.h b/components/esp_hal_gpio/esp32s31/include/hal/gpio_ll.h index 4c8ad117826..efe5d3814db 100644 --- a/components/esp_hal_gpio/esp32s31/include/hal/gpio_ll.h +++ b/components/esp_hal_gpio/esp32s31/include/hal/gpio_ll.h @@ -12,8 +12,6 @@ // The LL layer for ESP32-S31 GPIO register operations -// TODO: This GPIO LL is not very update to date!!! Needs to check every function carefully! - #pragma once #include @@ -35,6 +33,8 @@ #include "hal/gpio_types.h" #include "hal/misc.h" #include "hal/assert.h" +#include "hal/config.h" +#include "rom/gpio.h" // Get GPIO hardware instance with giving gpio num #define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL) @@ -59,7 +59,19 @@ extern "C" { */ static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config) { - // TODO: [ESP32S31] IDF-14780 + uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32); + uint32_t bit_mask = 1 << bit_shift; + 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 = (((gpio_num < 32) ? hw->enable.val : hw->enable1.val) & bit_mask) >> bit_shift; + io_config->oe_ctrl_by_periph = !(hw->func_out_sel_cfg[gpio_num].oen_sel); + io_config->oe_inv = hw->func_out_sel_cfg[gpio_num].oen_inv_sel; + io_config->od = hw->pin[gpio_num].pad_driver; + 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->func_out_sel_cfg[gpio_num].out_sel; + io_config->slp_sel = IO_MUX.gpio[gpio_num].slp_sel; } /** @@ -70,12 +82,22 @@ 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, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].fun_wpu = 1; } +/** + * @brief Connect a peripheral signal which tagged as output attribute with a GPIO. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param gpio_num GPIO number + * @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level. + * @param out_inv True if the signal output needs to be inverted, otherwise False. + */ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv) { - // TODO: [ESP32S31] IDF-14780 + hw->func_out_sel_cfg[gpio_num].out_sel = signal_idx; + hw->func_out_sel_cfg[gpio_num].out_inv_sel = out_inv; } /** @@ -87,7 +109,16 @@ static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint3 __attribute__((always_inline)) static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value + // USB DP pin is default to PU enabled + // Note that esp32s31 has supported USB_EXCHG_PINS feature. If this efuse is burnt, the gpio pin + // 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) { + USB_SERIAL_JTAG.conf0.pad_pull_override = 1; + USB_SERIAL_JTAG.conf0.dp_pullup = 0; + } + IO_MUX.gpio[gpio_num].fun_wpu = 0; } /** @@ -98,7 +129,7 @@ static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].fun_wpd = 1; } /** @@ -110,7 +141,7 @@ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].fun_wpd = 0; } /** @@ -135,7 +166,7 @@ static inline void gpio_ll_set_intr_type(gpio_dev_t *hw, uint32_t gpio_num, gpio __attribute__((always_inline)) static inline void gpio_ll_get_intr_status(gpio_dev_t *hw, uint32_t core_id, uint32_t *status) { - (void)core_id; // TODO: IDF-7995 There are 4 interrupt sources for GPIO on P4. New feature! Need to fix this function later. + (void)core_id; // TODO: IDF-7995 There are 4 interrupt sources for GPIO on S31. New feature! Need to fix this function later. *status = hw->intr_0.int_0; } @@ -149,7 +180,7 @@ static inline void gpio_ll_get_intr_status(gpio_dev_t *hw, uint32_t core_id, uin __attribute__((always_inline)) static inline void gpio_ll_get_intr_status_high(gpio_dev_t *hw, uint32_t core_id, uint32_t *status) { - (void)core_id; // TODO: IDF-7995 There are 4 interrupt sources for GPIO on P4. New feature! Need to fix this function later. + (void)core_id; // TODO: IDF-7995 There are 4 interrupt sources for GPIO on S31. New feature! Need to fix this function later. *status = hw->intr_01.int_01; } @@ -200,7 +231,7 @@ static inline void gpio_ll_intr_enable_on_core(gpio_dev_t *hw, uint32_t core_id, __attribute__((always_inline)) static inline void gpio_ll_intr_disable(gpio_dev_t *hw, uint32_t gpio_num) { - // hw->pin[gpio_num].int_ena = 0; //disable GPIO intr + hw->pin[gpio_num].int_ena = 0; //disable GPIO intr } /** @@ -212,7 +243,7 @@ static inline void gpio_ll_intr_disable(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num) { - // IO_MUX.gpio[gpio_num].fun_ie = 0; + IO_MUX.gpio[gpio_num].fun_ie = 0; } /** @@ -224,7 +255,7 @@ static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num) { - // IO_MUX.gpio[gpio_num].fun_ie = 1; + IO_MUX.gpio[gpio_num].fun_ie = 1; } /** @@ -235,7 +266,7 @@ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num) { - // IO_MUX.gpio[gpio_num].filter_en = 1; + IO_MUX.gpio[gpio_num].filter_en = 1; } /** @@ -246,7 +277,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) { - // IO_MUX.gpio[gpio_num].filter_en = 0; + IO_MUX.gpio[gpio_num].filter_en = 0; } /** @@ -257,7 +288,12 @@ 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) { - // TODO: [ESP32S31] IDF-14780 + // On ESP32S31, 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 S31. + // 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; } /** @@ -268,7 +304,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) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].hys_sel = 1; + IO_MUX.gpio[gpio_num].hys_en = 0; } /** @@ -335,6 +372,9 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t level) { +#if HAL_CONFIG(GPIO_USE_ROM_API) + rom_gpio_set_output_level(gpio_num, level); +#else if (level) { if (gpio_num < 32) { hw->out_w1ts.val = 1 << gpio_num; @@ -348,6 +388,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t hw->out1_w1tc.val = 1 << (gpio_num - 32); } } +#endif } /** @@ -365,11 +406,15 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t __attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { +#if HAL_CONFIG(GPIO_USE_ROM_API) + return rom_gpio_get_input_level(gpio_num); +#else if (gpio_num < 32) { return (hw->in.in_data_next >> gpio_num) & 0x1; } else { return (hw->in1.in1_data_next >> (gpio_num - 32)) & 0x1; } +#endif } /** @@ -403,7 +448,7 @@ static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t strength) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].fun_drv = strength; } /** @@ -415,14 +460,9 @@ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu */ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t *strength) { - // TODO: [ESP32S31] IDF-14780 + *strength = (gpio_drive_cap_t)(IO_MUX.gpio[gpio_num].fun_drv); } -// On ESP32S31, all digital GPIO pads can be held together during Deep-sleep through PMU.hp_sys[PMU_MODE_HP_SLEEP].syscntl.hp_pad_hold_all = 1 -// However, since the hold register for digital IOs is in TOP domain (HP_SYSTEM.gpio_o_hold_ctrlx), it gets powered down in Deep-sleep. -// Therefore, after waking up from Deep-sleep, the register has been reset, it is not able to hold at that time. -// In all, the users can not achieve the purpose of being hold all the time. So this feature is considered not usable on P4. - /** * @brief Enable gpio pad hold function. * @@ -432,12 +472,12 @@ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu __attribute__((always_inline)) static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num) { - if (gpio_num < 8) { - REG_SET_BIT(LP_SYSTEM_REG_PADCTRL_REG, (0x1 << (gpio_num + 8))); - } else if (gpio_num < 40) { - REG_SET_BIT(LP_SYSTEM_REG_HP_GPIO_O_HOLD_CTRL0_REG, (0x1 << (gpio_num - 8))); + if (gpio_num < SOC_RTCIO_PIN_COUNT) { + REG_SET_BIT(LP_SYSTEM_REG_PADCTRL_REG, (0x1 << (gpio_num + SOC_RTCIO_PIN_COUNT))); + } else if (gpio_num < SOC_RTCIO_PIN_COUNT + 32) { + REG_SET_BIT(LP_SYSTEM_REG_HP_GPIO_O_HOLD_CTRL0_REG, (0x1 << (gpio_num - SOC_RTCIO_PIN_COUNT))); } else { - REG_SET_BIT(LP_SYSTEM_REG_HP_GPIO_O_HOLD_CTRL1_REG, (0x1 << (gpio_num - 40))); + REG_SET_BIT(LP_SYSTEM_REG_HP_GPIO_O_HOLD_CTRL1_REG, (0x1 << (gpio_num - SOC_RTCIO_PIN_COUNT - 32))); } } @@ -450,12 +490,12 @@ static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num) { - if (gpio_num < 8) { - REG_CLR_BIT(LP_SYSTEM_REG_PADCTRL_REG, (0x1 << (gpio_num + 8))); - } else if (gpio_num < 40) { - REG_CLR_BIT(LP_SYSTEM_REG_HP_GPIO_O_HOLD_CTRL0_REG, (0x1 << (gpio_num - 8))); + if (gpio_num < SOC_RTCIO_PIN_COUNT) { + REG_CLR_BIT(LP_SYSTEM_REG_PADCTRL_REG, (0x1 << (gpio_num + SOC_RTCIO_PIN_COUNT))); + } else if (gpio_num < SOC_RTCIO_PIN_COUNT + 32) { + REG_CLR_BIT(LP_SYSTEM_REG_HP_GPIO_O_HOLD_CTRL0_REG, (0x1 << (gpio_num - SOC_RTCIO_PIN_COUNT))); } else { - REG_CLR_BIT(LP_SYSTEM_REG_HP_GPIO_O_HOLD_CTRL1_REG, (0x1 << (gpio_num - 40))); + REG_CLR_BIT(LP_SYSTEM_REG_HP_GPIO_O_HOLD_CTRL1_REG, (0x1 << (gpio_num - SOC_RTCIO_PIN_COUNT - 32))); } } @@ -476,13 +516,17 @@ static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num) { uint64_t bit_mask = 1ULL << gpio_num; if (!(bit_mask & SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK)) { - // GPIO 0-15 + // This function only handles digital IOs. If LP IO is queried here, there is a bug in the upper-level code. + // GPIO 0-7 abort(); } else { - // if (gpio_num < 32 + SOC_RTCIO_PIN_COUNT) { - // // GPIO 16-47 - // return !!(LP_SYSTEM.gpio_o_hold_ctrl0.reg_gpio_0_hold_ctrl0 & (bit_mask >> SOC_RTCIO_PIN_COUNT)); - // } + if (gpio_num < 32 + SOC_RTCIO_PIN_COUNT) { + // GPIO 8-39 + return !!(LP_SYS.hp_gpio_o_hold_ctrl0.hp_gpio_0_hold_ctrl0 & (bit_mask >> SOC_RTCIO_PIN_COUNT)); + } else { + // GPIO 40-62 + return !!(LP_SYS.hp_gpio_o_hold_ctrl1.hp_gpio_0_hold_ctrl1 & (bit_mask >> (32 + SOC_RTCIO_PIN_COUNT))); + } } } @@ -499,6 +543,24 @@ static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix; } +/** + * @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute. + * + * @note There's no limitation on the number of signals that a GPIO can combine with. + * + * @param hw Peripheral GPIO hardware instance address. + * @param signal_idx Peripheral signal index (tagged as input attribute) + * @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal + * `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal + * @param in_inv True if the GPIO input needs to be inverted, otherwise False. + */ +static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv) +{ + hw->func_in_sel_cfg[signal_idx].in_sel = gpio_num; + hw->func_in_sel_cfg[signal_idx].in_inv_sel = in_inv; + gpio_ll_set_input_signal_from(hw, signal_idx, true); +} + /** * @brief Configure the source of output enable signal for the pad (only takes effect if func sel is selected to be GPIO). * @@ -523,7 +585,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) { - // TODO: [ESP32S31] IDF-14780 + // Disable USB Serial JTAG if pin 33 or pin 34 needs to select an IOMUX function + if (gpio_num == USB_INT_PHY0_DM_GPIO_NUM || gpio_num == USB_INT_PHY0_DP_GPIO_NUM) { + USB_SERIAL_JTAG.conf0.usb_pad_enable = 0; + } + IO_MUX.gpio[gpio_num].mcu_sel = func; } /** @@ -570,7 +636,8 @@ static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in static inline void gpio_ll_force_hold_all(void) { // WT flag, it gets self-cleared after the configuration is done - // PMU.imm.pad_hold_all.tie_high_hp_pad_hold_all = 1; + PMU.imm_pad_hold_all.tie_high_hp_pad_hold_all = 1; + PMU.imm_pad_hold_all.tie_high_lp_pad_hold_all = 1; } /** @@ -580,7 +647,8 @@ static inline void gpio_ll_force_hold_all(void) static inline void gpio_ll_force_unhold_all(void) { // WT flag, it gets self-cleared after the configuration is done - // PMU.imm.pad_hold_all.tie_low_hp_pad_hold_all = 1; + PMU.imm_pad_hold_all.tie_low_hp_pad_hold_all = 1; + PMU.imm_pad_hold_all.tie_low_lp_pad_hold_all = 1; } /** @@ -592,7 +660,7 @@ static inline void gpio_ll_force_unhold_all(void) __attribute__((always_inline)) static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].slp_sel = 1; } /** @@ -605,7 +673,7 @@ static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].slp_sel = 0; } /** @@ -617,7 +685,7 @@ static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].mcu_wpu = 0; } /** @@ -629,7 +697,7 @@ static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].mcu_wpu = 1; } /** @@ -641,7 +709,7 @@ static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].mcu_wpd = 1; } /** @@ -653,7 +721,7 @@ static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].mcu_wpd = 0; } /** @@ -665,7 +733,7 @@ static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].mcu_ie = 0; } /** @@ -677,7 +745,7 @@ static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, uint32_t gpio_num __attribute__((always_inline)) static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].mcu_ie = 1; } /** @@ -689,7 +757,7 @@ static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, uint32_t gpio_num) __attribute__((always_inline)) static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].mcu_oe = 0; } /** @@ -701,7 +769,7 @@ static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, uint32_t gpio_nu __attribute__((always_inline)) static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num) { - // TODO: [ESP32S31] IDF-14780 + IO_MUX.gpio[gpio_num].mcu_oe = 1; } #ifdef __cplusplus diff --git a/components/esp_hal_gpio/esp32s31/include/hal/rtc_gpio_caps.h b/components/esp_hal_gpio/esp32s31/include/hal/rtc_gpio_caps.h new file mode 100644 index 00000000000..f797d22e791 --- /dev/null +++ b/components/esp_hal_gpio/esp32s31/include/hal/rtc_gpio_caps.h @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// TODO: [ESP32S31] IDF-14785 +// RTC GPIO capabilities are temporarily bypassed for ESP32-S31 +// This file provides stub definitions to allow the build to succeed. +// Full RTC GPIO capabilities for ESP32-S31 need to be implemented in the future. + +#pragma once + +#define RTC_GPIO_CAPS_GET(_attr) _RTC_GPIO_ ## _attr + +// TODO: [ESP32S31] IDF-14785 diff --git a/components/esp_hal_gpio/esp32s31/include/hal/rtc_io_ll.h b/components/esp_hal_gpio/esp32s31/include/hal/rtc_io_ll.h new file mode 100644 index 00000000000..b7d6b8d1f5e --- /dev/null +++ b/components/esp_hal_gpio/esp32s31/include/hal/rtc_io_ll.h @@ -0,0 +1,506 @@ +/* + * 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/include/hal/readme.md + ******************************************************************************/ + +// TODO: [ESP32S31] IDF-14785 +// RTC IO LL implementation is temporarily bypassed for ESP32-S31 +// This file provides stub function declarations to allow the build to succeed. +// Full RTC IO support for ESP32-S31 needs to be implemented in the future. + +#pragma once + +#include +#include +#include "soc/soc_caps.h" +#include "hal/gpio_types.h" +#include "hal/misc.h" +#include "hal/assert.h" + +#define RTCIO_LL_PIN_FUNC 1 + +#ifdef __cplusplus +extern "C" { +#endif + +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; + +typedef enum { + RTCIO_LL_OUTPUT_NORMAL = 0, /*!< RTCIO output mode is normal. */ + RTCIO_LL_OUTPUT_OD = 0x1, /*!< RTCIO output mode is open-drain. */ +} rtcio_ll_out_mode_t; + +/** + * @brief Select a RTC IOMUX function for the RTC IO + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param func Function to assign to the pin + */ +static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + (void)func; +} + +/** + * @brief Enable/Disable LP_GPIO peripheral clock. + * + * @param enable true to enable the clock / false to disable the clock + */ +static inline void _rtcio_ll_enable_io_clock(bool enable) +{ + // TODO: [ESP32S31] IDF-14785 + (void)enable; +} + +#define rtcio_ll_enable_io_clock(...) do { \ + (void)__DECLARE_RCC_ATOMIC_ENV; \ + _rtcio_ll_enable_io_clock(__VA_ARGS__); \ + } while(0) + +/** + * @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) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + (void)func; +} + +/** + * @brief Enable rtcio output. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_output_enable(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief Disable rtcio output. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_output_disable(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief Set RTCIO output level. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param level 0: output low; ~0: output high. + */ +static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + (void)level; +} + +/** + * @brief Enable rtcio input. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_input_enable(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief Disable rtcio input. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_input_disable(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief Get RTCIO input level. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return 0: input low; ~0: input high. + */ +static inline uint32_t rtcio_ll_get_level(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + return 0; +} + +/** + * @brief Set RTC GPIO pad drive capability + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param strength Drive capability of the pad. Range: 0 ~ 3. + */ +static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strength) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + (void)strength; +} + +/** + * @brief Get RTC GPIO pad drive capability. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Drive capability of the pad. Range: 0 ~ 3. + */ +static inline uint32_t rtcio_ll_get_drive_capability(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + return 0; +} + +/** + * @brief Set RTC GPIO pad output mode. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return mode Output mode. + */ +static inline void rtcio_ll_output_mode_set(int rtcio_num, rtcio_ll_out_mode_t mode) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + (void)mode; +} + +/** + * @brief RTC GPIO pullup enable. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_pullup_enable(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief RTC GPIO pullup disable. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_pullup_disable(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief Get RTC GPIO pad pullup status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pullup of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + return false; +} + +/** + * @brief RTC GPIO pulldown enable. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_pulldown_enable(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief RTC GPIO pulldown disable. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_pulldown_disable(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief Get RTC GPIO pad pulldown status. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return Whether the pulldown of the pad is enabled or not. + */ +static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + return false; +} + +/** + * @brief 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) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief 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) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief 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) +{ + // TODO: [ESP32S31] IDF-14785 +} + +/** + * @brief 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) +{ + // TODO: [ESP32S31] IDF-14785 +} + +/** + * @brief Enable wakeup function and set wakeup type from light sleep or deep sleep for rtcio. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param type Wakeup on high level or low level. + */ +static inline void rtcio_ll_wakeup_enable(int rtcio_num, gpio_int_type_t type) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + (void)type; +} + +/** + * @brief Disable wakeup function from light sleep or deep sleep for rtcio. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_wakeup_disable(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief Enable interrupt function and set interrupt type + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param type Interrupt type on high level or low level. + */ +static inline void rtcio_ll_intr_enable(int rtcio_num, gpio_int_type_t type) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + (void)type; +} + +/** + * @brief Enable rtc io output in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_enable_output_in_sleep(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief Disable rtc io output in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_disable_output_in_sleep(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief Enable rtc io input in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_enable_input_in_sleep(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief Disable rtc io input in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_disable_input_in_sleep(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief Enable rtc io keep another setting in deep sleep. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_enable_sleep_setting(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief Disable rtc io keep another setting in deep sleep. (Default) + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_disable_sleep_setting(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; +} + +/** + * @brief Get the status of whether an IO is used for sleep wake-up. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @return True if the pin is enabled to wake up from deep-sleep + */ +static inline bool rtcio_ll_wakeup_is_enabled(int rtcio_num) +{ + // TODO: [ESP32S31] IDF-14785 +#if SOC_RTCIO_PIN_COUNT > 0 + HAL_ASSERT(rtcio_num >= 0 && rtcio_num < SOC_RTCIO_PIN_COUNT && "io does not support deep sleep wake-up function"); +#endif + (void)rtcio_num; + return false; +} + +/** + * @brief Get the rtc io interrupt status + * + * @return bit 0~7 corresponding to 0 ~ SOC_RTCIO_PIN_COUNT. + */ +static inline uint32_t rtcio_ll_get_interrupt_status(void) +{ + // TODO: [ESP32S31] IDF-14785 + return 0; +} + +/** + * @brief Clear all LP IO pads status + */ +static inline void rtcio_ll_clear_interrupt_status(void) +{ + // TODO: [ESP32S31] IDF-14785 +} + +#if SOC_LP_GPIO_MATRIX_SUPPORTED +/** + * @brief Select signal input from a RTC GPIO + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param signal_idx LP peripheral signal index. + * @param inv True to invert input signal; False then no invert. + */ +static inline void rtcio_ll_matrix_in(int rtcio_num, int signal_idx, bool inv) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + (void)signal_idx; + (void)inv; +} + +/** + * @brief Select signal output to a RTC GPIO + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param signal_idx LP peripheral signal index. + * @param out_inv True to invert output signal; False then no invert. + * @param oen_inv True to invert output enable signal; False then no invert. + */ +static inline void rtcio_ll_matrix_out(int rtcio_num, int signal_idx, bool out_inv, bool oen_inv) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + (void)signal_idx; + (void)out_inv; + (void)oen_inv; +} +#endif // SOC_LP_GPIO_MATRIX_SUPPORTED + +#if SOC_RTCIO_WAKE_SUPPORTED +/** + * @brief Set specific logic level on an RTC IO pin as a ext0 wakeup trigger. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param level Logic level (0: low level trigger, 1: high level trigger) + */ +static inline void rtcio_ll_ext0_set_wakeup_pin(int rtcio_num, int level) +{ + // TODO: [ESP32S31] IDF-14785 + (void)rtcio_num; + (void)level; +} +#endif // SOC_RTCIO_WAKE_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_gpio/esp32s31/rtc_io_periph.c b/components/esp_hal_gpio/esp32s31/rtc_io_periph.c new file mode 100644 index 00000000000..3c47700dd4a --- /dev/null +++ b/components/esp_hal_gpio/esp32s31/rtc_io_periph.c @@ -0,0 +1,90 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// TODO: [ESP32S31] IDF-14785 +// RTC IO peripheral implementation is temporarily bypassed +// This file provides a stub implementation to allow the build to succeed. +// Full RTC IO support for ESP32-S31 needs to be implemented in the future. +// Related: Need to create soc/esp32s31/include/soc/rtc_io_channel.h and +// implement proper RTC IO pin mapping and descriptor tables. + +#include "hal/rtc_io_periph.h" + +const int8_t rtc_io_num_map[SOC_GPIO_PIN_COUNT] = { + -1,//GPIO0 + -1,//GPIO1 + -1,//GPIO2 + -1,//GPIO3 + -1,//GPIO4 + -1,//GPIO5 + -1,//GPIO6 + -1,//GPIO7 + -1,//GPIO8 + -1,//GPIO9 + -1,//GPIO10 + -1,//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 + -1,//GPIO26 + -1,//GPIO27 + -1,//GPIO28 + -1,//GPIO29 + -1,//GPIO30 + -1,//GPIO31 + -1,//GPIO32 + -1,//GPIO33 + -1,//GPIO34 + -1,//GPIO35 + -1,//GPIO36 + -1,//GPIO37 + -1,//GPIO38 + -1,//GPIO39 + -1,//GPIO40 + -1,//GPIO41 + -1,//GPIO42 + -1,//GPIO43 + -1,//GPIO44 + -1,//GPIO45 + -1,//GPIO46 + -1,//GPIO47 + -1,//GPIO48 + -1,//GPIO49 + -1,//GPIO50 + -1,//GPIO51 + -1,//GPIO52 + -1,//GPIO53 + -1,//GPIO54 + -1,//GPIO55 + -1,//GPIO56 + -1,//GPIO57 + -1,//GPIO58 + -1,//GPIO59 + -1,//GPIO60 + -1,//GPIO61 +}; + +// TODO: [ESP32S31] IDF-14785 +#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED +// This requires soc/esp32s31/include/soc/rtc_io_channel.h and +// soc/esp32s31/include/soc/rtc_io_reg.h to be created first +// Currently providing empty array as placeholder - all fields will be 0 +const rtc_io_desc_t rtc_io_desc[SOC_RTCIO_PIN_COUNT] = { + // TODO: Initialize 8 entries (SOC_RTCIO_PIN_COUNT = 8) with proper register addresses + // and bit masks once rtc_io_channel.h and rtc_io_reg.h are available +}; +#endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED diff --git a/components/esp_hw_support/port/esp32c5/io_mux.c b/components/esp_hw_support/port/esp32c5/io_mux.c index aaa18386138..d1410a5e396 100644 --- a/components/esp_hw_support/port/esp32c5/io_mux.c +++ b/components/esp_hw_support/port/esp32c5/io_mux.c @@ -5,7 +5,6 @@ */ #include "sdkconfig.h" -#include "freertos/FreeRTOS.h" #include "esp_private/esp_clk_tree_common.h" #include "esp_private/io_mux.h" #include "esp_private/periph_ctrl.h" @@ -15,7 +14,7 @@ #define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() -static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; +DEFINE_CRIT_SECTION_LOCK_STATIC(s_io_mux_spinlock); 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) #if CONFIG_ULP_COPROC_ENABLED @@ -29,7 +28,7 @@ static rtc_io_status_t s_rtc_io_status = { 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 + // check if the IO MUX has been set to another clock source esp_os_enter_critical(&s_io_mux_spinlock); if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { clk_conflict = true; diff --git a/components/esp_hw_support/port/esp32c6/io_mux.c b/components/esp_hw_support/port/esp32c6/io_mux.c index 1b559a1488b..e6352f8d9ba 100644 --- a/components/esp_hw_support/port/esp32c6/io_mux.c +++ b/components/esp_hw_support/port/esp32c6/io_mux.c @@ -6,7 +6,6 @@ #include "sdkconfig.h" #include "esp_attr.h" -#include "freertos/FreeRTOS.h" #include "esp_private/io_mux.h" #include "esp_private/periph_ctrl.h" #include "esp_private/critical_section.h" @@ -15,7 +14,7 @@ #define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() -static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; +DEFINE_CRIT_SECTION_LOCK_STATIC(s_io_mux_spinlock); 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) #if CONFIG_ULP_COPROC_ENABLED @@ -29,7 +28,7 @@ static rtc_io_status_t s_rtc_io_status = { 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 + // check if the IO MUX has been set to another clock source esp_os_enter_critical(&s_io_mux_spinlock); if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { clk_conflict = true; diff --git a/components/esp_hw_support/port/esp32c61/io_mux.c b/components/esp_hw_support/port/esp32c61/io_mux.c index dc3e4bea8dd..058cf4cf52b 100644 --- a/components/esp_hw_support/port/esp32c61/io_mux.c +++ b/components/esp_hw_support/port/esp32c61/io_mux.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "freertos/FreeRTOS.h" #include "esp_private/io_mux.h" #include "esp_private/periph_ctrl.h" #include "esp_private/critical_section.h" @@ -13,7 +12,7 @@ #define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() -static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; +DEFINE_CRIT_SECTION_LOCK_STATIC(s_io_mux_spinlock); 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 rtc_io_status_t s_rtc_io_status = { @@ -24,7 +23,7 @@ static rtc_io_status_t s_rtc_io_status = { 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 + // check if the IO MUX has been set to another clock source esp_os_enter_critical(&s_io_mux_spinlock); if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { clk_conflict = true; diff --git a/components/esp_hw_support/port/esp32h2/io_mux.c b/components/esp_hw_support/port/esp32h2/io_mux.c index 1a2aee3da20..255442aaf0c 100644 --- a/components/esp_hw_support/port/esp32h2/io_mux.c +++ b/components/esp_hw_support/port/esp32h2/io_mux.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "freertos/FreeRTOS.h" #include "esp_private/io_mux.h" #include "esp_private/periph_ctrl.h" #include "esp_private/critical_section.h" @@ -13,7 +12,7 @@ #define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() -static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; +DEFINE_CRIT_SECTION_LOCK_STATIC(s_io_mux_spinlock); 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 rtc_io_status_t s_rtc_io_status = { @@ -24,7 +23,7 @@ static rtc_io_status_t s_rtc_io_status = { 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 + // check if the IO MUX has been set to another clock source esp_os_enter_critical(&s_io_mux_spinlock); if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { clk_conflict = true; diff --git a/components/esp_hw_support/port/esp32h21/io_mux.c b/components/esp_hw_support/port/esp32h21/io_mux.c index 445868f941b..5a6b68890e1 100644 --- a/components/esp_hw_support/port/esp32h21/io_mux.c +++ b/components/esp_hw_support/port/esp32h21/io_mux.c @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "freertos/FreeRTOS.h" #include "esp_private/io_mux.h" #include "esp_private/periph_ctrl.h" #include "esp_private/critical_section.h" @@ -14,7 +13,7 @@ #define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() -static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; +DEFINE_CRIT_SECTION_LOCK_STATIC(s_io_mux_spinlock); 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 rtc_io_status_t s_rtc_io_status = { @@ -25,7 +24,7 @@ static rtc_io_status_t s_rtc_io_status = { 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 + // check if the IO MUX has been set to another clock source esp_os_enter_critical(&s_io_mux_spinlock); if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { clk_conflict = true; diff --git a/components/esp_hw_support/port/esp32h4/io_mux.c b/components/esp_hw_support/port/esp32h4/io_mux.c index f2c239a7e00..5f02ac37de4 100644 --- a/components/esp_hw_support/port/esp32h4/io_mux.c +++ b/components/esp_hw_support/port/esp32h4/io_mux.c @@ -5,7 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "freertos/FreeRTOS.h" #include "esp_private/io_mux.h" #include "esp_private/periph_ctrl.h" #include "esp_private/critical_section.h" @@ -14,7 +13,7 @@ #define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() -static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; +DEFINE_CRIT_SECTION_LOCK_STATIC(s_io_mux_spinlock); 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 rtc_io_status_t s_rtc_io_status = { @@ -25,7 +24,7 @@ static rtc_io_status_t s_rtc_io_status = { 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 + // check if the IO MUX has been set to another clock source esp_os_enter_critical(&s_io_mux_spinlock); if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { clk_conflict = true; diff --git a/components/esp_hw_support/port/esp32p4/io_mux.c b/components/esp_hw_support/port/esp32p4/io_mux.c index 17e9daa442f..12e6b4ae661 100644 --- a/components/esp_hw_support/port/esp32p4/io_mux.c +++ b/components/esp_hw_support/port/esp32p4/io_mux.c @@ -7,7 +7,6 @@ #include "sdkconfig.h" #include "esp_attr.h" #include "esp_check.h" -#include "freertos/FreeRTOS.h" #include "esp_private/esp_clk_tree_common.h" #include "esp_private/io_mux.h" #include "esp_private/periph_ctrl.h" @@ -18,7 +17,7 @@ #define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() -static __attribute__((unused)) portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; +DEFINE_CRIT_SECTION_LOCK_STATIC(s_io_mux_spinlock); 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) #if CONFIG_ULP_COPROC_ENABLED @@ -32,7 +31,7 @@ static rtc_io_status_t s_rtc_io_status = { 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 + // check if the IO MUX has been set to another clock source esp_os_enter_critical(&s_io_mux_spinlock); if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) { clk_conflict = true; diff --git a/components/esp_hw_support/port/esp32s2/io_mux.c b/components/esp_hw_support/port/esp32s2/io_mux.c index 7180ed507f3..895f009bfb5 100644 --- a/components/esp_hw_support/port/esp32s2/io_mux.c +++ b/components/esp_hw_support/port/esp32s2/io_mux.c @@ -6,7 +6,6 @@ #include "sdkconfig.h" #include "esp_attr.h" -#include "freertos/FreeRTOS.h" #include "esp_private/io_mux.h" #include "esp_private/critical_section.h" #include "hal/rtc_io_ll.h" @@ -23,7 +22,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) } extern portMUX_TYPE rtc_spinlock; -static portMUX_TYPE __attribute__((unused)) s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; +DEFINE_CRIT_SECTION_LOCK_STATIC(s_io_mux_spinlock); static rtc_io_status_t s_rtc_io_status = { .rtc_io_enabled_cnt = { 0 }, diff --git a/components/esp_hw_support/port/esp32s3/io_mux.c b/components/esp_hw_support/port/esp32s3/io_mux.c index 40eab9bba8b..895f009bfb5 100644 --- a/components/esp_hw_support/port/esp32s3/io_mux.c +++ b/components/esp_hw_support/port/esp32s3/io_mux.c @@ -6,7 +6,6 @@ #include "sdkconfig.h" #include "esp_attr.h" -#include "freertos/FreeRTOS.h" #include "esp_private/io_mux.h" #include "esp_private/critical_section.h" #include "hal/rtc_io_ll.h" @@ -23,7 +22,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) } extern portMUX_TYPE rtc_spinlock; -static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED; +DEFINE_CRIT_SECTION_LOCK_STATIC(s_io_mux_spinlock); static rtc_io_status_t s_rtc_io_status = { .rtc_io_enabled_cnt = { 0 }, diff --git a/components/esp_hw_support/port/esp32s31/io_mux.c b/components/esp_hw_support/port/esp32s31/io_mux.c index a7c43e70b42..00de979a012 100644 --- a/components/esp_hw_support/port/esp32s31/io_mux.c +++ b/components/esp_hw_support/port/esp32s31/io_mux.c @@ -4,4 +4,88 @@ * SPDX-License-Identifier: Apache-2.0 */ -// TODO: [ESP32S31] IDF-14780 +#include "sdkconfig.h" +#include "esp_attr.h" +#include "esp_check.h" +#include "esp_private/esp_clk_tree_common.h" +#include "esp_private/io_mux.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/critical_section.h" +#include "hal/gpio_ll.h" +#include "hal/rtc_io_ll.h" +#include "soc/soc_caps.h" + +#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC() + +DEFINE_CRIT_SECTION_LOCK_STATIC(s_io_mux_spinlock); +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) + +#if CONFIG_ULP_COPROC_ENABLED +RTC_DATA_ATTR +#endif +static rtc_io_status_t s_rtc_io_status = { + .rtc_io_enabled_cnt = { 0 }, + .rtc_io_using_mask = 0 +}; + +esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) +{ + bool clk_conflict = false; + // check if the IO MUX has been set to another clock source + esp_os_enter_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; + } + esp_os_exit_critical(&s_io_mux_spinlock); + + if (clk_conflict) { + return ESP_ERR_INVALID_STATE; + } + + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true)); + PERIPH_RCC_ATOMIC() { + 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) +{ + assert((gpio_num != GPIO_NUM_NC) && (gpio_num <= MAX_RTC_GPIO_NUM) && "RTCIO number error"); + esp_os_enter_critical(&s_io_mux_spinlock); + if (enable) { + if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { + s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num); + } + s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]++; + } else if (!enable && (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] > 0)) { + s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]--; + if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) { + s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num); + } + } + RTCIO_RCC_ATOMIC() { + if (s_rtc_io_status.rtc_io_using_mask == 0) { + rtcio_ll_enable_io_clock(false); + } else { + rtcio_ll_enable_io_clock(true); + } + } + esp_os_exit_critical(&s_io_mux_spinlock); +} + +void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num) +{ + assert((gpio_num != GPIO_NUM_NC) && (gpio_num <= MAX_RTC_GPIO_NUM) && "RTCIO number error"); + esp_os_enter_critical(&s_io_mux_spinlock); + s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0; + s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num); + if (s_rtc_io_status.rtc_io_using_mask == 0) { + RTCIO_RCC_ATOMIC() { + rtcio_ll_enable_io_clock(false); + } + } + esp_os_exit_critical(&s_io_mux_spinlock); +} diff --git a/components/esp_rom/esp32s31/include/esp32s31/rom/gpio.h b/components/esp_rom/esp32s31/include/esp32s31/rom/gpio.h index 8e94126256e..2b1f0d16825 100644 --- a/components/esp_rom/esp32s31/include/esp32s31/rom/gpio.h +++ b/components/esp_rom/esp32s31/include/esp32s31/rom/gpio.h @@ -26,13 +26,6 @@ extern "C" { #define GPIO_REG_READ(reg) READ_PERI_REG(reg) #define GPIO_REG_WRITE(reg, val) WRITE_PERI_REG(reg, val) -#define GPIO_FUNC_ZERO 0 -#define GPIO_FUNC_GPIO 1 - -#define GPIO_OUTPUT_SET(gpio_no, bit_value) rom_gpio_set_output_level(gpio_no, bit_value) -#define GPIO_DIS_OUTPUT(gpio_no) rom_gpio_output_disable(gpio_no) -#define GPIO_INPUT_GET(gpio_no) rom_gpio_get_input_level(gpio_no) - /** * @brief Set GPIO output level * diff --git a/components/soc/esp32s31/gpio_periph.c b/components/soc/esp32s31/gpio_periph.c index ee98eb2273d..5a248ea3396 100644 --- a/components/soc/esp32s31/gpio_periph.c +++ b/components/soc/esp32s31/gpio_periph.c @@ -7,133 +7,70 @@ #include "soc/gpio_periph.h" #include "soc/io_mux_reg.h" #include "esp_assert.h" -#include "soc/io_mux_reg.h" -const uint32_t GPIO_PIN_MUX_REG[] = { - IO_MUX_GPIO0_REG, - IO_MUX_GPIO1_REG, - IO_MUX_GPIO2_REG, - IO_MUX_GPIO3_REG, - IO_MUX_GPIO4_REG, - IO_MUX_GPIO5_REG, - IO_MUX_GPIO6_REG, - IO_MUX_GPIO7_REG, - IO_MUX_GPIO8_REG, - IO_MUX_GPIO9_REG, - IO_MUX_GPIO10_REG, - IO_MUX_GPIO11_REG, - IO_MUX_GPIO12_REG, - IO_MUX_GPIO13_REG, - IO_MUX_GPIO14_REG, - IO_MUX_GPIO15_REG, - IO_MUX_GPIO16_REG, - IO_MUX_GPIO17_REG, - IO_MUX_GPIO18_REG, - IO_MUX_GPIO19_REG, - IO_MUX_GPIO20_REG, - IO_MUX_GPIO21_REG, - IO_MUX_GPIO22_REG, - IO_MUX_GPIO23_REG, - IO_MUX_GPIO24_REG, - IO_MUX_GPIO25_REG, - IO_MUX_GPIO26_REG, - IO_MUX_GPIO27_REG, - IO_MUX_GPIO28_REG, - IO_MUX_GPIO29_REG, - IO_MUX_GPIO30_REG, - IO_MUX_GPIO31_REG, - IO_MUX_GPIO32_REG, - IO_MUX_GPIO33_REG, - IO_MUX_GPIO34_REG, - IO_MUX_GPIO35_REG, - IO_MUX_GPIO36_REG, - IO_MUX_GPIO37_REG, - IO_MUX_GPIO38_REG, - IO_MUX_GPIO39_REG, - IO_MUX_GPIO40_REG, - IO_MUX_GPIO41_REG, - IO_MUX_GPIO42_REG, - IO_MUX_GPIO43_REG, - IO_MUX_GPIO44_REG, - IO_MUX_GPIO45_REG, - IO_MUX_GPIO46_REG, - IO_MUX_GPIO47_REG, - IO_MUX_GPIO48_REG, - IO_MUX_GPIO49_REG, - IO_MUX_GPIO50_REG, - IO_MUX_GPIO51_REG, - IO_MUX_GPIO52_REG, - IO_MUX_GPIO53_REG, - IO_MUX_GPIO54_REG, - IO_MUX_GPIO55_REG, - IO_MUX_GPIO56_REG, - IO_MUX_GPIO57_REG, - IO_MUX_GPIO58_REG, - IO_MUX_GPIO59_REG, - IO_MUX_GPIO60_REG, - IO_MUX_GPIO61_REG, - IO_MUX_GPIO62_REG, -}; - -ESP_STATIC_ASSERT(sizeof(GPIO_PIN_MUX_REG) == SOC_GPIO_PIN_COUNT * sizeof(uint32_t), "Invalid size of GPIO_PIN_MUX_REG"); - -// CHECK HOLD MASK IDF-14780 const uint32_t GPIO_HOLD_MASK[] = { - BIT(0), //GPIO0 - BIT(1), //GPIO1 - BIT(2), //GPIO2 - BIT(3), //GPIO3 - BIT(4), //GPIO4 - BIT(5), //GPIO5 - BIT(6), //GPIO6 - BIT(7), //GPIO7 - BIT(8), //GPIO8 - BIT(9), //GPIO9 - BIT(10), //GPIO10 - BIT(11), //GPIO11 - BIT(12), //GPIO12 - BIT(13), //GPIO13 - BIT(14), //GPIO14 - BIT(15), //GPIO15 - BIT(0), //GPIO16 - BIT(1), //GPIO17 - BIT(2), //GPIO18 - BIT(3), //GPIO19 - BIT(4), //GPIO20 - BIT(5), //GPIO21 - BIT(6), //GPIO22 - BIT(7), //GPIO23 - BIT(8), //GPIO24 - BIT(9), //GPIO25 - BIT(10), //GPIO26 - BIT(11), //GPIO27 - BIT(12), //GPIO28 - BIT(13), //GPIO29 - BIT(14), //GPIO30 - BIT(15), //GPIO31 - BIT(16), //GPIO32 - BIT(17), //GPIO33 - BIT(18), //GPIO34 - BIT(19), //GPIO35 - BIT(20), //GPIO36 - BIT(21), //GPIO37 - BIT(22), //GPIO38 - BIT(23), //GPIO39 - BIT(24), //GPIO40 - BIT(25), //GPIO41 - BIT(26), //GPIO42 - BIT(27), //GPIO43 - BIT(28), //GPIO44 - BIT(29), //GPIO45 - BIT(30), //GPIO46 - BIT(31), //GPIO47 - BIT(0), //GPIO48 - BIT(1), //GPIO49 - BIT(2), //GPIO50 - BIT(3), //GPIO51 - BIT(4), //GPIO52 - BIT(5), //GPIO53 - BIT(6), //GPIO54 + BIT(8), //GPIO0, LP_SYSTEM_REG_PADCTRL_REG[8] + BIT(9), //GPIO1 + BIT(10), //GPIO2 + BIT(11), //GPIO3 + BIT(12), //GPIO4 + BIT(13), //GPIO5 + BIT(14), //GPIO6 + BIT(15), //GPIO7 + BIT(0), //GPIO8, LP_SYSTEM_REG_HP_GPIO_O_HOLD_CTRL0_REG[0] + BIT(1), //GPIO9 + BIT(2), //GPIO10 + BIT(3), //GPIO11 + BIT(4), //GPIO12 + BIT(5), //GPIO13 + BIT(6), //GPIO14 + BIT(7), //GPIO15 + BIT(8), //GPIO16 + BIT(9), //GPIO17 + BIT(10), //GPIO18 + BIT(11), //GPIO19 + BIT(12), //GPIO20 + BIT(13), //GPIO21 + BIT(14), //GPIO22 + BIT(15), //GPIO23 + BIT(16), //GPIO24 + BIT(17), //GPIO25 + BIT(18), //GPIO26 + BIT(19), //GPIO27 + BIT(20), //GPIO28 + 0, //GPIO29 (Not bonded/Dummy) + BIT(22), //GPIO30 + BIT(23), //GPIO31 + BIT(24), //GPIO32 + BIT(25), //GPIO33 + BIT(26), //GPIO34 + BIT(27), //GPIO35 + BIT(28), //GPIO36 + BIT(29), //GPIO37 + BIT(30), //GPIO38 + BIT(31), //GPIO39 + BIT(0), //GPIO40, LP_SYSTEM_REG_HP_GPIO_O_HOLD_CTRL1_REG[0] + 0, //GPIO41 (Not bonded/Dummy) + BIT(2), //GPIO42 + BIT(3), //GPIO43 + BIT(4), //GPIO44 + BIT(5), //GPIO45 + BIT(6), //GPIO46 + BIT(7), //GPIO47 + BIT(8), //GPIO48 + BIT(9), //GPIO49 + BIT(10), //GPIO50 + BIT(11), //GPIO51 + BIT(12), //GPIO52 + BIT(13), //GPIO53 + BIT(14), //GPIO54 + BIT(15), //GPIO55 + BIT(16), //GPIO56 + BIT(17), //GPIO57 + BIT(18), //GPIO58 + BIT(19), //GPIO59 + BIT(20), //GPIO60 + BIT(21), //GPIO61 }; ESP_STATIC_ASSERT(sizeof(GPIO_HOLD_MASK) == SOC_GPIO_PIN_COUNT * sizeof(uint32_t), "Invalid size of GPIO_HOLD_MASK"); diff --git a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in index 161f50ede5b..da34000e54a 100644 --- a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in @@ -141,16 +141,12 @@ config SOC_GPIO_PORT config SOC_GPIO_PIN_COUNT int - default 63 + default 62 config SOC_GPIO_SUPPORT_PIN_HYS_FILTER bool default y -config SOC_GPIO_SUPPORT_RTC_INDEPENDENT - bool - default y - config SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP bool default y @@ -163,17 +159,13 @@ config SOC_LP_IO_CLOCK_IS_INDEPENDENT bool default y -config SOC_GPIO_VALID_GPIO_MASK - hex - default 0x7FFFFFFFFFFFFFFF - config SOC_GPIO_IN_RANGE_MAX int - default 62 + default 61 config SOC_GPIO_OUT_RANGE_MAX int - default 62 + default 61 config SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK int @@ -183,17 +175,17 @@ config SOC_GPIO_DEEP_SLEEP_WAKE_SUPPORTED_PIN_CNT int default 8 +config SOC_GPIO_SUPPORT_FORCE_HOLD + bool + default y + config SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP bool default y -config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK - hex - default 0x7FFFFFFFFFFFFF00 - -config SOC_GPIO_SUPPORT_FORCE_HOLD - bool - default y +config SOC_RTCIO_PIN_COUNT + int + default 8 config SOC_MMU_PERIPH_NUM int diff --git a/components/soc/esp32s31/include/soc/gpio_num.h b/components/soc/esp32s31/include/soc/gpio_num.h index c71b29fe53f..f9b54be07a2 100644 --- a/components/soc/esp32s31/include/soc/gpio_num.h +++ b/components/soc/esp32s31/include/soc/gpio_num.h @@ -44,7 +44,6 @@ typedef enum { GPIO_NUM_26 = 26, /*!< GPIO26, input and output */ GPIO_NUM_27 = 27, /*!< GPIO27, input and output */ GPIO_NUM_28 = 28, /*!< GPIO28, input and output */ - GPIO_NUM_29 = 29, /*!< GPIO29, input and output */ GPIO_NUM_30 = 30, /*!< GPIO30, input and output */ GPIO_NUM_31 = 31, /*!< GPIO31, input and output */ GPIO_NUM_32 = 32, /*!< GPIO32, input and output */ @@ -56,7 +55,6 @@ typedef enum { GPIO_NUM_38 = 38, /*!< GPIO38, input and output */ GPIO_NUM_39 = 39, /*!< GPIO39, input and output */ GPIO_NUM_40 = 40, /*!< GPIO40, input and output */ - GPIO_NUM_41 = 41, /*!< GPIO41, input and output */ GPIO_NUM_42 = 42, /*!< GPIO42, input and output */ GPIO_NUM_43 = 43, /*!< GPIO43, input and output */ GPIO_NUM_44 = 44, /*!< GPIO44, input and output */ @@ -77,7 +75,6 @@ typedef enum { GPIO_NUM_59 = 59, /*!< GPIO59, input and output */ GPIO_NUM_60 = 60, /*!< GPIO60, input and output */ GPIO_NUM_61 = 61, /*!< GPIO61, input and output */ - GPIO_NUM_62 = 62, /*!< GPIO62, input and output */ GPIO_NUM_MAX, } gpio_num_t; diff --git a/components/soc/esp32s31/include/soc/gpio_pins.h b/components/soc/esp32s31/include/soc/gpio_pins.h index 1cae9027e3d..c09d3115887 100644 --- a/components/soc/esp32s31/include/soc/gpio_pins.h +++ b/components/soc/esp32s31/include/soc/gpio_pins.h @@ -10,10 +10,11 @@ extern "C" { #endif -// TODO: to be checked IDF-14780 - -#define GPIO_MATRIX_CONST_ONE_INPUT (0x3F) -#define GPIO_MATRIX_CONST_ZERO_INPUT (0x3E) +// For newer chips, the highest 2 bits of GPIO_FUNCn_IN_SEL determine the behavior: +// - If the highest bit is 1 and the second highest bit is 0, it means const 1. +// - If the highest bit is 1 and the second highest bit is 1, it means const 0. +#define GPIO_MATRIX_CONST_ONE_INPUT (0x80) +#define GPIO_MATRIX_CONST_ZERO_INPUT (0xC0) #ifdef __cplusplus } diff --git a/components/soc/esp32s31/include/soc/soc_caps.h b/components/soc/esp32s31/include/soc/soc_caps.h index 8589f6bae1d..7ea8cc9fb68 100644 --- a/components/soc/esp32s31/include/soc/soc_caps.h +++ b/components/soc/esp32s31/include/soc/soc_caps.h @@ -141,37 +141,44 @@ #define SOC_SIMD_PREFERRED_DATA_ALIGNMENT 16 // The preferred data alignment accepted by the SIMD instructions, in bytes /*-------------------------- GPIO CAPS ---------------------------------------*/ -// TODO: [ESP32S31] IDF-14780 // ESP32-S31 has 1 GPIO peripheral #define SOC_GPIO_PORT 1U -#define SOC_GPIO_PIN_COUNT 63 +#define SOC_GPIO_PIN_COUNT 62 +// #define SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER 1 // TODO: [ESP32S31] IDF-14781 +// #define SOC_GPIO_FLEX_GLITCH_FILTER_NUM 8 // TODO: [ESP32S31] IDF-14781 #define SOC_GPIO_SUPPORT_PIN_HYS_FILTER 1 -// Target has the full LP IO subsystem -#define SOC_GPIO_SUPPORT_RTC_INDEPENDENT (1) -// GPIO0~15 on ESP32S31 can support chip deep sleep wakeup +// GPIO peripheral has the ETM extension +// #define SOC_GPIO_SUPPORT_ETM 1 // TODO: [ESP32S31] IDF-14786 +// #define SOC_GPIO_ETM_EVENTS_PER_GROUP 8 // TODO: [ESP32S31] IDF-14786 +// #define SOC_GPIO_ETM_TASKS_PER_GROUP 8 // TODO: [ESP32S31] IDF-14786 + +// GPIO0~7 on ESP32S31 can support chip deep sleep wakeup #define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP (1) #define SOC_LP_IO_HAS_INDEPENDENT_WAKEUP_SOURCE (1) // LP IO peripherals have independent clock gating to manage #define SOC_LP_IO_CLOCK_IS_INDEPENDENT (1) -#define SOC_GPIO_VALID_GPIO_MASK (0x7FFFFFFFFFFFFFFF) +#define SOC_GPIO_VALID_GPIO_MASK (((1ULL << SOC_GPIO_PIN_COUNT) - 1) & ~(0ULL | BIT29 | BIT41)) #define SOC_GPIO_VALID_OUTPUT_GPIO_MASK SOC_GPIO_VALID_GPIO_MASK -#define SOC_GPIO_IN_RANGE_MAX 62 -#define SOC_GPIO_OUT_RANGE_MAX 62 +#define SOC_GPIO_IN_RANGE_MAX 61 +#define SOC_GPIO_OUT_RANGE_MAX 61 #define SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK (0ULL | 0xFF) #define SOC_GPIO_DEEP_SLEEP_WAKE_SUPPORTED_PIN_CNT (8) -#define SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP (1) - -// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_16~GPIO_NUM_62) -#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x7FFFFFFFFFFFFF00ULL +// digital I/O pad powered by VDD3V3_CPU or VDD_SPI(GPIO_NUM_8~GPIO_NUM_61, excluding GPIO29/41 which are not bonded) +#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK (SOC_GPIO_VALID_GPIO_MASK & ~((1ULL << SOC_RTCIO_PIN_COUNT) - 1)) // Support to force hold all IOs #define SOC_GPIO_SUPPORT_FORCE_HOLD (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) + +/*-------------------------- RTCIO CAPS --------------------------------------*/ +#define SOC_RTCIO_PIN_COUNT 8 /*-------------------------- MMU CAPS ----------------------------------------*/ // TODO: [ESP32S31] IDF-14669 diff --git a/components/soc/esp32s31/register/soc/cnnt_io_mux_struct.h b/components/soc/esp32s31/register/soc/cnnt_io_mux_struct.h index 626f78322e6..7305ad4ae3e 100644 --- a/components/soc/esp32s31/register/soc/cnnt_io_mux_struct.h +++ b/components/soc/esp32s31/register/soc/cnnt_io_mux_struct.h @@ -1169,6 +1169,7 @@ typedef struct { volatile cnnt_io_mux_date_reg_t date; } cnnt_io_mux_dev_t; +extern cnnt_io_mux_dev_t CNNT_PAD_CTRL; #ifndef __cplusplus _Static_assert(sizeof(cnnt_io_mux_dev_t) == 0x400, "Invalid size of cnnt_io_mux_dev_t structure"); diff --git a/components/soc/esp32s31/register/soc/gpio_struct.h b/components/soc/esp32s31/register/soc/gpio_struct.h index ed8eebdbd47..647e64f4ad8 100644 --- a/components/soc/esp32s31/register/soc/gpio_struct.h +++ b/components/soc/esp32s31/register/soc/gpio_struct.h @@ -975,8 +975,8 @@ typedef union { typedef union { struct { /** in_sel : R/W; bitpos: [7:0]; default: 63; - * set this value: s=0-56: connect GPIO[s] to this port. s=0x3F: set this port always - * high level. s=0x3E: set this port always low level. + * set this value: s=0-56: connect GPIO[s] to this port. s=0x80: set this port always + * high level. s=0xC0: set this port always low level. */ uint32_t in_sel:8; /** in_inv_sel : R/W; bitpos: [8]; default: 0; diff --git a/components/soc/esp32s31/register/soc/io_mux_reg.h b/components/soc/esp32s31/register/soc/io_mux_reg.h index 078a3d68724..1eecf95009c 100644 --- a/components/soc/esp32s31/register/soc/io_mux_reg.h +++ b/components/soc/esp32s31/register/soc/io_mux_reg.h @@ -137,12 +137,12 @@ #define IO_MUX_GPIO61_REG PERIPHS_IO_MUX_U_GPIO61 #define IO_MUX_GPIO62_REG PERIPHS_IO_MUX_U_GPIO62 -#define FUNC_GPIO_GPIO 1 #define PIN_FUNC_GPIO 1 #define MAX_RTC_GPIO_NUM 7 -#define MAX_PAD_GPIO_NUM 62 +#define USB_INT_PHY0_DM_GPIO_NUM 33 +#define USB_INT_PHY0_DP_GPIO_NUM 34 #define REG_IO_MUX_BASE DR_REG_IO_MUX_BASE diff --git a/components/soc/esp32s31/register/soc/io_mux_struct.h b/components/soc/esp32s31/register/soc/io_mux_struct.h index 878f1c68bbf..010ec51aa14 100644 --- a/components/soc/esp32s31/register/soc/io_mux_struct.h +++ b/components/soc/esp32s31/register/soc/io_mux_struct.h @@ -16,96 +16,96 @@ extern "C" { */ typedef union { struct { - /** gpio_mcu_oe : R/W; bitpos: [0]; default: 0; + /** mcu_oe : R/W; bitpos: [0]; default: 0; * Configures whether or not to enable the output of GPIOn in sleep mode. * 0: Disable * 1: Enable */ - uint32_t gpio_mcu_oe:1; - /** gpio_slp_sel : R/W; bitpos: [1]; default: 0; + uint32_t mcu_oe:1; + /** slp_sel : R/W; bitpos: [1]; default: 0; * Configures whether or not to enter sleep mode for GPIOn. * 0: Not enter * 1: Enter */ - uint32_t gpio_slp_sel:1; - /** gpio_mcu_wpd : R/W; bitpos: [2]; default: 0; + uint32_t slp_sel:1; + /** mcu_wpd : R/W; bitpos: [2]; default: 0; * Configure whether or not to enable pull-down resistor of GPIOn in sleep mode. * 0: Disable * 1: Enable */ - uint32_t gpio_mcu_wpd:1; - /** gpio_mcu_wpu : R/W; bitpos: [3]; default: 0; + uint32_t mcu_wpd:1; + /** mcu_wpu : R/W; bitpos: [3]; default: 0; * Configures whether or not to enable pull-up resistor of GPIOn during sleep mode. * 0: Disable * 1: Enable */ - uint32_t gpio_mcu_wpu:1; - /** gpio_mcu_ie : R/W; bitpos: [4]; default: 0; + uint32_t mcu_wpu:1; + /** mcu_ie : R/W; bitpos: [4]; default: 0; * Configures whether or not to enable the input of GPIOn during sleep mode. * 0: Disable * 1: Enable */ - uint32_t gpio_mcu_ie:1; - /** gpio_mcu_drv : R/W; bitpos: [6:5]; default: 0; + uint32_t mcu_ie:1; + /** mcu_drv : R/W; bitpos: [6:5]; default: 0; * Configures the drive strength of GPIOn during sleep mode. * 0: ~5 mA * 1: ~10 mA * 2: ~20 mA * 3: ~40 mA */ - uint32_t gpio_mcu_drv:2; - /** gpio_fun_wpd : R/W; bitpos: [7]; default: 0; + uint32_t mcu_drv:2; + /** fun_wpd : R/W; bitpos: [7]; default: 0; * Configures whether or not to enable pull-down resistor of GPIOn. * 0: Disable * 1: Enable */ - uint32_t gpio_fun_wpd:1; - /** gpio_fun_wpu : R/W; bitpos: [8]; default: 0; + uint32_t fun_wpd:1; + /** fun_wpu : R/W; bitpos: [8]; default: 0; * Configures whether or not enable pull-up resistor of GPIOn. * 0: Disable * 1: Enable */ - uint32_t gpio_fun_wpu:1; - /** gpio_fun_ie : R/W; bitpos: [9]; default: 0; + uint32_t fun_wpu:1; + /** fun_ie : R/W; bitpos: [9]; default: 0; * Configures whether or not to enable input of GPIOn. * 0: Disable * 1: Enable */ - uint32_t gpio_fun_ie:1; - /** gpio_fun_drv : R/W; bitpos: [11:10]; default: 2; + uint32_t fun_ie:1; + /** fun_drv : R/W; bitpos: [11:10]; default: 2; * Configures the drive strength of GPIOn. * 0: ~5 mA * 1: ~10 mA * 2: ~20 mA * 3: ~40 mA */ - uint32_t gpio_fun_drv:2; - /** gpio_mcu_sel : R/W; bitpos: [14:12]; default: 1; + uint32_t fun_drv:2; + /** mcu_sel : R/W; bitpos: [14:12]; default: 1; * Configures to select IO MUX function for this signal. * 0: Select Function 0 * 1: Select Function 1 * ...... */ - uint32_t gpio_mcu_sel:3; - /** gpio_filter_en : R/W; bitpos: [15]; default: 0; + uint32_t mcu_sel:3; + /** filter_en : R/W; bitpos: [15]; default: 0; * Configures whether or not to enable filter for pin input signals. * 0: Disable * 1: Enable */ - uint32_t gpio_filter_en:1; - /** gpio_hys_en : R/W; bitpos: [16]; default: 0; + uint32_t filter_en:1; + /** hys_en : R/W; bitpos: [16]; default: 0; * Configures whether or not to enable the hysteresis function of the pin when * IO_MUX_GPIOn_HYS_SEL is set to 1. * 0: Disable * 1: Enable */ - uint32_t gpio_hys_en:1; - /** gpio_hys_sel : R/W; bitpos: [17]; default: 0; + uint32_t hys_en:1; + /** hys_sel : R/W; bitpos: [17]; default: 0; * Configures to choose the signal for enabling the hysteresis function for GPIOn. * 0: Choose the output enable signal of eFuse * 1: Choose the output enable signal of IO_MUX_GPIOn_HYS_EN */ - uint32_t gpio_hys_sel:1; + uint32_t hys_sel:1; uint32_t reserved_18:14; }; uint32_t val; diff --git a/components/soc/esp32s31/register/soc/pmu_struct.h b/components/soc/esp32s31/register/soc/pmu_struct.h index 254e25d540b..bacdfb26d78 100644 --- a/components/soc/esp32s31/register/soc/pmu_struct.h +++ b/components/soc/esp32s31/register/soc/pmu_struct.h @@ -3480,6 +3480,7 @@ typedef struct { volatile pmu_date_reg_t date; } pmu_dev_t; +extern pmu_dev_t PMU; #ifndef __cplusplus _Static_assert(sizeof(pmu_dev_t) == 0x400, "Invalid size of pmu_dev_t structure"); diff --git a/components/soc/esp32s31/register/soc/usb_serial_jtag_struct.h b/components/soc/esp32s31/register/soc/usb_serial_jtag_struct.h index 41ed7f42efc..aad18ea677a 100644 --- a/components/soc/esp32s31/register/soc/usb_serial_jtag_struct.h +++ b/components/soc/esp32s31/register/soc/usb_serial_jtag_struct.h @@ -971,6 +971,7 @@ typedef struct { volatile usb_serial_jtag_date_reg_t date; } usb_serial_jtag_dev_t; +extern usb_serial_jtag_dev_t USB_SERIAL_JTAG; #ifndef __cplusplus _Static_assert(sizeof(usb_serial_jtag_dev_t) == 0x84, "Invalid size of usb_serial_jtag_dev_t structure"); diff --git a/docs/en/api-reference/peripherals/gpio.rst b/docs/en/api-reference/peripherals/gpio.rst index 904722496e2..b164726c4a1 100644 --- a/docs/en/api-reference/peripherals/gpio.rst +++ b/docs/en/api-reference/peripherals/gpio.rst @@ -37,7 +37,7 @@ An IO can be used in two ways: - As a simple GPIO input to read the level on the pin, or as a simple GPIO output to output the desired level on the pin. - As a peripheral signal input/output. -IDF peripheral drivers always take care of the necessary IO configurations that need to be applied onto the pins, so that they can be used as the peripheral signal inputs or outputs. This means the users usually only need to be responsible for configuring the IOs as simple inputs or outputs. :cpp:func:`gpio_config` is an all-in-one API that can be used to configure the I/O mode, internal pull-up/pull-down resistors, etc. for pins. +IDF peripheral drivers always take care of the necessary IO configurations that need to be applied onto the pins, so that they can be used as the peripheral signal inputs or outputs. This means the users usually only need to be responsible for configuring the IOs as simple inputs or outputs. :cpp:func:`gpio_config` is an all-in-one API that can be used to configure the I/O mode, internal pull-up/pull-down resistors, etc. for pins, including the ones reused by the USB PHY. In some applications, an IO pin can serve dual purposes. For example, the IO, which outputs a LEDC PWM signal, can also act as a GPIO input to generate interrupts or GPIO ETM events. Careful handling on the configuration step is necessary for such dual use of IO pins cases. :cpp:func:`gpio_config` is an API that overwrites all the current configurations, so it must be called to set the pin mode to :cpp:enumerator:`gpio_mode_t::GPIO_MODE_INPUT` before calling the LEDC driver API which connects the output signal to the pin. As an alternative, if no other configuration is needed other than making the pin input enabled, :cpp:func:`gpio_input_enable` can be the one to call at any time to achieve the same purpose. @@ -87,24 +87,6 @@ If an IO pin is routed to a peripheral signal through the GPIO matrix, the signa Do not rely on the default configurations values in the Technical Reference Manual, because it may be changed in the bootloader or application startup code before app_main. -.. only:: esp32c3 or esp32c6 or esp32h2 or esp32p4 or esp32s2 or esp32s3 or esp32c5 or esp32c61 - - Configure USB PHY Pins to GPIO - ------------------------------- - - To configure the USB PHY pins to GPIO, you can use the function :cpp:func:`gpio_config`. Below is an example of how to configure the USB PHY pins to GPIO: - - .. code-block:: c - - gpio_config_t usb_phy_conf = { - .pin_bit_mask = (1ULL << USB_PHY_DP_PIN) | (1ULL << USB_PHY_DM_PIN), - .mode = GPIO_MODE_INPUT_OUTPUT, - .pull_up_en = GPIO_PULLUP_DISABLE, - .pull_down_en = GPIO_PULLDOWN_DISABLE, - .intr_type = GPIO_INTR_DISABLE, - }; - gpio_config(&usb_phy_conf); - .. only:: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER or SOC_GPIO_FLEX_GLITCH_FILTER_NUM GPIO Glitch Filter diff --git a/docs/en/api-reference/peripherals/gpio/esp32s31.inc b/docs/en/api-reference/peripherals/gpio/esp32s31.inc new file mode 100644 index 00000000000..4520edf8cdc --- /dev/null +++ b/docs/en/api-reference/peripherals/gpio/esp32s31.inc @@ -0,0 +1,330 @@ +.. This file gets included from other .rst files in this folder. +.. It contains target-specific snippets. +.. Comments and '---' lines act as delimiters. +.. +.. This is necessary mainly because RST doesn't support substitutions +.. (defined in RST, not in Python) inside code blocks. If that is ever implemented, +.. These code blocks can be moved back to the main .rst files, with target-specific +.. file names being replaced by substitutions. + +.. gpio-summary + +The {IDF_TARGET_NAME} chip features 60 physical GPIO pins (GPIO0 ~ GPIO61, except GPIO29, GPIO41). Each pin can be used as a general-purpose I/O, or to be connected to an internal peripheral signal. Through GPIO matrix and IO MUX, peripheral input signals can be from any IO pins, and peripheral output signals can be routed to any IO pins. Together these modules provide highly configurable I/O. For more details, see *{IDF_TARGET_NAME} Technical Reference Manual* > *IO MUX and GPIO Matrix (GPIO, IO_MUX)* [`PDF <{IDF_TARGET_TRM_EN_URL}#iomuxgpio>`__]. + +The table below provides more information on pin usage, and please note the comments in the table for GPIOs with restrictions. + +.. list-table:: + :header-rows: 1 + :widths: 8 12 12 20 + + * - GPIO + - Analog Function + - LP GPIO + - Comment + + * - GPIO0 + - + - LP_GPIO0 + - + + * - GPIO1 + - + - LP_GPIO1 + - + + * - GPIO2 + - + - LP_GPIO2 + - + + * - GPIO3 + - + - LP_GPIO3 + - + + * - GPIO4 + - DAC0 + - LP_GPIO4 + - + + * - GPIO5 + - DAC1 + - LP_GPIO5 + - + + * - GPIO6 + - TOUCH0 + - LP_GPIO6 + - + + * - GPIO7 + - TOUCH1 + - LP_GPIO7 + - + + * - GPIO8 + - TOUCH2 + - + - + + * - GPIO9 + - TOUCH3 + - + - + + * - GPIO10 + - TOUCH4 + - + - + + * - GPIO11 + - TOUCH5 + - + - + + * - GPIO12 + - TOUCH6 + - + - + + * - GPIO13 + - TOUCH7 + - + - + + * - GPIO14 + - TOUCH8 + - + - + + * - GPIO15 + - TOUCH9 + - + - + + * - GPIO16 + - TOUCH10 + - + - + + * - GPIO17 + - TOUCH11 + - + - + + * - GPIO18 + - TOUCH12 + - + - + + * - GPIO19 + - TOUCH13 + - + - + + * - GPIO20 + - + - + - + + * - GPIO21 + - + - + - + + * - GPIO22 + - + - + - + + * - GPIO23 + - + - + - + + * - GPIO24 + - + - + - + + * - GPIO25 + - + - + - + + * - GPIO26 + - + - + - SPI0/1 + + * - GPIO27 + - + - + - SPI0/1 + + * - GPIO28 + - + - + - SPI0/1 + + * - GPIO30 + - + - + - SPI0/1 + + * - GPIO31 + - + - + - SPI0/1 + + * - GPIO32 + - + - + - SPI0/1 + + * - GPIO33 + - + - + - + + * - GPIO34 + - + - + - + + * - GPIO35 + - + - + - + + * - GPIO36 + - + - + - Strapping pin + + * - GPIO37 + - + - + - Strapping pin + + * - GPIO38 + - + - + - Strapping pin + + * - GPIO39 + - + - + - Strapping pin + + * - GPIO40 + - + - + - Strapping pin + + * - GPIO42 + - ADC1_CH0_N + - + - + + * - GPIO43 + - ADC1_CH0_P + - + - + + * - GPIO44 + - ADC1_CH1_N + - + - + + * - GPIO45 + - ADC1_CH1_P + - + - + + * - GPIO46 + - ADC1_CH2_N + - + - + + * - GPIO47 + - ADC1_CH2_P + - + - + + * - GPIO48 + - ADC1_CH3_N + - + - + + * - GPIO49 + - ADC1_CH3_P + - + - + + * - GPIO50 + - ADC2_CH0_N + - + - + + * - GPIO51 + - ADC2_CH0_P + - + - + + * - GPIO52 + - ADC2_CH1_N + - + - + + * - GPIO53 + - ADC2_CH1_P + - + - + + * - GPIO54 + - ADC2_CH2_N + - + - + + * - GPIO55 + - ADC2_CH2_P + - + - + + * - GPIO56 + - ADC2_CH3_N + - + - + + * - GPIO57 + - ADC2_CH3_P + - + - + + * - GPIO58 + - + - + - UART0 + + * - GPIO59 + - + - + - UART0 + + * - GPIO60 + - + - + - Strapping pin + + * - GPIO61 + - + - + - Strapping pin + +.. note:: + + - Strapping pin: GPIO36 ~ GPIO40, GPIO60 ~ GPIO61 are strapping pins. For more information, please refer to `{IDF_TARGET_NAME} datasheet <{IDF_TARGET_DATASHEET_EN_URL}>`_. + - SPI0/1: GPIO26 ~ GPIO32 are usually used for SPI flash, they're not recommended for other uses. + +--- diff --git a/docs/zh_CN/api-reference/peripherals/gpio.rst b/docs/zh_CN/api-reference/peripherals/gpio.rst index 3a8ace54d22..23f4b64cead 100644 --- a/docs/zh_CN/api-reference/peripherals/gpio.rst +++ b/docs/zh_CN/api-reference/peripherals/gpio.rst @@ -37,7 +37,7 @@ IO 可以有两种使用方式: - 作为简单的 GPIO 输入读取引脚上的电平,或作为简单的 GPIO 输出以输出所需的电平。 - 作为外设信号的输入/输出。 -IDF 外设驱动内部会处理需要应用到引脚上的必要 IO 配置,以便它们可以用作外设信号的输入或输出。这意味着用户通常自己只需负责将 IO 配置为简单的输入或输出。:cpp:func:`gpio_config` 是一个一体化的 API,可用于配置 I/O 模式、内部上拉/下拉电阻等管脚设置。 +IDF 外设驱动内部会处理需要应用到引脚上的必要 IO 配置,以便它们可以用作外设信号的输入或输出。这意味着用户通常自己只需负责将 IO 配置为简单的输入或输出。:cpp:func:`gpio_config` 是一个一体化的 API,可用于配置 I/O 模式、内部上拉/下拉电阻等管脚设置,包括那些被 USB PHY 复用的引脚。 在一些应用中,IO 管脚可以同时发挥双重作用。例如,输出 LEDC PWM 信号的 IO 也可以作为 GPIO 输入生成中断或 GPIO ETM 事件。这种双重用途的 IO 管脚在配置时需要特别注意。由于 :cpp:func:`gpio_config` 是一个会覆盖所有当前配置的 API ,因此必须先调用它将管脚模式设置为 :cpp:enumerator:`gpio_mode_t::GPIO_MODE_INPUT`,然后才能调用 LEDC 驱动 API 将输出信号连接到引脚上。作为替代方案,如果除了使管脚输入启用之外不需要其他额外配置,可以随时调用 :cpp:func:`gpio_input_enable` 以实现相同的目的。 @@ -87,24 +87,6 @@ GPIO 驱动提供了一个函数 :cpp:func:`gpio_dump_io_configuration` 用来 请不要依赖技术参考手册中记录的 GPIO 默认配置状态,因为特殊用途的 GPIO 可能会在 app_main 之前被引导加载程序或应用程序启动阶段的代码更改。 -.. only:: esp32c3 or esp32c6 or esp32h2 or esp32p4 or esp32s2 or esp32s3 or esp32c5 or esp32c61 - - 配置 USB PHY 管脚 为普通 GPIO 管脚 - --------------------------------------- - - 要将 USB PHY 管脚配置为普通 GPIO 管脚,可使用函数 :cpp:func:`gpio_config`,请参考以下代码片段来进行配置。 - - .. code-block:: c - - gpio_config_t usb_phy_conf = { - .pin_bit_mask = (1ULL << USB_PHY_DP_PIN) | (1ULL << USB_PHY_DM_PIN), - .mode = GPIO_MODE_INPUT_OUTPUT, - .pull_up_en = GPIO_PULLUP_DISABLE, - .pull_down_en = GPIO_PULLDOWN_DISABLE, - .intr_type = GPIO_INTR_DISABLE, - }; - gpio_config(&usb_phy_conf); - .. only:: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER or SOC_GPIO_FLEX_GLITCH_FILTER_NUM GPIO 毛刺过滤器 diff --git a/docs/zh_CN/api-reference/peripherals/gpio/esp32s31.inc b/docs/zh_CN/api-reference/peripherals/gpio/esp32s31.inc new file mode 100644 index 00000000000..b3ee87cbd39 --- /dev/null +++ b/docs/zh_CN/api-reference/peripherals/gpio/esp32s31.inc @@ -0,0 +1,330 @@ +.. This file gets included from other .rst files in this folder. +.. It contains target-specific snippets. +.. Comments and '---' lines act as delimiters. +.. +.. This is necessary mainly because RST doesn't support substitutions +.. (defined in RST, not in Python) inside code blocks. If that is ever implemented, +.. These code blocks can be moved back to the main .rst files, with target-specific +.. file names being replaced by substitutions. + +.. gpio-summary + +{IDF_TARGET_NAME} 芯片具有 60 个物理 GPIO 管脚(GPIO0 ~ GPIO61,除 GPIO29、GPIO41 外)。每个管脚都可用作一个通用 IO,或连接一个内部的外设信号。通过 GPIO 交换矩阵和 IO MUX,可配置外设模块的输入信号来源于任何的 IO 管脚,并且外设模块的输出信号也可连接到任意 IO 管脚。这些模块共同组成了芯片的 IO 控制。更多详细信息,请参阅 *{IDF_TARGET_NAME} 技术参考手册* > *IO MUX 和 GPIO 矩阵(GPIO、IO_MUX)* [`PDF <{IDF_TARGET_TRM_CN_URL}#iomuxgpio>`__]。 + +下表提供了各管脚的详细信息,部分 GPIO 具有特殊的使用限制,具体可参考表中的注释列。 + +.. list-table:: + :header-rows: 1 + :widths: 8 12 12 20 + + * - GPIO + - 模拟功能 + - LP GPIO + - 注释 + + * - GPIO0 + - + - LP_GPIO0 + - + + * - GPIO1 + - + - LP_GPIO1 + - + + * - GPIO2 + - + - LP_GPIO2 + - + + * - GPIO3 + - + - LP_GPIO3 + - + + * - GPIO4 + - DAC0 + - LP_GPIO4 + - + + * - GPIO5 + - DAC1 + - LP_GPIO5 + - + + * - GPIO6 + - TOUCH0 + - LP_GPIO6 + - + + * - GPIO7 + - TOUCH1 + - LP_GPIO7 + - + + * - GPIO8 + - TOUCH2 + - + - + + * - GPIO9 + - TOUCH3 + - + - + + * - GPIO10 + - TOUCH4 + - + - + + * - GPIO11 + - TOUCH5 + - + - + + * - GPIO12 + - TOUCH6 + - + - + + * - GPIO13 + - TOUCH7 + - + - + + * - GPIO14 + - TOUCH8 + - + - + + * - GPIO15 + - TOUCH9 + - + - + + * - GPIO16 + - TOUCH10 + - + - + + * - GPIO17 + - TOUCH11 + - + - + + * - GPIO18 + - TOUCH12 + - + - + + * - GPIO19 + - TOUCH13 + - + - + + * - GPIO20 + - + - + - + + * - GPIO21 + - + - + - + + * - GPIO22 + - + - + - + + * - GPIO23 + - + - + - + + * - GPIO24 + - + - + - + + * - GPIO25 + - + - + - + + * - GPIO26 + - + - + - SPI0/1 + + * - GPIO27 + - + - + - SPI0/1 + + * - GPIO28 + - + - + - SPI0/1 + + * - GPIO30 + - + - + - SPI0/1 + + * - GPIO31 + - + - + - SPI0/1 + + * - GPIO32 + - + - + - SPI0/1 + + * - GPIO33 + - + - + - + + * - GPIO34 + - + - + - + + * - GPIO35 + - + - + - + + * - GPIO36 + - + - + - Strapping 管脚 + + * - GPIO37 + - + - + - Strapping 管脚 + + * - GPIO38 + - + - + - Strapping 管脚 + + * - GPIO39 + - + - + - Strapping 管脚 + + * - GPIO40 + - + - + - Strapping 管脚 + + * - GPIO42 + - ADC1_CH0_N + - + - + + * - GPIO43 + - ADC1_CH0_P + - + - + + * - GPIO44 + - ADC1_CH1_N + - + - + + * - GPIO45 + - ADC1_CH1_P + - + - + + * - GPIO46 + - ADC1_CH2_N + - + - + + * - GPIO47 + - ADC1_CH2_P + - + - + + * - GPIO48 + - ADC1_CH3_N + - + - + + * - GPIO49 + - ADC1_CH3_P + - + - + + * - GPIO50 + - ADC2_CH0_N + - + - + + * - GPIO51 + - ADC2_CH0_P + - + - + + * - GPIO52 + - ADC2_CH1_N + - + - + + * - GPIO53 + - ADC2_CH1_P + - + - + + * - GPIO54 + - ADC2_CH2_N + - + - + + * - GPIO55 + - ADC2_CH2_P + - + - + + * - GPIO56 + - ADC2_CH3_N + - + - + + * - GPIO57 + - ADC2_CH3_P + - + - + + * - GPIO58 + - + - + - UART0 + + * - GPIO59 + - + - + - UART0 + + * - GPIO60 + - + - + - Strapping 管脚 + + * - GPIO61 + - + - + - Strapping 管脚 + +.. note:: + + - Strapping 管脚:GPIO36 ~ GPIO40、GPIO60 ~ GPIO61 是 Strapping 管脚。更多信息请参考 `{IDF_TARGET_NAME} 技术规格书 <{IDF_TARGET_DATASHEET_CN_URL}>`_。 + - SPI0/1:GPIO26 ~ GPIO32 通常用于 SPI flash,不推荐用于其他用途。 + +---