/* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "soc/soc_caps.h" #include "freertos/FreeRTOS.h" #include "esp_private/sar_periph_ctrl.h" #include "esp_log.h" #include "esp_timer.h" #if SOC_TEMP_SENSOR_SUPPORTED #include "hal/temperature_sensor_ll.h" #include "hal/temperature_sensor_hal.h" #include "soc/periph_defs.h" #include "esp_private/periph_ctrl.h" #include "esp_private/adc_share_hw_ctrl.h" #include "esp_private/critical_section.h" extern __attribute__((unused)) portMUX_TYPE rtc_spinlock; /*------------------------------------------------------------------------------------------------------------ -----------------------------------------Temperature Sensor--------------------------------------------------- ------------------------------------------------------------------------------------------------------------*/ static const char *TAG_TSENS = "temperature_sensor"; #define INT_NOT_USED 999999 #if !SOC_RCC_IS_INDEPENDENT #define TSENS_RCC_ATOMIC() PERIPH_RCC_ATOMIC() #else #define TSENS_RCC_ATOMIC() #endif #define TSENS_LINE_REGRESSION_US (200) static int s_temperature_sensor_power_cnt; static bool s_first_temp_read = false; static int64_t timer1 = 0; void temperature_sensor_power_acquire(void) { esp_os_enter_critical(&rtc_spinlock); s_temperature_sensor_power_cnt++; if (s_temperature_sensor_power_cnt == 1) { s_first_temp_read = true; regi2c_saradc_enable(); #if !SOC_TSENS_IS_INDEPENDENT_FROM_ADC adc_apb_periph_claim(); #endif TSENS_RCC_ATOMIC() { temperature_sensor_ll_bus_clk_enable(true); temperature_sensor_ll_reset_module(); } temperature_sensor_ll_enable(true); // Initialize HAL layer with the same tsens_idx temperature_sensor_hal_init(); timer1 = esp_timer_get_time(); } esp_os_exit_critical(&rtc_spinlock); } void temperature_sensor_power_release(void) { esp_os_enter_critical(&rtc_spinlock); s_temperature_sensor_power_cnt--; /* Sanity check */ if (s_temperature_sensor_power_cnt < 0) { esp_os_exit_critical(&rtc_spinlock); ESP_LOGE(TAG_TSENS, "%s called, but s_temperature_sensor_power_cnt == 0", __func__); abort(); } else if (s_temperature_sensor_power_cnt == 0) { temperature_sensor_ll_enable(false); TSENS_RCC_ATOMIC() { temperature_sensor_ll_bus_clk_enable(false); } #if !SOC_TSENS_IS_INDEPENDENT_FROM_ADC adc_apb_periph_free(); #endif regi2c_saradc_disable(); } esp_os_exit_critical(&rtc_spinlock); } int16_t temp_sensor_get_raw_value(bool *range_changed) { int16_t result; esp_os_enter_critical(&rtc_spinlock); // When this is the first time reading a value, check whether the time here minus the // initialization time is greater than 200 microseconds (the time for linear regression). // If it is less than 200 microseconds, continue waiting here. if (s_first_temp_read == true) { int64_t timer2 = esp_timer_get_time(); int64_t diff = timer2 - timer1; if (diff < TSENS_LINE_REGRESSION_US) { esp_rom_delay_us(TSENS_LINE_REGRESSION_US - diff); } s_first_temp_read = false; } result = temperature_sensor_hal_get_degree(range_changed); esp_os_exit_critical(&rtc_spinlock); return result; } #endif