Upgrade public source code to version 1.0.1332. New boards support

This commit is contained in:
Dmitry
2025-11-14 17:33:20 -05:00
parent 668a86f291
commit af5732e71b
26 changed files with 832 additions and 140 deletions

View File

@@ -1,7 +1,7 @@
#include "power.h"
#include "utils.h"
#ifdef HAS_AXP20X
#if defined(HAS_AXP20X) || defined(USE_XPOWERSLIB)
bool pmu_irq = false;
#endif
bool Power::setup()
@@ -9,6 +9,103 @@ bool Power::setup()
#ifdef HAS_AXP20X
axp192Init();
#endif
#ifdef USE_XPOWERSLIB
#ifdef PMU_USE_WIRE1
TwoWire &wire = Wire1;
#else
TwoWire &wire = Wire;
#endif
m_power = new XPowersPMU(wire);
m_pmuFound = m_power->init();
if(m_pmuFound)
{
DEBUG_MSG("PMU Found\n");
m_power->setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
/**
* gnss module power channel
* The default ALDO4 is off, you need to turn on the GNSS power first, otherwise it will be invalid during
* initialization
*/
m_power->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
m_power->enablePowerOutput(XPOWERS_ALDO4);
// lora radio power channel
m_power->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
m_power->enablePowerOutput(XPOWERS_ALDO3);
// m.2 interface
m_power->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
m_power->enablePowerOutput(XPOWERS_DCDC3);
/**
* ALDO2 cannot be turned off.
* It is a necessary condition for sensor communication.
* It must be turned on to properly access the sensor and screen
* It is also responsible for the power supply of PCF8563
*/
m_power->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
m_power->enablePowerOutput(XPOWERS_ALDO2);
// 6-axis , magnetometer ,bme280 , oled screen power channel
m_power->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
m_power->enablePowerOutput(XPOWERS_ALDO1);
// sdcard power channel
m_power->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
m_power->enablePowerOutput(XPOWERS_BLDO1);
// not use channel
m_power->disablePowerOutput(XPOWERS_DCDC2); // not elicited
m_power->disablePowerOutput(XPOWERS_DCDC5); // not elicited
m_power->disablePowerOutput(XPOWERS_DLDO1); // Invalid power channel, it does not exist
m_power->disablePowerOutput(XPOWERS_DLDO2); // Invalid power channel, it does not exist
m_power->disablePowerOutput(XPOWERS_VBACKUP);
m_power->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
m_power->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_1000MA);
m_power->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
m_power->clearIrqStatus();
// TBeam1.1 /T-Beam S3-Core has no external TS detection,
// it needs to be disabled, otherwise it will cause abnormal charging
m_power->disableTSPinMeasure();
// PMU->enableSystemVoltageMeasure();
m_power->enableVbusVoltageMeasure();
m_power->enableBattVoltageMeasure();
m_power->setPowerKeyPressOnTime(XPOWERS_POWERON_1S);
m_power->setPowerKeyPressOffTime(XPOWERS_POWEROFF_6S);
}
else
{
DEBUG_MSG("PMU NOT Found\n");
}
#ifdef PMU_IRQ
uint64_t pmuIrqMask = 0;
if (m_power->getChipModel() == XPOWERS_AXP192) {
pmuIrqMask = XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_PKEY_SHORT_IRQ | XPOWERS_AXP192_PKEY_LONG_IRQ;
} else if (m_power->getChipModel() == XPOWERS_AXP2101) {
pmuIrqMask = XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ;
}
pinMode(PMU_IRQ, INPUT);
attachInterrupt(
PMU_IRQ, [] { pmu_irq = true; }, FALLING);
// we do not look for AXPXXX_CHARGING_FINISHED_IRQ & AXPXXX_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 AXPXXX_BATT_REMOVED_IRQ because it occurs repeatedly while no battery installed
// we don't look at AXPXXX_VBUS_REMOVED_IRQ because we don't have anything hooked to vbus
m_power->enableIRQ(pmuIrqMask);
m_power->clearIrqStatus();
#endif
#endif
concurrency::PeriodicTask::setup(); // We don't start our periodic task unless we actually found the device
setPeriod(1);
@@ -16,12 +113,22 @@ bool Power::setup()
}
#ifdef BATTERY_PIN
static float read_battery() {
#ifdef ADC_CTRL
digitalWrite(ADC_CTRL, HIGH);
delay(2);
#endif
uint16_t v = analogRead(BATTERY_PIN);
//float battery_voltage = (float)v/4095*2*3.3*1.1;
float battery_voltage = (float)v*0.00246*1.19;
float battery_voltage = (float)v*BATTERY_M;
#ifdef ADC_CTRL
digitalWrite(ADC_CTRL, LOW);
#endif
return battery_voltage;
}
#else
static float read_battery() {
return 0;
}
#endif
/// Reads power status to powerStatus singleton.
@@ -59,6 +166,36 @@ void Power::readPowerStatus()
{
//powerFSM.trigger(EVENT_LOW_BATTERY);
}
#elif defined(USE_XPOWERSLIB)
bool hasBattery = m_power->isBatteryConnect();
int batteryVoltageMv = 0;
uint8_t batteryChargePercent = 0;
if (hasBattery)
{
batteryVoltageMv = m_power->getBattVoltage();
// If the AXP192 returns a valid battery percentage, use it
if (m_power->getBatteryPercent() >= 0)
{
batteryChargePercent = m_power->getBatteryPercent();
}
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);
}
}
// Notify any status instances that are observing us
const PowerStatus powerStatus = PowerStatus(hasBattery, m_power->isVbusIn(), m_power->isCharging(), batteryVoltageMv, batteryChargePercent);
newStatus.notifyObservers(&powerStatus);
// If we have a battery at all and it is less than 10% full, force deep sleep
if (powerStatus.getHasBattery() && !powerStatus.getHasUSB() &&
m_power->getBattVoltage() < MIN_BAT_MILLIVOLTS)
{
//powerFSM.trigger(EVENT_LOW_BATTERY);
}
#else
int batteryVoltageMv = read_battery()*1000;
uint8_t batteryChargePercent = clamp((int)(((batteryVoltageMv - BAT_MILLIVOLTS_EMPTY) * 1e2) / (BAT_MILLIVOLTS_FULL - BAT_MILLIVOLTS_EMPTY)), 0, 100);
@@ -78,6 +215,10 @@ void Power::doTask()
void Power::gpsOff()
{
#ifdef USE_XPOWERSLIB
m_power->disablePowerOutput(XPOWERS_ALDO4);
#endif
#ifdef HAS_AXP20X
axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF);
#endif
@@ -85,6 +226,9 @@ void Power::gpsOff()
void Power::shutdown()
{
#ifdef USE_XPOWERSLIB
m_power->shutdown();
#endif
#ifdef HAS_AXP20X
axp.shutdown();
#endif
@@ -92,6 +236,9 @@ void Power::shutdown()
void Power::gpsOn()
{
#ifdef USE_XPOWERSLIB
m_power->enablePowerOutput(XPOWERS_ALDO4);
#endif
#ifdef HAS_AXP20X
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON);
#endif
@@ -232,7 +379,55 @@ int Power::loop()
}
#endif
#else
// readPowerStatus();
#ifdef USE_XPOWERSLIB
#ifdef PMU_IRQ
if (pmu_irq)
{
pmu_irq = false;
m_power->getIrqStatus();
DEBUG_MSG("pmu irq!\n");
if (m_power->isBatChargeStartIrq())
{
DEBUG_MSG("Battery start charging\n");
}
if (m_power->isBatChargeDoneIrq())
{
DEBUG_MSG("Battery fully charged\n");
}
if (m_power->isVbusRemoveIrq())
{
DEBUG_MSG("USB unplugged\n");
}
if (m_power->isBatInsertIrq())
{
DEBUG_MSG("USB plugged In\n");
}
if (m_power->isBatInsertIrq())
{
DEBUG_MSG("Battery inserted\n");
}
if (m_power->isBatRemoveIrq())
{
DEBUG_MSG("Battery removed\n");
}
if (m_power->isPekeyShortPressIrq())
{
DEBUG_MSG("PEK short button press\n");
result |= 1;
}
if (m_power->isPekeyLongPressIrq())
{
DEBUG_MSG("PEK long button press\n");
result |= 2;
}
readPowerStatus();
m_power->clearIrqStatus();
}
#endif
#endif
#endif
return result;
}