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

This commit is contained in:
C.S.M 2024-09-27 19:11:30 +08:00
parent 39430c1404
commit 4cbc790628
30 changed files with 305 additions and 9 deletions

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -30,6 +30,12 @@ typedef struct {
int range_min; /**< the minimum value of the temperature you want to test */
int range_max; /**< the maximum value of the temperature you want to test */
temperature_sensor_clk_src_t clk_src; /**< the clock source of the temperature sensor. */
struct {
uint32_t allow_pd; /**< If set, the driver will backup/restore the temperature sensor registers before/after entering/exist sleep mode.
By this approach, the system can power off temperature sensor's power domain.
This can save power, but at the expense of more RAM being consumed */
} flags; /**< Temperature sensor config flags */
} temperature_sensor_config_t;
/**

View File

@ -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);

View File

@ -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 {

View File

@ -9,5 +9,5 @@ endif()
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES unity esp_wifi test_utils nvs_flash esp_driver_tsens esp_driver_gpio
PRIV_REQUIRES unity esp_wifi test_utils nvs_flash esp_driver_tsens esp_driver_gpio esp_pm
WHOLE_ARCHIVE)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -13,6 +13,11 @@
#include "freertos/task.h"
#include "soc/soc_caps.h"
#include "unity_test_utils_cache.h"
#include "esp_sleep.h"
#include "esp_private/sleep_cpu.h"
#include "esp_pm.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/esp_pmu.h"
TEST_CASE("Temperature_sensor_driver_workflow_test", "[temperature_sensor]")
{
@ -146,3 +151,59 @@ TEST_CASE("Temperature sensor callback test", "[temperature_sensor]")
}
#endif // SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
#if SOC_LIGHT_SLEEP_SUPPORTED && CONFIG_PM_ENABLE
static void test_temperature_sensor_sleep_retention(bool allow_pd)
{
printf("Initializing Temperature sensor\n");
float tsens_result0;
float tsens_result1;
temperature_sensor_config_t temp_sensor = {
.range_min = 10,
.range_max = 50,
.clk_src = TEMPERATURE_SENSOR_CLK_SRC_DEFAULT,
.flags.allow_pd = allow_pd,
};
temperature_sensor_handle_t temp_handle = NULL;
TEST_ESP_OK(temperature_sensor_install(&temp_sensor, &temp_handle));
TEST_ESP_OK(temperature_sensor_enable(temp_handle));
printf("Temperature sensor started\n");
TEST_ESP_OK(temperature_sensor_get_celsius(temp_handle, &tsens_result0));
printf("Temperature out celsius %f°C\n", tsens_result0);
esp_sleep_context_t sleep_ctx;
esp_sleep_set_sleep_context(&sleep_ctx);
#if ESP_SLEEP_POWER_DOWN_CPU
TEST_ESP_OK(sleep_cpu_configure(true));
#endif
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(2 * 1000 * 1000));
TEST_ESP_OK(esp_light_sleep_start());
#if ESP_SLEEP_POWER_DOWN_CPU
TEST_ESP_OK(sleep_cpu_configure(false));
#endif
printf("check if the sleep happened as expected\r\n");
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result);
#if SOC_TEMPERATURE_SENSOR_UNDER_PD_TOP_DOMAIN
// check if the power domain also is powered down
TEST_ASSERT_EQUAL(allow_pd ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP);
#elif CONFIG_IDF_TARGET_ESP32P4
TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP);
#endif
TEST_ESP_OK(temperature_sensor_get_celsius(temp_handle, &tsens_result1));
printf("Temperature out celsius %f°C\n", tsens_result1);
TEST_ASSERT_FLOAT_WITHIN(6.0, tsens_result0, tsens_result1);
TEST_ESP_OK(temperature_sensor_disable(temp_handle));
TEST_ESP_OK(temperature_sensor_uninstall(temp_handle));
}
TEST_CASE("temperature sensor sleep retention test", "[temperature_sensor]")
{
test_temperature_sensor_sleep_retention(false);
#if SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
test_temperature_sensor_sleep_retention(true);
#endif
}
#endif

View File

@ -1,4 +1,5 @@
CONFIG_PM_ENABLE=y
CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y

View File

@ -1 +1,3 @@
CONFIG_ESP_TASK_WDT_EN=n
# primitives for checking sleep internal state
CONFIG_ESP_SLEEP_DEBUG=y

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -70,6 +70,13 @@ void regi2c_analog_cali_reg_read(void);
void regi2c_analog_cali_reg_write(void);
#endif //#if ADC_CALI_PD_WORKAROUND
#if SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
// regi2c would be powered down in light sleep, but measure range is recorded
// in regi2c, so this function is used for record.
void regi2c_tsens_reg_read(void);
void regi2c_tsens_reg_write(void);
#endif
/* Enable/Disable regi2c_saradc with calling these two functions.
With reference count protection inside.
Internal use only.

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -12,6 +12,7 @@
#include "hal/regi2c_ctrl.h"
#include "hal/regi2c_ctrl_ll.h"
#include "esp_hw_log.h"
#include "soc/soc_caps.h"
static portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
@ -109,3 +110,21 @@ void regi2c_saradc_disable(void)
regi2c_exit_critical();
}
#if SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
#include "soc/regi2c_saradc.h"
static DRAM_ATTR uint8_t dac_offset_regi2c;
void IRAM_ATTR regi2c_tsens_reg_read(void)
{
dac_offset_regi2c = REGI2C_READ_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC);
}
void IRAM_ATTR regi2c_tsens_reg_write(void)
{
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC, dac_offset_regi2c);
}
#endif

View File

@ -679,6 +679,9 @@ FORCE_INLINE_ATTR void misc_modules_sleep_prepare(uint32_t pd_flags, bool deep_s
#endif
#if REGI2C_ANA_CALI_PD_WORKAROUND
regi2c_analog_cali_reg_read();
#endif
#if SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
regi2c_tsens_reg_read();
#endif
}
@ -724,6 +727,9 @@ FORCE_INLINE_ATTR void misc_modules_wake_prepare(uint32_t pd_flags)
#if REGI2C_ANA_CALI_PD_WORKAROUND
regi2c_analog_cali_reg_write();
#endif
#if SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
regi2c_tsens_reg_write();
#endif
}
static IRAM_ATTR void sleep_low_power_clock_calibration(bool is_dslp)

View File

@ -1407,6 +1407,14 @@ config SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
bool
default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_TEMPERATURE_SENSOR_UNDER_PD_TOP_DOMAIN
bool
default y
config SOC_WIFI_HW_TSF
bool
default y

View File

@ -38,6 +38,7 @@ typedef enum periph_retention_module {
SLEEP_RETENTION_MODULE_UART1 = 15,
SLEEP_RETENTION_MODULE_I2S0 = 16,
SLEEP_RETENTION_MODULE_ETM0 = 17,
SLEEP_RETENTION_MODULE_TEMP_SENSOR = 18,
/* modem module, which includes WiFi, BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_WIFI_MAC = 26,
@ -78,6 +79,7 @@ typedef enum periph_retention_module_bitmap {
SLEEP_RETENTION_MODULE_BM_UART1 = BIT(SLEEP_RETENTION_MODULE_UART1),
SLEEP_RETENTION_MODULE_BM_I2S0 = BIT(SLEEP_RETENTION_MODULE_I2S0),
SLEEP_RETENTION_MODULE_BM_ETM0 = BIT(SLEEP_RETENTION_MODULE_ETM0),
SLEEP_RETENTION_MODULE_BM_TEMP_SENSOR = BIT(SLEEP_RETENTION_MODULE_TEMP_SENSOR),
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1),
@ -100,6 +102,7 @@ typedef enum periph_retention_module_bitmap {
| SLEEP_RETENTION_MODULE_BM_UART1 \
| SLEEP_RETENTION_MODULE_BM_I2S0 \
| SLEEP_RETENTION_MODULE_BM_ETM0 \
| SLEEP_RETENTION_MODULE_BM_TEMP_SENSOR \
)
#ifdef __cplusplus
}

View File

@ -591,6 +591,8 @@
#define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1)
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)
#define SOC_TEMPERATURE_SENSOR_INTR_SUPPORT (1)
#define SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION (1)
#define SOC_TEMPERATURE_SENSOR_UNDER_PD_TOP_DOMAIN (1)
/*------------------------------------ WI-FI CAPS ------------------------------------*/
#define SOC_WIFI_HW_TSF (1) /*!< Support hardware TSF */

