12#if PC_ENABLE_POWER_MGMT
22#include <esp_system.h>
24#if defined(ARDUINO) && defined(CONFIG_BT_ENABLED)
27void pc_power_cfg_defaults(PowerCfg *cfg)
41PowerPlan pc_power_plan(
const PowerCfg *cfg, uint8_t load_pct, int16_t temp_c,
bool brownout_boot,
42 uint32_t since_boot_ms,
bool was_throttled)
56 bool have_temp = temp_c != INT16_MIN;
59 p.throttled = was_throttled ? (temp_c > cfg->temp_cool_c) : (temp_c >= cfg->temp_hot_c);
68 p.recovering = brownout_boot && since_boot_ms < cfg->recover_ms;
70 if (p.recovering || p.throttled)
72 p.cpu_mhz = cfg->mhz_min;
79 p.cpu_mhz = (load_pct >= cfg->busy_pct) ? cfg->mhz_max : cfg->mhz_min;
83size_t pc_power_json(
const PowerPlan *plan, int16_t temp_c,
char *out,
size_t cap)
85 if (!plan || !out || cap == 0)
91 pc_sb sb = {out, cap, 0,
true};
95 pc_sb_put(&sb, plan->throttled ?
"true" :
"false");
97 pc_sb_put(&sb, plan->recovering ?
"true" :
"false");
99 if (temp_c == INT16_MIN)
128 bool brownout_latched;
132static PowerCtx s_pwr = {
false,
false,
false};
134bool pc_power_brownout_boot(
void)
138 if (!s_pwr.boot_checked)
140 s_pwr.brownout_latched = (esp_reset_reason() == ESP_RST_BROWNOUT);
141 s_pwr.boot_checked =
true;
143 return s_pwr.brownout_latched;
146int16_t pc_power_temp_c(
void)
148#if defined(SOC_TEMP_SENSOR_SUPPORTED) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || \
149 defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32P4)
150 float t = temperatureRead();
152 if (t < -60.0f || t > 200.0f)
156 return (int16_t)(t + (t < 0 ? -0.5f : 0.5f));
162uint16_t pc_power_cpu_mhz(
void)
164 return (uint16_t)getCpuFrequencyMhz();
167bool pc_power_apply(
const PowerPlan *plan)
169 if (!plan || plan->cpu_mhz == 0)
173 if (pc_power_cpu_mhz() == plan->cpu_mhz)
177 return setCpuFrequencyMhz((uint32_t)plan->cpu_mhz);
180bool pc_power_gate_bt(
void)
182#if defined(CONFIG_BT_ENABLED)
183 if (s_pwr.bt_released)
189 if (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED)
191 esp_bt_controller_disable();
193 bool ok = esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) == ESP_OK;
194 s_pwr.bt_released = ok;
SoC power governor: frequency scaling, thermal throttle, brownout recovery, gating (PC_ENABLE_POWER_M...
#define PC_POWER_RECOVER_MS
How long (ms) to hold the floor clock after a brownout reset before ramping back up.
#define PC_POWER_TEMP_COOL_C
Die temperature (C) at/below which the throttle is released.
#define PC_POWER_TEMP_HOT_C
Die temperature (C) at/above which the clock is throttled.
#define PC_POWER_MHZ_MIN
CPU clock (MHz) when idle, thermally throttled, or recovering from a brownout.
#define PC_POWER_BUSY_PCT
Load percentage at/above which the ceiling clock is used.
#define PC_POWER_MHZ_MAX
CPU clock (MHz) when there is work to do.
Bounded no-heap string builder that fails closed on overflow (one shared copy).
size_t pc_sb_finish(pc_sb *b)
NUL-terminate and return the built length, or 0 if the build overflowed.
void pc_sb_i64(pc_sb *b, int64_t v)
Append v as signed decimal (64-bit), with a leading '-' when negative.
void pc_sb_put(pc_sb *b, const char *s)
Append NUL-terminated s; leaves the buffer untouched and clears ok if it would not fit.
void pc_sb_u32(pc_sb *b, uint32_t v)
Append v as decimal (no leading zeros; "0" for zero).
Bump-append target; ok latches false once an append would overflow cap.