From e96491fb1f861668c66ac5e0fe1be36d82531e2f Mon Sep 17 00:00:00 2001 From: morris Date: Thu, 7 Dec 2023 17:30:39 +0800 Subject: [PATCH] feat(systimer): support ETM on esp32p4 --- components/esp_rom/esp32p4/ld/esp32p4.rom.ld | 5 +-- .../esp_timer/src/esp_timer_impl_systimer.c | 7 +++- components/freertos/port_systick.c | 7 +++- .../hal/esp32c2/include/hal/systimer_ll.h | 32 ++++++++++++++++- .../hal/esp32c3/include/hal/systimer_ll.h | 32 ++++++++++++++++- .../hal/esp32c6/include/hal/systimer_ll.h | 29 +++++++++++++++ .../hal/esp32h2/include/hal/systimer_ll.h | 29 +++++++++++++++ .../hal/esp32p4/include/hal/clk_gate_ll.h | 6 ---- .../hal/esp32p4/include/hal/systimer_ll.h | 30 +++++++++++++++- .../hal/esp32s2/include/hal/systimer_ll.h | 35 ++++++++++++++++++- .../hal/esp32s3/include/hal/systimer_ll.h | 32 ++++++++++++++++- .../esp32p4/include/soc/Kconfig.soc_caps.in | 4 +++ components/soc/esp32p4/include/soc/soc_caps.h | 2 +- 13 files changed, 234 insertions(+), 16 deletions(-) diff --git a/components/esp_rom/esp32p4/ld/esp32p4.rom.ld b/components/esp_rom/esp32p4/ld/esp32p4.rom.ld index d39827a70a..92dd194fd5 100644 --- a/components/esp_rom/esp32p4/ld/esp32p4.rom.ld +++ b/components/esp_rom/esp32p4/ld/esp32p4.rom.ld @@ -175,8 +175,9 @@ g_flash_guard_ops = 0x4ff3fff0; ***************************************/ /* Functions */ -systimer_hal_init = 0x4fc00228; -systimer_hal_deinit = 0x4fc0022c; +/* The following ROM functions are commented out because they're patched in the esp_rom_systimer.c */ +/* systimer_hal_init = 0x4fc00228; */ +/* systimer_hal_deinit = 0x4fc0022c; */ systimer_hal_set_tick_rate_ops = 0x4fc00230; systimer_hal_get_counter_value = 0x4fc00234; systimer_hal_get_time = 0x4fc00238; diff --git a/components/esp_timer/src/esp_timer_impl_systimer.c b/components/esp_timer/src/esp_timer_impl_systimer.c index dbd701ee62..2c1a9362d7 100644 --- a/components/esp_timer/src/esp_timer_impl_systimer.c +++ b/components/esp_timer/src/esp_timer_impl_systimer.c @@ -156,7 +156,12 @@ void esp_timer_impl_advance(int64_t time_diff_us) esp_err_t esp_timer_impl_early_init(void) { - periph_module_enable(PERIPH_SYSTIMER_MODULE); + PERIPH_RCC_ACQUIRE_ATOMIC(PERIPH_SYSTIMER_MODULE, ref_count) { + if (ref_count == 0) { + systimer_ll_enable_bus_clock(true); + systimer_ll_reset_register(); + } + } systimer_hal_tick_rate_ops_t ops = { .ticks_to_us = systimer_ticks_to_us, .us_to_ticks = systimer_us_to_ticks, diff --git a/components/freertos/port_systick.c b/components/freertos/port_systick.c index cc2fa3fc52..20be1b8747 100644 --- a/components/freertos/port_systick.c +++ b/components/freertos/port_systick.c @@ -72,7 +72,12 @@ void vSystimerSetup(void) ESP_ERROR_CHECK(esp_intr_alloc(ETS_SYSTIMER_TARGET0_INTR_SOURCE + cpuid, ESP_INTR_FLAG_IRAM | level, SysTickIsrHandler, &systimer_hal, NULL)); if (cpuid == 0) { - periph_module_enable(PERIPH_SYSTIMER_MODULE); + PERIPH_RCC_ACQUIRE_ATOMIC(PERIPH_SYSTIMER_MODULE, ref_count) { + if (ref_count == 0) { + systimer_ll_enable_bus_clock(true); + systimer_ll_reset_register(); + } + } systimer_hal_init(&systimer_hal); systimer_hal_tick_rate_ops_t ops = { .ticks_to_us = systimer_ticks_to_us, diff --git a/components/hal/esp32c2/include/hal/systimer_ll.h b/components/hal/esp32c2/include/hal/systimer_ll.h index f5bb4d1ffd..5bcc86cdd8 100644 --- a/components/hal/esp32c2/include/hal/systimer_ll.h +++ b/components/hal/esp32c2/include/hal/systimer_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,7 @@ #include #include "soc/systimer_struct.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/assert.h" #ifdef __cplusplus @@ -35,6 +36,35 @@ static inline soc_periph_systimer_clk_src_t systimer_ll_get_clock_source(void) return SYSTIMER_CLK_SRC_XTAL; } +/** + * @brief Enable the bus clock for systimer module + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en0.systimer_clk_en = enable; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the systimer module + * + * @param group_id Group ID + */ +static inline void systimer_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.systimer_rst = 1; + SYSTEM.perip_rst_en0.systimer_rst = 0; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_reset_register(__VA_ARGS__) + /******************* Counter *************************/ __attribute__((always_inline)) static inline void systimer_ll_enable_counter(systimer_dev_t *dev, uint32_t counter_id, bool en) diff --git a/components/hal/esp32c3/include/hal/systimer_ll.h b/components/hal/esp32c3/include/hal/systimer_ll.h index f5bb4d1ffd..c5c8efe484 100644 --- a/components/hal/esp32c3/include/hal/systimer_ll.h +++ b/components/hal/esp32c3/include/hal/systimer_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,7 @@ #include #include "soc/systimer_struct.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/assert.h" #ifdef __cplusplus @@ -35,6 +36,35 @@ static inline soc_periph_systimer_clk_src_t systimer_ll_get_clock_source(void) return SYSTIMER_CLK_SRC_XTAL; } +/** + * @brief Enable the bus clock for systimer module + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en0.reg_systimer_clk_en = enable; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the systimer module + * + * @param group_id Group ID + */ +static inline void systimer_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.reg_systimer_rst = 1; + SYSTEM.perip_rst_en0.reg_systimer_rst = 0; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_reset_register(__VA_ARGS__) + /******************* Counter *************************/ __attribute__((always_inline)) static inline void systimer_ll_enable_counter(systimer_dev_t *dev, uint32_t counter_id, bool en) diff --git a/components/hal/esp32c6/include/hal/systimer_ll.h b/components/hal/esp32c6/include/hal/systimer_ll.h index 74dedc721f..aa68091757 100644 --- a/components/hal/esp32c6/include/hal/systimer_ll.h +++ b/components/hal/esp32c6/include/hal/systimer_ll.h @@ -37,6 +37,35 @@ static inline soc_periph_systimer_clk_src_t systimer_ll_get_clock_source(void) return (PCR.systimer_func_clk_conf.systimer_func_clk_sel == 1) ? SYSTIMER_CLK_SRC_RC_FAST : SYSTIMER_CLK_SRC_XTAL; } +/** + * @brief Enable the bus clock for systimer module + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_bus_clock(bool enable) +{ + PCR.systimer_conf.systimer_clk_en = enable; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the systimer module + * + * @param group_id Group ID + */ +static inline void systimer_ll_reset_register(void) +{ + PCR.systimer_conf.systimer_rst_en = 1; + PCR.systimer_conf.systimer_rst_en = 0; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_reset_register(__VA_ARGS__) + /********************** ETM *****************************/ __attribute__((always_inline)) static inline void systimer_ll_enable_etm(systimer_dev_t *dev, bool en) diff --git a/components/hal/esp32h2/include/hal/systimer_ll.h b/components/hal/esp32h2/include/hal/systimer_ll.h index 74dedc721f..aa68091757 100644 --- a/components/hal/esp32h2/include/hal/systimer_ll.h +++ b/components/hal/esp32h2/include/hal/systimer_ll.h @@ -37,6 +37,35 @@ static inline soc_periph_systimer_clk_src_t systimer_ll_get_clock_source(void) return (PCR.systimer_func_clk_conf.systimer_func_clk_sel == 1) ? SYSTIMER_CLK_SRC_RC_FAST : SYSTIMER_CLK_SRC_XTAL; } +/** + * @brief Enable the bus clock for systimer module + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_bus_clock(bool enable) +{ + PCR.systimer_conf.systimer_clk_en = enable; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the systimer module + * + * @param group_id Group ID + */ +static inline void systimer_ll_reset_register(void) +{ + PCR.systimer_conf.systimer_rst_en = 1; + PCR.systimer_conf.systimer_rst_en = 0; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_reset_register(__VA_ARGS__) + /********************** ETM *****************************/ __attribute__((always_inline)) static inline void systimer_ll_enable_etm(systimer_dev_t *dev, bool en) diff --git a/components/hal/esp32p4/include/hal/clk_gate_ll.h b/components/hal/esp32p4/include/hal/clk_gate_ll.h index 959bdbefce..4861a30927 100644 --- a/components/hal/esp32p4/include/hal/clk_gate_ll.h +++ b/components/hal/esp32p4/include/hal/clk_gate_ll.h @@ -34,8 +34,6 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) return 0; case PERIPH_I3C_MODULE: return HP_SYS_CLKRST_REG_I3C_MST_CLK_EN; - case PERIPH_SYSTIMER_MODULE: - return HP_SYS_CLKRST_REG_SYSTIMER_CLK_EN; case PERIPH_SARADC_MODULE: return HP_SYS_CLKRST_REG_ADC_CLK_EN; case PERIPH_PVT_MODULE: @@ -85,8 +83,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en return HP_SYS_CLKRST_REG_RST_EN_DMA2D; case PERIPH_PPA_MODULE: return HP_SYS_CLKRST_REG_RST_EN_PPA; - case PERIPH_SYSTIMER_MODULE: - return HP_SYS_CLKRST_REG_RST_EN_STIMER; case PERIPH_UHCI_MODULE: return HP_SYS_CLKRST_REG_RST_EN_UHCI; case PERIPH_I3C_MODULE: @@ -144,7 +140,6 @@ static inline uint32_t periph_ll_get_clk_en_reg(periph_module_t periph) case PERIPH_MIPI_DSI_MODULE: return HP_SYS_CLKRST_PERI_CLK_CTRL03_REG; case PERIPH_I3C_MODULE: - case PERIPH_SYSTIMER_MODULE: case PERIPH_SARADC_MODULE: return HP_SYS_CLKRST_PERI_CLK_CTRL22_REG; case PERIPH_PVT_MODULE: @@ -178,7 +173,6 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) case PERIPH_DMA2D_MODULE: return HP_SYS_CLKRST_HP_RST_EN0_REG; case PERIPH_PPA_MODULE: - case PERIPH_SYSTIMER_MODULE: case PERIPH_UHCI_MODULE: case PERIPH_I3C_MODULE: case PERIPH_SARADC_MODULE: diff --git a/components/hal/esp32p4/include/hal/systimer_ll.h b/components/hal/esp32p4/include/hal/systimer_ll.h index 65e3d364b3..e082de3e75 100644 --- a/components/hal/esp32p4/include/hal/systimer_ll.h +++ b/components/hal/esp32p4/include/hal/systimer_ll.h @@ -36,12 +36,40 @@ static inline void systimer_ll_set_clock_source(soc_periph_systimer_clk_src_t cl /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance #define systimer_ll_set_clock_source(...) (void)__DECLARE_RCC_ATOMIC_ENV; systimer_ll_set_clock_source(__VA_ARGS__) - static inline soc_periph_systimer_clk_src_t systimer_ll_get_clock_source(void) { return (HP_SYS_CLKRST.peri_clk_ctrl21.reg_systimer_clk_src_sel == 1) ? SYSTIMER_CLK_SRC_RC_FAST : SYSTIMER_CLK_SRC_XTAL; } +/** + * @brief Enable the bus clock for systimer module + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_bus_clock(bool enable) +{ + HP_SYS_CLKRST.soc_clk_ctrl2.reg_systimer_apb_clk_en = enable; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the systimer module + * + * @param group_id Group ID + */ +static inline void systimer_ll_reset_register(void) +{ + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_stimer = 1; + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_stimer = 0; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_reset_register(__VA_ARGS__) + /********************** ETM *****************************/ __attribute__((always_inline)) static inline void systimer_ll_enable_etm(systimer_dev_t *dev, bool en) diff --git a/components/hal/esp32s2/include/hal/systimer_ll.h b/components/hal/esp32s2/include/hal/systimer_ll.h index 755d349bb6..dd35801bc5 100644 --- a/components/hal/esp32s2/include/hal/systimer_ll.h +++ b/components/hal/esp32s2/include/hal/systimer_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,7 @@ #include #include "soc/systimer_struct.h" #include "soc/clk_tree_defs.h" +#include "soc/system_reg.h" #include "hal/assert.h" #ifdef __cplusplus @@ -35,6 +36,38 @@ static inline soc_periph_systimer_clk_src_t systimer_ll_get_clock_source(void) return SYSTIMER_CLK_SRC_XTAL; } +/** + * @brief Enable the bus clock for systimer module + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_bus_clock(bool enable) +{ + uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG); + reg_val &= ~DPORT_SYSTIMER_CLK_EN_M; + reg_val |= enable << DPORT_SYSTIMER_CLK_EN_S; + WRITE_PERI_REG(DPORT_PERIP_CLK_EN0_REG, reg_val); +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the systimer module + * + * @param group_id Group ID + */ +static inline void systimer_ll_reset_register(void) +{ + WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, DPORT_SYSTIMER_RST_M); + WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, 0); +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_reset_register(__VA_ARGS__) + /******************* Counter *************************/ __attribute__((always_inline)) static inline void systimer_ll_enable_counter(systimer_dev_t *dev, uint32_t counter_id, bool en) diff --git a/components/hal/esp32s3/include/hal/systimer_ll.h b/components/hal/esp32s3/include/hal/systimer_ll.h index 676ff1d9f9..36fe0fa117 100644 --- a/components/hal/esp32s3/include/hal/systimer_ll.h +++ b/components/hal/esp32s3/include/hal/systimer_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,7 @@ #include #include "soc/systimer_struct.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/assert.h" #ifdef __cplusplus @@ -35,6 +36,35 @@ static inline soc_periph_systimer_clk_src_t systimer_ll_get_clock_source(void) return SYSTIMER_CLK_SRC_XTAL; } +/** + * @brief Enable the bus clock for systimer module + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en0.systimer_clk_en = enable; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the systimer module + * + * @param group_id Group ID + */ +static inline void systimer_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.systimer_rst = 1; + SYSTEM.perip_rst_en0.systimer_rst = 0; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; systimer_ll_reset_register(__VA_ARGS__) + /******************* Counter *************************/ __attribute__((always_inline)) static inline void systimer_ll_enable_counter(systimer_dev_t *dev, uint32_t counter_id, bool en) diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 535398eab6..e29d060b09 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1039,6 +1039,10 @@ config SOC_SYSTIMER_ALARM_MISS_COMPENSATE bool default y +config SOC_SYSTIMER_SUPPORT_ETM + bool + default y + config SOC_LP_TIMER_BIT_WIDTH_LO int default 32 diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index d642af7c70..7b86255ebc 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -460,7 +460,7 @@ #define SOC_SYSTIMER_SUPPORT_RC_FAST 1 // Systimer can use RC_FAST clock source #define SOC_SYSTIMER_INT_LEVEL 1 // Systimer peripheral uses level interrupt #define SOC_SYSTIMER_ALARM_MISS_COMPENSATE 1 // Systimer peripheral can generate interrupt immediately if t(target) > t(current) -// #define SOC_SYSTIMER_SUPPORT_ETM 1 // Systimer comparator can generate ETM event //TODO: IDF-7486 +#define SOC_SYSTIMER_SUPPORT_ETM 1 // Systimer comparator can generate ETM event /*-------------------------- LP_TIMER CAPS ----------------------------------*/ #define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part