Temperature_sensor: Create new temperature sensor API

This commit is contained in:
Cao Sen Miao
2022-03-04 18:04:20 +08:00
parent d25feba1bf
commit b248046bcb
44 changed files with 1143 additions and 987 deletions

View File

@@ -19,7 +19,10 @@ set(srcs
"spi_bus_lock.c" "spi_bus_lock.c"
"uart.c") "uart.c")
set(includes "include" "${target}/include" "deprecated") set(includes "include" "deprecated")
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${target}/include")
list(APPEND includes "${target}/include")
endif()
if(CONFIG_SOC_ADC_SUPPORTED) if(CONFIG_SOC_ADC_SUPPORTED)
list(APPEND srcs list(APPEND srcs
@@ -59,6 +62,11 @@ if(CONFIG_SOC_I2S_SUPPORTED)
list(APPEND srcs "i2s.c") list(APPEND srcs "i2s.c")
endif() endif()
if(CONFIG_SOC_TEMP_SENSOR_SUPPORTED)
list(APPEND srcs "temperature_sensor.c"
"rtc_temperature_legacy.c")
endif()
if(CONFIG_SOC_TWAI_SUPPORTED) if(CONFIG_SOC_TWAI_SUPPORTED)
list(APPEND srcs "twai.c") list(APPEND srcs "twai.c")
endif() endif()
@@ -77,7 +85,6 @@ if(IDF_TARGET STREQUAL "esp32s2")
list(APPEND srcs "dac_common.c" list(APPEND srcs "dac_common.c"
"spi_slave_hd.c" "spi_slave_hd.c"
"touch_sensor_common.c" "touch_sensor_common.c"
"esp32s2/rtc_tempsensor.c"
"esp32s2/touch_sensor.c" "esp32s2/touch_sensor.c"
"esp32s2/adc.c" "esp32s2/adc.c"
"adc_deprecated.c" "adc_deprecated.c"
@@ -95,13 +102,11 @@ endif()
if(IDF_TARGET STREQUAL "esp32c3") if(IDF_TARGET STREQUAL "esp32c3")
list(APPEND srcs "spi_slave_hd.c" list(APPEND srcs "spi_slave_hd.c"
"usb_serial_jtag.c" "usb_serial_jtag.c"
"esp32c3/adc2_init_cal.c" "esp32c3/adc2_init_cal.c")
"esp32c3/rtc_tempsensor.c")
endif() endif()
if(IDF_TARGET STREQUAL "esp32h2") if(IDF_TARGET STREQUAL "esp32h2")
list(APPEND srcs "spi_slave_hd.c" list(APPEND srcs "spi_slave_hd.c")
"esp32h2/rtc_tempsensor.c")
endif() endif()
if(IDF_TARGET STREQUAL "esp32c2") if(IDF_TARGET STREQUAL "esp32c2")

View File

@@ -1,92 +0,0 @@
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
TSENS_DAC_L0 = 0, /*!< offset = -2, measure range: 50℃ ~ 125℃, error < 3℃. */
TSENS_DAC_L1, /*!< offset = -1, measure range: 20℃ ~ 100℃, error < 2℃. */
TSENS_DAC_L2, /*!< offset = 0, measure range:-10℃ ~ 80℃, error < 1℃. */
TSENS_DAC_L3, /*!< offset = 1, measure range:-30℃ ~ 50℃, error < 2℃. */
TSENS_DAC_L4, /*!< offset = 2, measure range:-40℃ ~ 20℃, error < 3℃. */
TSENS_DAC_MAX,
TSENS_DAC_DEFAULT = TSENS_DAC_L2,
} temp_sensor_dac_offset_t;
/**
* @brief Configuration for temperature sensor reading
*/
typedef struct {
temp_sensor_dac_offset_t dac_offset; /*!< The temperature measurement range is configured with a built-in temperature offset DAC. */
uint8_t clk_div; /*!< Default: 6 */
} temp_sensor_config_t;
#define TSENS_CONFIG_DEFAULT() {.dac_offset = TSENS_DAC_L2, \
.clk_div = 6}
/**
* @brief Set parameter of temperature sensor.
* @param tsens
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens);
/**
* @brief Get parameter of temperature sensor.
* @param tsens
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens);
/**
* @brief Start temperature sensor measure.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE if temperature sensor is started already.
*/
esp_err_t temp_sensor_start(void);
/**
* @brief Stop temperature sensor measure.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE if temperature sensor is stopped already.
*/
esp_err_t temp_sensor_stop(void);
/**
* @brief Read temperature sensor raw data.
* @param tsens_out Pointer to raw data, Range: 0 ~ 255
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG `tsens_out` is NULL
* - ESP_ERR_INVALID_STATE temperature sensor dont start
*/
esp_err_t temp_sensor_read_raw(uint32_t *tsens_out);
/**
* @brief Read temperature sensor data that is converted to degrees Celsius.
* @note Should not be called from interrupt.
* @param celsius The measure output value.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG ARG is NULL.
* - ESP_ERR_INVALID_STATE The ambient temperature is out of range.
*/
esp_err_t temp_sensor_read_celsius(float *celsius);
#ifdef __cplusplus
}
#endif

View File

@@ -1,92 +0,0 @@
/*
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
TSENS_DAC_L0 = 0, /*!< offset = -2, measure range: 50℃ ~ 125℃, error < 3℃. */
TSENS_DAC_L1, /*!< offset = -1, measure range: 20℃ ~ 100℃, error < 2℃. */
TSENS_DAC_L2, /*!< offset = 0, measure range:-10℃ ~ 80℃, error < 1℃. */
TSENS_DAC_L3, /*!< offset = 1, measure range:-30℃ ~ 50℃, error < 2℃. */
TSENS_DAC_L4, /*!< offset = 2, measure range:-40℃ ~ 20℃, error < 3℃. */
TSENS_DAC_MAX,
TSENS_DAC_DEFAULT = TSENS_DAC_L2,
} temp_sensor_dac_offset_t;
/**
* @brief Configuration for temperature sensor reading
*/
typedef struct {
temp_sensor_dac_offset_t dac_offset; /*!< The temperature measurement range is configured with a built-in temperature offset DAC. */
uint8_t clk_div; /*!< Default: 6 */
} temp_sensor_config_t;
#define TSENS_CONFIG_DEFAULT() {.dac_offset = TSENS_DAC_L2, \
.clk_div = 6}
/**
* @brief Set parameter of temperature sensor.
* @param tsens
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens);
/**
* @brief Get parameter of temperature sensor.
* @param tsens
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens);
/**
* @brief Start temperature sensor measure.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE if temperature sensor is started already.
*/
esp_err_t temp_sensor_start(void);
/**
* @brief Stop temperature sensor measure.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE if temperature sensor is stopped already.
*/
esp_err_t temp_sensor_stop(void);
/**
* @brief Read temperature sensor raw data.
* @param tsens_out Pointer to raw data, Range: 0 ~ 255
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG `tsens_out` is NULL
* - ESP_ERR_INVALID_STATE temperature sensor dont start
*/
esp_err_t temp_sensor_read_raw(uint32_t *tsens_out);
/**
* @brief Read temperature sensor data that is converted to degrees Celsius.
* @note Should not be called from interrupt.
* @param celsius The measure output value.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG ARG is NULL.
* - ESP_ERR_INVALID_STATE The ambient temperature is out of range.
*/
esp_err_t temp_sensor_read_celsius(float *celsius);
#ifdef __cplusplus
}
#endif

View File

@@ -1,164 +0,0 @@
/*
* SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <esp_types.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "esp_check.h"
#include "hal/adc_ll.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/apb_saradc_struct.h"
#include "soc/apb_saradc_reg.h"
#include "soc/system_reg.h"
#include "driver/temp_sensor.h"
#include "regi2c_ctrl.h"
#include "esp32c3/rom/ets_sys.h"
#include "esp_efuse_rtc_calib.h"
static const char *TAG = "tsens";
#define TSENS_XPD_WAIT_DEFAULT 0xFF /* Set wait cycle time(8MHz) from power up to reset enable. */
#define TSENS_ADC_FACTOR (0.4386)
#define TSENS_DAC_FACTOR (27.88)
#define TSENS_SYS_OFFSET (20.52)
typedef struct {
int index;
int offset;
int set_val;
int range_min;
int range_max;
int error_max;
} tsens_dac_offset_t;
static const tsens_dac_offset_t dac_offset[TSENS_DAC_MAX] = {
/* DAC Offset reg_val min max error */
{TSENS_DAC_L0, -2, 5, 50, 125, 3},
{TSENS_DAC_L1, -1, 7, 20, 100, 2},
{TSENS_DAC_L2, 0, 15, -10, 80, 1},
{TSENS_DAC_L3, 1, 11, -30, 50, 2},
{TSENS_DAC_L4, 2, 10, -40, 20, 3},
};
typedef enum {
TSENS_HW_STATE_UNCONFIGURED,
TSENS_HW_STATE_CONFIGURED,
TSENS_HW_STATE_STARTED,
} tsens_hw_state_t;
static tsens_hw_state_t tsens_hw_state = TSENS_HW_STATE_UNCONFIGURED;
static float s_deltaT = NAN; // unused number
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens)
{
if (tsens_hw_state == TSENS_HW_STATE_STARTED) {
ESP_LOGE(TAG, "Do not configure the temp sensor when it's running!");
return ESP_ERR_INVALID_STATE;
}
REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_TSENS_CLK_EN);
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PD);
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PU);
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC, dac_offset[tsens.dac_offset].set_val);
APB_SARADC.apb_tsens_ctrl.tsens_clk_div = tsens.clk_div;
APB_SARADC.apb_tsens_ctrl2.tsens_xpd_wait = TSENS_XPD_WAIT_DEFAULT;
APB_SARADC.apb_tsens_ctrl2.tsens_xpd_force = 1;
ESP_LOGD(TAG, "Config temperature range [%d°C ~ %d°C], error < %d°C",
dac_offset[tsens.dac_offset].range_min,
dac_offset[tsens.dac_offset].range_max,
dac_offset[tsens.dac_offset].error_max);
tsens_hw_state = TSENS_HW_STATE_CONFIGURED;
return ESP_OK;
}
esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens)
{
ESP_RETURN_ON_FALSE(tsens != NULL, ESP_ERR_INVALID_ARG, TAG, "no tsens specified");
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PD);
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PU);
tsens->dac_offset = REGI2C_READ_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC);
for (int i = TSENS_DAC_L0; i < TSENS_DAC_MAX; i++) {
if (tsens->dac_offset == dac_offset[i].set_val) {
tsens->dac_offset = dac_offset[i].index;
break;
}
}
tsens->clk_div = APB_SARADC.apb_tsens_ctrl.tsens_clk_div;
return ESP_OK;
}
esp_err_t temp_sensor_start(void)
{
if (tsens_hw_state != TSENS_HW_STATE_CONFIGURED) {
ESP_LOGE(TAG, "Temperature sensor is already running or not be configured");
return ESP_ERR_INVALID_STATE;
}
REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_TSENS_CLK_EN);
APB_SARADC.apb_tsens_ctrl2.tsens_clk_sel = 1;
APB_SARADC.apb_tsens_ctrl.tsens_pu = 1;
tsens_hw_state = TSENS_HW_STATE_STARTED;
return ESP_OK;
}
esp_err_t temp_sensor_stop(void)
{
APB_SARADC.apb_tsens_ctrl.tsens_pu = 0;
APB_SARADC.apb_tsens_ctrl2.tsens_clk_sel = 0;
return ESP_OK;
}
esp_err_t temp_sensor_read_raw(uint32_t *tsens_out)
{
ESP_RETURN_ON_FALSE(tsens_out != NULL, ESP_ERR_INVALID_ARG, TAG, "no tsens_out specified");
*tsens_out = APB_SARADC.apb_tsens_ctrl.tsens_out;
return ESP_OK;
}
static void read_delta_t_from_efuse(void)
{
uint32_t version = esp_efuse_rtc_calib_get_ver();
if (version == 1) {
// fetch calibration value for temp sensor from eFuse
s_deltaT = esp_efuse_rtc_calib_get_cal_temp(version);
} else {
// no value to fetch, use 0.
s_deltaT = 0;
}
ESP_LOGD(TAG, "s_deltaT = %f", s_deltaT);
}
static float parse_temp_sensor_raw_value(uint32_t tsens_raw, const int dac_offset)
{
if (isnan(s_deltaT)) { //suggests that the value is not initialized
read_delta_t_from_efuse();
}
float result = (TSENS_ADC_FACTOR * (float)tsens_raw - TSENS_DAC_FACTOR * dac_offset - TSENS_SYS_OFFSET) - s_deltaT / 10.0;
return result;
}
esp_err_t temp_sensor_read_celsius(float *celsius)
{
ESP_RETURN_ON_FALSE(celsius != NULL, ESP_ERR_INVALID_ARG, TAG, "celsius points to nothing");
temp_sensor_config_t tsens;
uint32_t tsens_out = 0;
esp_err_t ret = temp_sensor_get_config(&tsens);
if (ret == ESP_OK) {
ret = temp_sensor_read_raw(&tsens_out);
ESP_LOGV(TAG, "tsens_out %d", tsens_out);
ESP_RETURN_ON_FALSE(ret == ESP_OK, ret, TAG, "failed to read raw data");
const tsens_dac_offset_t *dac = &dac_offset[tsens.dac_offset];
*celsius = parse_temp_sensor_raw_value(tsens_out, dac->offset);
if (*celsius < dac->range_min || *celsius > dac->range_max) {
ESP_LOGW(TAG, "Exceeding the temperature range!");
ret = ESP_ERR_INVALID_STATE;
}
}
return ret;
}

