Analog Comparator

[中文]

Overview

An analog comparator tells you whether a source signal is above or below a reference signal. The reference can come from either an internal generator or an external input.

This makes the analog comparator useful for tasks such as:

  • Detecting whether a waveform crosses a fixed threshold

  • Turning a sine wave into a digital square wave around a chosen reference level

  • Comparing one analog signal against another analog signal

  • Generating interrupts or ETM events when the comparison result changes

  • Building simple hardware signal-processing pipelines without continuous CPU involvement

Note

The analog comparator peripheral is not a continuous-time comparator in the same sense as a discrete analog comparator IC or an op-amp based analog front end. It is driven by a source clock, so comparison results are sampled in hardware time. In practice, clock source, scan timing, debounce, and ETM configuration all affect what you observe on real signals.

Quick Start

If you are new to this peripheral, start with the simplest workflow:

  1. Create a comparator unit

  2. Select the source signal and reference source

  3. Configure the internal reference or external reference input

  4. Optionally configure debounce

  5. Register a callback or create ETM connections

  6. Enable the comparator

The following example uses an internal reference and an interrupt callback to detect when a source signal crosses 50% VDD:

ana_cmpr_handle_t cmpr = NULL;
ana_cmpr_config_t config = {
    .unit = 0,                            // Pick a comparator unit that is available on your target
    .clk_src = ANA_CMPR_CLK_SRC_DEFAULT,  // Most applications can use the default clock source
    .ref_src = ANA_CMPR_REF_SRC_INTERNAL, // Use the internal reference for a simple fixed threshold
    .cross_type = ANA_CMPR_CROSS_ANY,     // Trigger on both positive and negative crossings
    .src_chan0_gpio = 0,                  // Replace with the analog comparator source GPIO wired on your board
};
ESP_ERROR_CHECK(ana_cmpr_new_unit(&config, &cmpr));

ana_cmpr_internal_ref_config_t ref_cfg = {
    .ref_volt = ANA_CMPR_REF_VOLT_50_PCT_VDD, // Set the internal reference voltage to 50% of VDD, i.e., compare whether the source signal is above or below half of the supply voltage
};
ESP_ERROR_CHECK(ana_cmpr_set_internal_reference(cmpr, &ref_cfg));

ana_cmpr_debounce_config_t dbc_cfg = {
    .wait_us = 10, // Set a debounce time of 10 microseconds to suppress duplicate interrupts from noisy signals around the threshold
};
ESP_ERROR_CHECK(ana_cmpr_set_debounce(cmpr, &dbc_cfg));

ana_cmpr_event_callbacks_t cbs = {
    .on_cross = example_ana_cmpr_on_cross_callback, // Register a callback to be called when a crossing event occurs; this callback should be defined elsewhere in your code
};
ESP_ERROR_CHECK(ana_cmpr_register_event_callbacks(cmpr, &cbs, NULL));

ESP_ERROR_CHECK(ana_cmpr_enable(cmpr));

This flow introduces the most important ideas:

The rest of this document expands this flow into typical usage scenarios.

Lifecycle and Valid API States

The following diagram shows the analog comparator lifecycle and the states in which each API is intended to be used:

        flowchart TD
    NC([Not created]) -->|ana_cmpr_new_unit| INIT[Init / Disabled]
    INIT -->|ana_cmpr_enable| EN[Enabled]
    EN -->|ana_cmpr_disable| INIT
    INIT -->|ana_cmpr_del_unit| NC

    subgraph INIT_APIS [Init-state APIs]
        SCAN[ana_cmpr_set_scan_config]
        ADD[ana_cmpr_add_src_chan<br/>ana_cmpr_remove_src_chan]
        CB[ana_cmpr_register_event_callbacks]
    end

    subgraph BOTH_APIS [APIs usable in both states]
        IR[ana_cmpr_set_internal_reference]
        DBC[ana_cmpr_set_debounce]
    end

    subgraph EN_APIS [Enabled-only API]
        TRIG[ana_cmpr_trigger_scan]
    end

    INIT -. can call .-> SCAN
    INIT -. can call .-> ADD
    INIT -. can call .-> CB
    INIT -. can call .-> IR
    INIT -. can call .-> DBC
    EN -. can call .-> IR
    EN -. can call .-> DBC
    EN -. can call .-> TRIG

    classDef stateNeutral fill:#f8fafc,stroke:#64748b,stroke-width:1.5px,color:#111827;
    classDef stateInit fill:#eff6ff,stroke:#2563eb,stroke-width:1.5px,color:#111827;
    classDef stateEnabled fill:#fdf2f8,stroke:#db2777,stroke-width:1.5px,color:#111827;
    classDef initApi fill:#eff6ff,stroke:#60a5fa,color:#111827;
    classDef bothApi fill:#ecfdf5,stroke:#10b981,color:#111827;
    classDef enabledApi fill:#fdf2f8,stroke:#f472b6,color:#111827;

    class NC stateNeutral;
    class INIT stateInit;
    class EN stateEnabled;
    class SCAN,ADD,CB initApi;
    class IR,DBC bothApi;
    class TRIG enabledApi;
    

