refactor(lpperi): improve compatibility solution

This commit is contained in:
laokaiyao 2025-01-15 17:02:34 +08:00
parent 4d11fe5847
commit 692ca37edf
10 changed files with 25 additions and 93 deletions

View File

@ -41,7 +41,6 @@
#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 "hal/regi2c_ctrl_ll.h"
#include "hal/brownout_ll.h"
@ -110,9 +109,6 @@ 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();

View File

@ -53,7 +53,6 @@
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/cache.h"
#include "esp_memprot.h"
#include "soc/lpperi_struct.h"
#elif CONFIG_IDF_TARGET_ESP32C2
#include "esp32c2/rom/cache.h"
#include "esp32c2/rom/secure_boot.h"
@ -453,13 +452,6 @@ 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();

View File

@ -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_REG_SET(clk_en.rng_ck_en, en);
}
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way

View File

@ -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_REG_SET(clk_en.lp_io_ck_en, enable);
while (LPPERI_REG_GET(clk_en.lp_io_ck_en) != enable) {
;
}
}

View File

@ -27,10 +27,6 @@ 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()

View File

@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
/* For compatibility of ECO0 and ECO5 */
/* This is a wrapper for revisions compatibility */
#pragma once
@ -17,31 +17,33 @@ extern "C" {
#endif
/**
* @brief Compatible lpperi struct for ECO0-ECO4 and ECO5
* @brief Compatible lpperi struct wrapper
*
*/
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;
volatile lpperi_date_reg_t *date;
typedef union {
volatile lpperi_rev0_0_dev_t rev0_0; /* Struct for LPPERI v0.0 < rev < v1.2 */
volatile lpperi_rev1_2_dev_t rev1_2; /* Struct for LPPERI rev >= v1.2*/
} lpperi_dev_t;
extern lpperi_dev_t LPPERI; // Compatible instance that achieved in 'lpperi_struct.c'
extern lpperi_dev_t LPPERI;
/** The LPPERI date version of chip revision 1.2*/
#define LPPERI_REV1_2_DATE (0x2308030)
/**
* @brief Initialize the LP_PERI register address according to the register version
* @brief Set the register value compatibly
* @param reg The register to set (can carry the field, like clk_en.lp_io_ck_en)
* @param val The value to set
*/
void lpperi_compatible_reg_addr_init(void);
#define LPPERI_REG_SET(reg, val) (LPPERI.rev1_2.date.lpperi_date >= LPPERI_REV1_2_DATE ? \
(LPPERI.rev1_2.reg = (val)) : (LPPERI.rev0_0.reg = (val)))
/**
* @brief Get the register value compatibly
* @param reg The register to get (can carry the field, like clk_en.lp_io_ck_en)
*/
#define LPPERI_REG_GET(reg) (LPPERI.rev1_2.date.lpperi_date >= LPPERI_REV1_2_DATE ? \
(LPPERI.rev1_2.reg) : (LPPERI.rev0_0.reg))
#ifdef __cplusplus
}

View File

@ -66,8 +66,7 @@ PROVIDE ( LP_TIMER = 0x600B0C00 );
PROVIDE ( LP_AON = 0x600B1000 );
PROVIDE ( LP_WDT = 0x600B1C00 );
PROVIDE ( I2C_ANA_MST = 0x600B2400 );
PROVIDE ( LPPERI_REV0_0 = 0x600B2800 );
PROVIDE ( LPPERI_REV1_2 = 0x600B2800 );
PROVIDE ( LPPERI = 0x600B2800 );
PROVIDE ( LP_ANA_PERI = 0x600B2C00 );
PROVIDE ( LP_APM = 0x600B3800 );
PROVIDE ( OTP_DEBUG = 0x600B3C00 );

View File

@ -1,47 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#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);
}

View File

@ -301,9 +301,6 @@ typedef struct {
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

View File

@ -316,9 +316,6 @@ typedef struct {
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