View File

@@ -1,91 +0,0 @@
/*
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
TSENS_DAC_L0 = 0, /*!< offset = -2, measure range: 50℃ ~ 125℃, error < 3℃. */
TSENS_DAC_L1, /*!< offset = -1, measure range: 20℃ ~ 100℃, error < 2℃. */
TSENS_DAC_L2, /*!< offset = 0, measure range:-10℃ ~ 80℃, error < 1℃. */
TSENS_DAC_L3, /*!< offset = 1, measure range:-30℃ ~ 50℃, error < 2℃. */
TSENS_DAC_L4, /*!< offset = 2, measure range:-40℃ ~ 20℃, error < 3℃. */
TSENS_DAC_MAX,
TSENS_DAC_DEFAULT = TSENS_DAC_L2,
} temp_sensor_dac_offset_t;
/**
* @brief Configuration for temperature sensor reading
*/
typedef struct {
temp_sensor_dac_offset_t dac_offset; /*!< The temperature measurement range is configured with a built-in temperature offset DAC. */
uint8_t clk_div; /*!< Default: 6 */
} temp_sensor_config_t;
#define TSENS_CONFIG_DEFAULT() {.dac_offset = TSENS_DAC_L2, \
.clk_div = 6}
/**
* @brief Set parameter of temperature sensor.
* @param tsens
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens);
/**
* @brief Get parameter of temperature sensor.
* @param tsens
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens);
/**
* @brief Start temperature sensor measure.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG
*/
esp_err_t temp_sensor_start(void);
/**
* @brief Stop temperature sensor measure.
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_stop(void);
/**
* @brief Read temperature sensor raw data.
* @param tsens_out Pointer to raw data, Range: 0 ~ 255
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG `tsens_out` is NULL
* - ESP_ERR_INVALID_STATE temperature sensor dont start
*/
esp_err_t temp_sensor_read_raw(uint32_t *tsens_out);
/**
* @brief Read temperature sensor data that is converted to degrees Celsius.
* @note Should not be called from interrupt.
* @param celsius The measure output value.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG ARG is NULL.
* - ESP_ERR_INVALID_STATE The ambient temperature is out of range.
*/
esp_err_t temp_sensor_read_celsius(float *celsius);
#ifdef __cplusplus
}
#endif

View File

@@ -1,164 +0,0 @@
/*
* SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <esp_types.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "esp_check.h"
#include "hal/adc_ll.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/apb_saradc_struct.h"
#include "soc/apb_saradc_reg.h"
#include "soc/system_reg.h"
#include "driver/temp_sensor.h"
#include "regi2c_ctrl.h"
#include "esp32h2/rom/ets_sys.h"
#include "esp_efuse_rtc_calib.h"
static const char *TAG = "tsens";
#define TSENS_XPD_WAIT_DEFAULT 0xFF /* Set wait cycle time(8MHz) from power up to reset enable. */
#define TSENS_ADC_FACTOR (0.4386)
#define TSENS_DAC_FACTOR (27.88)
#define TSENS_SYS_OFFSET (20.52)
typedef struct {
int index;
int offset;
int set_val;
int range_min;
int range_max;
int error_max;
} tsens_dac_offset_t;
static const tsens_dac_offset_t dac_offset[TSENS_DAC_MAX] = {
/* DAC Offset reg_val min max error */
{TSENS_DAC_L0, -2, 5, 50, 125, 3},
{TSENS_DAC_L1, -1, 7, 20, 100, 2},
{TSENS_DAC_L2, 0, 15, -10, 80, 1},
{TSENS_DAC_L3, 1, 11, -30, 50, 2},
{TSENS_DAC_L4, 2, 10, -40, 20, 3},
};
typedef enum {
TSENS_HW_STATE_UNCONFIGURED,
TSENS_HW_STATE_CONFIGURED,
TSENS_HW_STATE_STARTED,
} tsens_hw_state_t;
static tsens_hw_state_t tsens_hw_state = TSENS_HW_STATE_UNCONFIGURED;
static float s_deltaT = NAN; // unused number
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens)
{
if (tsens_hw_state == TSENS_HW_STATE_STARTED) {
ESP_LOGE(TAG, "Do not configure the temp sensor when it's running!");
return ESP_ERR_INVALID_STATE;
}
REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_TSENS_CLK_EN);
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PD);
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PU);
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC, dac_offset[tsens.dac_offset].set_val);
APB_SARADC.apb_tsens_ctrl.tsens_clk_div = tsens.clk_div;
APB_SARADC.apb_tsens_ctrl2.tsens_xpd_wait = TSENS_XPD_WAIT_DEFAULT;
APB_SARADC.apb_tsens_ctrl2.tsens_xpd_force = 1;
ESP_LOGD(TAG, "Config temperature range [%d°C ~ %d°C], error < %d°C",
dac_offset[tsens.dac_offset].range_min,
dac_offset[tsens.dac_offset].range_max,
dac_offset[tsens.dac_offset].error_max);
tsens_hw_state = TSENS_HW_STATE_CONFIGURED;
return ESP_OK;
}
esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens)
{
ESP_RETURN_ON_FALSE(tsens != NULL, ESP_ERR_INVALID_ARG, TAG, "no tsens specified");
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PD);
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PU);
tsens->dac_offset = REGI2C_READ_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC);
for (int i = TSENS_DAC_L0; i < TSENS_DAC_MAX; i++) {
if (tsens->dac_offset == dac_offset[i].set_val) {
tsens->dac_offset = dac_offset[i].index;
break;
}
}
tsens->clk_div = APB_SARADC.apb_tsens_ctrl.tsens_clk_div;
return ESP_OK;
}
esp_err_t temp_sensor_start(void)
{
if (tsens_hw_state != TSENS_HW_STATE_CONFIGURED) {
ESP_LOGE(TAG, "Temperature sensor is already running or not be configured");
return ESP_ERR_INVALID_STATE;
}
REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_TSENS_CLK_EN);
APB_SARADC.apb_tsens_ctrl2.tsens_clk_sel = 1;
APB_SARADC.apb_tsens_ctrl.tsens_pu = 1;
tsens_hw_state = TSENS_HW_STATE_STARTED;
return ESP_OK;
}
esp_err_t temp_sensor_stop(void)
{
APB_SARADC.apb_tsens_ctrl.tsens_pu = 0;
APB_SARADC.apb_tsens_ctrl2.tsens_clk_sel = 0;
return ESP_OK;
}
esp_err_t temp_sensor_read_raw(uint32_t *tsens_out)
{
ESP_RETURN_ON_FALSE(tsens_out != NULL, ESP_ERR_INVALID_ARG, TAG, "no tsens_out specified");
*tsens_out = APB_SARADC.apb_tsens_ctrl.tsens_out;
return ESP_OK;
}
static void read_delta_t_from_efuse(void)
{
uint32_t version = esp_efuse_rtc_calib_get_ver();
if (version == 1) {
// fetch calibration value for temp sensor from eFuse
s_deltaT = esp_efuse_rtc_calib_get_cal_temp(version);
} else {
// no value to fetch, use 0.
s_deltaT = 0;
}
ESP_LOGD(TAG, "s_deltaT = %f", s_deltaT);
}
static float parse_temp_sensor_raw_value(uint32_t tsens_raw, const int dac_offset)
{
if (isnan(s_deltaT)) { //suggests that the value is not initialized
read_delta_t_from_efuse();
}
float result = (TSENS_ADC_FACTOR * (float)tsens_raw - TSENS_DAC_FACTOR * dac_offset - TSENS_SYS_OFFSET) - s_deltaT / 10.0;
return result;
}
esp_err_t temp_sensor_read_celsius(float *celsius)
{
ESP_RETURN_ON_FALSE(celsius != NULL, ESP_ERR_INVALID_ARG, TAG, "celsius points to nothing");
temp_sensor_config_t tsens;
uint32_t tsens_out = 0;
esp_err_t ret = temp_sensor_get_config(&tsens);
if (ret == ESP_OK) {
ret = temp_sensor_read_raw(&tsens_out);
ESP_LOGV(TAG, "tsens_out %d", tsens_out);
ESP_RETURN_ON_FALSE(ret == ESP_OK, ret, TAG, "failed to read raw data");
const tsens_dac_offset_t *dac = &dac_offset[tsens.dac_offset];
*celsius = parse_temp_sensor_raw_value(tsens_out, dac->offset);
if (*celsius < dac->range_min || *celsius > dac->range_max) {
ESP_LOGW(TAG, "Exceeding the temperature range!");
ret = ESP_ERR_INVALID_STATE;
}
}
return ret;
}

