Skip to content

Commit 91f1159

Browse files
committed
gpio: Fix the bug that gpio interrupt cannot be triggered on app cpu on ESP32S3
Add a test case for checking the interrupt on other cores. Closes #7885
1 parent 0e8286c commit 91f1159

File tree

4 files changed

+57
-24
lines changed

4 files changed

+57
-24
lines changed

Diff for: components/driver/test/test_gpio.c

+38-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "sdkconfig.h"
2121
#include "esp_rom_uart.h"
2222
#include "esp_rom_sys.h"
23+
#include "test_utils.h"
2324

2425

2526
#define WAKE_UP_IGNORE 1 // gpio_wakeup function development is not completed yet, set it deprecated.
@@ -100,7 +101,7 @@ static gpio_config_t init_io(gpio_num_t num)
100101
__attribute__((unused)) static void gpio_isr_edge_handler(void *arg)
101102
{
102103
uint32_t gpio_num = (uint32_t) arg;
103-
esp_rom_printf("GPIO[%d] intr, val: %d\n", gpio_num, gpio_get_level(gpio_num));
104+
esp_rom_printf("GPIO[%d] intr on core %d, val: %d\n", gpio_num, cpu_hal_get_core_id(), gpio_get_level(gpio_num));
104105
edge_intr_times++;
105106
}
106107

@@ -408,6 +409,42 @@ TEST_CASE("GPIO enable and disable interrupt test", "[gpio][test_env=UT_T1_GPIO]
408409
}
409410
#endif //DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
410411

412+
#if !CONFIG_FREERTOS_UNICORE
413+
static void install_isr_service_task(void *arg)
414+
{
415+
uint32_t gpio_num = (uint32_t) arg;
416+
//rising edge intr
417+
TEST_ESP_OK(gpio_set_intr_type(gpio_num, GPIO_INTR_POSEDGE));
418+
TEST_ESP_OK(gpio_install_isr_service(0));
419+
gpio_isr_handler_add(gpio_num, gpio_isr_edge_handler, (void *) gpio_num);
420+
vTaskSuspend(NULL);
421+
}
422+
423+
TEST_CASE("GPIO interrupt on other CPUs test", "[gpio]")
424+
{
425+
TaskHandle_t gpio_task_handle;
426+
gpio_config_t input_output_io = init_io(TEST_GPIO_EXT_OUT_IO);
427+
input_output_io.mode = GPIO_MODE_INPUT_OUTPUT;
428+
input_output_io.pull_up_en = 1;
429+
TEST_ESP_OK(gpio_config(&input_output_io));
430+
431+
for (int cpu_num = 1; cpu_num < portNUM_PROCESSORS; ++cpu_num) {
432+
// We assume unit-test task is running on core 0, so we install gpio interrupt on other cores
433+
edge_intr_times = 0;
434+
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0));
435+
xTaskCreatePinnedToCore(install_isr_service_task, "install_isr_service_task", 2048, (void *) TEST_GPIO_EXT_OUT_IO, 1, &gpio_task_handle, cpu_num);
436+
437+
vTaskDelay(200 / portTICK_RATE_MS);
438+
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1));
439+
vTaskDelay(100 / portTICK_RATE_MS);
440+
TEST_ASSERT_EQUAL_INT(edge_intr_times, 1);
441+
gpio_isr_handler_remove(TEST_GPIO_EXT_OUT_IO);
442+
gpio_uninstall_isr_service();
443+
test_utils_task_delete(gpio_task_handle);
444+
}
445+
}
446+
#endif //!CONFIG_FREERTOS_UNICORE
447+
411448
// ESP32 Connect GPIO18 with GPIO19, ESP32-S2 Connect GPIO17 with GPIO21,
412449
// ESP32-S3 Connect GPIO17 with GPIO21, ESP32C3 Connect GPIO2 with GPIO3
413450
// use multimeter to test the voltage, so it is ignored in CI

Diff for: components/hal/esp32s3/include/hal/gpio_ll.h

