feat(compile): ESP32-P4 and ESP32-C5 targets in the espidf lane
_idf_target mapped only c3/c6/s3 and defaulted everything else to 'esp32', so a P4 fqbn compiled with the XTENSA toolchain and -DARDUINO_ESP32P4_DEV. Adds p4/c5 predicates, IDF5-target membership, 0x2000 bootloader offsets, the riscv toolchain requirement, PSRAM held off until the engines validate it, P4 CPU-freq drops (its kconfig choices do not overlap the classic set), a rev0 sdkconfig pin for the P4 (the in-browser engine runs the only published mask ROM and v3 firmware reads a flash descriptor rev0 never wrote), and an honest refusal for C5 arduino builds (no core exists). Validated on staging: an esp32p4 arduino sketch now produces a merged image with the riscv32 toolchain that the esp32p4js engine accepts.
This commit is contained in:
parent
c4860d4f23
commit
010a112bc8
|
|
@ -526,7 +526,7 @@ class ESPIDFCompiler:
|
|||
|
||||
# Targets that only exist in ESP-IDF v5.x — the pinned v4.4.7 tree
|
||||
# predates them, so they build against idf5_path instead of idf_path.
|
||||
_IDF5_TARGETS: frozenset[str] = frozenset({'esp32c6'})
|
||||
_IDF5_TARGETS: frozenset[str] = frozenset({'esp32c6', 'esp32p4', 'esp32c5'})
|
||||
|
||||
# Flash offset where each chip's boot ROM expects the 2nd-stage
|
||||
# bootloader. ESP32 / ESP32-S2 use 0x1000; every newer chip (S3, C2,
|
||||
|
|
@ -535,6 +535,8 @@ class ESPIDFCompiler:
|
|||
_BOOTLOADER_OFFSETS: dict[str, int] = {
|
||||
'esp32': 0x1000,
|
||||
'esp32s2': 0x1000,
|
||||
'esp32p4': 0x2000,
|
||||
'esp32c5': 0x2000,
|
||||
}
|
||||
|
||||
def _is_esp32c3(self, board_fqbn: str) -> bool:
|
||||
|
|
@ -546,6 +548,16 @@ class ESPIDFCompiler:
|
|||
f = board_fqbn.lower()
|
||||
return 'esp32c6' in f or 'esp32-c6' in f
|
||||
|
||||
def _is_esp32p4(self, board_fqbn: str) -> bool:
|
||||
"""Return True if FQBN targets ESP32-P4 (RISC-V, IDF v5.x only)."""
|
||||
f = board_fqbn.lower()
|
||||
return 'esp32p4' in f or 'esp32-p4' in f
|
||||
|
||||
def _is_esp32c5(self, board_fqbn: str) -> bool:
|
||||
"""Return True if FQBN targets ESP32-C5 (RISC-V, IDF v5.x only)."""
|
||||
f = board_fqbn.lower()
|
||||
return 'esp32c5' in f or 'esp32-c5' in f
|
||||
|
||||
def _idf_root(self, use_idf5: bool) -> str:
|
||||
"""The ESP-IDF tree a compile builds against."""
|
||||
return self.idf5_path if use_idf5 else self.idf_path
|
||||
|
|
@ -599,6 +611,9 @@ class ESPIDFCompiler:
|
|||
error rather than being pattern-translated into something it
|
||||
isn't.
|
||||
"""
|
||||
if idf_target == 'esp32c5':
|
||||
# No arduino-esp32 core supports the C5 yet — IDF-native only.
|
||||
return False
|
||||
if idf_target in self._IDF5_TARGETS:
|
||||
return self.has_arduino5
|
||||
return self.has_arduino or self.has_arduino5
|
||||
|
|
@ -750,6 +765,10 @@ class ESPIDFCompiler:
|
|||
return 'esp32c6'
|
||||
if self._is_esp32s3(board_fqbn):
|
||||
return 'esp32s3'
|
||||
if self._is_esp32p4(board_fqbn):
|
||||
return 'esp32p4'
|
||||
if self._is_esp32c5(board_fqbn):
|
||||
return 'esp32c5'
|
||||
# Default to esp32 (Xtensa LX6) for the original ESP32 / ESP32-S2
|
||||
return 'esp32'
|
||||
|
||||
|
|
@ -2237,7 +2256,7 @@ class ESPIDFCompiler:
|
|||
# resolve. The old xtensa-only glob wrongly rejected RISC-V-only
|
||||
# roots such as the v5.x install used for esp32c6.
|
||||
xtensa_glob = 'tools/xtensa-esp32-elf/*/xtensa-esp32-elf/bin'
|
||||
if idf_target in ('esp32c3', 'esp32c6'):
|
||||
if idf_target in ('esp32c3', 'esp32c6', 'esp32p4', 'esp32c5'):
|
||||
required_globs: tuple[str, ...] = (
|
||||
'tools/riscv32-esp-elf/*/riscv32-esp-elf/bin',
|
||||
)
|
||||
|
|
@ -2553,8 +2572,11 @@ class ESPIDFCompiler:
|
|||
|
||||
# ESP32-C3 / ESP32-C6 have no external PSRAM controller — silently
|
||||
# disable so a stale field from an upgraded project doesn't trip up
|
||||
# the build.
|
||||
if idf_target in ('esp32c3', 'esp32c6'):
|
||||
# the build. P4/C5 modules DO carry PSRAM, but the in-browser engines
|
||||
# run without it for now (the P4 engine models PSRAM as optional and
|
||||
# firmware built with SPIRAM would fail honestly on a board that does
|
||||
# not declare it) — keep it off until the engines validate it.
|
||||
if idf_target in ('esp32c3', 'esp32c6', 'esp32p4', 'esp32c5'):
|
||||
normalized['psram'] = 'disabled'
|
||||
|
||||
# ESP32-C3 / ESP32-C6 top out at 160 MHz — clamp the historical 240
|
||||
|
|
@ -2615,7 +2637,7 @@ class ESPIDFCompiler:
|
|||
drops: tuple[str, ...] = ()
|
||||
if not arduino_mode:
|
||||
drops += self._IDF5_PUREIDF_DROP_PREFIXES
|
||||
elif idf_target in ('esp32c3', 'esp32c6'):
|
||||
elif idf_target in ('esp32c3', 'esp32c6', 'esp32c5'):
|
||||
# Arduino v5 on a single-core RISC-V chip: the running-core
|
||||
# options are hidden by `depends on !FREERTOS_UNICORE`, so drop
|
||||
# just those two (keep the rest of the Arduino/BT symbols).
|
||||
|
|
@ -2623,11 +2645,20 @@ class ESPIDFCompiler:
|
|||
'CONFIG_ARDUINO_RUNNING_CORE',
|
||||
'CONFIG_ARDUINO_EVENT_RUNNING_CORE',
|
||||
)
|
||||
if idf_target in ('esp32c3', 'esp32c6'):
|
||||
if idf_target in ('esp32c3', 'esp32c6', 'esp32c5'):
|
||||
drops += (
|
||||
'CONFIG_SPIRAM',
|
||||
'CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240',
|
||||
)
|
||||
if idf_target == 'esp32p4':
|
||||
# The P4's CPU-frequency kconfig choices (360/400) do not overlap
|
||||
# the classic 240/160/80/40 set the template renders — drop the
|
||||
# whole group and let IDF's own default stand. SPIRAM stays off
|
||||
# (see _normalize_options).
|
||||
drops += (
|
||||
'CONFIG_SPIRAM',
|
||||
'CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ',
|
||||
)
|
||||
if idf_target != 'esp32':
|
||||
drops += ('CONFIG_ESPTOOLPY_FLASHFREQ_26M',)
|
||||
return drops
|
||||
|
|
@ -2738,6 +2769,18 @@ class ESPIDFCompiler:
|
|||
rendered = self._fixup_sdkconfig_for_idf5(
|
||||
rendered, idf_target, arduino_mode
|
||||
)
|
||||
if idf_target == 'esp32p4':
|
||||
# The in-browser esp32p4js engine runs the ONLY published P4 mask
|
||||
# ROM (rev0), and from silicon v3.0 IDF switches ROM symbol tables
|
||||
# (esp32p4.rom.eco5.ld moves rom_spiflash_legacy_data) — firmware
|
||||
# built for v3 reads a flash descriptor the rev0 ROM never wrote
|
||||
# and rejects every partition. Pin the build to rev0 so images
|
||||
# boot on the engine (project/esp32p4-js-emulator/STATUS.md).
|
||||
rendered += (
|
||||
'\n# Velxio: esp32p4js runs the rev0 mask ROM\n'
|
||||
'CONFIG_ESP32P4_SELECTS_REV_LESS_V3=y\n'
|
||||
'CONFIG_ESP32P4_REV_MIN_0=y\n'
|
||||
)
|
||||
return rendered
|
||||
|
||||
def _render_partition_csv(self, scheme: str) -> str:
|
||||
|
|
|
|||
Loading…
Reference in New Issue