test_gpio.c 32 KB

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