Fix rak_wismeshtag low‑voltage reboot hang after App configuration (#9897)
* Fix TAG low‑voltage reboot hang after App configuration * nRF52: Move low-VDD System OFF logic to variant hook * Addressed review * serialize SAADC access with shared mutex for VDD and battery reads * raise LPCOMP wake threshold to ensure rising-edge wake * Trunk fmt --------- Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
co-authored by
GitHub
Ben Meadors
parent
33e7f16c05
commit
c36ae159ed
@@ -19,7 +19,11 @@
|
||||
*/
|
||||
|
||||
#include "variant.h"
|
||||
#include "Arduino.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "nrf.h"
|
||||
#include "power/PowerHAL.h"
|
||||
#include "sleep.h"
|
||||
#include "wiring_constants.h"
|
||||
#include "wiring_digital.h"
|
||||
|
||||
@@ -40,3 +44,39 @@ void initVariant()
|
||||
pinMode(PIN_3V3_EN, OUTPUT);
|
||||
digitalWrite(PIN_3V3_EN, HIGH);
|
||||
}
|
||||
|
||||
#ifdef LOW_VDD_SYSTEMOFF_DELAY_MS
|
||||
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 (!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_timer_armed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -225,7 +225,41 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
|
||||
#define AREF_VOLTAGE 3.0
|
||||
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
|
||||
#define ADC_MULTIPLIER 1.73
|
||||
#define OCV_ARRAY 4240, 4112, 4029, 3970, 3906, 3846, 3824, 3802, 3776, 3650, 3072
|
||||
#define OCV_ARRAY 4160, 4020, 3940, 3870, 3810, 3760, 3740, 3720, 3680, 3620, 2990 // updated OCV array for rak_wismeshtag
|
||||
|
||||
// Wake from System OFF when battery rises again (LPCOMP).
|
||||
// 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
|
||||
// LPCOMP compares the selected input to a fraction of VDD (here 5/8 of VDD at the LPCOMP input).
|
||||
// With VDD ≈ 3.3 V: threshold at input ≈ (5/8) * 3.3 V ≈ 2.06 V.
|
||||
// BAT_ADC divider: V_BAT_ADC = 0.6 * VBAT → equivalent VBAT ≈ 2.06 / 0.6 ≈ 3.4 V (wake when battery recovers).
|
||||
//
|
||||
// Note: if VDD is drooping/tracking VBAT in the low-voltage region, using a fraction >= divider ratio helps ensure the
|
||||
// input is below the threshold at shutdown; the intended wake event happens when the supply recovers enough for a rising
|
||||
// crossing to occur.
|
||||
#define BATTERY_LPCOMP_THRESHOLD NRF_LPCOMP_REF_SUPPLY_5_8
|
||||
|
||||
// Low voltage protection:
|
||||
// If VDD is below SAFE_VDD_VOLTAGE_THRESHOLD for longer than this delay (and no USB VBUS),
|
||||
// the device will enter System OFF to avoid brownout loops and flash corruption.
|
||||
#ifndef LOW_VDD_SYSTEMOFF_DELAY_MS
|
||||
#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 (SAFE_VDD_VOLTAGE_THRESHOLD_MV / 1000.0f)
|
||||
#endif
|
||||
#ifndef SAFE_VDD_VOLTAGE_THRESHOLD_HYST
|
||||
#define SAFE_VDD_VOLTAGE_THRESHOLD_HYST (SAFE_VDD_VOLTAGE_THRESHOLD_HYST_MV / 1000.0f)
|
||||
#endif
|
||||
|
||||
#define RAK_4631 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user