View File

@@ -1,97 +0,0 @@
/*
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief temperature sensor range option.
*/
typedef enum {
TSENS_DAC_L0 = 0, /*!< offset = -2, measure range: 50℃ ~ 125℃, error < 3℃. */
TSENS_DAC_L1, /*!< offset = -1, measure range: 20℃ ~ 100℃, error < 2℃. */
TSENS_DAC_L2, /*!< offset = 0, measure range:-10℃ ~ 80℃, error < 1℃. */
TSENS_DAC_L3, /*!< offset = 1, measure range:-30℃ ~ 50℃, error < 2℃. */
TSENS_DAC_L4, /*!< offset = 2, measure range:-40℃ ~ 20℃, error < 3℃. */
TSENS_DAC_MAX,
TSENS_DAC_DEFAULT = TSENS_DAC_L2,
} temp_sensor_dac_offset_t;
/**
* @brief Configuration for temperature sensor reading
*/
typedef struct {
temp_sensor_dac_offset_t dac_offset; /*!< The temperature measurement range is configured with a built-in temperature offset DAC. */
uint8_t clk_div; /*!< Default: 6 */
} temp_sensor_config_t;
/**
* @brief temperature sensor default setting.
*/
#define TSENS_CONFIG_DEFAULT() {.dac_offset = TSENS_DAC_L2, \
.clk_div = 6}
/**
* @brief Set parameter of temperature sensor.
* @param tsens
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens);
/**
* @brief Get parameter of temperature sensor.
* @param tsens
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens);
/**
* @brief Start temperature sensor measure.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG
*/
esp_err_t temp_sensor_start(void);
/**
* @brief Stop temperature sensor measure.
* @return
* - ESP_OK Success
*/
esp_err_t temp_sensor_stop(void);
/**
* @brief Read temperature sensor raw data.
* @param tsens_out Pointer to raw data, Range: 0 ~ 255
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG `tsens_out` is NULL
* - ESP_ERR_INVALID_STATE temperature sensor dont start
*/
esp_err_t temp_sensor_read_raw(uint32_t *tsens_out);
/**
* @brief Read temperature sensor data that is converted to degrees Celsius.
* @note Should not be called from interrupt.
* @param celsius The measure output value.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG ARG is NULL.
* - ESP_ERR_INVALID_STATE The ambient temperature is out of range.
*/
esp_err_t temp_sensor_read_celsius(float *celsius);
#ifdef __cplusplus
}
#endif

View File

@@ -1,187 +0,0 @@
/*
* SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include "esp_types.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "esp_check.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_reg.h"
#include "soc/rtc_io_struct.h"
#include "soc/sens_reg.h"
#include "soc/sens_struct.h"
#include "driver/temp_sensor.h"
#include "regi2c_ctrl.h"
#include "esp_log.h"
#include "esp_efuse_rtc_table.h"
static const char *TAG = "tsens";
#define TSENS_XPD_WAIT_DEFAULT 0xFF /* Set wait cycle time(8MHz) from power up to reset enable. */
#define TSENS_ADC_FACTOR (0.4386)
#define TSENS_DAC_FACTOR (27.88)
#define TSENS_SYS_OFFSET (20.52)
typedef struct {
int index;
int offset;
int set_val;
int range_min;
int range_max;
int error_max;
} tsens_dac_offset_t;
static const tsens_dac_offset_t dac_offset[TSENS_DAC_MAX] = {
/* DAC Offset reg_val min max error */
{TSENS_DAC_L0, -2, 5, 50, 125, 3},
{TSENS_DAC_L1, -1, 7, 20, 100, 2},
{TSENS_DAC_L2, 0, 15, -10, 80, 1},
{TSENS_DAC_L3, 1, 11, -30, 50, 2},
{TSENS_DAC_L4, 2, 10, -40, 20, 3},
};
typedef enum {
TSENS_HW_STATE_UNCONFIGURED,
TSENS_HW_STATE_CONFIGURED,
TSENS_HW_STATE_STARTED,
} tsens_hw_state_t;
static tsens_hw_state_t tsens_hw_state = TSENS_HW_STATE_UNCONFIGURED;
static SemaphoreHandle_t rtc_tsens_mux = NULL;
static float s_deltaT = NAN; // Unused number
esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens)
{
esp_err_t err = ESP_OK;
if (tsens_hw_state == TSENS_HW_STATE_STARTED) {
ESP_LOGE(TAG, "Do not configure the temp sensor when it's running!");
err = ESP_ERR_INVALID_STATE;
}
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M);
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_SAR_M);
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M);
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC, dac_offset[tsens.dac_offset].set_val);
SENS.sar_tctrl.tsens_clk_div = tsens.clk_div;
SENS.sar_tctrl.tsens_power_up_force = 1;
SENS.sar_tctrl2.tsens_xpd_wait = TSENS_XPD_WAIT_DEFAULT;
SENS.sar_tctrl2.tsens_xpd_force = 1;
SENS.sar_tctrl2.tsens_reset = 1;// Reset the temp sensor.
SENS.sar_tctrl2.tsens_reset = 0;// Clear the reset status.
ESP_LOGI(TAG, "Config temperature range [%d°C ~ %d°C], error < %d°C",
dac_offset[tsens.dac_offset].range_min,
dac_offset[tsens.dac_offset].range_max,
dac_offset[tsens.dac_offset].error_max);
tsens_hw_state = TSENS_HW_STATE_CONFIGURED;
return err;
}
esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens)
{
ESP_RETURN_ON_FALSE(tsens != NULL, ESP_ERR_INVALID_ARG, TAG, "no tsens specified");
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M);
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_SAR_M);
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M);
tsens->dac_offset = REGI2C_READ_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC);
for (int i = TSENS_DAC_L0; i < TSENS_DAC_MAX; i++) {
if ((int)tsens->dac_offset == dac_offset[i].set_val) {
tsens->dac_offset = dac_offset[i].index;
break;
}
}
tsens->clk_div = SENS.sar_tctrl.tsens_clk_div;
return ESP_OK;
}
esp_err_t temp_sensor_start(void)
{
esp_err_t err = ESP_OK;
if (tsens_hw_state != TSENS_HW_STATE_CONFIGURED) {
ESP_LOGE(TAG, "Temperature sensor is already running or not be configured");
err = ESP_ERR_INVALID_STATE;
}
if (rtc_tsens_mux == NULL) {
rtc_tsens_mux = xSemaphoreCreateMutex();
}
ESP_RETURN_ON_FALSE(rtc_tsens_mux != NULL, ESP_ERR_NO_MEM, TAG, "failed to create mutex");
SENS.sar_tctrl.tsens_dump_out = 0;
SENS.sar_tctrl2.tsens_clkgate_en = 1;
SENS.sar_tctrl.tsens_power_up = 1;
tsens_hw_state = TSENS_HW_STATE_STARTED;
return err;
}
esp_err_t temp_sensor_stop(void)
{
SENS.sar_tctrl.tsens_power_up = 0;
SENS.sar_tctrl2.tsens_clkgate_en = 0;
if (rtc_tsens_mux != NULL) {
vSemaphoreDelete(rtc_tsens_mux);
rtc_tsens_mux = NULL;
}
return ESP_OK;
}
esp_err_t temp_sensor_read_raw(uint32_t *tsens_out)
{
ESP_RETURN_ON_FALSE(tsens_out != NULL, ESP_ERR_INVALID_ARG, TAG, "no tsens_out specified");
ESP_RETURN_ON_FALSE(rtc_tsens_mux != NULL, ESP_ERR_INVALID_STATE, TAG, "mutex not ready");
xSemaphoreTake(rtc_tsens_mux, portMAX_DELAY);
SENS.sar_tctrl.tsens_dump_out = 1;
while (!SENS.sar_tctrl.tsens_ready);
*tsens_out = SENS.sar_tctrl.tsens_out;
SENS.sar_tctrl.tsens_dump_out = 0;
xSemaphoreGive(rtc_tsens_mux);
return ESP_OK;
}
static void read_delta_t_from_efuse(void)
{
uint32_t version = esp_efuse_rtc_table_read_calib_version();
if (version == 1 || version == 2) {
// fetch calibration value for temp sensor from eFuse
s_deltaT = esp_efuse_rtc_table_get_parsed_efuse_value(RTCCALIB_IDX_TMPSENSOR, false) / 10.0;
} else {
// no value to fetch, use 0.
s_deltaT = 0;
}
ESP_LOGD(TAG, "s_deltaT = %f\n", s_deltaT);
}
static float parse_temp_sensor_raw_value(uint32_t tsens_raw, const int dac_offset)
{
if (isnan(s_deltaT)) { //suggests that the value is not initialized
read_delta_t_from_efuse();
}
float result = (TSENS_ADC_FACTOR * (float)tsens_raw - TSENS_DAC_FACTOR * dac_offset - TSENS_SYS_OFFSET) - s_deltaT;
return result;
}
esp_err_t temp_sensor_read_celsius(float *celsius)
{
ESP_RETURN_ON_FALSE(celsius != NULL, ESP_ERR_INVALID_ARG, TAG, "celsius points to nothing");
temp_sensor_config_t tsens;
uint32_t tsens_out = 0;
esp_err_t ret = temp_sensor_get_config(&tsens);
if (ret == ESP_OK) {
ret = temp_sensor_read_raw(&tsens_out);
ESP_RETURN_ON_FALSE(ret == ESP_OK, ret, TAG, "failed to read raw data");
const tsens_dac_offset_t *dac = &dac_offset[tsens.dac_offset];
*celsius = parse_temp_sensor_raw_value(tsens_out, dac->offset);
if (*celsius < dac->range_min || *celsius > dac->range_max) {
ESP_LOGW(TAG, "Exceeding the temperature range!");
ret = ESP_ERR_INVALID_STATE;
}
}
return ret;
}

