test_touch_v1.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /*
  7. Tests for the touch sensor device driver for ESP32
  8. */
  9. #include "sdkconfig.h"
  10. #if CONFIG_IDF_TARGET_ESP32
  11. #include "esp_system.h"
  12. #include "driver/touch_pad.h"
  13. #include "unity.h"
  14. #include "esp_system.h"
  15. #include "freertos/FreeRTOS.h"
  16. #include "freertos/task.h"
  17. #include "esp_log.h"
  18. #include "nvs_flash.h"
  19. #include "test_utils.h"
  20. #include "soc/rtc_cntl_reg.h"
  21. #include "soc/rtc_cntl_struct.h"
  22. #include "soc/sens_reg.h"
  23. #include "soc/sens_struct.h"
  24. #include "soc/rtc_cntl_reg.h"
  25. #include "soc/rtc_cntl_struct.h"
  26. #include "soc/rtc_io_reg.h"
  27. #include "soc/rtc_io_struct.h"
  28. #include "esp_rom_sys.h"
  29. static const char *TAG = "test_touch";
  30. #define TOUCH_READ_INVALID_VAL (0)
  31. #define TOUCHPAD_FILTER_TOUCH_PERIOD (10)
  32. #define TOUCH_REG_BASE_TEST() ({ \
  33. TEST_ASSERT_EQUAL_UINT32(RTC_CNTL_BROWN_OUT_REG, &RTCCNTL.brown_out.val); \
  34. TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(SENS_SARDATE_REG, SENS_SAR_DATE), SENS.sardate.sar_date); \
  35. TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(RTC_IO_DATE_REG, RTC_IO_IO_DATE), RTCIO.date.date); \
  36. })
  37. #define TOUCH_READ_ERROR (100)
  38. #define TEST_TOUCH_COUNT_NUM (10)
  39. #define TEST_TOUCH_CHANNEL (3)
  40. static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = {
  41. // TOUCH_PAD_NUM0,
  42. // TOUCH_PAD_NUM1 is GPIO0, for download.
  43. // TOUCH_PAD_NUM2,
  44. // TOUCH_PAD_NUM3,
  45. // TOUCH_PAD_NUM4,
  46. // TOUCH_PAD_NUM5,
  47. // TOUCH_PAD_NUM6,
  48. TOUCH_PAD_NUM7,
  49. TOUCH_PAD_NUM8,
  50. TOUCH_PAD_NUM9,
  51. };
  52. static void printf_touch_hw_read(const char *str)
  53. {
  54. uint16_t touch_value;
  55. printf("[%s] ", str);
  56. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  57. while (!touch_pad_meas_is_done()) ;
  58. touch_pad_read_raw_data(touch_list[i], &touch_value);
  59. printf("[%d]%d ", touch_list[i], touch_value);
  60. }
  61. printf("\r\n");
  62. }
  63. /*
  64. * Change the slope to get larger value from touch sensor.
  65. */
  66. static void test_press_fake(touch_pad_t pad_num)
  67. {
  68. touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_2, TOUCH_PAD_TIE_OPT_DEFAULT);
  69. }
  70. /*
  71. * Change the slope to get smaller value from touch sensor.
  72. */
  73. static void test_release_fake(touch_pad_t pad_num)
  74. {
  75. touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT);
  76. }
  77. static esp_err_t test_touch_sw_read_test_runner(void)
  78. {
  79. ESP_LOGI(TAG, "%s", __func__);
  80. uint16_t touch_value;
  81. TEST_ESP_OK( touch_pad_init() );
  82. TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) );
  83. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  84. TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) );
  85. }
  86. // Start task to read values sensed by pads
  87. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  88. printf("test T%d\n", touch_list[i]);
  89. touch_pad_read(touch_list[i], &touch_value);
  90. printf("T%d:[%4d] ", touch_list[i], touch_value);
  91. }
  92. printf("\n");
  93. TEST_ESP_OK( touch_pad_deinit() );
  94. return ESP_OK;
  95. }
  96. static esp_err_t test_touch_sw_read(void)
  97. {
  98. ESP_LOGI(TAG, "%s", __func__);
  99. uint16_t touch_value;
  100. TEST_ESP_OK( touch_pad_init() );
  101. TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) );
  102. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  103. TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) );
  104. }
  105. // Start task to read values sensed by pads
  106. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  107. printf("test T%d\n", touch_list[i]);
  108. TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_value) );
  109. printf("T%d:[%4d] ", touch_list[i], touch_value);
  110. TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value);
  111. }
  112. printf("\n");
  113. TEST_ESP_OK( touch_pad_deinit() );
  114. return ESP_OK;
  115. }
  116. static esp_err_t test_touch_timer_read(void)
  117. {
  118. ESP_LOGI(TAG, "%s", __func__);
  119. uint16_t touch_value[TEST_TOUCH_CHANNEL], touch_temp[TEST_TOUCH_CHANNEL];
  120. int t_cnt = TEST_TOUCH_COUNT_NUM;
  121. TEST_ESP_OK( touch_pad_init() );
  122. TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) );
  123. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  124. TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) );
  125. }
  126. // Start task to read values sensed by pads
  127. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  128. TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_value[i]) );
  129. printf("T%d:[%4d] ", touch_list[i], touch_value[i]);
  130. TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value[i]);
  131. }
  132. while (t_cnt--) {
  133. // Start task to read values sensed by pads
  134. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  135. TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_temp[i]) );
  136. TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp[i]);
  137. TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]);
  138. }
  139. vTaskDelay(50 / portTICK_PERIOD_MS);
  140. }
  141. TEST_ESP_OK( touch_pad_deinit() );
  142. return ESP_OK;
  143. }
  144. static esp_err_t test_touch_filtered_read(void)
  145. {
  146. ESP_LOGI(TAG, "%s", __func__);
  147. uint16_t touch_value, touch_temp;
  148. int t_cnt = TEST_TOUCH_COUNT_NUM;
  149. TEST_ESP_OK( touch_pad_init() );
  150. TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) );
  151. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  152. TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) );
  153. }
  154. // Initialize and start a software filter to detect slight change of capacitance.
  155. touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD);
  156. vTaskDelay(10 / portTICK_PERIOD_MS);
  157. while (t_cnt--) {
  158. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  159. TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_value) );
  160. TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value);
  161. TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value) );
  162. TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value);
  163. TEST_ESP_OK( touch_pad_read_filtered(touch_list[i], &touch_temp) );
  164. TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp);
  165. TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value);
  166. printf("T%d:[%4d] ", touch_list[i], touch_value);
  167. }
  168. vTaskDelay(50 / portTICK_PERIOD_MS);
  169. }
  170. printf("\n");
  171. TEST_ESP_OK( touch_pad_deinit() );
  172. return ESP_OK;
  173. }
  174. // test the basic configuration function with right parameters and error parameters
  175. TEST_CASE("Touch Sensor all channel read test", "[touch]")
  176. {
  177. TOUCH_REG_BASE_TEST();
  178. test_touch_sw_read_test_runner();
  179. TEST_ESP_OK( test_touch_sw_read() );
  180. TEST_ESP_OK( test_touch_timer_read() );
  181. TEST_ESP_OK( test_touch_filtered_read() );
  182. }
  183. static int test_touch_parameter(touch_pad_t pad_num, int meas_time, int slp_time, int vol_h, int vol_l, int vol_a, int slope)
  184. {
  185. ESP_LOGI(TAG, "%s", __func__);
  186. uint16_t touch_value;
  187. TEST_ESP_OK( touch_pad_init() );
  188. TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) );
  189. TEST_ESP_OK( touch_pad_config(pad_num, TOUCH_READ_INVALID_VAL) );
  190. touch_pad_set_meas_time(slp_time, meas_time);
  191. touch_pad_set_voltage(vol_h, vol_l, vol_a);
  192. touch_pad_set_cnt_mode(pad_num, slope, TOUCH_PAD_TIE_OPT_DEFAULT);
  193. // Initialize and start a software filter to detect slight change of capacitance.
  194. touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD);
  195. vTaskDelay(500 / portTICK_PERIOD_MS);
  196. // Start task to read values sensed by pads
  197. TEST_ESP_OK( touch_pad_read(pad_num, &touch_value) );
  198. TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value);
  199. printf("T%d:[%4d] ", pad_num, touch_value);
  200. TEST_ESP_OK( touch_pad_read_raw_data(pad_num, &touch_value) );
  201. TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value);
  202. printf("T%d:[%4d] ", pad_num, touch_value);
  203. TEST_ESP_OK( touch_pad_read_filtered(pad_num, &touch_value) );
  204. TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value);
  205. printf("T%d:[%4d] \n", pad_num, touch_value);
  206. TEST_ESP_OK( touch_pad_deinit() );
  207. return touch_value;
  208. }
  209. TEST_CASE("Touch Sensor parameters test", "[touch]")
  210. {
  211. int touch_val[5] = {0};
  212. ESP_LOGI(TAG, "Charge / incharge voltage level test");
  213. touch_val[0] = test_touch_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT,
  214. TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V,
  215. TOUCH_PAD_SLOPE_DEFAULT);
  216. touch_val[1] = test_touch_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT,
  217. TOUCH_HVOLT_2V5, TOUCH_LVOLT_0V6, TOUCH_HVOLT_ATTEN_1V,
  218. TOUCH_PAD_SLOPE_DEFAULT);
  219. touch_val[2] = test_touch_parameter(touch_list[0], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT,
  220. TOUCH_HVOLT_2V4, TOUCH_LVOLT_0V8, TOUCH_HVOLT_ATTEN_1V5,
  221. TOUCH_PAD_SLOPE_DEFAULT);
  222. TEST_ASSERT_GREATER_OR_EQUAL(touch_val[0], touch_val[1]);
  223. TEST_ASSERT_GREATER_OR_EQUAL(touch_val[1], touch_val[2]);
  224. ESP_LOGI(TAG, "Measure time / sleep time test");
  225. touch_val[0] = test_touch_parameter(touch_list[0], 0xff, 0xa,
  226. TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT);
  227. touch_val[1] = test_touch_parameter(touch_list[0], 0x1ff, 0xf,
  228. TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT);
  229. touch_val[2] = test_touch_parameter(touch_list[0], 0x2fff, 0x1f,
  230. TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT);
  231. TEST_ASSERT_GREATER_OR_EQUAL(touch_val[0], touch_val[1]);
  232. TEST_ASSERT_GREATER_OR_EQUAL(touch_val[1], touch_val[2]);
  233. ESP_LOGI(TAG, "Charge / incharge slope level test");
  234. touch_val[0] = test_touch_parameter(touch_list[1], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT,
  235. TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 1);
  236. touch_val[1] = test_touch_parameter(touch_list[1], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT,
  237. TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 3);
  238. touch_val[2] = test_touch_parameter(touch_list[1], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT,
  239. TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 7);
  240. TEST_ASSERT_GREATER_OR_EQUAL(touch_val[0], touch_val[1]);
  241. TEST_ASSERT_GREATER_OR_EQUAL(touch_val[1], touch_val[2]);
  242. }
  243. static bool s_pad_activated[TOUCH_PAD_MAX];
  244. static void test_touch_intr_cb(void *arg)
  245. {
  246. uint32_t pad_intr = touch_pad_get_status();
  247. esp_rom_printf("T%x ", pad_intr);
  248. //clear interrupt
  249. touch_pad_clear_status();
  250. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  251. if ((pad_intr >> touch_list[i]) & 0x1) {
  252. s_pad_activated[touch_list[i]] = true;
  253. }
  254. }
  255. }
  256. static esp_err_t test_touch_interrupt(void)
  257. {
  258. ESP_LOGI(TAG, "%s", __func__);
  259. uint16_t touch_value;
  260. TEST_ESP_OK( touch_pad_init() );
  261. TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) );
  262. touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
  263. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  264. TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) );
  265. }
  266. // Initialize and start a software filter to detect slight change of capacitance.
  267. touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD);
  268. vTaskDelay(10 / portTICK_PERIOD_MS);
  269. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  270. //read filtered value
  271. TEST_ESP_OK( touch_pad_read_filtered(touch_list[i], &touch_value) );
  272. ESP_LOGI(TAG, "test init: touch pad [%d] val is %d", touch_list[i], touch_value);
  273. //set interrupt threshold.
  274. TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * 2 / 3) );
  275. }
  276. // Register touch interrupt ISR
  277. TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL) );
  278. TEST_ESP_OK( touch_pad_clear_status() );
  279. TEST_ESP_OK( touch_pad_intr_enable() );
  280. int test_cnt = TEST_TOUCH_COUNT_NUM;
  281. while (test_cnt--) {
  282. ESP_LOGI(TAG, "touch push");
  283. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  284. test_press_fake(touch_list[i]);
  285. }
  286. vTaskDelay(100 / portTICK_PERIOD_MS);
  287. printf_touch_hw_read("push");
  288. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  289. if (s_pad_activated[touch_list[i]] == false) {
  290. ESP_LOGE(TAG, "touch%d not active", touch_list[i]);
  291. TEST_FAIL();
  292. }
  293. }
  294. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  295. s_pad_activated[touch_list[i]] = 0;
  296. }
  297. ESP_LOGI(TAG, "touch release");
  298. for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) {
  299. test_release_fake(touch_list[i]);
  300. }
  301. printf_touch_hw_read("release");
  302. }
  303. TEST_ESP_OK( touch_pad_deinit() );
  304. return ESP_OK;
  305. }
  306. TEST_CASE("Touch Sensor interrupt test", "[touch]")
  307. {
  308. TEST_ESP_OK( test_touch_interrupt() );
  309. }
  310. #endif // CONFIG_IDF_TARGET_ESP32