View File

@ -4,7 +4,10 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "soc/regdma.h"
#include "soc/temperature_sensor_periph.h"
#include "soc/apb_saradc_reg.h"
const temperature_sensor_attribute_t temperature_sensor_attributes[TEMPERATURE_SENSOR_ATTR_RANGE_NUM] = {
/*Offset reg_val min max error */
@ -14,3 +17,24 @@ const temperature_sensor_attribute_t temperature_sensor_attributes[TEMPERATURE_S
{ 1, 11, -30, 50, 2},
{ 2, 10, -40, 20, 3},
};
// Temperature sensor sleep retention entries
// Temperature sensor registers require set the reg_update bit to make the configuration take effect
/* Temperature sensor Registers Context
Include: APB_SARADC_INT_ENA_REG /
APB_SARADC_APB_TSENS_CTRL_REG / APB_SARADC_TSENS_CTRL2_REG / APB_TSENS_WAKE_REG / APB_TSENS_SAMPLE_REG
*/
#define TEMPERATURE_SENSOR_RETENTION_REGS_CNT 5
#define TEMPERATURE_SENSOR_RETENTION_MAP_BASE APB_SARADC_INT_ENA_REG
static const uint32_t temperature_sensor_regs_map[4] = {0x6c1, 0, 0, 0};
static const regdma_entries_config_t temperature_sensor_regs_entries[] = {
[0] = {.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TSENS_LINK(0x00), TEMPERATURE_SENSOR_RETENTION_MAP_BASE, TEMPERATURE_SENSOR_RETENTION_MAP_BASE, TEMPERATURE_SENSOR_RETENTION_REGS_CNT, 0, 0, temperature_sensor_regs_map[0], temperature_sensor_regs_map[1], temperature_sensor_regs_map[2], temperature_sensor_regs_map[3]), \
.owner = ENTRY(0) | ENTRY(2) }, \
};
const temperature_sensor_reg_ctx_link_t temperature_sensor_regs_retention = {
.link_list = temperature_sensor_regs_entries,
.link_num = ARRAY_SIZE(temperature_sensor_regs_entries),
.module_id = SLEEP_RETENTION_MODULE_TEMP_SENSOR,
};