View File

@@ -0,0 +1,92 @@
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#include "hal/temperature_sensor_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Type of temperature sensor driver handle
*/
typedef struct temperature_sensor_obj_t *temperature_sensor_handle_t;
/**
* @brief Configuration of measurement range for the temperature sensor.
*
* @note If you see the log `the boundary you gave cannot meet the range of internal temperature sensor`. You may need to refer to
* predefined range listed doc ``api-reference/peripherals/Temperature sensor``.
*/
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.
} temperature_sensor_config_t;
#define TEMPERAUTRE_SENSOR_CONFIG_DEFAULT(min, max) {.range_min = min, \
.range_max = max, \
}
/**
* @brief Install temperature sensor driver
*
* @param tsens_config Pointer to config structure.
* @param ret_tsens Return the pointer of temperature sensor handle.
* @return
* - ESP_OK if succeed
*/
esp_err_t temperature_sensor_install(const temperature_sensor_config_t *tsens_config, temperature_sensor_handle_t *ret_tsens);
/**
* @brief Uninstall the temperature sensor driver
*
* @param tsens The handle created by `temperature_sensor_install()`.
* @return
* - ESP_OK if succeed.
*/
esp_err_t temperature_sensor_uninstall(temperature_sensor_handle_t tsens);
/**
* @brief Start temperature measurement.
*
* @param tsens The handle created by `temperature_sensor_install()`.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE if temperature sensor is started already.
*/
esp_err_t temperature_sensor_start(temperature_sensor_handle_t tsens);
/**
* @brief Stop temperature sensor measure.
*
* @param tsens The handle created by `temperature_sensor_install()`.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE if temperature sensor is stopped already.
*/
esp_err_t temperature_sensor_stop(temperature_sensor_handle_t tsens);
/**
* @brief Read temperature sensor data that is converted to degrees Celsius.
* @note Should not be called from interrupt.
*
* @param tsens The handle created by `temperature_sensor_install()`.
* @param out_celsius The measure output value.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG ARG is NULL.
* - ESP_ERR_INVALID_STATE The ambient temperature is out of range.
*/
esp_err_t temperature_sensor_get_celsius(temperature_sensor_handle_t tsens, float *out_celsius);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,200 @@
/*
* SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#if CONFIG_TEMP_SENSOR_ENABLE_DEBUG_LOG
// The local log level must be defined before including esp_log.h
// Set the maximum log level for this source file
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#endif
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "esp_log.h"
#include "sys/lock.h"
#include "soc/rtc.h"
#include "esp_check.h"
#include "esp_types.h"
#include "esp_heap_caps.h"
#include "clk_ctrl_os.h"
#include "freertos/FreeRTOS.h"
#include "driver/temperature_sensor.h"
#include "esp_efuse_rtc_calib.h"
#include "esp_private/periph_ctrl.h"
#include "hal/temperature_sensor_types.h"
#include "hal/temperature_sensor_ll.h"
static const char *TAG = "temperature_sensor";
extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
#define TEMPERATURE_SENSOR_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
#define TEMPERATURE_SENSOR_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
typedef enum {
TSENS_HW_STATE_UNCONFIGURED,
TSENS_HW_STATE_CONFIGURED,
TSENS_HW_STATE_STARTED,
} temp_sensor_state_t;
static float s_deltaT = NAN; // unused number
typedef struct temperature_sensor_obj_t temperature_sensor_obj_t;
struct temperature_sensor_obj_t {
const temp_sensor_ll_attribute_t *tsens_attribute;
temp_sensor_state_t tsens_hw_state;
temperature_sensor_clk_src_t clk_src;
};
static temp_sensor_ll_attribute_t *s_tsens_attribute_copy;
static int inline accuracy_compare(const void *p1, const void *p2)
{
return ((*(temp_sensor_ll_attribute_t*)p1).error_max < (*(temp_sensor_ll_attribute_t*)p2).error_max) ? -1 : 1;
}
static esp_err_t temperature_sensor_attribute_table_sort(void)
{
s_tsens_attribute_copy = (temp_sensor_ll_attribute_t*)heap_caps_malloc(sizeof(temp_sensor_ll_attributes), MALLOC_CAP_DEFAULT);
ESP_RETURN_ON_FALSE(s_tsens_attribute_copy != NULL, ESP_ERR_NO_MEM, TAG, "No space for s_tsens_attribute_copy");
for (int i = 0 ; i < TEMPERATURE_SENSOR_LL_RANGE_NUM; i++) {
s_tsens_attribute_copy[i] = temp_sensor_ll_attributes[i];
}
// Sort from small to large by error_max.
qsort(s_tsens_attribute_copy, TEMPERATURE_SENSOR_LL_RANGE_NUM, sizeof(s_tsens_attribute_copy[0]), accuracy_compare);
return ESP_OK;
}
static esp_err_t temperature_sensor_choose_best_range(temperature_sensor_handle_t tsens, const temperature_sensor_config_t *tsens_config)
{
for (int i = 0 ; i < TEMPERATURE_SENSOR_LL_RANGE_NUM; i++) {
if ((tsens_config->range_min >= s_tsens_attribute_copy[i].range_min) && (tsens_config->range_max <= s_tsens_attribute_copy[i].range_max)) {
tsens->tsens_attribute = &s_tsens_attribute_copy[i];
break;
}
}
ESP_RETURN_ON_FALSE(tsens->tsens_attribute != NULL, ESP_ERR_INVALID_ARG, TAG, "Out of testing range");
return ESP_OK;
}
esp_err_t temperature_sensor_install(const temperature_sensor_config_t *tsens_config, temperature_sensor_handle_t *ret_tsens)
{
esp_err_t ret = ESP_OK;
#if CONFIG_TEMP_SENSOR_ENABLE_DEBUG_LOG
esp_log_level_set(TAG, ESP_LOG_DEBUG);
#endif
ESP_RETURN_ON_FALSE((tsens_config && ret_tsens), ESP_ERR_INVALID_ARG, TAG, "Invalid argument");
ESP_RETURN_ON_FALSE((s_tsens_attribute_copy == NULL), ESP_ERR_INVALID_STATE, TAG, "Already installed");
temperature_sensor_handle_t tsens;
tsens = (temperature_sensor_obj_t*) heap_caps_calloc(1, sizeof(temperature_sensor_obj_t), MALLOC_CAP_DEFAULT);
ESP_GOTO_ON_FALSE(tsens != NULL, ESP_ERR_NO_MEM, err, TAG, "install fail...");
tsens->clk_src = tsens_config->clk_src;
periph_module_enable(PERIPH_TEMPSENSOR_MODULE);
periph_module_reset(PERIPH_TEMPSENSOR_MODULE);
ESP_GOTO_ON_ERROR(temperature_sensor_attribute_table_sort(), err, TAG, "Table sort failed");
ESP_GOTO_ON_ERROR(temperature_sensor_choose_best_range(tsens, tsens_config), err, TAG, "Cannot select the correct range");
ESP_LOGI(TAG, "Range [%d°C ~ %d°C], error < %d°C",
tsens->tsens_attribute->range_min,
tsens->tsens_attribute->range_max,
tsens->tsens_attribute->error_max);
TEMPERATURE_SENSOR_ENTER_CRITICAL();
temperature_sensor_ll_set_range(tsens->tsens_attribute->reg_val);
TEMPERATURE_SENSOR_EXIT_CRITICAL();
tsens->tsens_hw_state = TSENS_HW_STATE_CONFIGURED;
*ret_tsens = tsens;
return ESP_OK;
err:
temperature_sensor_uninstall(tsens);
return ret;
}
esp_err_t temperature_sensor_uninstall(temperature_sensor_handle_t tsens)
{
ESP_RETURN_ON_FALSE((tsens != NULL), ESP_ERR_INVALID_ARG, TAG, "Has already been uninstalled");
ESP_RETURN_ON_FALSE(tsens->tsens_hw_state != TSENS_HW_STATE_STARTED, ESP_ERR_INVALID_STATE, TAG, "Has not been stopped");
if (s_tsens_attribute_copy) {
free(s_tsens_attribute_copy);
}
s_tsens_attribute_copy = NULL;
tsens->tsens_hw_state = TSENS_HW_STATE_UNCONFIGURED;
heap_caps_free(tsens);
tsens = NULL;
return ESP_OK;
}
esp_err_t temperature_sensor_start(temperature_sensor_handle_t tsens)
{
ESP_RETURN_ON_FALSE((tsens != NULL), ESP_ERR_INVALID_ARG, TAG, "Has not been installed");
ESP_RETURN_ON_FALSE(tsens->tsens_hw_state == TSENS_HW_STATE_CONFIGURED, ESP_ERR_INVALID_STATE, TAG, "Is already running or has not been configured");
#if SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC
if (tsens->clk_src == TEMPERATURE_SENSOR_CLK_SRC_FAST_RC) {
periph_rtc_dig_clk8m_enable();
}
#endif
temperature_sensor_ll_clk_enable(true);
temperature_sensor_ll_clk_sel(tsens->clk_src);
temperature_sensor_ll_enable(true);
tsens->tsens_hw_state = TSENS_HW_STATE_STARTED;
return ESP_OK;
}
esp_err_t temperature_sensor_stop(temperature_sensor_handle_t tsens)
{
ESP_RETURN_ON_FALSE(tsens->tsens_hw_state == TSENS_HW_STATE_STARTED, ESP_ERR_INVALID_STATE, TAG, "Has not been started");
temperature_sensor_ll_enable(false);
#if SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC
if (tsens->clk_src == TEMPERATURE_SENSOR_CLK_SRC_FAST_RC) {
periph_rtc_dig_clk8m_disable();
}
#endif
periph_module_disable(PERIPH_TEMPSENSOR_MODULE);
tsens->tsens_hw_state = TSENS_HW_STATE_CONFIGURED;
return ESP_OK;
}
static esp_err_t temp_sensor_read_raw(uint32_t *tsens_out)
{
ESP_RETURN_ON_FALSE(tsens_out != NULL, ESP_ERR_INVALID_ARG, TAG, "No tsens_out specified");
*tsens_out = temperature_sensor_ll_get_raw_value();
return ESP_OK;
}
static esp_err_t read_delta_t_from_efuse(void)
{
if (esp_efuse_rtc_calib_get_tsens_val(&s_deltaT) != ESP_OK) {
ESP_LOGW(TAG, "Calibration failed");
}
ESP_LOGD(TAG, "s_deltaT = %f", s_deltaT);
return ESP_OK;
}
static float parse_temp_sensor_raw_value(uint32_t tsens_raw, const int dac_offset)
{
if (isnan(s_deltaT)) { //suggests that the value is not initialized
read_delta_t_from_efuse();
}
float result = (TEMPERATURE_SENSOR_LL_ADC_FACTOR * (float)tsens_raw - TEMPERATURE_SENSOR_LL_DAC_FACTOR * dac_offset - TEMPERATURE_SENSOR_LL_OFFSET_FACTOR) - s_deltaT / 10.0;
return result;
}
esp_err_t temperature_sensor_get_celsius(temperature_sensor_handle_t tsens, float *out_celsius)
{
ESP_RETURN_ON_FALSE((tsens != NULL), ESP_ERR_INVALID_ARG, TAG, "Has not been installed");
ESP_RETURN_ON_FALSE(out_celsius != NULL, ESP_ERR_INVALID_ARG, TAG, "Celsius points to nothing");
ESP_RETURN_ON_FALSE(tsens->tsens_hw_state == TSENS_HW_STATE_STARTED, ESP_ERR_INVALID_ARG, TAG, "Has not been started");
uint32_t tsens_out = 0;
temp_sensor_read_raw(&tsens_out);
ESP_LOGV(TAG, "tsens_out %d", tsens_out);
*out_celsius = parse_temp_sensor_raw_value(tsens_out, tsens->tsens_attribute->offset);
if (*out_celsius < tsens->tsens_attribute->range_min || *out_celsius > tsens->tsens_attribute->range_max) {
ESP_LOGW(TAG, "Temperature range exceeded!");
return ESP_ERR_INVALID_STATE;
}
return ESP_OK;
}

View File

@@ -0,0 +1,5 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(test_app_include_temperature_sensor)

View File

@@ -0,0 +1,2 @@
| Supported Targets | ESP32-S2 | ESP32-S3 | ESP32-C3 |
| ----------------- | -------- | -------- | -------- |

View File

@@ -0,0 +1,7 @@
set(srcs "test_app_main.c"
"test_temperature_sensor.c")
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES driver unity)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u test_app_include_temperature_sensor")

View File

@@ -0,0 +1,40 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "unity.h"
#include "unity_test_runner.h"
#include "esp_heap_caps.h"
#define TEST_MEMORY_LEAK_THRESHOLD (-600)
static size_t before_free_8bit;
static size_t before_free_32bit;
static void check_leak(size_t before_free, size_t after_free, const char *type)
{
ssize_t delta = after_free - before_free;
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak");
}
void setUp(void)
{
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
}
void tearDown(void)
{
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
check_leak(before_free_8bit, after_free_8bit, "8BIT");
check_leak(before_free_32bit, after_free_32bit, "32BIT");
}
void app_main(void)
{
unity_run_menu();
}

View File

@@ -0,0 +1,81 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdlib.h>
#include "esp_log.h"
#include "unity.h"
#include "driver/temperature_sensor.h"
void test_app_include_temperature_sensor(void)
{
}
TEST_CASE("Temperature_sensor_driver_workflow_test", "[temperature_sensor]")
{
printf("Initializing Temperature sensor\n");
float tsens_out;
temperature_sensor_config_t temp_sensor = TEMPERAUTRE_SENSOR_CONFIG_DEFAULT(10, 50);
temperature_sensor_handle_t temp_handle = NULL;
TEST_ESP_OK(temperature_sensor_install(&temp_sensor, &temp_handle));
TEST_ESP_OK(temperature_sensor_start(temp_handle));
printf("Temperature sensor started\n");
TEST_ESP_OK(temperature_sensor_get_celsius(temp_handle, &tsens_out));
printf("Temperature out celsius %f°C\n", tsens_out);
TEST_ESP_OK(temperature_sensor_stop(temp_handle));
TEST_ESP_OK(temperature_sensor_uninstall(temp_handle));
// Reconfig the temperature sensor.
temp_sensor.range_min = -20;
temp_sensor.range_max = 45;
TEST_ESP_OK(temperature_sensor_install(&temp_sensor, &temp_handle));
TEST_ESP_OK(temperature_sensor_start(temp_handle));
printf("Temperature sensor started again\n");
TEST_ESP_OK(temperature_sensor_get_celsius(temp_handle, &tsens_out));
printf("Temperature out celsius %f°C\n", tsens_out);
TEST_ESP_OK(temperature_sensor_stop(temp_handle));
TEST_ESP_OK(temperature_sensor_uninstall(temp_handle));
}
TEST_CASE("Double install error cause test", "[temperature_sensor]")
{
printf("Initializing Temperature sensor\n");
temperature_sensor_config_t temp_sensor = TEMPERAUTRE_SENSOR_CONFIG_DEFAULT(10, 50);
temperature_sensor_handle_t temp_handle = NULL;
TEST_ESP_OK(temperature_sensor_install(&temp_sensor, &temp_handle));
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, temperature_sensor_install(&temp_sensor, &temp_handle));
TEST_ESP_OK(temperature_sensor_uninstall(temp_handle));
}
TEST_CASE("Double start error cause test", "[temperatere_sensor]")
{
printf("Initializing Temperature sensor\n");
temperature_sensor_config_t temp_sensor = TEMPERAUTRE_SENSOR_CONFIG_DEFAULT(10, 50);
temperature_sensor_handle_t temp_handle = NULL;
TEST_ESP_OK(temperature_sensor_install(&temp_sensor, &temp_handle));
TEST_ESP_OK(temperature_sensor_start(temp_handle));
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, temperature_sensor_start(temp_handle));
TEST_ESP_OK(temperature_sensor_stop(temp_handle));
TEST_ESP_OK(temperature_sensor_uninstall(temp_handle));
}
TEST_CASE("Double Start-Stop test", "[temperature_sensor]")
{
printf("Initializing Temperature sensor\n");
float tsens_out;
temperature_sensor_config_t temp_sensor = TEMPERAUTRE_SENSOR_CONFIG_DEFAULT(10, 50);
temperature_sensor_handle_t temp_handle = NULL;
TEST_ESP_OK(temperature_sensor_install(&temp_sensor, &temp_handle));
TEST_ESP_OK(temperature_sensor_start(temp_handle));
printf("Temperature sensor started\n");
TEST_ESP_OK(temperature_sensor_get_celsius(temp_handle, &tsens_out));
printf("Temperature out celsius %f°C\n", tsens_out);
TEST_ESP_OK(temperature_sensor_stop(temp_handle));
TEST_ESP_OK(temperature_sensor_start(temp_handle));
printf("Temperature sensor started again\n");
TEST_ESP_OK(temperature_sensor_get_celsius(temp_handle, &tsens_out));
printf("Temperature out celsius %f°C\n", tsens_out);
TEST_ESP_OK(temperature_sensor_stop(temp_handle));
TEST_ESP_OK(temperature_sensor_uninstall(temp_handle));
}

View File

@@ -0,0 +1,18 @@
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32s2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.generic
@pytest.mark.parametrize('config', [
'release',
], indirect=True)
def test_temperature_sensor_driver(dut: Dut) -> None:
dut.expect('Press ENTER to see the list of tests')
dut.write('*')
dut.expect_unity_test_output(timeout=120)

View File

@@ -0,0 +1,5 @@
CONFIG_PM_ENABLE=y
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y

View File

@@ -0,0 +1 @@
CONFIG_ESP_TASK_WDT=n

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -73,9 +73,13 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, int atten, uint32_t*
return ESP_OK; return ESP_OK;
} }
float esp_efuse_rtc_calib_get_cal_temp(int version) esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal)
{ {
assert(version == 1); uint32_t version = esp_efuse_rtc_calib_get_ver();
if (version != 1) {
*tsens_cal = 0.0;
return ESP_ERR_NOT_SUPPORTED;
}
const esp_efuse_desc_t** cal_temp_efuse; const esp_efuse_desc_t** cal_temp_efuse;
cal_temp_efuse = ESP_EFUSE_TEMP_CALIB; cal_temp_efuse = ESP_EFUSE_TEMP_CALIB;
int cal_temp_size = esp_efuse_get_field_size(cal_temp_efuse); int cal_temp_size = esp_efuse_get_field_size(cal_temp_efuse);
@@ -86,5 +90,6 @@ float esp_efuse_rtc_calib_get_cal_temp(int version)
assert(err == ESP_OK); assert(err == ESP_OK);
(void)err; (void)err;
// BIT(8) stands for sign: 1: negtive, 0: positive // BIT(8) stands for sign: 1: negtive, 0: positive
return ((cal_temp & BIT(8)) != 0)? -(uint8_t)cal_temp: (uint8_t)cal_temp; *tsens_cal = ((cal_temp & BIT(8)) != 0)? -(uint8_t)cal_temp: (uint8_t)cal_temp;
return ESP_OK;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -47,11 +47,12 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, int atten, uint32_t*
/** /**
* @brief Get the temperature sensor calibration number delta_T stored in the efuse. * @brief Get the temperature sensor calibration number delta_T stored in the efuse.
* *
* @param version Version of the stored efuse * @param tsens_cal Pointer of the specification of temperature sensor calibration number in efuse.
* *
* @return The specification of temperature sensor calibration number in efuse. * @return ESP_OK if get the calibration value successfully.
* ESP_ERR_INVALID_ARG if can't get the calibration value.
*/ */
float esp_efuse_rtc_calib_get_cal_temp(int version); esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -72,9 +72,13 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, int atten, uint32_t*
return ESP_OK; return ESP_OK;
} }
float esp_efuse_rtc_calib_get_cal_temp(int version) esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal)
{ {
assert(version == 1); uint32_t version = esp_efuse_rtc_calib_get_ver();
if (version != 1) {
*tsens_cal = 0.0;
return ESP_ERR_NOT_SUPPORTED;
}
const esp_efuse_desc_t** cal_temp_efuse; const esp_efuse_desc_t** cal_temp_efuse;
cal_temp_efuse = ESP_EFUSE_TEMP_CALIB; cal_temp_efuse = ESP_EFUSE_TEMP_CALIB;
int cal_temp_size = esp_efuse_get_field_size(cal_temp_efuse); int cal_temp_size = esp_efuse_get_field_size(cal_temp_efuse);
@@ -85,5 +89,6 @@ float esp_efuse_rtc_calib_get_cal_temp(int version)
assert(err == ESP_OK); assert(err == ESP_OK);
(void)err; (void)err;
// BIT(8) stands for sign: 1: negtive, 0: positive // BIT(8) stands for sign: 1: negtive, 0: positive
return ((cal_temp & BIT(8)) != 0)? -(uint8_t)cal_temp: (uint8_t)cal_temp; *tsens_cal = ((cal_temp & BIT(8)) != 0)? -(uint8_t)cal_temp: (uint8_t)cal_temp;
return ESP_OK;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -43,11 +43,12 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, int atten, uint32_t*
/** /**
* @brief Get the temperature sensor calibration number delta_T stored in the efuse. * @brief Get the temperature sensor calibration number delta_T stored in the efuse.
* *
* @param version Version of the stored efuse * @param tsens_cal Pointer of the specification of temperature sensor calibration number in efuse.
* *
* @return The specification of temperature sensor calibration number in efuse. * @return ESP_OK if get the calibration value successfully.
* ESP_ERR_INVALID_ARG if can't get the calibration value.
*/ */
float esp_efuse_rtc_calib_get_cal_temp(int version); esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "esp_bit_defs.h"
#include "esp_efuse.h"
#include "esp_efuse_rtc_table.h"
esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal)
{
uint32_t version = esp_efuse_rtc_table_read_calib_version();
if ((version != 1) && (version != 2)) {
*tsens_cal = 0.0;
return ESP_ERR_NOT_SUPPORTED;
}
*tsens_cal = esp_efuse_rtc_table_get_parsed_efuse_value(RTCCALIB_IDX_TMPSENSOR, false);
return ESP_OK;
}

View File

@@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_types.h"
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get the temperature sensor calibration number delta_T stored in the efuse.
*
* @param tsens_cal Pointer of the specification of temperature sensor calibration number in efuse.
*
* @return ESP_OK if get the calibration value successfully.
* ESP_ERR_INVALID_ARG if can't get the calibration value.
*/
esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal);
#ifdef __cplusplus
}
#endif

