mirror of
https://github.com/esphome/esphome.git
synced 2025-07-29 06:36:45 +00:00
[esp32, debug] Add `cpu_frequency
` config option and debug sensor (#8542)
This commit is contained in:
parent
da9c755f67
commit
e215fafebe
@ -25,6 +25,7 @@ void DebugComponent::dump_config() {
|
||||
#ifdef USE_SENSOR
|
||||
LOG_SENSOR(" ", "Free space on heap", this->free_sensor_);
|
||||
LOG_SENSOR(" ", "Largest free heap block", this->block_sensor_);
|
||||
LOG_SENSOR(" ", "CPU frequency", this->cpu_frequency_sensor_);
|
||||
#if defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)
|
||||
LOG_SENSOR(" ", "Heap fragmentation", this->fragmentation_sensor_);
|
||||
#endif // defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)
|
||||
@ -86,6 +87,9 @@ void DebugComponent::update() {
|
||||
this->loop_time_sensor_->publish_state(this->max_loop_time_);
|
||||
this->max_loop_time_ = 0;
|
||||
}
|
||||
if (this->cpu_frequency_sensor_ != nullptr) {
|
||||
this->cpu_frequency_sensor_->publish_state(arch_get_cpu_freq_hz());
|
||||
}
|
||||
|
||||
#endif // USE_SENSOR
|
||||
update_platform_();
|
||||
|
@ -36,6 +36,9 @@ class DebugComponent : public PollingComponent {
|
||||
#ifdef USE_ESP32
|
||||
void set_psram_sensor(sensor::Sensor *psram_sensor) { this->psram_sensor_ = psram_sensor; }
|
||||
#endif // USE_ESP32
|
||||
void set_cpu_frequency_sensor(sensor::Sensor *cpu_frequency_sensor) {
|
||||
this->cpu_frequency_sensor_ = cpu_frequency_sensor;
|
||||
}
|
||||
#endif // USE_SENSOR
|
||||
protected:
|
||||
uint32_t free_heap_{};
|
||||
@ -53,6 +56,7 @@ class DebugComponent : public PollingComponent {
|
||||
#ifdef USE_ESP32
|
||||
sensor::Sensor *psram_sensor_{nullptr};
|
||||
#endif // USE_ESP32
|
||||
sensor::Sensor *cpu_frequency_sensor_{nullptr};
|
||||
#endif // USE_SENSOR
|
||||
|
||||
#ifdef USE_ESP32
|
||||
@ -75,6 +79,7 @@ class DebugComponent : public PollingComponent {
|
||||
#endif // USE_TEXT_SENSOR
|
||||
|
||||
std::string get_reset_reason_();
|
||||
std::string get_wakeup_cause_();
|
||||
uint32_t get_free_heap_();
|
||||
void get_device_info_(std::string &device_info);
|
||||
void update_platform_();
|
||||
|
@ -1,27 +1,15 @@
|
||||
#include "debug_component.h"
|
||||
|
||||
#ifdef USE_ESP32
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include <esp_sleep.h>
|
||||
|
||||
#include <esp_heap_caps.h>
|
||||
#include <esp_system.h>
|
||||
#include <esp_chip_info.h>
|
||||
#include <esp_partition.h>
|
||||
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
#include <esp32/rom/rtc.h>
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C2)
|
||||
#include <esp32c2/rom/rtc.h>
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C3)
|
||||
#include <esp32c3/rom/rtc.h>
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C6)
|
||||
#include <esp32c6/rom/rtc.h>
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32S2)
|
||||
#include <esp32s2/rom/rtc.h>
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
#include <esp32s3/rom/rtc.h>
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32H2)
|
||||
#include <esp32h2/rom/rtc.h>
|
||||
#endif
|
||||
#ifdef USE_ARDUINO
|
||||
#include <Esp.h>
|
||||
#endif
|
||||
@ -31,6 +19,67 @@ namespace debug {
|
||||
|
||||
static const char *const TAG = "debug";
|
||||
|
||||
// index by values returned by esp_reset_reason
|
||||
|
||||
static const char *const RESET_REASONS[] = {
|
||||
"unknown source",
|
||||
"power-on event",
|
||||
"external pin",
|
||||
"software via esp_restart",
|
||||
"exception/panic",
|
||||
"interrupt watchdog",
|
||||
"task watchdog",
|
||||
"other watchdogs",
|
||||
"exiting deep sleep mode",
|
||||
"brownout",
|
||||
"SDIO",
|
||||
"USB peripheral",
|
||||
"JTAG",
|
||||
"efuse error",
|
||||
"power glitch detected",
|
||||
"CPU lock up",
|
||||
};
|
||||
|
||||
std::string DebugComponent::get_reset_reason_() {
|
||||
std::string reset_reason;
|
||||
unsigned reason = esp_reset_reason();
|
||||
if (reason < sizeof(RESET_REASONS) / sizeof(RESET_REASONS[0])) {
|
||||
reset_reason = RESET_REASONS[reason];
|
||||
} else {
|
||||
reset_reason = "unknown source";
|
||||
}
|
||||
ESP_LOGD(TAG, "Reset Reason: %s", reset_reason.c_str());
|
||||
return "Reset by " + reset_reason;
|
||||
}
|
||||
|
||||
static const char *const WAKEUP_CAUSES[] = {
|
||||
"undefined",
|
||||
"undefined",
|
||||
"external signal using RTC_IO",
|
||||
"external signal using RTC_CNTL",
|
||||
"timer",
|
||||
"touchpad",
|
||||
"ULP program",
|
||||
"GPIO",
|
||||
"UART",
|
||||
"WIFI",
|
||||
"COCPU int",
|
||||
"COCPU crash",
|
||||
"BT",
|
||||
};
|
||||
|
||||
std::string DebugComponent::get_wakeup_cause_() {
|
||||
const char *wake_reason;
|
||||
unsigned reason = esp_sleep_get_wakeup_cause();
|
||||
if (reason < sizeof(WAKEUP_CAUSES) / sizeof(WAKEUP_CAUSES[0])) {
|
||||
wake_reason = WAKEUP_CAUSES[reason];
|
||||
} else {
|
||||
wake_reason = "unknown source";
|
||||
}
|
||||
ESP_LOGD(TAG, "Wakeup Reason: %s", wake_reason);
|
||||
return wake_reason;
|
||||
}
|
||||
|
||||
void DebugComponent::log_partition_info_() {
|
||||
ESP_LOGCONFIG(TAG, "Partition table:");
|
||||
ESP_LOGCONFIG(TAG, " %-12s %-4s %-8s %-10s %-10s", "Name", "Type", "Subtype", "Address", "Size");
|
||||
@ -44,173 +93,16 @@ void DebugComponent::log_partition_info_() {
|
||||
esp_partition_iterator_release(it);
|
||||
}
|
||||
|
||||
std::string DebugComponent::get_reset_reason_() {
|
||||
std::string reset_reason;
|
||||
switch (esp_reset_reason()) {
|
||||
case ESP_RST_POWERON:
|
||||
reset_reason = "Reset due to power-on event";
|
||||
break;
|
||||
case ESP_RST_EXT:
|
||||
reset_reason = "Reset by external pin";
|
||||
break;
|
||||
case ESP_RST_SW:
|
||||
reset_reason = "Software reset via esp_restart";
|
||||
break;
|
||||
case ESP_RST_PANIC:
|
||||
reset_reason = "Software reset due to exception/panic";
|
||||
break;
|
||||
case ESP_RST_INT_WDT:
|
||||
reset_reason = "Reset (software or hardware) due to interrupt watchdog";
|
||||
break;
|
||||
case ESP_RST_TASK_WDT:
|
||||
reset_reason = "Reset due to task watchdog";
|
||||
break;
|
||||
case ESP_RST_WDT:
|
||||
reset_reason = "Reset due to other watchdogs";
|
||||
break;
|
||||
case ESP_RST_DEEPSLEEP:
|
||||
reset_reason = "Reset after exiting deep sleep mode";
|
||||
break;
|
||||
case ESP_RST_BROWNOUT:
|
||||
reset_reason = "Brownout reset (software or hardware)";
|
||||
break;
|
||||
case ESP_RST_SDIO:
|
||||
reset_reason = "Reset over SDIO";
|
||||
break;
|
||||
#ifdef USE_ESP32_VARIANT_ESP32
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 4))
|
||||
case ESP_RST_USB:
|
||||
reset_reason = "Reset by USB peripheral";
|
||||
break;
|
||||
case ESP_RST_JTAG:
|
||||
reset_reason = "Reset by JTAG";
|
||||
break;
|
||||
case ESP_RST_EFUSE:
|
||||
reset_reason = "Reset due to efuse error";
|
||||
break;
|
||||
case ESP_RST_PWR_GLITCH:
|
||||
reset_reason = "Reset due to power glitch detected";
|
||||
break;
|
||||
case ESP_RST_CPU_LOCKUP:
|
||||
reset_reason = "Reset due to CPU lock up (double exception)";
|
||||
break;
|
||||
#endif // ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 4)
|
||||
#endif // USE_ESP32_VARIANT_ESP32
|
||||
default: // Includes ESP_RST_UNKNOWN
|
||||
switch (rtc_get_reset_reason(0)) {
|
||||
case POWERON_RESET:
|
||||
reset_reason = "Power On Reset";
|
||||
break;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
case SW_RESET:
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || \
|
||||
defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C6)
|
||||
case RTC_SW_SYS_RESET:
|
||||
#endif
|
||||
reset_reason = "Software Reset Digital Core";
|
||||
break;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
case OWDT_RESET:
|
||||
reset_reason = "Watch Dog Reset Digital Core";
|
||||
break;
|
||||
#endif
|
||||
case DEEPSLEEP_RESET:
|
||||
reset_reason = "Deep Sleep Reset Digital Core";
|
||||
break;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
case SDIO_RESET:
|
||||
reset_reason = "SLC Module Reset Digital Core";
|
||||
break;
|
||||
#endif
|
||||
case TG0WDT_SYS_RESET:
|
||||
reset_reason = "Timer Group 0 Watch Dog Reset Digital Core";
|
||||
break;
|
||||
#if !defined(USE_ESP32_VARIANT_ESP32C2)
|
||||
case TG1WDT_SYS_RESET:
|
||||
reset_reason = "Timer Group 1 Watch Dog Reset Digital Core";
|
||||
break;
|
||||
#endif
|
||||
case RTCWDT_SYS_RESET:
|
||||
reset_reason = "RTC Watch Dog Reset Digital Core";
|
||||
break;
|
||||
#if !defined(USE_ESP32_VARIANT_ESP32C6) && !defined(USE_ESP32_VARIANT_ESP32H2)
|
||||
case INTRUSION_RESET:
|
||||
reset_reason = "Intrusion Reset CPU";
|
||||
break;
|
||||
#endif
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
case TGWDT_CPU_RESET:
|
||||
reset_reason = "Timer Group Reset CPU";
|
||||
break;
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || \
|
||||
defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C6)
|
||||
case TG0WDT_CPU_RESET:
|
||||
reset_reason = "Timer Group 0 Reset CPU";
|
||||
break;
|
||||
#endif
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
case SW_CPU_RESET:
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || \
|
||||
defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C6)
|
||||
case RTC_SW_CPU_RESET:
|
||||
#endif
|
||||
reset_reason = "Software Reset CPU";
|
||||
break;
|
||||
case RTCWDT_CPU_RESET:
|
||||
reset_reason = "RTC Watch Dog Reset CPU";
|
||||
break;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
case EXT_CPU_RESET:
|
||||
reset_reason = "External CPU Reset";
|
||||
break;
|
||||
#endif
|
||||
case RTCWDT_BROWN_OUT_RESET:
|
||||
reset_reason = "Voltage Unstable Reset";
|
||||
break;
|
||||
case RTCWDT_RTC_RESET:
|
||||
reset_reason = "RTC Watch Dog Reset Digital Core And RTC Module";
|
||||
break;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || \
|
||||
defined(USE_ESP32_VARIANT_ESP32C6)
|
||||
case TG1WDT_CPU_RESET:
|
||||
reset_reason = "Timer Group 1 Reset CPU";
|
||||
break;
|
||||
case SUPER_WDT_RESET:
|
||||
reset_reason = "Super Watchdog Reset Digital Core And RTC Module";
|
||||
break;
|
||||
case EFUSE_RESET:
|
||||
reset_reason = "eFuse Reset Digital Core";
|
||||
break;
|
||||
#endif
|
||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
case GLITCH_RTC_RESET:
|
||||
reset_reason = "Glitch Reset Digital Core And RTC Module";
|
||||
break;
|
||||
#endif
|
||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C6)
|
||||
case USB_UART_CHIP_RESET:
|
||||
reset_reason = "USB UART Reset Digital Core";
|
||||
break;
|
||||
case USB_JTAG_CHIP_RESET:
|
||||
reset_reason = "USB JTAG Reset Digital Core";
|
||||
break;
|
||||
#endif
|
||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
case POWER_GLITCH_RESET:
|
||||
reset_reason = "Power Glitch Reset Digital Core And RTC Module";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
reset_reason = "Unknown Reset Reason";
|
||||
}
|
||||
break;
|
||||
}
|
||||
ESP_LOGD(TAG, "Reset Reason: %s", reset_reason.c_str());
|
||||
return reset_reason;
|
||||
}
|
||||
|
||||
uint32_t DebugComponent::get_free_heap_() { return heap_caps_get_free_size(MALLOC_CAP_INTERNAL); }
|
||||
|
||||
static const std::map<int, const char *> CHIP_FEATURES = {
|
||||
{CHIP_FEATURE_BLE, "BLE"},
|
||||
{CHIP_FEATURE_BT, "BT"},
|
||||
{CHIP_FEATURE_EMB_FLASH, "EMB Flash"},
|
||||
{CHIP_FEATURE_EMB_PSRAM, "EMB PSRAM"},
|
||||
{CHIP_FEATURE_WIFI_BGN, "2.4GHz WiFi"},
|
||||
};
|
||||
|
||||
void DebugComponent::get_device_info_(std::string &device_info) {
|
||||
#if defined(USE_ARDUINO)
|
||||
const char *flash_mode;
|
||||
@ -246,46 +138,16 @@ void DebugComponent::get_device_info_(std::string &device_info) {
|
||||
|
||||
esp_chip_info_t info;
|
||||
esp_chip_info(&info);
|
||||
const char *model;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32)
|
||||
model = "ESP32";
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C2)
|
||||
model = "ESP32-C2";
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C3)
|
||||
model = "ESP32-C3";
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32C6)
|
||||
model = "ESP32-C6";
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32S2)
|
||||
model = "ESP32-S2";
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
model = "ESP32-S3";
|
||||
#elif defined(USE_ESP32_VARIANT_ESP32H2)
|
||||
model = "ESP32-H2";
|
||||
#else
|
||||
model = "UNKNOWN";
|
||||
#endif
|
||||
const char *model = ESPHOME_VARIANT;
|
||||
std::string features;
|
||||
if (info.features & CHIP_FEATURE_EMB_FLASH) {
|
||||
features += "EMB_FLASH,";
|
||||
info.features &= ~CHIP_FEATURE_EMB_FLASH;
|
||||
for (auto feature : CHIP_FEATURES) {
|
||||
if (info.features & feature.first) {
|
||||
features += feature.second;
|
||||
features += ", ";
|
||||
info.features &= ~feature.first;
|
||||
}
|
||||
}
|
||||
if (info.features & CHIP_FEATURE_WIFI_BGN) {
|
||||
features += "WIFI_BGN,";
|
||||
info.features &= ~CHIP_FEATURE_WIFI_BGN;
|
||||
}
|
||||
if (info.features & CHIP_FEATURE_BLE) {
|
||||
features += "BLE,";
|
||||
info.features &= ~CHIP_FEATURE_BLE;
|
||||
}
|
||||
if (info.features & CHIP_FEATURE_BT) {
|
||||
features += "BT,";
|
||||
info.features &= ~CHIP_FEATURE_BT;
|
||||
}
|
||||
if (info.features & CHIP_FEATURE_EMB_PSRAM) {
|
||||
features += "EMB_PSRAM,";
|
||||
info.features &= ~CHIP_FEATURE_EMB_PSRAM;
|
||||
}
|
||||
if (info.features)
|
||||
if (info.features != 0)
|
||||
features += "Other:" + format_hex(info.features);
|
||||
ESP_LOGD(TAG, "Chip: Model=%s, Features=%s Cores=%u, Revision=%u", model, features.c_str(), info.cores,
|
||||
info.revision);
|
||||
@ -295,6 +157,8 @@ void DebugComponent::get_device_info_(std::string &device_info) {
|
||||
device_info += features;
|
||||
device_info += " Cores:" + to_string(info.cores);
|
||||
device_info += " Revision:" + to_string(info.revision);
|
||||
device_info += str_sprintf("|CPU Frequency: %" PRIu32 " MHz", arch_get_cpu_freq_hz() / 1000000);
|
||||
ESP_LOGD(TAG, "CPU Frequency: %" PRIu32 " MHz", arch_get_cpu_freq_hz() / 1000000);
|
||||
|
||||
// Framework detection
|
||||
device_info += "|Framework: ";
|
||||
@ -321,50 +185,7 @@ void DebugComponent::get_device_info_(std::string &device_info) {
|
||||
device_info += "|Reset: ";
|
||||
device_info += get_reset_reason_();
|
||||
|
||||
const char *wakeup_reason;
|
||||
switch (rtc_get_wakeup_cause()) {
|
||||
case NO_SLEEP:
|
||||
wakeup_reason = "No Sleep";
|
||||
break;
|
||||
case EXT_EVENT0_TRIG:
|
||||
wakeup_reason = "External Event 0";
|
||||
break;
|
||||
case EXT_EVENT1_TRIG:
|
||||
wakeup_reason = "External Event 1";
|
||||
break;
|
||||
case GPIO_TRIG:
|
||||
wakeup_reason = "GPIO";
|
||||
break;
|
||||
case TIMER_EXPIRE:
|
||||
wakeup_reason = "Wakeup Timer";
|
||||
break;
|
||||
case SDIO_TRIG:
|
||||
wakeup_reason = "SDIO";
|
||||
break;
|
||||
case MAC_TRIG:
|
||||
wakeup_reason = "MAC";
|
||||
break;
|
||||
case UART0_TRIG:
|
||||
wakeup_reason = "UART0";
|
||||
break;
|
||||
case UART1_TRIG:
|
||||
wakeup_reason = "UART1";
|
||||
break;
|
||||
#if !defined(USE_ESP32_VARIANT_ESP32C2)
|
||||
case TOUCH_TRIG:
|
||||
wakeup_reason = "Touch";
|
||||
break;
|
||||
#endif
|
||||
case SAR_TRIG:
|
||||
wakeup_reason = "SAR";
|
||||
break;
|
||||
case BT_TRIG:
|
||||
wakeup_reason = "BT";
|
||||
break;
|
||||
default:
|
||||
wakeup_reason = "Unknown";
|
||||
}
|
||||
ESP_LOGD(TAG, "Wakeup Reason: %s", wakeup_reason);
|
||||
std::string wakeup_reason = this->get_wakeup_cause_();
|
||||
device_info += "|Wakeup: ";
|
||||
device_info += wakeup_reason;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import sensor
|
||||
from esphome.components.esp32 import CONF_CPU_FREQUENCY
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_BLOCK,
|
||||
@ -10,6 +11,7 @@ from esphome.const import (
|
||||
ICON_COUNTER,
|
||||
ICON_TIMER,
|
||||
UNIT_BYTES,
|
||||
UNIT_HERTZ,
|
||||
UNIT_MILLISECOND,
|
||||
UNIT_PERCENT,
|
||||
)
|
||||
@ -60,6 +62,14 @@ CONFIG_SCHEMA = {
|
||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
),
|
||||
),
|
||||
cv.Optional(CONF_CPU_FREQUENCY): cv.All(
|
||||
sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_HERTZ,
|
||||
icon="mdi:speedometer",
|
||||
accuracy_decimals=0,
|
||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
),
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
@ -85,3 +95,7 @@ async def to_code(config):
|
||||
if psram_conf := config.get(CONF_PSRAM):
|
||||
sens = await sensor.new_sensor(psram_conf)
|
||||
cg.add(debug_component.set_psram_sensor(sens))
|
||||
|
||||
if cpu_freq_conf := config.get(CONF_CPU_FREQUENCY):
|
||||
sens = await sensor.new_sensor(cpu_freq_conf)
|
||||
cg.add(debug_component.set_cpu_frequency_sensor(sens))
|
||||
|
@ -1,4 +1,5 @@
|
||||
from dataclasses import dataclass
|
||||
import itertools
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
@ -37,6 +38,7 @@ from esphome.const import (
|
||||
__version__,
|
||||
)
|
||||
from esphome.core import CORE, HexInt, TimePeriod
|
||||
from esphome.cpp_generator import RawExpression
|
||||
import esphome.final_validate as fv
|
||||
from esphome.helpers import copy_file_if_changed, mkdir_p, write_file_if_changed
|
||||
|
||||
@ -54,6 +56,12 @@ from .const import ( # noqa
|
||||
KEY_SUBMODULES,
|
||||
KEY_VARIANT,
|
||||
VARIANT_ESP32,
|
||||
VARIANT_ESP32C2,
|
||||
VARIANT_ESP32C3,
|
||||
VARIANT_ESP32C6,
|
||||
VARIANT_ESP32H2,
|
||||
VARIANT_ESP32S2,
|
||||
VARIANT_ESP32S3,
|
||||
VARIANT_FRIENDLY,
|
||||
VARIANTS,
|
||||
)
|
||||
@ -70,7 +78,43 @@ CONF_RELEASE = "release"
|
||||
CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES = "enable_idf_experimental_features"
|
||||
|
||||
|
||||
def get_cpu_frequencies(*frequencies):
|
||||
return [str(x) + "MHZ" for x in frequencies]
|
||||
|
||||
|
||||
CPU_FREQUENCIES = {
|
||||
VARIANT_ESP32: get_cpu_frequencies(80, 160, 240),
|
||||
VARIANT_ESP32S2: get_cpu_frequencies(80, 160, 240),
|
||||
VARIANT_ESP32S3: get_cpu_frequencies(80, 160, 240),
|
||||
VARIANT_ESP32C2: get_cpu_frequencies(80, 120),
|
||||
VARIANT_ESP32C3: get_cpu_frequencies(80, 160),
|
||||
VARIANT_ESP32C6: get_cpu_frequencies(80, 120, 160),
|
||||
VARIANT_ESP32H2: get_cpu_frequencies(16, 32, 48, 64, 96),
|
||||
}
|
||||
|
||||
# Make sure not missed here if a new variant added.
|
||||
assert all(v in CPU_FREQUENCIES for v in VARIANTS)
|
||||
|
||||
FULL_CPU_FREQUENCIES = set(itertools.chain.from_iterable(CPU_FREQUENCIES.values()))
|
||||
|
||||
|
||||
def set_core_data(config):
|
||||
cpu_frequency = config.get(CONF_CPU_FREQUENCY, None)
|
||||
variant = config[CONF_VARIANT]
|
||||
# if not specified in config, set to 160MHz if supported, the fastest otherwise
|
||||
if cpu_frequency is None:
|
||||
choices = CPU_FREQUENCIES[variant]
|
||||
if "160MHZ" in choices:
|
||||
cpu_frequency = "160MHZ"
|
||||
else:
|
||||
cpu_frequency = choices[-1]
|
||||
config[CONF_CPU_FREQUENCY] = cpu_frequency
|
||||
elif cpu_frequency not in CPU_FREQUENCIES[variant]:
|
||||
raise cv.Invalid(
|
||||
f"Invalid CPU frequency '{cpu_frequency}' for {config[CONF_VARIANT]}",
|
||||
path=[CONF_CPU_FREQUENCY],
|
||||
)
|
||||
|
||||
CORE.data[KEY_ESP32] = {}
|
||||
CORE.data[KEY_CORE][KEY_TARGET_PLATFORM] = PLATFORM_ESP32
|
||||
conf = config[CONF_FRAMEWORK]
|
||||
@ -83,6 +127,7 @@ def set_core_data(config):
|
||||
CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] = cv.Version.parse(
|
||||
config[CONF_FRAMEWORK][CONF_VERSION]
|
||||
)
|
||||
|
||||
CORE.data[KEY_ESP32][KEY_BOARD] = config[CONF_BOARD]
|
||||
CORE.data[KEY_ESP32][KEY_VARIANT] = config[CONF_VARIANT]
|
||||
CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES] = {}
|
||||
@ -553,11 +598,15 @@ FLASH_SIZES = [
|
||||
]
|
||||
|
||||
CONF_FLASH_SIZE = "flash_size"
|
||||
CONF_CPU_FREQUENCY = "cpu_frequency"
|
||||
CONF_PARTITIONS = "partitions"
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_BOARD): cv.string_strict,
|
||||
cv.Optional(CONF_CPU_FREQUENCY): cv.one_of(
|
||||
*FULL_CPU_FREQUENCIES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_FLASH_SIZE, default="4MB"): cv.one_of(
|
||||
*FLASH_SIZES, upper=True
|
||||
),
|
||||
@ -598,6 +647,7 @@ async def to_code(config):
|
||||
os.path.join(os.path.dirname(__file__), "post_build.py.script"),
|
||||
)
|
||||
|
||||
freq = config[CONF_CPU_FREQUENCY][:-3]
|
||||
if conf[CONF_TYPE] == FRAMEWORK_ESP_IDF:
|
||||
cg.add_platformio_option("framework", "espidf")
|
||||
cg.add_build_flag("-DUSE_ESP_IDF")
|
||||
@ -631,6 +681,9 @@ async def to_code(config):
|
||||
add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0", False)
|
||||
add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1", False)
|
||||
|
||||
# Set default CPU frequency
|
||||
add_idf_sdkconfig_option(f"CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_{freq}", True)
|
||||
|
||||
cg.add_platformio_option("board_build.partitions", "partitions.csv")
|
||||
if CONF_PARTITIONS in config:
|
||||
add_extra_build_file(
|
||||
@ -696,6 +749,7 @@ async def to_code(config):
|
||||
f"VERSION_CODE({framework_ver.major}, {framework_ver.minor}, {framework_ver.patch})"
|
||||
),
|
||||
)
|
||||
cg.add(RawExpression(f"setCpuFrequencyMhz({freq})"))
|
||||
|
||||
|
||||
APP_PARTITION_SIZES = {
|
||||
|
@ -13,11 +13,13 @@
|
||||
#include <hal/cpu_hal.h>
|
||||
|
||||
#ifdef USE_ARDUINO
|
||||
#include <esp32-hal.h>
|
||||
#endif
|
||||
#include <Esp.h>
|
||||
#else
|
||||
#include <esp_clk_tree.h>
|
||||
|
||||
void setup();
|
||||
void loop();
|
||||
#endif
|
||||
|
||||
namespace esphome {
|
||||
|
||||
@ -59,9 +61,13 @@ uint32_t arch_get_cpu_cycle_count() { return esp_cpu_get_cycle_count(); }
|
||||
uint32_t arch_get_cpu_cycle_count() { return cpu_hal_get_cycle_count(); }
|
||||
#endif
|
||||
uint32_t arch_get_cpu_freq_hz() {
|
||||
rtc_cpu_freq_config_t config;
|
||||
rtc_clk_cpu_freq_get_config(&config);
|
||||
return config.freq_mhz * 1000000U;
|
||||
uint32_t freq = 0;
|
||||
#ifdef USE_ESP_IDF
|
||||
esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_CPU, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &freq);
|
||||
#elif defined(USE_ARDUINO)
|
||||
freq = ESP.getCpuFreqMHz() * 1000000;
|
||||
#endif
|
||||
return freq;
|
||||
}
|
||||
|
||||
#ifdef USE_ESP_IDF
|
||||
|
@ -1 +1,18 @@
|
||||
debug:
|
||||
|
||||
text_sensor:
|
||||
- platform: debug
|
||||
device:
|
||||
name: "Device Info"
|
||||
reset_reason:
|
||||
name: "Reset Reason"
|
||||
|
||||
sensor:
|
||||
- platform: debug
|
||||
free:
|
||||
name: "Heap Free"
|
||||
loop_time:
|
||||
name: "Loop Time"
|
||||
cpu_frequency:
|
||||
name: "CPU Frequency"
|
||||
|
||||
|
@ -1 +1,4 @@
|
||||
<<: !include common.yaml
|
||||
|
||||
esp32:
|
||||
cpu_frequency: 240MHz
|
||||
|
@ -1 +1,4 @@
|
||||
<<: !include common.yaml
|
||||
|
||||
esp32:
|
||||
cpu_frequency: 80MHz
|
||||
|
@ -1 +1,13 @@
|
||||
<<: !include common.yaml
|
||||
|
||||
esp32:
|
||||
cpu_frequency: 240MHz
|
||||
|
||||
sensor:
|
||||
- platform: debug
|
||||
free:
|
||||
name: "Heap Free"
|
||||
psram:
|
||||
name: "Free PSRAM"
|
||||
|
||||
psram:
|
||||
|
Loading…
x
Reference in New Issue
Block a user