Skip to content

Commit

Permalink
Merge branch 'feature/etm_support_h2' into 'master'
Browse files Browse the repository at this point in the history
etm: add basic driver on esp32h2

Closes IDF-6225

See merge request espressif/esp-idf!22246
  • Loading branch information
suda-morris committed Feb 8, 2023
2 parents f3d4d7a + 6b50733 commit c5e3139
Show file tree
Hide file tree
Showing 11 changed files with 284 additions and 12 deletions.
4 changes: 2 additions & 2 deletions components/esp_hw_support/test_apps/etm/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
| Supported Targets | ESP32-C6 |
| ----------------- | -------- |
| Supported Targets | ESP32-C6 | ESP32-H2 |
| ----------------- | -------- | -------- |
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -436,7 +436,7 @@ TEST_CASE("gptimer_start_stop_by_etm_task", "[etm]")
uint64_t cur_count_val = 0;
TEST_ESP_OK(gptimer_get_raw_count(gptimer, &cur_count_val));
printf("cur_count_val: %llu\r\n", cur_count_val);
TEST_ASSERT_UINT_WITHIN(900, 500000, cur_count_val);
TEST_ASSERT_UINT_WITHIN(1000, 500000, cur_count_val);

// trigger an neg-edge, this should stop the gptimer
TEST_ESP_OK(gpio_set_level(input_gpio, 0));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -105,7 +105,7 @@ TEST_CASE("esp_timer_etm_event", "[etm]")
TEST_ESP_OK(esp_etm_channel_connect(etm_channel_a, esp_timer_event, gpio_task));
TEST_ESP_OK(esp_etm_channel_enable(etm_channel_a));