View File

@@ -1,4 +1,5 @@
set(EFUSE_SOC_SRCS "esp_efuse_table.c" set(EFUSE_SOC_SRCS "esp_efuse_table.c"
"esp_efuse_fields.c" "esp_efuse_fields.c"
"esp_efuse_rtc_table.c" "esp_efuse_rtc_table.c"
"esp_efuse_rtc_calib.c"
"esp_efuse_utility.c") "esp_efuse_utility.c")

View File

@@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@@ -80,6 +72,8 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
return SYSTEM_BT_BASEBAND_EN; return SYSTEM_BT_BASEBAND_EN;
case PERIPH_BT_LC_MODULE: case PERIPH_BT_LC_MODULE:
return SYSTEM_BT_LC_EN; return SYSTEM_BT_LC_EN;
case PERIPH_TEMPSENSOR_MODULE:
return SYSTEM_TSENS_CLK_EN;
default: default:
return 0; return 0;
} }
@@ -123,6 +117,8 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en
return SYSTEM_TWAI_RST; return SYSTEM_TWAI_RST;
case PERIPH_HMAC_MODULE: case PERIPH_HMAC_MODULE:
return SYSTEM_CRYPTO_HMAC_RST; return SYSTEM_CRYPTO_HMAC_RST;
case PERIPH_TEMPSENSOR_MODULE:
return SYSTEM_TSENS_RST;
case PERIPH_AES_MODULE: case PERIPH_AES_MODULE:
if (enable == true) { if (enable == true) {
// Clear reset on digital signature, otherwise AES unit is held in reset also. // Clear reset on digital signature, otherwise AES unit is held in reset also.
@@ -171,6 +167,7 @@ static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
case PERIPH_RSA_MODULE: case PERIPH_RSA_MODULE:
case PERIPH_SHA_MODULE: case PERIPH_SHA_MODULE:
case PERIPH_GDMA_MODULE: case PERIPH_GDMA_MODULE:
case PERIPH_TEMPSENSOR_MODULE:
return SYSTEM_PERIP_CLK_EN1_REG; return SYSTEM_PERIP_CLK_EN1_REG;
default: default:
return SYSTEM_PERIP_CLK_EN0_REG; return SYSTEM_PERIP_CLK_EN0_REG;
@@ -194,6 +191,7 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
case PERIPH_RSA_MODULE: case PERIPH_RSA_MODULE:
case PERIPH_SHA_MODULE: case PERIPH_SHA_MODULE:
case PERIPH_GDMA_MODULE: case PERIPH_GDMA_MODULE:
case PERIPH_TEMPSENSOR_MODULE:
return SYSTEM_PERIP_RST_EN1_REG; return SYSTEM_PERIP_RST_EN1_REG;
default: default:
return SYSTEM_PERIP_RST_EN0_REG; return SYSTEM_PERIP_RST_EN0_REG;

View File

@@ -0,0 +1,154 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in component/hal/readme.md
******************************************************************************/
// The LL for temperature sensor
#pragma once
#include <stdbool.h>
#include <stdlib.h>
#include "regi2c_ctrl.h"
#include "soc/apb_saradc_struct.h"
#include "soc/soc.h"
#include "soc/soc_caps.h"
#include "hal/temperature_sensor_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TEMPERATURE_SENSOR_LL_ADC_FACTOR (0.4386)
#define TEMPERATURE_SENSOR_LL_DAC_FACTOR (27.88)
#define TEMPERATURE_SENSOR_LL_OFFSET_FACTOR (20.52)
#define TEMPERATURE_SENSOR_LL_RANGE_NUM (5)
typedef struct {
int offset;
int reg_val;
int range_min;
int range_max;
int error_max;
} temp_sensor_ll_attribute_t;
static const temp_sensor_ll_attribute_t temp_sensor_ll_attributes[TEMPERATURE_SENSOR_LL_RANGE_NUM] = {
/*Offset, reg_val, min, max, error */
{ -2, 5, 50, 125, 3},
{ -1, 7, 20, 100, 2},
{ 0, 15, -10, 80, 1},
{ 1, 11, -30, 50, 2},
{ 2, 10, -40, 20, 3},
};
/**
* @brief Enable the temperature sensor power.
*
* @param enable true: enable the power.
*/
static inline void temperature_sensor_ll_enable(bool enable)
{
APB_SARADC.apb_tsens_ctrl.tsens_pu = enable;
}
/**
* @brief Enable the clock
*/
static inline void temperature_sensor_ll_clk_enable(bool enable)
{
// No need to enable the temperature clock on esp32c3
}
/**
* @brief Select the clock source for temperature sensor. On ESP32-C3, temperautre sensor
* can use XTAL or FOSC. To make it convenience, suggest using XTAL all the time.
*
* @param clk_src refer to ``temperature_sensor_clk_src_t``
*/
static inline void temperature_sensor_ll_clk_sel(temperature_sensor_clk_src_t clk_src)
{
uint8_t clk_sel = 0;
switch (clk_src) {
case TEMPERATURE_SENSOR_CLK_SRC_DEFAULT:
case TEMPERATURE_SENSOR_CLK_SRC_XTAL:
clk_sel = 1;
break;
case TEMPERATURE_SENSOR_CLK_SRC_FAST_RC:
clk_sel = 0;
break;
default:
abort();
break;
}
APB_SARADC.apb_tsens_ctrl2.tsens_clk_sel = clk_sel;
}
/**
* @brief Set the hardware range, you can refer to the table ``temp_sensor_ll_attributes``
*
* @param tsens_dac ``reg_val`` in table ``temp_sensor_ll_attributes``
*/
static inline void temperature_sensor_ll_set_range(uint32_t range)
{
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PD);
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PU);
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC, range);
}
/**
* @brief Get the raw value of temperature sensor.
*
* @return uint32_t raw_value
*/
static inline uint32_t temperature_sensor_ll_get_raw_value(void)
{
return APB_SARADC.apb_tsens_ctrl.tsens_out;
}
/**
* @brief Get the offset value of temperature sensor.
*
* @note This function is only used in legacy driver
*
* @return uint32_t offset value
*/
static inline uint32_t temperature_sensor_ll_get_offset(void)
{
return REGI2C_READ_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC);
}
/**
* @brief Get the clock division factor value.
*
* @note This function is only used in legacy driver
*
* @return uint32_t clock division factor
*/
static inline uint32_t temperature_sensor_ll_get_clk_div(void)
{
return APB_SARADC.apb_tsens_ctrl.tsens_clk_div;
}
/**
* @brief Set the clock division factor value, actually this has no impact on temperature sensor.
* Suggest just keep it as default value 6.
*
* @note This function is only used in legacy driver
*
* @param clk_div clock division factor, range from 1-10
*/
static inline void temperature_sensor_ll_set_clk_div(uint8_t clk_div)
{
APB_SARADC.apb_tsens_ctrl.tsens_clk_div = clk_div;
}
#ifdef __cplusplus
}
#endif

