@@ -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
25242562ulp_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