Skip to content

Commit 2f4f089

Browse files
authored
HybridCompile: Refactor sdkconfig generation from boards json and add P4 (#316)
* HybridCompile: refactor generation of sdkconfig from boards manifest * add p4 to generate sdkconfig settings * new P4 boards.json entry for PSRAM speed
1 parent 1db24fc commit 2f4f089

File tree

4 files changed

+110
-67
lines changed

4 files changed

+110
-67
lines changed

boards/esp32-p4-evboard.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
],
77
"f_cpu": "360000000L",
88
"f_flash": "80000000L",
9+
"f_psram": "200000000L",
910
"flash_mode": "qio",
1011
"mcu": "esp32p4",
1112
"variant": "esp32p4"

boards/esp32-p4.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
],
77
"f_cpu": "360000000L",
88
"f_flash": "80000000L",
9+
"f_psram": "200000000L",
910
"flash_mode": "qio",
1011
"mcu": "esp32p4",
1112
"variant": "esp32p4"

boards/m5stack-tab5-p4.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
],
99
"f_cpu": "360000000L",
1010
"f_flash": "80000000L",
11+
"f_psram": "200000000L",
1112
"flash_mode": "qio",
1213
"mcu": "esp32p4",
1314
"variant": "m5stack_tab5"

builder/frameworks/espidf.py

Lines changed: 107 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -364,25 +364,20 @@ def generate_board_specific_config():
364364
if f_cpu:
365365
cpu_freq = str(f_cpu).replace("000000L", "")
366366
board_config_flags.append(f"CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ={cpu_freq}")
367+
368+
# MCU name mapping for config flags (uppercase MCU name)
369+
mcu_upper = mcu.upper().replace("-", "")
370+
367371
# Disable other CPU frequency options and enable the specific one
368372
common_cpu_freqs = ["80", "160", "240"]
369373
for freq in common_cpu_freqs:
370374
if freq != cpu_freq:
371-
if mcu == "esp32":
372-
board_config_flags.append(f"# CONFIG_ESP32_DEFAULT_CPU_FREQ_{freq} is not set")
373-
elif mcu in ["esp32s2", "esp32s3"]:
374-
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")
375-
elif mcu in ["esp32c2", "esp32c3", "esp32c6"]:
376-
board_config_flags.append(f"# CONFIG_ESP32C3_DEFAULT_CPU_FREQ_{freq} is not set")
377-
# Enable the specific CPU frequency
378-
if mcu == "esp32":
379-
board_config_flags.append(f"CONFIG_ESP32_DEFAULT_CPU_FREQ_{cpu_freq}=y")
380-
elif mcu == "esp32s2":
381-
board_config_flags.append(f"CONFIG_ESP32S2_DEFAULT_CPU_FREQ_{cpu_freq}=y")
382-
elif mcu == "esp32s3":
383-
board_config_flags.append(f"CONFIG_ESP32S3_DEFAULT_CPU_FREQ_{cpu_freq}=y")
384-
elif mcu in ["esp32c2", "esp32c3", "esp32c6"]:
385-
board_config_flags.append(f"CONFIG_ESP32C3_DEFAULT_CPU_FREQ_{cpu_freq}=y")
375+
board_config_flags.append(f"# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_{freq} is not set")
376+
board_config_flags.append(f"# CONFIG_{mcu_upper}_DEFAULT_CPU_FREQ_{freq} is not set")
377+
378+
# Enable the specific CPU frequency (both generic and MCU-specific)
379+
board_config_flags.append(f"CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_{cpu_freq}=y")
380+
board_config_flags.append(f"CONFIG_{mcu_upper}_DEFAULT_CPU_FREQ_{cpu_freq}=y")
386381

387382
# Set flash size with platformio.ini override support
388383
# Priority: platformio.ini > board.json manifest
@@ -434,53 +429,83 @@ def generate_board_specific_config():
434429
if not f_boot:
435430
f_boot = board.get("build.f_boot", None)
436431

