From a989ce4ab13a058f3cff36427a0fa32fa64e71b0 Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Tue, 18 Jul 2023 20:08:22 +0800 Subject: [PATCH] feat(ana_cmpr): supported analog comparator on esp32p4 --- .../driver/analog_comparator/ana_cmpr.c | 26 ++- .../include/driver/ana_cmpr_types.h | 5 +- .../hal/esp32h2/include/hal/ana_cmpr_ll.h | 23 ++- .../hal/esp32p4/include/hal/ana_cmpr_ll.h | 163 ++++++++++++++++++ components/soc/esp32h2/ana_cmpr_periph.c | 1 + components/soc/esp32p4/ana_cmpr_periph.c | 38 ++++ .../esp32p4/include/soc/Kconfig.soc_caps.in | 12 ++ .../esp32p4/include/soc/ana_cmpr_channel.h | 12 ++ .../soc/esp32p4/include/soc/ana_cmpr_struct.h | 37 ++++ .../soc/esp32p4/include/soc/clk_tree_defs.h | 16 ++ .../soc/esp32p4/include/soc/gpio_struct.h | 22 +-- .../esp32p4/include/soc/lp_system_struct.h | 40 +---- components/soc/esp32p4/include/soc/soc_caps.h | 6 +- .../soc/esp32p4/ld/esp32p4.peripherals.ld | 1 + components/soc/include/soc/ana_cmpr_periph.h | 2 + .../en/api-reference/peripherals/ana_cmpr.rst | 31 +++- docs/en/api-reference/peripherals/etm.rst | 4 + docs/zh_CN/api-reference/peripherals/etm.rst | 4 + 18 files changed, 377 insertions(+), 66 deletions(-) create mode 100644 components/hal/esp32p4/include/hal/ana_cmpr_ll.h create mode 100644 components/soc/esp32p4/ana_cmpr_periph.c create mode 100644 components/soc/esp32p4/include/soc/ana_cmpr_channel.h create mode 100644 components/soc/esp32p4/include/soc/ana_cmpr_struct.h diff --git a/components/driver/analog_comparator/ana_cmpr.c b/components/driver/analog_comparator/ana_cmpr.c index 7fbdcf2689..c560f17934 100644 --- a/components/driver/analog_comparator/ana_cmpr.c +++ b/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); diff --git a/components/driver/analog_comparator/include/driver/ana_cmpr_types.h b/components/driver/analog_comparator/include/driver/ana_cmpr_types.h index a04ae0b52f..acafb6ccda 100644 --- a/components/driver/analog_comparator/include/driver/ana_cmpr_types.h +++ b/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; /** diff --git a/components/hal/esp32h2/include/hal/ana_cmpr_ll.h b/components/hal/esp32h2/include/hal/ana_cmpr_ll.h index a818ea8b47..834391be30 100644 --- a/components/hal/esp32h2/include/hal/ana_cmpr_ll.h +++ b/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 * diff --git a/components/hal/esp32p4/include/hal/ana_cmpr_ll.h b/components/hal/esp32p4/include/hal/ana_cmpr_ll.h new file mode 100644 index 0000000000..9f4abbf6d3 --- /dev/null +++ b/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 +#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 diff --git a/components/soc/esp32h2/ana_cmpr_periph.c b/components/soc/esp32h2/ana_cmpr_periph.c index 4d3a67586c..8a5bec3c6c 100644 --- a/components/soc/esp32h2/ana_cmpr_periph.c +++ b/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, }, }; diff --git a/components/soc/esp32p4/ana_cmpr_periph.c b/components/soc/esp32p4/ana_cmpr_periph.c new file mode 100644 index 0000000000..f189bbd287 --- /dev/null +++ b/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, + }, +}; diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 3a120de79b..e5e7e61fd5 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/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 diff --git a/components/soc/esp32p4/include/soc/ana_cmpr_channel.h b/components/soc/esp32p4/include/soc/ana_cmpr_channel.h new file mode 100644 index 0000000000..e6430604c2 --- /dev/null +++ b/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 */ diff --git a/components/soc/esp32p4/include/soc/ana_cmpr_struct.h b/components/soc/esp32p4/include/soc/ana_cmpr_struct.h new file mode 100644 index 0000000000..b49d31807d --- /dev/null +++ b/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 +#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 diff --git a/components/soc/esp32p4/include/soc/clk_tree_defs.h b/components/soc/esp32p4/include/soc/clk_tree_defs.h index 8e3e34bc9c..a58f4214dd 100644 --- a/components/soc/esp32p4/include/soc/clk_tree_defs.h +++ b/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/////////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32p4/include/soc/gpio_struct.h b/components/soc/esp32p4/include/soc/gpio_struct.h index 7aaade2883..748d4c2b7d 100644 --- a/components/soc/esp32p4/include/soc/gpio_struct.h +++ b/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; diff --git a/components/soc/esp32p4/include/soc/lp_system_struct.h b/components/soc/esp32p4/include/soc/lp_system_struct.h index f54c249eec..633e5a0aaa 100644 --- a/components/soc/esp32p4/include/soc/lp_system_struct.h +++ b/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"); diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index e4ee0d074d..8cb49267ba 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/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) diff --git a/components/soc/esp32p4/ld/esp32p4.peripherals.ld b/components/soc/esp32p4/ld/esp32p4.peripherals.ld index 4085a915e4..f4223a2f01 100644 --- a/components/soc/esp32p4/ld/esp32p4.peripherals.ld +++ b/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 ); diff --git a/components/soc/include/soc/ana_cmpr_periph.h b/components/soc/include/soc/ana_cmpr_periph.h index 9418b15578..c197bdb10a 100644 --- a/components/soc/include/soc/ana_cmpr_periph.h +++ b/components/soc/include/soc/ana_cmpr_periph.h @@ -8,6 +8,7 @@ #include #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]; diff --git a/docs/en/api-reference/peripherals/ana_cmpr.rst b/docs/en/api-reference/peripherals/ana_cmpr.rst index 0593dd11f7..b686e6b693 100644 --- a/docs/en/api-reference/peripherals/ana_cmpr.rst +++ b/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 ` for how to connect an event to a task. + Application Example ------------------- diff --git a/docs/en/api-reference/peripherals/etm.rst b/docs/en/api-reference/peripherals/etm.rst index e8dbcefd8b..96165f19f4 100644 --- a/docs/en/api-reference/peripherals/etm.rst +++ b/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 diff --git a/docs/zh_CN/api-reference/peripherals/etm.rst b/docs/zh_CN/api-reference/peripherals/etm.rst index 37c036972d..3f7d5baddc 100644 --- a/docs/zh_CN/api-reference/peripherals/etm.rst +++ b/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 任务