View File

@ -1459,6 +1459,14 @@ config SOC_TEMPERATURE_SENSOR_SUPPORT_ETM
bool
default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_TEMPERATURE_SENSOR_UNDER_PD_TOP_DOMAIN
bool
default y
config SOC_RNG_CLOCK_IS_INDEPENDENT
bool
default y

View File

@ -38,6 +38,7 @@ typedef enum periph_retention_module {
SLEEP_RETENTION_MODULE_UART1 = 15,
SLEEP_RETENTION_MODULE_I2S0 = 16,
SLEEP_RETENTION_MODULE_ETM0 = 17,
SLEEP_RETENTION_MODULE_TEMP_SENSOR = 18,
/* Modem module, which includes WiFi, BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_WIFI_MAC = 26,
@ -72,6 +73,7 @@ typedef enum periph_retention_module_bitmap {
SLEEP_RETENTION_MODULE_BM_UART1 = BIT(SLEEP_RETENTION_MODULE_UART1),
SLEEP_RETENTION_MODULE_BM_I2S0 = BIT(SLEEP_RETENTION_MODULE_I2S0),
SLEEP_RETENTION_MODULE_BM_ETM0 = BIT(SLEEP_RETENTION_MODULE_ETM0),
SLEEP_RETENTION_MODULE_BM_TEMP_SENSOR = BIT(SLEEP_RETENTION_MODULE_TEMP_SENSOR),
/* modem module, which includes WiFi, BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_BM_WIFI_MAC = BIT(SLEEP_RETENTION_MODULE_WIFI_MAC),
SLEEP_RETENTION_MODULE_BM_WIFI_BB = BIT(SLEEP_RETENTION_MODULE_WIFI_BB),
@ -96,6 +98,7 @@ typedef enum periph_retention_module_bitmap {
| SLEEP_RETENTION_MODULE_BM_UART1 \
| SLEEP_RETENTION_MODULE_BM_I2S0 \
| SLEEP_RETENTION_MODULE_BM_ETM0 \
| SLEEP_RETENTION_MODULE_BM_TEMP_SENSOR \
)
#ifdef __cplusplus

View File

@ -574,6 +574,8 @@
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)
#define SOC_TEMPERATURE_SENSOR_INTR_SUPPORT (1)
#define SOC_TEMPERATURE_SENSOR_SUPPORT_ETM (1)
#define SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION (1)
#define SOC_TEMPERATURE_SENSOR_UNDER_PD_TOP_DOMAIN (1)
/*--------------------------------- RNG CAPS --------------------------------------------*/
#define SOC_RNG_CLOCK_IS_INDEPENDENT (1)

View File

@ -1,10 +1,13 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "soc/regdma.h"
#include "soc/temperature_sensor_periph.h"
#include "soc/apb_saradc_reg.h"
const temperature_sensor_attribute_t temperature_sensor_attributes[TEMPERATURE_SENSOR_ATTR_RANGE_NUM] = {
/*Offset reg_val min max error */
@ -14,3 +17,24 @@ const temperature_sensor_attribute_t temperature_sensor_attributes[TEMPERATURE_S
{ 1, 11, -30, 50, 2},
{ 2, 10, -40, 20, 3},
};
// Temperature sensor sleep retention entries
// Temperature sensor registers require set the reg_update bit to make the configuration take effect
/* Temperature sensor Registers Context
Include: APB_SARADC_INT_ENA_REG /
APB_SARADC_APB_TSENS_CTRL_REG / APB_SARADC_TSENS_CTRL2_REG / APB_TSENS_WAKE_REG / APB_TSENS_SAMPLE_REG
*/
#define TEMPERATURE_SENSOR_RETENTION_REGS_CNT 5
#define TEMPERATURE_SENSOR_RETENTION_MAP_BASE APB_SARADC_INT_ENA_REG
static const uint32_t temperature_sensor_regs_map[4] = {0x6c1, 0, 0, 0};
static const regdma_entries_config_t temperature_sensor_regs_entries[] = {
[0] = {.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TSENS_LINK(0x00), TEMPERATURE_SENSOR_RETENTION_MAP_BASE, TEMPERATURE_SENSOR_RETENTION_MAP_BASE, TEMPERATURE_SENSOR_RETENTION_REGS_CNT, 0, 0, temperature_sensor_regs_map[0], temperature_sensor_regs_map[1], temperature_sensor_regs_map[2], temperature_sensor_regs_map[3]), \
.owner = ENTRY(0) | ENTRY(2) }, \
};
const temperature_sensor_reg_ctx_link_t temperature_sensor_regs_retention = {
.link_list = temperature_sensor_regs_entries,
.link_num = ARRAY_SIZE(temperature_sensor_regs_entries),
.module_id = SLEEP_RETENTION_MODULE_TEMP_SENSOR,
};

View File

@ -1423,6 +1423,14 @@ config SOC_TEMPERATURE_SENSOR_SUPPORT_ETM
bool
default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_TEMPERATURE_SENSOR_UNDER_PD_TOP_DOMAIN
bool
default y
config SOC_RNG_CLOCK_IS_INDEPENDENT
bool
default y

View File

@ -39,6 +39,7 @@ typedef enum periph_retention_module {
SLEEP_RETENTION_MODULE_UART1 = 16,
SLEEP_RETENTION_MODULE_I2S0 = 17,
SLEEP_RETENTION_MODULE_ETM0 = 18,
SLEEP_RETENTION_MODULE_TEMP_SENSOR = 19,
/* Modem module, which includes BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_BLE_MAC = 28,
@ -72,6 +73,7 @@ typedef enum periph_retention_module_bitmap {
SLEEP_RETENTION_MODULE_BM_UART1 = BIT(SLEEP_RETENTION_MODULE_UART1),
SLEEP_RETENTION_MODULE_BM_I2S0 = BIT(SLEEP_RETENTION_MODULE_I2S0),
SLEEP_RETENTION_MODULE_BM_ETM0 = BIT(SLEEP_RETENTION_MODULE_ETM0),
SLEEP_RETENTION_MODULE_BM_TEMP_SENSOR = BIT(SLEEP_RETENTION_MODULE_TEMP_SENSOR),
/* modem module, which includes BLE and 802.15.4 */
SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC),
SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB),
@ -95,6 +97,7 @@ typedef enum periph_retention_module_bitmap {
| SLEEP_RETENTION_MODULE_BM_UART1 \
| SLEEP_RETENTION_MODULE_BM_I2S0 \
| SLEEP_RETENTION_MODULE_BM_ETM0 \
| SLEEP_RETENTION_MODULE_BM_TEMP_SENSOR \
)
#ifdef __cplusplus