The main constraints to remember are:

Scenario 1: Detect When a Signal Crosses a Fixed Threshold

Use this setup when you have one analog input and you only care whether it is above or below a threshold.

Typical examples:

  • Detect whether a sensor output rises above a limit

  • Convert a sine wave into a digital waveform around a fixed threshold

  • Trigger software when a signal changes polarity around mid-supply

The easiest way to build this is to compare the source signal against the internal reference.

Example: Internal Reference with Callback

static bool IRAM_ATTR example_ana_cmpr_on_cross_callback(ana_cmpr_handle_t cmpr,
                                                         const ana_cmpr_cross_event_data_t *edata,
                                                         void *user_ctx)
{
    if (edata->cross_type == ANA_CMPR_CROSS_POS) {
        gpio_set_level(EXAMPLE_MONITOR_GPIO_NUM, 1);
    } else if (edata->cross_type == ANA_CMPR_CROSS_NEG) {
        gpio_set_level(EXAMPLE_MONITOR_GPIO_NUM, 0);
    }
    return false;
}

ana_cmpr_handle_t cmpr = NULL;
ana_cmpr_config_t config = {
    .unit = 0,                            // Use a valid unit index for the selected target
    .clk_src = ANA_CMPR_CLK_SRC_DEFAULT,  // Start with default unless you need specific timing
    .ref_src = ANA_CMPR_REF_SRC_INTERNAL, // Compare source against internal threshold
    .cross_type = ANA_CMPR_CROSS_ANY,     // Report both positive and negative crossings
    .src_chan0_gpio = 0,                  // Replace with the source channel GPIO connected on your board
};
ESP_ERROR_CHECK(ana_cmpr_new_unit(&config, &cmpr));

ana_cmpr_internal_ref_config_t ref_cfg = {
    .ref_volt = ANA_CMPR_REF_VOLT_50_PCT_VDD,
};
ESP_ERROR_CHECK(ana_cmpr_set_internal_reference(cmpr, &ref_cfg));

ana_cmpr_debounce_config_t dbc_cfg = {
    .wait_us = 10,
};
ESP_ERROR_CHECK(ana_cmpr_set_debounce(cmpr, &dbc_cfg));

ana_cmpr_event_callbacks_t cbs = {
    .on_cross = example_ana_cmpr_on_cross_callback,
};
ESP_ERROR_CHECK(ana_cmpr_register_event_callbacks(cmpr, &cbs, NULL));

ESP_ERROR_CHECK(ana_cmpr_enable(cmpr));

How to Read the Configuration

The ana_cmpr_config_t structure describes the basic shape of the comparator instance:

When using the internal reference, ana_cmpr_set_internal_reference() sets the threshold with ana_cmpr_internal_ref_config_t::ref_volt. The available values are fixed percentages of VDD. For example, ANA_CMPR_REF_VOLT_50_PCT_VDD means the comparator reports whether the source signal is above or below half of the supply voltage.

Debounce and Signal Stability

Real analog signals are often noisy near the threshold. Without debounce, a signal that slowly moves across the threshold or jitters around it may trigger several crossing interrupts in a short time.

Use ana_cmpr_set_debounce() to suppress these duplicate crossings:

As a rule of thumb:

  • Increase wait_us if your signal is noisy and you see too many interrupts.

  • Decrease wait_us if your signal changes quickly and you start missing real crossings.