printf("create a periodic esp_timer\r\b");
printf("create a periodic esp_timer\r\n");
const esp_timer_create_args_t periodic_timer_args = {
.callback = periodic_timer_callback,
.name = "periodic"
Expand Down
3 changes: 2 additions & 1 deletion components/esp_hw_support/test_apps/etm/pytest_etm.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0

import pytest
from pytest_embedded import Dut


@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.generic
@pytest.mark.parametrize(
'config',
Expand Down
8 changes: 8 additions & 0 deletions components/hal/esp32h2/include/hal/clk_gate_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
return PCR_GDMA_CLK_EN;
case PERIPH_MCPWM0_MODULE:
return PCR_PWM_CLK_EN;
case PERIPH_ETM_MODULE:
return PCR_ETM_CLK_EN;
case PERIPH_AES_MODULE:
return PCR_AES_CLK_EN;
case PERIPH_SHA_MODULE:
Expand Down Expand Up @@ -124,6 +126,8 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en
return PCR_GDMA_RST_EN;
case PERIPH_MCPWM0_MODULE:
return PCR_PWM_RST_EN;
case PERIPH_ETM_MODULE:
return PCR_ETM_RST_EN;
case PERIPH_AES_MODULE:
if (enable == true) {
// Clear reset on digital signature, otherwise AES unit is held in reset also.
Expand Down Expand Up @@ -216,6 +220,8 @@ static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
return PCR_GDMA_CONF_REG;
case PERIPH_MCPWM0_MODULE:
return PCR_PWM_CONF_REG;
case PERIPH_ETM_MODULE:
return PCR_ETM_CONF_REG;
case PERIPH_AES_MODULE:
return PCR_AES_CONF_REG;
case PERIPH_SHA_MODULE:
Expand Down Expand Up @@ -271,6 +277,8 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
return PCR_GDMA_CONF_REG;
case PERIPH_MCPWM0_MODULE:
return PCR_PWM_CONF_REG;
case PERIPH_ETM_MODULE:
return PCR_ETM_CONF_REG;
case PERIPH_AES_MODULE:
return PCR_AES_CONF_REG;
case PERIPH_SHA_MODULE:
Expand Down
103 changes: 103 additions & 0 deletions components/hal/esp32h2/include/hal/etm_ll.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* SPDX-FileCopyrightText: 2023 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"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Enable the clock for ETM module
*
* @param hw ETM register base address
* @param enable true to enable, false to disable
*/
static inline void etm_ll_enable_clock(soc_etm_dev_t *hw, bool enable)
{
hw->clk_en.clk_en = enable;
}

/**
* @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)
{
hw->channel[chan].evt_id.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)
{
hw->channel[chan].task_id.task_id = task;
}

#ifdef __cplusplus
}
#endif
119 changes: 119 additions & 0 deletions components/hal/esp32h2/include/hal/gpio_etm_ll.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* SPDX-FileCopyrightText: 2023 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))

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Set which GPIO to be bounded to the event channel
*
* @param dev Register base address
* @param chan 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_ch0_event_sel = gpio_num;
}

/**
* @brief Wether to enable the event channel
*
* @param dev Register base address
* @param chan 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_ch0_event_en = enable;
}

/**
* @brief Set which GPIO to be bounded to the task channel
*
* @note One channel can be bounded to multiple different GPIOs
*
* @param dev Register base address
* @param chan 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 / 4;
int g_idx = gpio_num % 4;
uint32_t reg_val = dev->etm_task_pn_cfg[g_p].val;
reg_val &= ~(0x07 << (g_idx * 8 + 1));
reg_val |= ((chan & 0x07) << (g_idx * 8 + 1));
dev->etm_task_pn_cfg[g_p].val = reg_val;
}

/**
* @brief Wether 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 / 4;
int g_idx = gpio_num % 4;
uint32_t reg_val = dev->etm_task_pn_cfg[g_p].val;
reg_val &= ~(0x01 << (g_idx * 8));
reg_val |= ((enable & 0x01) << (g_idx * 8));
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 / 4;
int g_idx = gpio_num % 4;
return dev->etm_task_pn_cfg[g_p].val & (0x01 << (g_idx * 8));
}

/**
* @brief Get the channel number that the GPIO is bounded 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 / 4;
int g_idx = gpio_num % 4;
return (dev->etm_task_pn_cfg[g_p].val >> (g_idx * 8 + 1)) & 0x07;
}

#ifdef __cplusplus
}
#endif
28 changes: 28 additions & 0 deletions components/soc/esp32h2/include/soc/Kconfig.soc_caps.in
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ config SOC_SDM_SUPPORTED
bool
default y

config SOC_ETM_SUPPORTED
bool
default y

config SOC_RMT_SUPPORTED
bool
default y
Expand Down Expand Up @@ -259,6 +263,14 @@ config SOC_GDMA_SUPPORT_ETM
bool
default y

config SOC_ETM_GROUPS
int
default 1

config SOC_ETM_CHANNELS_PER_GROUP
int
default 50

config SOC_GPIO_PORT
int
default 1
Expand All @@ -267,6 +279,18 @@ config SOC_GPIO_PIN_COUNT
int
default 28

config SOC_GPIO_SUPPORT_ETM
bool
default y

config SOC_GPIO_ETM_EVENTS_PER_GROUP
int
default 8

config SOC_GPIO_ETM_TASKS_PER_GROUP
int
default 8

config SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
bool
default y
Expand Down Expand Up @@ -715,6 +739,10 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS
int
default 2

config SOC_TIMER_SUPPORT_ETM
bool
default y

config SOC_TWAI_CONTROLLER_NUM
bool
default y
Expand Down
1 change: 1 addition & 0 deletions components/soc/esp32h2/include/soc/periph_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ typedef enum {
PERIPH_DS_MODULE,
PERIPH_GDMA_MODULE,
PERIPH_MCPWM0_MODULE,
PERIPH_ETM_MODULE,
PERIPH_SYSTIMER_MODULE,
PERIPH_SARADC_MODULE,
PERIPH_MODULE_MAX
Expand Down
Loading

0 comments on commit c5e3139

Please sign in to comment.