View File

@@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@@ -68,6 +60,8 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
return SYSTEM_CRYPTO_HMAC_CLK_EN; return SYSTEM_CRYPTO_HMAC_CLK_EN;
case PERIPH_DS_MODULE: case PERIPH_DS_MODULE:
return SYSTEM_CRYPTO_DS_CLK_EN; return SYSTEM_CRYPTO_DS_CLK_EN;
case PERIPH_TEMPSENSOR_MODULE:
return SYSTEM_TSENS_CLK_EN;
default: default:
return 0; return 0;
} }
@@ -111,6 +105,8 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en
return SYSTEM_TWAI_RST; return SYSTEM_TWAI_RST;
case PERIPH_HMAC_MODULE: case PERIPH_HMAC_MODULE:
return SYSTEM_CRYPTO_HMAC_RST; return SYSTEM_CRYPTO_HMAC_RST;
case PERIPH_TEMPSENSOR_MODULE:
return SYSTEM_TSENS_RST;
case PERIPH_AES_MODULE: case PERIPH_AES_MODULE:
if (enable == true) { if (enable == true) {
// Clear reset on digital signature, otherwise AES unit is held in reset also. // Clear reset on digital signature, otherwise AES unit is held in reset also.
@@ -151,6 +147,7 @@ static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
case PERIPH_RSA_MODULE: case PERIPH_RSA_MODULE:
case PERIPH_SHA_MODULE: case PERIPH_SHA_MODULE:
case PERIPH_GDMA_MODULE: case PERIPH_GDMA_MODULE:
case PERIPH_TEMPSENSOR_MODULE:
return SYSTEM_PERIP_CLK_EN1_REG; return SYSTEM_PERIP_CLK_EN1_REG;
default: default:
return SYSTEM_PERIP_CLK_EN0_REG; return SYSTEM_PERIP_CLK_EN0_REG;
@@ -166,6 +163,7 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
case PERIPH_RSA_MODULE: case PERIPH_RSA_MODULE:
case PERIPH_SHA_MODULE: case PERIPH_SHA_MODULE:
case PERIPH_GDMA_MODULE: case PERIPH_GDMA_MODULE:
case PERIPH_TEMPSENSOR_MODULE:
return SYSTEM_PERIP_RST_EN1_REG; return SYSTEM_PERIP_RST_EN1_REG;
default: default:
return SYSTEM_PERIP_RST_EN0_REG; return SYSTEM_PERIP_RST_EN0_REG;

View File

@@ -0,0 +1,155 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in component/hal/readme.md
******************************************************************************/
// The LL for temperature sensor
#pragma once
#include <stdbool.h>
#include <stdlib.h>
#include "regi2c_ctrl.h"
#include "soc/apb_saradc_struct.h"
#include "soc/soc.h"
#include "soc/soc_caps.h"
#include "hal/temperature_sensor_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TEMPERATURE_SENSOR_LL_ADC_FACTOR (0.4386)
#define TEMPERATURE_SENSOR_LL_DAC_FACTOR (27.88)
#define TEMPERATURE_SENSOR_LL_OFFSET_FACTOR (20.52)
#define TEMPERATURE_SENSOR_LL_RANGE_NUM (5)
typedef struct {
int offset;
int reg_val;
int range_min;
int range_max;
int error_max;
} temp_sensor_ll_attribute_t;
static const temp_sensor_ll_attribute_t temp_sensor_ll_attributes[TEMPERATURE_SENSOR_LL_RANGE_NUM] = {
/*Offset, reg_val, min, max, error */
{ -2, 5, 50, 125, 3},
{ -1, 7, 20, 100, 2},
{ 0, 15, -10, 80, 1},
{ 1, 11, -30, 50, 2},
{ 2, 10, -40, 20, 3},
};
/**
* @brief Enable the temperature sensor power.
*
* @param enable true: enable the power.
*/
static inline void temperature_sensor_ll_enable(bool enable)
{
APB_SARADC.apb_tsens_ctrl.tsens_pu = enable;
}
/**
* @brief Enable the clock
*/
static inline void temperature_sensor_ll_clk_enable(bool enable)
{
// No need to enable the temperature clock on esp32h2
}
/**
* @brief Select the clock source for temperature sensor. On ESP32-H2, temperature sensor
* can use XTAL or FOSC. To make it convenience, suggest using XTAL all the time.
*
* @param clk_src refer to ``temperature_sensor_clk_src_t``
*/
static inline void temperature_sensor_ll_clk_sel(temperature_sensor_clk_src_t clk_src)
{
uint8_t clk_sel = 0;
switch (clk_src) {
case TEMPERATURE_SENSOR_CLK_SRC_DEFAULT:
case TEMPERATURE_SENSOR_CLK_SRC_XTAL:
clk_sel = 1;
break;
case TEMPERATURE_SENSOR_CLK_SRC_FAST_RC:
clk_sel = 0;
break;
default:
abort();
break;
}
APB_SARADC.apb_tsens_ctrl2.tsens_clk_sel = clk_sel;
}
/**
* @brief Set the hardware range, you can refer to the table ``temp_sensor_ll_attributes``
*
* @param tsens_dac ``reg_val`` in table ``temp_sensor_ll_attributes``
*/
static inline void temperature_sensor_ll_set_range(uint32_t range)
{
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_SAR_FORCE_PD);
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_I2C_SAR_FORCE_PU);
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC, range);
}
/**
* @brief Get the raw value of temperature sensor.
*
* @return uint32_t raw_value
*/
static inline uint32_t temperature_sensor_ll_get_raw_value(void)
{
return APB_SARADC.apb_tsens_ctrl.tsens_out;
}
/**
* @brief Get the offset value of temperature sensor.
*
* @note This function is only used in legacy driver
*
* @return uint32_t offset value
*/
static inline uint32_t temperature_sensor_ll_get_offset(void)
{
return REGI2C_READ_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC);
}
/**
* @brief Get the clock division factor value.
*
* @note This function is only used in legacy driver
*
* @return uint32_t clock division factor
*/
static inline uint32_t temperature_sensor_ll_get_clk_div(void)
{
return APB_SARADC.apb_tsens_ctrl.tsens_clk_div;
}
/**
* @brief Set the clock division factor value, actually this has no impact on temperature sensor.
* Suggest just keep it as default value 6.
*
* @note This function is only used in legacy driver
*
* @param clk_div clock division factor, range from 1-10
*/
static inline void temperature_sensor_ll_set_clk_div(uint8_t clk_div)
{
APB_SARADC.apb_tsens_ctrl.tsens_clk_div = clk_div;
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,147 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in component/hal/readme.md
******************************************************************************/
// The LL for temperature sensor
#pragma once
#include <stdbool.h>
#include "regi2c_ctrl.h"
#include "soc/apb_saradc_struct.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/sens_struct.h"
#include "hal/temperature_sensor_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TEMPERATURE_SENSOR_LL_ADC_FACTOR (0.4386)
#define TEMPERATURE_SENSOR_LL_DAC_FACTOR (27.88)
#define TEMPERATURE_SENSOR_LL_OFFSET_FACTOR (20.52)
#define TEMPERATURE_SENSOR_LL_RANGE_NUM (5)
typedef struct {
int offset;
int reg_val;
int range_min;
int range_max;
int error_max;
} temp_sensor_ll_attribute_t;
static const temp_sensor_ll_attribute_t temp_sensor_ll_attributes[TEMPERATURE_SENSOR_LL_RANGE_NUM] = {
/*Offset, reg_val, min, max, error */
{ -2, 5, 50, 125, 3},
{ -1, 7, 20, 100, 2},
{ 0, 15, -10, 80, 1},
{ 1, 11, -30, 50, 2},
{ 2, 10, -40, 20, 3},
};
/**
* @brief Enable the temperature sensor power.
*
* @param enable true: enable the power.
*/
static inline void temperature_sensor_ll_enable(bool enable)
{
SENS.sar_tctrl.tsens_power_up_force = enable;
SENS.sar_tctrl2.tsens_xpd_force = enable;
SENS.sar_tctrl.tsens_power_up = enable;
}
/**
* @brief Enable the clock
*/
static inline void temperature_sensor_ll_clk_enable(bool enable)
{
SENS.sar_tctrl2.tsens_clkgate_en = enable;
}
/**
* @brief Choose the clock. No need to choose the clock source on ESP32-S2. ESP32-S2
* can use RTC clock.
*/
static inline void temperature_sensor_ll_clk_sel(temperature_sensor_clk_src_t clk_src)
{
// No need to select the temperature sensor clock on esp32s2.
}
/**
* @brief Set the hardware range, you can refer to the table ``temp_sensor_ll_attributes``
*
* @param tsens_dac ``reg_val`` in table ``temp_sensor_ll_attributes``
*/
static inline void temperature_sensor_ll_set_range(uint32_t tsens_dac)
{
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M);
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_SAR_M);
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M);
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC, tsens_dac);
}
/**
* @brief Get the raw value of temperature sensor.
*
* @return uint32_t raw_value
*/
static inline uint32_t temperature_sensor_ll_get_raw_value(void)
{
SENS.sar_tctrl.tsens_dump_out = 1;
while (!SENS.sar_tctrl.tsens_ready) {
}
SENS.sar_tctrl.tsens_dump_out = 0;
return SENS.sar_tctrl.tsens_out;
}
/**
* @brief Get the offset value of temperature sensor.
*
* @note This function is only used in legacy driver
*
* @return uint32_t offset value
*/
static inline uint32_t temperature_sensor_ll_get_offset(void)
{
return REGI2C_READ_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC);
}
/**
* @brief Get the clock division factor value.
*
* @note This function is only used in legacy driver
*
* @return uint32_t clock division factor
*/
static inline uint32_t temperature_sensor_ll_get_clk_div(void)
{
return SENS.sar_tctrl.tsens_clk_div;
}
/**
* @brief Set the clock division factor value, actually this has no impact on temperature sensor.
* Suggest just keep it as default value 6.
*
* @note This function is only used in legacy driver
*
* @param clk_div clock division factor, range from 1-10
*/
static inline void temperature_sensor_ll_set_clk_div(uint8_t clk_div)
{
SENS.sar_tctrl.tsens_clk_div = clk_div;
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,38 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief temperature sensor clock source
* @note User should select the clock source based on the real requirement:
* @verbatim embed:rst:leading-asterisk
* +------------------------------------+-------------------------+----------------------------+
* | temperature sensor clock source | Features | Power Management |
* +====================================+=========================+============================+
* | TEMPERATURE_SENSOR_CLK_SRC_XTAL | external clock source | no lock |
* +------------------------------------+-------------------------+----------------------------+
* | TEMPERATURE_SENSOR_CLK_SRC_FAST_RC | On board clock source | no lock |
* +------------------------------------+-------------------------+----------------------------+
* @endverbatim
*/
typedef enum {
TEMPERATURE_SENSOR_CLK_SRC_DEFAULT = 0,
#if SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL
TEMPERATURE_SENSOR_CLK_SRC_XTAL = 1, /*!< Select XTAL as the source clock */
#endif
#if SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC
TEMPERATURE_SENSOR_CLK_SRC_FAST_RC = 2, /*!< Select FOSC as the source clock */
#endif
} temperature_sensor_clk_src_t;
#ifdef __cplusplus
}
#endif

