feat(temperature_sensor): Support temperature sensor on esp32h4

This commit is contained in:
C.S.M
2026-01-08 19:33:44 +08:00
parent 96a8cdff23
commit ff7a67fb4f
10 changed files with 391 additions and 13 deletions
@@ -1,2 +1,2 @@
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | -------- |
@@ -0,0 +1,321 @@
/*
* SPDX-FileCopyrightText: 2026 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 "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"
#include "soc/interrupts.h"
#include "soc/soc_etm_source.h"
#include "hal/temperature_sensor_types.h"
#include "hal/assert.h"
#include "hal/misc.h"
#include "hal/efuse_ll.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_ADC_FACTOR_INT (4386)
#define TEMPERATURE_SENSOR_LL_DAC_FACTOR_INT (278800)
#define TEMPERATURE_SENSOR_LL_OFFSET_FACTOR_INT (205200)
#define TEMPERATURE_SENSOR_LL_DENOMINATOR (10000)
#define TEMPERATURE_SENSOR_LL_MEASURE_MAX (125)
#define TEMPERATURE_SENSOR_LL_MEASURE_MIN (-40)
#define TEMPERATURE_SENSOR_LL_INTR_MASK APB_SARADC_APB_SARADC_TSENS_INT_ST
#define TEMPERATURE_SENSOR_LL_ETM_EVENT_TABLE(event) \
(uint32_t [TEMPERATURE_SENSOR_EVENT_MAX]){ \
[TEMPERATURE_SENSOR_EVENT_OVER_LIMIT] = TMPSNSR_EVT_OVER_LIMIT, \
}[event]
#define TEMPERATURE_SENSOR_LL_ETM_TASK_TABLE(task) \
(uint32_t [TEMPERATURE_SENSOR_TASK_MAX]){ \
[TEMPERATURE_SENSOR_TASK_START] = TMPSNSR_TASK_START_SAMPLE, \
[TEMPERATURE_SENSOR_TASK_STOP] = TMPSNSR_TASK_STOP_SAMPLE, \
}[task]
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.
*
* @param enable true: enable the power.
*/
static inline void temperature_sensor_ll_enable(bool enable)
{
APB_SARADC.saradc_apb_tsens_ctrl.saradc_tsens_pu = enable;
}
/**
* @brief Enable the clock
*/
static inline void temperature_sensor_ll_bus_clk_enable(bool enable)
{
PCR.tsens_clk_conf.tsens_clk_en = enable;
}
/**
* @brief Reset the Temperature sensor module
*/
static inline void temperature_sensor_ll_reset_module(void)
{
PCR.tsens_clk_conf.tsens_rst_en = 1;
PCR.tsens_clk_conf.tsens_rst_en = 0;
}
/**
* @brief Select the clock source for temperature sensor. On ESP32-H4, 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_XTAL:
clk_sel = 1;
break;
case TEMPERATURE_SENSOR_CLK_SRC_RC_FAST:
clk_sel = 0;
break;
default:
HAL_ASSERT(false);
break;
}
PCR.tsens_clk_conf.tsens_clk_sel = clk_sel;
}
/**
* @brief Set the hardware range, you can refer to the table ``temperature_sensor_attributes``
*
* @param tsens_dac ``reg_val`` in table ``temperature_sensor_attributes``
*/
static inline void temperature_sensor_ll_set_range(uint32_t range)
{
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC, range);
}
/**
* @brief Get the raw value of temperature sensor.
*
* @return uint32_t raw_value
*/
__attribute__((always_inline))
static inline uint32_t temperature_sensor_ll_get_raw_value(void)
{
return HAL_FORCE_READ_U32_REG_FIELD(APB_SARADC.saradc_apb_tsens_ctrl, saradc_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 HAL_FORCE_READ_U32_REG_FIELD(APB_SARADC.saradc_apb_tsens_ctrl, saradc_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)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.saradc_apb_tsens_ctrl, saradc_tsens_clk_div, clk_div);
}
/**
* @brief Choose the wake-up mode for temperature sensor
*
* @note ESP32-H4 does not support difference mode.
*
* @param mode 0: Absolute value mode. 1: Difference mode.
*/
static inline void temperature_sensor_ll_wakeup_mode(temperature_sensor_ll_wakeup_mode_t mode)
{
APB_SARADC.tsens_wake.saradc_wakeup_mode = mode;
}
/**
* @brief Get temperature sensor interrupt/wakeup in which reason
*
* @return uint8_t 0: temperature value lower than low threshold 1: otherwise, higher than high threshold.
*/
__attribute__((always_inline))
static inline uint8_t temperature_sensor_ll_get_wakeup_reason(void)
{
return APB_SARADC.tsens_wake.saradc_wakeup_over_upper_th;
}
/**
* @brief Configure whether to enable temperature sensor wake up
*
* @param en true: enable, false: disable.
*/
static inline void temperature_sensor_ll_wakeup_enable(bool en)
{
APB_SARADC.tsens_wake.saradc_wakeup_en = en;
}
/**
* @brief Configures the low threshold for temperature sensor to wakeup
*
* @param th_low low threshold value.
*/
static inline void temperature_sensor_ll_set_th_low_val(uint8_t th_low)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.tsens_wake, saradc_wakeup_th_low, th_low);
}
/**
* @brief Configures the high threshold for temperature sensor to wakeup
*
* @param th_high high threshold value.
*/
static inline void temperature_sensor_ll_set_th_high_val(uint8_t th_high)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.tsens_wake, saradc_wakeup_th_high, th_high);
}
/**
* @brief Enable temperature sensor interrupt
*
* @param enable true: enable. false: disable
*/
static inline void temperature_sensor_ll_enable_intr(bool enable)
{
APB_SARADC.saradc_int_ena.saradc_apb_saradc_tsens_int_ena = 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;
}
/**
* @brief Get temperature sensor interrupt status.
*/
static inline volatile void *temperature_sensor_ll_get_intr_status(void)
{
return &APB_SARADC.saradc_int_st;
}
/**
* @brief Configure whether to enable hardware sampling
*
* @param en true: enable, false: disable
*/
static inline void temperature_sensor_ll_sample_enable(bool en)
{
APB_SARADC.tsens_sample.saradc_tsens_sample_en = en;
}
/**
* @brief Configures the hardware sampling rate
*
* @param rate sampling rate
*/
static inline void temperature_sensor_ll_set_sample_rate(uint16_t rate)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.tsens_sample, saradc_tsens_sample_rate, rate);
}
/**
* @brief Retrieve and calculate the temperature sensor calibration value.
*
* @return Temperature calibration value.
*/
static inline int temperature_sensor_ll_load_calib_param(void)
{
return 0; // IDF-15117
}
/**
* @brief Structure for temperature sensor related register values
*/
typedef struct {
uint32_t tsens_ctrl; // Temperature sensor control register (APB_SARADC_APB_TSENS_CTRL_REG)
uint32_t tsens_ctrl2; // Temperature sensor control register 2 (APB_SARADC_TSENS_CTRL2_REG)
uint32_t tsens_wake; // Temperature sensor wake register (APB_TSENS_WAKE_REG)
uint32_t tsens_sample; // Temperature sensor sample register (APB_TSENS_SAMPLE_REG)
} tsens_ll_reg_values_t;
/**
* @brief Read temperature sensor related ADC register values for backup
*
* @param reg_values Output parameter, pointer to structure for storing register values
*/
static inline void tsens_ll_backup_registers(tsens_ll_reg_values_t *reg_values)
{
reg_values->tsens_ctrl = APB_SARADC.saradc_apb_tsens_ctrl.val;
reg_values->tsens_ctrl2 = APB_SARADC.saradc_tsens_ctrl2.val;
reg_values->tsens_wake = APB_SARADC.tsens_wake.val;
reg_values->tsens_sample = APB_SARADC.tsens_sample.val;
}
/**
* @brief Restore temperature sensor related ADC register values from backup
*
* @param reg_values Input parameter, pointer to structure containing register values to restore
*/
static inline void tsens_ll_restore_registers(const tsens_ll_reg_values_t *reg_values)
{
APB_SARADC.saradc_apb_tsens_ctrl.val = reg_values->tsens_ctrl;
APB_SARADC.saradc_tsens_ctrl2.val = reg_values->tsens_ctrl2;
APB_SARADC.tsens_wake.val = reg_values->tsens_wake;
APB_SARADC.tsens_sample.val = reg_values->tsens_sample;
}
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,19 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "soc/regdma.h"
#include "hal/temperature_sensor_periph.h"
#include "soc/apb_saradc_reg.h"
const temperature_sensor_attribute_t temperature_sensor_attributes[TEMPERATURE_SENSOR_ATTR_RANGE_NUM] = {
/*Offset reg_val min max error */
{-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},
};
@@ -87,6 +87,10 @@ config SOC_USB_SERIAL_JTAG_SUPPORTED
bool
default y
config SOC_TEMP_SENSOR_SUPPORTED
bool
default y
config SOC_EFUSE_KEY_PURPOSE_FIELD
bool
default y
@@ -1155,6 +1159,18 @@ config SOC_RCC_IS_INDEPENDENT
bool
default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC
bool
default y
config SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL
bool
default y
config SOC_TEMPERATURE_SENSOR_INTR_SUPPORT
bool
default y
config SOC_TOUCH_SENSOR_VERSION
int
default 3
@@ -230,6 +230,22 @@ typedef enum {
PCNT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
} soc_periph_pcnt_clk_src_t;
//////////////////////////////////////////////////Temp Sensor///////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of Temperature Sensor
*/
#define SOC_TEMP_SENSOR_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of Temp Sensor clock source
*/
typedef enum {
TEMPERATURE_SENSOR_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
TEMPERATURE_SENSOR_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
TEMPERATURE_SENSOR_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
} soc_periph_temperature_sensor_clk_src_t;
///////////////////////////////////////////////////UART/////////////////////////////////////////////////////////////////
/**
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/
@@ -87,8 +87,9 @@ typedef enum {
ETS_SYSTIMER_TARGET0_INTR_SOURCE,
ETS_SYSTIMER_TARGET1_INTR_SOURCE,
ETS_SYSTIMER_TARGET2_INTR_SOURCE,
ETS_APB_ADC_INTR_SOURCE,
ETS_PWM0_INTR_SOURCE,
ETS_APB_ADC_INTR_SOURCE = 71,
ETS_TEMPERATURE_SENSOR_INTR_SOURCE = ETS_APB_ADC_INTR_SOURCE,
ETS_PWM0_INTR_SOURCE = 72,
ETS_PWM1_INTR_SOURCE,
ETS_PCNT_INTR_SOURCE,
ETS_PARL_IO_TX_INTR_SOURCE,
@@ -52,3 +52,7 @@
#define ADC_SAR1_ENCAL_GND_ADDR 0x8
#define ADC_SAR1_ENCAL_GND_ADDR_MSB 0x1
#define ADC_SAR1_ENCAL_GND_ADDR_LSB 0x1
#define I2C_SARADC_TSENS_DAC 0x6
#define I2C_SARADC_TSENS_DAC_MSB 0x3
#define I2C_SARADC_TSENS_DAC_LSB 0x0
@@ -53,7 +53,7 @@
#define SOC_ASYNC_MEMCPY_SUPPORTED 1
#define SOC_USB_OTG_SUPPORTED 1
#define SOC_USB_SERIAL_JTAG_SUPPORTED 1
// #define SOC_TEMP_SENSOR_SUPPORTED 1 // TODO: [ESP32H4] IDF-12404
#define SOC_TEMP_SENSOR_SUPPORTED 1
// #define SOC_SUPPORTS_SECURE_DL_MODE 1
#define SOC_EFUSE_KEY_PURPOSE_FIELD 1
#define SOC_EFUSE_SUPPORTED 1
@@ -508,9 +508,10 @@
#define SOC_RCC_IS_INDEPENDENT 1 /*!< Reset and Clock Control is independent, thanks to the PCR registers */
/*-------------------------- Temperature Sensor CAPS -------------------------------------*/
// #define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1)
// #define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)
// #define SOC_TEMPERATURE_SENSOR_INTR_SUPPORT (1)
#define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1)
#define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1)
#define SOC_TEMPERATURE_SENSOR_INTR_SUPPORT (1)
// #define SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION (1)
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
#define SOC_TOUCH_SENSOR_VERSION (3) /*!< Hardware version of touch sensor */
@@ -1,5 +1,5 @@
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | -------- |
# Temperature Sensor Example
@@ -1,5 +1,5 @@
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 |
| ----------------- | -------- | -------- | --------- | -------- | -------- |
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-P4 |
| ----------------- | -------- | -------- | --------- | -------- | -------- | -------- |
# Temperature Sensor Interrupt Example