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 GPIO18 and GPIO19
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 "driver/rtc_io.h"
17 #include "freertos/FreeRTOS.h"
18 #include "freertos/task.h"
19 #include "freertos/queue.h"
20 #include "esp_err.h"
21 #include "esp_log.h"
22 #include "soc/rtc_io_periph.h"
23 
24 #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3, ESP32C3)
25 
26 #define RTCIO_CHECK(condition) TEST_ASSERT_MESSAGE((condition == ESP_OK), "ret is not ESP_OK")
27 #define RTCIO_VERIFY(condition, msg) TEST_ASSERT_MESSAGE((condition), msg)
28 
29 #define TEST_COUNT 10
30 static const char *TAG = "rtcio_test";
31 
32 #ifdef CONFIG_IDF_TARGET_ESP32
33 #define TEST_GPIO_PIN_COUNT 16
34 const int s_test_map[TEST_GPIO_PIN_COUNT] = {
35     // GPIO_NUM_0,    //GPIO0   // Workaround: GPIO0 is strap pin, can not be used pullup/pulldown test.
36     GPIO_NUM_2,    //GPIO2
37     GPIO_NUM_4,    //GPIO4
38     // GPIO_NUM_12,   //GPIO12  // Workaround: GPIO12 is strap pin, can not be used pullup/pulldown test.
39     GPIO_NUM_13,   //GPIO13
40     GPIO_NUM_14,   //GPIO14
41     GPIO_NUM_15,   //GPIO15
42     GPIO_NUM_25,   //GPIO25
43     GPIO_NUM_26,   //GPIO26
44     GPIO_NUM_27,   //GPIO27
45     GPIO_NUM_32,   //GPIO32
46     GPIO_NUM_33,   //GPIO33
47     GPIO_NUM_34,   //GPIO34
48     GPIO_NUM_35,   //GPIO35
49     GPIO_NUM_36,   //GPIO36
50     GPIO_NUM_37,   //GPIO37
51     GPIO_NUM_38,   //GPIO38
52     GPIO_NUM_39,   //GPIO39
53 };
54 #elif defined CONFIG_IDF_TARGET_ESP32S2
55 #define TEST_GPIO_PIN_COUNT 20
56 const int s_test_map[TEST_GPIO_PIN_COUNT] = {
57     // GPIO_NUM_0,    //GPIO0   // Workaround: GPIO0 is strap pin, can not be used pullup/pulldown test.
58     GPIO_NUM_1,    //GPIO1
59     GPIO_NUM_2,    //GPIO2
60     GPIO_NUM_3,    //GPIO3
61     GPIO_NUM_4,    //GPIO4
62     GPIO_NUM_5,    //GPIO5
63     GPIO_NUM_6,    //GPIO6
64     GPIO_NUM_7,    //GPIO7
65     GPIO_NUM_8,    //GPIO8
66     GPIO_NUM_9,    //GPIO9
67     GPIO_NUM_10,   //GPIO10
68     GPIO_NUM_11,   //GPIO11
69     GPIO_NUM_12,   //GPIO12
70     GPIO_NUM_13,   //GPIO13
71     GPIO_NUM_14,   //GPIO14
72     GPIO_NUM_15,   //GPIO15
73     GPIO_NUM_16,   //GPIO16
74     GPIO_NUM_17,   //GPIO17
75     // GPIO_NUM_18,   //GPIO18  // Workaround: IO18 is pullup outside in ESP32S2-Saola Runner.
76     GPIO_NUM_19,   //GPIO19
77     GPIO_NUM_20,   //GPIO20
78     GPIO_NUM_21,   //GPIO21
79 };
80 #endif
81 
82 /*
83  * Test output/input function.
84  */
85 TEST_CASE("RTCIO input/output test", "[rtcio]")
86 {
87     ESP_LOGI(TAG, "RTCIO input/output test");
88     // init rtcio
89     for (int i = 0; i < GPIO_PIN_COUNT; i++) {
90         if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) {
91             RTCIO_CHECK( rtc_gpio_init(i) );
92             RTCIO_CHECK( rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT) );
93             RTCIO_CHECK( rtc_gpio_pullup_dis(i) );
94             RTCIO_CHECK( rtc_gpio_pulldown_dis(i) );
95             ESP_LOGI(TAG, "gpio %d init", i);
96         }
97     }
98 
99     for (int cnt = 0; cnt < TEST_COUNT; cnt++) {
100         uint32_t level = cnt % 2;
101         ESP_LOGI(TAG, "RTCIO output level %d", level);
102         for (int i = 0; i < GPIO_PIN_COUNT; i++) {
103             if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) {
104                 RTCIO_CHECK( rtc_gpio_set_level(i, level) );
105                 vTaskDelay(10 / portTICK_RATE_MS);
106                 if (rtc_gpio_get_level(i) != level) {
107                     ESP_LOGE(TAG, "RTCIO input/output test err, gpio%d", i);
108                 }
109             }
110         }
111         vTaskDelay(100 / portTICK_RATE_MS);
112     }
113 
114     // Deinit rtcio
115     for (int i = 0; i < GPIO_PIN_COUNT; i++) {
116         if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) {
117             RTCIO_CHECK( rtc_gpio_deinit(i) );
118         }
119     }
120     ESP_LOGI(TAG, "RTCIO input/output test over");
121 }
122 
123 /*
124  * Test pullup/pulldown function.
125  * Note: extern circuit should not connect.
126  */
127 TEST_CASE("RTCIO pullup/pulldown test", "[rtcio]")
128 {
129     ESP_LOGI(TAG, "RTCIO pullup/pulldown test");
130     // init rtcio
131     for (int i = 0; i < TEST_GPIO_PIN_COUNT; i++) {
132         int num = rtc_io_number_get(s_test_map[i]);
133         if (rtc_gpio_is_valid_gpio(s_test_map[i]) && num > 0 && rtc_io_desc[num].pullup != 0) {
134             RTCIO_CHECK( rtc_gpio_init(s_test_map[i]) );
135             RTCIO_CHECK( rtc_gpio_set_direction(s_test_map[i], RTC_GPIO_MODE_INPUT_ONLY) );
136             RTCIO_CHECK( rtc_gpio_pullup_dis(s_test_map[i]) );
137             RTCIO_CHECK( rtc_gpio_pulldown_dis(s_test_map[i]) );
138             ESP_LOGI(TAG, "gpio %d init", s_test_map[i]);
139         }
140     }
141 
142     for (int cnt = 0; cnt < TEST_COUNT; cnt++) {
143         uint32_t level = cnt % 2;
144         ESP_LOGI(TAG, "RTCIO pull level %d", level);
145         for (int i = 0; i < TEST_GPIO_PIN_COUNT; i++) {
146             int num = rtc_io_number_get(s_test_map[i]);
147             if (rtc_gpio_is_valid_gpio(s_test_map[i]) && num > 0 && rtc_io_desc[num].pullup != 0) {
148                 if (level) {
149                     RTCIO_CHECK( rtc_gpio_pulldown_dis(s_test_map[i]) );
150                     RTCIO_CHECK( rtc_gpio_pullup_en(s_test_map[i]) );
151                 } else {
152                     RTCIO_CHECK( rtc_gpio_pullup_dis(s_test_map[i]) );
153                     RTCIO_CHECK( rtc_gpio_pulldown_en(s_test_map[i]) );
154                 }
155                 vTaskDelay(20 / portTICK_RATE_MS);
156                 if (rtc_gpio_get_level(s_test_map[i]) != level) {
157                     ESP_LOGE(TAG, "RTCIO pullup/pulldown test err, gpio%d", s_test_map[i]);
158                 }
159             }
160         }
161         vTaskDelay(100 / portTICK_RATE_MS);
162     }
163 
164     // Deinit rtcio
165     for (int i = 0; i < TEST_GPIO_PIN_COUNT; i++) {
166         int num = rtc_io_number_get(s_test_map[i]);
167         if (rtc_gpio_is_valid_gpio(s_test_map[i]) && num > 0 && rtc_io_desc[num].pullup != 0) {
168             RTCIO_CHECK( rtc_gpio_deinit(s_test_map[i]) );
169         }
170     }
171     ESP_LOGI(TAG, "RTCIO pullup/pulldown test over");
172 }
173 
174 /*
175  * Test output OD function.
176  */
177 TEST_CASE("RTCIO output OD test", "[rtcio]")
178 {
179     ESP_LOGI(TAG, "RTCIO output OD test");
180     // init rtcio
181     for (int i = 0; i < GPIO_PIN_COUNT; i++) {
182         if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) {
183             RTCIO_CHECK( rtc_gpio_init(i) );
184             RTCIO_CHECK( rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT_OD) );
185             RTCIO_CHECK( rtc_gpio_pullup_en(i) );
186             RTCIO_CHECK( rtc_gpio_pulldown_dis(i) );
187             ESP_LOGI(TAG, "gpio %d init", i);
188         }
189     }
190 
191     for (int cnt = 0; cnt < TEST_COUNT; cnt++) {
192         uint32_t level = cnt % 2;
193         ESP_LOGI(TAG, "RTCIO output level %d", level);
194         for (int i = 0; i < GPIO_PIN_COUNT; i++) {
195             if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) {
196                 RTCIO_CHECK( rtc_gpio_set_level(i, level) );
197                 vTaskDelay(10 / portTICK_RATE_MS);
198                 if (rtc_gpio_get_level(i) != level) {
199                     ESP_LOGE(TAG, "RTCIO output OD test err, gpio%d", i);
200                 }
201             }
202         }
203         vTaskDelay(100 / portTICK_RATE_MS);
204     }
205 
206     // Deinit rtcio
207     for (int i = 0; i < GPIO_PIN_COUNT; i++) {
208         if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) {
209             RTCIO_CHECK( rtc_gpio_deinit(i) );
210         }
211     }
212     ESP_LOGI(TAG, "RTCIO output OD test over");
213 }
214 
215 /*
216  * Test rtcio hold function.
217  */
218 TEST_CASE("RTCIO output hold test", "[rtcio]")
219 {
220     ESP_LOGI(TAG, "RTCIO output hold test");
221     // init rtcio
222     for (int i = 0; i < GPIO_PIN_COUNT; i++) {
223         if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) {
224             RTCIO_CHECK( rtc_gpio_init(i) );
225             RTCIO_CHECK( rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT_OD) );
226             RTCIO_CHECK( rtc_gpio_pullup_en(i) );
227             RTCIO_CHECK( rtc_gpio_pulldown_dis(i) );
228             RTCIO_CHECK( rtc_gpio_set_level(i, 1) );
229             ESP_LOGI(TAG, "gpio %d init, level 1", i);
230         }
231     }
232 
233     // hold all output rtcio.
234     for (int i = 0; i < GPIO_PIN_COUNT; i++) {
235         if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) {
236             RTCIO_CHECK( rtc_gpio_hold_en(i) );
237             vTaskDelay(10 / portTICK_RATE_MS);
238             RTCIO_CHECK( rtc_gpio_set_level(i, 0) );
239             ESP_LOGI(TAG, "RTCIO output pin hold, then set level 0");
240             vTaskDelay(10 / portTICK_RATE_MS);
241             if (rtc_gpio_get_level(i) == 0) {
242                 ESP_LOGE(TAG, "RTCIO hold test err, gpio%d", i);
243             }
244         }
245     }
246 
247     //unhold all rtcio.
248     for (int i = 0; i < GPIO_PIN_COUNT; i++) {
249         if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) {
250             RTCIO_CHECK( rtc_gpio_hold_dis(i) );
251         }
252     }
253 
254     // check the unhold status
255     for (int cnt = 0; cnt < 4; cnt++) {
256         uint32_t level = cnt % 2;
257         ESP_LOGI(TAG, "RTCIO output level %d", level);
258         for (int i = 0; i < GPIO_PIN_COUNT; i++) {
259             if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) {
260                 RTCIO_CHECK( rtc_gpio_set_level(i, level) );
261                 vTaskDelay(10 / portTICK_RATE_MS);
262                 if (rtc_gpio_get_level(i) != level) {
263                     ESP_LOGE(TAG, "RTCIO output OD test err, gpio%d", i);
264                 }
265             }
266         }
267         vTaskDelay(100 / portTICK_RATE_MS);
268     }
269 
270     // Deinit rtcio
271     for (int i = 0; i < GPIO_PIN_COUNT; i++) {
272         if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) {
273             RTCIO_CHECK( rtc_gpio_deinit(i) );
274         }
275     }
276     ESP_LOGI(TAG, "RTCIO hold test over");
277 }
278 
279 #endif
280