From 0e108c2178231f3bd76cf39ea5d4bc4dd55dc84f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 2 Jan 2026 14:14:52 -1000 Subject: [PATCH] [esp32] Add minimum_chip_revision setting and log chip revision at startup (#12696) --- esphome/components/esp32/__init__.py | 39 ++++++++++++++++++++++++++++ esphome/core/application.cpp | 16 ++++++++++++ esphome/core/defines.h | 1 + 3 files changed, 56 insertions(+) diff --git a/esphome/components/esp32/__init__.py b/esphome/components/esp32/__init__.py index d8397a87cc..da550e58dc 100644 --- a/esphome/components/esp32/__init__.py +++ b/esphome/components/esp32/__init__.py @@ -85,6 +85,7 @@ CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES = "enable_idf_experimental_features" CONF_ENABLE_LWIP_ASSERT = "enable_lwip_assert" CONF_ENABLE_OTA_ROLLBACK = "enable_ota_rollback" CONF_EXECUTE_FROM_PSRAM = "execute_from_psram" +CONF_MINIMUM_CHIP_REVISION = "minimum_chip_revision" CONF_RELEASE = "release" LOG_LEVELS_IDF = [ @@ -109,6 +110,21 @@ COMPILER_OPTIMIZATIONS = { "SIZE": "CONFIG_COMPILER_OPTIMIZATION_SIZE", } +# ESP32 (original) chip revision options +# Setting minimum revision to 3.0 or higher: +# - Reduces flash size by excluding workaround code for older chip bugs +# - For PSRAM users: disables CONFIG_SPIRAM_CACHE_WORKAROUND, which saves significant +# IRAM by keeping C library functions in ROM instead of recompiling them +# See: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/chip_revision.html +ESP32_CHIP_REVISIONS = { + "0.0": "CONFIG_ESP32_REV_MIN_0", + "1.0": "CONFIG_ESP32_REV_MIN_1", + "1.1": "CONFIG_ESP32_REV_MIN_1_1", + "2.0": "CONFIG_ESP32_REV_MIN_2", + "3.0": "CONFIG_ESP32_REV_MIN_3", + "3.1": "CONFIG_ESP32_REV_MIN_3_1", +} + # Socket limit configuration for ESP-IDF # ESP-IDF CONFIG_LWIP_MAX_SOCKETS has range 1-253, default 10 DEFAULT_MAX_SOCKETS = 10 # ESP-IDF default @@ -566,6 +582,16 @@ def final_validate(config): path=[CONF_FRAMEWORK, CONF_ADVANCED, CONF_IGNORE_EFUSE_MAC_CRC], ) ) + if ( + config[CONF_VARIANT] != VARIANT_ESP32 + and advanced.get(CONF_MINIMUM_CHIP_REVISION) is not None + ): + errs.append( + cv.Invalid( + f"'{CONF_MINIMUM_CHIP_REVISION}' is only supported on {VARIANT_ESP32}", + path=[CONF_FRAMEWORK, CONF_ADVANCED, CONF_MINIMUM_CHIP_REVISION], + ) + ) if advanced[CONF_EXECUTE_FROM_PSRAM]: if config[CONF_VARIANT] != VARIANT_ESP32S3: errs.append( @@ -694,6 +720,9 @@ FRAMEWORK_SCHEMA = cv.Schema( cv.Optional(CONF_ENABLE_LWIP_ASSERT, default=True): cv.boolean, cv.Optional(CONF_IGNORE_EFUSE_CUSTOM_MAC, default=False): cv.boolean, cv.Optional(CONF_IGNORE_EFUSE_MAC_CRC, default=False): cv.boolean, + cv.Optional(CONF_MINIMUM_CHIP_REVISION): cv.one_of( + *ESP32_CHIP_REVISIONS + ), # DHCP server is needed for WiFi AP mode. When WiFi component is used, # it will handle disabling DHCP server when AP is not configured. # Default to false (disabled) when WiFi is not used. @@ -1017,6 +1046,16 @@ async def to_code(config): add_idf_sdkconfig_option( f"CONFIG_ESPTOOLPY_FLASHSIZE_{config[CONF_FLASH_SIZE]}", True ) + + # Set minimum chip revision for ESP32 variant + # Setting this to 3.0 or higher reduces flash size by excluding workaround code, + # and for PSRAM users saves significant IRAM by keeping C library functions in ROM. + if variant == VARIANT_ESP32: + min_rev = conf[CONF_ADVANCED].get(CONF_MINIMUM_CHIP_REVISION) + if min_rev is not None: + for rev, flag in ESP32_CHIP_REVISIONS.items(): + add_idf_sdkconfig_option(flag, rev == min_rev) + cg.add_define("USE_ESP32_MIN_CHIP_REVISION_SET") add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_SINGLE_APP", False) add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_CUSTOM", True) add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_CUSTOM_FILENAME", "partitions.csv") diff --git a/esphome/core/application.cpp b/esphome/core/application.cpp index 4c9cc6b2b6..f8fa3b333e 100644 --- a/esphome/core/application.cpp +++ b/esphome/core/application.cpp @@ -7,6 +7,9 @@ #ifdef USE_ESP8266 #include #endif +#ifdef USE_ESP32 +#include +#endif #include "esphome/core/version.h" #include "esphome/core/hal.h" #include @@ -203,6 +206,19 @@ void Application::loop() { ESP_LOGI(TAG, "ESPHome version " ESPHOME_VERSION " compiled on %s", build_time_str); #ifdef ESPHOME_PROJECT_NAME ESP_LOGI(TAG, "Project " ESPHOME_PROJECT_NAME " version " ESPHOME_PROJECT_VERSION); +#endif +#ifdef USE_ESP32 + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + ESP_LOGI(TAG, "ESP32 Chip: %s r%d.%d, %d core(s)", ESPHOME_VARIANT, chip_info.revision / 100, + chip_info.revision % 100, chip_info.cores); +#if defined(USE_ESP32_VARIANT_ESP32) && !defined(USE_ESP32_MIN_CHIP_REVISION_SET) + // Suggest optimization for chips that don't need the PSRAM cache workaround + if (chip_info.revision >= 300) { + ESP_LOGW(TAG, "Set minimum_chip_revision: \"%d.%d\" to reduce binary size", chip_info.revision / 100, + chip_info.revision % 100); + } +#endif #endif } diff --git a/esphome/core/defines.h b/esphome/core/defines.h index 579edc065a..1fddc426d4 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -166,6 +166,7 @@ #define USE_MQTT_IDF_ENQUEUE #define USE_ESPHOME_TASK_LOG_BUFFER #define USE_OTA_ROLLBACK +#define USE_ESP32_MIN_CHIP_REVISION_SET #define USE_BLUETOOTH_PROXY #define BLUETOOTH_PROXY_MAX_CONNECTIONS 3