diff --git a/components/driver/include/driver/touch_pad.h b/components/driver/include/driver/touch_pad.h index f18069ab3..643b07bef 100644 --- a/components/driver/include/driver/touch_pad.h +++ b/components/driver/include/driver/touch_pad.h @@ -130,8 +130,12 @@ esp_err_t touch_pad_deinit(); /** * @brief Configure touch pad interrupt threshold. + * + * @note If FSM mode is set to TOUCH_FSM_MODE_TIMER, this function will be blocked for one measurement cycle and wait for data to be valid. + * * @param touch_num touch pad index * @param threshold interrupt threshold, + * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG if argument wrong @@ -144,28 +148,34 @@ esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold); * Each touch sensor has a counter to count the number of charge/discharge cycles. * When the pad is not 'touched', we can get a number of the counter. * When the pad is 'touched', the value in counter will get smaller because of the larger equivalent capacitance. - * @note This API requests hardware measurement once. If IIR filter mode is enabled,, + * + * @note This API requests hardware measurement once. If IIR filter mode is enabled, * please use 'touch_pad_read_raw_data' interface instead. + * * @param touch_num touch pad index * @param touch_value pointer to accept touch sensor value + * * @return * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Touch pad error + * - ESP_ERR_INVALID_ARG Touch pad parameter error + * - ESP_ERR_INVALID_STATE This touch pad hardware connection is error, the value of "touch_value" is 0. * - ESP_FAIL Touch pad not initialized */ esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t * touch_value); /** * @brief get filtered touch sensor counter value by IIR filter. + * * @note touch_pad_filter_start has to be called before calling touch_pad_read_filtered. * This function can be called from ISR * * @param touch_num touch pad index * @param touch_value pointer to accept touch sensor value + * * @return * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Touch pad error - * - ESP_ERR_INVALID_STATE Touch pad not initialized + * - ESP_ERR_INVALID_ARG Touch pad parameter error + * - ESP_ERR_INVALID_STATE This touch pad hardware connection is error, the value of "touch_value" is 0. * - ESP_FAIL Touch pad not initialized */ esp_err_t touch_pad_read_filtered(touch_pad_t touch_num, uint16_t *touch_value); @@ -173,6 +183,7 @@ esp_err_t touch_pad_read_filtered(touch_pad_t touch_num, uint16_t *touch_value); /** * @brief get raw data (touch sensor counter value) from IIR filter process. * Need not request hardware measurements. + * * @note touch_pad_filter_start has to be called before calling touch_pad_read_raw_data. * This function can be called from ISR * @@ -180,10 +191,10 @@ esp_err_t touch_pad_read_filtered(touch_pad_t touch_num, uint16_t *touch_value); * @param touch_value pointer to accept touch sensor value * * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Touch pad error - * - ESP_ERR_INVALID_STATE Touch pad not initialized - * - ESP_FAIL Touch pad not initialized + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Touch pad parameter error + * - ESP_ERR_INVALID_STATE This touch pad hardware connection is error, the value of "touch_value" is 0. + * - ESP_FAIL Touch pad not initialized */ esp_err_t touch_pad_read_raw_data(touch_pad_t touch_num, uint16_t *touch_value); @@ -508,8 +519,6 @@ esp_err_t touch_pad_get_filter_period(uint32_t* p_period_ms); * when detecting slight change of capacitance. * Need to call touch_pad_filter_start before all touch filter APIs * - * If filter is not initialized, this API will initialize the filter with given period. - * If filter is already initialized, this API will update the filter period. * @note This filter uses FreeRTOS timer, which is dispatched from a task with * priority 1 by default on CPU 0. So if some application task with higher priority * takes a lot of CPU0 time, then the quality of data obtained from this filter will be affected. diff --git a/components/driver/rtc_module.c b/components/driver/rtc_module.c index d08cbd135..9fb111abe 100644 --- a/components/driver/rtc_module.c +++ b/components/driver/rtc_module.c @@ -22,6 +22,7 @@ #include "soc/rtc_cntl_struct.h" #include "soc/syscon_reg.h" #include "soc/syscon_struct.h" +#include "soc/rtc.h" #include "rtc_io.h" #include "touch_pad.h" #include "adc.h" @@ -820,16 +821,28 @@ esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold) { RTC_MODULE_CHECK(rtc_touch_mux != NULL, "Touch pad not initialized", ESP_FAIL); RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG); - s_touch_pad_init_bit |= (1 << touch_num); + touch_fsm_mode_t mode; touch_pad_set_thresh(touch_num, threshold); touch_pad_io_init(touch_num); touch_pad_set_cnt_mode(touch_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_LOW); - touch_fsm_mode_t mode; touch_pad_get_fsm_mode(&mode); if (TOUCH_FSM_MODE_SW == mode) { touch_pad_clear_group_mask((1 << touch_num), (1 << touch_num), (1 << touch_num)); + s_touch_pad_init_bit |= (1 << touch_num); } else if (TOUCH_FSM_MODE_TIMER == mode){ + uint16_t sleep_time = 0; + uint16_t meas_cycle = 0; + uint32_t wait_time_ms = 0; + uint32_t wait_tick = 0; + uint32_t rtc_clk = rtc_clk_slow_freq_get_hz(); touch_pad_set_group_mask((1 << touch_num), (1 << touch_num), (1 << touch_num)); + touch_pad_get_meas_time(&sleep_time, &meas_cycle); + //If the FSM mode is 'TOUCH_FSM_MODE_TIMER', The data will be ready after one measurement cycle + //after this function is executed, otherwise, the "touch_value" by "touch_pad_read" is 0. + wait_time_ms = sleep_time/(rtc_clk/1000) + meas_cycle/(RTC_FAST_CLK_FREQ_APPROX/1000); + wait_tick = wait_time_ms/portTICK_RATE_MS; + vTaskDelay(wait_tick ? wait_tick : 1); + s_touch_pad_init_bit |= (1 << touch_num); } else { return ESP_FAIL; } @@ -846,11 +859,11 @@ esp_err_t touch_pad_init() } touch_pad_intr_disable(); touch_pad_clear_group_mask(TOUCH_PAD_BIT_MASK_MAX, TOUCH_PAD_BIT_MASK_MAX, TOUCH_PAD_BIT_MASK_MAX); - touch_pad_set_fsm_mode(TOUCH_FSM_MODE_DEFAULT); touch_pad_set_trigger_mode(TOUCH_TRIGGER_MODE_DEFAULT); touch_pad_set_trigger_source(TOUCH_TRIGGER_SOURCE_DEFAULT); touch_pad_clear_status(); touch_pad_set_meas_time(TOUCH_PAD_SLEEP_CYCLE_DEFAULT, TOUCH_PAD_MEASURE_CYCLE_DEFAULT); + touch_pad_set_fsm_mode(TOUCH_FSM_MODE_DEFAULT); return ESP_OK; } @@ -890,6 +903,9 @@ static esp_err_t _touch_pad_read(touch_pad_t touch_num, uint16_t *touch_value, t } else { res = ESP_FAIL; } + if (*touch_value == 0) { + res = ESP_ERR_INVALID_STATE; + } return res; } @@ -913,8 +929,11 @@ IRAM_ATTR esp_err_t touch_pad_read_raw_data(touch_pad_t touch_num, uint16_t *tou RTC_MODULE_CHECK(rtc_touch_mux != NULL, "Touch pad not initialized", ESP_FAIL); RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG); RTC_MODULE_CHECK(touch_value != NULL, "touch_value", ESP_ERR_INVALID_ARG); - RTC_MODULE_CHECK(s_touch_pad_filter != NULL, "Touch pad filter not initialized", ESP_ERR_INVALID_STATE); + RTC_MODULE_CHECK(s_touch_pad_filter != NULL, "Touch pad filter not initialized", ESP_FAIL); *touch_value = s_touch_pad_filter->raw_val[touch_num]; + if (*touch_value == 0) { + return ESP_ERR_INVALID_STATE; + } return ESP_OK; } @@ -923,8 +942,11 @@ IRAM_ATTR esp_err_t touch_pad_read_filtered(touch_pad_t touch_num, uint16_t *tou RTC_MODULE_CHECK(rtc_touch_mux != NULL, "Touch pad not initialized", ESP_FAIL); RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG); RTC_MODULE_CHECK(touch_value != NULL, "touch_value", ESP_ERR_INVALID_ARG); - RTC_MODULE_CHECK(s_touch_pad_filter != NULL, "Touch pad filter not initialized", ESP_ERR_INVALID_STATE); + RTC_MODULE_CHECK(s_touch_pad_filter != NULL, "Touch pad filter not initialized", ESP_FAIL); *touch_value = (s_touch_pad_filter->filtered_val[touch_num]); + if (*touch_value == 0) { + return ESP_ERR_INVALID_STATE; + } return ESP_OK; } @@ -984,13 +1006,10 @@ esp_err_t touch_pad_filter_start(uint32_t filter_period_ms) if (s_touch_pad_filter->timer == NULL) { ret = ESP_ERR_NO_MEM; } - xTimerStart(s_touch_pad_filter->timer, portMAX_DELAY); - } else { - xTimerChangePeriod(s_touch_pad_filter->timer, filter_period_ms / portTICK_PERIOD_MS, portMAX_DELAY); s_touch_pad_filter->period = filter_period_ms; - xTimerStart(s_touch_pad_filter->timer, portMAX_DELAY); } xSemaphoreGive(rtc_touch_mux); + touch_pad_filter_cb(NULL); return ret; } diff --git a/components/esp32/include/esp_sleep.h b/components/esp32/include/esp_sleep.h index a8bce5f79..8e50c7e20 100644 --- a/components/esp32/include/esp_sleep.h +++ b/components/esp32/include/esp_sleep.h @@ -113,6 +113,9 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us); * to be powered on (ESP_PD_OPTION_ON) or when ext0 wakeup * source is used. * + * @note The FSM mode of the touch button should be configured + * as the timer trigger mode. + * * @return * - ESP_OK on success * - ESP_ERR_INVALID_STATE if wakeup triggers conflict diff --git a/examples/peripherals/touch_pad_interrupt/main/tp_interrupt_main.c b/examples/peripherals/touch_pad_interrupt/main/tp_interrupt_main.c index dd0f8c26d..e3e3cbf21 100644 --- a/examples/peripherals/touch_pad_interrupt/main/tp_interrupt_main.c +++ b/examples/peripherals/touch_pad_interrupt/main/tp_interrupt_main.c @@ -35,14 +35,11 @@ static uint32_t s_pad_init_val[TOUCH_PAD_MAX]; static void tp_example_set_thresholds(void) { uint16_t touch_value; - //delay some time in order to make the filter work and get a initial value - vTaskDelay(500/portTICK_PERIOD_MS); - for (int i = 0; i