Callback Behavior

Register callbacks with ana_cmpr_register_event_callbacks() before enabling the unit.

The comparator currently provides one callback group member:

The callback receives ana_cmpr_cross_event_data_t, which tells you:

On targets that do not support independent positive and negative interrupt reporting, ana_cmpr_cross_event_data_t::cross_type can always be reported as ANA_CMPR_CROSS_ANY.

The callback runs in interrupt context, so keep it short and non-blocking.

Note

If CONFIG_ANA_CMPR_ISR_CACHE_SAFE is enabled, place the callback and any accessed data in internal RAM.

Scenario 2: Compare a Signal Against an External Reference

Use this setup when the reference level is not a fixed percentage of VDD.

Typical examples:

  • Compare a sensor signal against a voltage divider output

  • Compare a waveform against another waveform

  • Generate a digital result from a source/reference pair that both come from analog front-end circuitry

In this case, the comparator source is still your input signal, but the reference comes from another analog input.

Example: External Reference Input

ana_cmpr_handle_t cmpr = NULL;
ana_cmpr_config_t config = {
    .unit = 0,                             // Use a valid unit index for the selected target
    .clk_src = ANA_CMPR_CLK_SRC_DEFAULT,   // Default clock is usually enough
    .ref_src = ANA_CMPR_REF_SRC_EXTERNAL,  // Select external reference mode
    .cross_type = ANA_CMPR_CROSS_ANY,      // Report both crossing directions
    .src_chan0_gpio = 0,                   // Source signal GPIO from your board design
    .ext_ref_gpio = 1,                     // Reference signal GPIO from your board design
};
ESP_ERROR_CHECK(ana_cmpr_new_unit(&config, &cmpr));

ana_cmpr_debounce_config_t dbc_cfg = {
    .wait_us = 10,
};
ESP_ERROR_CHECK(ana_cmpr_set_debounce(cmpr, &dbc_cfg));

ana_cmpr_event_callbacks_t cbs = {
    .on_cross = example_ana_cmpr_on_cross_callback,
};
ESP_ERROR_CHECK(ana_cmpr_register_event_callbacks(cmpr, &cbs, NULL));

ESP_ERROR_CHECK(ana_cmpr_enable(cmpr));

What Changes Compared with Scenario 1

The main difference is ana_cmpr_config_t::ref_src:

  • ANA_CMPR_REF_SRC_INTERNAL means the reference is generated inside the comparator block.

  • ANA_CMPR_REF_SRC_EXTERNAL means the reference comes from a dedicated analog input.

When using an external reference:

You can query the actual GPIOs in use with ana_cmpr_get_channel_gpio():

gpio_num_t src_gpio = -1;
gpio_num_t ext_ref_gpio = -1;
// Read back actual channel mapping after initialization.
ESP_ERROR_CHECK(ana_cmpr_get_channel_gpio(cmpr, ANA_CMPR_SOURCE_CHAN, 0, &src_gpio));
ESP_ERROR_CHECK(ana_cmpr_get_channel_gpio(cmpr, ANA_CMPR_EXT_REF_CHAN, 0, &ext_ref_gpio));

Working with Multiple Source Channels

Some targets support more than one source channel per comparator unit. If your application needs to sample several analog inputs against the same reference, you can configure extra source channels while the comparator is in init state.

The relevant APIs are:

Example:

ana_cmpr_src_chan_config_t src_cfg = {
    .gpio_num = EXAMPLE_SRC_CHAN1_GPIO,
    .cross_type = ANA_CMPR_CROSS_ANY,
};
ESP_ERROR_CHECK(ana_cmpr_add_src_chan(cmpr, 1, &src_cfg));

When using multiple source channels:

Runtime Observation and Timing Helpers

The following APIs are general runtime helpers and are not tied to multi-source configuration:

Use ana_cmpr_get_output_level() when you need current digital comparison state from software. Use ana_cmpr_get_clock_resolution_hz() when converting PAD_COMP_CLK ticks (for example, capture timestamps) to time units. Use ana_cmpr_trigger_scan() when you want deterministic software-controlled refresh timing; it requires ana_cmpr_enable() and returns ESP_ERR_INVALID_STATE in init state.

To get meaningful capture timestamps, enable the capture timer when creating the unit:

