Explorar el Código

feat(ana_cmpr): supported analog comparator on esp32p4

laokaiyao hace 2 años
padre
commit
a989ce4ab1

+ 20 - 6
components/driver/analog_comparator/ana_cmpr.c

@@ -35,6 +35,7 @@ struct ana_cmpr_t {
     bool                        is_enabled;         /*!< Whether the Analog comparator unit is enabled */
     ana_cmpr_event_callbacks_t  cbs;                /*!< The callback group that set by user */
     intr_handle_t               intr_handle;        /*!< Interrupt handle */
+    uint32_t                    intr_mask;          /*!< Interrupt mask */
     void                        *user_data;         /*!< User data that passed to the callbacks */
     uint32_t                    src_clk_freq_hz;    /*!< Source clock frequency of the Analog Comparator unit */
     esp_pm_lock_handle_t        pm_lock;            /*!< The Power Management lock that used to avoid unexpected power down of the clock domain */
@@ -76,7 +77,14 @@ static void IRAM_ATTR s_ana_cmpr_default_intr_handler(void *usr_data)
     analog_cmpr_ll_clear_intr(cmpr_handle->dev, status);
 
     /* Call the user callback function if it is specified and the corresponding event triggers*/
-    if (cmpr_handle->cbs.on_cross && (status & ANALOG_CMPR_LL_EVENT_CROSS)) {
+    if (cmpr_handle->cbs.on_cross && (status & cmpr_handle->intr_mask)) {
+#if SOC_ANA_CMPR_SUPPORT_MULTI_INTR
+        if (status & ANALOG_CMPR_LL_POS_CROSS_MASK(cmpr_handle->unit)) {
+            evt_data.cross_type = ANA_CMPR_CROSS_POS;
+        } else if (status & ANALOG_CMPR_LL_NEG_CROSS_MASK(cmpr_handle->unit)) {
+            evt_data.cross_type = ANA_CMPR_CROSS_NEG;
+        }
+#endif  // SOC_ANA_CMPR_SUPPORT_MULTI_INTR
         need_yield = cmpr_handle->cbs.on_cross(cmpr_handle, &evt_data, cmpr_handle->user_data);
     }
     if (need_yield) {
@@ -102,7 +110,7 @@ esp_err_t ana_cmpr_new_unit(const ana_cmpr_config_t *config, ana_cmpr_handle_t *
     ESP_RETURN_ON_FALSE(s_ana_cmpr[unit], ESP_ERR_NO_MEM, TAG, "no memory for analog comparator struct");
 
     /* Assign analog comparator unit */
-    s_ana_cmpr[unit]->dev = ANALOG_CMPR_LL_GET_HW();
+    s_ana_cmpr[unit]->dev = ANALOG_CMPR_LL_GET_HW(unit);
     s_ana_cmpr[unit]->ref_src = config->ref_src;
     s_ana_cmpr[unit]->is_enabled = false;
     s_ana_cmpr[unit]->pm_lock = NULL;
@@ -126,12 +134,15 @@ esp_err_t ana_cmpr_new_unit(const ana_cmpr_config_t *config, ana_cmpr_handle_t *
     /* Configure the register */
     portENTER_CRITICAL(&s_spinlock);
     analog_cmpr_ll_set_ref_source(s_ana_cmpr[unit]->dev, config->ref_src);
+#if !SOC_ANA_CMPR_SUPPORT_MULTI_INTR
     analog_cmpr_ll_set_cross_type(s_ana_cmpr[unit]->dev, config->cross_type);
+#endif  // SOC_ANA_CMPR_SUPPORT_MULTI_INTR
     portEXIT_CRITICAL(&s_spinlock);
 
     /* Allocate the interrupt, currently the interrupt source of Analog Comparator is shared with GPIO interrupt source */
-    ESP_GOTO_ON_ERROR(esp_intr_alloc_intrstatus(ETS_GPIO_INTR_SOURCE, ANA_CMPR_INTR_FLAG, (uint32_t)analog_cmpr_ll_get_intr_status_reg(s_ana_cmpr[unit]->dev),
-                      ANALOG_CMPR_LL_EVENT_CROSS, s_ana_cmpr_default_intr_handler, s_ana_cmpr[unit], &s_ana_cmpr[unit]->intr_handle),
+    s_ana_cmpr[unit]->intr_mask = analog_cmpr_ll_get_intr_mask_by_type(s_ana_cmpr[unit]->dev, config->cross_type);
+    ESP_GOTO_ON_ERROR(esp_intr_alloc_intrstatus(ana_cmpr_io_map[unit].intr_src, ANA_CMPR_INTR_FLAG, (uint32_t)analog_cmpr_ll_get_intr_status_reg(s_ana_cmpr[unit]->dev),
+                      s_ana_cmpr[unit]->intr_mask, s_ana_cmpr_default_intr_handler, s_ana_cmpr[unit], &s_ana_cmpr[unit]->intr_handle),
                       err, TAG, "allocate interrupt failed");
 
     if (config->ref_src == ANA_CMPR_REF_SRC_INTERNAL) {
@@ -224,7 +235,10 @@ esp_err_t ana_cmpr_set_cross_type(ana_cmpr_handle_t cmpr, ana_cmpr_cross_type_t
                             ESP_ERR_INVALID_ARG, TAG, "invalid cross type");
 
     portENTER_CRITICAL_SAFE(&s_spinlock);
+#if !SOC_ANA_CMPR_SUPPORT_MULTI_INTR
     analog_cmpr_ll_set_cross_type(cmpr->dev, cross_type);
+#endif
+    cmpr->intr_mask = analog_cmpr_ll_get_intr_mask_by_type(cmpr->dev, cross_type);
     portEXIT_CRITICAL_SAFE(&s_spinlock);
 
     ESP_EARLY_LOGD(TAG, "unit %d cross type updated to %d", (int)cmpr->unit, cross_type);
@@ -273,7 +287,7 @@ esp_err_t ana_cmpr_enable(ana_cmpr_handle_t cmpr)
 
     /* Enable the Analog Comparator */
     portENTER_CRITICAL(&s_spinlock);
-    analog_cmpr_ll_enable_intr(cmpr->dev, ANALOG_CMPR_LL_EVENT_CROSS, !!(cmpr->cbs.on_cross));
+    analog_cmpr_ll_enable_intr(cmpr->dev, cmpr->intr_mask, true);
     analog_cmpr_ll_enable(cmpr->dev, true);
     portEXIT_CRITICAL(&s_spinlock);
 
@@ -289,7 +303,7 @@ esp_err_t ana_cmpr_disable(ana_cmpr_handle_t cmpr)
                         "the analog comparator not enabled yet");
     /* Disable the Analog Comparator */
     portENTER_CRITICAL(&s_spinlock);
-    analog_cmpr_ll_enable_intr(cmpr->dev, ANALOG_CMPR_LL_EVENT_CROSS, false);
+    analog_cmpr_ll_enable_intr(cmpr->dev, cmpr->intr_mask, false);
     analog_cmpr_ll_enable(cmpr->dev, false);
     portEXIT_CRITICAL(&s_spinlock);
 

+ 4 - 1
components/driver/analog_comparator/include/driver/ana_cmpr_types.h

@@ -90,7 +90,10 @@ typedef int ana_cmpr_clk_src_t;
  *
  */
 typedef struct {
-    // No data for now
+#if SOC_ANA_CMPR_SUPPORT_MULTI_INTR
+    ana_cmpr_cross_type_t cross_type;   /*!< The cross type of the target signal to the reference signal.
+                                         *   Will either be ANA_CMPR_CROSS_POS or ANA_CMPR_CROSS_NEG */
+#endif
 } ana_cmpr_cross_event_data_t;
 
 /**

+ 19 - 4
components/hal/esp32h2/include/hal/ana_cmpr_ll.h

@@ -11,12 +11,9 @@
 #include "hal/assert.h"
 #include "soc/gpio_ext_struct.h"
 
-#define ANALOG_CMPR_LL_GET_HW()         (&ANALOG_CMPR)
+#define ANALOG_CMPR_LL_GET_HW(unit)     (&ANALOG_CMPR)
 #define ANALOG_CMPR_LL_EVENT_CROSS      (1 << 0)
 
-#define ANALOG_CMPR_LL_POS_CROSS_MASK   (1 << 1)
-#define ANALOG_CMPR_LL_NEG_CROSS_MASK   (1 << 2)
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -84,6 +81,24 @@ static inline void analog_cmpr_ll_set_cross_type(analog_cmpr_dev_t *hw, uint8_t
     hw->pad_comp_config.zero_det_mode = type;
 }
 
+/**
+ * @brief Get the interrupt mask by trigger type
+ * @note  Only one interrupt on H2
+ *
+ * @param hw Analog comparator register base address
+ * @param type The type of cross interrupt
+ *              - 0: disable interrupt
+ *              - 1: enable positive cross interrupt (input analog goes from low to high and across the reference voltage)
+ *              - 2: enable negative cross interrupt (input analog goes from high to low and across the reference voltage)
+ *              - 3: enable any positive or negative cross interrupt
+ * @return interrupt mask
+ */
+__attribute__((always_inline))
+static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(analog_cmpr_dev_t *hw, uint8_t type)
+{
+    return ANALOG_CMPR_LL_EVENT_CROSS;
+}
+
 /**
  * @brief Set the debounce cycle for the cross detection
  *

+ 163 - 0
components/hal/esp32p4/include/hal/ana_cmpr_ll.h

@@ -0,0 +1,163 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include "hal/misc.h"
+#include "hal/assert.h"
+#include "soc/ana_cmpr_struct.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ANALOG_CMPR_LL_GET_HW(unit)     (&ANALOG_CMPR[unit])
+#define ANALOG_CMPR_LL_GET_UNIT(hw)     ((hw) == (&ANALOG_CMPR[0]) ? 0 : 1)
+#define ANALOG_CMPR_LL_EVENT_CROSS      (1 << 0)
+
+#define ANALOG_CMPR_LL_NEG_CROSS_MASK(unit)   (1UL << ((int)unit * 3))
+#define ANALOG_CMPR_LL_POS_CROSS_MASK(unit)   (1UL << ((int)unit * 3 + 1))
+
+/**
+ * @brief Enable analog comparator
+ *
+ * @param hw Analog comparator register base address
+ * @param en True to enable, False to disable
+ */
+static inline void analog_cmpr_ll_enable(analog_cmpr_dev_t *hw, bool en)
+{
+    hw->pad_comp_config->xpd_comp = en;
+}
+
+/**
+ * @brief Set the voltage of the internal reference
+ *
+ * @param hw Analog comparator register base address
+ * @param volt_level The voltage level of the internal reference, range [0.0V, 0.7VDD], step 0.1VDD
+ */
+__attribute__((always_inline))
+static inline void analog_cmpr_ll_set_internal_ref_voltage(analog_cmpr_dev_t *hw, uint32_t volt_level)
+{
+    hw->pad_comp_config->dref_comp = volt_level;
+}
+
+/**
+ * @brief Get the voltage of the internal reference
+ *
+ * @param hw Analog comparator register base address
+ * @return The voltage of the internal reference
+ */
+static inline float analog_cmpr_ll_get_internal_ref_voltage(analog_cmpr_dev_t *hw)
+{
+    return hw->pad_comp_config->dref_comp * 0.1F;
+}
+
+/**
+ * @brief The reference voltage comes from internal or external
+ *
+ * @note Also see `analog_cmpr_ll_set_internal_ref_voltage` to use the internal reference voltage
+ *
+ * @param hw Analog comparator register base address
+ * @param ref_src reference source, 0 for internal, 1 for external GPIO pad (GPIO10)
+ */
+static inline void analog_cmpr_ll_set_ref_source(analog_cmpr_dev_t *hw, uint32_t ref_src)
+{
+    hw->pad_comp_config->mode_comp = ref_src;
+}
+
+/**
+ * @brief Get the interrupt mask by trigger type
+ *
+ * @param hw Analog comparator register base address
+ * @param type The type of cross interrupt
+ *              - 0: disable interrupt
+ *              - 1: enable positive cross interrupt (input analog goes from low to high and across the reference voltage)
+ *              - 2: enable negative cross interrupt (input analog goes from high to low and across the reference voltage)
+ *              - 3: enable any positive or negative cross interrupt
+ * @return interrupt mask
+ */
+__attribute__((always_inline))
+static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(analog_cmpr_dev_t *hw, uint8_t type)
+{
+    uint32_t unit = ANALOG_CMPR_LL_GET_UNIT(hw);
+    uint32_t mask = 0;
+    if (type & 0x01) {
+        mask |= ANALOG_CMPR_LL_POS_CROSS_MASK(unit);
+    }
+    if (type & 0x02) {
+        mask |= ANALOG_CMPR_LL_POS_CROSS_MASK(unit);
+    }
+    return mask;
+}
+
+/**
+ * @brief Set the debounce cycle for the cross detection
+ *
+ * @note When the comparator detects a cross, it will wait for the debounce cycle to make sure the cross is stable.
+ *
+ * @param hw Analog comparator register base address
+ * @param cycle The debounce cycle
+ */
+__attribute__((always_inline))
+static inline void analog_cmpr_ll_set_debounce_cycle(analog_cmpr_dev_t *hw, uint32_t cycle)
+{
+    hw->pad_comp_filter->zero_det_filter_cnt = cycle;
+}
+
+/**
+ * @brief Enable comparator interrupt
+ *
+ * @param hw Analog comparator register base address
+ * @param mask Interrupt mask
+ * @param enable True to enable, False to disable
+ */
+static inline void analog_cmpr_ll_enable_intr(analog_cmpr_dev_t *hw, uint32_t mask, bool enable)
+{
+    if (enable) {
+        hw->int_ena->val |= mask;
+    } else {
+        hw->int_ena->val &= ~mask;
+    }
+}
+
+/**
+ * @brief Get comparator interrupt status
+ *
+ * @param hw Analog comparator register base address
+ */
+__attribute__((always_inline))
+static inline uint32_t analog_cmpr_ll_get_intr_status(analog_cmpr_dev_t *hw)
+{
+    return hw->int_st->val;
+}
+
+/**
+ * @brief Clear comparator interrupt status
+ *
+ * @param hw Analog comparator register base address
+ * @param mask Interrupt status word
+ */
+__attribute__((always_inline))
+static inline void analog_cmpr_ll_clear_intr(analog_cmpr_dev_t *hw, uint32_t mask)
+{
+    hw->int_clr->val = mask;
+}
+
+/**
+ * @brief Get the interrupt status register address
+ *
+ * @param hw Analog comparator register base address
+ * @return The interrupt status register address
+ */
+static inline volatile void *analog_cmpr_ll_get_intr_status_reg(analog_cmpr_dev_t *hw)
+{
+    return hw->int_st;
+}
+
+#ifdef __cplusplus
+}
+#endif

+ 1 - 0
components/soc/esp32h2/ana_cmpr_periph.c

@@ -10,5 +10,6 @@ const ana_cmpr_conn_t ana_cmpr_io_map[SOC_ANA_CMPR_NUM] = {
     [0] = {
         .src_gpio = ANA_CMPR0_SRC_GPIO,
         .ext_ref_gpio = ANA_CMPR0_EXT_REF_GPIO,
+        .intr_src = ETS_GPIO_INTR_SOURCE,
     },
 };

+ 38 - 0
components/soc/esp32p4/ana_cmpr_periph.c

@@ -0,0 +1,38 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "soc/ana_cmpr_periph.h"
+#include "soc/ana_cmpr_struct.h"
+
+const ana_cmpr_conn_t ana_cmpr_io_map[SOC_ANA_CMPR_NUM] = {
+    [0] = {
+        .src_gpio = ANA_CMPR0_SRC_GPIO,
+        .ext_ref_gpio = ANA_CMPR0_EXT_REF_GPIO,
+        .intr_src = ETS_GPIO_PAD_COMP_INTR_SOURCE,
+    },
+    [1] = {
+        .src_gpio = ANA_CMPR1_SRC_GPIO,
+        .ext_ref_gpio = ANA_CMPR1_EXT_REF_GPIO,
+        .intr_src = ETS_GPIO_PAD_COMP_INTR_SOURCE,
+    },
+};
+
+analog_cmpr_dev_t ANALOG_CMPR[SOC_ANA_CMPR_NUM] = {
+    [0] = {
+        .pad_comp_config = &LP_SYS.pad_comp[0],
+        .pad_comp_filter = &GPIO.zero_det_filter_cnt[0],
+        .int_st = &GPIO.int_st,
+        .int_ena = &GPIO.int_ena,
+        .int_clr = &GPIO.int_clr,
+    },
+    [1] = {
+        .pad_comp_config = &LP_SYS.pad_comp[1],
+        .pad_comp_filter = &GPIO.zero_det_filter_cnt[1],
+        .int_st = &GPIO.int_st,
+        .int_ena = &GPIO.int_ena,
+        .int_clr = &GPIO.int_clr,
+    },
+};

+ 12 - 0
components/soc/esp32p4/include/soc/Kconfig.soc_caps.in

@@ -3,6 +3,10 @@
 # using gen_soc_caps_kconfig.py, do not edit manually
 #####################################################
 
+config SOC_ANA_CMPR_SUPPORTED
+    bool
+    default y
+
 config SOC_UART_SUPPORTED
     bool
     default y
@@ -383,6 +387,14 @@ config SOC_DEDIC_PERIPH_ALWAYS_ENABLE
     bool
     default y
 
+config SOC_ANA_CMPR_NUM
+    int
+    default 2
+
+config SOC_ANA_CMPR_SUPPORT_MULTI_INTR
+    bool
+    default y
+
 config SOC_I2C_NUM
     int
     default 2

+ 12 - 0
components/soc/esp32p4/include/soc/ana_cmpr_channel.h

@@ -0,0 +1,12 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#define ANA_CMPR0_EXT_REF_GPIO    51      /*!< The GPIO that can be used as external reference voltage */
+#define ANA_CMPR0_SRC_GPIO        52      /*!< The GPIO that used for inputting the source signal to compare */
+#define ANA_CMPR1_EXT_REF_GPIO    53      /*!< The GPIO that can be used as external reference voltage */
+#define ANA_CMPR1_SRC_GPIO        54      /*!< The GPIO that used for inputting the source signal to compare */

+ 37 - 0
components/soc/esp32p4/include/soc/ana_cmpr_struct.h

@@ -0,0 +1,37 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ */
+
+/* NOTE: this file is created manually for compatibility */
+
+#pragma once
+
+#include <stdint.h>
+#include "soc/gpio_struct.h"
+#include "soc/lp_system_struct.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief The Analog Comparator Device struct
+ * @note  The field in it are register pointers, which point to the physical address
+ *        of the corresponding configuration register
+ * @note  see 'ana_cmpr_periph.c' for the device instance
+ */
+typedef struct {
+    volatile lp_system_reg_pad_comp_reg_t *pad_comp_config;
+    volatile gpio_zero_det_filter_cnt_reg_t *pad_comp_filter;
+    volatile gpio_int_st_reg_t *int_st;
+    volatile gpio_int_ena_reg_t *int_ena;
+    volatile gpio_int_clr_reg_t *int_clr;
+} analog_cmpr_dev_t;
+
+extern analog_cmpr_dev_t ANALOG_CMPR[2];
+
+#ifdef __cplusplus
+}
+#endif

+ 16 - 0
components/soc/esp32p4/include/soc/clk_tree_defs.h

@@ -405,6 +405,22 @@ typedef enum {
 
 //////////////////////////////////////////////////GPIO Glitch Filter////////////////////////////////////////////////////
 
+///////////////////////////////////////////////////Analog Comparator////////////////////////////////////////////////////
+
+/**
+ * @brief Array initializer for all supported clock sources of Analog Comparator
+ */
+#define SOC_ANA_CMPR_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL}
+
+/**
+ * @brief Sigma Delta Modulator clock source
+ */
+typedef enum {
+    ANA_CMPR_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,                   /*!< Select XTAL clock as the source clock */
+    ANA_CMPR_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M,           /*!< Select PLL_F80M clock as the source clock */
+    ANA_CMPR_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M,            /*!< Select PLL_F80M as the default clock choice */
+} soc_periph_ana_cmpr_clk_src_t;
+
 //////////////////////////////////////////////////TWAI//////////////////////////////////////////////////////////////////
 
 //////////////////////////////////////////////////ADC///////////////////////////////////////////////////////////////////

+ 4 - 18
components/soc/esp32p4/include/soc/gpio_struct.h

@@ -558,26 +558,13 @@ typedef union {
  */
 typedef union {
     struct {
-        /** zero_det0_filter_cnt : R/W; bitpos: [31:0]; default: 4294967295;
+        /** zero_det_filter_cnt : R/W; bitpos: [31:0]; default: 4294967295;
          *  GPIO analog comparator zero detect filter count
          */
-        uint32_t zero_det0_filter_cnt:32;
+        uint32_t zero_det_filter_cnt:32;
     };
     uint32_t val;
-} gpio_zero_det0_filter_cnt_reg_t;
-
-/** Type of zero_det1_filter_cnt register
- *  GPIO analog comparator zero detect filter count
- */
-typedef union {
-    struct {
-        /** zero_det1_filter_cnt : R/W; bitpos: [31:0]; default: 4294967295;
-         *  GPIO analog comparator zero detect filter count
-         */
-        uint32_t zero_det1_filter_cnt:32;
-    };
-    uint32_t val;
-} gpio_zero_det1_filter_cnt_reg_t;
+} gpio_zero_det_filter_cnt_reg_t;
 
 /** Type of send_seq register
  *  High speed sdio pad bist send sequence
@@ -871,8 +858,7 @@ typedef struct gpio_dev_t {
     volatile gpio_int_st_reg_t int_st;
     volatile gpio_int_ena_reg_t int_ena;
     volatile gpio_int_clr_reg_t int_clr;
-    volatile gpio_zero_det0_filter_cnt_reg_t zero_det0_filter_cnt;
-    volatile gpio_zero_det1_filter_cnt_reg_t zero_det1_filter_cnt;
+    volatile gpio_zero_det_filter_cnt_reg_t zero_det_filter_cnt[2];
     volatile gpio_send_seq_reg_t send_seq;
     volatile gpio_recive_seq_reg_t recive_seq;
     volatile gpio_bistin_sel_reg_t bistin_sel;

+ 9 - 31
components/soc/esp32p4/include/soc/lp_system_struct.h

@@ -677,44 +677,22 @@ typedef union {
  */
 typedef union {
     struct {
-        /** dref_comp0 : R/W; bitpos: [2:0]; default: 0;
+        /** dref_comp : R/W; bitpos: [2:0]; default: 0;
          *  pad comp dref
          */
-        uint32_t dref_comp0:3;
-        /** mode_comp0 : R/W; bitpos: [3]; default: 0;
+        uint32_t dref_comp:3;
+        /** mode_comp : R/W; bitpos: [3]; default: 0;
          *  pad comp mode
          */
-        uint32_t mode_comp0:1;
-        /** xpd_comp0 : R/W; bitpos: [4]; default: 0;
+        uint32_t mode_comp:1;
+        /** xpd_comp : R/W; bitpos: [4]; default: 0;
          *  pad comp xpd
          */
-        uint32_t xpd_comp0:1;
+        uint32_t xpd_comp:1;
         uint32_t reserved_5:27;
     };
     uint32_t val;
-} lp_system_reg_pad_comp0_reg_t;
-
-/** Type of pad_comp1 register
- *  need_des
- */
-typedef union {
-    struct {
-        /** dref_comp1 : R/W; bitpos: [2:0]; default: 0;
-         *  pad comp dref
-         */
-        uint32_t dref_comp1:3;
-        /** mode_comp1 : R/W; bitpos: [3]; default: 0;
-         *  pad comp mode
-         */
-        uint32_t mode_comp1:1;
-        /** xpd_comp1 : R/W; bitpos: [4]; default: 0;
-         *  pad comp xpd
-         */
-        uint32_t xpd_comp1:1;
-        uint32_t reserved_5:27;
-    };
-    uint32_t val;
-} lp_system_reg_pad_comp1_reg_t;
+} lp_system_reg_pad_comp_reg_t;
 
 /** Type of backup_dma_cfg0 register
  *  need_des
@@ -1291,8 +1269,7 @@ typedef struct {
     volatile lp_system_reg_lp_pmu_rdn_eco_low_reg_t lp_pmu_rdn_eco_low;
     volatile lp_system_reg_lp_pmu_rdn_eco_high_reg_t lp_pmu_rdn_eco_high;
     uint32_t reserved_140[2];
-    volatile lp_system_reg_pad_comp0_reg_t pad_comp0;
-    volatile lp_system_reg_pad_comp1_reg_t pad_comp1;
+    volatile lp_system_reg_pad_comp_reg_t pad_comp[2];
     uint32_t reserved_150;
     volatile lp_system_reg_backup_dma_cfg0_reg_t backup_dma_cfg0;
     volatile lp_system_reg_backup_dma_cfg1_reg_t backup_dma_cfg1;
@@ -1323,6 +1300,7 @@ typedef struct {
     volatile lp_system_reg_rng_cfg_reg_t rng_cfg;
 } lp_system_reg_dev_t;
 
+extern lp_system_reg_dev_t LP_SYS;
 
 #ifndef __cplusplus
 _Static_assert(sizeof(lp_system_reg_dev_t) == 0x1c4, "Invalid size of lp_system_reg_dev_t structure");

+ 5 - 1
components/soc/esp32p4/include/soc/soc_caps.h

@@ -26,7 +26,7 @@
 
 /*-------------------------- COMMON CAPS ---------------------------------------*/
 // #define SOC_ADC_SUPPORTED               1  //TODO: IDF-6496
-// #define SOC_ANA_CMPR_SUPPORTED          1  //TODO: IDF-7479
+#define SOC_ANA_CMPR_SUPPORTED          1
 // #define SOC_DEDICATED_GPIO_SUPPORTED    1  //TODO: IDF-7552
 #define SOC_UART_SUPPORTED              1
 #define SOC_GDMA_SUPPORTED              1
@@ -220,6 +220,10 @@
 #define SOC_DEDIC_GPIO_IN_CHANNELS_NUM  (8) /*!< 8 inward channels on each CPU core */
 #define SOC_DEDIC_PERIPH_ALWAYS_ENABLE  (1) /*!< The dedicated GPIO (a.k.a. fast GPIO) is featured by some customized CPU instructions, which is always enabled */
 
+/*------------------------- Analog Comparator CAPS ---------------------------*/
+#define SOC_ANA_CMPR_NUM                (2U)
+#define SOC_ANA_CMPR_SUPPORT_MULTI_INTR (1)
+
 /*-------------------------- I2C CAPS ----------------------------------------*/
 // ESP32-P4 has 2 I2Cs
 #define SOC_I2C_NUM                 (2U)

+ 1 - 0
components/soc/esp32p4/ld/esp32p4.peripherals.ld

@@ -65,6 +65,7 @@ PROVIDE ( TEE               = 0x60098000 ); /* TODO: IDF-7542 */
 PROVIDE ( HP_APM            = 0x60099000 ); /* TODO: IDF-7542 */
 
 PROVIDE ( PMU           = 0x50115000 );
+PROVIDE ( LP_SYS        = 0x50110000 );
 PROVIDE ( LP_AON_CLKRST = 0x50111000 );
 PROVIDE ( EFUSE         = 0x5012D000 );
 PROVIDE ( LP_TIMER      = 0x50112000 );

+ 2 - 0
components/soc/include/soc/ana_cmpr_periph.h

@@ -8,6 +8,7 @@
 
 #include <stdint.h>
 #include "soc/soc_caps.h"
+#include "soc/periph_defs.h"
 #if SOC_ANA_CMPR_SUPPORTED
 #include "soc/ana_cmpr_channel.h"
 #endif
@@ -20,6 +21,7 @@ extern "C" {
 typedef struct {
     int src_gpio;
     int ext_ref_gpio;
+    int intr_src;
 } ana_cmpr_conn_t;
 
 extern const ana_cmpr_conn_t ana_cmpr_io_map[SOC_ANA_CMPR_NUM];

+ 26 - 5
docs/en/api-reference/peripherals/ana_cmpr.rst

@@ -1,9 +1,11 @@
 Analog Comparator
 =================
 
-{IDF_TARGET_ANA_CMPR_NUM: default="NOT UPDATED", esp32h2="one"}
-{IDF_TARGET_ANA_CMPR_SRC_CHAN: default="NOT UPDATED", esp32h2="GPIO11"}
-{IDF_TARGET_ANA_CMPR_EXT_REF_CHAN: default="NOT UPDATED", esp32h2="GPIO10"}
+{IDF_TARGET_ANA_CMPR_NUM: default="NOT UPDATED", esp32h2="one", esp32p4="two"}
+{IDF_TARGET_ANA_CMPR_SRC_CHAN0: default="NOT UPDATED", esp32h2="GPIO11", esp32p4="GPIO52"}
+{IDF_TARGET_ANA_CMPR_EXT_REF_CHAN0: default="NOT UPDATED", esp32h2="GPIO10", esp32p4="GPIO51"}
+{IDF_TARGET_ANA_CMPR_SRC_CHAN1: default="NOT UPDATED", esp32p4="GPIO54"}
+{IDF_TARGET_ANA_CMPR_EXT_REF_CHAN1: default="NOT UPDATED", esp32p4="GPIO53"}
 
 Introduction
 ------------
@@ -16,10 +18,18 @@ Analog Comparator on {IDF_TARGET_NAME} has {IDF_TARGET_ANA_CMPR_NUM} unit(s), th
 
 **UNIT0**
 
-- Source Channel: {IDF_TARGET_ANA_CMPR_SRC_CHAN}
-- External Reference Channel: {IDF_TARGET_ANA_CMPR_EXT_REF_CHAN}
+- Source Channel: {IDF_TARGET_ANA_CMPR_SRC_CHAN0}
+- External Reference Channel: {IDF_TARGET_ANA_CMPR_EXT_REF_CHAN0}
 - Internal Reference Channel: Range 0% ~ 70% VDD, step 10% VDD
 
+.. only:: esp32p4
+
+    **UNIT1**
+
+    - Source Channel: {IDF_TARGET_ANA_CMPR_SRC_CHAN1}
+    - External Reference Channel: {IDF_TARGET_ANA_CMPR_EXT_REF_CHAN1}
+    - Internal Reference Channel: Range 0% ~ 70% VDD, step 10% VDD
+
 Functional Overview
 -------------------
 
@@ -33,6 +43,10 @@ The following sections of this document cover the typical steps to install and o
 -  `Thread Safety <#thread-safety>`__ - lists which APIs are guaranteed to be thread safe by the driver.
 -  `Kconfig Options <#kconfig-options>`__ - lists the supported Kconfig options that can be used to make a different effect on driver behavior.
 
+.. only:: SOC_ANA_CMPR_SUPPORT_ETM
+
+    - `ETM Events <#etm-events>`__ -
+
 Resource Allocation
 ^^^^^^^^^^^^^^^^^^^
 
@@ -180,6 +194,13 @@ Kconfig Options
 - :ref:`CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM` controls where to place the Analog Comparator control functions (IRAM or Flash), see `IRAM Safe <#iram-safe>`__ for more information.
 - :ref:`CONFIG_ANA_CMPR_ENABLE_DEBUG_LOG` is used to enabled the debug log output. Enabling this option increases the firmware binary size.
 
+.. only:: SOC_ANA_CMPR_SUPPORT_ETM
+
+    ETM Events
+    ^^^^^^^^^^
+
+    To create an analog comparator cross event, you need to include ``driver/ana_cmpr_etm.h`` additionally, and allocate the event by :cpp:func:`ana_cmpr_new_etm_event`. You can refer to :doc:`GPTimer </api-reference/peripherals/etm>` for how to connect an event to a task.
+
 Application Example
 -------------------
 

+ 4 - 0
docs/en/api-reference/peripherals/etm.rst

@@ -71,6 +71,10 @@ Other Peripheral Events
     :SOC_GDMA_SUPPORT_ETM: - Refer to :doc:`/api-reference/system/async_memcpy` for how to get the ETM event handle from async memcpy.
     :SOC_MCPWM_SUPPORT_ETM: - Refer to :doc:`/api-reference/peripherals/mcpwm` for how to get the ETM event handle from MCPWM.
 
+    .. only:: esp32p4
+
+        :SOC_ANA_CMPR_SUPPORT_ETM: - Refer to :doc:`/api-reference/peripherals/ana_cmpr` for how to get the ETM event handle from analog comparator.
+
 .. _etm-task:
 
 ETM Task

+ 4 - 0
docs/zh_CN/api-reference/peripherals/etm.rst

@@ -71,6 +71,10 @@ GPIO **边沿** 事件是最常见的事件类型,任何 GPIO 管脚均可触
     :SOC_GDMA_SUPPORT_ETM: - 要了解如何从 async memcpy 获取 ETM 事件句柄,请参阅 :doc:`/api-reference/system/async_memcpy`。
     :SOC_MCPWM_SUPPORT_ETM: - 要了解如何从 MCPWM 中获取 ETM 事件句柄,请参阅 :doc:`/api-reference/peripherals/mcpwm`。
 
+    .. only:: esp32p4
+
+        :SOC_ANA_CMPR_SUPPORT_ETM: - 要了解如何从模拟比较器获取 ETM 事件句柄,请参阅 :doc:`/api-reference/peripherals/ana_cmpr`。
+
 .. _etm-task:
 
 ETM 任务