mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
temperature_sensor: Implement temperature monitor interrupt feature on ESP32H2/ESP32C6
This commit is contained in:
parent
2f6a362be9
commit
840ff4f865
@ -208,6 +208,14 @@ menu "Driver Configurations"
|
||||
Wether to enable the debug log message for temperature sensor driver.
|
||||
Note that, this option only controls the temperature sensor driver log, won't affect other drivers.
|
||||
|
||||
config TEMP_SENSOR_ISR_IRAM_SAFE
|
||||
depends on SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
bool "Temperature sensor ISR IRAM-Safe"
|
||||
default n
|
||||
help
|
||||
Ensure the Temperature Sensor interrupt is IRAM-Safe by allowing the interrupt handler to be
|
||||
executable when the cache is disabled (e.g. SPI Flash write).
|
||||
|
||||
endmenu # TEMP_SENSOR Configuration
|
||||
|
||||
menu "UART Configuration"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "hal/temperature_sensor_types.h"
|
||||
|
||||
@ -94,6 +95,92 @@ esp_err_t temperature_sensor_disable(temperature_sensor_handle_t tsens);
|
||||
*/
|
||||
esp_err_t temperature_sensor_get_celsius(temperature_sensor_handle_t tsens, float *out_celsius);
|
||||
|
||||
#if SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
|
||||
/**
|
||||
* @brief Temperature sensor event data
|
||||
*/
|
||||
typedef struct {
|
||||
int celsius_value; /**< Celsius value in interrupt callback. */
|
||||
} temperature_sensor_threshold_event_data_t;
|
||||
|
||||
/**
|
||||
* @brief Callback for temperature sensor threshold interrupt.
|
||||
*
|
||||
* @param[in] tsens The handle created by `temperature_sensor_install()`.
|
||||
* @param[in] edata temperature sensor event data, fed by driver.
|
||||
* @param[in] user_data User data, set in `temperature_sensor_register_callbacks()`.
|
||||
* @return Whether a high priority task has been waken up by this function.
|
||||
*/
|
||||
typedef bool (*temperature_thres_cb_t)(temperature_sensor_handle_t tsens, const temperature_sensor_threshold_event_data_t *edata, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Group of temperature sensor callback functions, all of them will be run in ISR.
|
||||
*/
|
||||
typedef struct {
|
||||
temperature_thres_cb_t on_threshold; /**< Temperature value interrupt callback */
|
||||
} temperature_sensor_event_callbacks_t;
|
||||
|
||||
/**
|
||||
* @brief Config options for temperature value absolute interrupt.
|
||||
*/
|
||||
typedef struct {
|
||||
float high_threshold; /**< High threshold value(Celsius). Interrupt will be triggered if temperature value is higher than this value */
|
||||
float low_threshold; /**< Low threshold value(Celsius). Interrupt will be triggered if temperature value is lower than this value */
|
||||
} temperature_sensor_abs_threshold_config_t;
|
||||
|
||||
/**
|
||||
* @brief Set temperature sensor absolute mode automatic monitor.
|
||||
*
|
||||
* @param tsens The handle created by `temperature_sensor_install()`.
|
||||
* @param abs_cfg Configuration of temperature sensor absolute mode interrupt, see `temperature_sensor_abs_threshold_config_t`.
|
||||
* @note This function should not be called with `temperature_sensor_set_delta_threshold`.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Set absolute threshold successfully.
|
||||
* - ESP_ERR_INVALID_STATE: Set absolute threshold failed because of wrong state.
|
||||
* - ESP_ERR_INVALID_ARG: Set absolute threshold failed because of invalid argument.
|
||||
*/
|
||||
esp_err_t temperature_sensor_set_absolute_threshold(temperature_sensor_handle_t tsens, const temperature_sensor_abs_threshold_config_t *abs_cfg);
|
||||
|
||||
/**
|
||||
* @brief Config options for temperature value delta interrupt.
|
||||
*/
|
||||
typedef struct {
|
||||
float increase_delta; /**< Interrupt will be triggered if the temperature increment of two consecutive samplings if larger than `increase_delta` */
|
||||
float decrease_delta; /**< Interrupt will be triggered if the temperature decrement of two consecutive samplings if smaller than `decrease_delta` */
|
||||
} temperature_sensor_delta_threshold_config_t;
|
||||
|
||||
/**
|
||||
* @brief Set temperature sensor differential mode automatic monitor.
|
||||
*
|
||||
* @param tsens The handle created by `temperature_sensor_install()`.
|
||||
* @param delta_cfg Configuration of temperature sensor delta mode interrupt, see `temperature_sensor_delta_threshold_config_t`.
|
||||
* @note This function should not be called with `temperature_sensor_set_absolute_threshold`
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Set differential value threshold successfully.
|
||||
* - ESP_ERR_INVALID_STATE: Set absolute threshold failed because of wrong state.
|
||||
* - ESP_ERR_INVALID_ARG: Set differential value threshold failed because of invalid argument.
|
||||
*/
|
||||
esp_err_t temperature_sensor_set_delta_threshold(temperature_sensor_handle_t tsens, const temperature_sensor_delta_threshold_config_t *delta_cfg);
|
||||
|
||||
/**
|
||||
* @brief Install temperature sensor interrupt callback. Temperature sensor interrupt will be enabled at same time
|
||||
*
|
||||
* @param tsens The handle created by `temperature_sensor_install()`.
|
||||
* @param cbs Pointer to the group of temperature sensor interrupt callbacks.
|
||||
* @param user_arg Callback argument.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Set event callbacks successfully
|
||||
* - ESP_ERR_INVALID_ARG: Set event callbacks failed because of invalid argument
|
||||
* - ESP_FAIL: Set event callbacks failed because of other error
|
||||
*/
|
||||
esp_err_t temperature_sensor_register_callbacks(temperature_sensor_handle_t tsens, const temperature_sensor_event_callbacks_t *cbs, void *user_arg);
|
||||
|
||||
#endif // SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -24,25 +24,18 @@
|
||||
#include "driver/temperature_sensor.h"
|
||||
#include "esp_efuse_rtc_calib.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "temperature_sensor_private.h"
|
||||
#include "hal/temperature_sensor_ll.h"
|
||||
#include "soc/temperature_sensor_periph.h"
|
||||
#include "esp_memory_utils.h"
|
||||
|
||||
static const char *TAG = "temperature_sensor";
|
||||
|
||||
typedef enum {
|
||||
TEMP_SENSOR_FSM_INIT,
|
||||
TEMP_SENSOR_FSM_ENABLE,
|
||||
} temp_sensor_fsm_t;
|
||||
|
||||
static float s_deltaT = NAN; // unused number
|
||||
|
||||
typedef struct temperature_sensor_obj_t temperature_sensor_obj_t;
|
||||
|
||||
struct temperature_sensor_obj_t {
|
||||
const temperature_sensor_attribute_t *tsens_attribute;
|
||||
temp_sensor_fsm_t fsm;
|
||||
temperature_sensor_clk_src_t clk_src;
|
||||
};
|
||||
#if SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
static int8_t s_temperature_regval_2_celsius(temperature_sensor_handle_t tsens, uint8_t regval);
|
||||
#endif // SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
|
||||
static temperature_sensor_attribute_t *s_tsens_attribute_copy;
|
||||
|
||||
@ -53,7 +46,7 @@ static int inline accuracy_compare(const void *p1, const void *p2)
|
||||
|
||||
static esp_err_t temperature_sensor_attribute_table_sort(void)
|
||||
{
|
||||
s_tsens_attribute_copy = (temperature_sensor_attribute_t *)heap_caps_malloc(sizeof(temperature_sensor_attributes), MALLOC_CAP_DEFAULT);
|
||||
s_tsens_attribute_copy = (temperature_sensor_attribute_t *)heap_caps_malloc(sizeof(temperature_sensor_attributes), TEMPERATURE_SENSOR_MEM_ALLOC_CAPS);
|
||||
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_ATTR_RANGE_NUM; i++) {
|
||||
s_tsens_attribute_copy[i] = temperature_sensor_attributes[i];
|
||||
@ -75,6 +68,27 @@ static esp_err_t temperature_sensor_choose_best_range(temperature_sensor_handle_
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
static void IRAM_ATTR temperature_sensor_isr(void *arg)
|
||||
{
|
||||
temperature_sensor_ll_clear_intr();
|
||||
bool cbs_yield = false;
|
||||
temperature_sensor_handle_t tsens = (temperature_sensor_handle_t) arg;
|
||||
temperature_sensor_threshold_event_data_t data = {
|
||||
.celsius_value = s_temperature_regval_2_celsius(tsens, temperature_sensor_ll_get_raw_value()),
|
||||
};
|
||||
if (tsens->threshold_cbs) {
|
||||
if (tsens->threshold_cbs(tsens, &data, tsens->cb_user_arg)) {
|
||||
cbs_yield = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cbs_yield) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
#endif // SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
|
||||
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
|
||||
@ -121,6 +135,13 @@ esp_err_t temperature_sensor_uninstall(temperature_sensor_handle_t tsens)
|
||||
s_tsens_attribute_copy = NULL;
|
||||
regi2c_saradc_disable();
|
||||
|
||||
#if SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
temperature_sensor_ll_enable_intr(false);
|
||||
if (tsens->temp_sensor_isr_handle) {
|
||||
ESP_RETURN_ON_ERROR(esp_intr_free(tsens->temp_sensor_isr_handle), TAG, "uninstall interrupt service failed");
|
||||
}
|
||||
#endif // SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
|
||||
periph_module_disable(PERIPH_TEMPSENSOR_MODULE);
|
||||
free(tsens);
|
||||
return ESP_OK;
|
||||
@ -137,6 +158,11 @@ esp_err_t temperature_sensor_enable(temperature_sensor_handle_t tsens)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
temperature_sensor_ll_wakeup_enable(true);
|
||||
temperature_sensor_ll_sample_enable(true);
|
||||
#endif // SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
|
||||
temperature_sensor_ll_clk_enable(true);
|
||||
temperature_sensor_ll_clk_sel(tsens->clk_src);
|
||||
temperature_sensor_ll_enable(true);
|
||||
@ -149,6 +175,11 @@ esp_err_t temperature_sensor_disable(temperature_sensor_handle_t tsens)
|
||||
ESP_RETURN_ON_FALSE(tsens, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "tsens not enabled yet");
|
||||
|
||||
#if SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
temperature_sensor_ll_wakeup_enable(false);
|
||||
temperature_sensor_ll_sample_enable(false);
|
||||
#endif
|
||||
|
||||
temperature_sensor_ll_enable(false);
|
||||
#if SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC
|
||||
if (tsens->clk_src == TEMPERATURE_SENSOR_CLK_SRC_RC_FAST) {
|
||||
@ -185,7 +216,7 @@ esp_err_t temperature_sensor_get_celsius(temperature_sensor_handle_t tsens, floa
|
||||
ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "tsens not enabled yet");
|
||||
|
||||
uint32_t tsens_out = temperature_sensor_ll_get_raw_value();
|
||||
ESP_LOGV(TAG, "tsens_out %"PRIu32, tsens_out);
|
||||
ESP_LOGD(TAG, "tsens_out %"PRIu32, 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) {
|
||||
@ -194,3 +225,86 @@ esp_err_t temperature_sensor_get_celsius(temperature_sensor_handle_t tsens, floa
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
|
||||
static uint8_t s_temperature_celsius_2_regval(temperature_sensor_handle_t tsens, int8_t celsius)
|
||||
{
|
||||
return (uint8_t)((celsius + TEMPERATURE_SENSOR_LL_OFFSET_FACTOR + TEMPERATURE_SENSOR_LL_DAC_FACTOR * tsens->tsens_attribute->offset)/TEMPERATURE_SENSOR_LL_ADC_FACTOR);
|
||||
}
|
||||
|
||||
IRAM_ATTR static int8_t s_temperature_regval_2_celsius(temperature_sensor_handle_t tsens, uint8_t regval)
|
||||
{
|
||||
return TEMPERATURE_SENSOR_LL_ADC_FACTOR * regval - TEMPERATURE_SENSOR_LL_DAC_FACTOR * tsens->tsens_attribute->offset - TEMPERATURE_SENSOR_LL_OFFSET_FACTOR;
|
||||
}
|
||||
|
||||
esp_err_t temperature_sensor_set_absolute_threshold(temperature_sensor_handle_t tsens, const temperature_sensor_abs_threshold_config_t *abs_cfg)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_RETURN_ON_FALSE((tsens != NULL), ESP_ERR_INVALID_ARG, TAG, "Temperature sensor has not been installed");
|
||||
ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in init state");
|
||||
ESP_RETURN_ON_FALSE(abs_cfg, ESP_ERR_INVALID_ARG, TAG, "Invalid callback configuration");
|
||||
|
||||
temperature_sensor_ll_set_sample_rate(0xffff);
|
||||
temperature_sensor_ll_wakeup_mode(TEMPERATURE_SENSOR_LL_WAKE_ABSOLUTE);
|
||||
temperature_sensor_ll_set_th_high_val(s_temperature_celsius_2_regval(tsens, abs_cfg->high_threshold));
|
||||
temperature_sensor_ll_set_th_low_val(s_temperature_celsius_2_regval(tsens, abs_cfg->low_threshold));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t temperature_sensor_set_delta_threshold(temperature_sensor_handle_t tsens, const temperature_sensor_delta_threshold_config_t *delta_cfg)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_RETURN_ON_FALSE((tsens != NULL), ESP_ERR_INVALID_ARG, TAG, "Temperature sensor has not been installed");
|
||||
ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in init state");
|
||||
ESP_RETURN_ON_FALSE(delta_cfg, ESP_ERR_INVALID_ARG, TAG, "Invalid callback configuration");
|
||||
|
||||
temperature_sensor_ll_set_sample_rate(0xffff);
|
||||
temperature_sensor_ll_wakeup_mode(TEMPERATURE_SENSOR_LL_WAKE_DELTA);
|
||||
temperature_sensor_ll_set_th_high_val((uint8_t)(delta_cfg->increase_delta / TEMPERATURE_SENSOR_LL_ADC_FACTOR));
|
||||
temperature_sensor_ll_set_th_low_val((uint8_t)(delta_cfg->decrease_delta / TEMPERATURE_SENSOR_LL_ADC_FACTOR));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t temperature_sensor_register_callbacks(temperature_sensor_handle_t tsens, const temperature_sensor_event_callbacks_t *cbs, void *user_arg)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_RETURN_ON_FALSE((tsens != NULL), ESP_ERR_INVALID_ARG, TAG, "Temperature sensor has not been installed");
|
||||
ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in init state");
|
||||
ESP_RETURN_ON_FALSE(cbs, ESP_ERR_INVALID_ARG, TAG, "callback group pointer is invalid");
|
||||
|
||||
#if CONFIG_TEMP_SENSOR_ISR_IRAM_SAFE
|
||||
if (cbs->on_threshold) {
|
||||
ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_threshold), ESP_ERR_INVALID_ARG, TAG, "threshold callback not in IRAM");
|
||||
}
|
||||
if (user_arg) {
|
||||
ESP_RETURN_ON_FALSE(esp_ptr_internal(user_arg), ESP_ERR_INVALID_ARG, TAG, "user argument not in internal RAM");
|
||||
}
|
||||
#endif
|
||||
|
||||
int isr_flags = TEMPERATURE_SENSOR_INTR_ALLOC_FLAGS;
|
||||
#if SOC_ADC_TEMPERATURE_SHARE_INTR
|
||||
isr_flags |= ESP_INTR_FLAG_SHARED;
|
||||
#endif
|
||||
|
||||
// lazy install interrupt service.
|
||||
if (!tsens->temp_sensor_isr_handle) {
|
||||
ret = esp_intr_alloc_intrstatus(ETS_APB_ADC_INTR_SOURCE, isr_flags,
|
||||
(uint32_t)temperature_sensor_ll_get_intr_status(),
|
||||
TEMPERATURE_SENSOR_LL_INTR_MASK, temperature_sensor_isr, tsens, &tsens->temp_sensor_isr_handle);
|
||||
}
|
||||
|
||||
if (cbs->on_threshold != NULL) {
|
||||
temperature_sensor_ll_enable_intr(true);
|
||||
temperature_sensor_ll_clear_intr();
|
||||
tsens->threshold_cbs = cbs->on_threshold;
|
||||
tsens->cb_user_arg = user_arg;
|
||||
} else {
|
||||
temperature_sensor_ll_enable_intr(false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "soc/temperature_sensor_periph.h"
|
||||
#include "hal/temperature_sensor_types.h"
|
||||
#include "driver/temperature_sensor.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
TEMP_SENSOR_FSM_INIT,
|
||||
TEMP_SENSOR_FSM_ENABLE,
|
||||
} temp_sensor_fsm_t;
|
||||
|
||||
#if CONFIG_TEMP_SENSOR_ISR_IRAM_SAFE
|
||||
#define TEMPERATURE_SENSOR_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_LOWMED)
|
||||
#define TEMPERATURE_SENSOR_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
|
||||
#else
|
||||
#define TEMPERATURE_SENSOR_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_LOWMED)
|
||||
#define TEMPERATURE_SENSOR_MEM_ALLOC_CAPS (MALLOC_CAP_DEFAULT)
|
||||
#endif
|
||||
|
||||
typedef struct temperature_sensor_obj_t temperature_sensor_obj_t;
|
||||
|
||||
struct temperature_sensor_obj_t {
|
||||
const temperature_sensor_attribute_t *tsens_attribute;
|
||||
temp_sensor_fsm_t fsm;
|
||||
temperature_sensor_clk_src_t clk_src;
|
||||
#if SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
intr_handle_t temp_sensor_isr_handle;
|
||||
temperature_thres_cb_t threshold_cbs;
|
||||
void *cb_user_arg;
|
||||
#endif // SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -8,6 +8,11 @@
|
||||
#include "esp_log.h"
|
||||
#include "unity.h"
|
||||
#include "driver/temperature_sensor.h"
|
||||
#include "esp_attr.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "unity_test_utils_cache.h"
|
||||
|
||||
TEST_CASE("Temperature_sensor_driver_workflow_test", "[temperature_sensor]")
|
||||
{
|
||||
@ -79,3 +84,64 @@ TEST_CASE("Double Start-Stop test", "[temperature_sensor]")
|
||||
TEST_ESP_OK(temperature_sensor_disable(temp_handle));
|
||||
TEST_ESP_OK(temperature_sensor_uninstall(temp_handle));
|
||||
}
|
||||
|
||||
#if SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
|
||||
IRAM_ATTR static bool temp_sensor_cbs_test(temperature_sensor_handle_t tsens, const temperature_sensor_threshold_event_data_t *edata, void *user_data)
|
||||
{
|
||||
uint8_t *times = (uint8_t*)user_data;
|
||||
ESP_DRAM_LOGI("tsens", "Temperature value is higher or lower than threshold, restart...\n\n");
|
||||
(*times)++;
|
||||
return false;
|
||||
}
|
||||
|
||||
#if CONFIG_TEMP_SENSOR_ISR_IRAM_SAFE
|
||||
static void IRAM_ATTR test_delay_post_cache_disable(void *args)
|
||||
{
|
||||
esp_rom_delay_us(1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("Temperature sensor callback test", "[temperature_sensor]")
|
||||
{
|
||||
printf("Initializing Temperature sensor\n");
|
||||
float tsens_out;
|
||||
temperature_sensor_config_t temp_sensor = TEMPERATURE_SENSOR_CONFIG_DEFAULT(10, 50);
|
||||
temperature_sensor_handle_t temp_handle = NULL;
|
||||
TEST_ESP_OK(temperature_sensor_install(&temp_sensor, &temp_handle));
|
||||
|
||||
temperature_sensor_event_callbacks_t cbs = {
|
||||
.on_threshold = temp_sensor_cbs_test,
|
||||
};
|
||||
|
||||
temperature_sensor_abs_threshold_config_t threshold_cfg = {
|
||||
.high_threshold = 50,
|
||||
.low_threshold = -10,
|
||||
};
|
||||
uint8_t temperature_alarm = 0;
|
||||
uint8_t cnt = 10;
|
||||
TEST_ESP_OK(temperature_sensor_set_absolute_threshold(temp_handle, &threshold_cfg));
|
||||
temperature_sensor_register_callbacks(temp_handle, &cbs, &temperature_alarm);
|
||||
|
||||
TEST_ESP_OK(temperature_sensor_enable(temp_handle));
|
||||
#if CONFIG_TEMP_SENSOR_ISR_IRAM_SAFE
|
||||
printf("disable flash cache and check if we can still get temperature intr\r\n");
|
||||
for (int i = 0; i < 100; i++) {
|
||||
unity_utils_run_cache_disable_stub(test_delay_post_cache_disable, NULL);
|
||||
}
|
||||
#endif
|
||||
while (cnt--) {
|
||||
ESP_ERROR_CHECK(temperature_sensor_get_celsius(temp_handle, &tsens_out));
|
||||
printf("Temperature out celsius %f°C\n", tsens_out);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
TEST_ESP_OK(temperature_sensor_disable(temp_handle));
|
||||
TEST_ESP_OK(temperature_sensor_uninstall(temp_handle));
|
||||
printf("temperature alarm is %d\n", temperature_alarm);
|
||||
// Note that on CI runner there is no way to heat the board to trigger such an interrupt.
|
||||
// But locally test should be notice that alarm must be larger than 0.
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(0, temperature_alarm);
|
||||
}
|
||||
|
||||
#endif // SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
|
@ -16,6 +16,14 @@ from pytest_embedded import Dut
|
||||
'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)
|
||||
dut.run_all_single_board_cases()
|
||||
|
||||
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.esp32h2
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', [
|
||||
'iram_safe',
|
||||
], indirect=True)
|
||||
def test_temperature_sensor_cbs(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases()
|
||||
|
@ -0,0 +1,7 @@
|
||||
CONFIG_COMPILER_DUMP_RTL_FILES=y
|
||||
CONFIG_TEMP_SENSOR_ISR_IRAM_SAFE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_NONE=y
|
||||
# silent the error check, as the error string are stored in rodata, causing RTL check failure
|
||||
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
|
||||
# place non-ISR FreeRTOS functions in Flash
|
||||
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
|
@ -19,6 +19,7 @@
|
||||
#include "hal/regi2c_ctrl.h"
|
||||
#include "soc/regi2c_saradc.h"
|
||||
#include "soc/apb_saradc_struct.h"
|
||||
#include "soc/apb_saradc_reg.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
@ -34,6 +35,13 @@ extern "C" {
|
||||
#define TEMPERATURE_SENSOR_LL_DAC_FACTOR (27.88)
|
||||
#define TEMPERATURE_SENSOR_LL_OFFSET_FACTOR (20.52)
|
||||
|
||||
#define TEMPERATURE_SENSOR_LL_INTR_MASK APB_SARADC_APB_SARADC_TSENS_INT_ST
|
||||
|
||||
typedef enum {
|
||||
TEMPERATURE_SENSOR_LL_WAKE_ABSOLUTE = 0,
|
||||
TEMPERATURE_SENSOR_LL_WAKE_DELTA = 1,
|
||||
} temperature_sensor_ll_wakeup_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Enable the temperature sensor power.
|
||||
*
|
||||
@ -90,6 +98,7 @@ static inline void temperature_sensor_ll_set_range(uint32_t range)
|
||||
*
|
||||
* @return uint32_t raw_value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t temperature_sensor_ll_get_raw_value(void)
|
||||
{
|
||||
return APB_SARADC.saradc_apb_tsens_ctrl.saradc_tsens_out;
|
||||
@ -187,6 +196,7 @@ static inline void temperature_sensor_ll_enable_intr(bool enable)
|
||||
/**
|
||||
* @brief Clear temperature sensor interrupt
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void temperature_sensor_ll_clear_intr(void)
|
||||
{
|
||||
APB_SARADC.saradc_int_clr.saradc_apb_saradc_tsens_int_clr = 1;
|
||||
@ -194,12 +204,10 @@ static inline void temperature_sensor_ll_clear_intr(void)
|
||||
|
||||
/**
|
||||
* @brief Get temperature sensor interrupt status.
|
||||
*
|
||||
* @param[out] int_status interrupt status.
|
||||
*/
|
||||
static inline void temperature_sensor_ll_get_intr_status(uint8_t *int_status)
|
||||
static inline volatile void *temperature_sensor_ll_get_intr_status(void)
|
||||
{
|
||||
*int_status = APB_SARADC.saradc_int_st.saradc_apb_saradc_tsens_int_st;
|
||||
return &APB_SARADC.saradc_int_st;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "hal/regi2c_ctrl.h"
|
||||
#include "soc/regi2c_saradc.h"
|
||||
#include "soc/apb_saradc_struct.h"
|
||||
#include "soc/apb_saradc_reg.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
@ -34,6 +35,13 @@ extern "C" {
|
||||
#define TEMPERATURE_SENSOR_LL_DAC_FACTOR (27.88)
|
||||
#define TEMPERATURE_SENSOR_LL_OFFSET_FACTOR (20.52)
|
||||
|
||||
#define TEMPERATURE_SENSOR_LL_INTR_MASK APB_SARADC_APB_SARADC_TSENS_INT_ST
|
||||
|
||||
typedef enum {
|
||||
TEMPERATURE_SENSOR_LL_WAKE_ABSOLUTE = 0,
|
||||
TEMPERATURE_SENSOR_LL_WAKE_DELTA = 1,
|
||||
} temperature_sensor_ll_wakeup_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Enable the temperature sensor power.
|
||||
*
|
||||
@ -90,6 +98,7 @@ static inline void temperature_sensor_ll_set_range(uint32_t range)
|
||||
*
|
||||
* @return uint32_t raw_value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t temperature_sensor_ll_get_raw_value(void)
|
||||
{
|
||||
return APB_SARADC.saradc_apb_tsens_ctrl.saradc_tsens_out;
|
||||
@ -187,6 +196,7 @@ static inline void temperature_sensor_ll_enable_intr(bool enable)
|
||||
/**
|
||||
* @brief Clear temperature sensor interrupt
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void temperature_sensor_ll_clear_intr(void)
|
||||
{
|
||||
APB_SARADC.saradc_int_clr.saradc_apb_saradc_tsens_int_clr = 1;
|
||||
@ -194,12 +204,10 @@ static inline void temperature_sensor_ll_clear_intr(void)
|
||||
|
||||
/**
|
||||
* @brief Get temperature sensor interrupt status.
|
||||
*
|
||||
* @param[out] int_status interrupt status.
|
||||
*/
|
||||
static inline void temperature_sensor_ll_get_intr_status(uint8_t *int_status)
|
||||
static inline volatile void *temperature_sensor_ll_get_intr_status(void)
|
||||
{
|
||||
*int_status = APB_SARADC.saradc_int_st.saradc_apb_saradc_tsens_int_st;
|
||||
return &APB_SARADC.saradc_int_st;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -271,6 +271,10 @@ config SOC_ADC_CALIBRATION_V1_SUPPORTED
|
||||
bool
|
||||
default n
|
||||
|
||||
config SOC_ADC_TEMPERATURE_SHARE_INTR
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_APB_BACKUP_DMA
|
||||
bool
|
||||
default n
|
||||
@ -1099,6 +1103,10 @@ config SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_WIFI_HW_TSF
|
||||
bool
|
||||
default y
|
||||
|
@ -113,6 +113,9 @@
|
||||
/*!< Calibration */
|
||||
#define SOC_ADC_CALIBRATION_V1_SUPPORTED (0) /*!< support HW offset calibration version 1*/
|
||||
|
||||
/*!< Interrupt */
|
||||
#define SOC_ADC_TEMPERATURE_SHARE_INTR (1)
|
||||
|
||||
// ESP32C6-TODO: Copy from esp32c6, need check
|
||||
/*-------------------------- APB BACKUP DMA CAPS -------------------------------*/
|
||||
#define SOC_APB_BACKUP_DMA (0)
|
||||
@ -460,7 +463,8 @@
|
||||
|
||||
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/
|
||||
#define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1)
|
||||
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)
|
||||
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)
|
||||
#define SOC_TEMPERATURE_SENSOR_INTR_SUPPORT (1)
|
||||
|
||||
/*------------------------------------ WI-FI CAPS ------------------------------------*/
|
||||
#define SOC_WIFI_HW_TSF (1) /*!< Support hardware TSF */
|
||||
|
@ -235,6 +235,10 @@ config SOC_ADC_CALIBRATION_V1_SUPPORTED
|
||||
bool
|
||||
default n
|
||||
|
||||
config SOC_ADC_TEMPERATURE_SHARE_INTR
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_APB_BACKUP_DMA
|
||||
bool
|
||||
default n
|
||||
@ -1035,6 +1039,10 @@ config SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_BLE_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -14,7 +14,7 @@ extern "C" {
|
||||
/** APB_SARADC_CTRL_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_CTRL_REG (DR_REG_APB_BASE + 0x0)
|
||||
#define APB_SARADC_CTRL_REG (DR_REG_APB_SARADC_BASE + 0x0)
|
||||
/** APB_SARADC_SARADC_START_FORCE : R/W; bitpos: [0]; default: 0;
|
||||
* select software enable saradc sample
|
||||
*/
|
||||
@ -82,7 +82,7 @@ extern "C" {
|
||||
/** APB_SARADC_CTRL2_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_CTRL2_REG (DR_REG_APB_BASE + 0x4)
|
||||
#define APB_SARADC_CTRL2_REG (DR_REG_APB_SARADC_BASE + 0x4)
|
||||
/** APB_SARADC_SARADC_MEAS_NUM_LIMIT : R/W; bitpos: [0]; default: 0;
|
||||
* enable max meas num
|
||||
*/
|
||||
@ -129,7 +129,7 @@ extern "C" {
|
||||
/** APB_SARADC_FILTER_CTRL1_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_FILTER_CTRL1_REG (DR_REG_APB_BASE + 0x8)
|
||||
#define APB_SARADC_FILTER_CTRL1_REG (DR_REG_APB_SARADC_BASE + 0x8)
|
||||
/** APB_SARADC_APB_SARADC_FILTER_FACTOR1 : R/W; bitpos: [28:26]; default: 0;
|
||||
* Factor of saradc filter1
|
||||
*/
|
||||
@ -148,7 +148,7 @@ extern "C" {
|
||||
/** APB_SARADC_FSM_WAIT_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_FSM_WAIT_REG (DR_REG_APB_BASE + 0xc)
|
||||
#define APB_SARADC_FSM_WAIT_REG (DR_REG_APB_SARADC_BASE + 0xc)
|
||||
/** APB_SARADC_SARADC_XPD_WAIT : R/W; bitpos: [7:0]; default: 8;
|
||||
* saradc_xpd_wait
|
||||
*/
|
||||
@ -174,7 +174,7 @@ extern "C" {
|
||||
/** APB_SARADC_SAR1_STATUS_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_SAR1_STATUS_REG (DR_REG_APB_BASE + 0x10)
|
||||
#define APB_SARADC_SAR1_STATUS_REG (DR_REG_APB_SARADC_BASE + 0x10)
|
||||
/** APB_SARADC_SARADC_SAR1_STATUS : RO; bitpos: [31:0]; default: 536870912;
|
||||
* saradc1 status about data and channel
|
||||
*/
|
||||
@ -186,7 +186,7 @@ extern "C" {
|
||||
/** APB_SARADC_SAR2_STATUS_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_SAR2_STATUS_REG (DR_REG_APB_BASE + 0x14)
|
||||
#define APB_SARADC_SAR2_STATUS_REG (DR_REG_APB_SARADC_BASE + 0x14)
|
||||
/** APB_SARADC_SARADC_SAR2_STATUS : RO; bitpos: [31:0]; default: 536870912;
|
||||
* saradc2 status about data and channel
|
||||
*/
|
||||
@ -198,7 +198,7 @@ extern "C" {
|
||||
/** APB_SARADC_SAR_PATT_TAB1_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_SAR_PATT_TAB1_REG (DR_REG_APB_BASE + 0x18)
|
||||
#define APB_SARADC_SAR_PATT_TAB1_REG (DR_REG_APB_SARADC_BASE + 0x18)
|
||||
/** APB_SARADC_SARADC_SAR_PATT_TAB1 : R/W; bitpos: [23:0]; default: 16777215;
|
||||
* item 0 ~ 3 for pattern table 1 (each item one byte)
|
||||
*/
|
||||
@ -210,7 +210,7 @@ extern "C" {
|
||||
/** APB_SARADC_SAR_PATT_TAB2_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_SAR_PATT_TAB2_REG (DR_REG_APB_BASE + 0x1c)
|
||||
#define APB_SARADC_SAR_PATT_TAB2_REG (DR_REG_APB_SARADC_BASE + 0x1c)
|
||||
/** APB_SARADC_SARADC_SAR_PATT_TAB2 : R/W; bitpos: [23:0]; default: 16777215;
|
||||
* Item 4 ~ 7 for pattern table 1 (each item one byte)
|
||||
*/
|
||||
@ -222,7 +222,7 @@ extern "C" {
|
||||
/** APB_SARADC_ONETIME_SAMPLE_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_ONETIME_SAMPLE_REG (DR_REG_APB_BASE + 0x20)
|
||||
#define APB_SARADC_ONETIME_SAMPLE_REG (DR_REG_APB_SARADC_BASE + 0x20)
|
||||
/** APB_SARADC_SARADC_ONETIME_ATTEN : R/W; bitpos: [24:23]; default: 0;
|
||||
* configure onetime atten
|
||||
*/
|
||||
@ -262,7 +262,7 @@ extern "C" {
|
||||
/** APB_SARADC_ARB_CTRL_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_ARB_CTRL_REG (DR_REG_APB_BASE + 0x24)
|
||||
#define APB_SARADC_ARB_CTRL_REG (DR_REG_APB_SARADC_BASE + 0x24)
|
||||
/** APB_SARADC_ADC_ARB_APB_FORCE : R/W; bitpos: [2]; default: 0;
|
||||
* adc2 arbiter force to enableapb controller
|
||||
*/
|
||||
@ -323,7 +323,7 @@ extern "C" {
|
||||
/** APB_SARADC_FILTER_CTRL0_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_FILTER_CTRL0_REG (DR_REG_APB_BASE + 0x28)
|
||||
#define APB_SARADC_FILTER_CTRL0_REG (DR_REG_APB_SARADC_BASE + 0x28)
|
||||
/** APB_SARADC_APB_SARADC_FILTER_CHANNEL1 : R/W; bitpos: [21:18]; default: 13;
|
||||
* configure filter1 to adc channel
|
||||
*/
|
||||
@ -349,7 +349,7 @@ extern "C" {
|
||||
/** APB_SARADC_SAR1DATA_STATUS_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_SAR1DATA_STATUS_REG (DR_REG_APB_BASE + 0x2c)
|
||||
#define APB_SARADC_SAR1DATA_STATUS_REG (DR_REG_APB_SARADC_BASE + 0x2c)
|
||||
/** APB_SARADC_APB_SARADC1_DATA : RO; bitpos: [16:0]; default: 0;
|
||||
* saradc1 data
|
||||
*/
|
||||
@ -361,7 +361,7 @@ extern "C" {
|
||||
/** APB_SARADC_SAR2DATA_STATUS_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_SAR2DATA_STATUS_REG (DR_REG_APB_BASE + 0x30)
|
||||
#define APB_SARADC_SAR2DATA_STATUS_REG (DR_REG_APB_SARADC_BASE + 0x30)
|
||||
/** APB_SARADC_APB_SARADC2_DATA : RO; bitpos: [16:0]; default: 0;
|
||||
* saradc2 data
|
||||
*/
|
||||
@ -373,7 +373,7 @@ extern "C" {
|
||||
/** APB_SARADC_THRES0_CTRL_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_THRES0_CTRL_REG (DR_REG_APB_BASE + 0x34)
|
||||
#define APB_SARADC_THRES0_CTRL_REG (DR_REG_APB_SARADC_BASE + 0x34)
|
||||
/** APB_SARADC_APB_SARADC_THRES0_CHANNEL : R/W; bitpos: [3:0]; default: 13;
|
||||
* configure thres0 to adc channel
|
||||
*/
|
||||
@ -399,7 +399,7 @@ extern "C" {
|
||||
/** APB_SARADC_THRES1_CTRL_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_THRES1_CTRL_REG (DR_REG_APB_BASE + 0x38)
|
||||
#define APB_SARADC_THRES1_CTRL_REG (DR_REG_APB_SARADC_BASE + 0x38)
|
||||
/** APB_SARADC_APB_SARADC_THRES1_CHANNEL : R/W; bitpos: [3:0]; default: 13;
|
||||
* configure thres1 to adc channel
|
||||
*/
|
||||
@ -425,7 +425,7 @@ extern "C" {
|
||||
/** APB_SARADC_THRES_CTRL_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_THRES_CTRL_REG (DR_REG_APB_BASE + 0x3c)
|
||||
#define APB_SARADC_THRES_CTRL_REG (DR_REG_APB_SARADC_BASE + 0x3c)
|
||||
/** APB_SARADC_APB_SARADC_THRES_ALL_EN : R/W; bitpos: [27]; default: 0;
|
||||
* enable thres to all channel
|
||||
*/
|
||||
@ -451,7 +451,7 @@ extern "C" {
|
||||
/** APB_SARADC_INT_ENA_REG register
|
||||
* digital saradc int register
|
||||
*/
|
||||
#define APB_SARADC_INT_ENA_REG (DR_REG_APB_BASE + 0x40)
|
||||
#define APB_SARADC_INT_ENA_REG (DR_REG_APB_SARADC_BASE + 0x40)
|
||||
/** APB_SARADC_APB_SARADC_TSENS_INT_ENA : R/W; bitpos: [25]; default: 0;
|
||||
* tsens low interrupt enable
|
||||
*/
|
||||
@ -505,7 +505,7 @@ extern "C" {
|
||||
/** APB_SARADC_INT_RAW_REG register
|
||||
* digital saradc int register
|
||||
*/
|
||||
#define APB_SARADC_INT_RAW_REG (DR_REG_APB_BASE + 0x44)
|
||||
#define APB_SARADC_INT_RAW_REG (DR_REG_APB_SARADC_BASE + 0x44)
|
||||
/** APB_SARADC_APB_SARADC_TSENS_INT_RAW : R/WTC/SS; bitpos: [25]; default: 0;
|
||||
* saradc tsens interrupt raw
|
||||
*/
|
||||
@ -559,7 +559,7 @@ extern "C" {
|
||||
/** APB_SARADC_INT_ST_REG register
|
||||
* digital saradc int register
|
||||
*/
|
||||
#define APB_SARADC_INT_ST_REG (DR_REG_APB_BASE + 0x48)
|
||||
#define APB_SARADC_INT_ST_REG (DR_REG_APB_SARADC_BASE + 0x48)
|
||||
/** APB_SARADC_APB_SARADC_TSENS_INT_ST : RO; bitpos: [25]; default: 0;
|
||||
* saradc tsens interrupt state
|
||||
*/
|
||||
@ -613,7 +613,7 @@ extern "C" {
|
||||
/** APB_SARADC_INT_CLR_REG register
|
||||
* digital saradc int register
|
||||
*/
|
||||
#define APB_SARADC_INT_CLR_REG (DR_REG_APB_BASE + 0x4c)
|
||||
#define APB_SARADC_INT_CLR_REG (DR_REG_APB_SARADC_BASE + 0x4c)
|
||||
/** APB_SARADC_APB_SARADC_TSENS_INT_CLR : WT; bitpos: [25]; default: 0;
|
||||
* saradc tsens interrupt clear
|
||||
*/
|
||||
@ -667,7 +667,7 @@ extern "C" {
|
||||
/** APB_SARADC_DMA_CONF_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_DMA_CONF_REG (DR_REG_APB_BASE + 0x50)
|
||||
#define APB_SARADC_DMA_CONF_REG (DR_REG_APB_SARADC_BASE + 0x50)
|
||||
/** APB_SARADC_APB_ADC_EOF_NUM : R/W; bitpos: [15:0]; default: 255;
|
||||
* the dma_in_suc_eof gen when sample cnt = spi_eof_num
|
||||
*/
|
||||
@ -693,7 +693,7 @@ extern "C" {
|
||||
/** APB_SARADC_CLKM_CONF_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_CLKM_CONF_REG (DR_REG_APB_BASE + 0x54)
|
||||
#define APB_SARADC_CLKM_CONF_REG (DR_REG_APB_SARADC_BASE + 0x54)
|
||||
/** APB_SARADC_CLKM_DIV_NUM : R/W; bitpos: [7:0]; default: 4;
|
||||
* Integral I2S clock divider value
|
||||
*/
|
||||
@ -733,7 +733,7 @@ extern "C" {
|
||||
/** APB_SARADC_APB_TSENS_CTRL_REG register
|
||||
* digital tsens configure register
|
||||
*/
|
||||
#define APB_SARADC_APB_TSENS_CTRL_REG (DR_REG_APB_BASE + 0x58)
|
||||
#define APB_SARADC_APB_TSENS_CTRL_REG (DR_REG_APB_SARADC_BASE + 0x58)
|
||||
/** APB_SARADC_TSENS_OUT : RO; bitpos: [7:0]; default: 128;
|
||||
* temperature sensor data out
|
||||
*/
|
||||
@ -766,7 +766,7 @@ extern "C" {
|
||||
/** APB_SARADC_TSENS_CTRL2_REG register
|
||||
* digital tsens configure register
|
||||
*/
|
||||
#define APB_SARADC_TSENS_CTRL2_REG (DR_REG_APB_BASE + 0x5c)
|
||||
#define APB_SARADC_TSENS_CTRL2_REG (DR_REG_APB_SARADC_BASE + 0x5c)
|
||||
/** APB_SARADC_TSENS_XPD_WAIT : R/W; bitpos: [11:0]; default: 2;
|
||||
* the time that power up tsens need wait
|
||||
*/
|
||||
@ -799,7 +799,7 @@ extern "C" {
|
||||
/** APB_SARADC_CALI_REG register
|
||||
* digital saradc configure register
|
||||
*/
|
||||
#define APB_SARADC_CALI_REG (DR_REG_APB_BASE + 0x60)
|
||||
#define APB_SARADC_CALI_REG (DR_REG_APB_SARADC_BASE + 0x60)
|
||||
/** APB_SARADC_APB_SARADC_CALI_CFG : R/W; bitpos: [16:0]; default: 32768;
|
||||
* saradc cali factor
|
||||
*/
|
||||
@ -811,7 +811,7 @@ extern "C" {
|
||||
/** APB_TSENS_WAKE_REG register
|
||||
* digital tsens configure register
|
||||
*/
|
||||
#define APB_TSENS_WAKE_REG (DR_REG_APB_BASE + 0x64)
|
||||
#define APB_TSENS_WAKE_REG (DR_REG_APB_SARADC_BASE + 0x64)
|
||||
/** APB_SARADC_WAKEUP_TH_LOW : R/W; bitpos: [7:0]; default: 0;
|
||||
* reg_wakeup_th_low
|
||||
*/
|
||||
@ -851,7 +851,7 @@ extern "C" {
|
||||
/** APB_TSENS_SAMPLE_REG register
|
||||
* digital tsens configure register
|
||||
*/
|
||||
#define APB_TSENS_SAMPLE_REG (DR_REG_APB_BASE + 0x68)
|
||||
#define APB_TSENS_SAMPLE_REG (DR_REG_APB_SARADC_BASE + 0x68)
|
||||
/** APB_SARADC_TSENS_SAMPLE_RATE : R/W; bitpos: [15:0]; default: 20;
|
||||
* HW sample rate
|
||||
*/
|
||||
@ -870,7 +870,7 @@ extern "C" {
|
||||
/** APB_SARADC_CTRL_DATE_REG register
|
||||
* version
|
||||
*/
|
||||
#define APB_SARADC_CTRL_DATE_REG (DR_REG_APB_BASE + 0x3fc)
|
||||
#define APB_SARADC_CTRL_DATE_REG (DR_REG_APB_SARADC_BASE + 0x3fc)
|
||||
/** APB_SARADC_DATE : R/W; bitpos: [31:0]; default: 35676736;
|
||||
* version
|
||||
*/
|
||||
|
@ -109,6 +109,9 @@
|
||||
/*!< Calibration */
|
||||
#define SOC_ADC_CALIBRATION_V1_SUPPORTED (0) /*!< support HW offset calibration version 1*/
|
||||
|
||||
/*!< Interrupt */
|
||||
#define SOC_ADC_TEMPERATURE_SHARE_INTR (1)
|
||||
|
||||
// ESP32H2-TODO: Copy from esp32c6, need check
|
||||
/*-------------------------- APB BACKUP DMA CAPS -------------------------------*/
|
||||
#define SOC_APB_BACKUP_DMA (0)
|
||||
@ -454,10 +457,10 @@
|
||||
|
||||
#define SOC_CLK_LP_FAST_SUPPORT_LP_PLL (1) /*!< Support LP_PLL clock as the LP_FAST clock source */
|
||||
|
||||
// TODO: IDF-6229 (Copy from esp32c6, need check)
|
||||
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/
|
||||
#define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1)
|
||||
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)
|
||||
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)
|
||||
#define SOC_TEMPERATURE_SENSOR_INTR_SUPPORT (1)
|
||||
|
||||
/*---------------------------------- Bluetooth CAPS ----------------------------------*/
|
||||
#define SOC_BLE_SUPPORTED (1) /*!< Support Bluetooth Low Energy hardware */
|
||||
|
@ -29,11 +29,15 @@ Due to restrictions of hardware, the sensor has predefined measurement ranges wi
|
||||
Functional Overview
|
||||
-------------------
|
||||
|
||||
- `Resource Allocation <#resource-allocation>`__ - covers which parameters should be set up to get a temperature sensor handle and how to recycle the resources when temperature sensor finishes working.
|
||||
- `Enable and Disable Temperature Sensor <#enable-and-disable-temperature-sensor>`__ - covers how to enable and disable the temperature sensor.
|
||||
- `Get Temperature Value <#get-temperature-value>`__ - covers how to get the real-time temperature value.
|
||||
- `Power Management <#power-management>`__ - covers how temperature sensor is affected when changing power mode (i.e. light sleep).
|
||||
- `Thread Safety <#thread-safety>`__ - covers how to make the driver to be thread safe.
|
||||
.. list::
|
||||
|
||||
- `Resource Allocation <#resource-allocation>`__ - covers which parameters should be set up to get a temperature sensor handle and how to recycle the resources when temperature sensor finishes working.
|
||||
- `Enable and Disable Temperature Sensor <#enable-and-disable-temperature-sensor>`__ - covers how to enable and disable the temperature sensor.
|
||||
- `Get Temperature Value <#get-temperature-value>`__ - covers how to get the real-time temperature value.
|
||||
:SOC_TEMPERATURE_SENSOR_INTR_SUPPORT: - `Temperature Threshold Interrupt <#install-temperature-threshold-callback>`__ - describes how to register a temperature threshold callback.
|
||||
- `Power Management <#power-management>`__ - covers how temperature sensor is affected when changing power mode (i.e. light sleep).
|
||||
:SOC_TEMPERATURE_SENSOR_INTR_SUPPORT: - `IRAM Safe <#iram-safe>`__ - describes tips on how to make the temperature sensor interrupt work better along with a disabled cache.
|
||||
- `Thread Safety <#thread-safety>`__ - covers how to make the driver to be thread safe.
|
||||
|
||||
Resource Allocation
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
@ -89,11 +93,58 @@ After the temperature sensor is enabled by :cpp:func:`temperature_sensor_enable`
|
||||
// Disable the temperature sensor if it's not needed and save the power
|
||||
ESP_ERROR_CHECK(temperature_sensor_disable(temp_handle));
|
||||
|
||||
.. only:: SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
|
||||
Install Temperature Threshold Callback
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
{IDF_TARGET_NAME} supports automatically triggering to monitor the temperature value continuously. When temperature value reaches a given threshold, an interrupt will happen. Thus users can install their own interrupt callback functions to do what they want. (e.g. alarm, restart, etc.). Following information indicates how to prepare a threshold callback.
|
||||
|
||||
- :cpp:member:`temperature_sensor_event_callbacks_t::on_threshold`. As this function is called within the ISR context, you must ensure that the function does not attempt to block (e.g., by making sure that only FreeRTOS APIs with ``ISR`` suffix are called from within the function, etc.). The function prototype is declared in :cpp:type:`temperature_thres_cb_t`.
|
||||
|
||||
You can save your own context to :cpp:func:`temperature_sensor_register_callbacks` as well, via the parameter ``user_arg``. The user data will be directly passed to the callback function.
|
||||
|
||||
.. code:: c
|
||||
|
||||
IRAM_ATTR static bool temp_sensor_monitor_cbs(temperature_sensor_handle_t tsens, const temperature_sensor_threshold_event_data_t *edata, void *user_data)
|
||||
{
|
||||
ESP_DRAM_LOGI("tsens", "Temperature value is higher or lower than threshold, value is %d\n...\n\n", edata->celsius_value);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Callback configurations
|
||||
temperature_sensor_abs_threshold_config_t threshold_cfg = {
|
||||
.high_threshold = 50,
|
||||
.low_threshold = -10,
|
||||
};
|
||||
// Set absolute value monitor threshold.
|
||||
temperature_sensor_set_absolute_threshold(temp_sensor, &threshold_cfg);
|
||||
// Register interrupt callback
|
||||
temperature_sensor_event_callbacks_t cbs = {
|
||||
.on_threshold = temp_sensor_monitor_cbs,
|
||||
};
|
||||
// Install temperature callback.
|
||||
temperature_sensor_register_callbacks(temp_sensor, &cbs, NULL);
|
||||
|
||||
Power Management
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
When power management is enabled (i.e. ``CONFIG_PM_ENABLE`` is on), temperature sensor will still keep working because it uses XTAL clock (on ESP32-C3) or RTC clock (on ESP32-S2/S3).
|
||||
|
||||
.. only:: SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
|
||||
|
||||
IRAM Safe
|
||||
^^^^^^^^^
|
||||
|
||||
By default, the temperature sensor interrupt will be deferred when the Cache is disabled for reasons like writing/erasing Flash. Thus the event callback functions will not get executed in time, which is not expected in a real-time application.
|
||||
|
||||
There's a Kconfig option :ref:`CONFIG_TEMP_SENSOR_ISR_IRAM_SAFE` that will:
|
||||
|
||||
1. Enable the interrupt being serviced even when cache is disabled.
|
||||
2. Place all functions that used by the ISR into IRAM.
|
||||
|
||||
This will allow the interrupt to run while the cache is disabled but will come at the cost of increased IRAM consumption.
|
||||
|
||||
Thread Safety
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
@ -112,7 +163,10 @@ Unexpected Behaviors
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
* Temperature sensor reading example: :example:`peripherals/temp_sensor`.
|
||||
.. list::
|
||||
|
||||
* Temperature sensor reading example: :example:`peripherals/temperature_sensor/temp_sensor`.
|
||||
:SOC_TEMPERATURE_SENSOR_INTR_SUPPORT: * Temperature sensor value monitor example: :example:`peripherals/temperature_sensor/temp_sensor`.
|
||||
|
||||
API Reference
|
||||
----------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user