View File

@ -559,6 +559,8 @@
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)
#define SOC_TEMPERATURE_SENSOR_INTR_SUPPORT (1)
#define SOC_TEMPERATURE_SENSOR_SUPPORT_ETM (1)
#define SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION (1)
#define SOC_TEMPERATURE_SENSOR_UNDER_PD_TOP_DOMAIN (1)
/*--------------------------------- RNG CAPS --------------------------------------------*/
#define SOC_RNG_CLOCK_IS_INDEPENDENT (1)

View File

@ -1,10 +1,14 @@
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "soc/regdma.h"
#include "soc/temperature_sensor_periph.h"
#include "soc/apb_saradc_reg.h"
const temperature_sensor_attribute_t temperature_sensor_attributes[TEMPERATURE_SENSOR_ATTR_RANGE_NUM] = {
/*Offset reg_val min max error */
@ -14,3 +18,24 @@ const temperature_sensor_attribute_t temperature_sensor_attributes[TEMPERATURE_S
{ 1, 11, -30, 50, 2},
{ 2, 10, -40, 20, 3},
};
// Temperature sensor sleep retention entries
// Temperature sensor registers require set the reg_update bit to make the configuration take effect
/* Temperature sensor Registers Context
Include: APB_SARADC_INT_ENA_REG /
APB_SARADC_APB_TSENS_CTRL_REG / APB_SARADC_TSENS_CTRL2_REG / APB_TSENS_WAKE_REG / APB_TSENS_SAMPLE_REG
*/
#define TEMPERATURE_SENSOR_RETENTION_REGS_CNT 5
#define TEMPERATURE_SENSOR_RETENTION_MAP_BASE APB_SARADC_INT_ENA_REG
static const uint32_t temperature_sensor_regs_map[4] = {0x6c1, 0, 0, 0};
static const regdma_entries_config_t temperature_sensor_regs_entries[] = {
[0] = {.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TSENS_LINK(0x00), TEMPERATURE_SENSOR_RETENTION_MAP_BASE, TEMPERATURE_SENSOR_RETENTION_MAP_BASE, TEMPERATURE_SENSOR_RETENTION_REGS_CNT, 0, 0, temperature_sensor_regs_map[0], temperature_sensor_regs_map[1], temperature_sensor_regs_map[2], temperature_sensor_regs_map[3]), \
.owner = ENTRY(0) | ENTRY(2) }, \
};
const temperature_sensor_reg_ctx_link_t temperature_sensor_regs_retention = {
.link_list = temperature_sensor_regs_entries,
.link_num = ARRAY_SIZE(temperature_sensor_regs_entries),
.module_id = SLEEP_RETENTION_MODULE_TEMP_SENSOR,
};

