Skip to content

Commit d17b0ed

Browse files
committed
Merge branch 'feature/esp32h21_gpio_support' into 'master'
feat(esp32h21): support GPIO on esp32h21 Closes IDF-11611 See merge request espressif/esp-idf!36781
2 parents 13188dc + 7e54886 commit d17b0ed

File tree

35 files changed

+878
-237
lines changed

35 files changed

+878
-237
lines changed

components/esp_driver_gpio/src/gpio.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -604,13 +604,7 @@ esp_err_t gpio_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags,
604604
{
605605
GPIO_CHECK(fn, "GPIO ISR null", ESP_ERR_INVALID_ARG);
606606
gpio_isr_alloc_t p;
607-
#if CONFIG_IDF_TARGET_ESP32P4 //TODO: IDF-7995
608-
p.source = ETS_GPIO_INTR0_SOURCE;
609-
#elif CONFIG_IDF_TARGET_ESP32H21 // TODO: IDF-11611
610-
p.source = ETS_GPIO_INTERRUPT_PRO_SOURCE;
611-
#else
612-
p.source = ETS_GPIO_INTR_SOURCE;
613-
#endif
607+
p.source = GPIO_LL_INTR_SOURCE0;
614608
p.intr_alloc_flags = intr_alloc_flags;
615609
#if SOC_ANA_CMPR_INTR_SHARE_WITH_GPIO
616610
p.intr_alloc_flags |= ESP_INTR_FLAG_SHARED;

components/esp_driver_gpio/test_apps/.build-test-rules.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@
33
components/esp_driver_gpio/test_apps:
44
depends_components:
55
- esp_driver_gpio
6-
disable:
7-
- if: IDF_TARGET in ["esp32h21"]
8-
temporary: true
9-
reason: not support yet # TODO: [esp32h21] IDF-11611
10-
116
components/esp_driver_gpio/test_apps/gpio_extensions:
127
enable:
138
- if: SOC_DEDICATED_GPIO_SUPPORTED == 1
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
2-
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
1+
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
2+
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |

components/esp_driver_gpio/test_apps/gpio/main/test_gpio.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -561,6 +561,9 @@ TEST_CASE("GPIO_get_level_from_fixed_voltage_test", "[gpio]")
561561
TEST_ASSERT_EQUAL_INT_MESSAGE(0, level2, "get level error! the level should be low!");
562562
}
563563

564+
#if !CONFIG_IDF_ENV_FPGA
565+
// On FPGA do not support GPIO pull down
566+
564567
TEST_CASE("GPIO_io_pull_up/down_function", "[gpio]")
565568
{
566569
// First, ensure that the output IO will not affect the level
@@ -662,6 +665,8 @@ TEST_CASE("GPIO_mode_test", "[gpio]")
662665
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");
663666
}
664667

668+
#endif //!CONFIG_IDF_ENV_FPGA
669+
665670
static void prompt_to_continue(const char *str)
666671
{
667672
printf("%s , please press \"Enter\" to go on!\n", str);
Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,77 @@
11

22
/*
3-
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
3+
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
44
*
55
* SPDX-License-Identifier: Apache-2.0
66
*/
77

8-
//TODO: [ESP32H21] IDF-11611
8+
#include "freertos/FreeRTOS.h"
9+
#include "esp_private/io_mux.h"
10+
#include "esp_private/periph_ctrl.h"
11+
#include "hal/gpio_ll.h"
12+
#include "hal/rtc_io_ll.h"
13+
14+
#define RTCIO_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
15+
16+
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
17+
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)
18+
static uint8_t s_rtc_io_enabled_cnt[MAX_RTC_GPIO_NUM] = { 0 };
19+
static uint32_t s_rtc_io_using_mask = 0;
20+
21+
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
22+
{
23+
bool clk_conflict = false;
24+
// check is the IO MUX has been set to another clock source
25+
portENTER_CRITICAL(&s_io_mux_spinlock);
26+
if (s_io_mux_clk_src != 0 && s_io_mux_clk_src != clk_src) {
27+
clk_conflict = true;
28+
} else {
29+
s_io_mux_clk_src = clk_src;
30+
}
31+
portEXIT_CRITICAL(&s_io_mux_spinlock);
32+
33+
if (clk_conflict) {
34+
return ESP_ERR_INVALID_STATE;
35+
}
36+
37+
gpio_ll_iomux_set_clk_src(clk_src);
38+
39+
return ESP_OK;
40+
}
41+
42+
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
43+
{
44+
portENTER_CRITICAL(&s_io_mux_spinlock);
45+
if (enable) {
46+
if (s_rtc_io_enabled_cnt[gpio_num] == 0) {
47+
s_rtc_io_using_mask |= (1ULL << gpio_num);
48+
}
49+
s_rtc_io_enabled_cnt[gpio_num]++;
50+
} else if (!enable && (s_rtc_io_enabled_cnt[gpio_num] > 0)) {
51+
s_rtc_io_enabled_cnt[gpio_num]--;
52+
if (s_rtc_io_enabled_cnt[gpio_num] == 0) {
53+
s_rtc_io_using_mask &= ~(1ULL << gpio_num);
54+
}
55+
}
56+
RTCIO_RCC_ATOMIC() {
57+
if (s_rtc_io_using_mask == 0) {
58+
rtcio_ll_enable_io_clock(false);
59+
} else {
60+
rtcio_ll_enable_io_clock(true);
61+
}
62+
}
63+
portEXIT_CRITICAL(&s_io_mux_spinlock);
64+
}
65+
66+
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
67+
{
68+
portENTER_CRITICAL(&s_io_mux_spinlock);
69+
s_rtc_io_enabled_cnt[gpio_num] = 0;
70+
s_rtc_io_using_mask &= ~(1ULL << gpio_num);
71+
if (s_rtc_io_using_mask == 0) {
72+
RTCIO_RCC_ATOMIC() {
73+
rtcio_ll_enable_io_clock(false);
74+
}
75+
}
76+
portEXIT_CRITICAL(&s_io_mux_spinlock);
77+
}

