mirror of
https://github.com/esphome/esphome.git
synced 2025-04-07 19:30:29 +01:00
[psram] Allow use of experimental 120MHz octal mode (#8519)
This commit is contained in:
parent
9637ef35bd
commit
23dec912ad
@ -67,6 +67,7 @@ AUTO_LOAD = ["preferences"]
|
||||
IS_TARGET_PLATFORM = True
|
||||
|
||||
CONF_RELEASE = "release"
|
||||
CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES = "enable_idf_experimental_features"
|
||||
|
||||
|
||||
def set_core_data(config):
|
||||
@ -506,6 +507,7 @@ ESP_IDF_FRAMEWORK_SCHEMA = cv.All(
|
||||
CONF_IGNORE_EFUSE_CUSTOM_MAC, default=False
|
||||
): cv.boolean,
|
||||
cv.Optional(CONF_IGNORE_EFUSE_MAC_CRC): cv.boolean,
|
||||
cv.Optional(CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_COMPONENTS, default=[]): cv.ensure_list(
|
||||
@ -645,6 +647,11 @@ async def to_code(config):
|
||||
add_idf_sdkconfig_option(
|
||||
"CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE", False
|
||||
)
|
||||
if conf[CONF_ADVANCED].get(CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES):
|
||||
_LOGGER.warning(
|
||||
"Using experimental features in ESP-IDF may result in unexpected failures."
|
||||
)
|
||||
add_idf_sdkconfig_option("CONFIG_IDF_EXPERIMENTAL_FEATURES", True)
|
||||
|
||||
cg.add_define(
|
||||
"USE_ESP_IDF_VERSION_CODE",
|
||||
|
@ -1,17 +1,40 @@
|
||||
import logging
|
||||
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.esp32 import add_idf_sdkconfig_option, get_esp32_variant
|
||||
from esphome.components.esp32 import (
|
||||
CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES,
|
||||
VARIANT_ESP32,
|
||||
add_idf_sdkconfig_option,
|
||||
get_esp32_variant,
|
||||
only_on_variant,
|
||||
)
|
||||
from esphome.components.esp32.const import VARIANT_ESP32S2, VARIANT_ESP32S3
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_MODE, CONF_SPEED
|
||||
from esphome.const import (
|
||||
CONF_ADVANCED,
|
||||
CONF_FRAMEWORK,
|
||||
CONF_ID,
|
||||
CONF_MODE,
|
||||
CONF_SPEED,
|
||||
PLATFORM_ESP32,
|
||||
)
|
||||
from esphome.core import CORE
|
||||
import esphome.final_validate as fv
|
||||
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
|
||||
DEPENDENCIES = [PLATFORM_ESP32]
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
psram_ns = cg.esphome_ns.namespace("psram")
|
||||
PsramComponent = psram_ns.class_("PsramComponent", cg.Component)
|
||||
|
||||
TYPE_QUAD = "quad"
|
||||
TYPE_OCTAL = "octal"
|
||||
|
||||
CONF_ENABLE_ECC = "enable_ecc"
|
||||
|
||||
SPIRAM_MODES = {
|
||||
TYPE_QUAD: "CONFIG_SPIRAM_MODE_QUAD",
|
||||
TYPE_OCTAL: "CONFIG_SPIRAM_MODE_OCT",
|
||||
@ -26,7 +49,25 @@ SPIRAM_SPEEDS = {
|
||||
|
||||
def validate_psram_mode(config):
|
||||
if config[CONF_MODE] == TYPE_OCTAL and config[CONF_SPEED] == 120e6:
|
||||
raise cv.Invalid("PSRAM 120MHz is not supported in octal mode")
|
||||
esp32_config = fv.full_config.get()[PLATFORM_ESP32]
|
||||
if (
|
||||
esp32_config[CONF_FRAMEWORK]
|
||||
.get(CONF_ADVANCED, {})
|
||||
.get(CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES)
|
||||
):
|
||||
_LOGGER.warning(
|
||||
"120MHz PSRAM in octal mode is an experimental feature - use at your own risk"
|
||||
)
|
||||
else:
|
||||
raise cv.Invalid("PSRAM 120MHz is not supported in octal mode")
|
||||
if config[CONF_MODE] != TYPE_OCTAL and config[CONF_ENABLE_ECC]:
|
||||
raise cv.Invalid("ECC is only available in octal mode.")
|
||||
if config[CONF_MODE] == TYPE_OCTAL:
|
||||
variant = get_esp32_variant()
|
||||
if variant != VARIANT_ESP32S3:
|
||||
raise cv.Invalid(
|
||||
f"Octal PSRAM is only supported on ESP32-S3, not {variant}"
|
||||
)
|
||||
return config
|
||||
|
||||
|
||||
@ -37,19 +78,25 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.Optional(CONF_MODE, default=TYPE_QUAD): cv.enum(
|
||||
SPIRAM_MODES, lower=True
|
||||
),
|
||||
cv.Optional(CONF_ENABLE_ECC, default=False): cv.boolean,
|
||||
cv.Optional(CONF_SPEED, default=40e6): cv.All(
|
||||
cv.frequency, cv.one_of(*SPIRAM_SPEEDS)
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.only_on_esp32,
|
||||
validate_psram_mode,
|
||||
only_on_variant(
|
||||
supported=[VARIANT_ESP32, VARIANT_ESP32S3, VARIANT_ESP32S2],
|
||||
),
|
||||
)
|
||||
|
||||
FINAL_VALIDATE_SCHEMA = validate_psram_mode
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
if CORE.using_arduino:
|
||||
cg.add_build_flag("-DBOARD_HAS_PSRAM")
|
||||
if config[CONF_MODE] == TYPE_OCTAL:
|
||||
cg.add_platformio_option("board_build.arduino.memory_type", "qio_opi")
|
||||
|
||||
if CORE.using_esp_idf:
|
||||
add_idf_sdkconfig_option(
|
||||
@ -62,6 +109,14 @@ async def to_code(config):
|
||||
|
||||
add_idf_sdkconfig_option(f"{SPIRAM_MODES[config[CONF_MODE]]}", True)
|
||||
add_idf_sdkconfig_option(f"{SPIRAM_SPEEDS[config[CONF_SPEED]]}", True)
|
||||
if config[CONF_MODE] == TYPE_OCTAL and config[CONF_SPEED] == 120e6:
|
||||
add_idf_sdkconfig_option("CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240", True)
|
||||
# This works only on IDF 5.4.x but does no harm on earlier versions
|
||||
add_idf_sdkconfig_option(
|
||||
"CONFIG_SPIRAM_TIMING_TUNING_POINT_VIA_TEMPERATURE_SENSOR", True
|
||||
)
|
||||
if config[CONF_ENABLE_ECC]:
|
||||
add_idf_sdkconfig_option("CONFIG_SPIRAM_ECC_ENABLE", True)
|
||||
|
||||
cg.add_define("USE_PSRAM")
|
||||
|
||||
|
@ -1,25 +1,36 @@
|
||||
#include "psram.h"
|
||||
|
||||
#ifdef USE_ESP32
|
||||
#include "psram.h"
|
||||
#ifdef USE_ESP_IDF
|
||||
#include <esp_psram.h>
|
||||
#endif // USE_ESP_IDF
|
||||
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
#include <esp_heap_caps.h>
|
||||
#include <esp_idf_version.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace psram {
|
||||
|
||||
static const char *const TAG = "psram";
|
||||
|
||||
void PsramComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "PSRAM:");
|
||||
#ifdef USE_ESP_IDF
|
||||
bool available = esp_psram_is_initialized();
|
||||
|
||||
ESP_LOGCONFIG(TAG, " Available: %s", YESNO(available));
|
||||
if (available) {
|
||||
ESP_LOGCONFIG(TAG, " Size: %zu KB", esp_psram_get_size() / 1024);
|
||||
#if CONFIG_SPIRAM_ECC_ENABLE
|
||||
ESP_LOGCONFIG(TAG, " ECC enabled: YES");
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
// Technically this can be false if the PSRAM is full, but heap_caps_get_total_size() isn't always available, and it's
|
||||
// very unlikely for the PSRAM to be full.
|
||||
bool available = heap_caps_get_free_size(MALLOC_CAP_SPIRAM) > 0;
|
||||
|
||||
ESP_LOGCONFIG(TAG, "PSRAM:");
|
||||
ESP_LOGCONFIG(TAG, " Available: %s", YESNO(available));
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)
|
||||
|
||||
if (available) {
|
||||
const size_t psram_total_size_bytes = heap_caps_get_total_size(MALLOC_CAP_SPIRAM);
|
||||
const float psram_total_size_kb = psram_total_size_bytes / 1024.0f;
|
||||
@ -30,7 +41,7 @@ void PsramComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, " Size: %zu bytes", psram_total_size_bytes);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // USE_ESP_IDF
|
||||
}
|
||||
|
||||
} // namespace psram
|
||||
|
@ -1,3 +1,2 @@
|
||||
psram:
|
||||
mode: octal
|
||||
speed: 80MHz
|
||||
|
@ -1 +0,0 @@
|
||||
<<: !include common.yaml
|
@ -1 +0,0 @@
|
||||
<<: !include common.yaml
|
@ -1 +1,3 @@
|
||||
<<: !include common.yaml
|
||||
psram:
|
||||
mode: octal
|
||||
speed: 80MHz
|
||||
|
@ -1 +1,10 @@
|
||||
<<: !include common.yaml
|
||||
esp32:
|
||||
framework:
|
||||
type: esp-idf
|
||||
advanced:
|
||||
enable_idf_experimental_features: yes
|
||||
|
||||
psram:
|
||||
mode: octal
|
||||
speed: 120MHz
|
||||
enable_ecc: true
|
||||
|
Loading…
x
Reference in New Issue
Block a user