AXP PMU library changed

This commit is contained in:
cyberman54 2022-08-17 19:05:41 +02:00
parent eacf4a0d56
commit c7026ee7a4
3 changed files with 72 additions and 99 deletions

View File

@ -20,7 +20,7 @@
#ifndef PMU_CHG_CUTOFF #ifndef PMU_CHG_CUTOFF
#ifdef HAS_PMU #ifdef HAS_PMU
#define PMU_CHG_CUTOFF AXP202_TARGET_VOL_4_2V #define PMU_CHG_CUTOFF XPOWERS_CHG_VOL_4V2
#elif defined HAS_IP5306 #elif defined HAS_IP5306
#define PMU_CHG_CUTOFF 0 #define PMU_CHG_CUTOFF 0
#endif #endif
@ -28,7 +28,7 @@
#ifndef PMU_CHG_CURRENT #ifndef PMU_CHG_CURRENT
#ifdef HAS_PMU #ifdef HAS_PMU
#define PMU_CHG_CURRENT AXP1XX_CHARGE_CUR_450MA #define PMU_CHG_CURRENT XPOWERS_CHG_CUR_450MA
#elif defined HAS_IP5306 #elif defined HAS_IP5306
#define PMU_CHG_CURRENT 2 #define PMU_CHG_CURRENT 2
#endif #endif
@ -55,8 +55,8 @@ void calibrate_voltage(void);
bool batt_sufficient(void); bool batt_sufficient(void);
#ifdef HAS_PMU #ifdef HAS_PMU
#include <axp20x.h> #include "XPowersLib.h"
extern AXP20X_Class pmu; extern XPowersPMU pmu;
enum pmu_power_t { pmu_power_on, pmu_power_off, pmu_power_sleep }; enum pmu_power_t { pmu_power_on, pmu_power_off, pmu_power_sleep };
void AXP192_powerevent_IRQ(void); void AXP192_powerevent_IRQ(void);
void AXP192_power(pmu_power_t powerlevel); void AXP192_power(pmu_power_t powerlevel);

View File

@ -34,19 +34,14 @@ Reset -> reset device
// power management settings // power management settings
#define HAS_PMU 1 // has AXP192 chip #define HAS_PMU 1 // has AXP192 chip
#define XPOWERS_CHIP_AXP192 1
#define PMU_INT GPIO_NUM_35 // battery interrupt #define PMU_INT GPIO_NUM_35 // battery interrupt
#define PMU_CHG_CURRENT AXP1XX_CHARGE_CUR_1000MA // battery charge current #define PMU_CHG_CURRENT XPOWERS_CHG_CUR_1000MA // battery charge current
// possible values (mA): // possible values (mA):
// 100/190/280/360/450/550/630/700/780/880/960/1000/1080/1160/1240/1320 // 100/190/280/360/450/550/630/700/780/880/960/1000/1080/1160/1240/1320
#define PMU_CHG_CUTOFF AXP202_TARGET_VOL_4_2V // battery charge cutoff #define PMU_CHG_CUTOFF XPOWERS_CHG_VOL_4V2 // battery charge cutoff
// possible values (V): // possible values (V):
// 4_1/4_15/4_2/4_36 // 4V1/4V15/4V2/4V36
// blue onboard led settings
// possible values:
// AXP20X_LED_OFF / AXP20X_LED_LOW_LEVEL (means LED ON) / AXP20X_LED_BLINK_1HZ / AXP20X_LED_BLINK_4HZ
#define PMU_LED_RUN_MODE AXP20X_LED_LOW_LEVEL
#define PMU_LED_SLEEP_MODE AXP20X_LED_OFF
// GPS settings // GPS settings
#define HAS_GPS 1 // use on board GPS #define HAS_GPS 1 // use on board GPS

View File