+9-5
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ extern "C" {
2929
// Get GPIO hardware instance with giving gpio num
3030
#define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL)
3131

32-
#define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0))
33-
#define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1))
32+
// On ESP32S3, pro cpu and app cpu shares the same interrupt enable bit
33+
#define GPIO_LL_INTR_ENA (BIT(0))
34+
#define GPIO_LL_NMI_INTR_ENA (BIT(1))
3435

3536
/**
3637
* @brief Enable pull-up on GPIO.
@@ -97,6 +98,8 @@ static inline void gpio_ll_set_intr_type(gpio_dev_t *hw, gpio_num_t gpio_num, gp
9798
*/
9899
static inline void gpio_ll_get_intr_status(gpio_dev_t *hw, uint32_t core_id, uint32_t *status)
99100
{
101+
// On ESP32S3, pcpu_int register represents GPIO0-31 interrupt status on both cores
102+
(void)core_id;
100103
*status = hw->pcpu_int;
101104
}
102105

@@ -109,6 +112,8 @@ static inline void gpio_ll_get_intr_status(gpio_dev_t *hw, uint32_t core_id, uin
109112
*/
110113
static inline void gpio_ll_get_intr_status_high(gpio_dev_t *hw, uint32_t core_id, uint32_t *status)
111114
{
115+
// On ESP32S3, pcpu_int1 register represents GPIO32-48 interrupt status on both cores
116+
(void)core_id;
112117
*status = hw->pcpu_int1.intr;
113118
}
114119

@@ -143,9 +148,8 @@ static inline void gpio_ll_clear_intr_status_high(gpio_dev_t *hw, uint32_t mask)
143148
*/
144149
static inline void gpio_ll_intr_enable_on_core(gpio_dev_t *hw, uint32_t core_id, gpio_num_t gpio_num)
145150
{
146-
if (core_id == 0) {
147-
GPIO.pin[gpio_num].int_ena = GPIO_LL_PRO_CPU_INTR_ENA; //enable pro cpu intr
148-
}
151+
(void)core_id;
152+
GPIO.pin[gpio_num].int_ena = GPIO_LL_INTR_ENA; //enable intr
149153
}
150154

151155
/**

Diff for: components/soc/esp32s3/include/soc/gpio_struct.h

+10-17
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
1-
// Copyright 2017-2021 Espressif Systems (Shanghai) PTE LTD
2-
//
3-
// Licensed under the Apache License, Version 2.0 (the "License");
4-
// you may not use this file except in compliance with the License.
5-
// You may obtain a copy of the License at
6-
//
7-
// http://www.apache.org/licenses/LICENSE-2.0
8-
//
9-
// Unless required by applicable law or agreed to in writing, software
10-
// distributed under the License is distributed on an "AS IS" BASIS,
11-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12-
// See the License for the specific language governing permissions and
13-
// limitations under the License.
1+
/*
2+
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
147
#ifndef _SOC_GPIO_STRUCT_H_
158
#define _SOC_GPIO_STRUCT_H_
169

@@ -116,19 +109,19 @@ typedef volatile struct gpio_dev_s {
116109
};
117110
uint32_t val;
118111
} status1_w1tc;
119-
uint32_t pcpu_int;
120-
uint32_t pcpu_nmi_int;
112+
uint32_t pcpu_int; /*GPIO0~31 PRO & APP CPU interrupt status*/
113+
uint32_t pcpu_nmi_int; /*GPIO0~31 PRO & APP CPU non-maskable interrupt status*/
121114
uint32_t cpusdio_int;
122115
union {
123116
struct {
124-
uint32_t intr : 22;
117+
uint32_t intr : 22; /*GPIO32-48 PRO & APP CPU interrupt status*/
125118
uint32_t reserved22 : 10;
126119
};
127120
uint32_t val;
128121
} pcpu_int1;
129122
union {
130123
struct {
131-
uint32_t intr : 22;
124+
uint32_t intr : 22; /*GPIO32-48 PRO & APP CPU non-maskable interrupt status*/
132125
uint32_t reserved22 : 10;
133126
};
134127
uint32_t val;

Diff for: tools/ci/check_copyright_ignore.txt

-1
Original file line numberDiff line numberDiff line change
@@ -2097,7 +2097,6 @@ components/soc/esp32s3/include/soc/gpio_reg.h
20972097
components/soc/esp32s3/include/soc/gpio_sd_reg.h
20982098
components/soc/esp32s3/include/soc/gpio_sd_struct.h
20992099
components/soc/esp32s3/include/soc/gpio_sig_map.h
2100-
components/soc/esp32s3/include/soc/gpio_struct.h
21012100
components/soc/esp32s3/include/soc/hinf_reg.h
21022101
components/soc/esp32s3/include/soc/hinf_struct.h
21032102
components/soc/esp32s3/include/soc/host_reg.h

0 commit comments

Comments
 (0)