432+
# Get f_psram with override support (ESP32-P4 specific)
433+
f_psram = None
434+
if hasattr(env, 'GetProjectOption'):
435+
try:
436+
f_psram = env.GetProjectOption("board_build.f_psram", None)
437+
except:
438+
pass
439+
if not f_psram:
440+
f_psram = board.get("build.f_psram", None)
441+
437442
# Determine the frequencies to use
438-
esptool_flash_freq = f_flash # Always use f_flash for esptool compatibility
439-
compile_freq = f_boot if f_boot else f_flash # Use f_boot for compile-time if available
443+
# ESP32-P4: f_flash for Flash, f_psram for PSRAM (doesn't affect bootloader name)
444+
445+
if mcu == "esp32p4":
446+
# ESP32-P4: f_flash is always used for Flash frequency
447+
# f_psram is used for PSRAM frequency (if set), otherwise use f_flash
448+
# Note: f_boot is NOT used for P4 as it affects bootloader filename
449+
flash_compile_freq = f_flash
450+
psram_compile_freq = f_psram if f_psram else f_flash
451+
else:
452+
# Other chips: f_boot overrides f_flash for compile-time (both Flash and PSRAM)
453+
compile_freq = f_boot if f_boot else f_flash
454+
flash_compile_freq = compile_freq
455+
psram_compile_freq = compile_freq
440456

441-
if f_flash and compile_freq:
442-
# Ensure frequency compatibility (>= 80MHz must be identical for Flash and PSRAM)
443-
compile_freq_val = int(str(compile_freq).replace("000000L", ""))
457+
if f_flash and flash_compile_freq and psram_compile_freq:
458+
# Validate and parse frequency values
459+
try:
460+
flash_freq_val = int(str(flash_compile_freq).replace("000000L", ""))
461+
psram_freq_val = int(str(psram_compile_freq).replace("000000L", ""))
462+
except (ValueError, AttributeError):
463+
print("Warning: Invalid frequency values, skipping frequency configuration")
464+
flash_freq_val = None
465+
psram_freq_val = None
444466

445-
if compile_freq_val >= 80:
446-
# Above 80MHz, both Flash and PSRAM must use same frequency
447-
unified_freq = compile_freq_val
448-
flash_freq_str = f"{unified_freq}m"
449-
psram_freq_str = str(unified_freq)
467+
if flash_freq_val and psram_freq_val:
468+
# Determine frequency strings
469+
flash_freq_str = f"{flash_freq_val}m"
470+
psram_freq_str = str(psram_freq_val)
450471

451-
print(f"Info: Unified frequency mode (>= 80MHz): {unified_freq}MHz for both Flash and PSRAM")
452-
else:
453-
# Below 80MHz, frequencies can differ
454-
flash_freq_str = str(compile_freq).replace("000000L", "m")
455-
psram_freq_str = str(compile_freq).replace("000000L", "")
472+
# Info message
473+
if mcu == "esp32p4":
474+
print(f"Info: ESP32-P4 frequency mode: Flash={flash_freq_val}MHz, PSRAM={psram_freq_val}MHz")
475+
elif flash_freq_val >= 80:
476+
print(f"Info: Unified frequency mode (>= 80MHz): {flash_freq_val}MHz for both Flash and PSRAM")
477+
else:
478+
print(f"Info: Independent frequency mode (< 80MHz): Flash={flash_freq_str}, PSRAM={psram_freq_str}")
456479