View File

@@ -646,3 +646,11 @@ config SOC_PM_SUPPORT_WIFI_PD
config SOC_PM_SUPPORT_BT_PD config SOC_PM_SUPPORT_BT_PD
bool bool
default y default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC
bool
default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL
bool
default y

View File

@@ -38,6 +38,7 @@ typedef enum {
PERIPH_GDMA_MODULE, PERIPH_GDMA_MODULE,
PERIPH_SYSTIMER_MODULE, PERIPH_SYSTIMER_MODULE,
PERIPH_SARADC_MODULE, PERIPH_SARADC_MODULE,
PERIPH_TEMPSENSOR_MODULE,
PERIPH_MODULE_MAX PERIPH_MODULE_MAX
} periph_module_t; } periph_module_t;

View File

@@ -320,3 +320,7 @@
#define SOC_PM_SUPPORT_WIFI_PD (1) #define SOC_PM_SUPPORT_WIFI_PD (1)
#define SOC_PM_SUPPORT_BT_PD (1) #define SOC_PM_SUPPORT_BT_PD (1)
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/
#define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1)
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)

View File

@@ -606,3 +606,11 @@ config SOC_PM_SUPPORT_CPU_PD
config SOC_PM_SUPPORT_BT_PD config SOC_PM_SUPPORT_BT_PD
bool bool
default y default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC
bool
default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL
bool
default y

View File

