forked from espressif/esp-idf
feat(ana_cmpr): supported analog comparator etm function on p4
This commit is contained in:
@@ -47,6 +47,9 @@ endif()
|
|||||||
# Analog comparator related source files
|
# Analog comparator related source files
|
||||||
if(CONFIG_SOC_ANA_CMPR_SUPPORTED)
|
if(CONFIG_SOC_ANA_CMPR_SUPPORTED)
|
||||||
list(APPEND srcs "analog_comparator/ana_cmpr.c")
|
list(APPEND srcs "analog_comparator/ana_cmpr.c")
|
||||||
|
if(CONFIG_SOC_ANA_CMPR_SUPPORT_ETM)
|
||||||
|
list(APPEND srcs "analog_comparator/ana_cmpr_etm.c")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# DAC related source files
|
# DAC related source files
|
||||||
|
108
components/driver/analog_comparator/ana_cmpr_etm.c
Normal file
108
components/driver/analog_comparator/ana_cmpr_etm.c
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#if CONFIG_ETM_ENABLE_DEBUG_LOG
|
||||||
|
// The local log level must be defined before including esp_log.h
|
||||||
|
// Set the maximum log level for this source file
|
||||||
|
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||||
|
#endif
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_check.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
#include "hal/ana_cmpr_ll.h"
|
||||||
|
#include "driver/ana_cmpr_types.h"
|
||||||
|
#include "driver/ana_cmpr_etm.h"
|
||||||
|
#include "esp_private/etm_interface.h"
|
||||||
|
|
||||||
|
static const char *TAG = "ana-cmpr-etm";
|
||||||
|
|
||||||
|
#define ETM_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
|
||||||
|
|
||||||
|
typedef struct ana_cmpr_etm_event_t ana_cmpr_etm_event_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
portMUX_TYPE spinlock;
|
||||||
|
ana_cmpr_etm_event_t *events[SOC_ANA_CMPR_ETM_EVENTS_PER_UNIT];
|
||||||
|
} ana_cmpr_etm_unit_t;
|
||||||
|
|
||||||
|
struct ana_cmpr_etm_event_t {
|
||||||
|
esp_etm_event_t base;
|
||||||
|
ana_cmpr_unit_t unit;
|
||||||
|
ana_cmpr_event_type_t type;
|
||||||
|
};
|
||||||
|
|
||||||
|
static ana_cmpr_etm_unit_t s_ana_cmpr_etm_unit[SOC_ANA_CMPR_NUM] = {
|
||||||
|
[0 ... SOC_ANA_CMPR_NUM - 1] = {
|
||||||
|
.spinlock = portMUX_INITIALIZER_UNLOCKED,
|
||||||
|
.events[0 ... SOC_ANA_CMPR_ETM_EVENTS_PER_UNIT - 1] = NULL,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static esp_err_t ana_cmpr_etm_event_register_to_unit(ana_cmpr_etm_event_t *evt)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(!s_ana_cmpr_etm_unit[evt->unit].events[evt->type],
|
||||||
|
ESP_ERR_INVALID_STATE, TAG, "this event has been registered on the unit");
|
||||||
|
portENTER_CRITICAL(&s_ana_cmpr_etm_unit[evt->unit].spinlock);
|
||||||
|
s_ana_cmpr_etm_unit[evt->unit].events[evt->type] = evt;
|
||||||
|
portEXIT_CRITICAL(&s_ana_cmpr_etm_unit[evt->unit].spinlock);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t ana_cmpr_etm_event_unregister_from_unit(ana_cmpr_etm_event_t *evt)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(s_ana_cmpr_etm_unit[evt->unit].events[evt->type] == evt,
|
||||||
|
ESP_ERR_INVALID_ARG, TAG, "the event handle is not match to registered handle");
|
||||||
|
portENTER_CRITICAL(&s_ana_cmpr_etm_unit[evt->unit].spinlock);
|
||||||
|
s_ana_cmpr_etm_unit[evt->unit].events[evt->type] = NULL;
|
||||||
|
portEXIT_CRITICAL(&s_ana_cmpr_etm_unit[evt->unit].spinlock);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t ana_cmpr_del_etm_event(esp_etm_event_handle_t base_event)
|
||||||
|
{
|
||||||
|
ana_cmpr_etm_event_t *event = __containerof(base_event, ana_cmpr_etm_event_t, base);
|
||||||
|
ESP_RETURN_ON_ERROR(ana_cmpr_etm_event_unregister_from_unit(event), TAG, "unregister the event from the unit");
|
||||||
|
free(event);
|
||||||
|
event = NULL;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t ana_cmpr_new_etm_event(const ana_cmpr_etm_event_config_t *config, esp_etm_event_handle_t *ret_event)
|
||||||
|
{
|
||||||
|
#if CONFIG_ETM_ENABLE_DEBUG_LOG
|
||||||
|
esp_log_level_set(TAG, ESP_LOG_DEBUG);
|
||||||
|
#endif
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
ana_cmpr_etm_event_t *event = NULL;
|
||||||
|
ESP_GOTO_ON_FALSE(config && ret_event, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
|
||||||
|
|
||||||
|
event = heap_caps_calloc(1, sizeof(ana_cmpr_etm_event_t), ETM_MEM_ALLOC_CAPS);
|
||||||
|
ESP_GOTO_ON_FALSE(event, ESP_ERR_NO_MEM, err, TAG, "no mem for analog comparator event");
|
||||||
|
event->unit = config->unit;
|
||||||
|
event->type = config->event_type;
|
||||||
|
// register the event channel to the group
|
||||||
|
ESP_GOTO_ON_ERROR(ana_cmpr_etm_event_register_to_unit(event), err, TAG, "register event channel to group failed");
|
||||||
|
|
||||||
|
uint32_t event_id = ANALOG_CMPR_LL_ETM_SOURCE(config->unit, 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;
|
||||||
|
ESP_LOGD(TAG, "new event @%p, event_id=%"PRIu32", unit_id=%d", event, event_id, config->unit);
|
||||||
|
*ret_event = &event->base;
|
||||||
|
return ESP_OK;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (event) {
|
||||||
|
free(event);
|
||||||
|
event = NULL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_etm.h"
|
||||||
|
#include "driver/ana_cmpr_types.h"
|
||||||
|
|
||||||
|
#if SOC_ANA_CMPR_SUPPORT_ETM
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ANA_CMPR_EVENT_POS_CROSS,
|
||||||
|
ANA_CMPR_EVENT_NEG_CROSS,
|
||||||
|
} ana_cmpr_event_type_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ana_cmpr_unit_t unit;
|
||||||
|
ana_cmpr_event_type_t event_type; /*!< Which kind of cross type can trigger the ETM event module */
|
||||||
|
} ana_cmpr_etm_event_config_t;
|
||||||
|
|
||||||
|
esp_err_t ana_cmpr_new_etm_event(const ana_cmpr_etm_event_config_t *config, esp_etm_event_handle_t *ret_event);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SOC_ANA_CMPR_SUPPORT_ETM
|
@@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/clk_tree_defs.h"
|
#include "soc/clk_tree_defs.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -18,7 +19,10 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ANA_CMPR_UNIT_0, /*!< Analog Comparator unit */
|
ANA_CMPR_UNIT_0, /*!< Analog Comparator unit 0 */
|
||||||
|
#if SOC_ANA_CMPR_NUM == 2
|
||||||
|
ANA_CMPR_UNIT_1, /*!< Analog Comparator unit 1 */
|
||||||
|
#endif
|
||||||
} ana_cmpr_unit_t;
|
} ana_cmpr_unit_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -25,6 +25,7 @@ typedef enum {
|
|||||||
ETM_TRIG_PERIPH_GPTIMER, /*!< ETM trigger source: GPTimer */
|
ETM_TRIG_PERIPH_GPTIMER, /*!< ETM trigger source: GPTimer */
|
||||||
ETM_TRIG_PERIPH_SYSTIMER, /*!< ETM trigger source: Systimer */
|
ETM_TRIG_PERIPH_SYSTIMER, /*!< ETM trigger source: Systimer */
|
||||||
ETM_TRIG_PERIPH_MCPWM, /*!< ETM trigger source: MCPWM */
|
ETM_TRIG_PERIPH_MCPWM, /*!< ETM trigger source: MCPWM */
|
||||||
|
ETM_TRIG_PERIPH_ANA_CMPR, /*!< ETM trigger source: Analog Comparator */
|
||||||
} etm_trigger_peripheral_t;
|
} etm_trigger_peripheral_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include "hal/misc.h"
|
#include "hal/misc.h"
|
||||||
#include "hal/assert.h"
|
#include "hal/assert.h"
|
||||||
#include "soc/ana_cmpr_struct.h"
|
#include "soc/ana_cmpr_struct.h"
|
||||||
|
#include "soc/soc_etm_source.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -22,6 +23,8 @@ extern "C" {
|
|||||||
#define ANALOG_CMPR_LL_NEG_CROSS_MASK(unit) (1UL << ((int)unit * 3))
|
#define ANALOG_CMPR_LL_NEG_CROSS_MASK(unit) (1UL << ((int)unit * 3))
|
||||||
#define ANALOG_CMPR_LL_POS_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 1))
|
#define ANALOG_CMPR_LL_POS_CROSS_MASK(unit) (1UL << ((int)unit * 3 + 1))
|
||||||
|
|
||||||
|
#define ANALOG_CMPR_LL_ETM_SOURCE(unit, type) (GPIO_EVT_ZERO_DET_POS0 + (unit) * 2 + (type))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable analog comparator
|
* @brief Enable analog comparator
|
||||||
*
|
*
|
||||||
|
@@ -395,6 +395,14 @@ config SOC_ANA_CMPR_SUPPORT_MULTI_INTR
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_ANA_CMPR_SUPPORT_ETM
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
config SOC_ANA_CMPR_ETM_EVENTS_PER_UNIT
|
||||||
|
int
|
||||||
|
default 2
|
||||||
|
|
||||||
config SOC_I2C_NUM
|
config SOC_I2C_NUM
|
||||||
int
|
int
|
||||||
default 2
|
default 2
|
||||||
|
@@ -553,7 +553,7 @@ typedef union {
|
|||||||
uint32_t val;
|
uint32_t val;
|
||||||
} gpio_clock_gate_reg_t;
|
} gpio_clock_gate_reg_t;
|
||||||
|
|
||||||
/** Type of zero_det0_filter_cnt register
|
/** Type of zero_det_filter_cnt register
|
||||||
* GPIO analog comparator zero detect filter count
|
* GPIO analog comparator zero detect filter count
|
||||||
*/
|
*/
|
||||||
typedef union {
|
typedef union {
|
||||||
|
@@ -221,8 +221,10 @@
|
|||||||
#define SOC_DEDIC_PERIPH_ALWAYS_ENABLE (1) /*!< The dedicated GPIO (a.k.a. fast GPIO) is featured by some customized CPU instructions, which is always enabled */
|
#define SOC_DEDIC_PERIPH_ALWAYS_ENABLE (1) /*!< The dedicated GPIO (a.k.a. fast GPIO) is featured by some customized CPU instructions, which is always enabled */
|
||||||
|
|
||||||
/*------------------------- Analog Comparator CAPS ---------------------------*/
|
/*------------------------- Analog Comparator CAPS ---------------------------*/
|
||||||
#define SOC_ANA_CMPR_NUM (2U)
|
#define SOC_ANA_CMPR_NUM (2U)
|
||||||
#define SOC_ANA_CMPR_SUPPORT_MULTI_INTR (1)
|
#define SOC_ANA_CMPR_SUPPORT_MULTI_INTR (1)
|
||||||
|
#define SOC_ANA_CMPR_SUPPORT_ETM (1)
|
||||||
|
#define SOC_ANA_CMPR_ETM_EVENTS_PER_UNIT (2)
|
||||||
|
|
||||||
/*-------------------------- I2C CAPS ----------------------------------------*/
|
/*-------------------------- I2C CAPS ----------------------------------------*/
|
||||||
// ESP32-P4 has 2 I2Cs
|
// ESP32-P4 has 2 I2Cs
|
||||||
|
Reference in New Issue
Block a user