Skip to content

Commit

Permalink
Merge branch 'bugfix/fix_touch_pad_can_not_wake_up' into 'master'
Browse files Browse the repository at this point in the history
bugfix(touch pad): modify deep-sleep example and add note for sleep api

See merge request idf/esp-idf!2553
  • Loading branch information
projectgus committed Jun 20, 2018
2 parents e3a3130 + 9a0d57b commit c1fdd45
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 31 deletions.
29 changes: 19 additions & 10 deletions components/driver/include/driver/touch_pad.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -144,46 +148,53 @@ 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);

/**
* @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
*
* @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_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);

Expand Down Expand Up @@ -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.
Expand Down
37 changes: 28 additions & 9 deletions components/driver/rtc_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down
3 changes: 3 additions & 0 deletions components/esp32/include/esp_sleep.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<TOUCH_PAD_MAX; i++) {
//read filtered value
touch_pad_read_filtered(i, &touch_value);
s_pad_init_val[i] = touch_value;
ESP_LOGI(TAG, "test init touch val: %d", touch_value);
ESP_LOGI(TAG, "test init: touch pad [%d] val is %d", i, touch_value);
//set interrupt threshold.
ESP_ERROR_CHECK(touch_pad_set_thresh(i, touch_value * 2 / 3));

Expand Down Expand Up @@ -159,10 +156,10 @@ void app_main()
// For most usage scenarios, we recommend using the following combination:
// the high reference valtage will be 2.7V - 1V = 1.7V, The low reference voltage will be 0.5V.
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
// Initialize and start a software filter to detect slight change of capacitance.
touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD);
// Init touch pad IO
tp_example_touch_pad_init();
// Initialize and start a software filter to detect slight change of capacitance.
touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD);
// Set thresh hold
tp_example_set_thresholds();
// Register touch interrupt ISR
Expand Down
8 changes: 4 additions & 4 deletions examples/peripherals/touch_pad_read/main/tp_read_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ static void tp_example_read_task(void *pvParameter)
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
#if TOUCH_FILTER_MODE_EN
// If open the filter mode, please use this API to get the touch pad count.
ESP_ERROR_CHECK(touch_pad_read_raw_data(i, &touch_value));
ESP_ERROR_CHECK(touch_pad_read_filtered(i, &touch_filter_value));
touch_pad_read_raw_data(i, &touch_value);
touch_pad_read_filtered(i, &touch_filter_value);
printf("T%d:[%4d,%4d] ", i, touch_value, touch_filter_value);
#else
ESP_ERROR_CHECK(touch_pad_read(i, &touch_value));
touch_pad_read(i, &touch_value);
printf("T%d:[%4d] ", i, touch_value);
#endif
}
Expand All @@ -62,10 +62,10 @@ void app_main()
// The low reference voltage will be 0.5
// The larger the range, the larger the pulse count value.
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
tp_example_touch_pad_init();
#if TOUCH_FILTER_MODE_EN
touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD);
#endif
tp_example_touch_pad_init();
// Start task to read values sensed by pads
xTaskCreate(&tp_example_read_task, "touch_pad_read_task", 2048, NULL, 5, NULL);
}
16 changes: 14 additions & 2 deletions examples/system/deep_sleep/main/deep_sleep_example_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ static inline void ulp_data_write(size_t offset, uint16_t value)
#endif // CONFIG_ENABLE_ULP_TEMPERATURE_WAKEUP

#ifdef CONFIG_ENABLE_TOUCH_WAKEUP
#define TOUCH_THRESH_NO_USE 0
static void calibrate_touch_pad(touch_pad_t pad);
#endif

Expand Down Expand Up @@ -145,11 +146,24 @@ void app_main()
esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ESP_EXT1_WAKEUP_ANY_HIGH);

#ifdef CONFIG_ENABLE_TOUCH_WAKEUP
// Initialize touch pad peripheral.
// The default fsm mode is software trigger mode.
touch_pad_init();
// If use touch pad wake up, should set touch sensor FSM mode at 'TOUCH_FSM_MODE_TIMER'.
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
// Set reference voltage for charging/discharging
// In this case, the high reference valtage will be 2.4V - 1V = 1.4V
// The low reference voltage will be 0.5
// The larger the range, the larger the pulse count value.
touch_pad_set_voltage(TOUCH_HVOLT_2V4, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
//init RTC IO and mode for touch pad.
touch_pad_config(TOUCH_PAD_NUM8, TOUCH_THRESH_NO_USE);
touch_pad_config(TOUCH_PAD_NUM9, TOUCH_THRESH_NO_USE);
calibrate_touch_pad(TOUCH_PAD_NUM8);
calibrate_touch_pad(TOUCH_PAD_NUM9);
printf("Enabling touch pad wakeup\n");
esp_sleep_enable_touchpad_wakeup();

#endif // CONFIG_ENABLE_TOUCH_WAKEUP

#ifdef CONFIG_ENABLE_ULP_TEMPERATURE_WAKEUP
Expand All @@ -175,8 +189,6 @@ void app_main()
#ifdef CONFIG_ENABLE_TOUCH_WAKEUP
static void calibrate_touch_pad(touch_pad_t pad)
{
touch_pad_config(pad, 1000);

int avg = 0;
const size_t calibration_count = 128;
for (int i = 0; i < calibration_count; ++i) {
Expand Down

0 comments on commit c1fdd45

Please sign in to comment.