test_gpio.c 38 KB

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