Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/parameter.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ unsigned long t_batteryIcon = 0;
bool b_showBatteryIcon = true;
// volatile: now also written from the AsyncTCP task (WS soft-sleep command).
volatile bool b_softSleep = false;
unsigned long t_lastSerialActivity = 0;
#if defined(ACC_MPU6050) || defined(ACC_BMA400)
bool b_gyroEnabled = true;
#endif
Expand Down
34 changes: 34 additions & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,37 @@ platform = native
test_build_src = no
test_framework = unity
build_flags = -Iinclude

# Tier-2 automatic light-sleep build (AI FYI, see PR). Opt-in, from-source: the
# CONFIG_PM_* / tickless / BT-controller-sleep flags below are compile-time and
# require rebuilding the framework from source (custom_sdkconfig triggers it).
# The BT low-power clock is RTC_SLOW because this board has no external 32kHz
# crystal (CONFIG_RTC_CLK_SRC_INT_RC). Pair with the CONFIG_PM_ENABLE-guarded
# esp_pm_configure() + loop yield + UART wake in src/hds.ino. Build:
# pio run -e esp32s3_pm -t upload
# custom_component_remove skips unused managed IDF components that the from-source
# build would otherwise compile (esp-modbus fails a static assert); none are
# #included by this firmware, so removal is image-identical.
[env:esp32s3_pm]
extends = env:esp32s3
custom_component_remove =
espressif/esp-modbus
espressif/esp-sr
espressif/esp-zboss-lib
espressif/esp-zigbee-lib
espressif/esp_insights
espressif/esp_diagnostics
espressif/esp_diag_data_store
espressif/esp_rainmaker
espressif/rmaker_common
espressif/esp_modem
espressif/esp-dsp
chmorgan/esp-libhelix-mp3
espressif/qrcode
custom_sdkconfig =
CONFIG_PM_ENABLE=y
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
CONFIG_PM_DFS_INIT_AUTO=y
CONFIG_BT_CTRL_MODEM_SLEEP=y
CONFIG_BT_CTRL_MODEM_SLEEP_MODE_1=y
CONFIG_BT_CTRL_LPCLK_SEL_RTC_SLOW=y
50 changes: 50 additions & 0 deletions src/hds.ino
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include <Arduino.h>
#include <cstring>
#include "esp_pm.h"
#include "esp_sleep.h"
#include "driver/uart.h"
#include "config.h"

#include "parameter.h"
Expand Down Expand Up @@ -423,6 +426,13 @@ void wifi_init() {

MyUsbCallbacks usbCallbacks;

#if CONFIG_PM_ENABLE
// Held while the scale is connected + live (not soft-sleep), pinning the CPU at
// max freq so on-scale extensions have full compute; released otherwise so DFS
// scales down and light sleep engages.
esp_pm_lock_handle_t s_activeFreqLock = nullptr;
#endif

// Map esp_reset_reason() to a short string for the boot log only. The raw
// numeric code is what we ship in the ADS debug packet (byte 24); this is
// purely for human-readable serial output.
Expand Down Expand Up @@ -882,6 +892,22 @@ void setup() {
} else {
hdsOtaRollbackMarkValid();
}

#if CONFIG_PM_ENABLE
{
esp_pm_config_t pmcfg = {
.max_freq_mhz = 240,
.min_freq_mhz = 80,
.light_sleep_enable = true,
};
esp_err_t pmrc = esp_pm_configure(&pmcfg);
Serial.printf("[pm] esp_pm_configure ls=on 240/80 -> %s\n", esp_err_to_name(pmrc));
esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "active", &s_activeFreqLock);
uart_set_wakeup_threshold(UART_NUM_0, 3);
esp_err_t urc = esp_sleep_enable_uart_wakeup(UART_NUM_0);
Serial.printf("[pm] uart0 wake-on-rx -> %s\n", esp_err_to_name(urc));
}
#endif
}

/**
Expand Down Expand Up @@ -1570,6 +1596,19 @@ void loop() {
// here on the loop task rather than racing peripheral drivers.
processWsPendingCmds();

#if CONFIG_PM_ENABLE
{
static bool prevActive = false;
bool active = deviceConnected && !b_softSleep;
if (active != prevActive && s_activeFreqLock != nullptr) {
if (active) esp_pm_lock_acquire(s_activeFreqLock);
else esp_pm_lock_release(s_activeFreqLock);
prevActive = active;
Serial.printf("[pm] cpu %s (connected+live=%d)\n", active ? "pinned 240" : "released->DFS", active);
}
}
#endif

if (b_powerOff){
shut_down_now_nobeep();
return;
Expand Down Expand Up @@ -1605,6 +1644,7 @@ void loop() {
data[len++] = Serial.read();
}
usbCallbacks.onStream(data, len); // Process serial byte stream
t_lastSerialActivity = millis();
}
usbCallbacks.poll();

Expand Down Expand Up @@ -1785,6 +1825,16 @@ void loop() {
}
}
}

#if CONFIG_PM_ENABLE
if (millis() - t_lastSerialActivity <= 250) {
vTaskDelay(1);
} else if (b_softSleep) {
vTaskDelay(pdMS_TO_TICKS(50));
} else {
vTaskDelay(pdMS_TO_TICKS(10));
}
#endif
}


Expand Down
Loading