feat(temperature_sensor): Add sleep retention support for temperature sensor

This commit is contained in:
C.S.M
2024-10-16 17:35:35 +08:00
parent 39430c1404
commit 4cbc790628
30 changed files with 305 additions and 9 deletions
@@ -29,6 +29,9 @@
#include "soc/temperature_sensor_periph.h"
#include "esp_memory_utils.h"
#include "esp_private/sar_periph_ctrl.h"
#if TEMPERATURE_SENSOR_USE_RETENTION_LINK
#include "esp_private/sleep_retention.h"
#endif
static const char *TAG = "temperature_sensor";
@@ -93,6 +96,26 @@ static void IRAM_ATTR temperature_sensor_isr(void *arg)
}
#endif // SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
#if TEMPERATURE_SENSOR_USE_RETENTION_LINK
static esp_err_t s_temperature_sensor_sleep_retention_init(void *arg)
{
esp_err_t ret = sleep_retention_entries_create(temperature_sensor_regs_retention.link_list, temperature_sensor_regs_retention.link_num, REGDMA_LINK_PRI_TEMPERATURE_SENSOR, temperature_sensor_regs_retention.module_id);
ESP_RETURN_ON_ERROR(ret, TAG, "failed to allocate mem for sleep retention");
return ret;
}
void temperature_sensor_create_retention_module(temperature_sensor_handle_t tsens)
{
sleep_retention_module_t module_id = temperature_sensor_regs_retention.module_id;
if ((sleep_retention_get_inited_modules() & BIT(module_id)) && !(sleep_retention_get_created_modules() & BIT(module_id))) {
if (sleep_retention_module_allocate(module_id) != ESP_OK) {
// even though the sleep retention module_id create failed, temperature sensor driver should still work, so just warning here
ESP_LOGW(TAG, "create retention link failed, power domain won't be turned off during sleep");
}
}
}
#endif // TEMPERATURE_SENSOR_USE_RETENTION_LINK
esp_err_t temperature_sensor_install(const temperature_sensor_config_t *tsens_config, temperature_sensor_handle_t *ret_tsens)
{
#if CONFIG_TEMP_SENSOR_ENABLE_DEBUG_LOG
@@ -110,6 +133,24 @@ esp_err_t temperature_sensor_install(const temperature_sensor_config_t *tsens_co
tsens->clk_src = tsens_config->clk_src;
}
#if !SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
ESP_RETURN_ON_FALSE(tsens_config->flags.allow_pd == 0, ESP_ERR_NOT_SUPPORTED, TAG, "not able to power down in light sleep");
#endif // SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
#if TEMPERATURE_SENSOR_USE_RETENTION_LINK
sleep_retention_module_init_param_t init_param = {
.cbs = { .create = { .handle = s_temperature_sensor_sleep_retention_init, .arg = (void *)tsens } }
};
ret = sleep_retention_module_init(temperature_sensor_regs_retention.module_id, &init_param);
if (ret != ESP_OK) {
ESP_LOGW(TAG, "init sleep retention failed, power domain may be turned off during sleep");
}
if (tsens_config->flags.allow_pd != 0) {
temperature_sensor_create_retention_module(tsens);
}
#endif // TEMPERATURE_SENSOR_USE_RETENTION_LINK
temperature_sensor_power_acquire();
temperature_sensor_ll_clk_sel(tsens->clk_src);
@@ -147,6 +188,17 @@ esp_err_t temperature_sensor_uninstall(temperature_sensor_handle_t tsens)
ESP_RETURN_ON_ERROR(esp_intr_free(tsens->temp_sensor_isr_handle), TAG, "uninstall interrupt service failed");
}
#endif // SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
#if TEMPERATURE_SENSOR_USE_RETENTION_LINK
sleep_retention_module_t module_id = temperature_sensor_regs_retention.module_id;
if (sleep_retention_get_created_modules() & BIT(module_id)) {
sleep_retention_module_free(temperature_sensor_regs_retention.module_id);
}
if (sleep_retention_get_inited_modules() & BIT(module_id)) {
sleep_retention_module_deinit(temperature_sensor_regs_retention.module_id);
}
#endif // TEMPERATURE_SENSOR_USE_RETENTION_LINK
temperature_sensor_power_release();
free(tsens);
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -30,6 +30,9 @@ typedef enum {
#define TEMPERATURE_SENSOR_MEM_ALLOC_CAPS (MALLOC_CAP_DEFAULT)
#endif
// Use retention link only when the target supports sleep retention and PM is enabled
#define TEMPERATURE_SENSOR_USE_RETENTION_LINK (SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TEMPERATURE_SENSOR_UNDER_PD_TOP_DOMAIN)
typedef struct temperature_sensor_obj_t temperature_sensor_obj_t;
struct temperature_sensor_obj_t {