View File

@ -1907,6 +1907,10 @@ config SOC_TEMPERATURE_SENSOR_SUPPORT_ETM
bool
default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_MEM_TCM_SUPPORTED
bool
default y

View File

@ -722,6 +722,8 @@
#define SOC_TEMPERATURE_SENSOR_INTR_SUPPORT (1)
#define SOC_TSENS_IS_INDEPENDENT_FROM_ADC (1) /*!< Temperature sensor is a separate module, not share regs with ADC */
#define SOC_TEMPERATURE_SENSOR_SUPPORT_ETM (1)
// temperature sensor on esp32p4 in under low power domain.
#define SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION (1)
/*-------------------------- Memory CAPS --------------------------*/
#define SOC_MEM_TCM_SUPPORTED (1)

View File

@ -55,6 +55,7 @@ extern "C" {
#define REGDMA_TG1_TIMER_LINK(_pri) ((0x1D << 8) | _pri)
#define REGDMA_I2S_LINK(_pri) ((0x1E << 8) | _pri)
#define REGDMA_ETM_LINK(_pri) ((0x1F << 8) | _pri)
#define REGDMA_TSENS_LINK(_pri) ((0x20 << 8) | _pri)
#define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri)
#define REGDMA_LINK_PRI_SYS_CLK REGDMA_LINK_PRI_0
@ -74,6 +75,7 @@ extern "C" {
#define REGDMA_LINK_PRI_I2C REGDMA_LINK_PRI_GENERAL_PERIPH
#define REGDMA_LINK_PRI_I2S REGDMA_LINK_PRI_GENERAL_PERIPH
#define REGDMA_LINK_PRI_UART REGDMA_LINK_PRI_GENERAL_PERIPH
#define REGDMA_LINK_PRI_TEMPERATURE_SENSOR REGDMA_LINK_PRI_GENERAL_PERIPH
typedef enum {
REGDMA_LINK_PRI_0 = 0,

View File

@ -1,11 +1,16 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "soc/regdma.h"
#if SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
#include "soc/retention_periph_defs.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -22,6 +27,16 @@ typedef struct {
extern const temperature_sensor_attribute_t temperature_sensor_attributes[TEMPERATURE_SENSOR_ATTR_RANGE_NUM];
#if SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
typedef struct {
const regdma_entries_config_t *link_list;
uint32_t link_num;
periph_retention_module_t module_id;
} temperature_sensor_reg_ctx_link_t;
extern const temperature_sensor_reg_ctx_link_t temperature_sensor_regs_retention;
#endif // SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
#ifdef __cplusplus
}
#endif

View File

@ -59,6 +59,7 @@ In order to install a built-in temperature sensor instance, the first thing is t
- :cpp:member:`range_min`: The minimum value of the testing range you have evaluated.
- :cpp:member:`range_max`: The maximum value of the testing range you have evaluated.
- :cpp:member:`allow_pd` configures if the driver allows the system to power down the peripheral in light sleep mode. Before entering sleep, the system will backup the temperature sensor register context, which will be restored later when the system exit the sleep mode. Powering down the peripheral can save more power, but at the cost of more memory consumed to save the register context. It's a tradeoff between power consumption and memory consumption. This configuration option relies on specific hardware feature, if you enable it on an unsupported chip, you will see error message like ``not able to power down in light sleep``.
After the ranges are set, the structure could be passed to :cpp:func:`temperature_sensor_install`, which will instantiate the temperature sensor instance and return a handle.

View File

@ -156,6 +156,7 @@ The following peripheral drivers are not aware of DFS yet. Applications need to
:SOC_I2C_SUPPORT_SLEEP_RETENTION: - I2C
:SOC_I2S_SUPPORT_SLEEP_RETENTION: - I2S
:SOC_UART_SUPPORT_SLEEP_RETENTION: - All UARTs
:SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION: - Temperature Sensor
The following peripherals are not yet supported:

View File

@ -59,6 +59,7 @@
- :cpp:member:`range_min`:所测量温度范围的最小值。
- :cpp:member:`range_max`:所测量温度范围的最大值。
- :cpp:member:`allow_pd` 配置驱动程序是否允许系统在睡眠模式下关闭外设电源。在进入睡眠之前,系统将备份温度传感器寄存器上下文,当系统退出睡眠模式时,这些上下文将被恢复。关闭外设可以节省更多功耗,但代价是消耗更多内存来保存寄存器上下文。你需要在功耗和内存消耗之间做权衡。此配置选项依赖于特定的硬件功能,如果在不支持的芯片上启用它,你将看到类似 ``not able to power down in light sleep`` 的错误消息。
设置好温度范围后,将配置结构体传递给 :cpp:func:`temperature_sensor_install`,该函数将创建温度传感器模块并返回句柄。

View File

@ -156,6 +156,7 @@ ESP-IDF 中集成的电源管理算法可以根据应用程序组件的需求,
:SOC_I2S_SUPPORT_SLEEP_RETENTION: - I2S
:SOC_ETM_SUPPORT_SLEEP_RETENTION: - ETM
:SOC_UART_SUPPORT_SLEEP_RETENTION: - All UARTs
:SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION: - Temperature Sensor
以下外设尚未支持: