2020-06-29 02:03:39 +00:00
|
|
|
#include "power.h"
|
2021-01-17 07:10:08 +00:00
|
|
|
#include "NodeDB.h"
|
2020-06-28 04:19:49 +00:00
|
|
|
#include "PowerFSM.h"
|
|
|
|
#include "main.h"
|
|
|
|
#include "sleep.h"
|
2020-08-13 00:03:36 +00:00
|
|
|
#include "utils.h"
|
2020-06-28 04:19:49 +00:00
|
|
|
|
2021-03-15 02:00:20 +00:00
|
|
|
#ifdef TBEAM_V10
|
2020-06-28 04:19:49 +00:00
|
|
|
// FIXME. nasty hack cleanup how we load axp192
|
|
|
|
#undef AXP192_SLAVE_ADDRESS
|
|
|
|
#include "axp20x.h"
|
2020-08-13 00:03:36 +00:00
|
|
|
|
2020-06-28 04:19:49 +00:00
|
|
|
AXP20X_Class axp;
|
2021-03-15 02:00:20 +00:00
|
|
|
#else
|
|
|
|
// Copy of the base class defined in axp20x.h.
|
|
|
|
// I'd rather not inlude axp20x.h as it brings Wire dependency.
|
|
|
|
class HasBatteryLevel {
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Battery state of charge, from 0 to 100 or -1 for unknown
|
|
|
|
*/
|
|
|
|
virtual int getBattPercentage() { return -1; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The raw voltage of the battery or NAN if unknown
|
|
|
|
*/
|
|
|
|
virtual float getBattVoltage() { return NAN; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* return true if there is a battery installed in this unit
|
|
|
|
*/
|
|
|
|
virtual bool isBatteryConnect() { return false; }
|
|
|
|
|
|
|
|
virtual bool isVBUSPlug() { return false; }
|
2021-03-15 02:17:28 +00:00
|
|
|
virtual bool isChargeing() { return false; }
|
2021-03-15 02:00:20 +00:00
|
|
|
};
|
2020-08-13 00:03:36 +00:00
|
|
|
#endif
|
|
|
|
|
2020-06-28 04:19:49 +00:00
|
|
|
bool pmu_irq = false;
|
|
|
|
|
|
|
|
Power *power;
|
|
|
|
|
2020-08-25 19:48:47 +00:00
|
|
|
using namespace meshtastic;
|
|
|
|
|
2020-10-16 09:00:27 +00:00
|
|
|
#if defined(NRF52_SERIES)
|
|
|
|
/*
|
|
|
|
* Internal Reference is +/-0.6V, with an adjustable gain of 1/6, 1/5, 1/4,
|
|
|
|
* 1/3, 1/2 or 1, meaning 3.6, 3.0, 2.4, 1.8, 1.2 or 0.6V for the ADC levels.
|
|
|
|
*
|
|
|
|
* External Reference is VDD/4, with an adjustable gain of 1, 2 or 4, meaning
|
|
|
|
* VDD/4, VDD/2 or VDD for the ADC levels.
|
|
|
|
*
|
|
|
|
* Default settings are internal reference with 1/6 gain (GND..3.6V ADC range)
|
|
|
|
*/
|
|
|
|
#define AREF_VOLTAGE 3.6
|
|
|
|
#else
|
|
|
|
#define AREF_VOLTAGE 3.3
|
|
|
|
#endif
|
|
|
|
|
2020-08-13 00:03:36 +00:00
|
|
|
/**
|
|
|
|
* If this board has a battery level sensor, set this to a valid implementation
|
|
|
|
*/
|
|
|
|
static HasBatteryLevel *batteryLevel; // Default to NULL for no battery level sensor
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A simple battery level sensor that assumes the battery voltage is attached via a voltage-divider to an analog input
|
|
|
|
*/
|
|
|
|
class AnalogBatteryLevel : public HasBatteryLevel
|
2020-06-28 04:19:49 +00:00
|
|
|
{
|
2020-08-13 00:03:36 +00:00
|
|
|
/**
|
|
|
|
* Battery state of charge, from 0 to 100 or -1 for unknown
|
|
|
|
*
|
|
|
|
* FIXME - use a lipo lookup table, the current % full is super wrong
|
|
|
|
*/
|
|
|
|
virtual int getBattPercentage()
|
|
|
|
{
|
2021-03-15 02:00:20 +00:00
|
|
|
float v = getBattVoltage();
|
2020-08-13 00:03:36 +00:00
|
|
|
|
2020-10-18 01:44:29 +00:00
|
|
|
if (v < noBatVolt)
|
2020-08-27 21:46:59 +00:00
|
|
|
return -1; // If voltage is super low assume no battery installed
|
2020-08-13 00:03:36 +00:00
|
|
|
|
2020-10-18 01:44:29 +00:00
|
|
|
if (v > chargingVolt)
|
|
|
|
return 0; // While charging we can't report % full on the battery
|
|
|
|
|
|
|
|
return 100 * (v - emptyVolt) / (fullVolt - emptyVolt);
|
2020-08-13 00:03:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-08-13 18:23:27 +00:00
|
|
|
* The raw voltage of the batteryin millivolts or NAN if unknown
|
2020-08-13 00:03:36 +00:00
|
|
|
*/
|
|
|
|
virtual float getBattVoltage()
|
|
|
|
{
|
2021-03-15 02:00:20 +00:00
|
|
|
|
|
|
|
#ifndef ADC_MULTIPLIER
|
|
|
|
#define ADC_MULTIPLIER 2.0
|
|
|
|
#endif
|
|
|
|
|
2020-08-13 00:03:36 +00:00
|
|
|
#ifdef BATTERY_PIN
|
2021-03-15 02:00:20 +00:00
|
|
|
// Do not call analogRead() often.
|
|
|
|
const uint32_t min_read_interval = 5000;
|
|
|
|
if (millis() - last_read_time_ms > min_read_interval) {
|
|
|
|
last_read_time_ms = millis();
|
|
|
|
uint32_t raw = analogRead(BATTERY_PIN);
|
|
|
|
float scaled = 1000.0 * ADC_MULTIPLIER * (AREF_VOLTAGE / 1024.0) * raw;
|
|
|
|
// DEBUG_MSG("raw val=%u scaled=%u\n", raw, (uint32_t)(scaled));
|
|
|
|
last_read_value = scaled;
|
|
|
|
return scaled;
|
|
|
|
} else {
|
|
|
|
return last_read_value;
|
|
|
|
}
|
2020-08-13 00:03:36 +00:00
|
|
|
#else
|
2021-03-15 02:00:20 +00:00
|
|
|
return NAN;
|
2020-08-13 00:03:36 +00:00
|
|
|
#endif
|
|
|
|
}
|
2020-06-28 04:19:49 +00:00
|
|
|
|
2020-08-13 00:03:36 +00:00
|
|
|
/**
|
|
|
|
* return true if there is a battery installed in this unit
|
|
|
|
*/
|
2020-10-18 01:44:29 +00:00
|
|
|
virtual bool isBatteryConnect() { return getBattPercentage() != -1; }
|
|
|
|
|
|
|
|
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
|
|
|
/// in power
|
|
|
|
virtual bool isVBUSPlug() { return getBattVoltage() > chargingVolt; }
|
|
|
|
|
|
|
|
/// Assume charging if we have a battery and external power is connected.
|
|
|
|
/// we can't be smart enough to say 'full'?
|
2021-03-15 02:17:28 +00:00
|
|
|
virtual bool isChargeing() { return isBatteryConnect() && isVBUSPlug(); }
|
2020-10-18 01:44:29 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
|
|
|
/// in power
|
2021-03-15 02:00:20 +00:00
|
|
|
const float fullVolt = 4200, emptyVolt = 3270, chargingVolt = 4210, noBatVolt = 2100;
|
|
|
|
float last_read_value = 0.0;
|
|
|
|
uint32_t last_read_time_ms = 0;
|
2020-08-13 00:03:36 +00:00
|
|
|
} analogLevel;
|
2020-06-28 04:19:49 +00:00
|
|
|
|
2020-10-09 06:16:51 +00:00
|
|
|
Power::Power() : OSThread("Power") {}
|
|
|
|
|
2020-08-13 00:03:36 +00:00
|
|
|
bool Power::analogInit()
|
|
|
|
{
|
|
|
|
#ifdef BATTERY_PIN
|
|
|
|
DEBUG_MSG("Using analog input for battery level\n");
|
2020-10-16 09:00:27 +00:00
|
|
|
|
|
|
|
// disable any internal pullups
|
|
|
|
pinMode(BATTERY_PIN, INPUT);
|
|
|
|
|
2020-09-27 01:13:16 +00:00
|
|
|
#ifndef NO_ESP32
|
|
|
|
// ESP32 needs special analog stuff
|
2020-08-13 00:03:36 +00:00
|
|
|
adcAttachPin(BATTERY_PIN);
|
2020-09-27 01:13:16 +00:00
|
|
|
#endif
|
2020-10-16 09:00:27 +00:00
|
|
|
#ifdef NRF52_SERIES
|
|
|
|
analogReference(AR_INTERNAL); // 3.6V
|
|
|
|
#endif
|
|
|
|
|
2020-08-13 00:03:36 +00:00
|
|
|
// adcStart(BATTERY_PIN);
|
|
|
|
analogReadResolution(10); // Default of 12 is not very linear. Recommended to use 10 or 11 depending on needed resolution.
|
|
|
|
batteryLevel = &analogLevel;
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Power::setup()
|
|
|
|
{
|
|
|
|
bool found = axp192Init();
|
|
|
|
|
|
|
|
if (!found) {
|
|
|
|
found = analogInit();
|
|
|
|
}
|
2020-10-09 06:16:51 +00:00
|
|
|
enabled = found;
|
2020-08-13 00:03:36 +00:00
|
|
|
|
|
|
|
return found;
|
2020-06-28 04:19:49 +00:00
|
|
|
}
|
|
|
|
|
2020-11-23 03:01:48 +00:00
|
|
|
void Power::shutdown()
|
|
|
|
{
|
2020-11-23 03:12:11 +00:00
|
|
|
#ifdef TBEAM_V10
|
2020-11-23 02:50:14 +00:00
|
|
|
DEBUG_MSG("Shutting down\n");
|
|
|
|
axp.shutdown();
|
2021-03-15 02:00:20 +00:00
|
|
|
#elif NRF52_SERIES
|
|
|
|
doDeepSleep(DELAY_FOREVER);
|
2020-11-23 03:01:48 +00:00
|
|
|
#endif
|
2020-11-23 02:50:14 +00:00
|
|
|
}
|
|
|
|
|
2020-06-28 04:19:49 +00:00
|
|
|
/// Reads power status to powerStatus singleton.
|
|
|
|
//
|
|
|
|
// TODO(girts): move this and other axp stuff to power.h/power.cpp.
|
|
|
|
void Power::readPowerStatus()
|
|
|
|
{
|
2020-08-13 00:03:36 +00:00
|
|
|
if (batteryLevel) {
|
|
|
|
bool hasBattery = batteryLevel->isBatteryConnect();
|
|
|
|
int batteryVoltageMv = 0;
|
2020-08-25 19:48:47 +00:00
|
|
|
int8_t batteryChargePercent = 0;
|
2020-08-13 00:03:36 +00:00
|
|
|
if (hasBattery) {
|
|
|
|
batteryVoltageMv = batteryLevel->getBattVoltage();
|
|
|
|
// If the AXP192 returns a valid battery percentage, use it
|
|
|
|
if (batteryLevel->getBattPercentage() >= 0) {
|
|
|
|
batteryChargePercent = batteryLevel->getBattPercentage();
|
|
|
|
} else {
|
|
|
|
// If the AXP192 returns a percentage less than 0, the feature is either not supported or there is an error
|
|
|
|
// In that case, we compute an estimate of the charge percent based on maximum and minimum voltages defined in
|
|
|
|
// power.h
|
|
|
|
batteryChargePercent =
|
|
|
|
clamp((int)(((batteryVoltageMv - BAT_MILLIVOLTS_EMPTY) * 1e2) / (BAT_MILLIVOLTS_FULL - BAT_MILLIVOLTS_EMPTY)),
|
|
|
|
0, 100);
|
|
|
|
}
|
2020-06-28 04:19:49 +00:00
|
|
|
}
|
2020-06-29 01:17:52 +00:00
|
|
|
|
2020-08-13 00:03:36 +00:00
|
|
|
// Notify any status instances that are observing us
|
2020-08-25 19:48:47 +00:00
|
|
|
const PowerStatus powerStatus =
|
|
|
|
PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVBUSPlug() ? OptTrue : OptFalse,
|
2021-03-15 02:17:28 +00:00
|
|
|
batteryLevel->isChargeing() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent);
|
2020-10-18 01:44:29 +00:00
|
|
|
DEBUG_MSG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus.getHasUSB(),
|
2020-10-18 01:32:12 +00:00
|
|
|
powerStatus.getIsCharging(), powerStatus.getBatteryVoltageMv(), powerStatus.getBatteryChargePercent());
|
2020-08-13 00:03:36 +00:00
|
|
|
newStatus.notifyObservers(&powerStatus);
|
2020-06-28 04:19:49 +00:00
|
|
|
|
2020-08-13 00:03:36 +00:00
|
|
|
// If we have a battery at all and it is less than 10% full, force deep sleep
|
|
|
|
if (powerStatus.getHasBattery() && !powerStatus.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS)
|
|
|
|
powerFSM.trigger(EVENT_LOW_BATTERY);
|
2020-08-25 19:48:47 +00:00
|
|
|
} else {
|
|
|
|
// No power sensing on this board - tell everyone else we have no idea what is happening
|
|
|
|
const PowerStatus powerStatus = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1);
|
|
|
|
newStatus.notifyObservers(&powerStatus);
|
2020-08-13 00:03:36 +00:00
|
|
|
}
|
2020-06-28 04:19:49 +00:00
|
|
|
}
|
|
|
|
|
2020-10-10 01:57:57 +00:00
|
|
|
int32_t Power::runOnce()
|
2020-06-28 04:19:49 +00:00
|
|
|
{
|
|
|
|
readPowerStatus();
|
2020-08-13 00:03:36 +00:00
|
|
|
|
2020-10-12 01:33:15 +00:00
|
|
|
#ifdef TBEAM_V10
|
2020-10-12 01:27:07 +00:00
|
|
|
// WE no longer use the IRQ line to wake the CPU (due to false wakes from sleep), but we do poll
|
|
|
|
// the IRQ status by reading the registers over I2C
|
|
|
|
axp.readIRQ();
|
2020-10-09 06:16:51 +00:00
|
|
|
|
2020-10-12 01:27:07 +00:00
|
|
|
if (axp.isVbusRemoveIRQ()) {
|
|
|
|
DEBUG_MSG("USB unplugged\n");
|
|
|
|
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
|
|
|
}
|
|
|
|
if (axp.isVbusPlugInIRQ()) {
|
|
|
|
DEBUG_MSG("USB plugged In\n");
|
|
|
|
powerFSM.trigger(EVENT_POWER_CONNECTED);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
Other things we could check if we cared...
|
2020-10-09 06:16:51 +00:00
|
|
|
|
2020-10-12 01:27:07 +00:00
|
|
|
if (axp.isChargingIRQ()) {
|
|
|
|
DEBUG_MSG("Battery start charging\n");
|
2020-10-09 06:16:51 +00:00
|
|
|
}
|
2020-10-12 01:27:07 +00:00
|
|
|
if (axp.isChargingDoneIRQ()) {
|
|
|
|
DEBUG_MSG("Battery fully charged\n");
|
|
|
|
}
|
|
|
|
if (axp.isBattPlugInIRQ()) {
|
|
|
|
DEBUG_MSG("Battery inserted\n");
|
|
|
|
}
|
|
|
|
if (axp.isBattRemoveIRQ()) {
|
|
|
|
DEBUG_MSG("Battery removed\n");
|
|
|
|
}
|
|
|
|
if (axp.isPEKShortPressIRQ()) {
|
|
|
|
DEBUG_MSG("PEK short button press\n");
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
axp.clearIRQ();
|
2020-10-12 01:33:15 +00:00
|
|
|
#endif
|
2020-10-09 06:16:51 +00:00
|
|
|
|
2020-06-28 04:19:49 +00:00
|
|
|
// Only read once every 20 seconds once the power status for the app has been initialized
|
2020-10-10 01:57:57 +00:00
|
|
|
return (statusHandler && statusHandler->isInitialized()) ? (1000 * 20) : RUN_SAME;
|
2020-06-28 04:19:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Init the power manager chip
|
|
|
|
*
|
|
|
|
* axp192 power
|
|
|
|
DCDC1 0.7-3.5V @ 1200mA max -> OLED // If you turn this off you'll lose comms to the axp192 because the OLED and the axp192
|
|
|
|
share the same i2c bus, instead use ssd1306 sleep mode DCDC2 -> unused DCDC3 0.7-3.5V @ 700mA max -> ESP32 (keep this on!) LDO1
|
|
|
|
30mA -> charges GPS backup battery // charges the tiny J13 battery by the GPS to power the GPS ram (for a couple of days), can
|
|
|
|
not be turned off LDO2 200mA -> LORA LDO3 200mA -> GPS
|
|
|
|
*/
|
2020-08-13 00:03:36 +00:00
|
|
|
bool Power::axp192Init()
|
2020-06-28 04:19:49 +00:00
|
|
|
{
|
2020-08-13 00:03:36 +00:00
|
|
|
#ifdef TBEAM_V10
|
2020-06-28 04:19:49 +00:00
|
|
|
if (axp192_found) {
|
|
|
|
if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) {
|
2020-08-13 00:03:36 +00:00
|
|
|
batteryLevel = &axp;
|
|
|
|
|
2020-06-28 04:19:49 +00:00
|
|
|
DEBUG_MSG("AXP192 Begin PASS\n");
|
|
|
|
|
|
|
|
// axp.setChgLEDMode(LED_BLINK_4HZ);
|
|
|
|
DEBUG_MSG("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("----------------------------------------\n");
|
|
|
|
|
|
|
|
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); // LORA radio
|
2020-10-05 21:34:56 +00:00
|
|
|
// axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); // GPS main power - now turned on in setGpsPower
|
2020-06-28 04:19:49 +00:00
|
|
|
axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
|
|
|
|
axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
|
|
|
|
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
|
|
|
|
axp.setDCDC1Voltage(3300); // for the OLED power
|
|
|
|
|
|
|
|
DEBUG_MSG("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
|
|
|
|
DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
|
|
|
|
|
2021-01-17 07:10:08 +00:00
|
|
|
if (radioConfig.preferences.charge_current == ChargeCurrent_MAUnset) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_450MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA100) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_100MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA190) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_190MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA280) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_280MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA360) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_360MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA450) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_450MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA550) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_550MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA630) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_630MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA700) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_700MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA780) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_780MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA880) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_880MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA960) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_960MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1000) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1000MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1080) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1080MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1160) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1160MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1240) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1240MA);
|
|
|
|
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1320) {
|
|
|
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1320MA);
|
|
|
|
}
|
|
|
|
|
2020-06-28 04:19:49 +00:00
|
|
|
#if 0
|
|
|
|
|
|
|
|
// Not connected
|
|
|
|
//val = 0xfc;
|
|
|
|
//axp._writeByte(AXP202_VHTF_CHGSET, 1, &val); // Set temperature protection
|
|
|
|
|
|
|
|
//not used
|
|
|
|
//val = 0x46;
|
|
|
|
//axp._writeByte(AXP202_OFF_CTL, 1, &val); // enable bat detection
|
|
|
|
#endif
|
|
|
|
axp.debugCharging();
|
|
|
|
|
|
|
|
#ifdef PMU_IRQ
|
|
|
|
pinMode(PMU_IRQ, INPUT);
|
|
|
|
attachInterrupt(
|
|
|
|
PMU_IRQ, [] { pmu_irq = true; }, FALLING);
|
|
|
|
|
|
|
|
axp.adc1Enable(AXP202_BATT_CUR_ADC1, 1);
|
2020-10-06 04:45:19 +00:00
|
|
|
// we do not look for AXP202_CHARGING_FINISHED_IRQ & AXP202_CHARGING_IRQ because it occurs repeatedly while there is
|
|
|
|
// no battery also it could cause inadvertent waking from light sleep just because the battery filled
|
|
|
|
// we don't look for AXP202_BATT_REMOVED_IRQ because it occurs repeatedly while no battery installed
|
|
|
|
// we don't look at AXP202_VBUS_REMOVED_IRQ because we don't have anything hooked to vbus
|
2020-10-09 06:16:51 +00:00
|
|
|
axp.enableIRQ(AXP202_BATT_CONNECT_IRQ | AXP202_VBUS_CONNECT_IRQ | AXP202_PEK_SHORTPRESS_IRQ, 1);
|
2020-06-28 04:19:49 +00:00
|
|
|
|
|
|
|
axp.clearIRQ();
|
|
|
|
#endif
|
|
|
|
readPowerStatus();
|
|
|
|
} else {
|
|
|
|
DEBUG_MSG("AXP192 Begin FAIL\n");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
DEBUG_MSG("AXP192 not found\n");
|
|
|
|
}
|
2020-08-13 00:03:36 +00:00
|
|
|
|
|
|
|
return axp192_found;
|
|
|
|
#else
|
|
|
|
return false;
|
2020-06-28 04:19:49 +00:00
|
|
|
#endif
|
2020-08-13 00:03:36 +00:00
|
|
|
}
|