test_gpio.c 32 KB

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