From 6b361ed70f8e1929fd6b8dc76f672e19a90674ab Mon Sep 17 00:00:00 2001 From: fuzhibo Date: Wed, 3 Feb 2021 12:29:31 +0800 Subject: [PATCH] fix: reduce the consumption of touch sensor during deep sleep --- .../esp32s2/include/driver/touch_sensor.h | 16 +++++ components/driver/esp32s2/touch_sensor.c | 6 ++ .../esp32s3/include/driver/touch_sensor.h | 16 +++++ components/esp_system/sleep_modes.c | 72 +++++++++++-------- .../esp32s2/include/hal/touch_sensor_hal.h | 27 +++++++ components/hal/esp32s2/touch_sensor_hal.c | 23 ++++++ .../esp32s3/include/hal/touch_sensor_hal.h | 27 +++++++ components/hal/esp32s3/touch_sensor_hal.c | 23 ++++++ components/soc/esp32s2/include/soc/rtc.h | 2 +- components/soc/esp32s3/include/soc/rtc.h | 2 +- .../deep_sleep/main/deep_sleep_example_main.c | 2 + 11 files changed, 183 insertions(+), 33 deletions(-) diff --git a/components/driver/esp32s2/include/driver/touch_sensor.h b/components/driver/esp32s2/include/driver/touch_sensor.h index efb488ea5b..86aae5adba 100644 --- a/components/driver/esp32s2/include/driver/touch_sensor.h +++ b/components/driver/esp32s2/include/driver/touch_sensor.h @@ -579,6 +579,22 @@ esp_err_t touch_pad_sleep_channel_reset_benchmark(void); */ esp_err_t touch_pad_sleep_channel_read_proximity_cnt(touch_pad_t pad_num, uint32_t *proximity_cnt); +/** + * @brief Change the operating frequency of touch pad in deep sleep state. Reducing the operating frequency can effectively reduce power consumption. + * If this function is not called, the working frequency of touch in the deep sleep state is the same as that in the wake-up state. + * + * @param sleep_cycle The touch sensor will sleep after each measurement. + * sleep_cycle decide the interval between each measurement. + * t_sleep = sleep_cycle / (RTC_SLOW_CLK frequency). + * The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function. + * @param meas_times The times of charge and discharge in each measure process of touch channels. + * The timer frequency is 8Mhz. Range: 0 ~ 0xffff. + * Recommended typical value: Modify this value to make the measurement time around 1ms. + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_sleep_channel_set_work_time(uint16_t sleep_cycle, uint16_t meas_times); + #ifdef __cplusplus } #endif diff --git a/components/driver/esp32s2/touch_sensor.c b/components/driver/esp32s2/touch_sensor.c index e291d2fb71..ce09c0bcc6 100644 --- a/components/driver/esp32s2/touch_sensor.c +++ b/components/driver/esp32s2/touch_sensor.c @@ -629,3 +629,9 @@ esp_err_t touch_pad_sleep_channel_read_proximity_cnt(touch_pad_t pad_num, uint32 touch_hal_sleep_read_proximity_cnt(approach_cnt); return ESP_OK; } + +esp_err_t touch_pad_sleep_channel_set_work_time(uint16_t sleep_cycle, uint16_t meas_times) +{ + touch_hal_sleep_channel_set_work_time(sleep_cycle, meas_times); + return ESP_OK; +} diff --git a/components/driver/esp32s3/include/driver/touch_sensor.h b/components/driver/esp32s3/include/driver/touch_sensor.h index 9c7d6c6d6d..9576b4dd8f 100644 --- a/components/driver/esp32s3/include/driver/touch_sensor.h +++ b/components/driver/esp32s3/include/driver/touch_sensor.h @@ -577,6 +577,22 @@ esp_err_t touch_pad_sleep_channel_reset_benchmark(void); */ esp_err_t touch_pad_sleep_channel_read_proximity_cnt(touch_pad_t pad_num, uint32_t *proximity_cnt); +/** + * @brief Change the operating frequency of touch pad in deep sleep state. Reducing the operating frequency can effectively reduce power consumption. + * If this function is not called, the working frequency of touch in the deep sleep state is the same as that in the wake-up state. + * + * @param sleep_cycle The touch sensor will sleep after each measurement. + * sleep_cycle decide the interval between each measurement. + * t_sleep = sleep_cycle / (RTC_SLOW_CLK frequency). + * The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function. + * @param meas_times The times of charge and discharge in each measure process of touch channels. + * The timer frequency is 8Mhz. Range: 0 ~ 0xffff. + * Recommended typical value: Modify this value to make the measurement time around 1ms. + * @return + * - ESP_OK Success + */ +esp_err_t touch_pad_sleep_channel_set_work_time(uint16_t sleep_cycle, uint16_t meas_times); + #ifdef __cplusplus } #endif diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index 06c5c7f999..4dae2dd1a3 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -139,7 +139,7 @@ typedef struct { uint32_t ext0_trigger_level : 1; uint32_t ext0_rtc_gpio_num : 5; uint32_t gpio_wakeup_mask : 6; - uint32_t gpio_trigger_mode :6; + uint32_t gpio_trigger_mode : 6; uint32_t sleep_time_adjustment; uint32_t ccount_ticks_record; uint32_t sleep_time_overhead_out; @@ -165,7 +165,7 @@ static bool s_light_sleep_wakeup = false; is not thread-safe, so we need to disable interrupts before going to deep sleep. */ static portMUX_TYPE spinlock_rtc_deep_sleep = portMUX_INITIALIZER_UNLOCKED; -static const char* TAG = "sleep"; +static const char *TAG = "sleep"; static uint32_t get_power_down_flags(void); #if SOC_PM_SUPPORT_EXT_WAKEUP @@ -189,7 +189,7 @@ static DRAM_ATTR mac_bb_power_up_cb_t s_mac_bb_power_up_cb[MAC_BB_POWER_UP_CB esp_err_t esp_register_mac_bb_pd_callback(mac_bb_power_down_cb_t cb) { int index = MAC_BB_POWER_DOWN_CB_NO; - for (int i = MAC_BB_POWER_DOWN_CB_NO -1; i >= 0; i--) { + for (int i = MAC_BB_POWER_DOWN_CB_NO - 1; i >= 0; i--) { if (s_mac_bb_power_down_cb[i] == cb) { return ESP_ERR_INVALID_STATE; } @@ -209,7 +209,7 @@ esp_err_t esp_register_mac_bb_pd_callback(mac_bb_power_down_cb_t cb) esp_err_t esp_unregister_mac_bb_pd_callback(mac_bb_power_down_cb_t cb) { - for (int i = MAC_BB_POWER_DOWN_CB_NO -1; i >= 0; i--) { + for (int i = MAC_BB_POWER_DOWN_CB_NO - 1; i >= 0; i--) { if (s_mac_bb_power_down_cb[i] == cb) { s_mac_bb_power_down_cb[i] = NULL; return ESP_OK; @@ -230,7 +230,7 @@ static IRAM_ATTR void mac_bb_power_down_cb_execute(void) esp_err_t esp_register_mac_bb_pu_callback(mac_bb_power_up_cb_t cb) { int index = MAC_BB_POWER_UP_CB_NO; - for (int i = MAC_BB_POWER_UP_CB_NO -1; i >= 0; i--) { + for (int i = MAC_BB_POWER_UP_CB_NO - 1; i >= 0; i--) { if (s_mac_bb_power_up_cb[i] == cb) { return ESP_ERR_INVALID_STATE; } @@ -250,7 +250,7 @@ esp_err_t esp_register_mac_bb_pu_callback(mac_bb_power_up_cb_t cb) esp_err_t esp_unregister_mac_bb_pu_callback(mac_bb_power_up_cb_t cb) { - for (int i = MAC_BB_POWER_UP_CB_NO -1; i >= 0; i--) { + for (int i = MAC_BB_POWER_UP_CB_NO - 1; i >= 0; i--) { if (s_mac_bb_power_up_cb[i] == cb) { s_mac_bb_power_up_cb[i] = NULL; return ESP_OK; @@ -286,13 +286,14 @@ void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub) REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub); } -void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) { +void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) +{ /* Clear MMU for CPU 0 */ #if CONFIG_IDF_TARGET_ESP32 _DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG, - _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) | DPORT_PRO_CACHE_MMU_IA_CLR); + _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) | DPORT_PRO_CACHE_MMU_IA_CLR); _DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG, - _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) & (~DPORT_PRO_CACHE_MMU_IA_CLR)); + _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) & (~DPORT_PRO_CACHE_MMU_IA_CLR)); #if DEEP_SLEEP_WAKEUP_DELAY > 0 // ROM code has not started yet, so we need to set delay factor // used by esp_rom_delay_us first. @@ -332,7 +333,9 @@ static void IRAM_ATTR suspend_uarts(void) { for (int i = 0; i < SOC_UART_NUM; ++i) { #ifndef CONFIG_IDF_TARGET_ESP32 - if (!periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) continue; + if (!periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { + continue; + } #endif uart_ll_force_xoff(i); #if SOC_UART_SUPPORT_FSM_TX_WAIT_SEND @@ -350,7 +353,9 @@ static void IRAM_ATTR resume_uarts(void) { for (int i = 0; i < SOC_UART_NUM; ++i) { #ifndef CONFIG_IDF_TARGET_ESP32 - if (!periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) continue; + if (!periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { + continue; + } #endif uart_ll_force_xon(i); } @@ -364,12 +369,12 @@ esp_err_t esp_sleep_cpu_pd_low_init(bool enable) if (enable) { if (s_config.cpu_pd_mem == NULL) { void *buf = heap_caps_aligned_alloc(RTC_CNTL_CPU_PD_DMA_ADDR_ALIGN, - RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE + RTC_HAL_DMA_LINK_NODE_SIZE, - MALLOC_CAP_RETENTION|MALLOC_CAP_DEFAULT); + RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE + RTC_HAL_DMA_LINK_NODE_SIZE, + MALLOC_CAP_RETENTION | MALLOC_CAP_DEFAULT); if (buf) { memset(buf, 0, RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE + RTC_HAL_DMA_LINK_NODE_SIZE); s_config.cpu_pd_mem = rtc_cntl_hal_dma_link_init(buf, - buf+RTC_HAL_DMA_LINK_NODE_SIZE, RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE, NULL); + buf + RTC_HAL_DMA_LINK_NODE_SIZE, RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE, NULL); } else { return ESP_ERR_NO_MEM; } @@ -529,13 +534,13 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) rtc_sleep_low_init(s_config.rtc_clk_cal_period); // Set state machine time for light sleep - if(!deep_sleep) { + if (!deep_sleep) { rtc_sleep_low_init(s_config.rtc_clk_cal_period); } // Configure timer wakeup if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) && - s_config.sleep_duration > 0) { + s_config.sleep_duration > 0) { timer_wakeup_prepare(); } @@ -590,9 +595,9 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers) { #ifdef CONFIG_IDF_TARGET_ESP32 - return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers); + return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers); #else - return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers, 1); + return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers, 1); #endif } @@ -647,12 +652,12 @@ void IRAM_ATTR esp_deep_sleep_start(void) * Placed into IRAM as flash may need some time to be powered on. */ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, - uint32_t flash_enable_time_us, - rtc_vddsdio_config_t vddsdio_config) IRAM_ATTR __attribute__((noinline)); + uint32_t flash_enable_time_us, + rtc_vddsdio_config_t vddsdio_config) IRAM_ATTR __attribute__((noinline)); static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, - uint32_t flash_enable_time_us, - rtc_vddsdio_config_t vddsdio_config) + uint32_t flash_enable_time_us, + rtc_vddsdio_config_t vddsdio_config) { // Enter sleep esp_err_t err = esp_sleep_start(pd_flags); @@ -685,7 +690,7 @@ esp_err_t esp_light_sleep_start(void) s_config.rtc_ticks_at_sleep_start = rtc_time_get(); uint32_t ccount_at_sleep_start = cpu_ll_get_cycle_count(); uint64_t frc_time_at_start = esp_system_get_time(); - uint32_t sleep_time_overhead_in = (ccount_at_sleep_start-s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL); + uint32_t sleep_time_overhead_in = (ccount_at_sleep_start - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL); DPORT_STALL_OTHER_CPU_START(); @@ -713,7 +718,7 @@ esp_err_t esp_light_sleep_start(void) uint32_t rtc_cntl_xtl_buf_wait_slp_cycles = rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, s_config.rtc_clk_cal_period); s_config.sleep_time_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US + sleep_time_overhead_in + s_config.sleep_time_overhead_out - + rtc_time_slowclk_to_us(rtc_cntl_xtl_buf_wait_slp_cycles + RTC_CNTL_CK8M_WAIT_SLP_CYCLES + RTC_CNTL_WAKEUP_DELAY_CYCLES, s_config.rtc_clk_cal_period); + + rtc_time_slowclk_to_us(rtc_cntl_xtl_buf_wait_slp_cycles + RTC_CNTL_CK8M_WAIT_SLP_CYCLES + RTC_CNTL_WAKEUP_DELAY_CYCLES, s_config.rtc_clk_cal_period); // Decide if VDD_SDIO needs to be powered down; // If it needs to be powered down, adjust sleep time. @@ -734,8 +739,8 @@ esp_err_t esp_light_sleep_start(void) * 4. All the adjustment time which is s_config.sleep_time_adjustment below. */ const uint32_t vddsdio_pd_sleep_duration = MAX(FLASH_PD_MIN_SLEEP_TIME_US, - flash_enable_time_us + LIGHT_SLEEP_MIN_TIME_US + s_config.sleep_time_adjustment - + rtc_time_slowclk_to_us(RTC_MODULE_SLEEP_PREPARE_CYCLES, s_config.rtc_clk_cal_period)); + flash_enable_time_us + LIGHT_SLEEP_MIN_TIME_US + s_config.sleep_time_adjustment + + rtc_time_slowclk_to_us(RTC_MODULE_SLEEP_PREPARE_CYCLES, s_config.rtc_clk_cal_period)); if (s_config.sleep_duration > vddsdio_pd_sleep_duration) { pd_flags |= RTC_SLEEP_PD_VDDSDIO; @@ -771,7 +776,7 @@ esp_err_t esp_light_sleep_start(void) // Enter sleep, then wait for flash to be ready on wakeup esp_err_t err = esp_light_sleep_inner(pd_flags, - flash_enable_time_us, vddsdio_config); + flash_enable_time_us, vddsdio_config); s_light_sleep_wakeup = true; @@ -862,7 +867,7 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void) return ESP_ERR_NOT_SUPPORTED; #endif #ifdef CONFIG_ESP32_ULP_COPROC_ENABLED - if(s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) { + if (s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) { ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0"); return ESP_ERR_INVALID_STATE; } @@ -901,12 +906,17 @@ static void timer_wakeup_prepare(void) /* In deep sleep mode, only the sleep channel is supported, and other touch channels should be turned off. */ static void touch_wakeup_prepare(void) { + uint16_t sleep_cycle = 0; + uint16_t meas_times = 0; touch_pad_t touch_num = TOUCH_PAD_NUM0; touch_ll_sleep_get_channel_num(&touch_num); // Check if the sleep pad is enabled. if ((touch_num > TOUCH_PAD_NUM0) && (touch_num < TOUCH_PAD_MAX) && touch_ll_get_fsm_state()) { touch_ll_stop_fsm(); touch_ll_clear_channel_mask(TOUCH_PAD_BIT_MASK_ALL); touch_ll_intr_clear(TOUCH_PAD_INTR_MASK_ALL); // Clear state from previous wakeup + touch_hal_sleep_channel_get_work_time(&sleep_cycle, &meas_times); + touch_ll_set_meas_times(meas_times); + touch_ll_set_sleep_time(sleep_cycle); touch_ll_set_channel_mask(BIT(touch_num)); touch_ll_start_fsm(); } @@ -1210,7 +1220,7 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void) } esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, - esp_sleep_pd_option_t option) + esp_sleep_pd_option_t option) { if (domain >= ESP_PD_DOMAIN_MAX || option > ESP_PD_OPTION_AUTO) { return ESP_ERR_INVALID_ARG; @@ -1289,7 +1299,7 @@ static uint32_t get_power_down_flags(void) s_config.pd_options[ESP_PD_DOMAIN_XTAL] = ESP_PD_OPTION_OFF; } - const char* option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */}; + const char *option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */}; ESP_LOGD(TAG, "RTC_PERIPH: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH]]); #if SOC_RTC_SLOW_MEM_SUPPORTED ESP_LOGD(TAG, "RTC_SLOW_MEM: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM]]); @@ -1322,7 +1332,7 @@ static uint32_t get_power_down_flags(void) #if ((defined CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) && (defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT)) if ((s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) == 0) { - // If enabled EXT1 only and enable the additional current by touch, should be keep RTC_PERIPH power on. + // If enabled EXT1 only and enable the additional current by touch, should be keep RTC_PERIPH power on. pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH; } #endif diff --git a/components/hal/esp32s2/include/hal/touch_sensor_hal.h b/components/hal/esp32s2/include/hal/touch_sensor_hal.h index 582d0153c6..2f1629067f 100644 --- a/components/hal/esp32s2/include/hal/touch_sensor_hal.h +++ b/components/hal/esp32s2/include/hal/touch_sensor_hal.h @@ -608,6 +608,33 @@ void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable); */ #define touch_hal_get_wakeup_status(pad_num) touch_ll_get_wakeup_status(pad_num) +/** + * Change the operating frequency of touch pad in deep sleep state. Reducing the operating frequency can effectively reduce power consumption. + * If this function is not called, the working frequency of touch in the deep sleep state is the same as that in the wake-up state. + * + * @param sleep_cycle The touch sensor will sleep after each measurement. + * sleep_cycle decide the interval between each measurement. + * t_sleep = sleep_cycle / (RTC_SLOW_CLK frequency). + * The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function. + * @param meas_times The times of charge and discharge in each measure process of touch channels. + * The timer frequency is 8Mhz. Range: 0 ~ 0xffff. + * Recommended typical value: Modify this value to make the measurement time around 1ms. + */ +void touch_hal_sleep_channel_set_work_time(uint16_t sleep_cycle, uint16_t meas_times); + +/** + * Get the operating frequency of touch pad in deep sleep state. Reducing the operating frequency can effectively reduce power consumption. + * + * @param sleep_cycle The touch sensor will sleep after each measurement. + * sleep_cycle decide the interval between each measurement. + * t_sleep = sleep_cycle / (RTC_SLOW_CLK frequency). + * The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function. + * @param meas_times The times of charge and discharge in each measure process of touch channels. + * The timer frequency is 8Mhz. Range: 0 ~ 0xffff. + * Recommended typical value: Modify this value to make the measurement time around 1ms. + */ +void touch_hal_sleep_channel_get_work_time(uint16_t *sleep_cycle, uint16_t *meas_times); + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s2/touch_sensor_hal.c b/components/hal/esp32s2/touch_sensor_hal.c index e07af73494..b13f0191f7 100644 --- a/components/hal/esp32s2/touch_sensor_hal.c +++ b/components/hal/esp32s2/touch_sensor_hal.c @@ -18,6 +18,9 @@ #include "hal/touch_sensor_hal.h" #include "hal/touch_sensor_types.h" +static int s_sleep_cycle = -1; +static int s_meas_times = -1; + void touch_hal_init(void) { touch_ll_stop_fsm(); @@ -157,3 +160,23 @@ void touch_hal_sleep_channel_get_config(touch_pad_sleep_channel_t *slp_config) touch_ll_sleep_get_channel_num(&slp_config->touch_num); slp_config->en_proximity = touch_ll_sleep_get_approach_status(); } + +void touch_hal_sleep_channel_set_work_time(uint16_t sleep_cycle, uint16_t meas_times) +{ + s_sleep_cycle = (int)sleep_cycle; + s_meas_times = (int)meas_times; +} + +void touch_hal_sleep_channel_get_work_time(uint16_t *sleep_cycle, uint16_t *meas_times) +{ + if (s_meas_times < 0) { + touch_ll_get_measure_times(meas_times); + } else { + *meas_times = (uint16_t)s_meas_times; + } + if (s_sleep_cycle < 0) { + touch_ll_get_sleep_time(sleep_cycle); + } else { + *sleep_cycle = (uint16_t)s_sleep_cycle; + } +} diff --git a/components/hal/esp32s3/include/hal/touch_sensor_hal.h b/components/hal/esp32s3/include/hal/touch_sensor_hal.h index ce125aa854..565bde40c6 100644 --- a/components/hal/esp32s3/include/hal/touch_sensor_hal.h +++ b/components/hal/esp32s3/include/hal/touch_sensor_hal.h @@ -608,6 +608,33 @@ void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable); */ #define touch_hal_get_wakeup_status(pad_num) touch_ll_get_wakeup_status(pad_num) +/** + * Change the operating frequency of touch pad in deep sleep state. Reducing the operating frequency can effectively reduce power consumption. + * If this function is not called, the working frequency of touch in the deep sleep state is the same as that in the wake-up state. + * + * @param sleep_cycle The touch sensor will sleep after each measurement. + * sleep_cycle decide the interval between each measurement. + * t_sleep = sleep_cycle / (RTC_SLOW_CLK frequency). + * The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function. + * @param meas_times The times of charge and discharge in each measure process of touch channels. + * The timer frequency is 8Mhz. Range: 0 ~ 0xffff. + * Recommended typical value: Modify this value to make the measurement time around 1ms. + */ +void touch_hal_sleep_channel_set_work_time(uint16_t sleep_cycle, uint16_t meas_times); + +/** + * Get the operating frequency of touch pad in deep sleep state. Reducing the operating frequency can effectively reduce power consumption. + * + * @param sleep_cycle The touch sensor will sleep after each measurement. + * sleep_cycle decide the interval between each measurement. + * t_sleep = sleep_cycle / (RTC_SLOW_CLK frequency). + * The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function. + * @param meas_times The times of charge and discharge in each measure process of touch channels. + * The timer frequency is 8Mhz. Range: 0 ~ 0xffff. + * Recommended typical value: Modify this value to make the measurement time around 1ms. + */ +void touch_hal_sleep_channel_get_work_time(uint16_t *sleep_cycle, uint16_t *meas_times); + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s3/touch_sensor_hal.c b/components/hal/esp32s3/touch_sensor_hal.c index dac05f4958..43e3a6f3b2 100644 --- a/components/hal/esp32s3/touch_sensor_hal.c +++ b/components/hal/esp32s3/touch_sensor_hal.c @@ -18,6 +18,9 @@ #include "hal/touch_sensor_types.h" #include "soc/soc_caps.h" +static int s_sleep_cycle = -1; +static int s_meas_times = -1; + void touch_hal_init(void) { touch_ll_stop_fsm(); @@ -157,3 +160,23 @@ void touch_hal_sleep_channel_get_config(touch_pad_sleep_channel_t *slp_config) touch_ll_sleep_get_channel_num(&slp_config->touch_num); slp_config->en_proximity = touch_ll_sleep_get_approach_status(); } + +void touch_hal_sleep_channel_set_work_time(uint16_t sleep_cycle, uint16_t meas_times) +{ + s_sleep_cycle = (int)sleep_cycle; + s_meas_times = (int)meas_times; +} + +void touch_hal_sleep_channel_get_work_time(uint16_t *sleep_cycle, uint16_t *meas_times) +{ + if (s_meas_times < 0) { + touch_ll_get_measure_times(meas_times); + } else { + *meas_times = (uint16_t)s_meas_times; + } + if (s_sleep_cycle < 0) { + touch_ll_get_sleep_time(sleep_cycle); + } else { + *sleep_cycle = (uint16_t)s_sleep_cycle; + } +} diff --git a/components/soc/esp32s2/include/soc/rtc.h b/components/soc/esp32s2/include/soc/rtc.h index 409a39b6a7..a438783c6c 100644 --- a/components/soc/esp32s2/include/soc/rtc.h +++ b/components/soc/esp32s2/include/soc/rtc.h @@ -121,7 +121,7 @@ set sleep_init default param #define RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT 0 #define RTC_CNTL_BIASSLP_MONITOR_DEFAULT 0 #define RTC_CNTL_BIASSLP_SLEEP_DEFAULT 1 -#define RTC_CNTL_PD_CUR_MONITOR_DEFAULT 0 +#define RTC_CNTL_PD_CUR_MONITOR_DEFAULT 1 #define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1 #define APLL_SDM_STOP_VAL_1 0x09 diff --git a/components/soc/esp32s3/include/soc/rtc.h b/components/soc/esp32s3/include/soc/rtc.h index d754d01da6..ba5f92e7f4 100644 --- a/components/soc/esp32s3/include/soc/rtc.h +++ b/components/soc/esp32s3/include/soc/rtc.h @@ -123,7 +123,7 @@ set sleep_init default param #define RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT 0 #define RTC_CNTL_BIASSLP_MONITOR_DEFAULT 0 #define RTC_CNTL_BIASSLP_SLEEP_DEFAULT 1 -#define RTC_CNTL_PD_CUR_MONITOR_DEFAULT 0 +#define RTC_CNTL_PD_CUR_MONITOR_DEFAULT 1 #define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1 /** diff --git a/examples/system/deep_sleep/main/deep_sleep_example_main.c b/examples/system/deep_sleep/main/deep_sleep_example_main.c index 7555c5ebac..1250894a86 100644 --- a/examples/system/deep_sleep/main/deep_sleep_example_main.c +++ b/examples/system/deep_sleep/main/deep_sleep_example_main.c @@ -239,6 +239,8 @@ void app_main(void) /* Set sleep touch pad. */ touch_pad_sleep_channel_enable(TOUCH_PAD_NUM9, true); touch_pad_sleep_channel_enable_proximity(TOUCH_PAD_NUM9, false); + /* Reducing the operating frequency can effectively reduce power consumption. */ + touch_pad_sleep_channel_set_work_time(1000, TOUCH_PAD_MEASURE_CYCLE_DEFAULT); /* Enable touch sensor clock. Work mode is "timer trigger". */ touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); touch_pad_fsm_start();