Merge branch 'feat/etm_driver_support_esp32c5' into 'master'

feat(etm): support etm driver on esp32c5

Closes IDF-8693

See merge request espressif/esp-idf!32009
This commit is contained in:
morris
2024-07-15 18:05:49 +08:00
34 changed files with 465 additions and 985 deletions

View File

@@ -0,0 +1,117 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// Note that most of the register operations in this layer are non-atomic operations.
#pragma once
#include <stdbool.h>
#include "hal/assert.h"
#include "hal/misc.h"
#include "soc/soc_etm_struct.h"
#include "soc/pcr_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Enable the clock for ETM register
*
* @param group_id Group ID
* @param enable true to enable, false to disable
*/
static inline void etm_ll_enable_bus_clock(int group_id, bool enable)
{
(void)group_id;
PCR.etm_conf.etm_clk_en = enable;
}
/**
* @brief Reset the ETM register
*
* @param group_id Group ID
*/
static inline void etm_ll_reset_register(int group_id)
{
(void)group_id;
PCR.etm_conf.etm_rst_en = 1;
PCR.etm_conf.etm_rst_en = 0;
}
/**
* @brief Enable ETM channel
*
* @param hw ETM register base address
* @param chan Channel ID
*/
static inline void etm_ll_enable_channel(soc_etm_dev_t *hw, uint32_t chan)
{
if (chan < 32) {
hw->ch_ena_ad0_set.val = 1 << chan;
} else {
hw->ch_ena_ad1_set.val = 1 << (chan - 32);
}
}
/**
* @brief Disable ETM channel
*
* @param hw ETM register base address
* @param chan Channel ID
*/
static inline void etm_ll_disable_channel(soc_etm_dev_t *hw, uint32_t chan)
{
if (chan < 32) {
hw->ch_ena_ad0_clr.val = 1 << chan;
} else {
hw->ch_ena_ad1_clr.val = 1 << (chan - 32);
}
}
/**
* @brief Check whether the ETM channel is enabled or not
*
* @param hw ETM register base address
* @param chan Channel ID
* @return true if the channel is enabled, false otherwise
*/
static inline bool etm_ll_is_channel_enabled(soc_etm_dev_t *hw, uint32_t chan)
{
if (chan < 32) {
return hw->ch_ena_ad0.val & (1 << chan);
} else {
return hw->ch_ena_ad1.val & (1 << (chan - 32));
}
}
/**
* @brief Set the input event for the ETM channel
*
* @param hw ETM register base address
* @param chan Channel ID
* @param event Event ID
*/
static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, uint32_t event)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].eid, chn_evt_id, event);
}
/**
* @brief Set the output task for the ETM channel
*
* @param hw ETM register base address
* @param chan Channel ID
* @param task Task ID
*/
static inline void etm_ll_channel_set_task(soc_etm_dev_t *hw, uint32_t chan, uint32_t task)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].tid, chn_task_id, task);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,136 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// Note that most of the register operations in this layer are non-atomic operations.
#pragma once
#include <stdbool.h>
#include "hal/assert.h"
#include "hal/misc.h"
#include "soc/gpio_ext_struct.h"
#include "soc/soc_etm_source.h"
#define GPIO_LL_ETM_EVENT_ID_POS_EDGE(ch) (GPIO_EVT_CH0_RISE_EDGE + (ch))
#define GPIO_LL_ETM_EVENT_ID_NEG_EDGE(ch) (GPIO_EVT_CH0_FALL_EDGE + (ch))
#define GPIO_LL_ETM_EVENT_ID_ANY_EDGE(ch) (GPIO_EVT_CH0_ANY_EDGE + (ch))
#define GPIO_LL_ETM_TASK_ID_SET(ch) (GPIO_TASK_CH0_SET + (ch))
#define GPIO_LL_ETM_TASK_ID_CLR(ch) (GPIO_TASK_CH0_CLEAR + (ch))
#define GPIO_LL_ETM_TASK_ID_TOG(ch) (GPIO_TASK_CH0_TOGGLE + (ch))
#define GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP 8
#define GPIO_LL_ETM_TASK_CHANNELS_PER_GROUP 8
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Set which GPIO to be bound to the event channel
*
* @note Different channels can be bound to one GPIO
*
* @param dev Register base address
* @param chan GPIO ETM Event channel number
* @param gpio_num GPIO number
*/
static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint32_t chan, uint32_t gpio_num)
{
dev->etm_event_chn_cfg[chan].etm_chn_event_sel = gpio_num;
}
/**
* @brief Whether to enable the event channel
*
* @param dev Register base address
* @param chan GPIO ETM Event channel number
* @param enable True to enable, false to disable
*/
static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_t chan, bool enable)
{
dev->etm_event_chn_cfg[chan].etm_chn_event_en = enable;
}
/**
* @brief Get which GPIO is bound to the event channel
*
* @param dev Register base address
* @param chan GPIO ETM Event channel number
* @return GPIO number
*/
static inline uint32_t gpio_ll_etm_event_channel_get_gpio(gpio_etm_dev_t *dev, uint32_t chan)
{
return dev->etm_event_chn_cfg[chan].etm_chn_event_sel;
}
/**
* @brief Set which GPIO to be bound to the task channel
*
* @note One channel can be bound to multiple different GPIOs
*
* @param dev Register base address
* @param chan GPIO ETM Task channel number
* @param gpio_num GPIO number
*/
static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32_t gpio_num, uint32_t chan)
{
int g_p = gpio_num / 5;
int g_idx = gpio_num % 5;
uint32_t reg_val = dev->etm_task_pn_cfg[g_p].val;
reg_val &= ~(0x07 << (g_idx * 6));
reg_val |= ((chan & 0x07) << (g_idx * 6));
dev->etm_task_pn_cfg[g_p].val = reg_val;
}
/**
* @brief Whether to enable the GPIO to be managed by the task channel
*
* @param dev Register base address
* @param gpio_num GPIO number
* @param enable True to enable, false to disable
*/
static inline void gpio_ll_etm_enable_task_gpio(gpio_etm_dev_t *dev, uint32_t gpio_num, bool enable)
{
int g_p = gpio_num / 5;
int g_idx = gpio_num % 5;
uint32_t reg_val = dev->etm_task_pn_cfg[g_p].val;
reg_val &= ~(0x01 << (g_idx * 6 + 5));
reg_val |= ((enable & 0x01) << (g_idx * 6 + 5));
dev->etm_task_pn_cfg[g_p].val = reg_val;
}
/**
* @brief Check whether a GPIO has been enabled and managed by a task channel
*
* @param dev Register base address
* @param gpio_num GPIO number
* @return True if enabled, false otherwise
*/
static inline bool gpio_ll_etm_is_task_gpio_enabled(gpio_etm_dev_t *dev, uint32_t gpio_num)
{
int g_p = gpio_num / 5;
int g_idx = gpio_num % 5;
return dev->etm_task_pn_cfg[g_p].val & (0x01 << (g_idx * 6 + 5));
}
/**
* @brief Get the channel number that the GPIO is bound to
*
* @param dev Register base address
* @param gpio_num GPIO number
* @return GPIO ETM Task channel number
*/
static inline uint32_t gpio_ll_etm_gpio_get_task_channel(gpio_etm_dev_t *dev, uint32_t gpio_num)
{
int g_p = gpio_num / 5;
int g_idx = gpio_num % 5;
return (dev->etm_task_pn_cfg[g_p].val >> (g_idx * 6)) & 0x07;
}
#ifdef __cplusplus
}
#endif

