From 441900caa2cc1faf4875945ba57d7a474ea71361 Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Fri, 4 Mar 2022 17:59:07 +0800 Subject: [PATCH] Temperature_sensor: keep legacy drivers --- components/driver/Kconfig | 20 +++ .../driver/deprecated/driver/temp_sensor.h | 76 +++++++++ .../driver/temp_sensor_types_legacy.h | 40 +++++ components/driver/rtc_temperature_legacy.c | 152 ++++++++++++++++++ .../legacy_rtc_temp_driver/CMakeLists.txt | 5 + .../legacy_rtc_temp_driver/README.md | 2 + .../main/CMakeLists.txt | 7 + .../main/test_app_main.c | 40 +++++ .../main/test_rtc_temp_driver.c | 68 ++++++++ .../pytest_legacy_temp_sensor_driver.py | 18 +++ .../sdkconfig.ci.release | 5 + .../legacy_rtc_temp_driver/sdkconfig.defaults | 2 + 12 files changed, 435 insertions(+) create mode 100644 components/driver/deprecated/driver/temp_sensor.h create mode 100644 components/driver/deprecated/driver/temp_sensor_types_legacy.h create mode 100644 components/driver/rtc_temperature_legacy.c create mode 100644 components/driver/test_apps/legacy_rtc_temp_driver/CMakeLists.txt create mode 100644 components/driver/test_apps/legacy_rtc_temp_driver/README.md create mode 100644 components/driver/test_apps/legacy_rtc_temp_driver/main/CMakeLists.txt create mode 100644 components/driver/test_apps/legacy_rtc_temp_driver/main/test_app_main.c create mode 100644 components/driver/test_apps/legacy_rtc_temp_driver/main/test_rtc_temp_driver.c create mode 100644 components/driver/test_apps/legacy_rtc_temp_driver/pytest_legacy_temp_sensor_driver.py create mode 100644 components/driver/test_apps/legacy_rtc_temp_driver/sdkconfig.ci.release create mode 100644 components/driver/test_apps/legacy_rtc_temp_driver/sdkconfig.defaults diff --git a/components/driver/Kconfig b/components/driver/Kconfig index d0f0f8542b..0f98cdb998 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -145,6 +145,26 @@ menu "Driver configurations" endmenu # TWAI Configuration + menu "Temperature sensor Configuration" + visible if SOC_TEMP_SENSOR_SUPPORTED + + config TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN + bool "Suppress legacy driver deprecated warning" + default n + help + Wether to suppress the deprecation warnings when using legacy temperature sensor driver + (driver/temp_sensor.h). If you want to continue using the legacy driver, + and don't want to see related deprecation warnings, you can enable this option. + + config TEMP_SENSOR_ENABLE_DEBUG_LOG + bool "Enable debug log" + default n + help + 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. + + endmenu # TEMP_SENSOR Configuration + menu "UART configuration" config UART_ISR_IN_IRAM diff --git a/components/driver/deprecated/driver/temp_sensor.h b/components/driver/deprecated/driver/temp_sensor.h new file mode 100644 index 0000000000..c5a28600df --- /dev/null +++ b/components/driver/deprecated/driver/temp_sensor.h @@ -0,0 +1,76 @@ +/* + * SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_err.h" +#include "driver/temp_sensor_types_legacy.h" + +#if !CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN +#warning "legacy temperature sensor driver is deprecated, please migrate to driver/temperature_sensor.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @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 diff --git a/components/driver/deprecated/driver/temp_sensor_types_legacy.h b/components/driver/deprecated/driver/temp_sensor_types_legacy.h new file mode 100644 index 0000000000..61f5ab7919 --- /dev/null +++ b/components/driver/deprecated/driver/temp_sensor_types_legacy.h @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#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} + +#ifdef __cplusplus +} +#endif diff --git a/components/driver/rtc_temperature_legacy.c b/components/driver/rtc_temperature_legacy.c new file mode 100644 index 0000000000..a3f9f33443 --- /dev/null +++ b/components/driver/rtc_temperature_legacy.c @@ -0,0 +1,152 @@ +/* + * SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "esp_types.h" +#include "esp_log.h" +#include "esp_check.h" +#include "soc/rtc_cntl_reg.h" +#include "regi2c_ctrl.h" +#include "esp_log.h" +#include "esp_efuse_rtc_calib.h" +#include "hal/temperature_sensor_ll.h" +#include "driver/temp_sensor_types_legacy.h" +#include "esp_private/periph_ctrl.h" +#include "sdkconfig.h" + +static const char *TAG = "tsens"; + +#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 reg_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) +{ + 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; + } + temperature_sensor_ll_set_clk_div(tsens.clk_div); + temperature_sensor_ll_set_range(dac_offset[tsens.dac_offset].reg_val); + temperature_sensor_ll_enable(true); + ESP_LOGI(TAG, "Config 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"); + tsens->dac_offset = temperature_sensor_ll_get_offset(); + for (int i = TSENS_DAC_L0; i < TSENS_DAC_MAX; i++) { + if ((int)tsens->dac_offset == dac_offset[i].reg_val) { + tsens->dac_offset = dac_offset[i].index; + break; + } + } + tsens->clk_div = temperature_sensor_ll_get_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, "Is already running or not be configured"); + err = ESP_ERR_INVALID_STATE; + } + periph_module_enable(PERIPH_TEMPSENSOR_MODULE); + temperature_sensor_ll_enable(true); + temperature_sensor_ll_clk_enable(true); + temperature_sensor_ll_clk_sel(TEMPERATURE_SENSOR_CLK_SRC_DEFAULT); + tsens_hw_state = TSENS_HW_STATE_STARTED; + return err; +} + +esp_err_t temp_sensor_stop(void) +{ + temperature_sensor_ll_enable(false); + tsens_hw_state = TSENS_HW_STATE_CONFIGURED; + 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 = temperature_sensor_ll_get_raw_value(); + return ESP_OK; +} + +static esp_err_t read_delta_t_from_efuse(void) +{ + ESP_RETURN_ON_ERROR(esp_efuse_rtc_calib_get_tsens_val(&s_deltaT), TAG, "Calibration error"); + 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 temp_sensor_read_celsius(float *celsius) +{ + ESP_RETURN_ON_FALSE(celsius != NULL, ESP_ERR_INVALID_ARG, TAG, "celsius points to nothing"); + if (tsens_hw_state != TSENS_HW_STATE_STARTED) { + ESP_LOGE(TAG, "Has not been started"); + return ESP_ERR_INVALID_STATE; + } + temp_sensor_config_t tsens; + uint32_t tsens_out = 0; + temp_sensor_get_config(&tsens); + temp_sensor_read_raw(&tsens_out); + ESP_LOGV(TAG, "tsens_out %d", tsens_out); + 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!"); + return ESP_ERR_INVALID_STATE; + } + return ESP_OK; +} diff --git a/components/driver/test_apps/legacy_rtc_temp_driver/CMakeLists.txt b/components/driver/test_apps/legacy_rtc_temp_driver/CMakeLists.txt new file mode 100644 index 0000000000..761e56ea88 --- /dev/null +++ b/components/driver/test_apps/legacy_rtc_temp_driver/CMakeLists.txt @@ -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(legacy_rtc_temp_driver_test) diff --git a/components/driver/test_apps/legacy_rtc_temp_driver/README.md b/components/driver/test_apps/legacy_rtc_temp_driver/README.md new file mode 100644 index 0000000000..0dfa474720 --- /dev/null +++ b/components/driver/test_apps/legacy_rtc_temp_driver/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32-S2 | ESP32-S3 | ESP32-C3 | +| ----------------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/legacy_rtc_temp_driver/main/CMakeLists.txt b/components/driver/test_apps/legacy_rtc_temp_driver/main/CMakeLists.txt new file mode 100644 index 0000000000..483019a963 --- /dev/null +++ b/components/driver/test_apps/legacy_rtc_temp_driver/main/CMakeLists.txt @@ -0,0 +1,7 @@ +set(srcs "test_app_main.c" + "test_rtc_temp_driver.c") + +idf_component_register(SRCS ${srcs} + PRIV_REQUIRES driver unity) + +target_link_libraries(${COMPONENT_LIB} INTERFACE "-u test_app_include_rtc_temp_driver") diff --git a/components/driver/test_apps/legacy_rtc_temp_driver/main/test_app_main.c b/components/driver/test_apps/legacy_rtc_temp_driver/main/test_app_main.c new file mode 100644 index 0000000000..183a88ae3c --- /dev/null +++ b/components/driver/test_apps/legacy_rtc_temp_driver/main/test_app_main.c @@ -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(); +} diff --git a/components/driver/test_apps/legacy_rtc_temp_driver/main/test_rtc_temp_driver.c b/components/driver/test_apps/legacy_rtc_temp_driver/main/test_rtc_temp_driver.c new file mode 100644 index 0000000000..5ffdb8aaaf --- /dev/null +++ b/components/driver/test_apps/legacy_rtc_temp_driver/main/test_rtc_temp_driver.c @@ -0,0 +1,68 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "esp_log.h" +#include "unity.h" +#include "driver/temp_sensor.h" + +void test_app_include_rtc_temp_driver(void) +{ +} + +TEST_CASE("Temperature_lagecy_workflow_test", "[hw_timer]") +{ + printf("Initializing Temperature sensor\n"); + float tsens_out; + temp_sensor_config_t temp_sensor = TSENS_CONFIG_DEFAULT(); + TEST_ESP_OK(temp_sensor_get_config(&temp_sensor)); + printf("default dac %d, clk_div %d\n", temp_sensor.dac_offset, temp_sensor.clk_div); + temp_sensor.dac_offset = TSENS_DAC_DEFAULT; // DEFAULT: range:-10℃ ~ 80℃, error < 1℃. + TEST_ESP_OK(temp_sensor_set_config(temp_sensor)); + TEST_ESP_OK(temp_sensor_start()); + printf("Temperature sensor started\n"); + TEST_ESP_OK(temp_sensor_read_celsius(&tsens_out)); + printf("Temperature out celsius %f°C\n", tsens_out); + TEST_ESP_OK(temp_sensor_stop()); + temp_sensor.dac_offset = TSENS_DAC_L3; + TEST_ESP_OK(temp_sensor_set_config(temp_sensor)); + TEST_ESP_OK(temp_sensor_start()); + printf("Temperature sensor started again\n"); + TEST_ESP_OK(temp_sensor_read_celsius(&tsens_out)); + printf("Temperature out celsius %f°C\n", tsens_out); + TEST_ESP_OK(temp_sensor_stop()); +} + +TEST_CASE("Double start error cause test", "[temperatere_sensor]") +{ + printf("Initializing Temperature sensor\n"); + temp_sensor_config_t temp_sensor = TSENS_CONFIG_DEFAULT(); + TEST_ESP_OK(temp_sensor_set_config(temp_sensor)); + TEST_ESP_OK(temp_sensor_start()); + TEST_ESP_ERR(ESP_ERR_INVALID_STATE, temp_sensor_start()); + TEST_ESP_OK(temp_sensor_stop()); +} + +TEST_CASE("Double Start-Stop test", "[temperature_sensor]") +{ + printf("Initializing Temperature sensor\n"); + float tsens_out; + temp_sensor_config_t temp_sensor = TSENS_CONFIG_DEFAULT(); + TEST_ESP_OK(temp_sensor_get_config(&temp_sensor)); + printf("default dac %d, clk_div %d\n", temp_sensor.dac_offset, temp_sensor.clk_div); + temp_sensor.dac_offset = TSENS_DAC_DEFAULT; // DEFAULT: range:-10℃ ~ 80℃, error < 1℃. + TEST_ESP_OK(temp_sensor_set_config(temp_sensor)); + TEST_ESP_OK(temp_sensor_start()); + printf("Temperature sensor started\n"); + TEST_ESP_OK(temp_sensor_read_celsius(&tsens_out)); + printf("Temperature out celsius %f°C\n", tsens_out); + TEST_ESP_OK(temp_sensor_stop()); + TEST_ESP_OK(temp_sensor_start()); + printf("Temperature sensor started again\n"); + TEST_ESP_OK(temp_sensor_read_celsius(&tsens_out)); + printf("Temperature out celsius %f°C\n", tsens_out); + TEST_ESP_OK(temp_sensor_stop()); +} diff --git a/components/driver/test_apps/legacy_rtc_temp_driver/pytest_legacy_temp_sensor_driver.py b/components/driver/test_apps/legacy_rtc_temp_driver/pytest_legacy_temp_sensor_driver.py new file mode 100644 index 0000000000..e885e9efc7 --- /dev/null +++ b/components/driver/test_apps/legacy_rtc_temp_driver/pytest_legacy_temp_sensor_driver.py @@ -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_legacy_temp_sensor_driver(dut: Dut) -> None: + dut.expect('Press ENTER to see the list of tests') + dut.write('*') + dut.expect_unity_test_output(timeout=120) diff --git a/components/driver/test_apps/legacy_rtc_temp_driver/sdkconfig.ci.release b/components/driver/test_apps/legacy_rtc_temp_driver/sdkconfig.ci.release new file mode 100644 index 0000000000..91d93f163e --- /dev/null +++ b/components/driver/test_apps/legacy_rtc_temp_driver/sdkconfig.ci.release @@ -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 diff --git a/components/driver/test_apps/legacy_rtc_temp_driver/sdkconfig.defaults b/components/driver/test_apps/legacy_rtc_temp_driver/sdkconfig.defaults new file mode 100644 index 0000000000..4335b5386b --- /dev/null +++ b/components/driver/test_apps/legacy_rtc_temp_driver/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_ESP_TASK_WDT=n +CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN=y