1 /**
2  * About test environment UT_T1_GPIO:
3  * Please connect GPIO18 and GPIO19
4  */
5 #include <stdio.h>
6 #include <string.h>
7 
8 #include "esp_system.h"
9 #include "esp_sleep.h"
10 #include "unity.h"
11 #include "driver/gpio.h"
12 #include "freertos/FreeRTOS.h"
13 #include "freertos/task.h"
14 #include "freertos/queue.h"
15 #include "sdkconfig.h"
16 #include "esp_rom_uart.h"
17 #include "esp_rom_sys.h"
18 
19 
20 #define WAKE_UP_IGNORE 1  // gpio_wakeup function development is not completed yet, set it deprecated.
21 
22 #if CONFIG_IDF_TARGET_ESP32
23 #define TEST_GPIO_EXT_OUT_IO        18  // default output GPIO
24 #define TEST_GPIO_EXT_IN_IO         19  // default input GPIO
25 #define TEST_GPIO_OUTPUT_PIN        23
26 #define TEST_GPIO_INPUT_ONLY_PIN    34
27 #define TEST_GPIO_OUTPUT_MAX        GPIO_NUM_34
28 #elif CONFIG_IDF_TARGET_ESP32S2
29 // ESP32_S2 DEVKIC uses IO19 and IO20 as USB functions, so it is necessary to avoid using IO19, otherwise GPIO io pull up/down function cannot pass
30 // Also the first version of ESP32-S2-Saola has pullup issue on GPIO18, which is tied to 3V3 on the
31 // runner. Also avoid using GPIO18.
32 #define TEST_GPIO_EXT_OUT_IO        17  // default output GPIO
33 #define TEST_GPIO_EXT_IN_IO         21  // default input GPIO
34 #define TEST_GPIO_OUTPUT_PIN        12
35 #define TEST_GPIO_INPUT_ONLY_PIN    46
36 #define TEST_GPIO_OUTPUT_MAX        GPIO_NUM_46
37 #elif CONFIG_IDF_TARGET_ESP32S3
38 #define TEST_GPIO_EXT_OUT_IO        19  // default output GPIO
39 #define TEST_GPIO_EXT_IN_IO         20  // default input GPIO
40 #define TEST_GPIO_OUTPUT_PIN        12
41 #define TEST_GPIO_INPUT_ONLY_PIN    46
42 #define TEST_GPIO_OUTPUT_MAX        GPIO_NUM_47
43 #elif CONFIG_IDF_TARGET_ESP32C3
44 #define TEST_GPIO_EXT_OUT_IO        2  // default output GPIO
45 #define TEST_GPIO_EXT_IN_IO         3  // default input GPIO
46 #define TEST_GPIO_OUTPUT_PIN        1
47 #define TEST_GPIO_OUTPUT_MAX        GPIO_NUM_21
48 #endif
49 
50 // define public test io on all boards(esp32, esp32s2, esp32s3, esp32c3)
51 #define TEST_IO_9 GPIO_NUM_9
52 #define TEST_IO_10 GPIO_NUM_10
53 
54 static volatile int disable_intr_times = 0;  // use this to calculate how many times it go into interrupt
55 static volatile int level_intr_times = 0;  // use this to get how many times the level interrupt happened
56 static volatile int edge_intr_times = 0;   // use this to get how many times the edge interrupt happened
57 #if !WAKE_UP_IGNORE
58 static bool wake_up_result = false;  // use this to judge the wake up event happen or not
59 #endif
60 
61 
62 /**
63  * do some initialization operation in this function
64  * @param num: it is the destination GPIO wanted to be initialized
65  *
66  */
init_io(gpio_num_t num)67 static gpio_config_t init_io(gpio_num_t num)
68 {
69     TEST_ASSERT(num < TEST_GPIO_OUTPUT_MAX);
70     gpio_config_t io_conf;
71     io_conf.intr_type = GPIO_INTR_DISABLE;
72     io_conf.mode = GPIO_MODE_OUTPUT;
73     io_conf.pin_bit_mask = (1ULL << num);
74     io_conf.pull_down_en = 0;
75     io_conf.pull_up_en = 0;
76     return io_conf;
77 }
78 
79 #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
80 //No runners
81 // edge interrupt event
gpio_isr_edge_handler(void * arg)82 static void gpio_isr_edge_handler(void* arg)
83 {
84     uint32_t gpio_num = (uint32_t) arg;
85     esp_rom_printf("GPIO[%d] intr, val: %d\n", gpio_num, gpio_get_level(gpio_num));
86     edge_intr_times++;
87 }
88 
89 // level interrupt event with "gpio_intr_disable"
gpio_isr_level_handler(void * arg)90 static void gpio_isr_level_handler(void* arg)
91 {
92     uint32_t gpio_num = (uint32_t) arg;
93     disable_intr_times++;
94     esp_rom_printf("GPIO[%d] intr, val: %d, disable_intr_times = %d\n", gpio_num, gpio_get_level(gpio_num), disable_intr_times);
95     gpio_intr_disable(gpio_num);
96 }
97 
98 // level interrupt event
gpio_isr_level_handler2(void * arg)99 static void gpio_isr_level_handler2(void* arg)
100 {
101     uint32_t gpio_num = (uint32_t) arg;
102     level_intr_times++;
103     esp_rom_printf("GPIO[%d] intr, val: %d\n", gpio_num, gpio_get_level(gpio_num));
104     if(gpio_get_level(gpio_num)) {
105         gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
106     }else{
107         gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
108     }
109     esp_rom_printf("GPIO[%d] intr, val: %d, level_intr_times = %d\n", TEST_GPIO_EXT_OUT_IO, gpio_get_level(TEST_GPIO_EXT_OUT_IO), level_intr_times);
110     esp_rom_printf("GPIO[%d] intr, val: %d, level_intr_times = %d\n", gpio_num, gpio_get_level(gpio_num), level_intr_times);
111 }
112 #endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
113 
114 #if !WAKE_UP_IGNORE
115 // get result of waking up or not
sleep_wake_up(void * arg)116 static void sleep_wake_up(void *arg)
117 {
118     gpio_config_t io_config = init_io(TEST_GPIO_EXT_IN_IO);
119     io_config.mode = GPIO_MODE_INPUT;
120     gpio_config(&io_config);
121     TEST_ESP_OK(gpio_wakeup_enable(TEST_GPIO_EXT_IN_IO, GPIO_INTR_HIGH_LEVEL));
122     esp_light_sleep_start();
123     wake_up_result = true;
124 }
125 
126 // wake up light sleep event
trigger_wake_up(void * arg)127 static void trigger_wake_up(void *arg)
128 {
129     gpio_config_t io_config = init_io(TEST_GPIO_EXT_OUT_IO);
130     gpio_config(&io_config);
131     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
132     gpio_install_isr_service(0);
133     gpio_isr_handler_add(TEST_GPIO_EXT_OUT_IO, gpio_isr_level_handler, (void*) TEST_GPIO_EXT_IN_IO);
134     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
135     vTaskDelay(100 / portTICK_RATE_MS);
136 }
137 #endif //!WAKE_UP_IGNORE
138 
prompt_to_continue(const char * str)139 static void prompt_to_continue(const char* str)
140 {
141     printf("%s , please press \"Enter\" to go on!\n", str);
142     char sign[5] = {0};
143     while(strlen(sign) == 0) {
144         /* Flush anything already in the RX buffer */
145         while(esp_rom_uart_rx_one_char((uint8_t *) sign) == ETS_OK) {
146         }
147         /* Read line */
148         esp_rom_uart_rx_string((uint8_t*) sign, sizeof(sign) - 1);
149     }
150 }
151 
drive_capability_set_get(gpio_num_t num,gpio_drive_cap_t capability)152 static void drive_capability_set_get(gpio_num_t num, gpio_drive_cap_t capability)
153 {
154     gpio_config_t pad_io = init_io(num);
155     TEST_ESP_OK(gpio_config(&pad_io));
156     TEST_ASSERT(gpio_set_drive_capability(num, GPIO_DRIVE_CAP_MAX) == ESP_ERR_INVALID_ARG);
157 
158     gpio_drive_cap_t cap;
159     TEST_ESP_OK(gpio_set_drive_capability(num, capability));
160     TEST_ESP_OK(gpio_get_drive_capability(num, &cap));
161     TEST_ASSERT_EQUAL_INT(cap, capability);
162 }
163 
164 
165 // test the basic configuration function with right parameters and error parameters
166 TEST_CASE("GPIO config parameters test", "[gpio]")
167 {
168     //error param test
169     //ESP32 test 41 bit, ESP32-S2 test 48 bit
170     gpio_config_t io_config = { 0 };
171     io_config.intr_type = GPIO_INTR_DISABLE;
172     io_config.pin_bit_mask = ((uint64_t)1<<(GPIO_NUM_MAX+1));
173     TEST_ASSERT(gpio_config(&io_config) == ESP_ERR_INVALID_ARG);
174 
175     // test 0
176     io_config.pin_bit_mask = 0;
177     TEST_ASSERT(gpio_config(&io_config) == ESP_ERR_INVALID_ARG);
178 
179     //ESP32 test 40 bit, ESP32-S2 test 47 bit
180     io_config.pin_bit_mask = ((uint64_t)1<<GPIO_NUM_MAX);
181     TEST_ASSERT(gpio_config(&io_config) == ESP_ERR_INVALID_ARG);
182 
183     io_config.pin_bit_mask = ((uint64_t)1<<TEST_GPIO_OUTPUT_PIN);
184     TEST_ESP_OK(gpio_config(&io_config));
185 
186     //This IO is just used for input, C3 doesn't have input only pin.
187 #if !CONFIG_IDF_TARGET_ESP32C3
188     io_config.pin_bit_mask = ((uint64_t)1 << TEST_GPIO_INPUT_ONLY_PIN);
189     io_config.mode = GPIO_MODE_INPUT;
190     TEST_ESP_OK(gpio_config(&io_config));
191     io_config.mode = GPIO_MODE_OUTPUT;
192     // The pin is input only, once set as output should log something
193     TEST_ASSERT(gpio_config(&io_config) == ESP_ERR_INVALID_ARG);
194 #endif //!CONFIG_IDF_TARGET_ESP32C3
195 }
196 
197 #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
198 //No runners
199 TEST_CASE("GPIO rising edge interrupt test", "[gpio][test_env=UT_T1_GPIO]")
200 {
201     edge_intr_times = 0;  // set it as 0 prepare to test
202     //init input and output gpio
203     gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
204     gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
205     input_io.intr_type = GPIO_INTR_POSEDGE;
206     input_io.mode = GPIO_MODE_INPUT;
207     input_io.pull_up_en = 1;
208     TEST_ESP_OK(gpio_config(&output_io));
209     TEST_ESP_OK(gpio_config(&input_io));
210     TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0));
211 
212     //rising edge intr
213     TEST_ESP_OK(gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_POSEDGE));
214     TEST_ESP_OK(gpio_install_isr_service(0));
215     gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_edge_handler, (void*)TEST_GPIO_EXT_IN_IO);
216     TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1));
217     TEST_ASSERT_EQUAL_INT(edge_intr_times, 1);
218     vTaskDelay(100 / portTICK_RATE_MS);
219     gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO);
220     gpio_uninstall_isr_service();
221 }
222 
223 TEST_CASE("GPIO falling edge interrupt test", "[gpio][test_env=UT_T1_GPIO]")
224 {
225     edge_intr_times = 0;
226     gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
227     gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
228     input_io.intr_type = GPIO_INTR_POSEDGE;
229     input_io.mode = GPIO_MODE_INPUT;
230     input_io.pull_up_en = 1;
231     TEST_ESP_OK(gpio_config(&output_io));
232     TEST_ESP_OK(gpio_config(&input_io));
233     TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1));
234 
235     gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_NEGEDGE);
236     gpio_install_isr_service(0);
237     gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_edge_handler, (void*) TEST_GPIO_EXT_IN_IO);
238     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
239     vTaskDelay(100 / portTICK_RATE_MS);
240     TEST_ASSERT_EQUAL_INT(edge_intr_times, 1);
241     vTaskDelay(100 / portTICK_RATE_MS);
242     gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO);
243     gpio_uninstall_isr_service();
244 }
245 
246 TEST_CASE("GPIO both rising and falling edge interrupt test", "[gpio][test_env=UT_T1_GPIO]")
247 {
248     edge_intr_times = 0;
249     gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
250     gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
251     input_io.intr_type = GPIO_INTR_POSEDGE;
252     input_io.mode = GPIO_MODE_INPUT;
253     input_io.pull_up_en = 1;
254     TEST_ESP_OK(gpio_config(&output_io));
255     TEST_ESP_OK(gpio_config(&input_io));
256     TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0));
257     int level = 0;
258 
259     gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_ANYEDGE);
260     gpio_install_isr_service(0);
261     gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_edge_handler, (void*) TEST_GPIO_EXT_IN_IO);
262     // for rising edge in GPIO_INTR_ANYEDGE
263     while(1) {
264         level = level + 1;
265         gpio_set_level(TEST_GPIO_EXT_OUT_IO, level*0.2);
266         if(level > 10) {
267             break;
268         }
269         vTaskDelay(100 / portTICK_RATE_MS);
270     }
271     vTaskDelay(100 / portTICK_RATE_MS);
272     // for falling rdge in GPIO_INTR_ANYEDGE
273     while(1) {
274         level = level - 1;
275         gpio_set_level(TEST_GPIO_EXT_OUT_IO, level/5);
276         if(level < 0) {
277             break;
278         }
279         vTaskDelay(100 / portTICK_RATE_MS);
280     }
281     vTaskDelay(100 / portTICK_RATE_MS);
282     TEST_ASSERT_EQUAL_INT(edge_intr_times, 2);
283     vTaskDelay(100 / portTICK_RATE_MS);
284     gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO);
285     gpio_uninstall_isr_service();
286 }
287 
288 TEST_CASE("GPIO input high level trigger, cut the interrupt source exit interrupt test", "[gpio][test_env=UT_T1_GPIO]")
289 {
290     level_intr_times=0;
291     gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
292     gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
293     input_io.intr_type = GPIO_INTR_POSEDGE;
294     input_io.mode = GPIO_MODE_INPUT;
295     input_io.pull_up_en = 1;
296     TEST_ESP_OK(gpio_config(&output_io));
297     TEST_ESP_OK(gpio_config(&input_io));
298     TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0));
299 
300     gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_HIGH_LEVEL);
301     gpio_install_isr_service(0);
302     gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_level_handler2, (void*) TEST_GPIO_EXT_IN_IO);
303     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
304     vTaskDelay(100 / portTICK_RATE_MS);
305     TEST_ASSERT_EQUAL_INT_MESSAGE(level_intr_times, 1, "go into high-level interrupt more than once with cur interrupt source way");
306     gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO);
307     gpio_uninstall_isr_service();
308 
309 }
310 
311 TEST_CASE("GPIO low level interrupt test", "[gpio][test_env=UT_T1_GPIO]")
312 {
313     disable_intr_times=0;
314     gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
315     gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
316     input_io.intr_type = GPIO_INTR_POSEDGE;
317     input_io.mode = GPIO_MODE_INPUT;
318     input_io.pull_up_en = 1;
319     TEST_ESP_OK(gpio_config(&output_io));
320     TEST_ESP_OK(gpio_config(&input_io));
321     TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1));
322 
323     gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_LOW_LEVEL);
324     gpio_install_isr_service(0);
325     gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_level_handler, (void*) TEST_GPIO_EXT_IN_IO);
326     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
327     printf("get level:%d\n",gpio_get_level(TEST_GPIO_EXT_IN_IO));
328     vTaskDelay(100 / portTICK_RATE_MS);
329     TEST_ASSERT_EQUAL_INT_MESSAGE(disable_intr_times, 1, "go into low-level interrupt more than once with disable way");
330     gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO);
331     gpio_uninstall_isr_service();
332 }
333 
334 TEST_CASE("GPIO multi-level interrupt test, to cut the interrupt source exit interrupt ", "[gpio][test_env=UT_T1_GPIO]")
335 {
336     level_intr_times=0;
337     gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
338     gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
339     input_io.intr_type = GPIO_INTR_POSEDGE;
340     input_io.mode = GPIO_MODE_INPUT;
341     input_io.pull_up_en = 1;
342     TEST_ESP_OK(gpio_config(&output_io));
343     TEST_ESP_OK(gpio_config(&input_io));
344     TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0));
345 
346     gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_HIGH_LEVEL);
347     gpio_install_isr_service(0);
348     gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_level_handler2, (void*) TEST_GPIO_EXT_IN_IO);
349     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
350     vTaskDelay(100 / portTICK_RATE_MS);
351     TEST_ASSERT_EQUAL_INT_MESSAGE(level_intr_times, 1, "go into high-level interrupt more than once with cur interrupt source way");
352     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
353     vTaskDelay(200 / portTICK_RATE_MS);
354     TEST_ASSERT_EQUAL_INT_MESSAGE(level_intr_times, 2, "go into high-level interrupt more than once with cur interrupt source way");
355     gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO);
356     gpio_uninstall_isr_service();
357 }
358 
359 TEST_CASE("GPIO enable and disable interrupt test", "[gpio][test_env=UT_T1_GPIO]")
360 {
361     disable_intr_times = 0;
362     gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
363     gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
364     input_io.intr_type = GPIO_INTR_POSEDGE;
365     input_io.mode = GPIO_MODE_INPUT;
366     input_io.pull_up_en = 1;
367     TEST_ESP_OK(gpio_config(&output_io));
368     TEST_ESP_OK(gpio_config(&input_io));
369 
370     TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0)); // Because of GPIO_INTR_HIGH_LEVEL interrupt, 0 must be set first
371     TEST_ESP_OK(gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_HIGH_LEVEL));
372     TEST_ESP_OK(gpio_install_isr_service(0));
373     TEST_ESP_OK(gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_level_handler, (void*) TEST_GPIO_EXT_IN_IO));
374     TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1));
375     TEST_ESP_OK(gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO));
376     TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0));
377     TEST_ASSERT_EQUAL_INT_MESSAGE(disable_intr_times, 1, "go into high-level interrupt more than once with disable way");
378 
379     // not install service now
380     vTaskDelay(100 / portTICK_RATE_MS);
381     TEST_ESP_OK(gpio_intr_disable(TEST_GPIO_EXT_IN_IO));
382     TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1));
383     TEST_ASSERT_EQUAL_INT_MESSAGE(disable_intr_times, 1, "disable interrupt does not work, still go into interrupt!");
384 
385     gpio_uninstall_isr_service();  //uninstall the service
386     TEST_ASSERT(gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_level_handler, (void*) TEST_GPIO_EXT_IN_IO) == ESP_ERR_INVALID_STATE);
387     TEST_ASSERT(gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO) == ESP_ERR_INVALID_STATE);
388 }
389 #endif //DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
390 
391 // ESP32 Connect GPIO18 with GPIO19, ESP32-S2 Connect GPIO17 with GPIO21,
392 // ESP32-S3 Connect GPIO19 with GPIO20, ESP32C3 Connect GPIO2 with GPIO3
393 // use multimeter to test the voltage, so it is ignored in CI
394 TEST_CASE("GPIO set gpio output level test", "[gpio][ignore]")
395 {
396     gpio_config_t io_conf;
397     io_conf.intr_type = GPIO_INTR_DISABLE;
398     io_conf.mode = GPIO_MODE_OUTPUT;
399     io_conf.pin_bit_mask = (1<<TEST_GPIO_EXT_OUT_IO);
400     io_conf.pull_down_en = 0;
401     io_conf.pull_up_en = 0;
402     gpio_config(&io_conf);
403 
404     io_conf.pin_bit_mask = (1<<TEST_GPIO_EXT_IN_IO);
405     io_conf.mode = GPIO_MODE_INPUT;
406     gpio_config(&io_conf);
407 
408     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
409     // tested voltage is around 0v
410     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "get level error! the level should be low!");
411     vTaskDelay(1000 / portTICK_RATE_MS);
412     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
413     // tested voltage is around 3.3v
414     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 1, "get level error! the level should be high!");
415 
416     //This IO is just used for input, C3 doesn't have input only pin.
417 #if !CONFIG_IDF_TARGET_ESP32C3
418     io_conf.pin_bit_mask = ((uint64_t)1<<TEST_GPIO_INPUT_ONLY_PIN);
419     io_conf.mode = GPIO_MODE_OUTPUT;
420     gpio_config(&io_conf);
421     TEST_ASSERT(gpio_config(&io_conf) == ESP_ERR_INVALID_ARG);
422 #endif //!CONFIG_IDF_TARGET_ESP32C3
423 }
424 
425 // gpio17 connects to 3.3v pin, gpio19 connects to the GND pin
426 // use multimeter to test the voltage, so it is ignored in CI
427 TEST_CASE("GPIO get input level test", "[gpio][ignore]")
428 {
429     gpio_num_t num = 17;
430     int level = gpio_get_level(num);
431     printf("gpio17's level is: %d\n", level);
432     TEST_ASSERT_EQUAL_INT_MESSAGE(level, 1, "get level error! the level should be high!");
433 
434     gpio_num_t num2 = 19;
435     int level2 = gpio_get_level(num2);
436     printf("gpio19's level is: %d\n", level2);
437     TEST_ASSERT_EQUAL_INT_MESSAGE(level2, 0, "get level error! the level should be low!");
438     printf("the memory get: %d\n", esp_get_free_heap_size());
439 
440     gpio_num_t num3 = 34;  // connect with 3.3v
441     int level3 = gpio_get_level(num3);
442     printf("gpio19's level is: %d\n", level3);
443     TEST_ASSERT_EQUAL_INT_MESSAGE(level3, 0, "get level error! the level should be low!");
444     printf("the memory get: %d\n", esp_get_free_heap_size());
445     //when case finish, get the result from multimeter, the pin17 is 3.3v, the pin19 is 0.00v
446 }
447 
448 TEST_CASE("GPIO io pull up/down function", "[gpio]")
449 {
450     // First, ensure that the output IO will not affect the level
451     gpio_config_t  io_conf = init_io(TEST_GPIO_EXT_OUT_IO);
452     gpio_config(&io_conf);
453     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT);
454     io_conf = init_io(TEST_GPIO_EXT_IN_IO);
455     gpio_config(&io_conf);
456     gpio_set_direction(TEST_GPIO_EXT_IN_IO, GPIO_MODE_INPUT);
457     TEST_ESP_OK(gpio_pullup_en(TEST_GPIO_EXT_IN_IO));  // pull up first
458     vTaskDelay(100 / portTICK_RATE_MS);
459     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 1, "gpio_pullup_en error, it can't pull up");
460     TEST_ESP_OK(gpio_pulldown_dis(TEST_GPIO_EXT_IN_IO)); //can't be pull down
461     vTaskDelay(100 / portTICK_RATE_MS);
462     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 1, "gpio_pulldown_dis error, it can pull down");
463     TEST_ESP_OK(gpio_pulldown_en(TEST_GPIO_EXT_IN_IO)); // can be pull down now
464     vTaskDelay(100 / portTICK_RATE_MS);
465     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "gpio_pulldown_en error, it can't pull down");
466     TEST_ESP_OK(gpio_pullup_dis(TEST_GPIO_EXT_IN_IO)); // can't be pull up
467     vTaskDelay(100 / portTICK_RATE_MS);
468     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "gpio_pullup_dis error, it can pull up");
469 }
470 
471 #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
472 //No runners
473 TEST_CASE("GPIO output and input mode test", "[gpio][test_env=UT_T1_GPIO]")
474 {
475     //ESP32 connect io18 and io19, ESP32-S2 connect io17 and io21, ESP32-S3 connect io19 and io20, ESP32C3 Connect GPIO2 with GPIO3
476     gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
477     gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
478     gpio_config(&output_io);
479     gpio_config(&input_io);
480     int level = gpio_get_level(TEST_GPIO_EXT_IN_IO);
481 
482     //disable mode
483     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_DISABLE);
484     gpio_set_direction(TEST_GPIO_EXT_IN_IO, GPIO_MODE_OUTPUT);
485     gpio_set_level(TEST_GPIO_EXT_OUT_IO, !level);
486     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), level, "direction GPIO_MODE_DISABLE set error, it can output");
487 
488     //input mode and output mode
489     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_OUTPUT);
490     gpio_set_direction(TEST_GPIO_EXT_IN_IO, GPIO_MODE_INPUT);
491     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
492     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 1, "direction GPIO_MODE_OUTPUT set error, it can't output");
493     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
494     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
495 
496     // open drain mode(output), can just output low level
497     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_OUTPUT_OD);
498     gpio_set_direction(TEST_GPIO_EXT_IN_IO, GPIO_MODE_INPUT);
499     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
500     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
501     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
502     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
503 
504     // open drain mode(output and input), can just output low level
505     // output test
506     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT_OUTPUT_OD);
507     gpio_set_direction(TEST_GPIO_EXT_IN_IO, GPIO_MODE_INPUT);
508     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
509     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
510     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
511     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
512 
513     // GPIO_MODE_INPUT_OUTPUT mode
514     // output test
515     level = gpio_get_level(TEST_GPIO_EXT_IN_IO);
516     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT_OUTPUT);
517     gpio_set_direction(TEST_GPIO_EXT_IN_IO, GPIO_MODE_INPUT);
518     gpio_set_level(TEST_GPIO_EXT_OUT_IO, !level);
519     TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), !level, "direction set error, it can't output");
520 }
521 
522 TEST_CASE("GPIO repeate call service and isr has no memory leak test","[gpio][test_env=UT_T1_GPIO][timeout=90]")
523 {
524     gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
525     gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
526     input_io.intr_type = GPIO_INTR_POSEDGE;
527     input_io.mode = GPIO_MODE_INPUT;
528     input_io.pull_up_en = 1;
529     TEST_ESP_OK(gpio_config(&output_io));
530     TEST_ESP_OK(gpio_config(&input_io));
531     TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0));
532     //rising edge
533     uint32_t size = esp_get_free_heap_size();
534     for(int i=0;i<1000;i++) {
535         TEST_ESP_OK(gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_POSEDGE));
536         TEST_ESP_OK(gpio_install_isr_service(0));
537         TEST_ESP_OK(gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_edge_handler, (void*)TEST_GPIO_EXT_IN_IO));
538         gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
539         TEST_ESP_OK(gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO));
540         gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
541         gpio_uninstall_isr_service();
542     }
543     TEST_ASSERT_INT32_WITHIN(size, esp_get_free_heap_size(), 100);
544 }
545 #endif //DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
546 
547 #if !WAKE_UP_IGNORE
548 //this function development is not completed yet, set it ignored
549 TEST_CASE("GPIO wake up enable and disenable test", "[gpio][ignore]")
550 {
551     xTaskCreate(sleep_wake_up, "sleep_wake_up", 4096, NULL, 5, NULL);
552     xTaskCreate(trigger_wake_up, "trigger_wake_up", 4096, NULL, 5, NULL);
553     vTaskDelay(100 / portTICK_RATE_MS);
554     TEST_ASSERT_TRUE(wake_up_result);
555 
556     wake_up_result = false;
557     TEST_ESP_OK(gpio_wakeup_disable(TEST_GPIO_EXT_IN_IO));
558     gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
559     vTaskDelay(100 / portTICK_RATE_MS);
560     TEST_ASSERT_FALSE(wake_up_result);
561 }
562 #endif // !WAKE_UP_IGNORE
563 
564 // this case need the resistance to pull up the voltage or pull down the voltage
565 // ignored because the voltage needs to be tested with multimeter
566 TEST_CASE("GPIO verify only the gpio with input ability can be set pull/down", "[gpio][ignore]")
567 {
568     gpio_config_t  output_io = init_io(TEST_GPIO_EXT_OUT_IO);
569     gpio_config_t  input_io = init_io(TEST_GPIO_EXT_IN_IO);
570     gpio_config(&output_io);
571     input_io.mode = GPIO_MODE_INPUT;
572     gpio_config(&input_io);
573 
574     printf("pull up test!\n");
575     // pull up test
576     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_OUTPUT);
577     TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLUP_ONLY));
578     prompt_to_continue("mode: GPIO_MODE_OUTPUT");
579 
580     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_OUTPUT_OD);
581     TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLUP_ONLY));
582 
583     // open drain just can output low level
584     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT_OUTPUT_OD);
585     TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLUP_ONLY));
586     prompt_to_continue("mode: GPIO_MODE_OUTPUT_OD");
587 
588     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT_OUTPUT);
589     TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLUP_ONLY));
590     prompt_to_continue("mode: GPIO_MODE_INPUT_OUTPUT");
591 
592     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT);
593     TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLUP_ONLY));
594     prompt_to_continue("mode: GPIO_MODE_INPUT");
595 
596     // after pull up the level is high now
597     // pull down test
598     printf("pull down test!\n");
599 
600     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_OUTPUT);
601     TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLDOWN_ONLY));
602     prompt_to_continue("mode: GPIO_MODE_OUTPUT");
603 
604     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_OUTPUT_OD);
605     TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLDOWN_ONLY));
606     prompt_to_continue("mode: GPIO_MODE_OUTPUT_OD");
607 
608     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT_OUTPUT_OD);
609     TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLDOWN_ONLY));
610     prompt_to_continue("mode: GPIO_MODE_INPUT_OUTPUT_OD");
611 
612     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT_OUTPUT);
613     TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLDOWN_ONLY));
614     prompt_to_continue("mode: GPIO_MODE_INPUT_OUTPUT");
615 
616     gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT);
617     TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLDOWN_ONLY));
618     prompt_to_continue("mode: GPIO_MODE_INPUT");
619 }
620 
621 /**
622  * There are 5 situation for the GPIO drive capability:
623  * 1. GPIO drive weak capability test
624  * 2. GPIO drive stronger capability test
625  * 3. GPIO drive default capability test
626  * 4. GPIO drive default capability test2
627  * 5. GPIO drive strongest capability test
628  *
629  * How to test:
630  * when testing, use the sliding resistor and a multimeter
631  * adjust the resistor from low to high, 0-10k
632  * watch the current change
633  * the current test result:
634  * weak capability: (0.32-10.1)mA
635  * stronger capability: (0.32-20.0)mA
636  * default capability: (0.33-39.8)mA
637  * default capability2: (0.33-39.9)mA
638  * strongest capability: (0.33-64.2)mA
639  *
640  * the data shows:
641  * weak capability<stronger capability<default capability=default capability2<strongest capability
642  *
643  * all of these cases should be ignored that it will not run in CI
644  */
645 
646 // drive capability test
647 TEST_CASE("GPIO drive capability test", "[gpio][ignore]")
648 {
649     printf("weak capability test! please view the current change!\n");
650     drive_capability_set_get(TEST_GPIO_EXT_OUT_IO, GPIO_DRIVE_CAP_0);
651     prompt_to_continue("If this test finishes");
652 
653     printf("stronger capability test! please view the current change!\n");
654     drive_capability_set_get(TEST_GPIO_EXT_OUT_IO, GPIO_DRIVE_CAP_1);
655     prompt_to_continue("If this test finishes");
656 
657     printf("default capability test! please view the current change!\n");
658     drive_capability_set_get(TEST_GPIO_EXT_OUT_IO, GPIO_DRIVE_CAP_2);
659     prompt_to_continue("If this test finishes");
660 
661     printf("default capability2 test! please view the current change!\n");
662     drive_capability_set_get(TEST_GPIO_EXT_OUT_IO, GPIO_DRIVE_CAP_DEFAULT);
663     prompt_to_continue("If this test finishes");
664 
665     printf("strongest capability test! please view the current change!\n");
666     drive_capability_set_get(TEST_GPIO_EXT_OUT_IO, GPIO_DRIVE_CAP_3);
667     prompt_to_continue("If this test finishes");
668 }
669 
670 #if !CONFIG_FREERTOS_UNICORE
671 #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
gpio_enable_task(void * param)672 void gpio_enable_task(void *param)
673 {
674     int gpio_num = (int)param;
675     TEST_ESP_OK(gpio_intr_enable(gpio_num));
676     vTaskDelete(NULL);
677 }
678 
679 /** Test the GPIO Interrupt Enable API with dual core enabled. The GPIO ISR service routine is registered on one core.
680  * When the GPIO interrupt on another core is enabled, the GPIO interrupt will be lost.
681  * First on the core 0, Do the following steps:
682  *     1. Configure the GPIO9 input_output mode, and enable the rising edge interrupt mode.
683  *     2. Trigger the GPIO9 interrupt and check if the interrupt responds correctly.
684  *     3. Disable the GPIO9 interrupt
685  * Then on the core 1, Do the following steps:
686  *     1. Enable the GPIO9 interrupt again.
687  *     2. Trigger the GPIO9 interrupt and check if the interrupt responds correctly.
688  *
689  */
690 TEST_CASE("GPIO Enable/Disable interrupt on multiple cores", "[gpio][ignore]")
691 {
692     gpio_config_t io_conf;
693     io_conf.intr_type = GPIO_INTR_NEGEDGE;
694     io_conf.mode = GPIO_MODE_INPUT_OUTPUT;
695     io_conf.pin_bit_mask = (1ULL << TEST_IO_9);
696     io_conf.pull_down_en = 0;
697     io_conf.pull_up_en = 1;
698     TEST_ESP_OK(gpio_config(&io_conf));
699     TEST_ESP_OK(gpio_set_level(TEST_IO_9, 0));
700     TEST_ESP_OK(gpio_install_isr_service(0));
701     TEST_ESP_OK(gpio_isr_handler_add(TEST_IO_9, gpio_isr_edge_handler, (void*) TEST_IO_9));
702     vTaskDelay(1000 / portTICK_RATE_MS);
703     TEST_ESP_OK(gpio_set_level(TEST_IO_9, 1));
704     vTaskDelay(100 / portTICK_RATE_MS);
705     TEST_ESP_OK(gpio_set_level(TEST_IO_9, 0));
706     vTaskDelay(100 / portTICK_RATE_MS);
707     TEST_ESP_OK(gpio_intr_disable(TEST_IO_9));
708     TEST_ASSERT(edge_intr_times == 1);
709     xTaskCreatePinnedToCore(gpio_enable_task, "gpio_enable_task", 1024*4, (void*)TEST_IO_9, 8, NULL, (xPortGetCoreID() == 0));
710     vTaskDelay(1000 / portTICK_RATE_MS);
711     TEST_ESP_OK(gpio_set_level(TEST_IO_9, 1));
712     vTaskDelay(100 / portTICK_RATE_MS);
713     TEST_ESP_OK(gpio_set_level(TEST_IO_9, 0));
714     vTaskDelay(100 / portTICK_RATE_MS);
715     TEST_ESP_OK(gpio_intr_disable(TEST_IO_9));
716     TEST_ESP_OK(gpio_isr_handler_remove(TEST_IO_9));
717     gpio_uninstall_isr_service();
718     TEST_ASSERT(edge_intr_times == 2);
719 }
720 #endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
721 #endif //!CONFIG_FREERTOS_UNICORE
722 
723 typedef struct {
724     int gpio_num;
725     int isr_cnt;
726 } gpio_isr_param_t;
727 
gpio_isr_handler(void * arg)728 static void gpio_isr_handler(void* arg)
729 {
730     gpio_isr_param_t *param = (gpio_isr_param_t *)arg;
731     esp_rom_printf("GPIO[%d] intr, val: %d\n", param->gpio_num, gpio_get_level(param->gpio_num));
732     param->isr_cnt++;
733 }
734 
735 /** The previous GPIO interrupt service routine polls the interrupt raw status register to find the GPIO that triggered the interrupt.
736  * But this will incorrectly handle the interrupt disabled GPIOs, because the raw interrupt status register can still be set when
737  * the trigger signal arrives, even if the interrupt is disabled.
738  * First on the core 0:
739  *     1. Configure the GPIO9 and GPIO10(ESP32, ESP32C3)/GPIO21(ESP32-S2) input_output mode.
740  *     2. Enable GPIO9 dual edge triggered interrupt, enable GPIO10(ESP32, ESP32C3)/GPIO21(ESP32-S2) falling edge triggered interrupt.
741  *     3. Trigger GPIO9 interrupt, than disable the GPIO18 interrupt, and than trigger GPIO18 again(This time will not respond to the interrupt).
742  *     4. Trigger GPIO10(ESP32, ESP32C3)/GPIO21(ESP32-S2) interrupt.
743  * If the bug is not fixed, you will see, in the step 4, the interrupt of GPIO9 will also respond.
744  */
745 TEST_CASE("GPIO ISR service test", "[gpio][ignore]")
746 {
747     static gpio_isr_param_t io9_param = {
748         .gpio_num =  TEST_IO_9,
749         .isr_cnt = 0,
750     };
751     static gpio_isr_param_t io10_param = {
752         .gpio_num =  TEST_IO_10,
753         .isr_cnt = 0,
754     };
755     gpio_config_t io_conf;
756     io_conf.intr_type = GPIO_INTR_DISABLE;
757     io_conf.mode = GPIO_MODE_INPUT_OUTPUT;
758     io_conf.pin_bit_mask = (1ULL << TEST_IO_9) | (1ULL << TEST_IO_10);
759     io_conf.pull_down_en = 0;
760     io_conf.pull_up_en = 1;
761     TEST_ESP_OK(gpio_config(&io_conf));
762     TEST_ESP_OK(gpio_set_level(TEST_IO_9, 0));
763     TEST_ESP_OK(gpio_set_level(TEST_IO_10, 0));
764     TEST_ESP_OK(gpio_install_isr_service(0));
765     TEST_ESP_OK(gpio_set_intr_type(TEST_IO_9, GPIO_INTR_ANYEDGE));
766     TEST_ESP_OK(gpio_set_intr_type(TEST_IO_10, GPIO_INTR_NEGEDGE));
767     TEST_ESP_OK(gpio_isr_handler_add(TEST_IO_9, gpio_isr_handler, (void*)&io9_param));
768     TEST_ESP_OK(gpio_isr_handler_add(TEST_IO_10, gpio_isr_handler, (void*)&io10_param));
769     printf("Triggering the interrupt of GPIO9\n");
770     vTaskDelay(1000 / portTICK_RATE_MS);
771     //Rising edge
772     TEST_ESP_OK(gpio_set_level(TEST_IO_9, 1));
773     printf("Disable the interrupt of GPIO9\n");
774     vTaskDelay(100 / portTICK_RATE_MS);
775     //Disable GPIO9 interrupt, GPIO18 will not respond to the next falling edge interrupt.
776     TEST_ESP_OK(gpio_intr_disable(TEST_IO_9));
777     vTaskDelay(100 / portTICK_RATE_MS);
778     //Falling edge
779     TEST_ESP_OK(gpio_set_level(TEST_IO_9, 0));
780 
781     printf("Triggering the interrupt of GPIO10\n");
782     vTaskDelay(100 / portTICK_RATE_MS);
783     TEST_ESP_OK(gpio_set_level(TEST_IO_10, 1));
784     vTaskDelay(100 / portTICK_RATE_MS);
785     //Falling edge
786     TEST_ESP_OK(gpio_set_level(TEST_IO_10, 0));
787     vTaskDelay(100 / portTICK_RATE_MS);
788     TEST_ESP_OK(gpio_isr_handler_remove(TEST_IO_9));
789     TEST_ESP_OK(gpio_isr_handler_remove(TEST_IO_10));
790     gpio_uninstall_isr_service();
791     TEST_ASSERT((io9_param.isr_cnt == 1) && (io10_param.isr_cnt == 1));
792 }
793