ana_cmpr_config_t config = {
    .unit = 0,                            // Use a valid unit index for your target
    .clk_src = ANA_CMPR_CLK_SRC_DEFAULT,  // PAD_COMP_CLK source
    .ref_src = ANA_CMPR_REF_SRC_INTERNAL, // Reference mode used by your capture scenario
    .cross_type = ANA_CMPR_CROSS_ANY,     // Keep both crossing directions by default
    .src_chan0_gpio = 0,                  // Must match your board's source signal wiring
    .en_capture_timer = true,             // Required for capture timestamp APIs
};

Then convert ticks to time with:

uint32_t resolution_hz = 0;
uint32_t current_ticks = 0;
ESP_ERROR_CHECK(ana_cmpr_get_clock_resolution_hz(cmpr, &resolution_hz));
ESP_ERROR_CHECK(ana_cmpr_get_capture_timestamps(cmpr, 0, &current_ticks, NULL));
uint32_t time_us = (uint32_t)(((uint64_t)current_ticks * 1000000U) / resolution_hz);

Practical Configuration Notes

Choosing the Clock Source

The comparator clock affects sampling behavior. In most applications, use ANA_CMPR_CLK_SRC_DEFAULT unless you have a specific clocking requirement.

Note that the analog comparator clock source can be shared with other GPIO-extension style peripherals on some targets. If different peripherals request incompatible clock sources, initialization can fail.

Choosing the Internal Reference Level

The internal reference is defined as a percentage of VDD, not as an arbitrary voltage in volts.

This is convenient when:

  • the input signal naturally swings with the supply range

  • you want a simple mid-supply or supply-relative threshold

This is less suitable when:

  • you need a precise threshold independent of VDD variation

  • the threshold must change continuously instead of in coarse steps

Tuning Debounce

Debounce is one of the first parameters to tune on real hardware.

  • Too little debounce: duplicate interrupts or unstable event behavior near the threshold

  • Too much debounce: missed crossings on fast-changing signals

There is no single good value for every application. Start small and adjust based on observed signal behavior.

Tuning Scan Timing

On scan-capable targets, scan timing and resampling should be chosen together:

  • Reduce poll_period_us when you need quicker updates

  • Increase ana_cmpr_config_t::resample_limit when you need better noise rejection

  • Avoid choosing a scan rate that is much slower than the effective input dynamics you want to detect

Operational Notes

Enable and Disable Lifecycle

The comparator follows a simple lifecycle:

  1. Create and configure it

  2. Enable it

  3. Run your application

  4. Disable it before deleting it

Use ana_cmpr_enable() and ana_cmpr_disable() as a pair.

While enabled, only a limited set of runtime control functions are intended to be adjusted. Configuration functions such as source channel management and scan configuration must be done before enabling the unit.

Power Management

When CONFIG_PM_ENABLE is enabled, sleep and clock changes can affect the comparator. The driver uses a power management lock internally when needed, so enabling the comparator can prevent light sleep while the unit is active.

If power consumption matters, structure your application so the comparator is only enabled when needed.

IRAM Safe

If you need comparator interrupts to keep working while the cache is disabled, enable CONFIG_ANA_CMPR_ISR_CACHE_SAFE.

If you also need the runtime control functions to remain callable in that situation, enable CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM.

The following control APIs can be placed in IRAM:

Thread Safety

The driver is designed to be thread-safe for concurrent API calls on the same ana_cmpr_handle_t, by combining:

  • A per-handle FSM (INIT/ENABLE/WAIT) with atomic state transitions to serialize incompatible operations

  • Short critical sections to keep shared software state and hardware registers updated atomically

  • Slot lifecycle protection for create/delete windows

The main lifecycle contract still applies: call ana_cmpr_disable() before ana_cmpr_del_unit(), and make sure no active dependent objects (for example ETM handles) remain when deleting the unit.

Kconfig Options

The most relevant Kconfig options are:

Examples

  • peripherals/analog_comparator/auto_scan shows auto-scan based threshold detection. After enabling the comparator, hardware scans continuously and updates output in real time, while monitor GPIO is driven via interrupt or ETM depending on target capabilities.

API Reference

Driver APIs

