Merge branch 'feat/ana_cmpr_esp32h4_eco1' into 'master'

feat(ana_cmpr): enable ana_cmpr driver support on esp32h4

Closes IDF-12395 and IDF-15224

See merge request espressif/esp-idf!48316
This commit is contained in:
morris
2026-05-21 14:01:03 +08:00
8 changed files with 46 additions and 26 deletions

View File

@@ -1,2 +1,2 @@
| Supported Targets | ESP32-C5 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S31 |
| ----------------- | -------- | --------- | -------- | --------- | -------- | --------- |
| Supported Targets | ESP32-C5 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S31 |
| ----------------- | -------- | --------- | -------- | --------- | -------- | -------- | --------- |

View File

@@ -235,7 +235,6 @@ TEST_CASE("ana_cmpr trigger scan step mode", "[ana_cmpr]")
config.cross_type = ANA_CMPR_CROSS_ANY;
config.src_chan0_gpio = test_pad_gpio_num(ana_cmpr_periph[TEST_ANA_CMPR_UNIT_ID].pad_gpios[0]);
config.ext_ref_gpio = GPIO_NUM_NC;
config.resample_limit = 3;
TEST_ESP_OK(ana_cmpr_new_unit(&config, &cmpr));
ana_cmpr_src_chan_config_t src_cfg = {};
@@ -350,8 +349,12 @@ TEST_CASE("ana_cmpr capture timestamps", "[ana_cmpr]")
uint32_t delta_us = (uint32_t)(((uint64_t)delta_ticks * 1000000U) / resolution_hz);
printf("ana_cmpr capture timestamps: current=%" PRIu32 ", previous=%" PRIu32 ", delta_ticks=%" PRIu32 ", delta_us=%" PRIu32 "\r\n",
current, previous, delta_ticks, delta_us);
#if CONFIG_IDF_TARGET_ESP32H4
TEST_ASSERT_UINT_WITHIN(50, 100, delta_us);
#else
// We insert ~100 us delay between two trigger_scan() calls.
TEST_ASSERT_UINT_WITHIN(20, 100, delta_us);
#endif
TEST_ESP_OK(ana_cmpr_disable(cmpr));
TEST_ESP_OK(ana_cmpr_del_unit(cmpr));

View File

@@ -16,6 +16,7 @@
#include "soc/pcr_struct.h"
#include "soc/soc_etm_struct.h"
#include "soc/soc_etm_source.h"
#include "esp_rom_sys.h"
#ifdef __cplusplus
extern "C" {
@@ -42,6 +43,9 @@ typedef zero_det_dev_t analog_cmpr_dev_t;
// Can detect positive/negative/any cross type
#define ANALOG_CMPR_LL_SUPPORT_EDGE_SPECIFIC_INTR_MASK 1
// Support software trigger channel scan
#define ANALOG_CMPR_LL_SUPPORT_SW_SCAN 1
#define ANALOG_CMPR_LL_GET_HW(unit) (&ZERO_DET)
#define ANALOG_CMPR_LL_NEG_CROSS_INTR_MASK(unit, src_chan) (1UL << ((2 - (src_chan)) * 3 + 0))
@@ -111,17 +115,6 @@ static inline void analog_cmpr_ll_set_clk_src(int unit_id, ana_cmpr_clk_src_t cl
}
}
/**
* @brief Enable the function clock for Analog Comparator module
*
* @param unit_id Unit ID
* @param enable true to enable, false to disable
*/
static inline void analog_cmpr_ll_enable_function_clock(int unit_id, bool enable)
{
PCR.zero_det_clk_conf.zero_det_func_clk_en = enable;
}
/**
* @brief Set the clock divider for analog comparator PAD_COMP_CLK
*
@@ -135,6 +128,17 @@ static inline void analog_cmpr_ll_set_clk_div(int unit_id, uint32_t div)
(void)div;
}
/**
* @brief Enable the function clock for Analog Comparator module
*
* @param unit_id Unit ID
* @param enable true to enable, false to disable
*/
static inline void analog_cmpr_ll_enable_function_clock(int unit_id, bool enable)
{
PCR.zero_det_clk_conf.zero_det_func_clk_en = enable;
}
/**
* @brief Get the interrupt mask from the given cross type
*
@@ -343,13 +347,17 @@ static inline void analog_cmpr_ll_set_scan_mode(analog_cmpr_dev_t *hw, ana_cmpr_
__attribute__((always_inline))
static inline void analog_cmpr_ll_start_scan(analog_cmpr_dev_t *dev)
{
(void)dev;
// enable ETM register clock
PCR.etm_conf.etm_clk_en = 1;
while (PCR.etm_conf.etm_ready == 0) {
}
int trigger_times = dev->det_conf.det_limit_cnt;
// use reg_etm_date[31] register to trigger analog comparator to start
SOC_ETM.etm_date.val |= 1UL << 31;
while (trigger_times--) {
SOC_ETM.etm_date.val |= 1UL << 31;
esp_rom_delay_us(10);
}
}
/**
@@ -374,6 +382,7 @@ static inline void analog_cmpr_ll_set_poll_period(analog_cmpr_dev_t *hw, uint32_
*/
static inline void analog_cmpr_ll_set_resample_limit(analog_cmpr_dev_t *hw, uint8_t limit_cnt)
{
limit_cnt = MAX(limit_cnt, 1);
hw->det_conf.det_limit_cnt = limit_cnt;
}

