Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions src/Power.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ static HasBatteryLevel *batteryLevel; // Default to NULL for no battery level se

#ifdef BATTERY_PIN

static void adcEnable()
void battery_adcEnable()
{
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
#ifdef ADC_USE_PULLUP
Expand All @@ -214,7 +214,7 @@ static void adcEnable()
#endif
}

static void adcDisable()
static void battery_adcDisable()
{
#ifdef ADC_CTRL // disable adc voltage divider when we need to read
#ifdef ADC_USE_PULLUP
Expand Down Expand Up @@ -320,7 +320,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
uint32_t raw = 0;
float scaled = 0;

adcEnable();
battery_adcEnable();
#ifdef ARCH_ESP32 // ADC block for espressif platforms
raw = espAdcRead();
scaled = esp_adc_cal_raw_to_voltage(raw, adc_characs);
Expand All @@ -332,7 +332,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
raw = raw / BATTERY_SENSE_SAMPLES;
scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw;
#endif
adcDisable();
battery_adcDisable();

if (!initial_read_done) {
// Flush the smoothing filter with an ADC reading, if the reading is plausibly correct
Expand Down Expand Up @@ -903,13 +903,8 @@ void Power::readPowerStatus()
low_voltage_counter++;
LOG_DEBUG("Low voltage counter: %d/10", low_voltage_counter);
if (low_voltage_counter > 10) {
#ifdef ARCH_NRF52
// We can't trigger deep sleep on NRF52, it's freezing the board
LOG_DEBUG("Low voltage detected, but not trigger deep sleep");
#else
LOG_INFO("Low voltage detected, trigger deep sleep");
powerFSM.trigger(EVENT_LOW_BATTERY);
#endif
}
} else {
low_voltage_counter = 0;
Expand Down Expand Up @@ -1549,4 +1544,4 @@ bool Power::meshSolarInit()
{
return false;
}
#endif
#endif
22 changes: 21 additions & 1 deletion src/platform/nrf52/main-nrf52.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
#include "error.h"
#include "main.h"
#include "meshUtils.h"
#include "power.h"

#include <hal/nrf_lpcomp.h>

#ifdef BQ25703A_ADDR
#include "BQ25713.h"
Expand Down Expand Up @@ -389,6 +392,23 @@ void cpuDeepSleep(uint32_t msecToWake)
nrf_gpio_cfg_sense_set(BUTTON_PIN, sense); // Apply SENSE to wake up the device from the deep sleep
#endif

#ifdef BATTERY_LPCOMP_INPUT
// Wake up if power rises again
nrf_lpcomp_config_t c;
c.reference = BATTERY_LPCOMP_THRESHOLD;
c.detection = NRF_LPCOMP_DETECT_UP;
c.hyst = NRF_LPCOMP_HYST_NOHYST;
nrf_lpcomp_configure(NRF_LPCOMP, &c);
nrf_lpcomp_input_select(NRF_LPCOMP, BATTERY_LPCOMP_INPUT);
nrf_lpcomp_enable(NRF_LPCOMP);

battery_adcEnable();

nrf_lpcomp_task_trigger(NRF_LPCOMP, NRF_LPCOMP_TASK_START);
while (!nrf_lpcomp_event_check(NRF_LPCOMP, NRF_LPCOMP_EVENT_READY))
;
#endif

auto ok = sd_power_system_off();
if (ok != NRF_SUCCESS) {
LOG_ERROR("FIXME: Ignoring soft device (EasyDMA pending?) and forcing system-off!");
Expand Down Expand Up @@ -420,4 +440,4 @@ void enterDfuMode()
#else
enterUf2Dfu();
#endif
}
}
2 changes: 2 additions & 0 deletions src/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,6 @@ class Power : private concurrency::OSThread
#endif
};

void battery_adcEnable();

extern Power *power;
10 changes: 10 additions & 0 deletions variants/nrf52840/heltec_mesh_node_t114/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,16 @@ No longer populated on PCB
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
#define ADC_MULTIPLIER (4.916F)

// rf52840 AIN2 = Pin 4
#define BATTERY_LPCOMP_INPUT NRF_LPCOMP_INPUT_2

// We have AIN2 with a VBAT divider so AIN2 = VBAT * (100/490)
// We have the device going deep sleep under 3.1V, which is AIN2 = 0.63V
// So we can wake up when VBAT>=VDD is restored to 3.3V, where AIN2 = 0.67V
// Ratio 0.67/3.3 = 0.20, so we can pick a bit higher, 2/8 VDD, which means
// VBAT=4.04V
#define BATTERY_LPCOMP_THRESHOLD NRF_LPCOMP_REF_SUPPLY_2_8

#define HAS_RTC 0
#ifdef __cplusplus
}
Expand Down
14 changes: 14 additions & 0 deletions variants/nrf52840/rak4631/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,20 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
#define ADC_MULTIPLIER 1.73

// RAK4630 AIN0 = nrf52840 AIN3 = Pin 5
#define BATTERY_LPCOMP_INPUT NRF_LPCOMP_INPUT_3

// We have AIN3 with a VBAT divider so AIN3 = VBAT * (1.5/2.5)
// We have the device going deep sleep under 3.1V, which is AIN3 = 1.86V
// So we can wake up when VBAT>=VDD is restored to 3.3V, where AIN3 = 1.98V
// 1.98/3.3 = 6/10, but that's close to the VBAT divider, so we
// pick 6/8VDD, which means VBAT=4.1V.
// Reference:
// VDD=3.3V AIN3=5/8*VDD=2.06V VBAT=1.66*AIN3=3.41V
// VDD=3.3V AIN3=11/16*VDD=2.26V VBAT=1.66*AIN3=3.76V
// VDD=3.3V AIN3=6/8*VDD=2.47V VBAT=1.66*AIN3=4.1V
#define BATTERY_LPCOMP_THRESHOLD NRF_LPCOMP_REF_SUPPLY_11_16

#define HAS_RTC 1

#define HAS_ETHERNET 1
Expand Down