diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index b71e77879e..2b4f908cfd 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -111,8 +111,8 @@ CHIP_CSRCS += esp32_himem.c CHIP_CSRCS += esp32_himem_chardev.c endif -ifeq ($(CONFIG_ESP32_EFUSE),y) CHIP_CSRCS += esp32_efuse.c +ifeq ($(CONFIG_ESP32_EFUSE),y) CHIP_CSRCS += esp32_efuse_table.c CHIP_CSRCS += esp32_efuse_lowerhalf.c endif diff --git a/arch/xtensa/src/esp32/esp32_efuse.c b/arch/xtensa/src/esp32/esp32_efuse.c index 12f2ddd514..df7518520c 100644 --- a/arch/xtensa/src/esp32/esp32_efuse.c +++ b/arch/xtensa/src/esp32/esp32_efuse.c @@ -68,6 +68,7 @@ uint32_t g_start_efuse_wrreg[4] = * Private Prototypes ****************************************************************************/ +#ifdef CONFIG_ESP32_EFUSE static int esp_efuse_set_timing(void); void esp_efuse_burn_efuses(void); static uint32_t get_mask(uint32_t bit_count, uint32_t shift); @@ -90,11 +91,17 @@ static int esp_efuse_fill_buff(uint32_t num_reg, int bit_offset, int *bits_counter); static void esp_efuse_write_reg(uint32_t blk, uint32_t num_reg, uint32_t value); +#endif /* CONFIG_ESP32_EFUSE */ + +static uint32_t efuse_hal_get_major_chip_version(void); +static uint32_t efuse_hal_get_minor_chip_version(void); /**************************************************************************** * Private Functions ****************************************************************************/ +#ifdef CONFIG_ESP32_EFUSE + static int esp_efuse_set_timing(void) { uint32_t apb_freq_mhz = esp_clk_apb_freq() / 1000000; @@ -429,10 +436,105 @@ static void esp_efuse_write_reg(uint32_t blk, uint32_t num_reg, putreg32(reg_to_write, addr_wr_reg); } +#endif /* CONFIG_ESP32_EFUSE */ + +/**************************************************************************** + * Name: efuse_hal_get_major_chip_version + * + * Description: + * Retrieves the major version of the chip. It reads the version + * information from specific registers and combines them to determine + * the major version. + * + * Input Parameters: + * None + * + * Returned Value: + * The major version of the chip as an unsigned 32-bit integer. + * + ****************************************************************************/ + +IRAM_ATTR static uint32_t efuse_hal_get_major_chip_version(void) +{ + uint8_t eco_bit0; + uint8_t eco_bit1; + uint8_t eco_bit2; + uint32_t combine_value; + uint32_t chip_ver = 0; + + eco_bit0 = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_REV1); + eco_bit1 = REG_GET_FIELD(EFUSE_BLK0_RDATA5_REG, EFUSE_RD_CHIP_VER_REV2); + eco_bit2 = (getreg32(APB_CTRL_DATE_REG) & 0x80000000) >> 31; + combine_value = (eco_bit2 << 2) | (eco_bit1 << 1) | eco_bit0; + + switch (combine_value) + { + case 0: + chip_ver = 0; + break; + case 1: + chip_ver = 1; + break; + case 3: + chip_ver = 2; + break; + case 7: + chip_ver = 3; + break; + default: + chip_ver = 0; + break; + } + + return chip_ver; +} + +/**************************************************************************** + * Name: efuse_hal_get_minor_chip_version + * + * Description: + * Retrieves the minor version of the chip. It reads the version + * information from a specific register. + * + * Input Parameters: + * None + * + * Returned Value: + * The minor version of the chip as an unsigned 32-bit integer. + * + ****************************************************************************/ + +IRAM_ATTR static uint32_t efuse_hal_get_minor_chip_version(void) +{ + return REG_GET_FIELD(EFUSE_BLK0_RDATA5_REG, EFUSE_RD_WAFER_VERSION_MINOR); +} + /**************************************************************************** * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: esp_efuse_hal_chip_revision + * + * Description: + * Returns the chip version in the format: Major * 100 + Minor. + * + * Input Parameters: + * None + * + * Returned Value: + * The chip version as an unsigned 32-bit integer. + * + ****************************************************************************/ + +IRAM_ATTR uint32_t esp_efuse_hal_chip_revision(void) +{ + return (efuse_hal_get_major_chip_version() * 100) + + efuse_hal_get_minor_chip_version(); +} + +#ifdef CONFIG_ESP32_EFUSE + /* Read value from EFUSE, writing it into an array */ int esp_efuse_read_field(const efuse_desc_t *field[], void *dst, @@ -499,3 +601,4 @@ void esp_efuse_burn_efuses(void) }; } +#endif /* CONFIG_ESP32_EFUSE */ diff --git a/arch/xtensa/src/esp32/esp32_efuse.h b/arch/xtensa/src/esp32/esp32_efuse.h index 51497ba318..904693d3fc 100644 --- a/arch/xtensa/src/esp32/esp32_efuse.h +++ b/arch/xtensa/src/esp32/esp32_efuse.h @@ -18,6 +18,16 @@ * ****************************************************************************/ +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + /* Type of eFuse blocks for ESP32 */ typedef enum @@ -52,6 +62,24 @@ typedef int (*efuse_func_proc_t) (unsigned int num_reg, * Public Functions Prototypes ****************************************************************************/ +/**************************************************************************** + * Name: esp_efuse_hal_chip_revision + * + * Description: + * Returns the chip version in the format: Major * 100 + Minor. + * + * Input Parameters: + * None + * + * Returned Value: + * The chip version as an unsigned 32-bit integer. + * + ****************************************************************************/ + +uint32_t esp_efuse_hal_chip_revision(void); + +#ifdef CONFIG_ESP32_EFUSE + int esp_efuse_read_field(const efuse_desc_t *field[], void *dst, size_t dst_size_bits); @@ -61,3 +89,5 @@ int esp_efuse_write_field(const efuse_desc_t *field[], void esp_efuse_burn_efuses(void); int esp32_efuse_initialize(const char *devpath); + +#endif /* CONFIG_ESP32_EFUSE */ diff --git a/arch/xtensa/src/esp32/esp32_start.c b/arch/xtensa/src/esp32/esp32_start.c index 0422dd7a3e..30679d7840 100644 --- a/arch/xtensa/src/esp32/esp32_start.c +++ b/arch/xtensa/src/esp32/esp32_start.c @@ -24,6 +24,7 @@ #include +#include #include #include #include @@ -35,6 +36,7 @@ #include "xtensa_attr.h" #include "esp32_clockconfig.h" +#include "esp32_efuse.h" #include "esp32_region.h" #include "esp32_start.h" #include "esp32_spiram.h" @@ -91,8 +93,9 @@ extern uint8_t _image_drom_size[]; * ROM Function Prototypes ****************************************************************************/ -#ifdef CONFIG_ESP32_APP_FORMAT_MCUBOOT extern int ets_printf(const char *fmt, ...) printf_like(1, 2); + +#ifdef CONFIG_ESP32_APP_FORMAT_MCUBOOT extern void cache_read_enable(int cpu); extern void cache_read_disable(int cpu); extern void cache_flush(int cpu); @@ -143,6 +146,7 @@ static noreturn_function void __esp32_start(void) { uint32_t sp; uint32_t regval unused_data; + uint32_t chip_rev; /* Make sure that normal interrupts are disabled. This is really only an * issue when we are started in un-usual ways (such as from IRAM). In this @@ -222,6 +226,26 @@ static noreturn_function void __esp32_start(void) showprogress('A'); + chip_rev = esp_efuse_hal_chip_revision(); + + _info("ESP32 chip revision is v%d.%01d\n", chip_rev / 100, chip_rev % 100); + + if (chip_rev < 300) + { +#ifndef ESP32_IGNORE_CHIP_REVISION_CHECK + ets_printf("ERROR: NuttX supports ESP32 chip revision >= v3.0" + " (chip revision is v%d.%01d)\n", + chip_rev / 100, chip_rev % 100); + PANIC(); +#endif + ets_printf("WARNING: NuttX supports ESP32 chip revision >= v3.0" + " (chip is v%d.%01d).\n" + "Ignoring this error and continuing because " + "`ESP32_IGNORE_CHIP_REVISION_CHECK` is set...\n" + "THIS MAY NOT WORK! DON'T USE THIS CHIP IN PRODUCTION!\n", + chip_rev / 100, chip_rev % 100); + } + #if defined(CONFIG_ESP32_SPIRAM_BOOT_INIT) if (esp_spiram_init() != OK) {