Header File

  • components/esp_driver_ana_cmpr/include/driver/ana_cmpr.h

  • This header file can be included with:

    #include "driver/ana_cmpr.h"
    
  • This header file is a part of the API provided by the esp_driver_ana_cmpr component. To declare that your component depends on esp_driver_ana_cmpr, add the following to your CMakeLists.txt:

    REQUIRES esp_driver_ana_cmpr
    

    or

    PRIV_REQUIRES esp_driver_ana_cmpr
    

Functions

esp_err_t ana_cmpr_new_unit(const ana_cmpr_config_t *config, ana_cmpr_handle_t *ret_cmpr)

Allocating a new analog comparator unit handle.

Parameters:
  • config -- [in] The config of the analog comparator unit

  • ret_cmpr -- [out] The returned analog comparator unit handle

Returns:

  • ESP_OK Allocate analog comparator unit handle success

  • ESP_ERR_NO_MEM No memory for the analog comparator structure

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters or wrong unit number

  • ESP_ERR_INVALID_STATE The unit has been allocated or the clock source has been occupied

esp_err_t ana_cmpr_del_unit(ana_cmpr_handle_t cmpr)

Delete the analog comparator unit handle.

Note

Caller must ensure no active users remain before deleting the unit handle, including any ETM event/task handles created from this unit (delete them first via esp_etm_del_event() and esp_etm_del_task()).

Parameters:

cmpr -- [in] The handle of analog comparator unit

Returns:

  • ESP_OK Delete analog comparator unit handle success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters or wrong unit number

  • ESP_ERR_INVALID_STATE The analog comparator is not disabled yet

esp_err_t ana_cmpr_set_internal_reference(ana_cmpr_handle_t cmpr, const ana_cmpr_internal_ref_config_t *ref_cfg)

Set internal reference configuration.

Note

This function only need to be called when ana_cmpr_config_t::ref_src is set to ANA_CMPR_REF_SRC_INTERNAL.

Note

This function is allowed to run within ISR context including interrupt callbacks

Note

This function will be placed into IRAM if CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM is on, so that it's allowed to be executed when Cache is disabled

Parameters:
  • cmpr -- [in] The handle of analog comparator unit

  • ref_cfg -- [in] Internal reference configuration

Returns:

  • ESP_OK Set internal reference configuration success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters

  • ESP_ERR_NOT_ALLOWED Set the reference voltage for external reference channel is not allowed

esp_err_t ana_cmpr_set_debounce(ana_cmpr_handle_t cmpr, const ana_cmpr_debounce_config_t *dbc_cfg)

Set debounce configuration to the analog comparator.

Note

This function is allowed to run within ISR context including interrupt callbacks

Note

This function will be placed into IRAM if CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM is on, so that it's allowed to be executed when Cache is disabled

Parameters:
  • cmpr -- [in] The handle of analog comparator unit

  • dbc_cfg -- [in] Debounce configuration

Returns:

  • ESP_OK Set debounce configuration success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters

esp_err_t ana_cmpr_get_capture_timestamps(ana_cmpr_handle_t cmpr, int src_chan_id, uint32_t *current, uint32_t *previous)

Get capture timestamps of a source channel.

Note

Returned timestamp values are measured in PAD_COMP_CLK cycles

Note

Convert ticks to time by first querying comparator clock resolution with ana_cmpr_get_clock_resolution_hz(). For example, time_us = ticks * 1000000 / resolution_hz.

Parameters:
  • cmpr -- [in] The handle of analog comparator unit

  • src_chan_id -- [in] The source channel index

  • current -- [out] Timestamp of the latest cross event, in PAD_COMP_CLK cycles. Can be NULL if not needed.

  • previous -- [out] Timestamp of the previous cross event, in PAD_COMP_CLK cycles. Can be NULL if not needed.

Returns:

  • ESP_OK Get capture timestamps success

  • ESP_ERR_INVALID_ARG Both output pointers are NULL, or invalid channel id

  • ESP_ERR_NOT_SUPPORTED Hardware doesn't support capture timer

esp_err_t ana_cmpr_get_clock_resolution_hz(ana_cmpr_handle_t cmpr, uint32_t *resolution_hz)

Get clock resolution of the analog comparator unit.

Note

