From 9825afdb7f042b16aec52a449e1c9857d990b4d0 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 9 Oct 2025 00:44:03 +0200 Subject: [PATCH] Revert get settings from boards.json for HybridCompile Refactor ESP-IDF configuration handling to improve clarity and maintainability. Remove unused functions and streamline flash configuration logic. --- builder/frameworks/espidf.py | 358 +++-------------------------------- 1 file changed, 27 insertions(+), 331 deletions(-) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index 2b435ed..56acff9 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -78,7 +78,7 @@ config = env.GetProjectConfig() board = env.BoardConfig() mcu = board.get("build.mcu", "esp32") flash_speed = board.get("build.f_flash", "40000000L") -flash_frequency = str(flash_speed.replace("000000L", "")) +flash_frequency = str(flash_speed.replace("000000L", "m")) flash_mode = board.get("build.flash_mode", "dio") idf_variant = mcu.lower() flag_custom_sdkonfig = False @@ -218,29 +218,6 @@ if config.has_option("env:"+env["PIOENV"], "custom_sdkconfig"): if "espidf.custom_sdkconfig" in board: flag_custom_sdkonfig = True - -# Check for board-specific configurations that require sdkconfig generation -def has_board_specific_config(): - """Check if board has configuration that needs to be applied to sdkconfig.""" - # Check for PSRAM support - extra_flags = board.get("build.extra_flags", []) - has_psram = any("-DBOARD_HAS_PSRAM" in flag for flag in extra_flags) - - # Check for special memory types - memory_type = None - build_section = board.get("build", {}) - arduino_section = build_section.get("arduino", {}) - if "memory_type" in arduino_section: - memory_type = arduino_section["memory_type"] - elif "memory_type" in build_section: - memory_type = build_section["memory_type"] - has_special_memory = memory_type and ("opi" in memory_type.lower()) - - return has_psram or has_special_memory - -if has_board_specific_config(): - flag_custom_sdkonfig = True - def HandleArduinoIDFsettings(env): """ Handles Arduino IDF settings configuration with custom sdkconfig support. @@ -307,322 +284,48 @@ def HandleArduinoIDFsettings(env): return line.split("=")[0] return None - def generate_board_specific_config(): - """Generate board-specific sdkconfig settings from board.json manifest.""" - board_config_flags = [] - - # Handle memory type configuration with platformio.ini override support - # Priority: platformio.ini > board.json manifest - memory_type = None - - # Check for memory_type override in platformio.ini - if hasattr(env, 'GetProjectOption'): - try: - memory_type = env.GetProjectOption("board_build.memory_type", None) - except: - pass - - # Fallback to board.json manifest - if not memory_type: - build_section = board.get("build", {}) - arduino_section = build_section.get("arduino", {}) - if "memory_type" in arduino_section: - memory_type = arduino_section["memory_type"] - elif "memory_type" in build_section: - memory_type = build_section["memory_type"] - - flash_memory_type = None - psram_memory_type = None - if memory_type: - parts = memory_type.split("_") - if len(parts) == 2: - flash_memory_type, psram_memory_type = parts - else: - flash_memory_type = memory_type - - # Check for additional flash configuration indicators - boot_mode = board.get("build", {}).get("boot", None) - flash_mode = board.get("build", {}).get("flash_mode", None) - - # Override flash_memory_type if boot mode indicates OPI - if boot_mode == "opi" or flash_mode in ["dout", "opi"]: - if not flash_memory_type or flash_memory_type.lower() != "opi": - flash_memory_type = "opi" - print(f"Info: Detected OPI Flash via boot_mode='{boot_mode}' or flash_mode='{flash_mode}'") - - # Set CPU frequency with platformio.ini override support - # Priority: platformio.ini > board.json manifest - f_cpu = None - if hasattr(env, 'GetProjectOption'): - # Check for board_build.f_cpu override in platformio.ini - try: - f_cpu = env.GetProjectOption("board_build.f_cpu", None) - except: - pass - - # Fallback to board.json manifest - if not f_cpu: - f_cpu = board.get("build.f_cpu", None) - - if f_cpu: - cpu_freq = str(f_cpu).replace("000000L", "") - board_config_flags.append(f"CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ={cpu_freq}") - # Disable other CPU frequency options and enable the specific one - common_cpu_freqs = ["80", "160", "240"] - for freq in common_cpu_freqs: - if freq != cpu_freq: - if mcu == "esp32": - board_config_flags.append(f"# CONFIG_ESP32_DEFAULT_CPU_FREQ_{freq} is not set") - elif mcu in ["esp32s2", "esp32s3"]: - board_config_flags.append(f"# CONFIG_ESP32S2_DEFAULT_CPU_FREQ_{freq} is not set" if mcu == "esp32s2" else f"# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_{freq} is not set") - elif mcu in ["esp32c2", "esp32c3", "esp32c6"]: - board_config_flags.append(f"# CONFIG_ESP32C3_DEFAULT_CPU_FREQ_{freq} is not set") - # Enable the specific CPU frequency - if mcu == "esp32": - board_config_flags.append(f"CONFIG_ESP32_DEFAULT_CPU_FREQ_{cpu_freq}=y") - elif mcu == "esp32s2": - board_config_flags.append(f"CONFIG_ESP32S2_DEFAULT_CPU_FREQ_{cpu_freq}=y") - elif mcu == "esp32s3": - board_config_flags.append(f"CONFIG_ESP32S3_DEFAULT_CPU_FREQ_{cpu_freq}=y") - elif mcu in ["esp32c2", "esp32c3", "esp32c6"]: - board_config_flags.append(f"CONFIG_ESP32C3_DEFAULT_CPU_FREQ_{cpu_freq}=y") - - # Set flash size with platformio.ini override support - # Priority: platformio.ini > board.json manifest - flash_size = None - if hasattr(env, 'GetProjectOption'): - # Check for board_upload.flash_size override in platformio.ini - try: - flash_size = env.GetProjectOption("board_upload.flash_size", None) - except: - pass - - # Fallback to board.json manifest - if not flash_size: - flash_size = board.get("upload", {}).get("flash_size", None) - - if flash_size: - # Configure both string and boolean flash size formats - # Disable other flash size options first - flash_sizes = ["4MB", "8MB", "16MB", "32MB", "64MB", "128MB"] - for size in flash_sizes: - if size != flash_size: - board_config_flags.append(f"# CONFIG_ESPTOOLPY_FLASHSIZE_{size} is not set") - - # Set the specific flash size configs - board_config_flags.append(f"CONFIG_ESPTOOLPY_FLASHSIZE=\"{flash_size}\"") - board_config_flags.append(f"CONFIG_ESPTOOLPY_FLASHSIZE_{flash_size}=y") - - # Handle Flash and PSRAM frequency configuration with platformio.ini override support - # Priority: platformio.ini > board.json manifest - # From 80MHz onwards, Flash and PSRAM frequencies must be identical - - # Get f_flash with override support - f_flash = None - if hasattr(env, 'GetProjectOption'): - try: - f_flash = env.GetProjectOption("board_build.f_flash", None) - except: - pass - if not f_flash: - f_flash = board.get("build.f_flash", None) - - # Get f_boot with override support - f_boot = None - if hasattr(env, 'GetProjectOption'): - try: - f_boot = env.GetProjectOption("board_build.f_boot", None) - except: - pass - if not f_boot: - f_boot = board.get("build.f_boot", None) - - # Determine the frequencies to use - esptool_flash_freq = f_flash # Always use f_flash for esptool compatibility - compile_freq = f_boot if f_boot else f_flash # Use f_boot for compile-time if available - - if f_flash and compile_freq: - # Ensure frequency compatibility (>= 80MHz must be identical for Flash and PSRAM) - compile_freq_val = int(str(compile_freq).replace("000000L", "")) - - if compile_freq_val >= 80: - # Above 80MHz, both Flash and PSRAM must use same frequency - unified_freq = compile_freq_val - flash_freq_str = f"{unified_freq}m" - psram_freq_str = str(unified_freq) - - print(f"Info: Unified frequency mode (>= 80MHz): {unified_freq}MHz for both Flash and PSRAM") - else: - # Below 80MHz, frequencies can differ - flash_freq_str = str(compile_freq).replace("000000L", "m") - psram_freq_str = str(compile_freq).replace("000000L", "") - - print(f"Info: Independent frequency mode (< 80MHz): Flash={flash_freq_str}, PSRAM={psram_freq_str}") - - # Configure Flash frequency - # Disable other flash frequency options first - flash_freqs = ["20m", "26m", "40m", "80m", "120m"] - for freq in flash_freqs: - if freq != flash_freq_str: - board_config_flags.append(f"# CONFIG_ESPTOOLPY_FLASHFREQ_{freq.upper()} is not set") - # Then set the specific frequency configs - board_config_flags.append(f"CONFIG_ESPTOOLPY_FLASHFREQ=\"{flash_freq_str}\"") - board_config_flags.append(f"CONFIG_ESPTOOLPY_FLASHFREQ_{flash_freq_str.upper()}=y") - - # Configure PSRAM frequency (same as Flash for >= 80MHz) - # Disable other SPIRAM speed options first - psram_freqs = ["40", "80", "120"] - for freq in psram_freqs: - if freq != psram_freq_str: - board_config_flags.append(f"# CONFIG_SPIRAM_SPEED_{freq}M is not set") - # Then set the specific SPIRAM configs - board_config_flags.append(f"CONFIG_SPIRAM_SPEED={psram_freq_str}") - board_config_flags.append(f"CONFIG_SPIRAM_SPEED_{psram_freq_str}M=y") - - # Enable experimental features for frequencies > 80MHz - if compile_freq_val > 80: - board_config_flags.append("CONFIG_IDF_EXPERIMENTAL_FEATURES=y") - board_config_flags.append("CONFIG_SPI_FLASH_HPM_ENABLE=y") - board_config_flags.append("CONFIG_SPI_FLASH_HPM_AUTO=y") - - # Check for PSRAM support based on board flags - extra_flags = board.get("build.extra_flags", []) - has_psram = any("-DBOARD_HAS_PSRAM" in flag for flag in extra_flags) - - # Additional PSRAM detection methods - if not has_psram: - # Check if memory_type contains psram indicators - if memory_type and ("opi" in memory_type.lower() or "psram" in memory_type.lower()): - has_psram = True - # Check build.psram_type - elif "psram_type" in board.get("build", {}): - has_psram = True - # Check for SPIRAM mentions in extra_flags - elif any("SPIRAM" in str(flag) for flag in extra_flags): - has_psram = True - # For ESP32-S3, assume PSRAM capability (can be disabled later if not present) - elif mcu == "esp32s3": - has_psram = True - - if has_psram: - # Enable basic SPIRAM support - board_config_flags.append("CONFIG_SPIRAM=y") - - # Determine PSRAM type with platformio.ini override support - # Priority: platformio.ini > memory_type > build.psram_type > default - psram_type = None - - # Priority 1: Check for platformio.ini override - if hasattr(env, 'GetProjectOption'): - try: - psram_type = env.GetProjectOption("board_build.psram_type", None) - if psram_type: - psram_type = psram_type.lower() - except: - pass - - # Priority 2: Check psram_memory_type from memory_type field (e.g., "qio_opi") - if not psram_type and psram_memory_type: - psram_type = psram_memory_type.lower() - # Priority 3: Check build.psram_type field as fallback - elif not psram_type and "psram_type" in board.get("build", {}): - psram_type = board.get("build.psram_type", "qio").lower() - # Priority 4: Default to qio - elif not psram_type: - psram_type = "qio" - - # Configure PSRAM mode based on detected type - if psram_type == "opi": - # Octal PSRAM configuration (for ESP32-S3 only) - if mcu == "esp32s3": - board_config_flags.extend([ - "CONFIG_IDF_EXPERIMENTAL_FEATURES=y", - "# CONFIG_SPIRAM_MODE_QUAD is not set", - "CONFIG_SPIRAM_MODE_OCT=y", - "CONFIG_SPIRAM_TYPE_AUTO=y" - ]) - else: - # Fallback to QUAD for non-S3 chips - board_config_flags.extend([ - "# CONFIG_SPIRAM_MODE_OCT is not set", - "CONFIG_SPIRAM_MODE_QUAD=y" - ]) - - elif psram_type in ["qio", "qspi"]: - # Quad PSRAM configuration - if mcu in ["esp32s2", "esp32s3"]: - board_config_flags.extend([ - "# CONFIG_SPIRAM_MODE_OCT is not set", - "CONFIG_SPIRAM_MODE_QUAD=y" - ]) - elif mcu == "esp32": - board_config_flags.extend([ - "# CONFIG_SPIRAM_MODE_OCT is not set", - "# CONFIG_SPIRAM_MODE_QUAD is not set" - ]) - - # Use flash_memory_type for flash config - if flash_memory_type and "opi" in flash_memory_type.lower(): - # OPI Flash configurations require specific settings - board_config_flags.extend([ - "# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set", - "# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set", - "# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set", - "CONFIG_ESPTOOLPY_FLASHMODE_DOUT=y", - "CONFIG_ESPTOOLPY_OCT_FLASH=y", - "# CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR is not set", - "CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR=y" - ]) - - return board_config_flags - def build_idf_config_flags(): """Build complete IDF configuration flags from all sources.""" flags = [] - # FIRST: Add board-specific flags derived from board.json manifest - board_flags = generate_board_specific_config() - if board_flags: - flags.extend(board_flags) - - # SECOND: Add board-specific flags from board manifest (espidf.custom_sdkconfig) + # Add board-specific flags first if "espidf.custom_sdkconfig" in board: - board_manifest_flags = board.get("espidf.custom_sdkconfig", []) - if board_manifest_flags: - flags.extend(board_manifest_flags) + board_flags = board.get("espidf.custom_sdkconfig", []) + if board_flags: + flags.extend(board_flags) - # THIRD: Add custom sdkconfig file content + # Add custom sdkconfig file content custom_file_content = load_custom_sdkconfig_file() if custom_file_content: flags.append(custom_file_content) - # FOURTH: Add project-level custom sdkconfig (highest precedence for user overrides) + # Add project-level custom sdkconfig if config.has_option("env:" + env["PIOENV"], "custom_sdkconfig"): custom_flags = env.GetProjectOption("custom_sdkconfig").rstrip("\n") if custom_flags: flags.append(custom_flags) - # FIFTH: Apply ESP32-specific compatibility fixes - all_flags_str = "\n".join(flags) + "\n" if flags else "" - esp32_compatibility_flags = apply_esp32_compatibility_fixes(all_flags_str) - if esp32_compatibility_flags: - flags.extend(esp32_compatibility_flags) - return "\n".join(flags) + "\n" if flags else "" - def apply_esp32_compatibility_fixes(config_flags_str): - """Apply ESP32-specific compatibility fixes based on final configuration.""" - compatibility_flags = [] + def add_flash_configuration(config_flags): + """Add flash frequency and mode configuration.""" + if flash_frequency != "80m": + config_flags += "# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set\n" + config_flags += f"CONFIG_ESPTOOLPY_FLASHFREQ_{flash_frequency.upper()}=y\n" + config_flags += f"CONFIG_ESPTOOLPY_FLASHFREQ=\"{flash_frequency}\"\n" + + if flash_mode != "qio": + config_flags += "# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set\n" + + flash_mode_flag = f"CONFIG_ESPTOOLPY_FLASHMODE_{flash_mode.upper()}=y\n" + if flash_mode_flag not in config_flags: + config_flags += flash_mode_flag # ESP32 specific SPIRAM configuration - # On ESP32, SPIRAM is not used with UNICORE mode - if mcu == "esp32" and "CONFIG_FREERTOS_UNICORE=y" in config_flags_str: - if "CONFIG_SPIRAM=y" in config_flags_str: - compatibility_flags.append("# CONFIG_SPIRAM is not set") - print("Info: ESP32 SPIRAM disabled since solo1 core mode is enabled") + if mcu == "esp32" and "CONFIG_FREERTOS_UNICORE=y" in config_flags: + config_flags += "# CONFIG_SPIRAM is not set\n" - return compatibility_flags - + return config_flags def write_sdkconfig_file(idf_config_flags, checksum_source): if "arduino" not in env.subst("$PIOFRAMEWORK"): @@ -643,9 +346,7 @@ def HandleArduinoIDFsettings(env): dst.write(f"# TASMOTA__{checksum}\n") # Process each line from source sdkconfig - src_lines = src.readlines() - - for line in src_lines: + for line in src: flag_name = extract_flag_name(line) if flag_name is None: @@ -674,25 +375,20 @@ def HandleArduinoIDFsettings(env): print(f"Add: {cleaned_flag}") dst.write(cleaned_flag + "\n") - # Main execution logic has_custom_config = ( config.has_option("env:" + env["PIOENV"], "custom_sdkconfig") or "espidf.custom_sdkconfig" in board ) - has_board_config = has_board_specific_config() - - if not has_custom_config and not has_board_config: + if not has_custom_config: return - if has_board_config and not has_custom_config: - print("*** Apply board-specific settings to IDF sdkconfig.defaults ***") - else: - print("*** Add \"custom_sdkconfig\" settings to IDF sdkconfig.defaults ***") + print("*** Add \"custom_sdkconfig\" settings to IDF sdkconfig.defaults ***") # Build complete configuration idf_config_flags = build_idf_config_flags() + idf_config_flags = add_flash_configuration(idf_config_flags) # Convert to list for processing idf_config_list = [line for line in idf_config_flags.splitlines() if line.strip()]