457-
print(f"Info: Independent frequency mode (< 80MHz): Flash={flash_freq_str}, PSRAM={psram_freq_str}")
458-
459-
# Configure Flash frequency
460-
# Disable other flash frequency options first
461-
flash_freqs = ["20m", "26m", "40m", "80m", "120m"]
462-
for freq in flash_freqs:
463-
if freq != flash_freq_str:
464-
board_config_flags.append(f"# CONFIG_ESPTOOLPY_FLASHFREQ_{freq.upper()} is not set")
465-
# Then set the specific frequency configs
466-
board_config_flags.append(f"CONFIG_ESPTOOLPY_FLASHFREQ=\"{flash_freq_str}\"")
467-
board_config_flags.append(f"CONFIG_ESPTOOLPY_FLASHFREQ_{flash_freq_str.upper()}=y")
468-
469-
# Configure PSRAM frequency (same as Flash for >= 80MHz)
470-
# Disable other SPIRAM speed options first
471-
psram_freqs = ["40", "80", "120"]
472-
for freq in psram_freqs:
473-
if freq != psram_freq_str:
474-
board_config_flags.append(f"# CONFIG_SPIRAM_SPEED_{freq}M is not set")
475-
# Then set the specific SPIRAM configs
476-
board_config_flags.append(f"CONFIG_SPIRAM_SPEED={psram_freq_str}")
477-
board_config_flags.append(f"CONFIG_SPIRAM_SPEED_{psram_freq_str}M=y")
478-
479-
# Enable experimental features for frequencies > 80MHz
480-
if compile_freq_val > 80:
481-
board_config_flags.append("CONFIG_IDF_EXPERIMENTAL_FEATURES=y")
482-
board_config_flags.append("CONFIG_SPI_FLASH_HPM_ENABLE=y")
483-
board_config_flags.append("CONFIG_SPI_FLASH_HPM_AUTO=y")
480+
# Configure Flash frequency
481+
# Disable other flash frequency options first
482+
flash_freqs = ["20m", "26m", "40m", "80m", "120m"]
483+
for freq in flash_freqs:
484+
if freq != flash_freq_str:
485+
board_config_flags.append(f"# CONFIG_ESPTOOLPY_FLASHFREQ_{freq.upper()} is not set")
486+
# Then set the specific frequency configs
487+
board_config_flags.append(f"CONFIG_ESPTOOLPY_FLASHFREQ=\"{flash_freq_str}\"")
488+
board_config_flags.append(f"CONFIG_ESPTOOLPY_FLASHFREQ_{flash_freq_str.upper()}=y")
489+
490+
# ESP32-P4 requires additional FLASHFREQ_VAL setting
491+
if mcu == "esp32p4":
492+
board_config_flags.append(f"CONFIG_ESPTOOLPY_FLASHFREQ_VAL={flash_freq_val}")
493+
494+
# Configure PSRAM frequency
495+
# Disable other SPIRAM speed options first
496+
psram_freqs = ["20", "40", "80", "120", "200"]
497+
for freq in psram_freqs:
498+
if freq != psram_freq_str:
499+
board_config_flags.append(f"# CONFIG_SPIRAM_SPEED_{freq}M is not set")
500+
# Then set the specific SPIRAM configs
501+
board_config_flags.append(f"CONFIG_SPIRAM_SPEED={psram_freq_str}")
502+
board_config_flags.append(f"CONFIG_SPIRAM_SPEED_{psram_freq_str}M=y")
503+
504+
# Enable experimental features for Flash frequencies > 80MHz
505+
if flash_freq_val > 80:
506+
board_config_flags.append("CONFIG_IDF_EXPERIMENTAL_FEATURES=y")
507+
board_config_flags.append("CONFIG_SPI_FLASH_HPM_ENABLE=y")
508+
board_config_flags.append("CONFIG_SPI_FLASH_HPM_AUTO=y")
484509

485510
# Check for PSRAM support based on board flags
486511
extra_flags = board.get("build.extra_flags", [])
@@ -497,9 +522,6 @@ def generate_board_specific_config():
497522
# Check for SPIRAM mentions in extra_flags
498523
elif any("SPIRAM" in str(flag) for flag in extra_flags):
499524
has_psram = True
500-
# For ESP32-S3, assume PSRAM capability (can be disabled later if not present)
501-
elif mcu == "esp32s3":
502-
has_psram = True
503525