Returned value is in Hz and corresponds to the PAD_COMP_CLK domain. This clock is shared by features like debounce filtering and capture timestamps.

Parameters:
  • cmpr -- [in] The handle of analog comparator unit

  • resolution_hz -- [out] Comparator clock resolution in Hz

Returns:

  • ESP_OK Get comparator clock resolution success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters

esp_err_t ana_cmpr_add_src_chan(ana_cmpr_handle_t cmpr, int src_chan_id, const ana_cmpr_src_chan_config_t *src_cfg)

Add or update a source channel.

Note

This function can only be called when the comparator unit is in init (disabled) state

Parameters:
  • cmpr -- [in] The handle of analog comparator unit

  • src_chan_id -- [in] The source channel index

  • src_cfg -- [in] Source channel configuration

Returns:

  • ESP_OK Add/update source channel success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters or invalid channel/GPIO configuration

  • ESP_ERR_INVALID_STATE The analog comparator is not in init state

  • ESP_ERR_NOT_SUPPORTED Source channel index is not supported by the current target

esp_err_t ana_cmpr_remove_src_chan(ana_cmpr_handle_t cmpr, int src_chan_id)

Remove a source channel from scan and interrupt routing.

Note

This function can only be called when the comparator unit is in init (disabled) state

Note

This API is idempotent: removing an already-removed channel still returns ESP_OK

Parameters:
  • cmpr -- [in] The handle of analog comparator unit

  • src_chan_id -- [in] The source channel index

Returns:

  • ESP_OK Remove source channel success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters or invalid channel id

  • ESP_ERR_INVALID_STATE The analog comparator is not in init state

  • ESP_ERR_NOT_SUPPORTED Source channel index is not supported by the current target

esp_err_t ana_cmpr_set_src_chan_cross_type(ana_cmpr_handle_t cmpr, int src_chan_id, ana_cmpr_cross_type_t cross_type)

Set cross type for the given source channel.

Note

On targets with edge-type interrupt support, interrupt source selection is fixed when adding source channels, so runtime cross-type switching is not supported.

Parameters:
  • cmpr -- [in] The handle of analog comparator unit

  • src_chan_id -- [in] The source channel index

  • cross_type -- [in] The source signal cross type that can trigger the interrupt

Returns:

  • ESP_OK Set cross type configuration success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters or invalid channel/cross type

  • ESP_ERR_INVALID_STATE The target source channel isn't configured

  • ESP_ERR_NOT_SUPPORTED Runtime cross-type switching isn't supported by the current target

esp_err_t ana_cmpr_set_scan_config(ana_cmpr_handle_t cmpr, const ana_cmpr_scan_config_t *scan_cfg)

Set scan configuration.

Note

This function can only be called when the comparator unit is in init (disabled) state

Parameters:
  • cmpr -- [in] The handle of analog comparator unit

  • scan_cfg -- [in] Scan configuration

Returns:

  • ESP_OK Set scan configuration success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters

  • ESP_ERR_INVALID_STATE The analog comparator is not in init state

  • ESP_ERR_NOT_SUPPORTED Scan configuration is not supported by current target

esp_err_t ana_cmpr_trigger_scan(ana_cmpr_handle_t cmpr)

Trigger one analog comparator scan sequence.

Parameters:

cmpr -- [in] The handle of analog comparator unit

Returns:

  • ESP_OK Trigger scan success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters

  • ESP_ERR_INVALID_STATE Invalid unit state for triggering scan

  • ESP_ERR_NOT_SUPPORTED The hardware doesn't support software triggered scan

esp_err_t ana_cmpr_get_output_level(ana_cmpr_handle_t cmpr, int src_chan_id, bool *out_level)

Get the output level of a source channel.

Note

The output level indicates whether the source voltage is higher than the reference voltage

Note

This function is allowed to run within ISR context including interrupt callbacks

Parameters:
  • cmpr -- [in] The handle of analog comparator unit

  • src_chan_id -- [in] The source channel index

  • out_level -- [out] The output level of the source channel

    • true: source voltage > reference voltage

    • false: source voltage < reference voltage

Returns:

  • ESP_OK Get output level success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters or invalid channel id

  • ESP_ERR_NOT_SUPPORTED Hardware can't report the output level of the source channel or the source channel index is not supported by the current target

