test_gpio.c 30 KB

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