components/esp_rom/esp32h21/include/esp32h21/rom/gpio.h

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -10,8 +10,6 @@
1010
#include <stdbool.h>
1111
#include "soc/gpio_reg.h"
1212

13-
//TODO: [ESP32H21] IDF-11611
14-
1513
#ifdef __cplusplus
1614
extern "C" {
1715
#endif
@@ -30,7 +28,6 @@ extern "C" {
3028
#define GPIO_ID_PIN(n) (GPIO_ID_PIN0+(n))
3129
#define GPIO_PIN_ADDR(i) (GPIO_PIN0_REG + i*4)
3230

33-
//TODO: [ESP32H21] IDF-11611, need check
3431
#define GPIO_FUNC_IN_HIGH 0x20
3532
#define GPIO_FUNC_IN_LOW 0x30
3633

@@ -50,7 +47,7 @@ typedef enum {
5047

5148

5249
/**
53-
* @brief Change GPIO(0-27) pin output by setting, clearing, or disabling pins, GPIO0<->BIT(0).
50+
* @brief Change GPIO(0-25) pin output by setting, clearing, or disabling pins, GPIO0<->BIT(0).
5451
* There is no particular ordering guaranteed; so if the order of writes is significant,
5552
* calling code should divide a single call into multiple calls.
5653
*
@@ -67,7 +64,7 @@ typedef enum {
6764
void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask);
6865

6966
/**
70-
* @brief Sample the value of GPIO input pins(0-27) and returns a bitmask.
67+
* @brief Sample the value of GPIO input pins(0-25) and returns a bitmask.
7168
*
7269
* @param None
7370
*
@@ -76,7 +73,7 @@ void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mas
7673
uint32_t gpio_input_get(void);
7774

7875
/**
79-
* @brief Set GPIO to wakeup the ESP32.
76+
* @brief Set GPIO to wakeup the ESP32H21.
8077
* Please do not call this function in SDK.
8178
*
8279
* @param uint32_t i: gpio number.
@@ -88,7 +85,7 @@ uint32_t gpio_input_get(void);
8885
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
8986

9087
/**
91-
* @brief disable GPIOs to wakeup the ESP32.
88+
* @brief disable GPIOs to wakeup the ESP32H21.
9289
* Please do not call this function in SDK.
9390
*
9491
* @param None
@@ -100,10 +97,9 @@ void gpio_pin_wakeup_disable(void);
10097
/**
10198
* @brief set gpio input to a signal, one gpio can input to several signals.
10299
*
103-
* @param uint32_t gpio : gpio number, 0~27
104-
* gpio == 0x3C, input 0 to signal
105-
* gpio == 0x3A, input nothing to signal
106-
* gpio == 0x38, input 1 to signal
100+
* @param uint32_t gpio : gpio number, 0~25
101+
* gpio == 0x30, input 0 to signal
102+
* gpio == 0x20, input 1 to signal
107103
*
108104
* @param uint32_t signal_idx : signal index.
109105
*
@@ -116,7 +112,7 @@ void gpio_matrix_in(uint32_t gpio, uint32_t signal_idx, bool inv);
116112
/**
117113
* @brief set signal output to gpio, one signal can output to several gpios.
118114
*
119-
* @param uint32_t gpio : gpio number, 0~27
115+
* @param uint32_t gpio : gpio number, 0~25
120116
*
121117
* @param uint32_t signal_idx : signal index.
122118
* 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_
132128
/**
133129
* @brief Select pad as a gpio function from IOMUX.
134130
*
135-
* @param uint32_t gpio_num : gpio number, 0~27
131+
* @param uint32_t gpio_num : gpio number, 0~25
136132
*
137133
* @return None
138134
*/
@@ -141,7 +137,7 @@ void gpio_pad_select_gpio(uint32_t gpio_num);
141137
/**
142138
* @brief Set pad driver capability.
143139
*
144-
* @param uint32_t gpio_num : gpio number, 0~27
140+
* @param uint32_t gpio_num : gpio number, 0~25
145141
*
146142
* @param uint32_t drv : 0-3
147143
*
@@ -152,7 +148,7 @@ void gpio_pad_set_drv(uint32_t gpio_num, uint32_t drv);
152148
/**
153149
* @brief Pull up the pad from gpio number.
154150
*
155-
* @param uint32_t gpio_num : gpio number, 0~27
151+
* @param uint32_t gpio_num : gpio number, 0~25
156152
*
157153
* @return None
158154
*/
@@ -161,7 +157,7 @@ void gpio_pad_pullup(uint32_t gpio_num);
161157
/**
162158
* @brief Pull down the pad from gpio number.
163159
*
164-
* @param uint32_t gpio_num : gpio number, 0~27
160+
* @param uint32_t gpio_num : gpio number, 0~25
165161
*
166162
* @return None
167163
*/
@@ -170,7 +166,7 @@ void gpio_pad_pulldown(uint32_t gpio_num);
170166
/**
171167
* @brief Unhold the pad from gpio number.
172168
*
173-
* @param uint32_t gpio_num : gpio number, 0~27
169+
* @param uint32_t gpio_num : gpio number, 0~25
174170
*
175171
* @return None
176172
*/
@@ -179,7 +175,7 @@ void gpio_pad_unhold(uint32_t gpio_num);
179175
/**
180176
* @brief Hold the pad from gpio number.
181177
*
182-
* @param uint32_t gpio_num : gpio number, 0~27
178+
* @param uint32_t gpio_num : gpio number, 0~25
183179
*
184180
* @return None
185181
*/
@@ -188,7 +184,7 @@ void gpio_pad_hold(uint32_t gpio_num);
188184
/**
189185
* @brief enable gpio pad input.
190186
*
191-
* @param uint32_t gpio_num : gpio number, 0~27
187+
* @param uint32_t gpio_num : gpio number, 0~25
192188
*
193189
* @return None
194190
*/
@@ -197,7 +193,7 @@ void gpio_pad_input_enable(uint32_t gpio_num);
197193
/**
198194
* @brief disable gpio pad input.
199195
*
200-
* @param uint32_t gpio_num : gpio number, 0~27
196+
* @param uint32_t gpio_num : gpio number, 0~25
201197
*
202198
* @return None
203199
*/

components/hal/esp32/include/hal/gpio_ll.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ extern const uint8_t GPIO_PIN_MUX_REG_OFFSET[SOC_GPIO_PIN_COUNT];
4242
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(3))
4343
#define GPIO_LL_SDIO_EXT_INTR_ENA (BIT(4))
4444

45+
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
46+
4547
/**
4648
* @brief Get the configuration for an IO
4749
*

components/hal/esp32c2/include/hal/gpio_ll.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ extern "C" {
3333
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
3434
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
3535

36+
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
37+
3638
/**
3739
* @brief Get the configuration for an IO
3840
*

components/hal/esp32c3/include/hal/gpio_ll.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ extern "C" {
3535
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
3636
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
3737

38+
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
39+
3840
/**
3941
* @brief Enable pull-up on GPIO.
4042
*

components/hal/esp32c5/include/hal/gpio_ll.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ extern "C" {
3737

3838
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
3939

40+
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
41+
4042
/**
4143
* @brief Get the configuration for an IO
4244
*
@@ -259,7 +261,7 @@ static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num)
259261
static inline void gpio_ll_pin_input_hysteresis_enable(gpio_dev_t *hw, uint32_t gpio_num)
260262
{
261263
// On ESP32C5, there is an efuse bit that controls the hysteresis enable or not for all IOs.
262-
// We are not going to use the hardware control in IDF for C5.
264+
// We are not going to use the hardware control for C5.
263265
// Therefore, we need to always switch to use software control first.
264266
// i.e. Swt hys_sel to 1, so that hys_en determines whether hysteresis is enabled or not
265267
IO_MUX.gpio[gpio_num].hys_sel = 1;

0 commit comments

Comments
 (0)