esp_err_t ana_cmpr_register_event_callbacks(ana_cmpr_handle_t cmpr, const ana_cmpr_event_callbacks_t *cbs, void *user_data)

Register analog comparator interrupt event callbacks.

Note

This function can only be called before enabling the unit

Parameters:
  • cmpr -- [in] The handle of analog comparator unit

  • cbs -- [in] Group of callback functions

  • user_data -- [in] The user data that will be passed to callback functions directly

Returns:

  • ESP_OK Register callbacks success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters

  • ESP_ERR_INVALID_STATE The analog comparator has been enabled

esp_err_t ana_cmpr_enable(ana_cmpr_handle_t cmpr)

Enable the analog comparator unit.

Parameters:

cmpr -- [in] The handle of analog comparator unit

Returns:

  • ESP_OK Enable analog comparator unit success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters

  • ESP_ERR_INVALID_STATE The analog comparator has been enabled

esp_err_t ana_cmpr_disable(ana_cmpr_handle_t cmpr)

Disable the analog comparator unit.

Parameters:

cmpr -- [in] The handle of analog comparator unit

Returns:

  • ESP_OK Disable analog comparator unit success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters

  • ESP_ERR_INVALID_STATE The analog comparator has disabled already

esp_err_t ana_cmpr_get_channel_gpio(ana_cmpr_handle_t cmpr, ana_cmpr_channel_type_t chan_type, int chan_id, gpio_num_t *gpio_num)

Get the GPIO number of a configured analog comparator channel.

Parameters:
  • cmpr -- [in] The handle of analog comparator unit

  • chan_type -- [in] The channel type of analog comparator, either source channel or external reference channel

  • chan_id -- [in] The source channel index when chan_type is ANA_CMPR_SOURCE_CHAN. Must be 0 when chan_type is ANA_CMPR_EXT_REF_CHAN

  • gpio_num -- [out] The output GPIO number of this channel

Returns:

  • ESP_OK Get GPIO success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters or wrong channel type/channel id

  • ESP_ERR_INVALID_STATE The target channel is not configured

  • ESP_ERR_NOT_SUPPORTED The source channel index is not supported by the current target

  • ESP_ERR_NOT_FOUND The requested channel doesn't have a GPIO mapping, e.g. the reference source is internal

static inline esp_err_t ana_cmpr_set_cross_type(ana_cmpr_handle_t cmpr, ana_cmpr_cross_type_t cross_type)

Set the cross type for the source channel 0 that can trigger the event.

Note

The initial cross type is configured in ana_cmpr_new_unit, this function can update the cross type

Note

This function is allowed to run within ISR context including interrupt callbacks

Note

This is a legacy API that only applies to source channel 0

Parameters:
  • cmpr -- [in] The handle of analog comparator unit

  • cross_type -- [in] The source signal cross type that can trigger the interrupt

Returns:

  • ESP_OK Set cross type configuration success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters

esp_err_t ana_cmpr_get_gpio(ana_cmpr_unit_t unit, ana_cmpr_channel_type_t chan_type, int *gpio_num)

Get the fixed GPIO number of the analog comparator unit.

Deprecated:

Please use ana_cmpr_get_channel_gpio() instead to query the GPIO of the configured comparator instance

Parameters:
  • unit -- [in] The handle of analog comparator unit

  • chan_type -- [in] The channel type of analog comparator, like source channel or reference channel

  • gpio_num -- [out] The output GPIO number of this channel

Returns:

  • ESP_OK Get GPIO success

  • ESP_ERR_INVALID_ARG NULL pointer of the parameters or wrong unit number or wrong channel type

Structures

struct ana_cmpr_config_t

Analog comparator unit configuration.

Public Members

int unit

Analog comparator unit ID, index from 0

ana_cmpr_clk_src_t clk_src

The clock source of the analog comparator, which decide the resolution of the comparator

ana_cmpr_ref_source_t ref_src

Reference signal source of the comparator, select using ANA_CMPR_REF_SRC_INTERNAL or ANA_CMPR_REF_SRC_EXTERNAL. For internal reference, the reference voltage should be set to internal_ref_volt, for external reference, the reference signal should be connect to ANA_CMPRx_EXT_REF_GPIO