View File

@@ -25,30 +25,30 @@ extern "C" {
#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
#define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
(uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \
[GPTIMER_ETM_TASK_START_COUNT] = TIMER0_TASK_CNT_START_TIMER0, \
[GPTIMER_ETM_TASK_STOP_COUNT] = TIMER0_TASK_CNT_STOP_TIMER0, \
[GPTIMER_ETM_TASK_EN_ALARM] = TIMER0_TASK_ALARM_START_TIMER0, \
[GPTIMER_ETM_TASK_RELOAD] = TIMER0_TASK_CNT_RELOAD_TIMER0, \
[GPTIMER_ETM_TASK_CAPTURE] = TIMER0_TASK_CNT_CAP_TIMER0, \
}}, \
{{ \
[GPTIMER_ETM_TASK_START_COUNT] = TIMER1_TASK_CNT_START_TIMER0, \
[GPTIMER_ETM_TASK_STOP_COUNT] = TIMER1_TASK_CNT_STOP_TIMER0, \
[GPTIMER_ETM_TASK_EN_ALARM] = TIMER1_TASK_ALARM_START_TIMER0, \
[GPTIMER_ETM_TASK_RELOAD] = TIMER1_TASK_CNT_RELOAD_TIMER0, \
[GPTIMER_ETM_TASK_CAPTURE] = TIMER1_TASK_CNT_CAP_TIMER0, \
}}, \
#define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
(uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \
[GPTIMER_ETM_TASK_START_COUNT] = TG0_TASK_CNT_START_TIMER0, \
[GPTIMER_ETM_TASK_STOP_COUNT] = TG0_TASK_CNT_STOP_TIMER0, \
[GPTIMER_ETM_TASK_EN_ALARM] = TG0_TASK_ALARM_START_TIMER0, \
[GPTIMER_ETM_TASK_RELOAD] = TG0_TASK_CNT_RELOAD_TIMER0, \
[GPTIMER_ETM_TASK_CAPTURE] = TG0_TASK_CNT_CAP_TIMER0, \
}}, \
{{ \
[GPTIMER_ETM_TASK_START_COUNT] = TG1_TASK_CNT_START_TIMER0, \
[GPTIMER_ETM_TASK_STOP_COUNT] = TG1_TASK_CNT_STOP_TIMER0, \
[GPTIMER_ETM_TASK_EN_ALARM] = TG1_TASK_ALARM_START_TIMER0, \
[GPTIMER_ETM_TASK_RELOAD] = TG1_TASK_CNT_RELOAD_TIMER0, \
[GPTIMER_ETM_TASK_CAPTURE] = TG1_TASK_CNT_CAP_TIMER0, \
}}, \
}[group][timer][task]
#define TIMER_LL_ETM_EVENT_TABLE(group, timer, event) \
(uint32_t [2][1][GPTIMER_ETM_EVENT_MAX]){{{ \
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TIMER0_EVT_CNT_CMP_TIMER0, \
}}, \
{{ \
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TIMER1_EVT_CNT_CMP_TIMER0, \
}}, \
#define TIMER_LL_ETM_EVENT_TABLE(group, timer, event) \
(uint32_t [2][1][GPTIMER_ETM_EVENT_MAX]){{{ \
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TG0_EVT_CNT_CMP_TIMER0, \
}}, \
{{ \
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TG1_EVT_CNT_CMP_TIMER0, \
}}, \
}[group][timer][event]
/**