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 // Only trigger shutdown if reading is valid (>1000mV) AND below threshold
// This prevents spurious shutdowns on ADC glitches or uninitialized reads // This prevents spurious shutdowns on ADC glitches or uninitialized reads
if (boot_voltage_mv > 1000 && boot_voltage_mv < config->voltage_bootlock) { 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); if (boot_voltage_mv > 1000 && boot_voltage_mv < config->voltage_bootlock) {
return false; // Should never reach this MESH_DEBUG_PRINTLN("PWRMGT: Boot voltage too low - entering protective shutdown");
initiateShutdown(SHUTDOWN_REASON_BOOT_PROTECT);
return false; // Should never reach this
}
} }
return true; return true;
@ -163,7 +170,7 @@ void NRF52Board::enterSystemOff(uint8_t reason) {
NVIC_SystemReset(); 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 // LPCOMP is not managed by SoftDevice - direct register access required
// Halt and disable before reconfiguration // Halt and disable before reconfiguration
NRF_LPCOMP->TASKS_STOP = 1; NRF_LPCOMP->TASKS_STOP = 1;
@ -199,6 +206,14 @@ void NRF52Board::configureVoltageWake(uint8_t ain_channel, uint8_t refsel) {
delayMicroseconds(50); 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) { if (refsel == 7) {
MESH_DEBUG_PRINTLN("PWRMGT: LPCOMP wake configured (AIN%d, ref=ARef)", ain_channel); MESH_DEBUG_PRINTLN("PWRMGT: LPCOMP wake configured (AIN%d, ref=ARef)", ain_channel);
} else if (refsel <= 6) { } 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"); MESH_DEBUG_PRINTLN("PWRMGT: VBUS wake configured");
return true;
} }
#endif #endif

2
src/helpers/NRF52Board.h

@ -40,7 +40,7 @@ protected:
bool checkBootVoltage(const PowerMgtConfig* config); bool checkBootVoltage(const PowerMgtConfig* config);
void enterSystemOff(uint8_t reason); 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); virtual void initiateShutdown(uint8_t reason);
#endif #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); digitalWrite(PIN_BAT_CTL, enable_lpcomp ? HIGH : LOW);
if (enable_lpcomp) { 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); enterSystemOff(reason);

4
variants/rak4631/RAK4631Board.cpp

@ -18,7 +18,9 @@ void RAK4631Board::initiateShutdown(uint8_t reason) {
if (reason == SHUTDOWN_REASON_LOW_VOLTAGE || if (reason == SHUTDOWN_REASON_LOW_VOLTAGE ||
reason == SHUTDOWN_REASON_BOOT_PROTECT) { 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); 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); digitalWrite(VBAT_ENABLE, enable_lpcomp ? LOW : HIGH);
if (enable_lpcomp) { 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); enterSystemOff(reason);

Loading…
Cancel
Save