fix: stabilize Heltec RC32 startup

This commit is contained in:
mikecarper committed 2026-08-27 17:06:20 -07:00
1 parent 7676e4b1c2
commit 5a26d4ddd1
10 files changed
+95 -9

No files matched your search

+16 -3
View File
@@ -2416,11 +2416,24 @@ is_esp32_dual_cdc_companion_radio_full_target() {
esac
}
prepare_esp32_dual_cdc_framework() {
requires_esp32_arduino3_framework() {
local env_name=$1
local pio_env_name=$2
is_esp32_dual_cdc_companion_radio_full_target "$env_name" || return 0
if is_esp32_dual_cdc_companion_radio_full_target "$env_name"; then
return 0
fi
case "${env_name,,}:${pio_env_name,,}" in
heltec_rc32_*:*|*:heltec_rc32_*) return 0 ;;
*) return 1 ;;
esac
}
prepare_esp32_arduino3_framework() {
local env_name=$1
local pio_env_name=$2
requires_esp32_arduino3_framework "$env_name" "$pio_env_name" || return 0
# PlatformIO's standard ESP32 platform and pioarduino publish incompatible
# Arduino 2.x/3.x cores under the same global package name. `pio run` restores
@@ -3667,7 +3680,7 @@ build_firmware() {
fi
fi
if [ "$build_status" -eq 0 ]; then
prepare_esp32_dual_cdc_framework "$env_name" "$pio_env_name"
prepare_esp32_arduino3_framework "$env_name" "$pio_env_name"
build_status=$?
fi
pio_run_args=(run -e "$pio_env_name")
+3 -1
View File
@@ -289,7 +289,9 @@ static int8_t attempted_power_saving = -1;
static unsigned long power_saving_retry_at = 0;
static uint32_t companionNominalCpuMhz() {
#ifdef ESP32_CPU_FREQ
#ifdef ESP32_POST_BOOT_CPU_FREQ
return ESP32_POST_BOOT_CPU_FREQ;
#elif defined(ESP32_CPU_FREQ)
return ESP32_CPU_FREQ;
#else
return F_CPU / 1000000UL;
+2
View File
@@ -141,6 +141,8 @@ void setup() {
#if ENABLE_ADVERT_ON_BOOT == 1
the_mesh.sendSelfAdvertisement(16000, false);
#endif
board.onBootComplete();
}
void loop() {
+14
View File
@@ -92,9 +92,23 @@ class CustomSX1262 : public SX1262 {
#endif
int status = begin(LORA_FREQ, LORA_BW, LORA_SF, cr, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 16, tcxo, useRegulatorLDO);
if (status != RADIOLIB_ERR_NONE) {
#if defined(SX126X_ALLOW_RECOVERABLE_INIT_STATUS) && SX126X_ALLOW_RECOVERABLE_INIT_STATUS
// Some SX1262 modules report a transient command status after the
// chip has already answered its identity probe. Continue configuring
// those devices; an absent chip or a hard command failure is fatal.
if (status == RADIOLIB_ERR_CHIP_NOT_FOUND
|| status == RADIOLIB_ERR_SPI_CMD_FAILED) {
mesh::usbLoggingPort().print("ERROR: radio init failed: ");
mesh::usbLoggingPort().println(status);
return false;
}
mesh::usbLoggingPort().print("WARN: recoverable radio init status: ");
mesh::usbLoggingPort().println(status);
#else
mesh::usbLoggingPort().print("ERROR: radio init failed: ");
mesh::usbLoggingPort().println(status);
return false; // fail
#endif
}
// RadioLib's default DIO3 TCXO delay is 5 ms and its RX duty-cycle
+27
View File
@@ -12,6 +12,25 @@ fail() {
[ "$OPTION3_BUILD_WORKERS" -eq 1 ] \
|| fail "logging matrix permits concurrent PlatformIO target builds"
requires_esp32_arduino3_framework \
heltec_rc32_repeater heltec_rc32_repeater \
|| fail "RC32 omitted its Arduino-ESP32 3.x package preflight"
if requires_esp32_arduino3_framework \
Heltec_v3_repeater Heltec_v3_repeater; then
fail "ordinary ESP32 target unexpectedly selected Arduino-ESP32 3.x"
fi
grep -Fq 'void HeltecRC32Board::onBootComplete()' \
variants/heltec_rc32/HeltecRC32Board.cpp \
|| fail "RC32 omitted its post-boot clock transition"
grep -Fq 'current_mhz > ESP32_POST_BOOT_CPU_FREQ' \
variants/heltec_rc32/HeltecRC32Board.cpp \
|| fail "RC32 post-boot clock transition overrides lower power-saving clocks"
grep -Fq 'return ESP32_POST_BOOT_CPU_FREQ;' examples/companion_radio/main.cpp \
|| fail "Companion power saving ignores the RC32 post-boot nominal clock"
grep -Fq 'board.onBootComplete();' examples/simple_sensor/main.cpp \
|| fail "sensor firmware never applies board post-boot policy"
# Interactive builds can carry the complete version from the newest artifact
# in out/, while an empty directory falls through to the existing tag-derived
# editable prompt.
@@ -88,6 +107,14 @@ require("Heltec_E290_companion_usb_ble", "build_flags", "BLE_PIN_CODE=123456")
require("Heltec_T190_companion_radio_usb_ble_", "build_flags", "ENABLE_USB_INTERFACE")
require("Heltec_T190_companion_radio_usb_ble_", "build_flags", "BLE_PIN_CODE=123456")
rc32_repeater = "heltec_rc32_repeater"
require(rc32_repeater, "platform", "55.03.311")
require(rc32_repeater, "platform_packages", "esp32-core-3.3.11.tar.xz")
require(rc32_repeater, "build_flags", "ESP32_POST_BOOT_CPU_FREQ=160")
require(rc32_repeater, "build_flags", "RC32_PERIPHERAL_WARMUP_MS=100")
require(rc32_repeater, "build_flags", "SX126X_ALLOW_RECOVERABLE_INIT_STATUS=1")
reject(rc32_repeater, "build_flags", "ESP32_CPU_FREQ=160")
for env_name in (
"Heltec_t114_without_display_repeater",
"Heltec_t114_repeater",
+3 -3
View File
@@ -414,16 +414,16 @@ def test_esp32_s3_full_profiles_inherit_dio_boot_mode():
build = (root / "build.sh").read_text(encoding="utf-8")
framework_preflight = build.split(
"prepare_esp32_dual_cdc_framework()", 1
"prepare_esp32_arduino3_framework()", 1
)[1].split("requires_esp32_companion_full_ota_fallback()", 1)[0]
assert "is_esp32_dual_cdc_companion_radio_full_target" in framework_preflight
assert "requires_esp32_arduino3_framework" in framework_preflight
assert 'pio pkg install -e "$pio_env_name"' in framework_preflight
build_call = build.split(
'print_build_flags "$pio_env_name" "$env_name"', 1
)[1].split(
"restore_platformio_build_flags", 1
)[0]
assert 'prepare_esp32_dual_cdc_framework "$env_name" "$pio_env_name"' in build_call
assert 'prepare_esp32_arduino3_framework "$env_name" "$pio_env_name"' in build_call
assert 'if [ "$build_status" -eq 0 ]; then' in build_call
assert 'flock "$platformio_package_lock_fd"' in build_call
assert 'flock -u "$platformio_package_lock_fd"' in build_call
+19
View File
@@ -18,6 +18,9 @@ void HeltecRC32Board::begin() {
periph_power.begin();
periph_power.claim();
#ifdef RC32_PERIPHERAL_WARMUP_MS
delay(RC32_PERIPHERAL_WARMUP_MS);
#endif
esp_reset_reason_t reason = esp_reset_reason();
if (reason == ESP_RST_DEEPSLEEP) {
@@ -31,6 +34,22 @@ void HeltecRC32Board::begin() {
}
}
void HeltecRC32Board::onBootComplete() {
#ifdef ESP32_POST_BOOT_CPU_FREQ
const uint32_t current_mhz = getCpuFrequencyMhz();
if (current_mhz > ESP32_POST_BOOT_CPU_FREQ) {
if (setCpuFrequencyMhz(ESP32_POST_BOOT_CPU_FREQ)) {
MESH_DEBUG_PRINTLN("RC32 startup complete; CPU reduced from %lu to %u MHz",
(unsigned long)current_mhz,
(unsigned)ESP32_POST_BOOT_CPU_FREQ);
} else {
MESH_DEBUG_PRINTLN("RC32 could not set post-boot CPU frequency to %u MHz",
(unsigned)ESP32_POST_BOOT_CPU_FREQ);
}
}
#endif
}
void HeltecRC32Board::powerOff() {
enterDeepSleep(0);
}
+1
View File
@@ -19,6 +19,7 @@ public:
HeltecRC32Board() : periph_power(SENSOR_POWER_CTRL_PIN, SENSOR_POWER_ON){}
void begin();
void onBootComplete() override;
void onBeforeTransmit() override;
void onAfterTransmit() override;
void powerOff() override;
+8 -1
View File
@@ -1,5 +1,9 @@
[Heltec_RC32]
extends = esp32_base
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
platform_packages =
framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32/releases/download/3.3.11/esp32-core-3.3.11.tar.xz
framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.3.11/esp32-core-3.3.11-libs.tar.xz
board = heltec-rc32
board_build.partitions = default_16MB.csv
build_flags =
@@ -9,7 +13,10 @@ build_flags =
-I src/helpers/ui
-D HELTEC_RC32
-D USE_SX1262
-D ESP32_CPU_FREQ=160
; Keep the board at its 240 MHz default through peripheral initialization.
-D ESP32_POST_BOOT_CPU_FREQ=160
-D RC32_PERIPHERAL_WARMUP_MS=100
-D SX126X_ALLOW_RECOVERABLE_INIT_STATUS=1
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
-D P_LORA_DIO_1=14
+2 -1
View File
@@ -8,7 +8,8 @@ HeltecRC32Board board;
#if defined(P_LORA_SCLK)
static SPIClass spi(FSPI);
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi);
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi,
SPISettings(4000000, MSBFIRST, SPI_MODE0));
#else
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
#endif