// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /* Tests for the touch sensor device driver */ #include #include "esp_system.h" #include "driver/touch_pad.h" #include "unity.h" #include "esp_system.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include "freertos/queue.h" #include "esp_log.h" #include "test_utils.h" #include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_struct.h" #include "soc/sens_reg.h" #include "soc/sens_struct.h" #include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_struct.h" #include "soc/rtc_io_reg.h" #include "soc/rtc_io_struct.h" #include "soc/apb_ctrl_reg.h" #include "driver/rtc_io.h" #if !DISABLED_FOR_TARGETS(ESP8266, ESP32) // This testcase for ESP32S2 static const char *TAG = "test_touch"; #define PLATFORM_SELECT (1) //0: pxp; 1: chip #if (PLATFORM_SELECT == 0) //PXP platform #define SET_BREAK_POINT(flag) REG_WRITE(APB_CTRL_DATE_REG, flag) //PXP clk is slower. #define SYS_DELAY_TIME_MOM (1/40) #define RTC_SLOW_CLK_FLAG 1 // Slow clock is 32KHz. void test_pxp_deinit_io(void) { for (int i = 0; i < 22; i++) { rtc_gpio_init(i); } } #else //PXP clk is slower. #define SET_BREAK_POINT(flag) #define SYS_DELAY_TIME_MOM (1) #define RTC_SLOW_CLK_FLAG 0 // Slow clock is 32KHz. void test_pxp_deinit_io(void) { ; } #endif #define TOUCH_READ_INVALID_VAL (SOC_TOUCH_PAD_THRESHOLD_MAX) #define TOUCH_READ_ERROR (100) #define TOUCH_INTR_THRESHOLD (0.1) #define TOUCH_EXCEED_TIME_MS (1000) #define TOUCH_REG_BASE_TEST() ({ \ TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_CNTL_DATE), RTCCNTL.date.date); \ TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(SENS_SARDATE_REG, SENS_SAR_DATE), SENS.sardate.sar_date); \ TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(RTC_IO_DATE_REG, RTC_IO_IO_DATE), RTCIO.date.date); \ }) #define TEST_TOUCH_COUNT_NUM (5) #define TEST_TOUCH_CHANNEL (14) static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { // TOUCH_PAD_NUM0, is GPIO0, for download. TOUCH_PAD_NUM1, TOUCH_PAD_NUM2, TOUCH_PAD_NUM3, TOUCH_PAD_NUM4, TOUCH_PAD_NUM5, TOUCH_PAD_NUM6, TOUCH_PAD_NUM7, TOUCH_PAD_NUM8, TOUCH_PAD_NUM9, TOUCH_PAD_NUM10, TOUCH_PAD_NUM11, TOUCH_PAD_NUM12, TOUCH_PAD_NUM13, TOUCH_PAD_NUM14 }; #define TOUCH_WATERPROOF_RING_PAD TOUCH_PAD_NUM1 static touch_pad_t proximity_pad[3] = { TOUCH_PAD_NUM2, TOUCH_PAD_NUM3, TOUCH_PAD_NUM4, }; static QueueHandle_t que_touch = NULL; typedef struct touch_msg { touch_pad_intr_mask_t intr_mask; uint32_t pad_num; uint32_t pad_status; uint32_t pad_val; uint32_t slp_proxi_cnt; uint32_t slp_proxi_base; } touch_event_t; static uint32_t s_touch_timeout_mask = 0; static void printf_touch_hw_read(const char *str) { uint32_t touch_value; printf("[%s] ", str); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { touch_pad_read_raw_data(touch_list[i], &touch_value); printf("[%d]%d ", touch_list[i], touch_value); } printf("\r\n"); } static void printf_touch_baseline_read(const char *str) { uint32_t touch_value; printf("[%s] ", str); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); printf("[%d]%d ", touch_list[i], touch_value); } printf("\r\n"); } static void printf_touch_smooth_read(const char *str) { uint32_t touch_value; printf("[%s] ", str); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { touch_pad_filter_read_smooth(touch_list[i], &touch_value); printf("[%d]%d ", touch_list[i], touch_value); } printf("\r\n"); } static void test_timeout_trigger_fake(touch_pad_t pad_num) { touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_0, TOUCH_PAD_TIE_OPT_DEFAULT); } static void test_timeout_normal(touch_pad_t pad_num) { touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); } /* * Change the slope to get larger value from touch sensor. */ static void test_press_fake(touch_pad_t pad_num) { touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_3, TOUCH_PAD_TIE_OPT_DEFAULT); } /* * Change the slope to get larger value from touch sensor. */ static void test_release_fake(touch_pad_t pad_num) { touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); } static void test_touch_push_all(void) { ESP_LOGI(TAG, "touch push"); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { test_press_fake(touch_list[i]); } } static void test_touch_release_all(void) { ESP_LOGI(TAG, "touch release"); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { test_release_fake(touch_list[i]); } } /* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ static void test_touch_baseline_not_update(void) { uint32_t touch_val[TEST_TOUCH_CHANNEL] = {0}; uint32_t touch_temp[TEST_TOUCH_CHANNEL] = {0}; for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_val[i]) ); } for (int i = 0; i < 10; i++) { vTaskDelay(20 / portTICK_PERIOD_MS); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_temp[i]) ); TEST_ASSERT_EQUAL(touch_temp[i], touch_val[i]); } } } /* * Test the stable and change of touch sensor reading in SW mode. */ esp_err_t test_touch_sw_read(void) { uint32_t touch_value[TEST_TOUCH_CHANNEL] = {0}; uint32_t touch_temp[TEST_TOUCH_CHANNEL] = {0}; uint32_t touch_push[TEST_TOUCH_CHANNEL] = {0}; int test_cnt = TEST_TOUCH_COUNT_NUM; ESP_LOGI(TAG, " >> %s << \n", __func__); TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); TEST_ESP_OK( touch_pad_fsm_start() ); while (test_cnt--) { test_touch_release_all(); /* Read the touch sensor raw data in SW mode. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_sw_start() ); while (!touch_pad_meas_is_done()) ; TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value[i]) ); printf("T%d:[%4d] ", touch_list[i], touch_value[i]); TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value[i]); } printf("\n"); /* Check the stable of reading. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { if (touch_temp[i]) { TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); } touch_temp[i] = touch_value[i]; } test_touch_push_all(); /* Read the touch sensor raw data in SW mode. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_sw_start() ); while (!touch_pad_meas_is_done()) ; TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_push[i]) ); printf("T%d:[%4d] ", touch_list[i], touch_push[i]); TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_push[i]); } printf("\n"); /* Check the change of reading. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ASSERT_GREATER_THAN(touch_value[i], touch_push[i]); } } TEST_ESP_OK( touch_pad_deinit() ); return ESP_OK; } /* * Test the stable and change of touch sensor reading in timer mode. * TEST POINT: * 1. Timer mode for FSM. * 2. Touch channel slope setting. * 3. Touch reading stable. */ esp_err_t test_touch_timer_read(void) { uint32_t touch_value[TEST_TOUCH_CHANNEL] = {0}; uint32_t touch_temp[TEST_TOUCH_CHANNEL] = {0}; uint32_t touch_push[TEST_TOUCH_CHANNEL] = {0}; int test_cnt = TEST_TOUCH_COUNT_NUM; ESP_LOGI(TAG, " >> %s << \n", __func__); TEST_ESP_OK( touch_pad_init() ); /* Set different slope for channels to test slope function. */ printf("Set slope for channel: "); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); TEST_ESP_OK( touch_pad_set_cnt_mode(touch_list[i], i % 7 ? i % 7 : 1, TOUCH_PAD_TIE_OPT_DEFAULT) ); printf("[ch%d-%d] ", touch_list[i], i % 7 ? i % 7 : 1); } printf("\n"); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); TEST_ESP_OK( touch_pad_fsm_start() ); /* Wait touch sensor stable */ vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); while (test_cnt--) { test_touch_release_all(); vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); // Start task to read values sensed by pads for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value[i]) ); TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value[i]); printf("T%d:[%4d] ", touch_list[i], touch_value[i]); } printf("\n"); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { if (touch_temp[i]) { TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); } touch_temp[i] = touch_value[i]; } test_touch_push_all(); vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); /* Read the touch sensor raw data in FSM mode. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_push[i]) ); printf("T%d:[%4d] ", touch_list[i], touch_push[i]); TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_push[i]); } printf("\n"); /* Check the change of reading. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ASSERT_GREATER_THAN(touch_value[i], touch_push[i]); } } TEST_ESP_OK( touch_pad_deinit() ); return ESP_OK; } /* * Test the filter mode. * TEST POINT: * 1. Timer mode for FSM. * 2. Touch reading stable. * 3. Touch reading init value. * 4. Touch reading filtered value equal to raw data. */ esp_err_t test_touch_filtered_read(void) { uint32_t touch_value[TEST_TOUCH_CHANNEL] = {0}; uint32_t touch_temp[TEST_TOUCH_CHANNEL] = {0}; ESP_LOGI(TAG, " >> %s << \n", __func__); TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_32, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = 4, // use for jitter mode. .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); TEST_ESP_OK( touch_pad_fsm_start() ); /* Wait touch pad init done. */ vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); /* Test the stable for init value of touch reading. * Ideal: baseline == raw data == smooth data. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value[i]) ); TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value[i]); TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_temp[i]) ); TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp[i]); TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &touch_temp[i]) ); TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp[i]); TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); } printf("touch filter init value:\n"); printf_touch_hw_read("raw "); printf_touch_baseline_read("base "); printf_touch_smooth_read("smooth"); printf("\n"); int test_cnt = TEST_TOUCH_COUNT_NUM; while (test_cnt--) { /* Touch reading filtered value equal to raw data. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value[i]) ); TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_temp[i]) ); TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &touch_temp[i]) ); TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); } for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { if (touch_temp[i]) { TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); } touch_temp[i] = touch_value[i]; } vTaskDelay(20 / portTICK_PERIOD_MS); } TEST_ESP_OK( touch_pad_deinit() ); return ESP_OK; } TEST_CASE("Touch Sensor reading test (SW, Timer, filter)", "[touch]") { TOUCH_REG_BASE_TEST(); TEST_ESP_OK( test_touch_sw_read() ); TEST_ESP_OK( test_touch_timer_read() ); TEST_ESP_OK( test_touch_filtered_read() ); } /* * Test the base patameter mode. * TEST POINT: * 1. measure time and sleep time setting. * 2. Charge / incharge voltage threshold setting. * 3. Touch slope setting. * 4. Touch reading filtered value equal to raw data. */ int test_touch_base_parameter(touch_pad_t pad_num, int meas_time, int slp_time, int vol_h, int vol_l, int vol_a, int slope, bool is_conn_gnd) { uint32_t touch_value = 0; uint32_t touch_temp = 0, touch_filter; uint64_t val_sum = 0; int test_cnt = TEST_TOUCH_COUNT_NUM; ESP_LOGI(TAG, " >> %s << \n", __func__); TEST_ESP_OK( touch_pad_init() ); /* Note: init all channel, but test one channel. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } TEST_ESP_OK( touch_pad_set_cnt_mode(pad_num, slope, TOUCH_PAD_TIE_OPT_DEFAULT) ); TEST_ESP_OK( touch_pad_set_meas_time(slp_time, meas_time) ); TEST_ESP_OK( touch_pad_set_voltage(vol_h, vol_l, vol_a) ); TEST_ESP_OK( touch_pad_set_idle_channel_connect(is_conn_gnd) ); ESP_LOGI(TAG, "meas_time[%d]_slp_time[%d]_vol_h[%d]_vol_l[%d]_vol_a[%d]_slope[%d]_is_conn_gnd[%d]", meas_time, slp_time, vol_h, vol_l, vol_a, slope, is_conn_gnd); touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_32, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = 4, // use for jitter mode. .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); TEST_ESP_OK( touch_pad_fsm_start() ); /* Some parameters will delay the init time. so wait longger time */ vTaskDelay(100 / portTICK_PERIOD_MS); while (test_cnt--) { /* Correctness of reading. Ideal: baseline == raw data == smooth data. */ TEST_ESP_OK( touch_pad_read_raw_data(pad_num, &touch_value) ); TEST_ESP_OK( touch_pad_filter_read_baseline(pad_num, &touch_filter) ); TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_filter, touch_value); TEST_ESP_OK( touch_pad_filter_read_smooth(pad_num, &touch_filter) ); TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_filter, touch_value); /* Stable of reading */ TEST_ESP_OK( touch_pad_read_raw_data(pad_num, &touch_value) ); TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value); if (touch_temp) { TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); } touch_temp = touch_value; printf("T%d:[%4d] ", pad_num, touch_value); val_sum += touch_value; // For check. vTaskDelay(20 / portTICK_PERIOD_MS); } printf("\n"); TEST_ESP_OK( touch_pad_deinit() ); return (uint32_t)(val_sum / TEST_TOUCH_COUNT_NUM); } TEST_CASE("Touch Sensor base parameters test (meas_time, voltage, slope, inv_conn)", "[touch]") { int touch_val[5] = {0}; ESP_LOGI(TAG, "Charge / incharge voltage level test"); touch_val[0] = test_touch_base_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, TOUCH_HVOLT_2V4, TOUCH_LVOLT_0V8, TOUCH_HVOLT_ATTEN_1V5, TOUCH_PAD_SLOPE_DEFAULT, true); touch_val[1] = test_touch_base_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, TOUCH_HVOLT_2V5, TOUCH_LVOLT_0V6, TOUCH_HVOLT_ATTEN_1V, TOUCH_PAD_SLOPE_DEFAULT, true); touch_val[2] = test_touch_base_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V, TOUCH_PAD_SLOPE_DEFAULT, true); TEST_ASSERT_GREATER_THAN(touch_val[0], touch_val[1]); TEST_ASSERT_GREATER_THAN(touch_val[1], touch_val[2]); ESP_LOGI(TAG, "Measure time / sleep time test"); touch_val[0] = test_touch_base_parameter(touch_list[1], 0xff, 0x1ff, TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, true); touch_val[1] = test_touch_base_parameter(touch_list[1], 0xfff, 0xff, TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, true); touch_val[2] = test_touch_base_parameter(touch_list[1], 0x1fff, 0xf, TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, true); TEST_ASSERT_GREATER_THAN(touch_val[0], touch_val[1]); TEST_ASSERT_GREATER_THAN(touch_val[1], touch_val[2]); ESP_LOGI(TAG, "Charge / incharge slope level test"); touch_val[0] = test_touch_base_parameter(touch_list[0], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 7, true); touch_val[1] = test_touch_base_parameter(touch_list[0], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 5, true); touch_val[2] = test_touch_base_parameter(touch_list[0], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 3, true); TEST_ASSERT_GREATER_THAN(touch_val[0], touch_val[1]); TEST_ASSERT_GREATER_THAN(touch_val[1], touch_val[2]); /* The GND option causes larger parasitic capacitance and larger reading */ ESP_LOGI(TAG, "Inactive connect test"); touch_val[0] = test_touch_base_parameter(touch_list[3], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, false); touch_val[1] = test_touch_base_parameter(touch_list[3], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, true); TEST_ASSERT_GREATER_THAN(touch_val[0], touch_val[1]); } /* * Check active interrupt of touch channels. */ static esp_err_t test_touch_check_ch_touched(uint32_t test_ch_num, uint32_t exceed_time_ms) { touch_event_t evt = {0}; esp_err_t ret = ESP_FAIL; printf("Active: "); while (1) { if (pdTRUE == xQueueReceive(que_touch, &evt, exceed_time_ms / portTICK_PERIOD_MS)) { if (evt.intr_mask & TOUCH_PAD_INTR_MASK_ACTIVE) { printf("0x%x, ", evt.pad_status); if (test_ch_num == __builtin_popcount(evt.pad_status)) { ret = ESP_OK; break; } } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_DONE | TOUCH_PAD_INTR_MASK_SCAN_DONE)) { continue; } else { // If the interrupt type error, test error. ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); break; } } else { ESP_LOGI(TAG, "Touch intr exceed time"); break; } } printf("\n"); return ret; } /* * Check inactive interrupt of touch channels. */ static esp_err_t test_touch_check_ch_released(uint32_t test_ch_num, uint32_t exceed_time_ms) { touch_event_t evt = {0}; esp_err_t ret = ESP_FAIL; printf("Inactive: "); while (1) { if (pdTRUE == xQueueReceive(que_touch, &evt, exceed_time_ms / portTICK_PERIOD_MS)) { if (evt.intr_mask & TOUCH_PAD_INTR_MASK_INACTIVE) { printf("0x%x, ", evt.pad_status); if ((TEST_TOUCH_CHANNEL - test_ch_num) == __builtin_popcount(evt.pad_status)) { ret = ESP_OK; break; } } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_DONE | TOUCH_PAD_INTR_MASK_SCAN_DONE)) { continue; } else { // If the interrupt type error, test error. ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); break; } } else { ESP_LOGI(TAG, "Touch intr exceed time"); break; } } printf("\n"); return ret; } static esp_err_t test_touch_check_ch_touched_with_proximity(uint32_t test_ch_num, uint32_t exceed_time_ms) { uint32_t count = 0; uint16_t ch_mask = 0; touch_event_t evt = {0}; esp_err_t ret = ESP_FAIL; TEST_ESP_OK( touch_pad_proximity_get_count(TOUCH_PAD_MAX, &count) ); printf("Active: "); while (1) { if (pdTRUE == xQueueReceive(que_touch, &evt, exceed_time_ms / portTICK_PERIOD_MS)) { if (evt.intr_mask & TOUCH_PAD_INTR_MASK_ACTIVE) { printf("0x%x, ", evt.pad_status); if (test_ch_num == __builtin_popcount(evt.pad_status)) { ret = ESP_OK; break; } } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_SCAN_DONE)) { touch_pad_get_channel_mask(&ch_mask); for (int i = TOUCH_PAD_MAX - 1; i >= 0; i--) { if (BIT(i) & ch_mask) { if (evt.pad_num == i) { if (count == evt.slp_proxi_cnt) { ets_printf("priximity base(%d) cnt(%d)\n", evt.slp_proxi_base, evt.slp_proxi_cnt); } } } } continue; } else { // If the interrupt type error, test error. ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); continue;; } } else { ESP_LOGI(TAG, "Touch intr exceed time"); break; } } printf("\n"); return (esp_err_t)ret; } static esp_err_t test_touch_check_ch_released_with_proximity(uint32_t test_ch_num, uint32_t exceed_time_ms) { uint32_t count = 0; uint16_t ch_mask = 0; touch_event_t evt = {0}; esp_err_t ret = ESP_FAIL; TEST_ESP_OK( touch_pad_proximity_get_count(TOUCH_PAD_MAX, &count) ); printf("Inactive: "); while (1) { if (pdTRUE == xQueueReceive(que_touch, &evt, exceed_time_ms / portTICK_PERIOD_MS)) { if (evt.intr_mask & TOUCH_PAD_INTR_MASK_INACTIVE) { printf("0x%x, ", evt.pad_status); if ((TEST_TOUCH_CHANNEL - test_ch_num) == __builtin_popcount(evt.pad_status)) { ret = ESP_OK; break; } } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_SCAN_DONE)) { touch_pad_get_channel_mask(&ch_mask); for (int i = TOUCH_PAD_MAX - 1; i >= 0; i--) { if (BIT(i) & ch_mask) { if (evt.pad_num == i) { if (count == evt.slp_proxi_cnt) { ets_printf("priximity base(%d) cnt(%d)\n", evt.slp_proxi_base, evt.slp_proxi_cnt); } } } } continue; } else { // If the interrupt type error, test error. ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); continue;; } } else { ESP_LOGI(TAG, "Touch intr exceed time"); break; } } printf("\n"); return (esp_err_t)ret; } /* * Check scan done interrupt of touch channels. */ static esp_err_t test_touch_check_ch_intr_scan_done(void) { touch_event_t evt = {0}; uint16_t ch_mask = 0; esp_err_t ret = ESP_FAIL; /* Check the scan done interrupt. */ while (1) { if (pdTRUE == xQueueReceive(que_touch, &evt, 1000 / portTICK_PERIOD_MS)) { /* Scan done interrupt have bug that be trigger by last two channel. */ if (evt.intr_mask & TOUCH_PAD_INTR_MASK_SCAN_DONE) { touch_pad_get_channel_mask(&ch_mask); for (int i = TOUCH_PAD_MAX - 1; i >= 0; i--) { if (BIT(i) & ch_mask) { if (evt.pad_num == i) { ESP_LOGI(TAG, "touch _SCAN_DONE INTR be triggered"); ret = ESP_OK; } goto NEXT_TEST; } } } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_DONE | TOUCH_PAD_INTR_MASK_SCAN_DONE)) { continue; } else { // If the interrupt type error, test error. ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); break; } } else { ESP_LOGI(TAG, "Touch intr exceed time"); break; } } NEXT_TEST: printf("\n"); return (esp_err_t)ret; } /* * Check timeout interrupt of touch channels. */ static esp_err_t test_touch_check_ch_intr_timeout(touch_pad_t pad_num) { esp_err_t ret = ESP_FAIL; touch_event_t evt = {0}; while (1) { if (pdTRUE == xQueueReceive(que_touch, &evt, 1000 / portTICK_PERIOD_MS)) { /* Scan done interrupt have bug that be trigger by last two channel. */ if (evt.intr_mask & TOUCH_PAD_INTR_MASK_TIMEOUT) { if (pad_num == evt.pad_num) { ESP_LOGI(TAG, "touch TIMEOUT be triggered"); s_touch_timeout_mask = 0; ret = ESP_OK; touch_pad_timeout_resume(); break; } else { ets_printf("-timeout %x T[%d] status %d, evt_msk %x -\n", s_touch_timeout_mask, evt.pad_num, evt.pad_status, evt.intr_mask); touch_pad_timeout_resume(); } } else { continue; } } else { ESP_LOGI(TAG, "Touch intr exceed time"); break; } } printf("\n"); return (esp_err_t)ret; } static void test_touch_intr_cb(void *arg) { uint32_t cnt, touch_value; int task_awoken = pdFALSE; touch_event_t evt; evt.intr_mask = touch_pad_read_intr_status_mask(); evt.pad_status = touch_pad_get_status(); evt.pad_num = touch_pad_get_current_meas_channel(); if (!evt.intr_mask) { ets_printf("."); return; } if (evt.intr_mask & TOUCH_PAD_INTR_MASK_SCAN_DONE) { touch_pad_filter_read_baseline(evt.pad_num, &evt.pad_val); touch_pad_sleep_channel_t slp_config; touch_pad_sleep_channel_get_info(&slp_config); touch_pad_sleep_channel_read_baseline(slp_config.touch_num, &touch_value); touch_pad_sleep_channel_read_proximity_cnt(slp_config.touch_num, &cnt); evt.slp_proxi_cnt = cnt; evt.slp_proxi_base = touch_value; // ets_printf("[intr] base(%d) cnt(%d)\n", touch_value, cnt); } if (evt.intr_mask & TOUCH_PAD_INTR_MASK_TIMEOUT) { s_touch_timeout_mask |= (BIT(evt.pad_num)); ets_printf("-%dtout-", SENS.sar_touch_status0.touch_scan_curr); } xQueueSendFromISR(que_touch, &evt, &task_awoken); if (task_awoken == pdTRUE) { portYIELD_FROM_ISR(); } } /* * Test the touch active/inactive interrupt. * TEST POINT: * 1. Touch interrupt. * 2. Raw data noise. * 3. smooth data and baseline data. */ esp_err_t test_touch_interrupt(void) { uint32_t touch_value, smooth; int test_cnt = TEST_TOUCH_COUNT_NUM; ESP_LOGI(TAG, " >> %s << \n", __func__); if (que_touch == NULL) { que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); /* Should register once. */ touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL); } else { xQueueReset(que_touch); } TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = 4, // use for jitter mode. .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); /* Register touch interrupt ISR, enable intr type. */ TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); TEST_ESP_OK( touch_pad_fsm_start() ); // Initialize and start a software filter to detect slight change of capacitance. vTaskDelay(50 / portTICK_PERIOD_MS); /* Set threshold of touch sensor */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); } while (test_cnt--) { test_touch_push_all(); TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("push"); /* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ test_touch_baseline_not_update(); test_touch_release_all(); TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("release"); } TEST_ESP_OK( touch_pad_deinit() ); return ESP_OK; } /* * Test the touch active/inactive, scan_done interrupt. * TEST POINT: * 1. Touch interrupt. * 2. Raw data noise. * 3. smooth data and baseline data. */ esp_err_t test_touch_scan_done_interrupt(void) { ESP_LOGI(TAG, " >> %s << \n", __func__); uint32_t touch_value, smooth; int test_cnt = TEST_TOUCH_COUNT_NUM; if (que_touch == NULL) { que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); /* Should register once. */ TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); } else { xQueueReset(que_touch); } TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = 4, // use for jitter mode. .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); /* Register touch interrupt ISR, enable intr type. */ TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_SCAN_DONE | TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); TEST_ESP_OK( touch_pad_fsm_start() ); /* Check the scan done interrupt */ TEST_ESP_OK( test_touch_check_ch_intr_scan_done() ); vTaskDelay(50 / portTICK_PERIOD_MS); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", \ touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); } while (test_cnt--) { test_touch_push_all(); TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("push"); /* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ test_touch_baseline_not_update(); test_touch_release_all(); TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("release"); } TEST_ESP_OK( touch_pad_deinit() ); return ESP_OK; } /* * Test the touch active/inactive, timeout interrupt. * TEST POINT: * 1. Touch interrupt. * 2. Raw data noise. * 3. smooth data and baseline data. */ esp_err_t test_touch_timeout_interrupt(void) { ESP_LOGI(TAG, " >> %s << \n", __func__); uint32_t touch_value, smooth; if (que_touch == NULL) { que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); /* Should register once. */ TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); } else { xQueueReset(que_touch); } TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = 4, // use for jitter mode. .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); /* Register touch interrupt ISR, enable intr type. */ TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_TIMEOUT | TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); TEST_ESP_OK( touch_pad_fsm_start() ); // Initialize and start a software filter to detect slight change of capacitance. vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); } /* Set timeout parameter */ TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[0], &touch_value) ); TEST_ESP_OK( touch_pad_timeout_set(true , touch_value * 10) ); // Only fake push one touch pad. vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); test_timeout_trigger_fake(touch_list[0]); TEST_ESP_OK( test_touch_check_ch_intr_timeout(touch_list[0]) ); test_timeout_normal(touch_list[0]); vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); printf_touch_hw_read("raw "); printf_touch_baseline_read("base "); printf_touch_smooth_read("smooth"); int test_cnt = TEST_TOUCH_COUNT_NUM; while (test_cnt--) { test_touch_push_all(); TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("push"); /* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ test_touch_baseline_not_update(); test_touch_release_all(); TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("release"); } TEST_ESP_OK( touch_pad_deinit() ); return ESP_OK; } TEST_CASE("Touch Sensor interrupt test (active, inactive, scan_done, timeout)", "[touch]") { TEST_ESP_OK( test_touch_interrupt() ); TEST_ESP_OK( test_touch_scan_done_interrupt() ); TEST_ESP_OK( test_touch_timeout_interrupt() ); } static void test_touch_measure_step(uint32_t step) { /* Fake the process of debounce. */ // printf("measure cnt %d: [ ", step); for (int i = 0; i < step; i++) { for (int j = 0; j < TEST_TOUCH_CHANNEL; j++) { TEST_ESP_OK( touch_pad_sw_start() ); while (!touch_pad_meas_is_done()) ; } // printf("."); } // printf(" ]\n"); } /* * Test the touch active/inactive, scan_done interrupt. * TEST POINT: * 1. Touch interrupt. * 2. Raw data noise. * 3. smooth data and baseline data. */ esp_err_t test_touch_filter_parameter_debounce(int deb_cnt) { uint32_t touch_value; int test_cnt = 2; ESP_LOGI(TAG, " >> %s << \n", __func__); if (que_touch == NULL) { que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); /* Should register once. */ TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); } else { xQueueReset(que_touch); } TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_128, // Test jitter and filter 1/4. .debounce_cnt = ((deb_cnt < 0) ? 1 : deb_cnt) , // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = 4, // use for jitter mode. .smh_lvl = TOUCH_PAD_SMOOTH_OFF, }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); /* Register touch interrupt ISR, enable intr type. */ TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); TEST_ESP_OK( touch_pad_fsm_start() ); /* Run to wait the data become stable. */ test_touch_measure_step(20); // 2 scan loop /* Set the threshold. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); ESP_LOGI(TAG, "test init: touch pad [%d] base %d, thresh %d", \ touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); } while (test_cnt--) { test_touch_push_all(); /* Fake the process of push debounce. */ test_touch_measure_step(deb_cnt); // measure n times. touch state not changed. TEST_ESP_ERR( ESP_FAIL, test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); test_touch_measure_step(1); // measure n+1 times. touch state changed. TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("push"); test_touch_release_all(); /* Fake the process of release debounce. */ test_touch_measure_step(deb_cnt); // measure n times. touch state not changed. TEST_ESP_ERR( ESP_FAIL, test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); test_touch_measure_step(1); // measure n+1 times. touch state changed. TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("release"); } TEST_ESP_OK( touch_pad_deinit() ); return ESP_OK; } esp_err_t test_touch_filter_parameter_neg_reset(int reset_cnt) { uint32_t touch_value, base_value; ESP_LOGI(TAG, " >> %s << \n", __func__); if (que_touch == NULL) { que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); /* Should register once. */ TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); } else { xQueueReset(que_touch); } TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } reset_cnt = ((reset_cnt < 0) ? 10 : reset_cnt); touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = reset_cnt, // 10 time count. .jitter_step = 4, // use for jitter mode. .smh_lvl = TOUCH_PAD_SMOOTH_OFF, }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); /* Register touch interrupt ISR, enable intr type. */ TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); TEST_ESP_OK( touch_pad_fsm_start() ); /* Run to wait the data become stable. */ test_touch_measure_step(20); // 2 scan loop /* Set the threshold. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); ESP_LOGI(TAG, "test init: touch pad [%d] base %d, thresh %d", \ touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); } /* 1. Fake init status is touched. */ test_touch_push_all(); TEST_ESP_OK( touch_pad_filter_reset_baseline(TOUCH_PAD_MAX) ); /* Run to wait the data become stable. */ test_touch_measure_step(20); // 2 scan loop printf_touch_hw_read("[raw ] reset:"); printf_touch_baseline_read("[base] reset:"); /* 2. Fake the touch status is released. */ test_touch_release_all(); /* 3. Fake measure `reset_cnt + 1` times to reset the baseline. */ test_touch_measure_step(reset_cnt); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &base_value) ); if ((base_value - touch_value) < (base_value * TOUCH_INTR_THRESHOLD)) { ESP_LOGE(TAG, "neg reset cnt err"); TEST_FAIL(); } } printf_touch_hw_read("[raw ] neg_cnt:"); printf_touch_baseline_read("[base] neg_cnt:"); test_touch_measure_step(1); /* ESP32S2 neg reset baseline to raw data */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &base_value) ); TEST_ASSERT_EQUAL_UINT32(base_value, touch_value); } printf_touch_hw_read("[raw ] neg_cnt+1:"); printf_touch_baseline_read("[base] neg_cnt+1:"); int test_cnt = 2; while (test_cnt--) { test_touch_push_all(); /* Fake the process of push debounce. */ test_touch_measure_step(filter_info.debounce_cnt + 1); TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("push"); test_touch_release_all(); /* Fake the process of release debounce. */ test_touch_measure_step(filter_info.debounce_cnt + 1); TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("release"); } TEST_ESP_OK( touch_pad_deinit() ); return ESP_OK; } esp_err_t test_touch_filter_parameter_jitter(int jitter_step) { uint32_t touch_value, base_value = 0; ESP_LOGI(TAG, " >> %s << \n", __func__); if (que_touch == NULL) { que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); /* Should register once. */ TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); } else { xQueueReset(que_touch); } TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } jitter_step = ((jitter_step < 0) ? 4 : jitter_step); touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_JITTER, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = jitter_step, // use for jitter mode. }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); /* Register touch interrupt ISR, enable intr type. */ TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); TEST_ESP_OK( touch_pad_fsm_start() ); /* Run to wait the data become stable. */ test_touch_measure_step(20); // 2 scan loop /* Check the jitter step. */ printf_touch_baseline_read("[smooth] t1:"); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { test_touch_measure_step(1); TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); test_press_fake(touch_list[i]); test_touch_measure_step(1); TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &base_value) ); TEST_ASSERT_EQUAL_UINT32(jitter_step, (base_value - touch_value)); } printf_touch_baseline_read("[smooth] t2:"); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { test_touch_measure_step(1); TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); test_release_fake(touch_list[i]); test_touch_measure_step(1); TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &base_value) ); TEST_ASSERT_EQUAL_UINT32(jitter_step, (touch_value - base_value)); } printf_touch_baseline_read("[smooth] t3:"); /* Set the threshold. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { //read baseline value TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); //set interrupt threshold. TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); ESP_LOGI(TAG, "test init: touch pad [%d] base %d, thresh %d", \ touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); } int test_cnt = 2; while (test_cnt--) { test_touch_push_all(); /* Fake the process of push debounce. */ test_touch_measure_step(filter_info.debounce_cnt + 1); TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_smooth_read("push"); test_touch_release_all(); /* Fake the process of release debounce. */ test_touch_measure_step(filter_info.debounce_cnt + 1); TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_smooth_read("release"); } TEST_ESP_OK( touch_pad_deinit() ); return ESP_OK; } TEST_CASE("Touch Sensor filter paramter test (debounce, neg_reset, jitter)", "[touch]") { ESP_LOGI(TAG, "*********** touch filter debounce test ********************"); TEST_ESP_OK( test_touch_filter_parameter_debounce(0) ); TEST_ESP_OK( test_touch_filter_parameter_debounce(3) ); TEST_ESP_OK( test_touch_filter_parameter_debounce(7) ); ESP_LOGI(TAG, "*********** touch filter neg threshold reset limit test ********************"); TEST_ESP_OK( test_touch_filter_parameter_neg_reset(1) ); TEST_ESP_OK( test_touch_filter_parameter_neg_reset(5) ); TEST_ESP_OK( test_touch_filter_parameter_neg_reset(15) ); ESP_LOGI(TAG, "*********** touch filter jitter test ********************"); TEST_ESP_OK( test_touch_filter_parameter_jitter(1) ); TEST_ESP_OK( test_touch_filter_parameter_jitter(5) ); TEST_ESP_OK( test_touch_filter_parameter_jitter(15) ); } esp_err_t test_touch_denoise(uint32_t out_val[], uint32_t *denoise_val, touch_pad_denoise_grade_t grade, touch_pad_denoise_cap_t cap) { uint32_t touch_value; ESP_LOGI(TAG, " >> %s << \n", __func__); ESP_LOGI(TAG, "Denoise level (%d), cap level (%d) \n", grade, cap); if (que_touch == NULL) { que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); /* Should register once. */ TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); } else { xQueueReset(que_touch); } TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } /* Denoise setting at TouchSensor 0. */ touch_pad_denoise_t denoise = { /* The bits to be cancelled are determined according to the noise level. */ .grade = (grade < 0) ? TOUCH_PAD_DENOISE_BIT4 : grade, .cap_level = (cap < 0) ? TOUCH_PAD_DENOISE_CAP_L4 : cap, }; TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); TEST_ESP_OK( touch_pad_denoise_enable() ); ESP_LOGI(TAG, "Denoise function init"); touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = 4, // use for jitter mode. }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); /* Register touch interrupt ISR, enable intr type. */ TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); TEST_ESP_OK( touch_pad_fsm_start() ); /* Run to wait the data become stable. */ test_touch_measure_step(20); // 2 scan loop /* Set the threshold. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); if (out_val) { /* Output value for check. */ out_val[i] = touch_value; } } printf_touch_baseline_read("Denoise"); if (denoise_val) { touch_pad_denoise_read_data(denoise_val); } int test_cnt = 1; while (test_cnt--) { test_touch_push_all(); /* Fake the process of push debounce. */ test_touch_measure_step(filter_info.debounce_cnt + 1); TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); test_touch_release_all(); /* Fake the process of release debounce. */ test_touch_measure_step(filter_info.debounce_cnt + 1); TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); } TEST_ESP_OK( touch_pad_deinit() ); return ESP_OK; } TEST_CASE("Touch Sensor denoise test (cap, level)", "[touch]") { uint32_t val_1[TEST_TOUCH_CHANNEL]; uint32_t val_2[TEST_TOUCH_CHANNEL]; uint32_t val_3[TEST_TOUCH_CHANNEL]; uint32_t denoise_val[TOUCH_PAD_DENOISE_CAP_MAX]; ESP_LOGI(TAG, "*********** touch filter denoise level test ********************"); TEST_ESP_OK( test_touch_denoise(val_1, NULL, TOUCH_PAD_DENOISE_BIT4, TOUCH_PAD_DENOISE_CAP_L0) ); TEST_ESP_OK( test_touch_denoise(val_2, NULL, TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L0) ); TEST_ESP_OK( test_touch_denoise(val_3, NULL, TOUCH_PAD_DENOISE_BIT12, TOUCH_PAD_DENOISE_CAP_L0) ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ASSERT_GREATER_OR_EQUAL(val_3[i], val_2[i]); TEST_ASSERT_GREATER_OR_EQUAL(val_2[i], val_1[i]); } ESP_LOGI(TAG, "*********** touch filter denoise cap level test ********************"); TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[0], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L0) ); TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[1], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L1) ); TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[2], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L2) ); TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[3], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L3) ); TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[4], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L4) ); TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[5], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L5) ); TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[6], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L6) ); TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[7], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L7) ); printf("denoise read: "); for (int i = 0; i < TOUCH_PAD_DENOISE_CAP_MAX - 1; i++) { TEST_ASSERT_GREATER_OR_EQUAL(denoise_val[i], denoise_val[i + 1]); printf("%d ", denoise_val[i]); } printf("\n"); } esp_err_t test_touch_waterproof(void) { uint32_t touch_value; int test_cnt = TEST_TOUCH_COUNT_NUM; ESP_LOGI(TAG, " >> %s << \n", __func__); if (que_touch == NULL) { que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); /* Should register once. */ touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL); } else { xQueueReset(que_touch); } TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } /* Denoise setting at TouchSensor 0. */ touch_pad_denoise_t denoise = { /* The bits to be cancelled are determined according to the noise level. */ .grade = TOUCH_PAD_DENOISE_BIT4, .cap_level = TOUCH_PAD_DENOISE_CAP_L4, }; TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); TEST_ESP_OK( touch_pad_denoise_enable() ); ESP_LOGI(TAG, "Denoise function init"); touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = 4, // use for jitter mode. }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); /* Register touch interrupt ISR, enable intr type. */ TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); /* Waterproof function */ touch_pad_waterproof_t waterproof = { .guard_ring_pad = TOUCH_WATERPROOF_RING_PAD, // If no ring pad, set 0; /* It depends on the number of the parasitic capacitance of the shield pad. */ .shield_driver = TOUCH_PAD_SHIELD_DRV_L0, //40pf }; TEST_ESP_OK( touch_pad_waterproof_set_config(&waterproof) ); TEST_ESP_OK( touch_pad_waterproof_enable() ); ESP_LOGI(TAG, "touch pad waterproof init"); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); TEST_ESP_OK( touch_pad_fsm_start() ); vTaskDelay(50 / portTICK_PERIOD_MS); /* Set the threshold. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); } while (test_cnt--) { test_touch_push_all(); vTaskDelay(20 / portTICK_PERIOD_MS); TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL - 1, TOUCH_EXCEED_TIME_MS) ); // take off shield pad printf_touch_hw_read("push"); test_touch_release_all(); vTaskDelay(20 / portTICK_PERIOD_MS); TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("release"); } TEST_ESP_OK( touch_pad_deinit() ); return ESP_OK; } TEST_CASE("Touch Sensor waterproof guard test", "[touch]") { ESP_LOGI(TAG, "*********** touch filter waterproof guard test ********************"); TEST_ESP_OK( test_touch_waterproof() ); } esp_err_t test_touch_proximity(int meas_num) { ESP_LOGI(TAG, " >> %s << \n", __func__); uint32_t touch_value; if (que_touch == NULL) { que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); /* Should register once. */ TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); } else { xQueueReset(que_touch); } TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } /* Denoise setting at TouchSensor 0. */ touch_pad_denoise_t denoise = { /* The bits to be cancelled are determined according to the noise level. */ .grade = TOUCH_PAD_DENOISE_BIT4, .cap_level = TOUCH_PAD_DENOISE_CAP_L4, }; TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); TEST_ESP_OK( touch_pad_denoise_enable() ); ESP_LOGI(TAG, "Denoise function init"); touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = 4, // use for jitter mode. }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); /* Register touch interrupt ISR, enable intr type. */ TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); /* Waterproof function */ touch_pad_waterproof_t waterproof = { .guard_ring_pad = TOUCH_WATERPROOF_RING_PAD,// If no ring pad, set 0; /* It depends on the number of the parasitic capacitance of the shield pad. */ .shield_driver = TOUCH_PAD_SHIELD_DRV_L0, //40pf }; TEST_ESP_OK( touch_pad_waterproof_set_config(&waterproof) ); TEST_ESP_OK( touch_pad_waterproof_enable() ); ESP_LOGI(TAG, "touch pad waterproof init"); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); TEST_ESP_OK( touch_pad_fsm_start() ); vTaskDelay(50 / portTICK_PERIOD_MS); /* Set the threshold. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); if (touch_list[i] == proximity_pad[0] || touch_list[i] == proximity_pad[1] || touch_list[i] == proximity_pad[2]) { /* The threshold of proximity pad is the sum of touch reading `meas_num` times */ TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD)) ); ESP_LOGI(TAG, "proximity pad [%d] base %d, thresh %d", touch_list[i], touch_value, (uint32_t)(meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD))); } else { TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); ESP_LOGI(TAG, "touch pad [%d] base %d, thresh %d", \ touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); } } /* Should stop the measure, then change the config. */ while (!touch_pad_meas_is_done()); TEST_ESP_OK( touch_pad_fsm_stop() ); /* Proximity function */ TEST_ESP_OK( touch_pad_proximity_enable(proximity_pad[0], true) ); TEST_ESP_OK( touch_pad_proximity_enable(proximity_pad[1], true) ); TEST_ESP_OK( touch_pad_proximity_enable(proximity_pad[2], true) ); TEST_ESP_OK( touch_pad_proximity_set_count(TOUCH_PAD_MAX, meas_num < 0 ? 16 : meas_num) ); ESP_LOGI(TAG, "touch pad proximity init"); TEST_ESP_OK( touch_pad_fsm_start() ); vTaskDelay(20 / portTICK_PERIOD_MS); int test_cnt = TEST_TOUCH_COUNT_NUM; while (test_cnt--) { test_touch_push_all(); vTaskDelay(20 / portTICK_PERIOD_MS); TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL - 1, TOUCH_EXCEED_TIME_MS) ); // take off shield pad printf_touch_hw_read("push"); test_touch_release_all(); vTaskDelay(20 / portTICK_PERIOD_MS); TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("release"); } TEST_ESP_OK( touch_pad_deinit() ); return ESP_OK; } TEST_CASE("Touch Sensor proximity test", "[touch]") { ESP_LOGI(TAG, "*********** touch proximity test ********************"); TEST_ESP_OK( test_touch_proximity(5) ); TEST_ESP_OK( test_touch_proximity(1) ); } esp_err_t test_touch_sleep_reading_stable(touch_pad_t sleep_pad) { uint32_t touch_temp = 0; uint32_t touch_value, smooth, ret_val; int test_cnt = TEST_TOUCH_COUNT_NUM; ESP_LOGI(TAG, " >> %s << \n", __func__); if (que_touch == NULL) { que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); /* Should register once. */ TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); } else { xQueueReset(que_touch); } TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } // /* Denoise setting at TouchSensor 0. */ touch_pad_denoise_t denoise = { /* The bits to be cancelled are determined according to the noise level. */ .grade = TOUCH_PAD_DENOISE_BIT4, .cap_level = TOUCH_PAD_DENOISE_CAP_L4, }; TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); TEST_ESP_OK( touch_pad_denoise_enable() ); touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = 4, // use for jitter mode. .smh_lvl = TOUCH_PAD_SMOOTH_OFF, }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); TEST_ESP_OK( touch_pad_sleep_channel_enable(sleep_pad, true) ); TEST_ESP_OK( touch_pad_sleep_channel_enable_proximity(sleep_pad, false) ); /* Register touch interrupt ISR, enable intr type. */ TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); TEST_ESP_OK( touch_pad_fsm_start() ); // Initialize and start a software filter to detect slight change of capacitance. vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); /* Set threshold of touch sensor */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); } /* Sleep channel setting */ TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(sleep_pad, &touch_value) ); TEST_ESP_OK( touch_pad_sleep_set_threshold(sleep_pad, touch_value * TOUCH_INTR_THRESHOLD) ); vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); while (test_cnt--) { /* Touch reading filtered value equal to raw data. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_sleep_channel_read_data(sleep_pad, &touch_value) ); TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(sleep_pad, &touch_temp) ); TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(sleep_pad, &touch_temp) ); TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); } for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { if (touch_temp) { TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); } touch_temp = touch_value; } vTaskDelay(20 / portTICK_PERIOD_MS); } TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(sleep_pad, &ret_val) ); TEST_ESP_OK( touch_pad_deinit() ); return ret_val; } TEST_CASE("Touch Sensor sleep pad reading stable test", "[touch]") { ESP_LOGI(TAG, "*********** touch sleep pad low power (wakeup) test ********************"); test_touch_sleep_reading_stable(touch_list[0]); } /* * Test the touch sleep pad interrupt in normal mode. * TEST POINT: * 1. Touch sleep pad interrupt. * 2. sleep pad reading. * 3. sleep pad enable proximity. */ uint32_t test_touch_sleep_pad_proximity(touch_pad_t sleep_pad, bool is_proximity, uint32_t meas_num) { uint32_t touch_value, smooth, ret_val; uint32_t measure_out; uint32_t proximity_cnt; uint32_t touch_thres; int test_cnt = TEST_TOUCH_COUNT_NUM; ESP_LOGI(TAG, " >> %s << \n", __func__); if (que_touch == NULL) { que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); /* Should register once. */ TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); } else { xQueueReset(que_touch); } TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } /* Denoise setting at TouchSensor 0. */ touch_pad_denoise_t denoise = { /* The bits to be cancelled are determined according to the noise level. */ .grade = TOUCH_PAD_DENOISE_BIT4, .cap_level = TOUCH_PAD_DENOISE_CAP_L4, }; TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); TEST_ESP_OK( touch_pad_denoise_enable() ); touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = 4, // use for jitter mode. .smh_lvl = TOUCH_PAD_SMOOTH_OFF, }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); /* Sleep channel setting */ TEST_ESP_OK( touch_pad_sleep_channel_enable(sleep_pad, true) ); TEST_ESP_OK( touch_pad_sleep_channel_enable_proximity(sleep_pad, is_proximity) ); /* Register touch interrupt ISR, enable intr type. */ TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_SCAN_DONE | TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); TEST_ESP_OK( touch_pad_fsm_start() ); // Initialize and start a software filter to detect slight change of capacitance. vTaskDelay(100 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); if (is_proximity) { /* Set the threshold. */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { if (touch_list[i] == sleep_pad) { touch_pad_sleep_channel_read_smooth(sleep_pad, &touch_value); touch_pad_sleep_set_threshold(sleep_pad, meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD)); ESP_LOGI(TAG, "Sleep pad [%d] base %d, thresh %d", touch_list[i], touch_value, (uint32_t)(meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD))); } else if (touch_list[i] == sleep_pad) { // TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); touch_pad_sleep_channel_read_smooth(sleep_pad, &touch_value); /* The threshold of proximity pad is the sum of touch reading `meas_num` times */ touch_pad_sleep_set_threshold(sleep_pad, meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD)); ESP_LOGI(TAG, "proximity pad [%d] base %d, thresh %d", touch_list[i], touch_value, (uint32_t)(meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD))); } else { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); ESP_LOGI(TAG, "touch pad [%d] base %d, thresh %d", \ touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); } } /* Should stop the measure, then change the config. */ while (!touch_pad_meas_is_done()); TEST_ESP_OK( touch_pad_fsm_stop() ); /* Proximity function */ TEST_ESP_OK( touch_pad_proximity_enable(proximity_pad[0], false) ); TEST_ESP_OK( touch_pad_proximity_enable(proximity_pad[1], false) ); TEST_ESP_OK( touch_pad_proximity_enable(proximity_pad[2], false) ); TEST_ESP_OK( touch_pad_proximity_enable(sleep_pad, true) ); TEST_ESP_OK( touch_pad_proximity_set_count(TOUCH_PAD_MAX, meas_num) ); ESP_LOGI(TAG, "touch pad proximity init"); TEST_ESP_OK( touch_pad_fsm_start() ); vTaskDelay(100 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); } else { /* Set threshold of touch sensor */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); } /* Sleep channel setting */ TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(sleep_pad, &touch_value) ); TEST_ESP_OK( touch_pad_sleep_set_threshold(sleep_pad, touch_value * TOUCH_INTR_THRESHOLD) ); vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); } TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(sleep_pad, &ret_val) ); while (test_cnt--) { test_touch_push_all(); TEST_ESP_OK( test_touch_check_ch_touched_with_proximity(TEST_TOUCH_CHANNEL, 5000) ); printf_touch_hw_read("push"); if (is_proximity) { TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(sleep_pad, &smooth) ); TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(sleep_pad, &touch_value) ); TEST_ESP_OK( touch_pad_proximity_get_data(sleep_pad, &measure_out) ); TEST_ESP_OK( touch_pad_sleep_channel_read_proximity_cnt(sleep_pad, &proximity_cnt) ); TEST_ESP_OK( touch_pad_sleep_get_threshold(sleep_pad, &touch_thres) ); printf("touch slp smooth %d, base %d, proxi %d cnt %d thres%d status 0x%x\n", smooth, touch_value, measure_out, proximity_cnt, touch_thres, touch_pad_get_status()); } test_touch_release_all(); TEST_ESP_OK( test_touch_check_ch_released_with_proximity(TEST_TOUCH_CHANNEL, 5000) ); printf_touch_hw_read("release"); if (is_proximity) { TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(sleep_pad, &smooth) ); TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(sleep_pad, &touch_value) ); TEST_ESP_OK( touch_pad_proximity_get_data(sleep_pad, &measure_out) ); TEST_ESP_OK( touch_pad_sleep_channel_read_proximity_cnt(sleep_pad, &proximity_cnt) ); printf("touch slp smooth %d, base %d, proxi %d cnt %d status 0x%x\n", smooth, touch_value, measure_out, proximity_cnt, touch_pad_get_status()); } } TEST_ESP_OK( touch_pad_deinit() ); return ret_val; } TEST_CASE("Touch Sensor sleep pad and proximity interrupt test", "[touch]") { ESP_LOGI(TAG, "*********** touch sleep pad interrupt test ********************"); test_touch_sleep_pad_proximity(touch_list[0], false, 0); test_touch_sleep_pad_proximity(touch_list[0], false, 0); test_touch_sleep_pad_proximity(touch_list[0], false, 0); ESP_LOGI(TAG, "*********** touch sleep pad interrupt (proximity) test ********************"); test_touch_sleep_pad_proximity(touch_list[0], true, 1); test_touch_sleep_pad_proximity(touch_list[0], true, 3); test_touch_sleep_pad_proximity(touch_list[0], true, 5); } /* * Test the touch sleep pad interrupt in normal mode. * TEST POINT: * 1. Touch sleep pad interrupt. * 2. sleep pad reading. * 3. denoise, waterproof */ esp_err_t test_touch_sleep_pad_interrupt_wakeup_deep_sleep(touch_pad_t sleep_pad) { uint32_t touch_value, smooth, raw; ESP_LOGI(TAG, " >> %s << \n", __func__); if (que_touch == NULL) { que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); /* Should register once. */ TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); } else { xQueueReset(que_touch); } TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } // /* Denoise setting at TouchSensor 0. */ touch_pad_denoise_t denoise = { /* The bits to be cancelled are determined according to the noise level. */ .grade = TOUCH_PAD_DENOISE_BIT4, .cap_level = TOUCH_PAD_DENOISE_CAP_L4, }; TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); TEST_ESP_OK( touch_pad_denoise_disable() ); touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 3, // 0% .noise_thr = 0, // 50% .noise_neg_thr = 0, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = 4, // use for jitter mode. .smh_lvl = TOUCH_PAD_SMOOTH_OFF, }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); /* Sleep channel setting */ TEST_ESP_OK( touch_pad_sleep_channel_enable(sleep_pad, true) ); TEST_ESP_OK( touch_pad_sleep_channel_enable_proximity(sleep_pad, false) ); /* Register touch interrupt ISR, enable intr type. */ TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); TEST_ESP_OK( touch_pad_fsm_start() ); // Initialize and start a software filter to detect slight change of capacitance. vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); /* Set threshold of touch sensor */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); } /* Sleep channel setting */ TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(sleep_pad, &touch_value) ); TEST_ESP_OK( touch_pad_sleep_set_threshold(sleep_pad, touch_value * TOUCH_INTR_THRESHOLD) ); vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); test_touch_push_all(); TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("push"); TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(sleep_pad, &smooth) ); TEST_ESP_OK( touch_pad_sleep_channel_read_data(sleep_pad, &raw) ); TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(sleep_pad, &touch_value) ); printf("touch slp raw %d, smooth %d, base %d, status 0x%x\n", raw, smooth, touch_value, touch_pad_get_status()); test_touch_release_all(); TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("release"); TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(sleep_pad, &smooth) ); TEST_ESP_OK( touch_pad_sleep_channel_read_data(sleep_pad, &raw) ); TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(sleep_pad, &touch_value) ); printf("touch slp raw %d, smooth %d, base %d, status 0x%x\n", raw, smooth, touch_value, touch_pad_get_status()); return ESP_OK; } #include #include "esp_sleep.h" static RTC_DATA_ATTR struct timeval sleep_enter_time; static void test_deep_sleep_init(void) { struct timeval now; gettimeofday(&now, NULL); int sleep_time_ms = (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - sleep_enter_time.tv_usec) / 1000; printf("RTC_CNTL_SLP_WAKEUP_CAUSE_REG %x\n", REG_READ(RTC_CNTL_SLP_WAKEUP_CAUSE_REG)); switch (esp_sleep_get_wakeup_cause()) { case ESP_SLEEP_WAKEUP_EXT1: { uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status(); if (wakeup_pin_mask != 0) { int pin = __builtin_ffsll(wakeup_pin_mask) - 1; printf("Wake up from GPIO %d\n", pin); } else { printf("Wake up from GPIO\n"); } break; } case ESP_SLEEP_WAKEUP_TIMER: { printf("Wake up from timer. Time spent in deep sleep: %dms\n", sleep_time_ms); break; } case ESP_SLEEP_WAKEUP_TOUCHPAD: { printf("Wake up from touch on pad %d\n", esp_sleep_get_touchpad_wakeup_status()); break; } case ESP_SLEEP_WAKEUP_UNDEFINED: default: { printf("Not a deep sleep reset\n"); ESP_LOGI(TAG, "*********** touch sleep pad wakeup test ********************"); /* Sleep pad should be init once. */ test_touch_sleep_pad_interrupt_wakeup_deep_sleep(touch_list[0]); } } vTaskDelay(100 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); printf("Enabling touch pad wakeup\n"); esp_sleep_enable_touchpad_wakeup(); printf("Entering deep sleep\n"); gettimeofday(&sleep_enter_time, NULL); } TEST_CASE("Touch Sensor sleep pad wakeup deep sleep test", "[touch][ignore]") { test_deep_sleep_init(); /* Change the work duty of touch sensor to reduce current. */ touch_pad_set_meas_time(100, TOUCH_PAD_MEASURE_CYCLE_DEFAULT); /* Close PD current in deep sleep. */ RTCCNTL.bias_conf.pd_cur_deep_slp = 1; RTCCNTL.bias_conf.pd_cur_monitor = 1; RTCCNTL.bias_conf.bias_sleep_deep_slp = 1; RTCCNTL.bias_conf.bias_sleep_monitor = 1; esp_deep_sleep_start(); } #include "touch_scope.h" /* * 0: 10 channels raw/smooth/baseline data debug. * 1: 5 channges smooth + baseline data debug. * 2: 1 channels filter data. */ #define SCOPE_DEBUG_TYPE 2 #define TOUCH_THRESHOLD 0.5 #define TOUCH_SHELD_PAD (1) #define SCOPE_DEBUG_CHANNEL_MAX (10) #define SCOPE_DEBUG_ENABLE (0) #define SCOPE_UART_BUADRATE (256000) #define SCOPE_DEBUG_FREQ_MS (50) void test_touch_slope_debug(int pad_num) { touch_event_t evt; uint32_t touch_value, smooth; ESP_LOGI(TAG, " >> %s << \n", __func__); if (que_touch == NULL) { que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); /* Should register once. */ touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL); } else { xQueueReset(que_touch); } TEST_ESP_OK( touch_pad_init() ); for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_config(touch_list[i]) ); } touch_filter_config_t filter_info = { .mode = TOUCH_PAD_FILTER_IIR_32, // Test jitter and filter 1/4. .debounce_cnt = 1, // 1 time count. .hysteresis_thr = 2, // 6.25% .noise_thr = 3, // 50% .noise_neg_thr = 3, // 50% .neg_noise_limit = 10, // 10 time count. .jitter_step = 4, // use for jitter mode. .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, }; TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); TEST_ESP_OK( touch_pad_filter_enable() ); /* Register touch interrupt ISR, enable intr type. */ TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); TEST_ESP_OK( touch_pad_fsm_start() ); /* Waterproof function */ touch_pad_waterproof_t waterproof = { .guard_ring_pad = 0, // If no ring pad, set 0; /* It depends on the number of the parasitic capacitance of the shield pad. */ .shield_driver = TOUCH_PAD_SHIELD_DRV_L2, //40pf }; TEST_ESP_OK( touch_pad_waterproof_set_config(&waterproof) ); TEST_ESP_OK( touch_pad_waterproof_enable() ); ESP_LOGI(TAG, "touch pad waterproof init"); // Initialize and start a software filter to detect slight change of capacitance. vTaskDelay(50 / portTICK_PERIOD_MS); /* Set threshold of touch sensor */ for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_THRESHOLD) ); ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", \ touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_THRESHOLD)); } float scope_temp[SCOPE_DEBUG_CHANNEL_MAX] = {0}; // max scope channel is 10. uint32_t scope_data[SCOPE_DEBUG_CHANNEL_MAX] = {0}; // max scope channel is 10. test_tp_scope_debug_init(0, -1, -1, SCOPE_UART_BUADRATE); #if SCOPE_DEBUG_TYPE == 0 while (1) { for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { touch_pad_read_raw_data(touch_list[i], &scope_data[i]); // touch_pad_filter_read_smooth(touch_list[i], &scope_data[i]); // touch_pad_filter_read_baseline(touch_list[i], &scope_data[i]); scope_temp[i] = scope_data[i]; } test_tp_print_to_scope(scope_temp, TEST_TOUCH_CHANNEL); vTaskDelay(SCOPE_DEBUG_FREQ_MS / portTICK_RATE_MS); } #elif SCOPE_DEBUG_TYPE == 1 while (1) { int cnt = 0; for (int i = 0; i < 5; i++) { touch_pad_read_raw_data(touch_list[i], &scope_data[i]); scope_temp[i] = scope_data[i]; } for (int i = 0; i < 5; i++) { touch_pad_filter_read_smooth(touch_list[i], &scope_data[i]); scope_temp[i + SCOPE_DEBUG_CHANNEL_MAX / 2] = scope_data[i]; } test_tp_print_to_scope(scope_temp, SCOPE_DEBUG_CHANNEL_MAX); vTaskDelay(SCOPE_DEBUG_FREQ_MS / portTICK_RATE_MS); } #elif SCOPE_DEBUG_TYPE == 2 uint32_t status; touch_pad_filter_read_baseline(pad_num, &status); while (1) { xQueueReceive(que_touch, &evt, SCOPE_DEBUG_FREQ_MS / portTICK_RATE_MS); //read filtered value touch_pad_read_raw_data(pad_num, &scope_data[0]); touch_pad_filter_read_baseline(pad_num, &scope_data[1]); touch_pad_get_thresh(pad_num, &scope_data[2]); touch_pad_filter_read_smooth(pad_num, &scope_data[8]); // raw data scope_temp[0] = scope_data[0]; // baseline scope_temp[1] = scope_data[1]; // smooth data scope_temp[8] = scope_data[8]; // noise neg thr scope_temp[2] = scope_temp[1] - scope_data[2] * 0.5; // noise thr scope_temp[3] = scope_temp[1] + scope_data[2] * 0.5; // touch thr scope_temp[4] = scope_temp[1] + scope_data[2]; // hysteresis_thr thr scope_temp[5] = scope_temp[4] - scope_data[2] * 0.0625; // hysteresis_thr thr scope_temp[6] = scope_temp[4] + scope_data[2] * 0.0625; // touch status if (touch_pad_get_status() & BIT(pad_num)) { scope_temp[7] = status + 100; } else { scope_temp[7] = status - 100; //0:release; 1:push; } test_tp_print_to_scope(scope_temp, 9); } #elif SCOPE_DEBUG_TYPE == 3 while (1) { test_touch_push_all(); TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("push"); /* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ test_touch_baseline_not_update(); test_touch_release_all(); TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); printf_touch_hw_read("release"); } #endif TEST_ESP_OK( touch_pad_deinit() ); } #endif // !DISABLED_FOR_TARGETS(ESP8266, ESP32)