@ -23,59 +23,44 @@ static const adc_unit_t unit = ADC_UNIT_1;
#endif // BAT_MEASURE_ADC #endif // BAT_MEASURE_ADC
#ifdef HAS_PMU #ifdef HAS_PMU
AXP20X_Class pmu; XPowersPMU pmu;
void AXP192_powerevent_IRQ(void) { void AXP192_powerevent_IRQ(void) {
pmu.readIRQ(); pmu.getIrqStatus();
if (pmu.isVbusOverVoltageIRQ()) if (pmu.isVbusOverVoltageIrq())
ESP_LOGI(TAG, "USB voltage %.2fV too high.", pmu.getVbusVoltage() / 1000); ESP_LOGI(TAG, "USB voltage %.2fV too high.", pmu.getVbusVoltage() / 1000);
if (pmu.isVbusPlugInIRQ()) if (pmu.isVbusInsertIrq())
ESP_LOGI(TAG, "USB plugged, %.2fV @ %.0mA", pmu.getVbusVoltage() / 1000, ESP_LOGI(TAG, "USB plugged, %.2fV @ %.0mA", pmu.getVbusVoltage() / 1000,
pmu.getVbusCurrent()); pmu.getVbusCurrent());
if (pmu.isVbusRemoveIRQ()) if (pmu.isVbusRemoveIrq())
ESP_LOGI(TAG, "USB unplugged."); ESP_LOGI(TAG, "USB unplugged.");
if (pmu.isBattPlugInIRQ()) if (pmu.isBatInsertIrq())
ESP_LOGI(TAG, "Battery is connected."); ESP_LOGI(TAG, "Battery is connected.");
if (pmu.isBattRemoveIRQ()) if (pmu.isBatRemoveIrq())
ESP_LOGI(TAG, "Battery was removed."); ESP_LOGI(TAG, "Battery was removed.");
if (pmu.isChargingIRQ()) if (pmu.isBatChagerStartIrq())
ESP_LOGI(TAG, "Battery charging."); ESP_LOGI(TAG, "Battery charging started.");
if (pmu.isChargingDoneIRQ()) { if (pmu.isBatChagerDoneIrq())
ESP_LOGI(TAG, "Battery charging done."); ESP_LOGI(TAG, "Battery charging done.");
#ifdef PMU_LED_RUN_MODE if (pmu.isBattTempLowIrq())
pmu.setChgLEDMode(PMU_LED_RUN_MODE);
#else
pmu.setChgLEDMode(AXP20X_LED_LOW_LEVEL);
#endif
}
if (pmu.isBattTempLowIRQ())
ESP_LOGI(TAG, "Battery high temperature."); ESP_LOGI(TAG, "Battery high temperature.");
if (pmu.isBattTempHighIRQ()) if (pmu.isBattTempHighIrq())
ESP_LOGI(TAG, "Battery low temperature."); ESP_LOGI(TAG, "Battery low temperature.");
if (pmu.isLowVoltageLevel1IRQ()) {
ESP_LOGI(TAG, "Battery has reached voltage level 1.");
pmu.setChgLEDMode(AXP20X_LED_BLINK_4HZ);
}
if (pmu.isLowVoltageLevel2IRQ()) {
ESP_LOGI(TAG, "Battery has reached voltage level 2.");
pmu.setChgLEDMode(AXP20X_LED_BLINK_1HZ);
}
#ifdef HAS_BUTTON #ifdef HAS_BUTTON
// short press -> esp32 deep sleep mode, can be exited by pressing user button // short press -> esp32 deep sleep mode, can be exited by pressing user button
if (pmu.isPEKShortPressIRQ()) { if (pmu.isPekeyShortPressIrq()) {
enter_deepsleep(0, HAS_BUTTON); enter_deepsleep(0, HAS_BUTTON);
} }
#endif #endif
// long press -> shutdown power, can be exited by another longpress // long press -> shutdown power, can be exited by another longpress
if (pmu.isPEKLongtPressIRQ()) { if (pmu.isPekeyLongPressIrq()) {
AXP192_power(pmu_power_off); // switch off Lora, GPS, display AXP192_power(pmu_power_off); // switch off Lora, GPS, display
} }
pmu.clearIRQ(); pmu.clearIrqStatus();
// refresh stored voltage value // refresh stored voltage value
read_battlevel(); read_battlevel();
@ -86,46 +71,37 @@ void AXP192_power(pmu_power_t powerlevel) {
case pmu_power_off: case pmu_power_off:
pmu.shutdown(); pmu.shutdown();
break; break;
case pmu_power_sleep: case pmu_power_sleep:
#ifdef PMU_LED_SLEEP_MODE pmu.setChargerLedFunction(XPOWER_CHGLED_CTRL_MANUAL);
pmu.setChgLEDMode(PMU_LED_SLEEP_MODE); pmu.setChargingLedFreq(XPOWERS_CHG_LED_FRE_1HZ);
#else
pmu.setChgLEDMode(AXP20X_LED_OFF);
#endif
// we don't cut off DCDC1, because OLED display will then block i2c bus // we don't cut off DCDC1, because OLED display will then block i2c bus
// pmu.setPowerOutPut(AXP192_DCDC1, AXP202_OFF); // OLED off // pmu.disableDC1(); // OLED off
pmu.setPowerOutPut(AXP192_LDO3, AXP202_OFF); // gps off pmu.disableLDO3(); // gps off
pmu.setPowerOutPut(AXP192_LDO2, AXP202_OFF); // lora off pmu.disableLDO2(); // lora off
pmu.enableSleep();
break; break;
case pmu_power_on: case pmu_power_on:
default: default:
pmu.setPowerOutPut(AXP192_LDO2, AXP202_ON); // Lora on T-Beam V1.0/1.1 pmu.enableLDO2(); // Lora on T-Beam V1.0/1.1
pmu.setPowerOutPut(AXP192_LDO3, AXP202_ON); // Gps on T-Beam V1.0/1.1 pmu.enableLDO3(); // Gps on T-Beam V1.0/1.1
pmu.setPowerOutPut(AXP192_DCDC1, AXP202_ON); // OLED on T-Beam v1.0/1.1 pmu.enableDC1(); // OLED on T-Beam v1.0/1.1
pmu.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); // unused on T-Beam v1.0/1.1 pmu.setChargerLedFunction(XPOWER_CHGLED_CTRL_MANUAL);
pmu.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); // unused on T-Beam v1.0/1.1 pmu.setChargingLedFreq(XPOWERS_CHG_LED_LEVEL_LOW);
#ifdef PMU_LED_RUN_MODE
pmu.setChgLEDMode(PMU_LED_RUN_MODE);
#else
pmu.setChgLEDMode(AXP20X_LED_LOW_LEVEL);
#endif
break; break;
} }
} }
void AXP192_showstatus(void) { void AXP192_showstatus(void) {
if (pmu.isBatteryConnect()) if (pmu.isBatteryConnect())
if (pmu.isChargeing()) if (pmu.isCharging())
ESP_LOGI(TAG, "Battery charging, %.2fV @ %.0fmAh", ESP_LOGI(TAG, "Battery charging, %.2fV @ %.0fmAh",
pmu.getBattVoltage() / 1000, pmu.getBattChargeCurrent()); pmu.getBattVoltage() / 1000, pmu.getBatteryChargeCurrent());
else else
ESP_LOGI(TAG, "Battery not charging"); ESP_LOGI(TAG, "Battery not charging");
else else
ESP_LOGI(TAG, "No Battery"); ESP_LOGI(TAG, "No Battery");
if (pmu.isVBUSPlug()) if (pmu.isVbusIn())
ESP_LOGI(TAG, "USB powered, %.0fmW", ESP_LOGI(TAG, "USB powered, %.0fmW",
pmu.getVbusVoltage() / 1000 * pmu.getVbusCurrent()); pmu.getVbusVoltage() / 1000 * pmu.getVbusCurrent());
else else
@ -133,58 +109,58 @@ void AXP192_showstatus(void) {
} }
void AXP192_init(void) { void AXP192_init(void) {
if (pmu.begin(i2c_readBytes, i2c_writeBytes, AXP192_PRIMARY_ADDRESS) == if (!pmu.begin(Wire, AXP192_PRIMARY_ADDRESS, SCL, SDA))
AXP_FAIL)
ESP_LOGI(TAG, "AXP192 PMU initialization failed"); ESP_LOGI(TAG, "AXP192 PMU initialization failed");
else { else {
// configure voltages ESP_LOGD(TAG, "AXP192 ChipID:0x%x", pmu.getChipID());
pmu.setDCDC1Voltage(3300); // for external OLED display
pmu.setLDO2Voltage(3300); // LORA VDD 3v3
pmu.setLDO3Voltage(3300); // GPS VDD 3v3
// configure voltage warning levels // set pmu operating voltages
pmu.setVWarningLevel1(3600); pmu.setMinSystemVoltage(2700);
pmu.setVWarningLevel2(3800); pmu.setVbusVoltageLimit(XPOWERS_VBUS_VOL_LIM_4V5);
pmu.setPowerDownVoltage(3300); pmu.disableVbusCurrLimit();
// set device operating voltages
pmu.setDC1Voltage(3300); // for external OLED display
pmu.setLDO2Voltage(3300); // LORA VDD 3v3
pmu.setLDO3Voltage(3300); // GPS VDD 3v3
// configure PEK button settings // configure PEK button settings
pmu.setTimeOutShutdown(false); // forced shutdown by PEK enabled pmu.setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
pmu.setShutdownTime( pmu.setPowerKeyPressOnTime(XPOWERS_POWERON_128MS);
AXP_POWER_OFF_TIME_6S); // 6 sec button press for shutdown
pmu.setlongPressTime(
AXP_LONGPRESS_TIME_1S5); // 1.5 sec button press for long press
pmu.setStartupTime(
AXP192_STARTUP_TIME_1S); // 1 sec button press for startup
// set battery temperature sensing pin off to save power // set battery temperature sensing pin off to save power
pmu.setTSmode(AXP_TS_PIN_MODE_DISABLE); pmu.disableTSPinMeasure();
// switch ADCs on // Enable internal ADC detection
pmu.adc1Enable(AXP202_BATT_VOL_ADC1, true); pmu.enableBattDetection();
pmu.adc1Enable(AXP202_BATT_CUR_ADC1, true); pmu.enableVbusVoltageMeasure();
pmu.adc1Enable(AXP202_VBUS_VOL_ADC1, true); pmu.enableBattVoltageMeasure();
pmu.adc1Enable(AXP202_VBUS_CUR_ADC1, true); pmu.enableSystemVoltageMeasure();
#ifdef PMU_INT #ifdef PMU_INT
pinMode(PMU_INT, INPUT_PULLUP); pinMode(PMU_INT, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PMU_INT), PMUIRQ, FALLING); attachInterrupt(digitalPinToInterrupt(PMU_INT), PMUIRQ, FALLING);
pmu.enableIRQ(AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ | // disable all interrupts
AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ | pmu.disableIRQ(XPOWERS_ALL_IRQ);
AXP202_CHARGING_FINISHED_IRQ | AXP202_PEK_SHORTPRESS_IRQ, // clear all interrupt flags
1); pmu.clearIrqStatus();
pmu.clearIRQ(); // enable the required interrupt function
pmu.enableIRQ(XPOWERS_BAT_INSERT_IRQ | XPOWERS_BAT_REMOVE_IRQ | // BATTERY
XPOWERS_VBUS_INSERT_IRQ | XPOWERS_VBUS_REMOVE_IRQ | // VBUS
XPOWERS_PKEY_SHORT_IRQ | XPOWERS_PKEY_LONG_IRQ | // POWER KEY
XPOWERS_BAT_CHG_DONE_IRQ | XPOWERS_BAT_CHG_START_IRQ // CHARGE
);
#endif // PMU_INT #endif // PMU_INT
// set charging parameterss according to user settings if we have (see power.h) // set charging parameterss according to user settings if we have (see power.h)
#ifdef PMU_CHG_CURRENT #ifdef PMU_CHG_CURRENT
pmu.setChargeControlCur(PMU_CHG_CURRENT); pmu.setChargeCurrent(PMU_CHG_CURRENT);
pmu.setChargingTargetVoltage(PMU_CHG_CUTOFF); pmu.setChargerVoltageLimit(PMU_CHG_CUTOFF);
pmu.enableChargeing(true); pmu.enableCharge();
#endif #endif
// switch power rails on // switch power rails on
AXP192_power(pmu_power_on); AXP192_power(pmu_power_on);
ESP_LOGI(TAG, "AXP192 PMU initialized"); ESP_LOGI(TAG, "AXP192 PMU initialized");
} }
} }
@ -263,6 +239,8 @@ uint8_t read_battlevel(mapFn_t mapFunction) {
uint8_t batt_percent = 0; uint8_t batt_percent = 0;
#ifdef HAS_IP5306 #ifdef HAS_IP5306
batt_percent = IP5306_GetBatteryLevel(); batt_percent = IP5306_GetBatteryLevel();
#elif defined HAS_PMU
batt_percent = pmu.getBatteryPercent();
#else #else
const uint16_t batt_voltage = read_voltage(); const uint16_t batt_voltage = read_voltage();
if (batt_voltage <= BAT_MIN_VOLTAGE) if (batt_voltage <= BAT_MIN_VOLTAGE)
@ -292,7 +270,7 @@ uint8_t read_battlevel(mapFn_t mapFunction) {
// overwrite calculated value if we have external power // overwrite calculated value if we have external power
#ifdef HAS_PMU #ifdef HAS_PMU
if (pmu.isVBUSPlug()) if (pmu.isVbusIn())
LMIC_setBatteryLevel(MCMD_DEVS_EXT_POWER); LMIC_setBatteryLevel(MCMD_DEVS_EXT_POWER);
#elif defined HAS_IP5306 #elif defined HAS_IP5306
if (IP5306_GetPowerSource()) if (IP5306_GetPowerSource())