@@ -38,6 +38,7 @@ typedef enum {
PERIPH_GDMA_MODULE, PERIPH_GDMA_MODULE,
PERIPH_SYSTIMER_MODULE, PERIPH_SYSTIMER_MODULE,
PERIPH_SARADC_MODULE, PERIPH_SARADC_MODULE,
PERIPH_TEMPSENSOR_MODULE,
PERIPH_MODULE_MAX PERIPH_MODULE_MAX
} periph_module_t; } periph_module_t;

View File

@@ -303,3 +303,7 @@
#define SOC_PM_SUPPORT_CPU_PD (1) #define SOC_PM_SUPPORT_CPU_PD (1)
#define SOC_PM_SUPPORT_BT_PD (1) #define SOC_PM_SUPPORT_BT_PD (1)
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/
#define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1)
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)

View File

@@ -730,3 +730,7 @@ config SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP
config SOC_COEX_HW_PTI config SOC_COEX_HW_PTI
bool bool
default y default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC
bool
default y

View File

@@ -42,6 +42,7 @@ typedef enum {
PERIPH_SHA_DMA_MODULE, PERIPH_SHA_DMA_MODULE,
PERIPH_DEDIC_GPIO_MODULE, PERIPH_DEDIC_GPIO_MODULE,
PERIPH_SARADC_MODULE, PERIPH_SARADC_MODULE,
PERIPH_TEMPSENSOR_MODULE,
PERIPH_MODULE_MAX PERIPH_MODULE_MAX
} periph_module_t; } periph_module_t;

View File

@@ -359,3 +359,6 @@
#define SOC_COEX_HW_PTI (1) #define SOC_COEX_HW_PTI (1)
/* ---------------------------- Compatibility ------------------------------- */ /* ---------------------------- Compatibility ------------------------------- */
// No contents // No contents
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/
#define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1)

View File

@@ -1,9 +1,9 @@
| Supported Targets | ESP32-S2 | ESP32-C3 | | Supported Targets | ESP32-S2 | ESP32-C3 | ESP32-S3 |
| ----------------- | -------- | -------- | | ----------------- | -------- | -------- | -------- |
# Temperature Sensor Example # Temperature Sensor Example
The ESP32-S2 and ESP32-C3 has a built-in temperature sensor. The temperature sensor module contains an 8-bit Sigma-Delta ADC and a temperature offset DAC. The ESP32-S2/C3/S3 has a built-in temperature sensor. The temperature sensor module contains an 8-bit Sigma-Delta ADC and a temperature offset DAC.
The conversion relationship is the first two columns of the table below. Among them, `offset = 0`(default) is the main measurement option, and other values are extended measurement options. The conversion relationship is the first two columns of the table below. Among them, `offset = 0`(default) is the main measurement option, and other values are extended measurement options.
@@ -21,7 +21,7 @@ Before project configuration and build, be sure to set the correct chip target u
### Hardware Required ### Hardware Required
* A development board with ESP32-S2 or ESP32-C3 SoC (e.g., ESP32-S2-Saola-1, ESP32-S2-DevKitM-1, ESP32-C3-DevKitM-1, etc.) * A development board with ESP32-S2/C3/S3 SoC (e.g., ESP32-S2-Saola-1, ESP32-S2-DevKitM-1, ESP32-C3-DevKitM-1, ESP32-S3-WROOM-1, etc.)
* A USB cable for power supply and programming * A USB cable for power supply and programming
### Build and Flash ### Build and Flash
@@ -37,15 +37,19 @@ See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/l
## Example Output ## Example Output
``` ```
I (243) TempSensor: Initializing Temperature sensor I (276) example: Initializing Temperature sensor
I (243) TempSensor: default dac 2, clk_div 6 I (276) temperature_sensor: temperature range [-10°C ~ 80°C], error < 1°C
I (243) TempSensor: Config temperature range [-10°C ~ 80°C], error < 1°C I (286) example: Temperature sensor started
I (253) TempSensor: Temperature sensor started I (1286) example: Temperature out celsius 21.64
I (1253) TempSensor: Temperature out celsius 27.287399°C I (2286) example: Temperature out celsius 21.64
I (2253) TempSensor: Temperature out celsius 26.848801°C I (3286) example: Temperature out celsius 21.64
I (3253) TempSensor: Temperature out celsius 26.848801°C I (4286) example: Temperature out celsius 22.08
I (4253) TempSensor: Temperature out celsius 27.287399°C I (5286) example: Temperature out celsius 22.08
I (5253) TempSensor: Temperature out celsius 27.287399°C I (6286) example: Temperature out celsius 22.08
I (7286) example: Temperature out celsius 22.08
I (8286) example: Temperature out celsius 22.08
I (9286) example: Temperature out celsius 22.08
``` ```
## Troubleshooting ## Troubleshooting

View File

@@ -1,54 +1,37 @@
/* Temperature Sensor Example /*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
This example code is in the Public Domain (or CC0 licensed, at your option.) *
* SPDX-License-Identifier: Apache-2.0
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#include <stdio.h>
#include <stdlib.h>
#include "esp_log.h" #include "esp_log.h"
#include "esp_check.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "driver/temperature_sensor.h"
/* Note: ESP32 don't support temperature sensor */ static const char *TAG = "example";
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 void tempsensor_example(void)
#include "driver/temp_sensor.h"
static const char *TAG = "TempSensor";
void tempsensor_example(void *arg)
{ {
// Initialize touch pad peripheral, it will start a timer to run a filter // Initialize touch pad peripheral, it will start a timer to run a filter
ESP_LOGI(TAG, "Initializing Temperature sensor"); ESP_LOGI(TAG, "Initializing Temperature sensor");
float tsens_out; float tsens_out;
temp_sensor_config_t temp_sensor = TSENS_CONFIG_DEFAULT(); temperature_sensor_config_t temp_sensor = TEMPERAUTRE_SENSOR_CONFIG_DEFAULT(10, 50);
temp_sensor_get_config(&temp_sensor); temperature_sensor_handle_t temp_handle = NULL;
ESP_LOGI(TAG, "default dac %d, clk_div %d", temp_sensor.dac_offset, temp_sensor.clk_div); ESP_ERROR_CHECK(temperature_sensor_install(&temp_sensor, &temp_handle));
temp_sensor.dac_offset = TSENS_DAC_DEFAULT; // DEFAULT: range:-10℃ ~ 80℃, error < 1℃. ESP_ERROR_CHECK(temperature_sensor_start(temp_handle));
temp_sensor_set_config(temp_sensor);
temp_sensor_start();
ESP_LOGI(TAG, "Temperature sensor started"); ESP_LOGI(TAG, "Temperature sensor started");
while (1) { int cnt = 20; //read value for 20 times
while (cnt) {
vTaskDelay(1000 / portTICK_PERIOD_MS); vTaskDelay(1000 / portTICK_PERIOD_MS);
temp_sensor_read_celsius(&tsens_out); ESP_ERROR_CHECK(temperature_sensor_get_celsius(temp_handle, &tsens_out));
ESP_LOGI(TAG, "Temperature out celsius %f°C", tsens_out); ESP_LOGI(TAG, "Temperature out celsius %.02f", tsens_out);
cnt--;
} }
vTaskDelete(NULL);
} }
void app_main(void) void app_main(void)
{ {
xTaskCreate(tempsensor_example, "temp", 2048, NULL, 5, NULL); tempsensor_example();
} }
#elif CONFIG_IDF_TARGET_ESP32
void app_main(void)
{
printf("ESP32 don't support temperature sensor\n");
}
#endif

View File

@@ -0,0 +1,17 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded.dut import Dut
@pytest.mark.esp32s2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.generic
def test_temp_sensor_example(dut: Dut) -> None:
dut.expect_exact('Initializing Temperature sensor')
dut.expect_exact('Temperature sensor started')
temp_value = dut.expect(r'Temperature out celsius (\d+\.\d+)', timeout=30)
# Because the example test only run in the normal temperature environment. So this assert range is meaningful
assert 0 < float(temp_value.group(1)) < 45

View File

@@ -838,7 +838,6 @@ components/hal/esp32c3/brownout_hal.c
components/hal/esp32c3/hmac_hal.c components/hal/esp32c3/hmac_hal.c
components/hal/esp32c3/include/hal/adc_hal_conf.h components/hal/esp32c3/include/hal/adc_hal_conf.h
components/hal/esp32c3/include/hal/aes_ll.h components/hal/esp32c3/include/hal/aes_ll.h
components/hal/esp32c3/include/hal/clk_gate_ll.h
components/hal/esp32c3/include/hal/ds_ll.h components/hal/esp32c3/include/hal/ds_ll.h
components/hal/esp32c3/include/hal/gpspi_flash_ll.h components/hal/esp32c3/include/hal/gpspi_flash_ll.h
components/hal/esp32c3/include/hal/hmac_hal.h components/hal/esp32c3/include/hal/hmac_hal.h
@@ -862,7 +861,6 @@ components/hal/esp32h2/brownout_hal.c
components/hal/esp32h2/hmac_hal.c components/hal/esp32h2/hmac_hal.c
components/hal/esp32h2/include/hal/adc_hal_conf.h components/hal/esp32h2/include/hal/adc_hal_conf.h
components/hal/esp32h2/include/hal/aes_ll.h components/hal/esp32h2/include/hal/aes_ll.h
components/hal/esp32h2/include/hal/clk_gate_ll.h
components/hal/esp32h2/include/hal/ds_ll.h components/hal/esp32h2/include/hal/ds_ll.h
components/hal/esp32h2/include/hal/gpspi_flash_ll.h components/hal/esp32h2/include/hal/gpspi_flash_ll.h
components/hal/esp32h2/include/hal/hmac_hal.h components/hal/esp32h2/include/hal/hmac_hal.h
@@ -2236,7 +2234,6 @@ examples/peripherals/spi_slave_hd/append_mode/master/main/app_main.c
examples/peripherals/spi_slave_hd/append_mode/slave/main/app_main.c examples/peripherals/spi_slave_hd/append_mode/slave/main/app_main.c
examples/peripherals/spi_slave_hd/segment_mode/seg_master/main/app_main.c examples/peripherals/spi_slave_hd/segment_mode/seg_master/main/app_main.c
examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c
examples/peripherals/temp_sensor/main/temp_sensor_main.c
examples/peripherals/touch_element/touch_button/main/touch_button_example_main.c examples/peripherals/touch_element/touch_button/main/touch_button_example_main.c
examples/peripherals/touch_element/touch_element_waterproof/main/waterproof_example_main.c examples/peripherals/touch_element/touch_element_waterproof/main/waterproof_example_main.c
examples/peripherals/touch_element/touch_elements_combination/main/touch_elements_example_main.c examples/peripherals/touch_element/touch_elements_combination/main/touch_elements_example_main.c