Browse Source

Fix RAK4631 boot issue

Wait 50ms after boot before actually shutting down on low voltage

Also fix deadlock issue where only USB can wake the device
pull/1914/head
Wessel Nieboer 3 months ago
parent
commit
2492397613
No known key found for this signature in database GPG Key ID: 929C8E45E33B5FD2
  1. 25
      src/helpers/NRF52Board.cpp
  2. 2
      src/helpers/NRF52Board.h
  3. 4
      variants/heltec_t114/T114Board.cpp
  4. 4
      variants/rak4631/RAK4631Board.cpp
  5. 4
      variants/xiao_nrf52/XiaoNrf52Board.cpp

25
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,6 +236,8 @@ void NRF52Board::configureVoltageWake(uint8_t ain_channel, uint8_t refsel) {
}
MESH_DEBUG_PRINTLN("PWRMGT: VBUS wake configured");
return true;
}
#endif

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);

4
variants/rak4631/RAK4631Board.cpp

@ -18,7 +18,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);

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