mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(ana_cmpr): added low level functions for esp32h4 and esp32s31
This commit is contained in:
@@ -65,9 +65,9 @@ void ana_cmpr_default_intr_handler(void *usr_data)
|
||||
if (cmpr_handle->cbs.on_cross && (status & cmpr_handle->intr_mask)) {
|
||||
// some chip can distinguish the edge of the cross event
|
||||
#if ANALOG_CMPR_LL_SUPPORT(EDGE_TYPE)
|
||||
if (status & ANALOG_CMPR_LL_POS_CROSS_MASK(cmpr_handle->unit)) {
|
||||
if (status & ANALOG_CMPR_LL_POS_CROSS_MASK(cmpr_handle->unit, 0)) {
|
||||
evt_data.cross_type = ANA_CMPR_CROSS_POS;
|
||||
} else if (status & ANALOG_CMPR_LL_NEG_CROSS_MASK(cmpr_handle->unit)) {
|
||||
} else if (status & ANALOG_CMPR_LL_NEG_CROSS_MASK(cmpr_handle->unit, 0)) {
|
||||
evt_data.cross_type = ANA_CMPR_CROSS_NEG;
|
||||
}
|
||||
#endif // ANALOG_CMPR_LL_SUPPORT(EDGE_TYPE)
|
||||
@@ -123,10 +123,25 @@ esp_err_t ana_cmpr_new_unit(const ana_cmpr_config_t *config, ana_cmpr_handle_t *
|
||||
ana_cmpr_hdl->unit = unit;
|
||||
ana_cmpr_hdl->intr_priority = config->intr_priority;
|
||||
atomic_init(&ana_cmpr_hdl->fsm, ANA_CMPR_FSM_INIT);
|
||||
|
||||
// Enable bus clock
|
||||
analog_cmpr_ll_enable_bus_clock(unit, true);
|
||||
// Reset register
|
||||
analog_cmpr_ll_reset_register(unit);
|
||||
ana_cmpr_clk_src_t clk_src = config->clk_src ? config->clk_src : ANA_CMPR_CLK_SRC_DEFAULT;
|
||||
// Analog comparator located in the IO MUX, but IO MUX clock might be shared with other submodules as well, check if there's conflict
|
||||
#if ANALOG_CMPR_LL_GET(IP_VERSION) > 1
|
||||
// Reset core
|
||||
analog_cmpr_ll_reset_core(unit);
|
||||
// Set clock source (use default if not specified in config)
|
||||
analog_cmpr_ll_set_clk_src(unit, clk_src);
|
||||
// Set clock divider to 1
|
||||
analog_cmpr_ll_set_clk_div(unit, 1);
|
||||
// Enable function clock
|
||||
analog_cmpr_ll_enable_function_clock(unit, true);
|
||||
#else
|
||||
// Analog comparator located in the IO MUX module in older chips, so the clock source is shared with IO MUX.
|
||||
// TODO: Check if the clock source conflicts with other IOMUX consumers
|
||||
ESP_GOTO_ON_ERROR(io_mux_set_clock_source((soc_module_clk_t)clk_src), err, TAG, "clock source conflicts with other IOMUX consumers");
|
||||
#endif
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &ana_cmpr_hdl->src_clk_freq_hz),
|
||||
err, TAG, "get source clock frequency failed");
|
||||
|
||||
@@ -146,13 +161,13 @@ esp_err_t ana_cmpr_new_unit(const ana_cmpr_config_t *config, ana_cmpr_handle_t *
|
||||
#endif // !ANALOG_CMPR_LL_SUPPORT(EDGE_TYPE)
|
||||
// record the interrupt mask, the interrupt will be lazy installed when register user callbacks
|
||||
// different cross type means different interrupt mask
|
||||
ana_cmpr_hdl->intr_mask = analog_cmpr_ll_get_intr_mask_by_type(ana_cmpr_hdl->dev, config->cross_type);
|
||||
ana_cmpr_hdl->intr_mask = analog_cmpr_ll_get_intr_mask_by_type(unit, 0, config->cross_type);
|
||||
|
||||
// different unit share the same interrupt register, so using a spin lock to protect it
|
||||
portENTER_CRITICAL(&s_spinlock);
|
||||
// disable the interrupt by default, and clear pending status
|
||||
analog_cmpr_ll_enable_intr(ana_cmpr_hdl->dev, ANALOG_CMPR_LL_ALL_INTR_MASK(unit), false);
|
||||
analog_cmpr_ll_clear_intr(ana_cmpr_hdl->dev, ANALOG_CMPR_LL_ALL_INTR_MASK(unit));
|
||||
analog_cmpr_ll_enable_intr(ana_cmpr_hdl->dev, ANALOG_CMPR_LL_ALL_INTR_MASK(unit, 0), false);
|
||||
analog_cmpr_ll_clear_intr(ana_cmpr_hdl->dev, ANALOG_CMPR_LL_ALL_INTR_MASK(unit, 0));
|
||||
portEXIT_CRITICAL(&s_spinlock);
|
||||
|
||||
// GPIO configuration
|
||||
@@ -191,6 +206,11 @@ esp_err_t ana_cmpr_del_unit(ana_cmpr_handle_t cmpr)
|
||||
ESP_RETURN_ON_FALSE(unit != -1, ESP_ERR_INVALID_ARG, TAG, "unregistered unit handle");
|
||||
ESP_RETURN_ON_FALSE(atomic_load(&cmpr->fsm) == ANA_CMPR_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "not in init state");
|
||||
|
||||
// Disable function clock first
|
||||
analog_cmpr_ll_enable_function_clock(unit, false);
|
||||
// Disable bus clock last
|
||||
analog_cmpr_ll_enable_bus_clock(unit, false);
|
||||
|
||||
ana_cmpr_destroy_unit(cmpr);
|
||||
// unregister it from the global object array
|
||||
s_ana_cmpr[unit] = NULL;
|
||||
@@ -225,7 +245,7 @@ esp_err_t ana_cmpr_set_debounce(ana_cmpr_handle_t cmpr, const ana_cmpr_debounce_
|
||||
uint32_t wait_cycle = dbc_cfg->wait_us * (cmpr->src_clk_freq_hz / 1000000);
|
||||
// the underlying register may be accessed by different threads at the same time, so use spin lock to protect it
|
||||
portENTER_CRITICAL_SAFE(&s_spinlock);
|
||||
analog_cmpr_ll_set_debounce_cycle(cmpr->dev, wait_cycle);
|
||||
analog_cmpr_ll_set_cross_debounce_cycle(cmpr->dev, wait_cycle);
|
||||
portEXIT_CRITICAL_SAFE(&s_spinlock);
|
||||
|
||||
return ESP_OK;
|
||||
@@ -248,7 +268,7 @@ esp_err_t ana_cmpr_set_cross_type(ana_cmpr_handle_t cmpr, ana_cmpr_cross_type_t
|
||||
|
||||
portENTER_CRITICAL_SAFE(&s_spinlock);
|
||||
analog_cmpr_ll_set_intr_cross_type(cmpr->dev, cross_type);
|
||||
cmpr->intr_mask = analog_cmpr_ll_get_intr_mask_by_type(cmpr->dev, cross_type);
|
||||
cmpr->intr_mask = analog_cmpr_ll_get_intr_mask_by_type(cmpr->unit, 0, cross_type);
|
||||
portEXIT_CRITICAL_SAFE(&s_spinlock);
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
@@ -29,7 +29,7 @@ esp_err_t ana_cmpr_new_etm_event(ana_cmpr_handle_t cmpr, const ana_cmpr_etm_even
|
||||
ana_cmpr_etm_event_t *event = heap_caps_calloc(1, sizeof(ana_cmpr_etm_event_t), ETM_MEM_ALLOC_CAPS);
|
||||
ESP_RETURN_ON_FALSE(event, ESP_ERR_NO_MEM, TAG, "no mem for analog comparator event");
|
||||
|
||||
uint32_t event_id = ANALOG_CMPR_LL_ETM_SOURCE(unit, config->event_type);
|
||||
uint32_t event_id = ANALOG_CMPR_LL_ETM_SOURCE(unit, 0, config->event_type);
|
||||
event->base.del = ana_cmpr_del_etm_event;
|
||||
event->base.event_id = event_id;
|
||||
event->base.trig_periph = ETM_TRIG_PERIPH_ANA_CMPR;
|
||||
|
||||
@@ -17,15 +17,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Analog Comparator ETM Events for each unit
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
ANA_CMPR_EVENT_POS_CROSS, /*!< Positive cross event when the source signal becomes higher than the reference signal */
|
||||
ANA_CMPR_EVENT_NEG_CROSS, /*!< Negative cross event when the source signal becomes lower than the reference signal */
|
||||
} ana_cmpr_event_type_t;
|
||||
|
||||
/**
|
||||
* @brief Analog Comparator ETM event configuration
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -22,14 +22,6 @@ typedef int ana_cmpr_unit_t;
|
||||
|
||||
#define ANA_CMPR_UNIT_0 0 /*!< @deprecated Analog comparator unit 0 */
|
||||
|
||||
/**
|
||||
* @brief Analog comparator reference source
|
||||
*/
|
||||
typedef enum {
|
||||
ANA_CMPR_REF_SRC_INTERNAL, /*!< Analog Comparator reference voltage comes from internal, divided from VDD */
|
||||
ANA_CMPR_REF_SRC_EXTERNAL, /*!< Analog Comparator reference voltage comes from external pin, e.g. `ANA_CMPR0_EXT_REF_GPIO` */
|
||||
} ana_cmpr_ref_source_t;
|
||||
|
||||
/**
|
||||
* @brief Analog comparator channel type
|
||||
*/
|
||||
@@ -43,18 +35,6 @@ typedef enum {
|
||||
*/
|
||||
typedef struct ana_cmpr_t *ana_cmpr_handle_t;
|
||||
|
||||
#if SOC_ANA_CMPR_SUPPORTED
|
||||
/**
|
||||
* @brief Analog comparator clock source
|
||||
*/
|
||||
typedef soc_periph_ana_cmpr_clk_src_t ana_cmpr_clk_src_t;
|
||||
#else
|
||||
/**
|
||||
* @brief Analog comparator clock source
|
||||
*/
|
||||
typedef int ana_cmpr_clk_src_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Analog comparator cross event data
|
||||
*/
|
||||
|
||||
@@ -23,19 +23,55 @@ extern "C" {
|
||||
// Number of Analog Comparator instances
|
||||
#define ANALOG_CMPR_LL_INST_NUM 1
|
||||
|
||||
// ANA_CMPR IP version
|
||||
#define ANALOG_CMPR_LL_IP_VERSION 1
|
||||
|
||||
// Number of pads for each Analog Comparator instance
|
||||
#define ANALOG_CMPR_LL_PAD_NUM 2
|
||||
|
||||
// Number of source channels for the comparator
|
||||
#define ANALOG_CMPR_LL_SRC_CHANNEL_NUM 1
|
||||
|
||||
// Can detect positive/negative/any cross type
|
||||
#define ANALOG_CMPR_LL_SUPPORT_EDGE_TYPE 1
|
||||
|
||||
#define ANALOG_CMPR_LL_GET_HW(unit) (&ANALOG_CMPR[unit])
|
||||
#define ANALOG_CMPR_LL_GET_UNIT(hw) (0)
|
||||
|
||||
#define ANALOG_CMPR_LL_NEG_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 0))
|
||||
#define ANALOG_CMPR_LL_POS_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 1))
|
||||
#define ANALOG_CMPR_LL_ANY_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 2))
|
||||
#define ANALOG_CMPR_LL_NEG_CROSS_MASK(unit, src_chan) (1UL << ((unit) * 3 + 0))
|
||||
#define ANALOG_CMPR_LL_POS_CROSS_MASK(unit, src_chan) (1UL << ((unit) * 3 + 1))
|
||||
#define ANALOG_CMPR_LL_ANY_CROSS_MASK(unit, src_chan) (1UL << ((unit) * 3 + 2))
|
||||
|
||||
#define ANALOG_CMPR_LL_ALL_INTR_MASK(unit) (ANALOG_CMPR_LL_NEG_CROSS_MASK(unit) | ANALOG_CMPR_LL_POS_CROSS_MASK(unit) | ANALOG_CMPR_LL_ANY_CROSS_MASK(unit))
|
||||
#define ANALOG_CMPR_LL_ALL_INTR_MASK(unit, src_chan) (ANALOG_CMPR_LL_NEG_CROSS_MASK(unit, src_chan) | ANALOG_CMPR_LL_POS_CROSS_MASK(unit, src_chan) | ANALOG_CMPR_LL_ANY_CROSS_MASK(unit, src_chan))
|
||||
|
||||
#define ANALOG_CMPR_LL_ETM_SOURCE(unit, type) (GPIO_EVT_ZERO_DET_POS0 + (unit) * 2 + (type))
|
||||
#define ANALOG_CMPR_LL_ETM_SOURCE(unit, src_chan, type) (GPIO_EVT_ZERO_DET_POS0 + (unit) * 2 + (type))
|
||||
|
||||
/**
|
||||
* @brief Get the interrupt mask from the given cross type
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param src_chan Source channel ID
|
||||
* @param type Cross type
|
||||
* @return Interrupt mask value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(uint32_t unit_id, uint32_t src_chan, ana_cmpr_cross_type_t type)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
switch (type) {
|
||||
case ANA_CMPR_CROSS_POS:
|
||||
mask |= ANALOG_CMPR_LL_POS_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
case ANA_CMPR_CROSS_NEG:
|
||||
mask |= ANALOG_CMPR_LL_NEG_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
case ANA_CMPR_CROSS_ANY:
|
||||
mask |= ANALOG_CMPR_LL_ANY_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable analog comparator
|
||||
@@ -55,7 +91,7 @@ static inline void analog_cmpr_ll_enable(analog_cmpr_dev_t *hw, bool en)
|
||||
* @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)
|
||||
static inline void analog_cmpr_ll_set_internal_ref_voltage(analog_cmpr_dev_t *hw, ana_cmpr_ref_voltage_t volt_level)
|
||||
{
|
||||
hw->pad_comp_config->dref_comp_0 = volt_level;
|
||||
}
|
||||
@@ -77,38 +113,13 @@ static inline float analog_cmpr_ll_get_internal_ref_voltage(analog_cmpr_dev_t *h
|
||||
* @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)
|
||||
* @param ref_src reference source, 0 for internal, 1 for external GPIO pad
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_ref_source(analog_cmpr_dev_t *hw, ana_cmpr_ref_voltage_t ref_src)
|
||||
static inline void analog_cmpr_ll_set_ref_source(analog_cmpr_dev_t *hw, ana_cmpr_ref_source_t ref_src)
|
||||
{
|
||||
hw->pad_comp_config->mode_comp_0 = 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, ana_cmpr_cross_type_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_NEG_CROSS_MASK(unit);
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the debounce cycle for the cross detection
|
||||
*
|
||||
@@ -118,7 +129,7 @@ static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(analog_cmpr_dev_t *h
|
||||
* @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)
|
||||
static inline void analog_cmpr_ll_set_cross_debounce_cycle(analog_cmpr_dev_t *hw, uint32_t cycle)
|
||||
{
|
||||
hw->pad_comp_filter->zero_det_filter_cnt_0 = cycle;
|
||||
}
|
||||
@@ -175,6 +186,75 @@ static inline volatile void *analog_cmpr_ll_get_intr_status_reg(analog_cmpr_dev_
|
||||
return hw->int_st;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the bus 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_bus_clock(int unit_id, bool enable)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_register(int unit_id)
|
||||
{
|
||||
(void)unit_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the core logic of Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_core(int unit_id)
|
||||
{
|
||||
(void)unit_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock source for analog comparator PAD_COMP_CLK
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param clk_src Clock source, see `ana_cmpr_clk_src_t`
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_src(int unit_id, ana_cmpr_clk_src_t clk_src)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)clk_src;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock divider for analog comparator PAD_COMP_CLK
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param div Clock divider value, the output clock frequency is input clock frequency divided by this value.
|
||||
* Must be greater than 0.
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_div(int unit_id, uint32_t div)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)div;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -23,19 +23,55 @@ extern "C" {
|
||||
// Number of Analog Comparator instances
|
||||
#define ANALOG_CMPR_LL_INST_NUM 1
|
||||
|
||||
// ANA_CMPR IP version
|
||||
#define ANALOG_CMPR_LL_IP_VERSION 1
|
||||
|
||||
// Number of pads for each Analog Comparator instance
|
||||
#define ANALOG_CMPR_LL_PAD_NUM 2
|
||||
|
||||
// Number of source channels for the comparator
|
||||
#define ANALOG_CMPR_LL_SRC_CHANNEL_NUM 1
|
||||
|
||||
// Can detect positive/negative/any cross type
|
||||
#define ANALOG_CMPR_LL_SUPPORT_EDGE_TYPE 1
|
||||
|
||||
#define ANALOG_CMPR_LL_GET_HW(unit) (&ANALOG_CMPR[unit])
|
||||
#define ANALOG_CMPR_LL_GET_UNIT(hw) (0)
|
||||
|
||||
#define ANALOG_CMPR_LL_NEG_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 0))
|
||||
#define ANALOG_CMPR_LL_POS_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 1))
|
||||
#define ANALOG_CMPR_LL_ANY_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 2))
|
||||
#define ANALOG_CMPR_LL_NEG_CROSS_MASK(unit, src_chan) (1UL << ((unit) * 3 + 0))
|
||||
#define ANALOG_CMPR_LL_POS_CROSS_MASK(unit, src_chan) (1UL << ((unit) * 3 + 1))
|
||||
#define ANALOG_CMPR_LL_ANY_CROSS_MASK(unit, src_chan) (1UL << ((unit) * 3 + 2))
|
||||
|
||||
#define ANALOG_CMPR_LL_ALL_INTR_MASK(unit) (ANALOG_CMPR_LL_NEG_CROSS_MASK(unit) | ANALOG_CMPR_LL_POS_CROSS_MASK(unit) | ANALOG_CMPR_LL_ANY_CROSS_MASK(unit))
|
||||
#define ANALOG_CMPR_LL_ALL_INTR_MASK(unit, src_chan) (ANALOG_CMPR_LL_NEG_CROSS_MASK(unit, src_chan) | ANALOG_CMPR_LL_POS_CROSS_MASK(unit, src_chan) | ANALOG_CMPR_LL_ANY_CROSS_MASK(unit, src_chan))
|
||||
|
||||
#define ANALOG_CMPR_LL_ETM_SOURCE(unit, type) (GPIO_EVT_ZERO_DET_POS0 + (unit) * 2 + (type))
|
||||
#define ANALOG_CMPR_LL_ETM_SOURCE(unit, src_chan, type) (GPIO_EVT_ZERO_DET_POS0 + (unit) * 2 + (type))
|
||||
|
||||
/**
|
||||
* @brief Get the interrupt mask from the given cross type
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param src_chan Source channel ID
|
||||
* @param type Cross type
|
||||
* @return Interrupt mask value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(uint32_t unit_id, uint32_t src_chan, ana_cmpr_cross_type_t type)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
switch (type) {
|
||||
case ANA_CMPR_CROSS_POS:
|
||||
mask |= ANALOG_CMPR_LL_POS_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
case ANA_CMPR_CROSS_NEG:
|
||||
mask |= ANALOG_CMPR_LL_NEG_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
case ANA_CMPR_CROSS_ANY:
|
||||
mask |= ANALOG_CMPR_LL_ANY_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable analog comparator
|
||||
@@ -55,7 +91,7 @@ static inline void analog_cmpr_ll_enable(analog_cmpr_dev_t *hw, bool en)
|
||||
* @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)
|
||||
static inline void analog_cmpr_ll_set_internal_ref_voltage(analog_cmpr_dev_t *hw, ana_cmpr_ref_voltage_t volt_level)
|
||||
{
|
||||
hw->pad_comp_config->dref_comp_0 = volt_level;
|
||||
}
|
||||
@@ -77,38 +113,13 @@ static inline float analog_cmpr_ll_get_internal_ref_voltage(analog_cmpr_dev_t *h
|
||||
* @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)
|
||||
* @param ref_src reference source, 0 for internal, 1 for external GPIO pad
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_ref_source(analog_cmpr_dev_t *hw, ana_cmpr_ref_voltage_t ref_src)
|
||||
static inline void analog_cmpr_ll_set_ref_source(analog_cmpr_dev_t *hw, ana_cmpr_ref_source_t ref_src)
|
||||
{
|
||||
hw->pad_comp_config->mode_comp_0 = 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, ana_cmpr_cross_type_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_NEG_CROSS_MASK(unit);
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the debounce cycle for the cross detection
|
||||
*
|
||||
@@ -118,7 +129,7 @@ static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(analog_cmpr_dev_t *h
|
||||
* @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)
|
||||
static inline void analog_cmpr_ll_set_cross_debounce_cycle(analog_cmpr_dev_t *hw, uint32_t cycle)
|
||||
{
|
||||
hw->pad_comp_filter->zero_det_filter_cnt_0 = cycle;
|
||||
}
|
||||
@@ -175,6 +186,75 @@ static inline volatile void *analog_cmpr_ll_get_intr_status_reg(analog_cmpr_dev_
|
||||
return hw->int_st;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the bus 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_bus_clock(int unit_id, bool enable)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_register(int unit_id)
|
||||
{
|
||||
(void)unit_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the core logic of Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_core(int unit_id)
|
||||
{
|
||||
(void)unit_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock source for analog comparator PAD_COMP_CLK
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param clk_src Clock source, see `ana_cmpr_clk_src_t`
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_src(int unit_id, ana_cmpr_clk_src_t clk_src)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)clk_src;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock divider for analog comparator PAD_COMP_CLK
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param div Clock divider value, the output clock frequency is input clock frequency divided by this value.
|
||||
* Must be greater than 0.
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_div(int unit_id, uint32_t div)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)div;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -18,15 +18,41 @@
|
||||
// Number of Analog Comparator instances
|
||||
#define ANALOG_CMPR_LL_INST_NUM 1
|
||||
|
||||
// ANA_CMPR IP version
|
||||
#define ANALOG_CMPR_LL_IP_VERSION 1
|
||||
|
||||
// Number of pads for each Analog Comparator instance
|
||||
#define ANALOG_CMPR_LL_PAD_NUM 2
|
||||
|
||||
// Number of source channels for the comparator
|
||||
#define ANALOG_CMPR_LL_SRC_CHANNEL_NUM 1
|
||||
|
||||
#define ANALOG_CMPR_LL_GET_HW(unit) (&ANALOG_CMPR[unit])
|
||||
#define ANALOG_CMPR_LL_EVENT_CROSS (1 << 0)
|
||||
|
||||
#define ANALOG_CMPR_LL_ALL_INTR_MASK(unit) (ANALOG_CMPR_LL_EVENT_CROSS)
|
||||
#define ANALOG_CMPR_LL_ALL_INTR_MASK(unit, src_chan) (ANALOG_CMPR_LL_EVENT_CROSS)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get the interrupt mask from the given cross type
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param src_chan Source channel ID
|
||||
* @param type Cross type
|
||||
* @return Interrupt mask value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(uint32_t unit_id, uint32_t src_chan, ana_cmpr_cross_type_t type)
|
||||
{
|
||||
(void)type;
|
||||
(void)unit_id;
|
||||
(void)src_chan;
|
||||
return ANALOG_CMPR_LL_EVENT_CROSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable analog comparator
|
||||
*
|
||||
@@ -45,7 +71,7 @@ static inline void analog_cmpr_ll_enable(analog_cmpr_dev_t *hw, bool en)
|
||||
* @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)
|
||||
static inline void analog_cmpr_ll_set_internal_ref_voltage(analog_cmpr_dev_t *hw, ana_cmpr_ref_voltage_t volt_level)
|
||||
{
|
||||
hw->pad_comp_config->dref_comp = volt_level;
|
||||
}
|
||||
@@ -67,9 +93,9 @@ static inline uint32_t analog_cmpr_ll_get_internal_ref_voltage(analog_cmpr_dev_t
|
||||
* @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)
|
||||
* @param ref_src reference source, 0 for internal, 1 for external GPIO pad
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_ref_source(analog_cmpr_dev_t *hw, ana_cmpr_ref_voltage_t ref_src)
|
||||
static inline void analog_cmpr_ll_set_ref_source(analog_cmpr_dev_t *hw, ana_cmpr_ref_source_t ref_src)
|
||||
{
|
||||
hw->pad_comp_config->mode_comp = ref_src;
|
||||
}
|
||||
@@ -90,22 +116,6 @@ static inline void analog_cmpr_ll_set_intr_cross_type(analog_cmpr_dev_t *hw, ana
|
||||
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 Not used on H2, because H2 can't distinguish the edge type
|
||||
* The parameter here only to be compatible with other targets
|
||||
* @return interrupt mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(analog_cmpr_dev_t *hw, ana_cmpr_cross_type_t type)
|
||||
{
|
||||
(void)type;
|
||||
return ANALOG_CMPR_LL_EVENT_CROSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the debounce cycle for the cross detection
|
||||
*
|
||||
@@ -115,7 +125,7 @@ static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(analog_cmpr_dev_t *h
|
||||
* @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)
|
||||
static inline void analog_cmpr_ll_set_cross_debounce_cycle(analog_cmpr_dev_t *hw, uint32_t cycle)
|
||||
{
|
||||
hw->pad_comp_filter->zero_det_filter_cnt = cycle;
|
||||
}
|
||||
@@ -172,6 +182,75 @@ static inline volatile void *analog_cmpr_ll_get_intr_status_reg(analog_cmpr_dev_
|
||||
return hw->int_st;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the bus 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_bus_clock(int unit_id, bool enable)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_register(int unit_id)
|
||||
{
|
||||
(void)unit_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the core logic of Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_core(int unit_id)
|
||||
{
|
||||
(void)unit_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock source for analog comparator PAD_COMP_CLK
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param clk_src Clock source, see `ana_cmpr_clk_src_t`
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_src(int unit_id, ana_cmpr_clk_src_t clk_src)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)clk_src;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock divider for analog comparator PAD_COMP_CLK
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param div Clock divider value, the output clock frequency is input clock frequency divided by this value.
|
||||
* Must be greater than 0.
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_div(int unit_id, uint32_t div)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)div;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -22,17 +22,53 @@ extern "C" {
|
||||
// Number of Analog Comparator instances
|
||||
#define ANALOG_CMPR_LL_INST_NUM 1
|
||||
|
||||
// ANA_CMPR IP version
|
||||
#define ANALOG_CMPR_LL_IP_VERSION 1
|
||||
|
||||
// Number of pads for each Analog Comparator instance
|
||||
#define ANALOG_CMPR_LL_PAD_NUM 2
|
||||
|
||||
// Number of source channels for the comparator
|
||||
#define ANALOG_CMPR_LL_SRC_CHANNEL_NUM 1
|
||||
|
||||
// Can detect positive/negative/any cross type
|
||||
#define ANALOG_CMPR_LL_SUPPORT_EDGE_TYPE 1
|
||||
|
||||
#define ANALOG_CMPR_LL_GET_HW(unit) (&ANALOG_CMPR[unit])
|
||||
#define ANALOG_CMPR_LL_GET_UNIT(hw) (0)
|
||||
|
||||
#define ANALOG_CMPR_LL_NEG_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 0))
|
||||
#define ANALOG_CMPR_LL_POS_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 1))
|
||||
#define ANALOG_CMPR_LL_ANY_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 2))
|
||||
#define ANALOG_CMPR_LL_NEG_CROSS_MASK(unit, src_chan) (1UL << ((unit) * 3 + 0))
|
||||
#define ANALOG_CMPR_LL_POS_CROSS_MASK(unit, src_chan) (1UL << ((unit) * 3 + 1))
|
||||
#define ANALOG_CMPR_LL_ANY_CROSS_MASK(unit, src_chan) (1UL << ((unit) * 3 + 2))
|
||||
|
||||
#define ANALOG_CMPR_LL_ALL_INTR_MASK(unit) (ANALOG_CMPR_LL_NEG_CROSS_MASK(unit) | ANALOG_CMPR_LL_POS_CROSS_MASK(unit) | ANALOG_CMPR_LL_ANY_CROSS_MASK(unit))
|
||||
#define ANALOG_CMPR_LL_ALL_INTR_MASK(unit, src_chan) (ANALOG_CMPR_LL_NEG_CROSS_MASK(unit, src_chan) | ANALOG_CMPR_LL_POS_CROSS_MASK(unit, src_chan) | ANALOG_CMPR_LL_ANY_CROSS_MASK(unit, src_chan))
|
||||
|
||||
/**
|
||||
* @brief Get the interrupt mask from the given cross type
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param src_chan Source channel ID
|
||||
* @param type Cross type
|
||||
* @return Interrupt mask value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(uint32_t unit_id, uint32_t src_chan, ana_cmpr_cross_type_t type)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
switch (type) {
|
||||
case ANA_CMPR_CROSS_POS:
|
||||
mask |= ANALOG_CMPR_LL_POS_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
case ANA_CMPR_CROSS_NEG:
|
||||
mask |= ANALOG_CMPR_LL_NEG_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
case ANA_CMPR_CROSS_ANY:
|
||||
mask |= ANALOG_CMPR_LL_ANY_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable analog comparator
|
||||
@@ -52,7 +88,7 @@ static inline void analog_cmpr_ll_enable(analog_cmpr_dev_t *hw, bool en)
|
||||
* @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)
|
||||
static inline void analog_cmpr_ll_set_internal_ref_voltage(analog_cmpr_dev_t *hw, ana_cmpr_ref_voltage_t volt_level)
|
||||
{
|
||||
hw->pad_comp_config->ext_dref_comp_0 = volt_level;
|
||||
}
|
||||
@@ -74,38 +110,13 @@ static inline float analog_cmpr_ll_get_internal_ref_voltage(analog_cmpr_dev_t *h
|
||||
* @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)
|
||||
* @param ref_src reference source, 0 for internal, 1 for external GPIO pad
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_ref_source(analog_cmpr_dev_t *hw, ana_cmpr_ref_voltage_t ref_src)
|
||||
static inline void analog_cmpr_ll_set_ref_source(analog_cmpr_dev_t *hw, ana_cmpr_ref_source_t ref_src)
|
||||
{
|
||||
hw->pad_comp_config->ext_mode_comp_0 = 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, ana_cmpr_cross_type_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_NEG_CROSS_MASK(unit);
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the debounce cycle for the cross detection
|
||||
*
|
||||
@@ -115,7 +126,7 @@ static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(analog_cmpr_dev_t *h
|
||||
* @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)
|
||||
static inline void analog_cmpr_ll_set_cross_debounce_cycle(analog_cmpr_dev_t *hw, uint32_t cycle)
|
||||
{
|
||||
hw->pad_comp_filter->ext_zero_det_filter_cnt_0 = cycle;
|
||||
}
|
||||
@@ -172,6 +183,75 @@ static inline volatile void *analog_cmpr_ll_get_intr_status_reg(analog_cmpr_dev_
|
||||
return hw->int_st;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the bus 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_bus_clock(int unit_id, bool enable)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_register(int unit_id)
|
||||
{
|
||||
(void)unit_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the core logic of Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_core(int unit_id)
|
||||
{
|
||||
(void)unit_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock source for analog comparator PAD_COMP_CLK
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param clk_src Clock source, see `ana_cmpr_clk_src_t`
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_src(int unit_id, ana_cmpr_clk_src_t clk_src)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)clk_src;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock divider for analog comparator PAD_COMP_CLK
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param div Clock divider value, the output clock frequency is input clock frequency divided by this value.
|
||||
* Must be greater than 0.
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_div(int unit_id, uint32_t div)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)div;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "hal/ana_cmpr_periph.h"
|
||||
|
||||
const ana_cmpr_periph_t ana_cmpr_periph[1] = {
|
||||
[0] = {
|
||||
.pad_gpios = {
|
||||
ANA_CMPR0_PAD0_GPIO,
|
||||
ANA_CMPR0_PAD1_GPIO,
|
||||
ANA_CMPR0_PAD2_GPIO,
|
||||
ANA_CMPR0_PAD3_GPIO,
|
||||
},
|
||||
.intr_src = ETS_ZERO_DET_INTR_SOURCE,
|
||||
.module_name = "ANA_CMPR_U0",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 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 "hal/ana_cmpr_types.h"
|
||||
#include "soc/zero_det_struct.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/soc_etm_source.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// the analog comparator on this target is also called zero detector
|
||||
typedef zero_dev_t analog_cmpr_dev_t;
|
||||
|
||||
#define ANALOG_CMPR_LL_GET(_attr) ANALOG_CMPR_LL_ ## _attr
|
||||
#define ANALOG_CMPR_LL_SUPPORT(_feat) ANALOG_CMPR_LL_SUPPORT_ ## _feat
|
||||
|
||||
// Number of Analog Comparator instances
|
||||
#define ANALOG_CMPR_LL_INST_NUM 1
|
||||
|
||||
// ANA_CMPR IP version
|
||||
#define ANALOG_CMPR_LL_IP_VERSION 2
|
||||
|
||||
// Number of pads for each Analog Comparator instance
|
||||
#define ANALOG_CMPR_LL_PAD_NUM 4
|
||||
|
||||
// Number of source channels for the comparator
|
||||
#define ANALOG_CMPR_LL_SRC_CHANNEL_NUM 3
|
||||
|
||||
// Can detect positive/negative/any cross type
|
||||
#define ANALOG_CMPR_LL_SUPPORT_EDGE_TYPE 1
|
||||
|
||||
#define ANALOG_CMPR_LL_GET_HW(unit) (&ZERO_DET)
|
||||
|
||||
#define ANALOG_CMPR_LL_NEG_CROSS_MASK(unit, src_chan) (1UL << ((2 - (src_chan)) * 3 + 0))
|
||||
#define ANALOG_CMPR_LL_POS_CROSS_MASK(unit, src_chan) (1UL << ((2 - (src_chan)) * 3 + 1))
|
||||
#define ANALOG_CMPR_LL_ANY_CROSS_MASK(unit, src_chan) (1UL << ((2 - (src_chan)) * 3 + 2))
|
||||
|
||||
#define ANALOG_CMPR_LL_ALL_INTR_MASK(unit, src_chan) (ANALOG_CMPR_LL_NEG_CROSS_MASK(unit, src_chan) | ANALOG_CMPR_LL_POS_CROSS_MASK(unit, src_chan) | ANALOG_CMPR_LL_ANY_CROSS_MASK(unit, src_chan))
|
||||
|
||||
#define ANALOG_CMPR_LL_ETM_SOURCE(unit, src_chan, type) (ZERO_DET_EVT_CHANNEL_1_POS + (src_chan) + ((type) * ANALOG_CMPR_LL_SRC_CHANNEL_NUM))
|
||||
|
||||
/**
|
||||
* @brief Enable the bus 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_bus_clock(int unit_id, bool enable)
|
||||
{
|
||||
PCR.zero_det_conf.zero_det_clk_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_register(int unit_id)
|
||||
{
|
||||
PCR.zero_det_conf.zero_det_rst_en = 1;
|
||||
PCR.zero_det_conf.zero_det_rst_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the core logic of Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_core(int unit_id)
|
||||
{
|
||||
(void)unit_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock source for analog comparator PAD_COMP_CLK
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param clk_src Clock source, see `ana_cmpr_clk_src_t`
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_src(int unit_id, ana_cmpr_clk_src_t clk_src)
|
||||
{
|
||||
// switch (clk_src) {
|
||||
// case ANA_CMPR_CLK_SRC_XTAL:
|
||||
// PCR.zero_det_clk_conf.zero_det_func_clk_sel = 0;
|
||||
// break;
|
||||
// case ANA_CMPR_CLK_SRC_RC_FAST:
|
||||
// PCR.zero_det_clk_conf.zero_det_func_clk_sel = 1;
|
||||
// break;
|
||||
// case ANA_CMPR_CLK_SRC_PLL_F48M:
|
||||
// PCR.zero_det_clk_conf.zero_det_func_clk_sel = 2;
|
||||
// break;
|
||||
// default:
|
||||
// HAL_ASSERT(false);
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param div Clock divider value, the output clock frequency is input clock frequency divided by this value.
|
||||
* Must be greater than 0.
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_div(int unit_id, uint32_t div)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)div;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the interrupt mask from the given cross type
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param src_chan Source channel ID
|
||||
* @param type Cross type
|
||||
* @return Interrupt mask value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(uint32_t unit_id, uint32_t src_chan, ana_cmpr_cross_type_t type)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
switch (type) {
|
||||
case ANA_CMPR_CROSS_POS:
|
||||
mask |= ANALOG_CMPR_LL_POS_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
case ANA_CMPR_CROSS_NEG:
|
||||
mask |= ANALOG_CMPR_LL_NEG_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
case ANA_CMPR_CROSS_ANY:
|
||||
mask |= ANALOG_CMPR_LL_ANY_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable (power on) 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->det_pad_comp_cfg.det_pad_comp_xpd = 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, ana_cmpr_ref_voltage_t volt_level)
|
||||
{
|
||||
hw->det_pad_comp_cfg.det_pad_comp_dref = 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->det_pad_comp_cfg.det_pad_comp_dref * 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
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_ref_source(analog_cmpr_dev_t *hw, ana_cmpr_ref_source_t ref_src)
|
||||
{
|
||||
hw->det_pad_comp_cfg.det_pad_comp_mode = ref_src;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_cross_debounce_cycle(analog_cmpr_dev_t *hw, uint32_t cycle)
|
||||
{
|
||||
hw->det_filter_cnt.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)
|
||||
{
|
||||
uint32_t val = hw->det_int_ena.val;
|
||||
if (enable) {
|
||||
val |= mask;
|
||||
} else {
|
||||
val &= ~mask;
|
||||
}
|
||||
hw->det_int_ena.val = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->det_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->det_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->det_int_st;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set external reference PAD id
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param vref_pad_id PAD id (0..3)
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_ext_ref_pad(analog_cmpr_dev_t *hw, uint32_t vref_pad_id)
|
||||
{
|
||||
hw->det_conf.det_vref_channel_sel = 1 << vref_pad_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set comparator source PAD id for one source channel
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param src_chan Source channel id (0..2)
|
||||
* @param src_pad_id PAD id (0..3)
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_src_pad(analog_cmpr_dev_t *hw, uint32_t src_chan, uint32_t src_pad_id)
|
||||
{
|
||||
uint32_t val = 1 << src_pad_id;
|
||||
switch (src_chan) {
|
||||
case 0:
|
||||
hw->det_conf.det_comp_channel_1_sel = val;
|
||||
break;
|
||||
case 1:
|
||||
hw->det_conf.det_comp_channel_2_sel = val;
|
||||
break;
|
||||
default:
|
||||
hw->det_conf.det_comp_channel_3_sel = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set scan channel mask
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param poll_mask Channel mask (bit0..bit2 => CH1..CH3)
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_scan_mask(analog_cmpr_dev_t *hw, uint32_t poll_mask)
|
||||
{
|
||||
hw->det_conf.det_comp_poll_mask = poll_mask & 0x7;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set scan mode
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param scan_mode Scan mode, see `ana_cmpr_scan_mode_t`
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_scan_mode(analog_cmpr_dev_t *hw, ana_cmpr_scan_mode_t scan_mode)
|
||||
{
|
||||
hw->det_conf.det_comp_poll_mode = scan_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set channel switch wait cycles
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param period_cycles Wait cycles in PAD_COMP_CLK domain
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_poll_period(analog_cmpr_dev_t *hw, uint32_t period_cycles)
|
||||
{
|
||||
hw->det_poll_period.det_comp_poll_period = period_cycles & 0xFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the resample limit for the cross detection
|
||||
*
|
||||
* @note If the current status is high, N consecutive low levels need to be sampled before switching to low, vice versa.
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param limit_cnt The resample limit count
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_resample_limit(analog_cmpr_dev_t *hw, uint32_t limit_cnt)
|
||||
{
|
||||
hw->det_conf.det_limit_cnt = limit_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set ETM delay event cycles
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param delay_cycles Delay cycles in PAD_COMP_CLK domain
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_etm_delay_cycles(analog_cmpr_dev_t *hw, uint32_t delay_cycles)
|
||||
{
|
||||
hw->det_delay_event_time.det_delay_event_time = delay_cycles & 0xFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable per-channel delayed ETM event timer
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param src_chan Source channel id (0..2)
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
static inline void analog_cmpr_ll_enable_channel_etm_delay(analog_cmpr_dev_t *hw, uint32_t src_chan, bool enable)
|
||||
{
|
||||
switch (src_chan) {
|
||||
case 0:
|
||||
hw->det_conf.det_channel_1_event_timer_en = enable;
|
||||
break;
|
||||
case 1:
|
||||
hw->det_conf.det_channel_2_event_timer_en = enable;
|
||||
break;
|
||||
default:
|
||||
hw->det_conf.det_channel_3_event_timer_en = enable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable channel capture timer for cross detection time stamping
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
static inline void analog_cmpr_ll_enable_capture_timer(analog_cmpr_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->det_conf.det_channel_timer_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set hysteresis level
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param hys_level Hysteresis level enum
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_ref_hys_level(analog_cmpr_dev_t *hw, ana_cmpr_ref_hys_t hys_level)
|
||||
{
|
||||
switch (hys_level) {
|
||||
case ANA_CMPR_REF_HYS_LEVEL0:
|
||||
hw->det_pad_comp_cfg.det_pad_comp_hys = 0;
|
||||
break;
|
||||
case ANA_CMPR_REF_HYS_LEVEL1:
|
||||
hw->det_pad_comp_cfg.det_pad_comp_hys = 1;
|
||||
break;
|
||||
case ANA_CMPR_REF_HYS_LEVEL2:
|
||||
hw->det_pad_comp_cfg.det_pad_comp_hys = 2;
|
||||
break;
|
||||
default:
|
||||
hw->det_pad_comp_cfg.det_pad_comp_hys = 4;
|
||||
break;
|
||||
}
|
||||
hw->det_pad_comp_cfg.det_pad_comp_hys_en = hys_level != ANA_CMPR_REF_HYS_LEVEL0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current compare result of one source channel
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param src_chan Source channel id (0..2)
|
||||
* @return true if the source signal is higher than the reference signal, false otherwise
|
||||
*/
|
||||
static inline bool analog_cmpr_ll_get_compare_result(analog_cmpr_dev_t *hw, uint32_t src_chan)
|
||||
{
|
||||
switch (src_chan) {
|
||||
case 0:
|
||||
return hw->det_channel_status.det_channel_1_pad_comp_status;
|
||||
case 1:
|
||||
return hw->det_channel_status.det_channel_2_pad_comp_status;
|
||||
default:
|
||||
return hw->det_channel_status.det_channel_3_pad_comp_status;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current capture timer value for a source channel, which can be used for time stamping the cross event
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param src_chan Source channel id (0..2)
|
||||
* @return Current capture timer value in cycles of PAD_COMP_CLK
|
||||
*/
|
||||
static inline uint32_t analog_cmpr_ll_get_current_capture_time(analog_cmpr_dev_t *hw, uint32_t src_chan)
|
||||
{
|
||||
uint32_t reg_val = 0;
|
||||
switch (src_chan) {
|
||||
case 0:
|
||||
reg_val = hw->det_channel_1_timer0.det_channel_1_timer0;
|
||||
break;
|
||||
case 1:
|
||||
reg_val = hw->det_channel_2_timer0.det_channel_2_timer0;
|
||||
break;
|
||||
default:
|
||||
reg_val = hw->det_channel_3_timer0.det_channel_3_timer0;
|
||||
break;
|
||||
}
|
||||
return reg_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the previous capture timer value for a source channel, which is the timestamp of the last cross event that triggered an interrupt
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param src_chan Source channel id (0..2)
|
||||
* @return Previous capture timer value in cycles of PAD_COMP_CLK
|
||||
*/
|
||||
static inline uint32_t analog_cmpr_ll_get_previous_capture_time(analog_cmpr_dev_t *hw, uint32_t src_chan)
|
||||
{
|
||||
uint32_t reg_val = 0;
|
||||
switch (src_chan) {
|
||||
case 0:
|
||||
reg_val = hw->det_channel_1_timer1.det_channel_1_timer1;
|
||||
break;
|
||||
case 1:
|
||||
reg_val = hw->det_channel_2_timer1.det_channel_2_timer1;
|
||||
break;
|
||||
default:
|
||||
reg_val = hw->det_channel_3_timer1.det_channel_3_timer1;
|
||||
break;
|
||||
}
|
||||
return reg_val;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -23,19 +23,56 @@ extern "C" {
|
||||
// Number of Analog Comparator instances
|
||||
#define ANALOG_CMPR_LL_INST_NUM 2
|
||||
|
||||
// ANA_CMPR IP version
|
||||
#define ANALOG_CMPR_LL_IP_VERSION 1
|
||||
|
||||
// Number of pads for each Analog Comparator instance
|
||||
#define ANALOG_CMPR_LL_PAD_NUM 2
|
||||
|
||||
// Number of source channels for the comparator
|
||||
#define ANALOG_CMPR_LL_SRC_CHANNEL_NUM 1
|
||||
|
||||
// Can detect positive/negative/any cross type
|
||||
#define ANALOG_CMPR_LL_SUPPORT_EDGE_TYPE 1
|
||||
|
||||
#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_NEG_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 0))
|
||||
#define ANALOG_CMPR_LL_POS_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 1))
|
||||
#define ANALOG_CMPR_LL_ANY_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 2))
|
||||
#define ANALOG_CMPR_LL_NEG_CROSS_MASK(unit, src_chan) (1UL << ((unit) * 3 + 0))
|
||||
#define ANALOG_CMPR_LL_POS_CROSS_MASK(unit, src_chan) (1UL << ((unit) * 3 + 1))
|
||||
#define ANALOG_CMPR_LL_ANY_CROSS_MASK(unit, src_chan) (1UL << ((unit) * 3 + 2))
|
||||
|
||||
#define ANALOG_CMPR_LL_ALL_INTR_MASK(unit) (ANALOG_CMPR_LL_NEG_CROSS_MASK(unit) | ANALOG_CMPR_LL_POS_CROSS_MASK(unit) | ANALOG_CMPR_LL_ANY_CROSS_MASK(unit))
|
||||
#define ANALOG_CMPR_LL_ALL_INTR_MASK(unit, src_chan) (ANALOG_CMPR_LL_NEG_CROSS_MASK(unit, src_chan) | ANALOG_CMPR_LL_POS_CROSS_MASK(unit, src_chan) | ANALOG_CMPR_LL_ANY_CROSS_MASK(unit, src_chan))
|
||||
|
||||
#define ANALOG_CMPR_LL_ETM_SOURCE(unit, type) (GPIO_EVT_ZERO_DET_POS0 + (unit) * 2 + (type))
|
||||
#define ANALOG_CMPR_LL_ETM_SOURCE(unit, src_chan, type) (GPIO_EVT_ZERO_DET_POS0 + (unit) * 2 + (type))
|
||||
|
||||
/**
|
||||
* @brief Get the interrupt mask from the given cross type
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param src_chan Source channel ID
|
||||
* @param type Cross type
|
||||
* @return Interrupt mask value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(uint32_t unit_id, uint32_t src_chan, ana_cmpr_cross_type_t type)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
switch (type) {
|
||||
case ANA_CMPR_CROSS_POS:
|
||||
mask |= ANALOG_CMPR_LL_POS_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
case ANA_CMPR_CROSS_NEG:
|
||||
mask |= ANALOG_CMPR_LL_NEG_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
case ANA_CMPR_CROSS_ANY:
|
||||
mask |= ANALOG_CMPR_LL_ANY_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable analog comparator
|
||||
@@ -55,7 +92,7 @@ static inline void analog_cmpr_ll_enable(analog_cmpr_dev_t *hw, bool en)
|
||||
* @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)
|
||||
static inline void analog_cmpr_ll_set_internal_ref_voltage(analog_cmpr_dev_t *hw, ana_cmpr_ref_voltage_t volt_level)
|
||||
{
|
||||
hw->pad_comp_config->dref_comp = volt_level;
|
||||
}
|
||||
@@ -77,38 +114,13 @@ static inline float analog_cmpr_ll_get_internal_ref_voltage(analog_cmpr_dev_t *h
|
||||
* @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)
|
||||
* @param ref_src reference source, 0 for internal, 1 for external GPIO pad
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_ref_source(analog_cmpr_dev_t *hw, ana_cmpr_ref_voltage_t ref_src)
|
||||
static inline void analog_cmpr_ll_set_ref_source(analog_cmpr_dev_t *hw, ana_cmpr_ref_source_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, ana_cmpr_cross_type_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_NEG_CROSS_MASK(unit);
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the debounce cycle for the cross detection
|
||||
*
|
||||
@@ -118,7 +130,7 @@ static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(analog_cmpr_dev_t *h
|
||||
* @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)
|
||||
static inline void analog_cmpr_ll_set_cross_debounce_cycle(analog_cmpr_dev_t *hw, uint32_t cycle)
|
||||
{
|
||||
hw->pad_comp_filter->zero_det_filter_cnt = cycle;
|
||||
}
|
||||
@@ -175,6 +187,75 @@ static inline volatile void *analog_cmpr_ll_get_intr_status_reg(analog_cmpr_dev_
|
||||
return hw->int_st;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the bus 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_bus_clock(int unit_id, bool enable)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_register(int unit_id)
|
||||
{
|
||||
(void)unit_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the core logic of Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_core(int unit_id)
|
||||
{
|
||||
(void)unit_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock source for analog comparator PAD_COMP_CLK
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param clk_src Clock source, see `ana_cmpr_clk_src_t`
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_src(int unit_id, ana_cmpr_clk_src_t clk_src)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)clk_src;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock divider for analog comparator PAD_COMP_CLK
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param div Clock divider value, the output clock frequency is input clock frequency divided by this value.
|
||||
* Must be greater than 0.
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_div(int unit_id, uint32_t div)
|
||||
{
|
||||
(void)unit_id;
|
||||
(void)div;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "hal/ana_cmpr_periph.h"
|
||||
|
||||
const ana_cmpr_periph_t ana_cmpr_periph[1] = {
|
||||
[0] = {
|
||||
.pad_gpios = {
|
||||
ANA_CMPR0_PAD0_GPIO,
|
||||
ANA_CMPR0_PAD1_GPIO,
|
||||
ANA_CMPR0_PAD2_GPIO,
|
||||
ANA_CMPR0_PAD3_GPIO,
|
||||
},
|
||||
.intr_src = ETS_ZERO_DET_INTR_SOURCE,
|
||||
.module_name = "ANA_CMPR_U0",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 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 "hal/ana_cmpr_types.h"
|
||||
#include "soc/zero_det_struct.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "soc/soc_etm_source.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// the analog comparator on this target is also called zero detector
|
||||
typedef zero_det_dev_t analog_cmpr_dev_t;
|
||||
|
||||
#define ANALOG_CMPR_LL_GET(_attr) ANALOG_CMPR_LL_ ## _attr
|
||||
#define ANALOG_CMPR_LL_SUPPORT(_feat) ANALOG_CMPR_LL_SUPPORT_ ## _feat
|
||||
|
||||
// Number of Analog Comparator instances
|
||||
#define ANALOG_CMPR_LL_INST_NUM 1
|
||||
|
||||
// ANA_CMPR IP version
|
||||
#define ANALOG_CMPR_LL_IP_VERSION 2
|
||||
|
||||
// Number of pads for each Analog Comparator instance
|
||||
#define ANALOG_CMPR_LL_PAD_NUM 4
|
||||
|
||||
// Number of source channels for the comparator
|
||||
#define ANALOG_CMPR_LL_SRC_CHANNEL_NUM 3
|
||||
|
||||
// Can detect positive/negative/any cross type
|
||||
#define ANALOG_CMPR_LL_SUPPORT_EDGE_TYPE 1
|
||||
|
||||
#define ANALOG_CMPR_LL_GET_HW(unit) (&ZERO_DET)
|
||||
|
||||
#define ANALOG_CMPR_LL_NEG_CROSS_MASK(unit, src_chan) (1UL << ((2 - (src_chan)) * 3 + 0))
|
||||
#define ANALOG_CMPR_LL_POS_CROSS_MASK(unit, src_chan) (1UL << ((2 - (src_chan)) * 3 + 1))
|
||||
#define ANALOG_CMPR_LL_ANY_CROSS_MASK(unit, src_chan) (1UL << ((2 - (src_chan)) * 3 + 2))
|
||||
|
||||
#define ANALOG_CMPR_LL_ALL_INTR_MASK(unit, src_chan) (ANALOG_CMPR_LL_NEG_CROSS_MASK(unit, src_chan) | ANALOG_CMPR_LL_POS_CROSS_MASK(unit, src_chan) | ANALOG_CMPR_LL_ANY_CROSS_MASK(unit, src_chan))
|
||||
|
||||
#define ANALOG_CMPR_LL_ETM_SOURCE(unit, src_chan, type) (ZERO_DET_EVT_CHANNEL_1_POS + (src_chan) + ((type) * ANALOG_CMPR_LL_SRC_CHANNEL_NUM))
|
||||
|
||||
/**
|
||||
* @brief Enable the bus 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_bus_clock(int unit_id, bool enable)
|
||||
{
|
||||
HP_SYS_CLKRST.zero_det_ctrl0.reg_zero_det_apb_clk_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_register(int unit_id)
|
||||
{
|
||||
HP_SYS_CLKRST.zero_det_ctrl0.reg_zero_det_apb_rst_en = 1;
|
||||
HP_SYS_CLKRST.zero_det_ctrl0.reg_zero_det_apb_rst_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the core logic of Analog Comparator module
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
*/
|
||||
static inline void analog_cmpr_ll_reset_core(int unit_id)
|
||||
{
|
||||
HP_SYS_CLKRST.zero_det_ctrl0.reg_zero_det_core_rst_en = 1;
|
||||
HP_SYS_CLKRST.zero_det_ctrl0.reg_zero_det_core_rst_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock source for analog comparator PAD_COMP_CLK
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param clk_src Clock source, see `ana_cmpr_clk_src_t`
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_src(int unit_id, ana_cmpr_clk_src_t clk_src)
|
||||
{
|
||||
// switch (clk_src) {
|
||||
// case ANA_CMPR_CLK_SRC_XTAL:
|
||||
// HP_SYS_CLKRST.zero_det_ctrl0.reg_zero_det_clk_src_sel = 0;
|
||||
// break;
|
||||
// case ANA_CMPR_CLK_SRC_RC_FAST:
|
||||
// HP_SYS_CLKRST.zero_det_ctrl0.reg_zero_det_clk_src_sel = 1;
|
||||
// break;
|
||||
// case ANA_CMPR_CLK_SRC_PLL_F80M:
|
||||
// HP_SYS_CLKRST.zero_det_ctrl0.reg_zero_det_clk_src_sel = 2;
|
||||
// break;
|
||||
// default:
|
||||
// HAL_ASSERT(false);
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clock divider for analog comparator PAD_COMP_CLK
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param div Clock divider value, the output clock frequency is input clock frequency divided by this value.
|
||||
* Must be greater than 0.
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_clk_div(int unit_id, uint32_t div)
|
||||
{
|
||||
HP_SYS_CLKRST.zero_det_ctrl0.reg_zero_det_clk_div_num = div - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
HP_SYS_CLKRST.zero_det_ctrl0.reg_zero_det_clk_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the interrupt mask from the given cross type
|
||||
*
|
||||
* @param unit_id Unit ID
|
||||
* @param src_chan Source channel ID
|
||||
* @param type Cross type
|
||||
* @return Interrupt mask value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t analog_cmpr_ll_get_intr_mask_by_type(uint32_t unit_id, uint32_t src_chan, ana_cmpr_cross_type_t type)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
switch (type) {
|
||||
case ANA_CMPR_CROSS_POS:
|
||||
mask |= ANALOG_CMPR_LL_POS_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
case ANA_CMPR_CROSS_NEG:
|
||||
mask |= ANALOG_CMPR_LL_NEG_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
case ANA_CMPR_CROSS_ANY:
|
||||
mask |= ANALOG_CMPR_LL_ANY_CROSS_MASK(unit_id, src_chan);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable (power on) 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_cfg.pad_comp_xpd = 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, ana_cmpr_ref_voltage_t volt_level)
|
||||
{
|
||||
hw->pad_comp_cfg.pad_comp_dref = 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_cfg.pad_comp_dref * 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
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_ref_source(analog_cmpr_dev_t *hw, ana_cmpr_ref_source_t ref_src)
|
||||
{
|
||||
hw->pad_comp_cfg.pad_comp_mode = ref_src;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_cross_debounce_cycle(analog_cmpr_dev_t *hw, uint32_t cycle)
|
||||
{
|
||||
hw->filter_cnt.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)
|
||||
{
|
||||
uint32_t val = hw->int_ena.val;
|
||||
if (enable) {
|
||||
val |= mask;
|
||||
} else {
|
||||
val &= ~mask;
|
||||
}
|
||||
hw->int_ena.val = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set external reference PAD id
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param vref_pad_id PAD id (0..3)
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_ext_ref_pad(analog_cmpr_dev_t *hw, uint32_t vref_pad_id)
|
||||
{
|
||||
hw->conf.vref_channel_sel = 1 << vref_pad_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set comparator source PAD id for one source channel
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param src_chan Source channel id (0..2)
|
||||
* @param src_pad_id PAD id (0..3)
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_src_pad(analog_cmpr_dev_t *hw, uint32_t src_chan, uint32_t src_pad_id)
|
||||
{
|
||||
uint32_t val = 1 << src_pad_id;
|
||||
switch (src_chan) {
|
||||
case 0:
|
||||
hw->conf.comp_channel_1_sel = val;
|
||||
break;
|
||||
case 1:
|
||||
hw->conf.comp_channel_2_sel = val;
|
||||
break;
|
||||
default:
|
||||
hw->conf.comp_channel_3_sel = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set scan channel mask
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param poll_mask Channel mask (bit0..bit2 => CH1..CH3)
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_scan_mask(analog_cmpr_dev_t *hw, uint32_t poll_mask)
|
||||
{
|
||||
hw->conf.comp_poll_mask = poll_mask & 0x7;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set scan mode
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param scan_mode Scan mode, see `ana_cmpr_scan_mode_t`
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_scan_mode(analog_cmpr_dev_t *hw, ana_cmpr_scan_mode_t scan_mode)
|
||||
{
|
||||
hw->conf.comp_poll_mode = scan_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set channel switch wait cycles
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param period_cycles Wait cycles in PAD_COMP_CLK domain
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_poll_period(analog_cmpr_dev_t *hw, uint32_t period_cycles)
|
||||
{
|
||||
hw->poll_period.comp_poll_period = period_cycles & 0xFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the resample limit for the cross detection
|
||||
*
|
||||
* @note If the current status is high, N consecutive low levels need to be sampled before switching to low, vice versa.
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param limit_cnt The resample limit count
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_resample_limit(analog_cmpr_dev_t *hw, uint32_t limit_cnt)
|
||||
{
|
||||
hw->conf.limit_cnt = limit_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set ETM delay event cycles
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param delay_cycles Delay cycles in PAD_COMP_CLK domain
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_etm_delay_cycles(analog_cmpr_dev_t *hw, uint32_t delay_cycles)
|
||||
{
|
||||
hw->delay_event_time.delay_event_time = delay_cycles & 0xFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable per-channel delayed ETM event timer
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param src_chan Source channel id (0..2)
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
static inline void analog_cmpr_ll_enable_channel_etm_delay(analog_cmpr_dev_t *hw, uint32_t src_chan, bool enable)
|
||||
{
|
||||
switch (src_chan) {
|
||||
case 0:
|
||||
hw->conf.channel_1_event_timer_en = enable;
|
||||
break;
|
||||
case 1:
|
||||
hw->conf.channel_2_event_timer_en = enable;
|
||||
break;
|
||||
default:
|
||||
hw->conf.channel_3_event_timer_en = enable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable channel capture timer for cross detection time stamping
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
static inline void analog_cmpr_ll_enable_capture_timer(analog_cmpr_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->conf.channel_timer_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set hysteresis level
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param hys_level Hysteresis level enum
|
||||
*/
|
||||
static inline void analog_cmpr_ll_set_ref_hys_level(analog_cmpr_dev_t *hw, ana_cmpr_ref_hys_t hys_level)
|
||||
{
|
||||
switch (hys_level) {
|
||||
case ANA_CMPR_REF_HYS_LEVEL0:
|
||||
hw->pad_comp_cfg.pad_comp_hys = 0;
|
||||
break;
|
||||
case ANA_CMPR_REF_HYS_LEVEL1:
|
||||
hw->pad_comp_cfg.pad_comp_hys = 1;
|
||||
break;
|
||||
case ANA_CMPR_REF_HYS_LEVEL2:
|
||||
hw->pad_comp_cfg.pad_comp_hys = 2;
|
||||
break;
|
||||
default:
|
||||
hw->pad_comp_cfg.pad_comp_hys = 4;
|
||||
break;
|
||||
}
|
||||
hw->pad_comp_cfg.pad_comp_hys_en = hys_level != ANA_CMPR_REF_HYS_LEVEL0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current compare result of one source channel
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param src_chan Source channel id (0..2)
|
||||
* @return true if the source signal is higher than the reference signal, false otherwise
|
||||
*/
|
||||
static inline bool analog_cmpr_ll_get_compare_result(analog_cmpr_dev_t *hw, uint32_t src_chan)
|
||||
{
|
||||
switch (src_chan) {
|
||||
case 0:
|
||||
return hw->channel_status.channel_1_pad_comp_status;
|
||||
case 1:
|
||||
return hw->channel_status.channel_2_pad_comp_status;
|
||||
default:
|
||||
return hw->channel_status.channel_3_pad_comp_status;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current capture timer value for a source channel, which can be used for time stamping the cross event
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param src_chan Source channel id (0..2)
|
||||
* @return Current capture timer value in cycles of PAD_COMP_CLK
|
||||
*/
|
||||
static inline uint32_t analog_cmpr_ll_get_current_capture_time(analog_cmpr_dev_t *hw, uint32_t src_chan)
|
||||
{
|
||||
uint32_t reg_val = 0;
|
||||
switch (src_chan) {
|
||||
case 0:
|
||||
reg_val = hw->channel_1_timer0.channel_1_timer0;
|
||||
break;
|
||||
case 1:
|
||||
reg_val = hw->channel_2_timer0.channel_2_timer0;
|
||||
break;
|
||||
default:
|
||||
reg_val = hw->channel_3_timer0.channel_3_timer0;
|
||||
break;
|
||||
}
|
||||
return reg_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the previous capture timer value for a source channel, which is the timestamp of the last cross event that triggered an interrupt
|
||||
*
|
||||
* @param hw Analog comparator register base address
|
||||
* @param src_chan Source channel id (0..2)
|
||||
* @return Previous capture timer value in cycles of PAD_COMP_CLK
|
||||
*/
|
||||
static inline uint32_t analog_cmpr_ll_get_previous_capture_time(analog_cmpr_dev_t *hw, uint32_t src_chan)
|
||||
{
|
||||
uint32_t reg_val = 0;
|
||||
switch (src_chan) {
|
||||
case 0:
|
||||
reg_val = hw->channel_1_timer1.channel_1_timer1;
|
||||
break;
|
||||
case 1:
|
||||
reg_val = hw->channel_2_timer1.channel_2_timer1;
|
||||
break;
|
||||
default:
|
||||
reg_val = hw->channel_3_timer1.channel_3_timer1;
|
||||
break;
|
||||
}
|
||||
return reg_val;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -20,10 +20,15 @@ extern "C" {
|
||||
|
||||
#if SOC_ANA_CMPR_SUPPORTED
|
||||
typedef struct {
|
||||
int src_gpio;
|
||||
int ext_ref_gpio;
|
||||
int intr_src;
|
||||
const char *module_name;
|
||||
union {
|
||||
struct {
|
||||
const int ext_ref_gpio; // External reference GPIO number
|
||||
const int src_gpio; // Source GPIO number
|
||||
};
|
||||
const int pad_gpios[ANALOG_CMPR_LL_GET(PAD_NUM)]; // Array of GPIO numbers for the pads, indexed by pad number
|
||||
};
|
||||
const int intr_src; // Interrupt source ID
|
||||
const char *module_name; // Module name
|
||||
} ana_cmpr_periph_t;
|
||||
|
||||
extern const ana_cmpr_periph_t ana_cmpr_periph[ANALOG_CMPR_LL_GET(INST_NUM)];
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Analog comparator interrupt type
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
ANA_CMPR_CROSS_DISABLE, /*!< Disable the cross event interrupt */
|
||||
@@ -23,7 +25,6 @@ typedef enum {
|
||||
|
||||
/**
|
||||
* @brief Analog comparator internal reference voltage
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
ANA_CMPR_REF_VOLT_0_PCT_VDD, /*!< Internal reference voltage equals to 0% VDD */
|
||||
@@ -36,6 +37,58 @@ typedef enum {
|
||||
ANA_CMPR_REF_VOLT_70_PCT_VDD, /*!< Internal reference voltage equals to 70% VDD */
|
||||
} ana_cmpr_ref_voltage_t;
|
||||
|
||||
/**
|
||||
* @brief Analog comparator reference source
|
||||
*/
|
||||
typedef enum {
|
||||
ANA_CMPR_REF_SRC_INTERNAL, /*!< Analog Comparator reference voltage comes from internal */
|
||||
ANA_CMPR_REF_SRC_EXTERNAL, /*!< Analog Comparator reference voltage comes from external pin */
|
||||
} ana_cmpr_ref_source_t;
|
||||
|
||||
/**
|
||||
* @brief Analog comparator internal reference hysteresis level
|
||||
*
|
||||
* @note The exact hysteresis voltage is hardware-dependent. The level-to-voltage
|
||||
* mapping on ESP32-H4 is approximately:
|
||||
* - LEVEL1: ~0.04V
|
||||
* - LEVEL2: ~0.08V
|
||||
* - LEVEL3: ~0.12V
|
||||
*/
|
||||
typedef enum {
|
||||
ANA_CMPR_REF_HYS_LEVEL0, /*!< No hysteresis */
|
||||
ANA_CMPR_REF_HYS_LEVEL1, /*!< Hysteresis level 1 */
|
||||
ANA_CMPR_REF_HYS_LEVEL2, /*!< Hysteresis level 2 */
|
||||
ANA_CMPR_REF_HYS_LEVEL3, /*!< Hysteresis level 3 */
|
||||
} ana_cmpr_ref_hys_t;
|
||||
|
||||
/**
|
||||
* @brief Analog comparator scan mode
|
||||
*/
|
||||
typedef enum {
|
||||
ANA_CMPR_SCAN_MODE_FULL, /*!< One trigger scans all enabled source channels */
|
||||
ANA_CMPR_SCAN_MODE_STEP, /*!< One trigger scans one enabled source channel in sequence */
|
||||
} ana_cmpr_scan_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Analog Comparator ETM Events for each unit
|
||||
*/
|
||||
typedef enum {
|
||||
ANA_CMPR_EVENT_POS_CROSS, /*!< Positive cross event when the source signal becomes higher than the reference signal */
|
||||
ANA_CMPR_EVENT_NEG_CROSS, /*!< Negative cross event when the source signal becomes lower than the reference signal */
|
||||
} ana_cmpr_event_type_t;
|
||||
|
||||
#if SOC_ANA_CMPR_SUPPORTED
|
||||
/**
|
||||
* @brief Analog comparator clock source
|
||||
*/
|
||||
typedef soc_periph_ana_cmpr_clk_src_t ana_cmpr_clk_src_t;
|
||||
#else
|
||||
/**
|
||||
* @brief Analog comparator clock source
|
||||
*/
|
||||
typedef int ana_cmpr_clk_src_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user