int intr_priority

The interrupt priority, range 1~3. If set to 0, the driver will automatically select a relative low priority (1,2,3)

ana_cmpr_cross_type_t cross_type

The crossing type of source channel 0, that can trigger interrupt

gpio_num_t src_chan0_gpio

The GPIO number of source channel 0 signal

gpio_num_t ext_ref_gpio

The GPIO number of external reference signal, only valid when ref_src is set to ANA_CMPR_REF_SRC_EXTERNAL

uint8_t resample_limit

Unit-wide consecutive sample count required to update channel status

bool en_capture_timer

Enable channel capture timer at unit creation.

struct ana_cmpr_internal_ref_config_t

Analog comparator internal reference configuration.

Public Members

ana_cmpr_ref_voltage_t ref_volt

The internal reference voltage. It can be specified to a certain fixed percentage of the VDD power supply, currently supports 0%~70% VDD with a step 10%

ana_cmpr_ref_hys_t ref_hys_level

Internal reference hysteresis level

struct ana_cmpr_debounce_config_t

Analog comparator debounce filter configuration.

Public Members

uint32_t wait_us

The wait time to prevent frequent interrupts caused by signal noise or bouncing. During the specified wait_us period, no new interrupts will be triggered. Set the value according to the signal characteristics. A rapid signal requires a small wait time, otherwise the next cross event may be missed.

struct ana_cmpr_src_chan_config_t

Analog comparator source channel configuration.

Public Members

gpio_num_t gpio_num

Source input GPIO

ana_cmpr_cross_type_t cross_type

Crossing type that can trigger events for this source channel

struct ana_cmpr_scan_config_t

Analog comparator scan configuration.

Public Members

ana_cmpr_scan_mode_t scan_mode

Channel scan mode

uint32_t poll_period_us

Channel switching wait time in microseconds

Driver Types

Header File

  • components/esp_driver_ana_cmpr/include/driver/ana_cmpr_types.h

  • This header file can be included with:

    #include "driver/ana_cmpr_types.h"
    
  • This header file is a part of the API provided by the esp_driver_ana_cmpr component. To declare that your component depends on esp_driver_ana_cmpr, add the following to your CMakeLists.txt:

    REQUIRES esp_driver_ana_cmpr
    

    or

    PRIV_REQUIRES esp_driver_ana_cmpr
    

Structures

struct ana_cmpr_cross_event_data_t

Analog comparator cross event data.

Public Members

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 Always be ANA_CMPR_CROSS_ANY if target does not support independent interrupt (like ESP32H2)

int src_chan_id

The source channel index that triggers the interrupt, valid when the target supports multiple source channels

struct ana_cmpr_event_callbacks_t

Group of Analog Comparator callbacks.

Note

The callbacks are all running under ISR environment

Note

When CONFIG_ANA_CMPR_ISR_CACHE_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. The variables used in the function should be in the SRAM as well.

Public Members

ana_cmpr_cross_cb_t on_cross

The callback function on cross interrupt

Macros

ANA_CMPR_UNIT_0

Deprecated:

Analog comparator unit 0

Type Definitions

typedef int ana_cmpr_unit_t

Analog comparator unit.

typedef struct ana_cmpr_t *ana_cmpr_handle_t

Analog comparator unit handle.

typedef bool (*ana_cmpr_cross_cb_t)(ana_cmpr_handle_t cmpr, const ana_cmpr_cross_event_data_t *edata, void *user_ctx)

Prototype of Analog comparator event callback.

Param cmpr:

[in] Analog Comparator handle, created from ana_cmpr_new_unit()

Param edata:

[in] Point to Analog Comparator event data. The lifecycle of this pointer memory is inside this function, user should copy it into static memory if used outside this function. (Currently not use)

Param user_ctx:

[in] User registered context, passed from ana_cmpr_register_event_callbacks()

Return:

Whether a high priority task has been waken up by this callback function

Enumerations

enum ana_cmpr_channel_type_t

Analog comparator channel type.

Values:

enumerator ANA_CMPR_SOURCE_CHAN

Analog Comparator source channel, which is used to input the signal that to be compared

enumerator ANA_CMPR_EXT_REF_CHAN

Analog Comparator external reference channel, which is used as the reference signal


Was this page helpful?