diff --git a/src/platform/nrf52/main-nrf52.cpp b/src/platform/nrf52/main-nrf52.cpp index 9b26721c0..4bb778ca6 100644 --- a/src/platform/nrf52/main-nrf52.cpp +++ b/src/platform/nrf52/main-nrf52.cpp @@ -78,11 +78,18 @@ bool powerHAL_isVBUSConnected() bool powerHAL_isPowerLevelSafe() { + static bool powerLevelSafe = true; - static bool powerLevelSafe = true; - - uint16_t threshold = SAFE_VDD_VOLTAGE_THRESHOLD * 1000; // convert V to mV - uint16_t hysteresis = SAFE_VDD_VOLTAGE_THRESHOLD_HYST * 1000; +#ifdef SAFE_VDD_VOLTAGE_THRESHOLD_MV + uint16_t threshold = SAFE_VDD_VOLTAGE_THRESHOLD_MV; +#else + uint16_t threshold = (uint16_t)(SAFE_VDD_VOLTAGE_THRESHOLD * 1000.0f + 0.5f); // convert V to mV +#endif +#ifdef SAFE_VDD_VOLTAGE_THRESHOLD_HYST_MV + uint16_t hysteresis = SAFE_VDD_VOLTAGE_THRESHOLD_HYST_MV; +#else + uint16_t hysteresis = (uint16_t)(SAFE_VDD_VOLTAGE_THRESHOLD_HYST * 1000.0f + 0.5f); +#endif if (powerLevelSafe) { if (getVDDVoltage() < threshold) { diff --git a/variants/nrf52840/rak_wismeshtag/variant.cpp b/variants/nrf52840/rak_wismeshtag/variant.cpp index c2a899ed5..1c53bbc0d 100644 --- a/variants/nrf52840/rak_wismeshtag/variant.cpp +++ b/variants/nrf52840/rak_wismeshtag/variant.cpp @@ -51,15 +51,31 @@ void variant_nrf52LoopHook(void) // If VDD stays unsafe for a while (brownout), force System OFF. // Skip when VBUS present to allow recovery while USB-powered. if (!powerHAL_isVBUSConnected()) { + // Rate-limit VDD safety checks: powerHAL_isPowerLevelSafe() calls getVDDVoltage() each time. + static constexpr uint32_t POWER_LEVEL_CHECK_INTERVAL_MS = 100; + static uint32_t last_vdd_check_ms = 0; + static bool last_power_level_safe = true; + + const uint32_t now = millis(); + if (last_vdd_check_ms == 0 || (uint32_t)(now - last_vdd_check_ms) >= POWER_LEVEL_CHECK_INTERVAL_MS) { + last_vdd_check_ms = now; + last_power_level_safe = powerHAL_isPowerLevelSafe(); + } + + // Do not use millis()==0 as a sentinel: at boot, millis() may be 0 while VDD is unsafe. + static bool low_vdd_timer_armed = false; static uint32_t low_vdd_since_ms = 0; - if (!powerHAL_isPowerLevelSafe()) { - if (low_vdd_since_ms == 0) - low_vdd_since_ms = millis(); - if ((uint32_t)(millis() - low_vdd_since_ms) >= (uint32_t)LOW_VDD_SYSTEMOFF_DELAY_MS) { + + if (!last_power_level_safe) { + if (!low_vdd_timer_armed) { + low_vdd_since_ms = now; + low_vdd_timer_armed = true; + } + if ((uint32_t)(now - low_vdd_since_ms) >= (uint32_t)LOW_VDD_SYSTEMOFF_DELAY_MS) { cpuDeepSleep(portMAX_DELAY); } } else { - low_vdd_since_ms = 0; + low_vdd_timer_armed = false; } } } diff --git a/variants/nrf52840/rak_wismeshtag/variant.h b/variants/nrf52840/rak_wismeshtag/variant.h index 6014af871..284bba062 100644 --- a/variants/nrf52840/rak_wismeshtag/variant.h +++ b/variants/nrf52840/rak_wismeshtag/variant.h @@ -231,8 +231,10 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG // BAT_ADC divider: R22=1M (top), R24=1.5M (bottom) => V_BAT_ADC = VBAT * (1.5 / (1.0 + 1.5)) = 0.6 * VBAT // RAK4630 module: AIN0 = nrf52840 AIN3 = Pin 5 (A0/BATTERY_PIN) #define BATTERY_LPCOMP_INPUT NRF_LPCOMP_INPUT_3 -// If VDD is regulated ~3.3V, this wakes around VBAT ~3.09V (good for brownout recovery). -#define BATTERY_LPCOMP_THRESHOLD NRF_LPCOMP_REF_SUPPLY_9_16 //3.09V NRF_LPCOMP_REF_SUPPLY_9_16 = 3.09V +// LPCOMP compares the selected input to a fraction of VDD (here 9/16 of VDD at the LPCOMP input). +// With VDD ≈ 3.3 V: threshold at input ≈ (9/16) * 3.3 V ≈ 1.86 V. +// BAT_ADC divider: V_BAT_ADC = 0.6 * VBAT → equivalent VBAT ≈ 1.86 / 0.6 ≈ 3.1 V (wake when battery recovers). +#define BATTERY_LPCOMP_THRESHOLD NRF_LPCOMP_REF_SUPPLY_9_16 // Low voltage protection: // If VDD is below SAFE_VDD_VOLTAGE_THRESHOLD for longer than this delay (and no USB VBUS), @@ -241,12 +243,18 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG #define LOW_VDD_SYSTEMOFF_DELAY_MS 5000 #endif +// Prefer integer mV so platform code avoids float→int truncation quirks (e.g. 0.1 V → 99 vs 100 mV). +#ifndef SAFE_VDD_VOLTAGE_THRESHOLD_MV +#define SAFE_VDD_VOLTAGE_THRESHOLD_MV 2900 +#endif +#ifndef SAFE_VDD_VOLTAGE_THRESHOLD_HYST_MV +#define SAFE_VDD_VOLTAGE_THRESHOLD_HYST_MV 100 +#endif #ifndef SAFE_VDD_VOLTAGE_THRESHOLD -#define SAFE_VDD_VOLTAGE_THRESHOLD 2.9 +#define SAFE_VDD_VOLTAGE_THRESHOLD (SAFE_VDD_VOLTAGE_THRESHOLD_MV / 1000.0f) #endif - #ifndef SAFE_VDD_VOLTAGE_THRESHOLD_HYST -#define SAFE_VDD_VOLTAGE_THRESHOLD_HYST 0.1 +#define SAFE_VDD_VOLTAGE_THRESHOLD_HYST (SAFE_VDD_VOLTAGE_THRESHOLD_HYST_MV / 1000.0f) #endif #define RAK_4631 1