From b271179cc9ad8f554db2b57279a2ccda6734d6c1 Mon Sep 17 00:00:00 2001 From: liquidraver <504870+liquidraver@users.noreply.github.com> Date: Mon, 18 May 2026 22:31:04 +0200 Subject: [PATCH] activate PSRAM in capable devices to fit OTA --- .gitignore | 1 + zephcore/Kconfig | 3 ++ zephcore/Kconfig.psram | 23 ++++++++++ zephcore/boards/esp32/station_g2/board.conf | 4 ++ zephcore/boards/esp32/xiao_esp32s3/board.conf | 4 ++ zephcore/boards/example_board/README.md | 44 +++++++++++++++++++ 6 files changed, 79 insertions(+) create mode 100644 zephcore/Kconfig.psram diff --git a/.gitignore b/.gitignore index 49fb807..847900a 100644 --- a/.gitignore +++ b/.gitignore @@ -97,3 +97,4 @@ zephcore/apc.md RADIO_AUDIT_INDEX.md RX_BUSY_LATCH_PLAN.md zephcore/SX126X_LBT_RX_DEBUG_HANDOFF.md +PSRAM_HANDOFF.md diff --git a/zephcore/Kconfig b/zephcore/Kconfig index 639ce62..137515b 100644 --- a/zephcore/Kconfig +++ b/zephcore/Kconfig @@ -2,6 +2,9 @@ source "$(ZEPHYR_BASE)/Kconfig.zephyr" +# DT-driven PSRAM auto-enable for ESP32 boards (see Kconfig.psram). +rsource "Kconfig.psram" + module = ZEPHCORE_MAIN module-str = zephcore_main source "$(ZEPHYR_BASE)/subsys/logging/Kconfig.template.log_config" diff --git a/zephcore/Kconfig.psram b/zephcore/Kconfig.psram new file mode 100644 index 0000000..701b698 --- /dev/null +++ b/zephcore/Kconfig.psram @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# DT-driven PSRAM auto-enable for ESP32 boards. +# +# Upstream Zephyr's esp32*_wroom_n*r*.dtsi files override psram0 size when +# the chip variant has PSRAM stuffed (R-suffix in the Espressif part number). +# We auto-enable PSRAM whenever the DTS size is non-zero — the upstream +# Kconfig.spiram then auto-reads ESP_SPIRAM_SIZE from the same DT property. +# +# Boards without PSRAM include a non-R-suffix dtsi (e.g. esp32s3_wroom_n8), +# which leaves psram0 at size = 0 — auto-detect leaves PSRAM off for them. +# ESP32-C3 and ESP32-C6 are outside Kconfig.spiram's SOC gate entirely, so +# this symbol doesn't exist on those builds — no effect. +# +# Mode (QUAD vs OCT) cannot be auto-picked here: upstream Kconfig.spiram +# sets an unconditional `default SPIRAM_MODE_QUAD` on the choice, which wins +# over any conditional default we'd add. ESP32-S3 R8 boards (8 MB OPI octal +# PSRAM) must set CONFIG_SPIRAM_MODE_OCT=y in their board.conf. R2 boards +# (2 MB QSPI quad) need nothing — QUAD is the upstream default. + +config ESP_SPIRAM + default y if (SOC_SERIES_ESP32 || SOC_SERIES_ESP32S2 || SOC_SERIES_ESP32S3 || SOC_SERIES_ESP32C5) && \ + "$(dt_node_int_prop_int,$(dt_nodelabel_path,psram0),size)" != 0 diff --git a/zephcore/boards/esp32/station_g2/board.conf b/zephcore/boards/esp32/station_g2/board.conf index 5001f03..eb6eb01 100644 --- a/zephcore/boards/esp32/station_g2/board.conf +++ b/zephcore/boards/esp32/station_g2/board.conf @@ -20,3 +20,7 @@ CONFIG_ZEPHCORE_DEFAULT_TX_POWER_DBM=15 # Flash size — 16MB (override Zephyr default) CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y + +# PSRAM mode — ESP32-S3R8 is silicon-strapped OPI octal. +# Enable is auto-detected from DTS by Kconfig.psram; only the mode is set here. +CONFIG_SPIRAM_MODE_OCT=y diff --git a/zephcore/boards/esp32/xiao_esp32s3/board.conf b/zephcore/boards/esp32/xiao_esp32s3/board.conf index 2ef8a44..47fdfd9 100644 --- a/zephcore/boards/esp32/xiao_esp32s3/board.conf +++ b/zephcore/boards/esp32/xiao_esp32s3/board.conf @@ -14,3 +14,7 @@ CONFIG_ZEPHCORE_BOARD_NAME="XIAO ESP32-S3" # Device Information Service model name CONFIG_BT_DIS_MODEL_NUMBER_STR="XIAO ESP32-S3" + +# PSRAM mode — ESP32-S3R8 is silicon-strapped OPI octal. +# Enable is auto-detected from DTS by Kconfig.psram; only the mode is set here. +CONFIG_SPIRAM_MODE_OCT=y diff --git a/zephcore/boards/example_board/README.md b/zephcore/boards/example_board/README.md index 6b99d0e..f5f2844 100644 --- a/zephcore/boards/example_board/README.md +++ b/zephcore/boards/example_board/README.md @@ -248,6 +248,50 @@ should ONLY contain settings that can't be inferred from hardware: CONFIG_SPI Auto from ZEPHCORE_RADIO_LR1110 CONFIG_NORDIC_QSPI_NOR Auto from DT nordic,qspi-nor node CONFIG_ZEPHCORE_LORA_RX_DUTY_CYCLE Auto: ON for companion+SX1262, OFF for repeater/LR1110 + CONFIG_ESP_SPIRAM Auto: ON when DT psram0 size > 0 (ESP32-S/C5) + CONFIG_ESP_SPIRAM_SIZE Auto: read from DT psram0 size by upstream Kconfig + + NOT auto-detected (must set in board.conf for ESP32-S3 R8 boards): + CONFIG_SPIRAM_MODE_OCT R8 chips (8 MB OPI octal) need this set + to "y" in board.conf. R2 chips (2 MB QSPI + quad) need nothing — QUAD is the upstream + default. See "ESP32 PSRAM" section below. + + +ESP32 PSRAM (auto-enable, per-board mode on S3 R8) +-------------------------------------------------- + +`CONFIG_ESP_SPIRAM=y` is enabled automatically from devicetree by +[zephcore/Kconfig.psram](../../Kconfig.psram). As long as a board's DTS +includes a Zephyr WROOM dtsi with an R-suffix (e.g. `esp32s3_wroom_n16r2.dtsi`, +`esp32s3_wroom_n8r8.dtsi`), PSRAM lights up — no `board.conf` entry needed +for the basics. Boards without PSRAM use a non-R-suffix dtsi (e.g. +`esp32s3_wroom_n8`), which leaves `psram0` at size = 0, so PSRAM stays off. +ESP32-C3/C6 are outside Espressif's PSRAM Kconfig gate entirely — no effect. + +**Mode selection is silicon-strapped, but not auto-pickable here:** upstream +Kconfig.spiram sets an unconditional `default SPIRAM_MODE_QUAD` on the choice, +which wins over any conditional override we'd add downstream. So: + +| Chip suffix | PSRAM size | Mode | board.conf needs | +|-------------|-----------|-----------|----------------------------| +| `R2` | 2 MB | QSPI quad | nothing — upstream default | +| `R8` | 8 MB | OPI octal | `CONFIG_SPIRAM_MODE_OCT=y` | + +If you add a new ESP32-S3 **R8** board (e.g. `esp32s3_wroom_n*r8.dtsi`), +add a one-liner to its board.conf: + +```kconfig +# PSRAM mode — ESP32-S3R8 is silicon-strapped OPI octal. +# Enable is auto-detected from DTS by Kconfig.psram; only the mode is set here. +CONFIG_SPIRAM_MODE_OCT=y +``` + +For aggressive DRAM relief beyond the heap rebalance, additional Kconfigs +`CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y` and `CONFIG_SPIRAM_RODATA=y` move +text/rodata into PSRAM at boot, but introduce PSRAM-cache-miss timing +variability — only enable per-board after verifying radio and BLE paths +still meet their timing budgets. Config Inheritance