504526
if has_psram:
505527
# Enable basic SPIRAM support
@@ -524,13 +546,21 @@ def generate_board_specific_config():
524546
# Priority 3: Check build.psram_type field as fallback
525547
elif not psram_type and "psram_type" in board.get("build", {}):
526548
psram_type = board.get("build.psram_type", "qio").lower()
527-
# Priority 4: Default to qio
549+
# Priority 4: Default based on MCU
528550
elif not psram_type:
529-
psram_type = "qio"
551+
# ESP32-P4 defaults to HEX (only type available)
552+
if mcu == "esp32p4":
553+
psram_type = "hex"
554+
else:
555+
psram_type = "qio"
530556

531557
# Configure PSRAM mode based on detected type
532-
if psram_type == "opi":
533-
# Octal PSRAM configuration (for ESP32-S3 only)
558+
if psram_type == "hex":
559+
# HEX PSRAM configuration (ESP32-P4 only)
560+
board_config_flags.append("CONFIG_SPIRAM_MODE_HEX=y")
561+
562+
elif psram_type == "opi":
563+
# Octal PSRAM configuration (for ESP32-S3)
534564
if mcu == "esp32s3":
535565
board_config_flags.extend([
536566
"CONFIG_IDF_EXPERIMENTAL_FEATURES=y",
@@ -539,7 +569,7 @@ def generate_board_specific_config():
539569
"CONFIG_SPIRAM_TYPE_AUTO=y"
540570
])
541571
else:
542-
# Fallback to QUAD for non-S3 chips
572+
# Fallback to QUAD for other chips
543573
board_config_flags.extend([
544574
"# CONFIG_SPIRAM_MODE_OCT is not set",
545575
"CONFIG_SPIRAM_MODE_QUAD=y"
@@ -557,13 +587,21 @@ def generate_board_specific_config():
557587
"# CONFIG_SPIRAM_MODE_OCT is not set",
558588
"# CONFIG_SPIRAM_MODE_QUAD is not set"
559589
])
590+
else:
591+
# Explicitly disable PSRAM if not present
592+
board_config_flags.extend([
593+
"# CONFIG_SPIRAM is not set"
594+
])
560595

561596
# Use flash_memory_type for flash config
562597
if flash_memory_type and "opi" in flash_memory_type.lower():
563598
# OPI Flash configurations require specific settings
599+
# According to ESP-IDF documentation, OPI flash must use DOUT mode for bootloader
600+
# The bootloader starts in DOUT mode and switches to OPI at runtime
601+
# Reference: ESP-IDF Programming Guide - SPI Flash Configuration
564602
board_config_flags.extend([
565603
"# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set",
566-
"# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set",
604+
"# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set",
567605
"# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set",
568606
"CONFIG_ESPTOOLPY_FLASHMODE_DOUT=y",
569607
"CONFIG_ESPTOOLPY_OCT_FLASH=y",
@@ -2522,7 +2560,9 @@ def _skip_prj_source_files(node):
25222560
#
25232561

25242562
ulp_dir = str(Path(PROJECT_DIR) / "ulp")
2525-
if os.path.isdir(ulp_dir) and os.listdir(ulp_dir) and mcu not in ("esp32c2", "esp32c3", "esp32h2"):
2563+
# ULP support: ESP32, ESP32-S2, ESP32-S3, ESP32-C6, ESP32-P4
2564+
# No ULP: ESP32-C2, ESP32-C3, ESP32-C5, ESP32-H2
2565+
if os.path.isdir(ulp_dir) and os.listdir(ulp_dir) and mcu not in ("esp32c2", "esp32c3", "esp32c5", "esp32h2"):
25262566
env.SConscript("ulp.py", exports="env sdk_config project_config app_includes idf_variant")
25272567

25282568
#

0 commit comments

Comments
 (0)