diff --git a/components/esp_hw_support/test_apps/etm/README.md b/components/esp_hw_support/test_apps/etm/README.md index e3ba9c6759..b450dc5ffa 100644 --- a/components/esp_hw_support/test_apps/etm/README.md +++ b/components/esp_hw_support/test_apps/etm/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32-C6 | -| ----------------- | -------- | +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | diff --git a/components/esp_hw_support/test_apps/etm/main/test_gptimer_etm.c b/components/esp_hw_support/test_apps/etm/main/test_gptimer_etm.c index 06d0bc8816..e6c752c12e 100644 --- a/components/esp_hw_support/test_apps/etm/main/test_gptimer_etm.c +++ b/components/esp_hw_support/test_apps/etm/main/test_gptimer_etm.c @@ -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 */ @@ -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)); diff --git a/components/esp_hw_support/test_apps/etm/main/test_systimer_etm.c b/components/esp_hw_support/test_apps/etm/main/test_systimer_etm.c index 69bf008e00..81b6e48f2c 100644 --- a/components/esp_hw_support/test_apps/etm/main/test_systimer_etm.c +++ b/components/esp_hw_support/test_apps/etm/main/test_systimer_etm.c @@ -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 */ @@ -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" diff --git a/components/esp_hw_support/test_apps/etm/pytest_etm.py b/components/esp_hw_support/test_apps/etm/pytest_etm.py index 6a795fe95d..461804e9e0 100644 --- a/components/esp_hw_support/test_apps/etm/pytest_etm.py +++ b/components/esp_hw_support/test_apps/etm/pytest_etm.py @@ -1,4 +1,4 @@ -# 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 @@ -6,6 +6,7 @@ from pytest_embedded import Dut @pytest.mark.esp32c6 +@pytest.mark.esp32h2 @pytest.mark.generic @pytest.mark.parametrize( 'config', diff --git a/components/hal/esp32h2/include/hal/clk_gate_ll.h b/components/hal/esp32h2/include/hal/clk_gate_ll.h index 9f3c55fcd4..349bc4aa74 100644 --- a/components/hal/esp32h2/include/hal/clk_gate_ll.h +++ b/components/hal/esp32h2/include/hal/clk_gate_ll.h @@ -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: @@ -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. @@ -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: @@ -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: diff --git a/components/hal/esp32h2/include/hal/etm_ll.h b/components/hal/esp32h2/include/hal/etm_ll.h new file mode 100644 index 0000000000..e15a77f4a2 --- /dev/null +++ b/components/hal/esp32h2/include/hal/etm_ll.h @@ -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 +#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 diff --git a/components/hal/esp32h2/include/hal/gpio_etm_ll.h b/components/hal/esp32h2/include/hal/gpio_etm_ll.h new file mode 100644 index 0000000000..49da6692ba --- /dev/null +++ b/components/hal/esp32h2/include/hal/gpio_etm_ll.h @@ -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 +#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 diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 69cc116a32..9e62f91e5a 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/components/soc/esp32h2/include/soc/periph_defs.h b/components/soc/esp32h2/include/soc/periph_defs.h index 167ef1bf8f..4268055c0d 100644 --- a/components/soc/esp32h2/include/soc/periph_defs.h +++ b/components/soc/esp32h2/include/soc/periph_defs.h @@ -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 diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index c9ddaf27cd..9a327a59ab 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -47,6 +47,7 @@ #define SOC_RTC_MEM_SUPPORTED 1 #define SOC_I2S_SUPPORTED 1 #define SOC_SDM_SUPPORTED 1 +#define SOC_ETM_SUPPORTED 1 #define SOC_RMT_SUPPORTED 1 // #define SOC_GPSPI_SUPPORTED 1 // TODO: IDF-6264 #define SOC_LEDC_SUPPORTED 1 @@ -147,11 +148,20 @@ #define SOC_GDMA_PAIRS_PER_GROUP (3) // Number of GDMA pairs in each group #define SOC_GDMA_SUPPORT_ETM (1) // Support ETM submodule +/*-------------------------- ETM CAPS --------------------------------------*/ +#define SOC_ETM_GROUPS 1U // Number of ETM groups +#define SOC_ETM_CHANNELS_PER_GROUP 50 // Number of ETM channels in the group + /*-------------------------- GPIO CAPS ---------------------------------------*/ // ESP32-H2 has 1 GPIO peripheral #define SOC_GPIO_PORT (1U) #define SOC_GPIO_PIN_COUNT (28) +// GPIO peripheral has the ETM extension +#define SOC_GPIO_SUPPORT_ETM 1 +#define SOC_GPIO_ETM_EVENTS_PER_GROUP 8 +#define SOC_GPIO_ETM_TASKS_PER_GROUP 8 + // Target has no full LP IO subsystem, GPIO7~14 remain LP function (powered by VDD3V3_LP, and can be used as deep-sleep wakeup pins) // GPIO7~14 on ESP32H2 can support chip deep sleep wakeup @@ -348,7 +358,7 @@ #define SOC_TIMER_GROUP_SUPPORT_PLL_F48M (1) // #define SOC_TIMER_GROUP_SUPPORT_RC_FAST (1) // TODO: IDF-6265 #define SOC_TIMER_GROUP_TOTAL_TIMERS (2) -// #define SOC_TIMER_SUPPORT_ETM (1) +#define SOC_TIMER_SUPPORT_ETM (1) // TODO: IDF-6217 (Copy from esp32c6, need check) /*-------------------------- TWAI CAPS ---------------------------------------*/ diff --git a/components/soc/esp32h2/ld/esp32h2.peripherals.ld b/components/soc/esp32h2/ld/esp32h2.peripherals.ld index 8e74e69474..9eae994fe2 100644 --- a/components/soc/esp32h2/ld/esp32h2.peripherals.ld +++ b/components/soc/esp32h2/ld/esp32h2.peripherals.ld @@ -41,10 +41,12 @@ PROVIDE ( ECC = 0x6008B000 ); PROVIDE ( DS = 0x6008C000 ); PROVIDE ( HMAC = 0x6008D000 ); -PROVIDE ( IO_MUX = 0x60090000 ); -PROVIDE ( GPIO = 0x60091000 ); -PROVIDE ( GPIO_EXT = 0x60091f00 ); -PROVIDE ( SDM = 0x60091f00 ); /*ESP32H2-TODO*/ +PROVIDE ( IO_MUX = 0x60090000 ); +PROVIDE ( GPIO = 0x60091000 ); +PROVIDE ( GPIO_EXT = 0x60091f00 ); +PROVIDE ( SDM = 0x60091f00 ); +PROVIDE ( GLITCH_FILTER = 0x60091f30 ); +PROVIDE ( GPIO_ETM = 0x60091f60 ); PROVIDE ( MEM_ACS_MONITOR = 0x60092000 ); PROVIDE ( PAU = 0x60093000 ); diff --git a/docs/docs_not_updated/esp32h2.txt b/docs/docs_not_updated/esp32h2.txt index ed7f009e9e..3696c751c4 100644 --- a/docs/docs_not_updated/esp32h2.txt +++ b/docs/docs_not_updated/esp32h2.txt @@ -77,7 +77,6 @@ api-reference/peripherals/usb_device api-reference/peripherals/sdspi_host api-reference/peripherals/dac api-reference/peripherals/spi_slave -api-reference/peripherals/etm api-reference/peripherals/i2s api-reference/peripherals/touch_element api-reference/peripherals/lcd diff --git a/examples/peripherals/timer_group/gptimer_capture_hc_sr04/README.md b/examples/peripherals/timer_group/gptimer_capture_hc_sr04/README.md index 692651d778..144af4a23f 100644 --- a/examples/peripherals/timer_group/gptimer_capture_hc_sr04/README.md +++ b/examples/peripherals/timer_group/gptimer_capture_hc_sr04/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C6 | -| ----------------- | -------- | +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | # HC-SR04 Example based on GPTimer Capture and ETM diff --git a/examples/peripherals/timer_group/gptimer_capture_hc_sr04/pytest_gptimer_capture_example.py b/examples/peripherals/timer_group/gptimer_capture_hc_sr04/pytest_gptimer_capture_example.py index 83b7945edf..fb58810528 100644 --- a/examples/peripherals/timer_group/gptimer_capture_hc_sr04/pytest_gptimer_capture_example.py +++ b/examples/peripherals/timer_group/gptimer_capture_hc_sr04/pytest_gptimer_capture_example.py @@ -1,4 +1,4 @@ -# 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 @@ -6,6 +6,7 @@ from pytest_embedded import Dut @pytest.mark.esp32c6 +@pytest.mark.esp32h2 @pytest.mark.generic def test_gptimer_capture(dut: Dut) -> None: dut.expect_exact('Configure trig gpio')