View File

@@ -370,6 +370,7 @@ static inline void analog_cmpr_ll_set_poll_period(analog_cmpr_dev_t *hw, uint32_
*/
static inline void analog_cmpr_ll_set_resample_limit(analog_cmpr_dev_t *hw, uint8_t limit_cnt)
{
limit_cnt = MAX(limit_cnt, 1);
hw->conf.limit_cnt = limit_cnt;
}

View File

@@ -7,6 +7,10 @@ config SOC_ADC_SUPPORTED
bool
default y
config SOC_ANA_CMPR_SUPPORTED
bool
default y
config SOC_DEDICATED_GPIO_SUPPORTED
bool
default y
@@ -347,6 +351,14 @@ config SOC_APB_BACKUP_DMA
bool
default n
config SOC_ANA_CMPR_SUPPORT_ETM
bool
default y
config SOC_ANA_CMPR_SUPPORT_ETM_SCAN
bool
default y
config SOC_CACHE_WRITEBACK_SUPPORTED
bool
default y

View File

@@ -32,7 +32,7 @@
/*-------------------------- COMMON CAPS ---------------------------------------*/
#define SOC_ADC_SUPPORTED 1
// #define SOC_ANA_CMPR_SUPPORTED 1
#define SOC_ANA_CMPR_SUPPORTED 1
#define SOC_DEDICATED_GPIO_SUPPORTED 1
#define SOC_UART_SUPPORTED 1
#define SOC_UHCI_SUPPORTED 1
@@ -153,8 +153,8 @@
#define SOC_APB_BACKUP_DMA (0)
/*------------------------- Analog Comparator CAPS ---------------------------*/
// #define SOC_ANA_CMPR_SUPPORT_ETM (1)
// #define SOC_ANA_CMPR_SUPPORT_ETM_SCAN (1)
#define SOC_ANA_CMPR_SUPPORT_ETM (1)
#define SOC_ANA_CMPR_SUPPORT_ETM_SCAN (1)
/*-------------------------- BROWNOUT CAPS -----------------------------------*/
// #define SOC_BROWNOUT_RESET_SUPPORTED 1

View File

@@ -1,5 +1,5 @@
| Supported Targets | ESP32-S31 |
| ----------------- | --------- |
| Supported Targets | ESP32-H4 | ESP32-S31 |
| ----------------- | -------- | --------- |
# Analog Comparator ETM Periodic Scan Example

View File

@@ -189,11 +189,6 @@ void app_main(void)
example_init_etm(cmpr, gptimer);
ESP_ERROR_CHECK(ana_cmpr_enable(cmpr));
/* Run one software-triggered scan before the periodic timer starts.
* This gives the comparator an initial result immediately, instead of waiting for the first timer alarm. */
ESP_ERROR_CHECK(ana_cmpr_trigger_scan(cmpr));
vTaskDelay(pdMS_TO_TICKS(10));
/* After the timer starts, future scans are launched by ETM rather than by CPU code. */
ESP_ERROR_CHECK(gptimer_start(gptimer));
ESP_LOGI(TAG, "Periodic ETM-driven comparator scan started");