mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-09 20:41:14 +00:00
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:
117
components/hal/esp32c5/include/hal/etm_ll.h
Normal file
117
components/hal/esp32c5/include/hal/etm_ll.h
Normal 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
|
136
components/hal/esp32c5/include/hal/gpio_etm_ll.h
Normal file
136
components/hal/esp32c5/include/hal/gpio_etm_ll.h
Normal 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
|
@@ -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]
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user