Browse Source

Merge 0f123d6d05 into 5f3b7f25d0

pull/1914/merge
Wessel 18 hours ago
committed by GitHub
parent
commit
4d96f65efe
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 33
      src/helpers/NRF52Board.cpp
  2. 2
      src/helpers/NRF52Board.h
  3. 4
      variants/heltec_t114/T114Board.cpp
  4. 38
      variants/rak4631/RAK4631Board.cpp
  5. 17
      variants/rak4631/platformio.ini
  6. 4
      variants/xiao_nrf52/XiaoNrf52Board.cpp

33
src/helpers/NRF52Board.cpp

@ -116,10 +116,17 @@ bool NRF52Board::checkBootVoltage(const PowerMgtConfig* config) {
// Only trigger shutdown if reading is valid (>1000mV) AND below threshold
// This prevents spurious shutdowns on ADC glitches or uninitialized reads
if (boot_voltage_mv > 1000 && boot_voltage_mv < config->voltage_bootlock) {
MESH_DEBUG_PRINTLN("PWRMGT: Boot voltage too low - entering protective shutdown");
// First reading below threshold - wait for DCDC to stabilize and re-read
delay(50);
boot_voltage_mv = getBattMilliVolts();
MESH_DEBUG_PRINTLN("PWRMGT: Boot voltage (confirmed) = %u mV (threshold = %u mV)",
boot_voltage_mv, config->voltage_bootlock);
initiateShutdown(SHUTDOWN_REASON_BOOT_PROTECT);
return false; // Should never reach this
if (boot_voltage_mv > 1000 && boot_voltage_mv < config->voltage_bootlock) {
MESH_DEBUG_PRINTLN("PWRMGT: Boot voltage too low - entering protective shutdown");
initiateShutdown(SHUTDOWN_REASON_BOOT_PROTECT);
return false; // Should never reach this
}
}
return true;
@ -163,7 +170,7 @@ void NRF52Board::enterSystemOff(uint8_t reason) {
NVIC_SystemReset();
}
void NRF52Board::configureVoltageWake(uint8_t ain_channel, uint8_t refsel) {
bool NRF52Board::configureVoltageWake(uint8_t ain_channel, uint8_t refsel) {
// LPCOMP is not managed by SoftDevice - direct register access required
// Halt and disable before reconfiguration
NRF_LPCOMP->TASKS_STOP = 1;
@ -199,6 +206,14 @@ void NRF52Board::configureVoltageWake(uint8_t ain_channel, uint8_t refsel) {
delayMicroseconds(50);
}
// Safety: if voltage is already above threshold, UP detection will never fire
if (NRF_LPCOMP->RESULT & LPCOMP_RESULT_RESULT_Msk) {
MESH_DEBUG_PRINTLN("PWRMGT: LPCOMP shows voltage above threshold - unsafe for SYSTEMOFF");
NRF_LPCOMP->TASKS_STOP = 1;
NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled;
return false;
}
if (refsel == 7) {
MESH_DEBUG_PRINTLN("PWRMGT: LPCOMP wake configured (AIN%d, ref=ARef)", ain_channel);
} else if (refsel <= 6) {
@ -221,19 +236,23 @@ void NRF52Board::configureVoltageWake(uint8_t ain_channel, uint8_t refsel) {
}
MESH_DEBUG_PRINTLN("PWRMGT: VBUS wake configured");
return true;
}
#endif
void NRF52BoardDCDC::begin() {
NRF52Board::begin();
// Enable DC/DC converter for improved power efficiency
// Enable DC/DC converter only when SoftDevice is managing the POWER peripheral.
// Without SoftDevice, NRF_POWER->DCDCEN = 1 leaves the DC/DC permanently on,
// which causes boot failures on some boards when running on battery alone.
// The SoftDevice manages DC/DC dynamically (on during radio, off during idle),
// which is the safe way to use it.
uint8_t sd_enabled = 0;
sd_softdevice_is_enabled(&sd_enabled);
if (sd_enabled) {
sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE);
} else {
NRF_POWER->DCDCEN = 1;
}
}

2
src/helpers/NRF52Board.h

@ -40,7 +40,7 @@ protected:
bool checkBootVoltage(const PowerMgtConfig* config);
void enterSystemOff(uint8_t reason);
void configureVoltageWake(uint8_t ain_channel, uint8_t refsel);
bool configureVoltageWake(uint8_t ain_channel, uint8_t refsel);
virtual void initiateShutdown(uint8_t reason);
#endif

4
variants/heltec_t114/T114Board.cpp

@ -25,7 +25,9 @@ void T114Board::initiateShutdown(uint8_t reason) {
digitalWrite(PIN_BAT_CTL, enable_lpcomp ? HIGH : LOW);
if (enable_lpcomp) {
configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel);
if (!configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel)) {
NVIC_SystemReset();
}
}
enterSystemOff(reason);

38
variants/rak4631/RAK4631Board.cpp

@ -3,6 +3,22 @@
#include "RAK4631Board.h"
#ifdef BOOT_DIAG
// Diagnostic LED blink: N short blinks on green LED to indicate boot stage
static void diag_blink(uint8_t count) {
pinMode(PIN_LED1, OUTPUT);
for (uint8_t i = 0; i < count; i++) {
digitalWrite(PIN_LED1, HIGH);
delay(100);
digitalWrite(PIN_LED1, LOW);
delay(150);
}
delay(300);
}
#else
#define diag_blink(n) ((void)0)
#endif
#ifdef NRF52_POWER_MANAGEMENT
// Static configuration for power management
// Values set in variant.h defines
@ -18,7 +34,9 @@ void RAK4631Board::initiateShutdown(uint8_t reason) {
if (reason == SHUTDOWN_REASON_LOW_VOLTAGE ||
reason == SHUTDOWN_REASON_BOOT_PROTECT) {
configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel);
if (!configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel)) {
NVIC_SystemReset();
}
}
enterSystemOff(reason);
@ -26,7 +44,16 @@ void RAK4631Board::initiateShutdown(uint8_t reason) {
#endif // NRF52_POWER_MANAGEMENT
void RAK4631Board::begin() {
diag_blink(1); // Stage 1: entering begin()
#ifdef DISABLE_DCDC
NRF52Board::begin();
#else
NRF52BoardDCDC::begin();
#endif
diag_blink(2); // Stage 2: board base init done
pinMode(PIN_VBAT_READ, INPUT);
#ifdef PIN_USER_BTN
pinMode(PIN_USER_BTN, INPUT_PULLUP);
@ -42,12 +69,19 @@ void RAK4631Board::begin() {
Wire.begin();
diag_blink(3); // Stage 3: I2C done, about to configure LoRa power
pinMode(SX126X_POWER_EN, OUTPUT);
#ifdef NRF52_POWER_MANAGEMENT
#if defined(NRF52_POWER_MANAGEMENT) && !defined(DISABLE_BOOT_PROTECTION)
// Boot voltage protection check (may not return if voltage too low)
// We need to call this after we configure SX126X_POWER_EN as output but before we pull high
checkBootVoltage(&power_config);
#endif
diag_blink(4); // Stage 4: power check passed
digitalWrite(SX126X_POWER_EN, HIGH);
delay(10); // give sx1262 some time to power up
diag_blink(5); // Stage 5: board.begin() complete
}

17
variants/rak4631/platformio.ini

@ -53,6 +53,23 @@ build_src_filter = ${rak4631.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<../examples/simple_repeater>
; Diagnostic build: LED blinks at boot stages + boot protection disabled
[env:RAK_4631_repeater_diag]
extends = env:RAK_4631_repeater
build_flags =
${env:RAK_4631_repeater.build_flags}
-D BOOT_DIAG
-D DISABLE_BOOT_PROTECTION
; Diagnostic build: LED blinks + boot protection disabled + DC/DC disabled
[env:RAK_4631_repeater_diag_no_dcdc]
extends = env:RAK_4631_repeater
build_flags =
${env:RAK_4631_repeater.build_flags}
-D BOOT_DIAG
-D DISABLE_BOOT_PROTECTION
-D DISABLE_DCDC
[env:RAK_4631_repeater_bridge_rs232_serial1]
extends = rak4631
build_flags =

4
variants/xiao_nrf52/XiaoNrf52Board.cpp

@ -22,7 +22,9 @@ void XiaoNrf52Board::initiateShutdown(uint8_t reason) {
digitalWrite(VBAT_ENABLE, enable_lpcomp ? LOW : HIGH);
if (enable_lpcomp) {
configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel);
if (!configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel)) {
NVIC_SystemReset();
}
}
enterSystemOff(reason);

Loading…
Cancel
Save