From 90457a9a4ed0b8c2f6d5f2858cea5171116e839b Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Wed, 8 Jan 2025 16:54:57 +0800 Subject: [PATCH] refactor(lpperi): compatible refactor for H2 ECO5 --- .../src/esp32h2/bootloader_esp32h2.c | 4 + components/esp_system/port/cpu_start.c | 10 +- .../hal/esp32h2/include/hal/lp_clkrst_ll.h | 4 +- .../hal/esp32h2/include/hal/rtc_io_ll.h | 6 +- components/soc/CMakeLists.txt | 4 + .../soc/esp32h2/include/soc/lpperi_reg.h | 113 ++++-- .../include/soc/lpperi_rev0_0_struct.h | 313 +++++++++++++++++ .../include/soc/lpperi_rev1_2_struct.h | 328 ++++++++++++++++++ .../soc/esp32h2/include/soc/lpperi_struct.h | 315 ++--------------- .../soc/esp32h2/ld/esp32h2.peripherals.ld | 3 +- components/soc/esp32h2/lpperi_struct.c | 47 +++ 11 files changed, 817 insertions(+), 330 deletions(-) create mode 100644 components/soc/esp32h2/include/soc/lpperi_rev0_0_struct.h create mode 100644 components/soc/esp32h2/include/soc/lpperi_rev1_2_struct.h create mode 100644 components/soc/esp32h2/lpperi_struct.c diff --git a/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c b/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c index 0daeb60937..ba659dea20 100644 --- a/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c +++ b/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c @@ -42,6 +42,7 @@ #include "hal/lpwdt_ll.h" #include "soc/lp_wdt_reg.h" #include "soc/pmu_reg.h" +#include "soc/lpperi_struct.h" #include "hal/efuse_hal.h" #include "modem/modem_lpcon_reg.h" @@ -107,6 +108,9 @@ esp_err_t bootloader_init(void) { esp_err_t ret = ESP_OK; + // Assign the compatible LPPERI register address in case it is used in the bootloader + lpperi_compatible_reg_addr_init(); + bootloader_hardware_init(); bootloader_ana_reset_config(); bootloader_super_wdt_auto_feed(); diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 5fd3d4e3a7..28afa1f8da 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -61,6 +61,7 @@ #include "esp32h2/rtc.h" #include "esp32h2/rom/cache.h" #include "esp_memprot.h" +#include "soc/lpperi_struct.h" #elif CONFIG_IDF_TARGET_ESP32C2 #include "esp32c2/rtc.h" #include "esp32c2/rom/cache.h" @@ -459,6 +460,13 @@ void IRAM_ATTR call_start_cpu0(void) } #endif +#if CONFIG_IDF_TARGET_ESP32H2 + // Some modules' register layout are not binary compatible among the different chip revisions, + // they will be wrapped into a new compatible instance which will point to the correct register address according to the revision. + // To ensure the compatible instance is initialized before used, the initialization is done after BBS is cleared + lpperi_compatible_reg_addr_init(); +#endif + #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP && !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE && !SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE // It helps to fix missed cache settings for other cores. It happens when bootloader is unicore. do_multicore_settings(); diff --git a/components/hal/esp32h2/include/hal/lp_clkrst_ll.h b/components/hal/esp32h2/include/hal/lp_clkrst_ll.h index bffe712ba4..1e269388b0 100644 --- a/components/hal/esp32h2/include/hal/lp_clkrst_ll.h +++ b/components/hal/esp32h2/include/hal/lp_clkrst_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -63,7 +63,7 @@ static inline void lp_clkrst_ll_select_modem_32k_clock_source(lp_clkrst_dev_t *h __attribute__((always_inline)) static inline void _lp_clkrst_ll_enable_rng_clock(bool en) { - LPPERI.clk_en.rng_ck_en = en; + LPPERI.clk_en->rng_ck_en = en; } /// LPPERI.clk_en is a shared register, so this function must be used in an atomic way diff --git a/components/hal/esp32h2/include/hal/rtc_io_ll.h b/components/hal/esp32h2/include/hal/rtc_io_ll.h index bfeb758a59..2f69a7777c 100644 --- a/components/hal/esp32h2/include/hal/rtc_io_ll.h +++ b/components/hal/esp32h2/include/hal/rtc_io_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -38,8 +38,8 @@ typedef enum { */ static inline void _rtcio_ll_enable_io_clock(bool enable) { - LPPERI.clk_en.lp_io_ck_en = enable; - while (LPPERI.clk_en.lp_io_ck_en != enable) { + LPPERI.clk_en->lp_io_ck_en = enable; + while (LPPERI.clk_en->lp_io_ck_en != enable) { ; } } diff --git a/components/soc/CMakeLists.txt b/components/soc/CMakeLists.txt index 2e3d92bd6c..f7697cf916 100644 --- a/components/soc/CMakeLists.txt +++ b/components/soc/CMakeLists.txt @@ -27,6 +27,10 @@ if(target STREQUAL "esp32") list(APPEND srcs "${target_folder}/dport_access.c") endif() +if(target STREQUAL "esp32h2") + list(APPEND srcs "${target_folder}/lpperi_struct.c") +endif() + if(CONFIG_SOC_ADC_SUPPORTED) list(APPEND srcs "${target_folder}/adc_periph.c") endif() diff --git a/components/soc/esp32h2/include/soc/lpperi_reg.h b/components/soc/esp32h2/include/soc/lpperi_reg.h index f4046ad2a3..4587bb9fd6 100644 --- a/components/soc/esp32h2/include/soc/lpperi_reg.h +++ b/components/soc/esp32h2/include/soc/lpperi_reg.h @@ -1,7 +1,7 @@ -/** - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +/* + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 + * SPDX-License-Identifier: Apache-2.0 */ #pragma once @@ -11,6 +11,34 @@ extern "C" { #endif +/** LPPERI_DATE_REG register + * need_des + */ +#define LPPERI_DATE_REG (DR_REG_LPPERI_BASE + 0x3fc) +/** LPPERI_LPPERI_DATE : R/W; bitpos: [30:0]; default: 36732976 (0x2308030); + * need_des + */ +#define LPPERI_LPPERI_DATE 0x7FFFFFFFU +#define LPPERI_LPPERI_DATE_M (LPPERI_LPPERI_DATE_V << LPPERI_LPPERI_DATE_S) +#define LPPERI_LPPERI_DATE_V 0x7FFFFFFFU +#define LPPERI_LPPERI_DATE_S 0 +/** LPPERI_CLK_EN : R/W; bitpos: [31]; default: 0; + * need_des + */ +#define LPPERI_CLK_EN (BIT(31)) +#define LPPERI_CLK_EN_M (LPPERI_CLK_EN_V << LPPERI_CLK_EN_S) +#define LPPERI_CLK_EN_V 0x00000001U +#define LPPERI_CLK_EN_S 31 + +/** + * @brief Get the register offset according to the register version + * @note H2 ECO5 inserted a new register LPPERI_RNG_CFG_REG, + * so the addressed of the rest registers are shifted 4 bytes + * This macro can help to get the correct register offset according to the register version + */ +#define LPPERI_REG_OFFSET(offset) (REG_GET_FIELD(LPPERI_DATE_REG, LPPERI_LPPERI_DATE) >= 0x2308030 ? (offset) : (offset) - 4) + + /** LPPERI_CLK_EN_REG register * need_des */ @@ -140,22 +168,40 @@ extern "C" { #define LPPERI_LP_CPU_RESET_EN_V 0x00000001U #define LPPERI_LP_CPU_RESET_EN_S 31 -/** LPPERI_RNG_DATA_REG register +/** LPPERI_RNG_CFG_REG register * need_des */ -#define LPPERI_RNG_DATA_REG (DR_REG_LPPERI_BASE + 0x8) +#define LPPERI_RNG_CFG_REG (DR_REG_LPPERI_BASE + 0x8) +/** LPPERI_RNG_CFG_ENABLE : R/W; bitpos: [1:0]; default: 0; + * need_des + * Note: this register only exist on the chips that LPPERI_LPPERI_DATE >= 0x2308030, + * i.e., ESP32-H2 chip_revision >= 1.2 + */ +#define LPPERI_RNG_CFG_ENABLE 0x00000003U +#define LPPERI_RNG_CFG_ENABLE_M (LPPERI_RNG_CFG_ENABLE_V << LPPERI_RNG_CFG_ENABLE_S) +#define LPPERI_RNG_CFG_ENABLE_V 0x00000003U +#define LPPERI_RNG_CFG_ENABLE_S 0 + +/** LPPERI_RNG_DATA_REG register + * need_des + * Note: this register address is different on different H2 revisions, + * here uses LPPERI_REG_OFFSET to get the compatible offset. + */ +#define LPPERI_RNG_DATA_REG (DR_REG_LPPERI_BASE + LPPERI_REG_OFFSET(0xc)) /** LPPERI_RNG_DATA : RO; bitpos: [31:0]; default: 0; * need_des */ -#define LPPERI_RNG_DATA 0xFFFFFFFFU -#define LPPERI_RND_GATA_M (LPPERI_RND_GATA_V << LPPERI_RND_GATA_S) -#define LPPERI_RND_GATA_V 0xFFFFFFFFU -#define LPPERI_RND_GATA_S 0 +#define LPPERI_RND_DATA 0xFFFFFFFFU +#define LPPERI_RND_DATA_M (LPPERI_RND_DATA_V << LPPERI_RND_DATA_S) +#define LPPERI_RND_DATA_V 0xFFFFFFFFU +#define LPPERI_RND_DATA_S 0 /** LPPERI_CPU_REG register * need_des + * Note: this register address is different on different H2 revisions, + * here uses LPPERI_REG_OFFSET to get the compatible offset. */ -#define LPPERI_CPU_REG (DR_REG_LPPERI_BASE + 0xc) +#define LPPERI_CPU_REG (DR_REG_LPPERI_BASE + LPPERI_REG_OFFSET(0x10)) /** LPPERI_LPCORE_DBGM_UNAVALIABLE : R/W; bitpos: [31]; default: 1; * need_des */ @@ -166,8 +212,10 @@ extern "C" { /** LPPERI_BUS_TIMEOUT_REG register * need_des + * Note: this register address is different on different H2 revisions, + * here uses LPPERI_REG_OFFSET to get the compatible offset. */ -#define LPPERI_BUS_TIMEOUT_REG (DR_REG_LPPERI_BASE + 0x10) +#define LPPERI_BUS_TIMEOUT_REG (DR_REG_LPPERI_BASE + LPPERI_REG_OFFSET(0x14)) /** LPPERI_LP_PERI_TIMEOUT_THRES : R/W; bitpos: [29:14]; default: 65535; * need_des */ @@ -192,8 +240,10 @@ extern "C" { /** LPPERI_BUS_TIMEOUT_ADDR_REG register * need_des + * Note: this register address is different on different H2 revisions, + * here uses LPPERI_REG_OFFSET to get the compatible offset. */ -#define LPPERI_BUS_TIMEOUT_ADDR_REG (DR_REG_LPPERI_BASE + 0x14) +#define LPPERI_BUS_TIMEOUT_ADDR_REG (DR_REG_LPPERI_BASE + LPPERI_REG_OFFSET(0x18)) /** LPPERI_LP_PERI_TIMEOUT_ADDR : RO; bitpos: [31:0]; default: 0; * need_des */ @@ -204,8 +254,10 @@ extern "C" { /** LPPERI_BUS_TIMEOUT_UID_REG register * need_des + * Note: this register address is different on different H2 revisions, + * here uses LPPERI_REG_OFFSET to get the compatible offset. */ -#define LPPERI_BUS_TIMEOUT_UID_REG (DR_REG_LPPERI_BASE + 0x18) +#define LPPERI_BUS_TIMEOUT_UID_REG (DR_REG_LPPERI_BASE + LPPERI_REG_OFFSET(0x1c)) /** LPPERI_LP_PERI_TIMEOUT_UID : RO; bitpos: [6:0]; default: 0; * need_des */ @@ -216,8 +268,10 @@ extern "C" { /** LPPERI_MEM_CTRL_REG register * need_des + * Note: this register address is different on different H2 revisions, + * here uses LPPERI_REG_OFFSET to get the compatible offset. */ -#define LPPERI_MEM_CTRL_REG (DR_REG_LPPERI_BASE + 0x1c) +#define LPPERI_MEM_CTRL_REG (DR_REG_LPPERI_BASE + LPPERI_REG_OFFSET(0x20)) /** LPPERI_UART_WAKEUP_FLAG_CLR : WT; bitpos: [0]; default: 0; * need_des */ @@ -256,8 +310,10 @@ extern "C" { /** LPPERI_INTERRUPT_SOURCE_REG register * need_des + * Note: this register address is different on different H2 revisions, + * here uses LPPERI_REG_OFFSET to get the compatible offset. */ -#define LPPERI_INTERRUPT_SOURCE_REG (DR_REG_LPPERI_BASE + 0x20) +#define LPPERI_INTERRUPT_SOURCE_REG (DR_REG_LPPERI_BASE + LPPERI_REG_OFFSET(0x24)) /** LPPERI_LP_INTERRUPT_SOURCE : RO; bitpos: [5:0]; default: 0; * BIT5~BIT0: pmu_lp_int, modem_lp_int, lp_timer_lp_int, lp_uart_int, lp_i2c_int, * lp_io_int @@ -269,8 +325,10 @@ extern "C" { /** LPPERI_DEBUG_SEL0_REG register * need des + * Note: this register address is different on different H2 revisions, + * here uses LPPERI_REG_OFFSET to get the compatible offset. */ -#define LPPERI_DEBUG_SEL0_REG (DR_REG_LPPERI_BASE + 0x24) +#define LPPERI_DEBUG_SEL0_REG (DR_REG_LPPERI_BASE + LPPERI_REG_OFFSET(0x28)) /** LPPERI_DEBUG_SEL0 : R/W; bitpos: [6:0]; default: 0; * need des */ @@ -302,8 +360,10 @@ extern "C" { /** LPPERI_DEBUG_SEL1_REG register * need des + * Note: this register address is different on different H2 revisions, + * here uses LPPERI_REG_OFFSET to get the compatible offset. */ -#define LPPERI_DEBUG_SEL1_REG (DR_REG_LPPERI_BASE + 0x28) +#define LPPERI_DEBUG_SEL1_REG (DR_REG_LPPERI_BASE + LPPERI_REG_OFFSET(0x2c)) /** LPPERI_DEBUG_SEL4 : R/W; bitpos: [6:0]; default: 0; * need des */ @@ -312,25 +372,6 @@ extern "C" { #define LPPERI_DEBUG_SEL4_V 0x0000007FU #define LPPERI_DEBUG_SEL4_S 0 -/** LPPERI_DATE_REG register - * need_des - */ -#define LPPERI_DATE_REG (DR_REG_LPPERI_BASE + 0x3fc) -/** LPPERI_LPPERI_DATE : R/W; bitpos: [30:0]; default: 35676464; - * need_des - */ -#define LPPERI_LPPERI_DATE 0x7FFFFFFFU -#define LPPERI_LPPERI_DATE_M (LPPERI_LPPERI_DATE_V << LPPERI_LPPERI_DATE_S) -#define LPPERI_LPPERI_DATE_V 0x7FFFFFFFU -#define LPPERI_LPPERI_DATE_S 0 -/** LPPERI_CLK_EN : R/W; bitpos: [31]; default: 0; - * need_des - */ -#define LPPERI_CLK_EN (BIT(31)) -#define LPPERI_CLK_EN_M (LPPERI_CLK_EN_V << LPPERI_CLK_EN_S) -#define LPPERI_CLK_EN_V 0x00000001U -#define LPPERI_CLK_EN_S 31 - #ifdef __cplusplus } #endif diff --git a/components/soc/esp32h2/include/soc/lpperi_rev0_0_struct.h b/components/soc/esp32h2/include/soc/lpperi_rev0_0_struct.h new file mode 100644 index 0000000000..970b12ed10 --- /dev/null +++ b/components/soc/esp32h2/include/soc/lpperi_rev0_0_struct.h @@ -0,0 +1,313 @@ +/** + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +/** + * @file lpperi_rev0_0_struct.h + * @brief Applicable to the ESP32-H2 that chip revision < 1.2. + */ + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** Group: configure_register */ +/** Type of clk_en register + * need_des + */ +typedef union { + struct { + uint32_t reserved_0:24; + /** rng_ck_en : R/W; bitpos: [24]; default: 1; + * need_des + */ + uint32_t rng_ck_en:1; + /** otp_dbg_ck_en : R/W; bitpos: [25]; default: 1; + * need_des + */ + uint32_t otp_dbg_ck_en:1; + /** lp_uart_ck_en : R/W; bitpos: [26]; default: 1; + * need_des + */ + uint32_t lp_uart_ck_en:1; + /** lp_io_ck_en : R/W; bitpos: [27]; default: 1; + * need_des + */ + uint32_t lp_io_ck_en:1; + /** lp_ext_i2c_ck_en : R/W; bitpos: [28]; default: 1; + * need_des + */ + uint32_t lp_ext_i2c_ck_en:1; + /** lp_ana_i2c_ck_en : R/W; bitpos: [29]; default: 1; + * need_des + */ + uint32_t lp_ana_i2c_ck_en:1; + /** efuse_ck_en : R/W; bitpos: [30]; default: 1; + * need_des + */ + uint32_t efuse_ck_en:1; + /** lp_cpu_ck_en : R/W; bitpos: [31]; default: 0; + * need_des + */ + uint32_t lp_cpu_ck_en:1; + }; + uint32_t val; +} lpperi_rev0_0_clk_en_reg_t; + +/** Type of reset_en register + * need_des + */ +typedef union { + struct { + uint32_t reserved_0:23; + /** bus_reset_en : WT; bitpos: [23]; default: 0; + * need_des + */ + uint32_t bus_reset_en:1; + /** lp_ble_timer_reset_en : R/W; bitpos: [24]; default: 0; + * need_des + */ + uint32_t lp_ble_timer_reset_en:1; + /** otp_dbg_reset_en : R/W; bitpos: [25]; default: 0; + * need_des + */ + uint32_t otp_dbg_reset_en:1; + /** lp_uart_reset_en : R/W; bitpos: [26]; default: 0; + * need_des + */ + uint32_t lp_uart_reset_en:1; + /** lp_io_reset_en : R/W; bitpos: [27]; default: 0; + * need_des + */ + uint32_t lp_io_reset_en:1; + /** lp_ext_i2c_reset_en : R/W; bitpos: [28]; default: 0; + * need_des + */ + uint32_t lp_ext_i2c_reset_en:1; + /** lp_ana_i2c_reset_en : R/W; bitpos: [29]; default: 0; + * need_des + */ + uint32_t lp_ana_i2c_reset_en:1; + /** efuse_reset_en : R/W; bitpos: [30]; default: 0; + * need_des + */ + uint32_t efuse_reset_en:1; + /** lp_cpu_reset_en : WT; bitpos: [31]; default: 0; + * need_des + */ + uint32_t lp_cpu_reset_en:1; + }; + uint32_t val; +} lpperi_rev0_0_reset_en_reg_t; + +/** Type of rng_data register + * need_des + */ +typedef union { + struct { + /** rnd_data : RO; bitpos: [31:0]; default: 0; + * need_des + */ + uint32_t rnd_data:32; + }; + uint32_t val; +} lpperi_rev0_0_rng_data_reg_t; + +/** Type of cpu register + * need_des + */ +typedef union { + struct { + uint32_t reserved_0:31; + /** lpcore_dbgm_unavaliable : R/W; bitpos: [31]; default: 1; + * need_des + */ + uint32_t lpcore_dbgm_unavaliable:1; + }; + uint32_t val; +} lpperi_rev0_0_cpu_reg_t; + +/** Type of bus_timeout register + * need_des + */ +typedef union { + struct { + uint32_t reserved_0:14; + /** lp_peri_timeout_thres : R/W; bitpos: [29:14]; default: 65535; + * need_des + */ + uint32_t lp_peri_timeout_thres:16; + /** lp_peri_timeout_int_clear : WT; bitpos: [30]; default: 0; + * need_des + */ + uint32_t lp_peri_timeout_int_clear:1; + /** lp_peri_timeout_protect_en : R/W; bitpos: [31]; default: 1; + * need_des + */ + uint32_t lp_peri_timeout_protect_en:1; + }; + uint32_t val; +} lpperi_rev0_0_bus_timeout_reg_t; + +/** Type of bus_timeout_addr register + * need_des + */ +typedef union { + struct { + /** lp_peri_timeout_addr : RO; bitpos: [31:0]; default: 0; + * need_des + */ + uint32_t lp_peri_timeout_addr:32; + }; + uint32_t val; +} lpperi_rev0_0_bus_timeout_addr_reg_t; + +/** Type of bus_timeout_uid register + * need_des + */ +typedef union { + struct { + /** lp_peri_timeout_uid : RO; bitpos: [6:0]; default: 0; + * need_des + */ + uint32_t lp_peri_timeout_uid:7; + uint32_t reserved_7:25; + }; + uint32_t val; +} lpperi_rev0_0_bus_timeout_uid_reg_t; + +/** Type of mem_ctrl register + * need_des + */ +typedef union { + struct { + /** uart_wakeup_flag_clr : WT; bitpos: [0]; default: 0; + * need_des + */ + uint32_t uart_wakeup_flag_clr:1; + /** uart_wakeup_flag : R/WTC/SS; bitpos: [1]; default: 0; + * need_des + */ + uint32_t uart_wakeup_flag:1; + uint32_t reserved_2:27; + /** uart_wakeup_en : R/W; bitpos: [29]; default: 0; + * need_des + */ + uint32_t uart_wakeup_en:1; + /** uart_mem_force_pd : R/W; bitpos: [30]; default: 0; + * need_des + */ + uint32_t uart_mem_force_pd:1; + /** uart_mem_force_pu : R/W; bitpos: [31]; default: 1; + * need_des + */ + uint32_t uart_mem_force_pu:1; + }; + uint32_t val; +} lpperi_rev0_0_mem_ctrl_reg_t; + +/** Type of interrupt_source register + * need_des + */ +typedef union { + struct { + /** lp_interrupt_source : RO; bitpos: [5:0]; default: 0; + * BIT5~BIT0: pmu_lp_int, modem_lp_int, lp_timer_lp_int, lp_uart_int, lp_i2c_int, + * lp_io_int + */ + uint32_t lp_interrupt_source:6; + uint32_t reserved_6:26; + }; + uint32_t val; +} lpperi_rev0_0_interrupt_source_reg_t; + +/** Type of debug_sel0 register + * need des + */ +typedef union { + struct { + /** debug_sel0 : R/W; bitpos: [6:0]; default: 0; + * need des + */ + uint32_t debug_sel0:7; + /** debug_sel1 : R/W; bitpos: [13:7]; default: 0; + * need des + */ + uint32_t debug_sel1:7; + /** debug_sel2 : R/W; bitpos: [20:14]; default: 0; + * need des + */ + uint32_t debug_sel2:7; + /** debug_sel3 : R/W; bitpos: [27:21]; default: 0; + * need des + */ + uint32_t debug_sel3:7; + uint32_t reserved_28:4; + }; + uint32_t val; +} lpperi_rev0_0_debug_sel0_reg_t; + +/** Type of debug_sel1 register + * need des + */ +typedef union { + struct { + /** debug_sel4 : R/W; bitpos: [6:0]; default: 0; + * need des + */ + uint32_t debug_sel4:7; + uint32_t reserved_7:25; + }; + uint32_t val; +} lpperi_rev0_0_debug_sel1_reg_t; + + +/** Group: Version register */ +/** Type of date register + * need_des + */ +typedef union { + struct { + /** lpperi_date : R/W; bitpos: [30:0]; default: 35676464; + * need_des + */ + uint32_t lpperi_date:31; + /** clk_en : R/W; bitpos: [31]; default: 0; + * need_des + */ + uint32_t clk_en:1; + }; + uint32_t val; +} lpperi_rev0_0_date_reg_t; + + +typedef struct { + volatile lpperi_rev0_0_clk_en_reg_t clk_en; + volatile lpperi_rev0_0_reset_en_reg_t reset_en; + volatile lpperi_rev0_0_rng_data_reg_t rng_data; + volatile lpperi_rev0_0_cpu_reg_t cpu; + volatile lpperi_rev0_0_bus_timeout_reg_t bus_timeout; + volatile lpperi_rev0_0_bus_timeout_addr_reg_t bus_timeout_addr; + volatile lpperi_rev0_0_bus_timeout_uid_reg_t bus_timeout_uid; + volatile lpperi_rev0_0_mem_ctrl_reg_t mem_ctrl; + volatile lpperi_rev0_0_interrupt_source_reg_t interrupt_source; + volatile lpperi_rev0_0_debug_sel0_reg_t debug_sel0; + volatile lpperi_rev0_0_debug_sel1_reg_t debug_sel1; + uint32_t reserved_02c[244]; + volatile lpperi_rev0_0_date_reg_t date; +} lpperi_rev0_0_dev_t; + +/* Please don't use the following instance, use the compatible instance LPPERI in `lpperi_struct.h` instead. */ +extern lpperi_rev0_0_dev_t LPPERI_REV0_0; + +#ifndef __cplusplus +_Static_assert(sizeof(lpperi_rev0_0_dev_t) == 0x400, "Invalid size of lpperi_rev0_0_dev_t structure"); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32h2/include/soc/lpperi_rev1_2_struct.h b/components/soc/esp32h2/include/soc/lpperi_rev1_2_struct.h new file mode 100644 index 0000000000..5f3598e3c6 --- /dev/null +++ b/components/soc/esp32h2/include/soc/lpperi_rev1_2_struct.h @@ -0,0 +1,328 @@ +/** + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +/** + * @file lpperi_rev1_2_struct.h + * @brief Applicable to the ESP32-H2 that chip revision >= 1.2. + */ + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** Group: configure_register */ +/** Type of clk_en register + * need_des + */ +typedef union { + struct { + uint32_t reserved_0:24; + /** rng_ck_en : R/W; bitpos: [24]; default: 1; + * need_des + */ + uint32_t rng_ck_en:1; + /** otp_dbg_ck_en : R/W; bitpos: [25]; default: 1; + * need_des + */ + uint32_t otp_dbg_ck_en:1; + /** lp_uart_ck_en : R/W; bitpos: [26]; default: 1; + * need_des + */ + uint32_t lp_uart_ck_en:1; + /** lp_io_ck_en : R/W; bitpos: [27]; default: 1; + * need_des + */ + uint32_t lp_io_ck_en:1; + /** lp_ext_i2c_ck_en : R/W; bitpos: [28]; default: 1; + * need_des + */ + uint32_t lp_ext_i2c_ck_en:1; + /** lp_ana_i2c_ck_en : R/W; bitpos: [29]; default: 1; + * need_des + */ + uint32_t lp_ana_i2c_ck_en:1; + /** efuse_ck_en : R/W; bitpos: [30]; default: 1; + * need_des + */ + uint32_t efuse_ck_en:1; + /** lp_cpu_ck_en : R/W; bitpos: [31]; default: 0; + * need_des + */ + uint32_t lp_cpu_ck_en:1; + }; + uint32_t val; +} lpperi_clk_en_reg_t; + +/** Type of reset_en register + * need_des + */ +typedef union { + struct { + uint32_t reserved_0:23; + /** bus_reset_en : WT; bitpos: [23]; default: 0; + * need_des + */ + uint32_t bus_reset_en:1; + /** lp_ble_timer_reset_en : R/W; bitpos: [24]; default: 0; + * need_des + */ + uint32_t lp_ble_timer_reset_en:1; + /** otp_dbg_reset_en : R/W; bitpos: [25]; default: 0; + * need_des + */ + uint32_t otp_dbg_reset_en:1; + /** lp_uart_reset_en : R/W; bitpos: [26]; default: 0; + * need_des + */ + uint32_t lp_uart_reset_en:1; + /** lp_io_reset_en : R/W; bitpos: [27]; default: 0; + * need_des + */ + uint32_t lp_io_reset_en:1; + /** lp_ext_i2c_reset_en : R/W; bitpos: [28]; default: 0; + * need_des + */ + uint32_t lp_ext_i2c_reset_en:1; + /** lp_ana_i2c_reset_en : R/W; bitpos: [29]; default: 0; + * need_des + */ + uint32_t lp_ana_i2c_reset_en:1; + /** efuse_reset_en : R/W; bitpos: [30]; default: 0; + * need_des + */ + uint32_t efuse_reset_en:1; + /** lp_cpu_reset_en : WT; bitpos: [31]; default: 0; + * need_des + */ + uint32_t lp_cpu_reset_en:1; + }; + uint32_t val; +} lpperi_reset_en_reg_t; + +/** Type of rng_cfg register + * need_des + */ +typedef union { + struct { + /** rng_cfg_enable : R/W; bitpos: [1:0]; default: 0; + * need_des + */ + uint32_t rng_cfg_enable:2; + uint32_t reserved_2:30; + }; + uint32_t val; +} lpperi_rng_cfg_reg_t; + +/** Type of rng_data register + * need_des + */ +typedef union { + struct { + /** rnd_data : RO; bitpos: [31:0]; default: 0; + * need_des + */ + uint32_t rnd_data:32; + }; + uint32_t val; +} lpperi_rng_data_reg_t; + +/** Type of cpu register + * need_des + */ +typedef union { + struct { + uint32_t reserved_0:31; + /** lpcore_dbgm_unavaliable : R/W; bitpos: [31]; default: 1; + * need_des + */ + uint32_t lpcore_dbgm_unavaliable:1; + }; + uint32_t val; +} lpperi_cpu_reg_t; + +/** Type of bus_timeout register + * need_des + */ +typedef union { + struct { + uint32_t reserved_0:14; + /** lp_peri_timeout_thres : R/W; bitpos: [29:14]; default: 65535; + * need_des + */ + uint32_t lp_peri_timeout_thres:16; + /** lp_peri_timeout_int_clear : WT; bitpos: [30]; default: 0; + * need_des + */ + uint32_t lp_peri_timeout_int_clear:1; + /** lp_peri_timeout_protect_en : R/W; bitpos: [31]; default: 1; + * need_des + */ + uint32_t lp_peri_timeout_protect_en:1; + }; + uint32_t val; +} lpperi_bus_timeout_reg_t; + +/** Type of bus_timeout_addr register + * need_des + */ +typedef union { + struct { + /** lp_peri_timeout_addr : RO; bitpos: [31:0]; default: 0; + * need_des + */ + uint32_t lp_peri_timeout_addr:32; + }; + uint32_t val; +} lpperi_bus_timeout_addr_reg_t; + +/** Type of bus_timeout_uid register + * need_des + */ +typedef union { + struct { + /** lp_peri_timeout_uid : RO; bitpos: [6:0]; default: 0; + * need_des + */ + uint32_t lp_peri_timeout_uid:7; + uint32_t reserved_7:25; + }; + uint32_t val; +} lpperi_bus_timeout_uid_reg_t; + +/** Type of mem_ctrl register + * need_des + */ +typedef union { + struct { + /** uart_wakeup_flag_clr : WT; bitpos: [0]; default: 0; + * need_des + */ + uint32_t uart_wakeup_flag_clr:1; + /** uart_wakeup_flag : R/WTC/SS; bitpos: [1]; default: 0; + * need_des + */ + uint32_t uart_wakeup_flag:1; + uint32_t reserved_2:27; + /** uart_wakeup_en : R/W; bitpos: [29]; default: 0; + * need_des + */ + uint32_t uart_wakeup_en:1; + /** uart_mem_force_pd : R/W; bitpos: [30]; default: 0; + * need_des + */ + uint32_t uart_mem_force_pd:1; + /** uart_mem_force_pu : R/W; bitpos: [31]; default: 1; + * need_des + */ + uint32_t uart_mem_force_pu:1; + }; + uint32_t val; +} lpperi_mem_ctrl_reg_t; + +/** Type of interrupt_source register + * need_des + */ +typedef union { + struct { + /** lp_interrupt_source : RO; bitpos: [5:0]; default: 0; + * BIT5~BIT0: pmu_lp_int, modem_lp_int, lp_timer_lp_int, lp_uart_int, lp_i2c_int, + * lp_io_int + */ + uint32_t lp_interrupt_source:6; + uint32_t reserved_6:26; + }; + uint32_t val; +} lpperi_interrupt_source_reg_t; + +/** Type of debug_sel0 register + * need des + */ +typedef union { + struct { + /** debug_sel0 : R/W; bitpos: [6:0]; default: 0; + * need des + */ + uint32_t debug_sel0:7; + /** debug_sel1 : R/W; bitpos: [13:7]; default: 0; + * need des + */ + uint32_t debug_sel1:7; + /** debug_sel2 : R/W; bitpos: [20:14]; default: 0; + * need des + */ + uint32_t debug_sel2:7; + /** debug_sel3 : R/W; bitpos: [27:21]; default: 0; + * need des + */ + uint32_t debug_sel3:7; + uint32_t reserved_28:4; + }; + uint32_t val; +} lpperi_debug_sel0_reg_t; + +/** Type of debug_sel1 register + * need des + */ +typedef union { + struct { + /** debug_sel4 : R/W; bitpos: [6:0]; default: 0; + * need des + */ + uint32_t debug_sel4:7; + uint32_t reserved_7:25; + }; + uint32_t val; +} lpperi_debug_sel1_reg_t; + + +/** Group: Version register */ +/** Type of date register + * need_des + */ +typedef union { + struct { + /** lpperi_date : R/W; bitpos: [30:0]; default: 36732976 (0x2308030); + * need_des + */ + uint32_t lpperi_date:31; + /** clk_en : R/W; bitpos: [31]; default: 0; + * need_des + */ + uint32_t clk_en:1; + }; + uint32_t val; +} lpperi_date_reg_t; + + +typedef struct { + volatile lpperi_clk_en_reg_t clk_en; + volatile lpperi_reset_en_reg_t reset_en; + volatile lpperi_rng_cfg_reg_t rng_cfg; + volatile lpperi_rng_data_reg_t rng_data; + volatile lpperi_cpu_reg_t cpu; + volatile lpperi_bus_timeout_reg_t bus_timeout; + volatile lpperi_bus_timeout_addr_reg_t bus_timeout_addr; + volatile lpperi_bus_timeout_uid_reg_t bus_timeout_uid; + volatile lpperi_mem_ctrl_reg_t mem_ctrl; + volatile lpperi_interrupt_source_reg_t interrupt_source; + volatile lpperi_debug_sel0_reg_t debug_sel0; + volatile lpperi_debug_sel1_reg_t debug_sel1; + uint32_t reserved_030[243]; + volatile lpperi_date_reg_t date; +} lpperi_rev1_2_dev_t; + +/* Please don't use the following instance, use the compatible instance LPPERI in `lpperi_struct.h` instead. */ +extern lpperi_rev1_2_dev_t LPPERI_REV1_2; + +#ifndef __cplusplus +_Static_assert(sizeof(lpperi_rev1_2_dev_t) == 0x400, "Invalid size of lpperi_rev1_2_dev_t structure"); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32h2/include/soc/lpperi_struct.h b/components/soc/esp32h2/include/soc/lpperi_struct.h index c5456eed1b..40c20b7686 100644 --- a/components/soc/esp32h2/include/soc/lpperi_struct.h +++ b/components/soc/esp32h2/include/soc/lpperi_struct.h @@ -1,306 +1,47 @@ /** - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ + +/* For compatibility of ECO0 and ECO5 */ + #pragma once +#include "soc/lpperi_rev0_0_struct.h" +#include "soc/lpperi_rev1_2_struct.h" + #include #ifdef __cplusplus extern "C" { #endif -/** Group: configure_register */ -/** Type of clk_en register - * need_des +/** + * @brief Compatible lpperi struct for ECO0-ECO4 and ECO5 + * */ -typedef union { - struct { - uint32_t reserved_0:24; - /** rng_ck_en : R/W; bitpos: [24]; default: 1; - * need_des - */ - uint32_t rng_ck_en:1; - /** otp_dbg_ck_en : R/W; bitpos: [25]; default: 1; - * need_des - */ - uint32_t otp_dbg_ck_en:1; - /** lp_uart_ck_en : R/W; bitpos: [26]; default: 1; - * need_des - */ - uint32_t lp_uart_ck_en:1; - /** lp_io_ck_en : R/W; bitpos: [27]; default: 1; - * need_des - */ - uint32_t lp_io_ck_en:1; - /** lp_ext_i2c_ck_en : R/W; bitpos: [28]; default: 1; - * need_des - */ - uint32_t lp_ext_i2c_ck_en:1; - /** lp_ana_i2c_ck_en : R/W; bitpos: [29]; default: 1; - * need_des - */ - uint32_t lp_ana_i2c_ck_en:1; - /** efuse_ck_en : R/W; bitpos: [30]; default: 1; - * need_des - */ - uint32_t efuse_ck_en:1; - /** lp_cpu_ck_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t lp_cpu_ck_en:1; - }; - uint32_t val; -} lpperi_clk_en_reg_t; - -/** Type of reset_en register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:23; - /** bus_reset_en : WT; bitpos: [23]; default: 0; - * need_des - */ - uint32_t bus_reset_en:1; - /** lp_ble_timer_reset_en : R/W; bitpos: [24]; default: 0; - * need_des - */ - uint32_t lp_ble_timer_reset_en:1; - /** otp_dbg_reset_en : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t otp_dbg_reset_en:1; - /** lp_uart_reset_en : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t lp_uart_reset_en:1; - /** lp_io_reset_en : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t lp_io_reset_en:1; - /** lp_ext_i2c_reset_en : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t lp_ext_i2c_reset_en:1; - /** lp_ana_i2c_reset_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t lp_ana_i2c_reset_en:1; - /** efuse_reset_en : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t efuse_reset_en:1; - /** lp_cpu_reset_en : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t lp_cpu_reset_en:1; - }; - uint32_t val; -} lpperi_reset_en_reg_t; - -/** Type of rng_data register - * need_des - */ -typedef union { - struct { - /** rng_data : RO; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t rng_data:32; - }; - uint32_t val; -} lpperi_rng_data_reg_t; - -/** Type of cpu register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** lpcore_dbgm_unavaliable : R/W; bitpos: [31]; default: 1; - * need_des - */ - uint32_t lpcore_dbgm_unavaliable:1; - }; - uint32_t val; -} lpperi_cpu_reg_t; - -/** Type of bus_timeout register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:14; - /** lp_peri_timeout_thres : R/W; bitpos: [29:14]; default: 65535; - * need_des - */ - uint32_t lp_peri_timeout_thres:16; - /** lp_peri_timeout_int_clear : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t lp_peri_timeout_int_clear:1; - /** lp_peri_timeout_protect_en : R/W; bitpos: [31]; default: 1; - * need_des - */ - uint32_t lp_peri_timeout_protect_en:1; - }; - uint32_t val; -} lpperi_bus_timeout_reg_t; - -/** Type of bus_timeout_addr register - * need_des - */ -typedef union { - struct { - /** lp_peri_timeout_addr : RO; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t lp_peri_timeout_addr:32; - }; - uint32_t val; -} lpperi_bus_timeout_addr_reg_t; - -/** Type of bus_timeout_uid register - * need_des - */ -typedef union { - struct { - /** lp_peri_timeout_uid : RO; bitpos: [6:0]; default: 0; - * need_des - */ - uint32_t lp_peri_timeout_uid:7; - uint32_t reserved_7:25; - }; - uint32_t val; -} lpperi_bus_timeout_uid_reg_t; - -/** Type of mem_ctrl register - * need_des - */ -typedef union { - struct { - /** uart_wakeup_flag_clr : WT; bitpos: [0]; default: 0; - * need_des - */ - uint32_t uart_wakeup_flag_clr:1; - /** uart_wakeup_flag : R/WTC/SS; bitpos: [1]; default: 0; - * need_des - */ - uint32_t uart_wakeup_flag:1; - uint32_t reserved_2:27; - /** uart_wakeup_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t uart_wakeup_en:1; - /** uart_mem_force_pd : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t uart_mem_force_pd:1; - /** uart_mem_force_pu : R/W; bitpos: [31]; default: 1; - * need_des - */ - uint32_t uart_mem_force_pu:1; - }; - uint32_t val; -} lpperi_mem_ctrl_reg_t; - -/** Type of interrupt_source register - * need_des - */ -typedef union { - struct { - /** lp_interrupt_source : RO; bitpos: [5:0]; default: 0; - * BIT5~BIT0: pmu_lp_int, modem_lp_int, lp_timer_lp_int, lp_uart_int, lp_i2c_int, - * lp_io_int - */ - uint32_t lp_interrupt_source:6; - uint32_t reserved_6:26; - }; - uint32_t val; -} lpperi_interrupt_source_reg_t; - -/** Type of debug_sel0 register - * need des - */ -typedef union { - struct { - /** debug_sel0 : R/W; bitpos: [6:0]; default: 0; - * need des - */ - uint32_t debug_sel0:7; - /** debug_sel1 : R/W; bitpos: [13:7]; default: 0; - * need des - */ - uint32_t debug_sel1:7; - /** debug_sel2 : R/W; bitpos: [20:14]; default: 0; - * need des - */ - uint32_t debug_sel2:7; - /** debug_sel3 : R/W; bitpos: [27:21]; default: 0; - * need des - */ - uint32_t debug_sel3:7; - uint32_t reserved_28:4; - }; - uint32_t val; -} lpperi_debug_sel0_reg_t; - -/** Type of debug_sel1 register - * need des - */ -typedef union { - struct { - /** debug_sel4 : R/W; bitpos: [6:0]; default: 0; - * need des - */ - uint32_t debug_sel4:7; - uint32_t reserved_7:25; - }; - uint32_t val; -} lpperi_debug_sel1_reg_t; - - -/** Group: Version register */ -/** Type of date register - * need_des - */ -typedef union { - struct { - /** lpperi_date : R/W; bitpos: [30:0]; default: 35676464; - * need_des - */ - uint32_t lpperi_date:31; - /** clk_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t clk_en:1; - }; - uint32_t val; -} lpperi_date_reg_t; - - typedef struct { - volatile lpperi_clk_en_reg_t clk_en; - volatile lpperi_reset_en_reg_t reset_en; - volatile lpperi_rng_data_reg_t rng_data; - volatile lpperi_cpu_reg_t cpu; - volatile lpperi_bus_timeout_reg_t bus_timeout; - volatile lpperi_bus_timeout_addr_reg_t bus_timeout_addr; - volatile lpperi_bus_timeout_uid_reg_t bus_timeout_uid; - volatile lpperi_mem_ctrl_reg_t mem_ctrl; - volatile lpperi_interrupt_source_reg_t interrupt_source; - volatile lpperi_debug_sel0_reg_t debug_sel0; - volatile lpperi_debug_sel1_reg_t debug_sel1; - uint32_t reserved_02c[244]; - volatile lpperi_date_reg_t date; + volatile lpperi_clk_en_reg_t *clk_en; + volatile lpperi_reset_en_reg_t *reset_en; + volatile lpperi_rng_cfg_reg_t *rng_cfg; + volatile lpperi_rng_data_reg_t *rng_data; + volatile lpperi_cpu_reg_t *cpu; + volatile lpperi_bus_timeout_reg_t *bus_timeout; + volatile lpperi_bus_timeout_addr_reg_t *bus_timeout_addr; + volatile lpperi_bus_timeout_uid_reg_t *bus_timeout_uid; + volatile lpperi_mem_ctrl_reg_t *mem_ctrl; + volatile lpperi_interrupt_source_reg_t *interrupt_source; + volatile lpperi_debug_sel0_reg_t *debug_sel0; + volatile lpperi_debug_sel1_reg_t *debug_sel1; + volatile lpperi_date_reg_t *date; } lpperi_dev_t; -extern lpperi_dev_t LPPERI; +extern lpperi_dev_t LPPERI; // Compatible instance that achieved in 'lpperi_struct.c' -#ifndef __cplusplus -_Static_assert(sizeof(lpperi_dev_t) == 0x400, "Invalid size of lpperi_dev_t structure"); -#endif +/** + * @brief Initialize the LP_PERI register address according to the register version + */ +void lpperi_compatible_reg_addr_init(void); #ifdef __cplusplus } diff --git a/components/soc/esp32h2/ld/esp32h2.peripherals.ld b/components/soc/esp32h2/ld/esp32h2.peripherals.ld index f2d4e25be7..59ecdedb6d 100644 --- a/components/soc/esp32h2/ld/esp32h2.peripherals.ld +++ b/components/soc/esp32h2/ld/esp32h2.peripherals.ld @@ -66,7 +66,8 @@ PROVIDE ( LP_TIMER = 0x600B0C00 ); PROVIDE ( LP_AON = 0x600B1000 ); PROVIDE ( LP_WDT = 0x600B1C00 ); PROVIDE ( I2C_ANA_MST = 0x600B2400 ); -PROVIDE ( LPPERI = 0x600B2800 ); +PROVIDE ( LPPERI_REV0_0 = 0x600B2800 ); +PROVIDE ( LPPERI_REV1_2 = 0x600B2800 ); PROVIDE ( LP_ANA_PERI = 0x600B2C00 ); PROVIDE ( LP_APM = 0x600B3800 ); PROVIDE ( OTP_DEBUG = 0x600B3C00 ); diff --git a/components/soc/esp32h2/lpperi_struct.c b/components/soc/esp32h2/lpperi_struct.c new file mode 100644 index 0000000000..ea396eec9d --- /dev/null +++ b/components/soc/esp32h2/lpperi_struct.c @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "assert.h" +#include "soc/lpperi_struct.h" + +#define LPPERI_REV1_2_DATE (0x2308030) +#define LPPERI_REG_ADDR(reg) ((LPPERI_REV1_2.date.lpperi_date >= LPPERI_REV1_2_DATE) ? \ + &LPPERI_REV1_2.reg : \ + (volatile typeof(LPPERI_REV1_2.reg) *)&LPPERI_REV0_0.reg) + +/** + * @brief Compatible LPPERI instance + * @note Set NULL as default so that to abort when use the LPPEIR before initialization + * If you want to use the LPPERI before it is initialized, please use `lpperi_reg.h` instead + */ +lpperi_dev_t LPPERI = {}; + +/** + * @brief Initialize the LP_PERI register address according to the register version + */ +void lpperi_compatible_reg_addr_init(void) +{ + LPPERI.clk_en = LPPERI_REG_ADDR(clk_en); + LPPERI.reset_en = LPPERI_REG_ADDR(reset_en); + LPPERI.rng_cfg = ((LPPERI_REV1_2.date.lpperi_date >= LPPERI_REV1_2_DATE) ? &LPPERI_REV1_2.rng_cfg : NULL); + LPPERI.rng_data = LPPERI_REG_ADDR(rng_data); + LPPERI.cpu = LPPERI_REG_ADDR(cpu); + LPPERI.bus_timeout = LPPERI_REG_ADDR(bus_timeout); + LPPERI.bus_timeout_addr = LPPERI_REG_ADDR(bus_timeout_addr); + LPPERI.bus_timeout_uid = LPPERI_REG_ADDR(bus_timeout_uid); + LPPERI.mem_ctrl = LPPERI_REG_ADDR(mem_ctrl); + LPPERI.interrupt_source = LPPERI_REG_ADDR(interrupt_source); + LPPERI.debug_sel0 = LPPERI_REG_ADDR(debug_sel0); + LPPERI.debug_sel1 = LPPERI_REG_ADDR(debug_sel1); + LPPERI.date = LPPERI_REG_ADDR(date); +} + +__attribute__((constructor)) +static void s_lpperi_compatible_init_check(void) +{ + // Make sure it is initialized + assert(LPPERI.clk_en != NULL); +}