Initial commit of Arduino libraries
This commit is contained in:
403
XPowersLib/examples/AXP192_Example/AXP192_Example.ino
Normal file
403
XPowersLib/examples/AXP192_Example/AXP192_Example.ino
Normal file
@@ -0,0 +1,403 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 lewis he
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
#ifndef XPOWERS_NO_ERROR
|
||||
#error "Running this example is known to not damage the device! Please go and uncomment this!"
|
||||
#endif
|
||||
|
||||
// Defined using AXP192
|
||||
#define XPOWERS_CHIP_AXP192
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Arduino.h>
|
||||
#include "XPowersLib.h"
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 22
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 35
|
||||
#endif
|
||||
|
||||
bool pmu_flag = 0;
|
||||
XPowersPMU power;
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
|
||||
void setFlag(void)
|
||||
{
|
||||
pmu_flag = true;
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
bool result = power.begin(Wire, AXP192_SLAVE_ADDRESS, i2c_sda, i2c_scl);
|
||||
|
||||
if (result == false) {
|
||||
Serial.println("power is not online..."); while (1)delay(50);
|
||||
}
|
||||
|
||||
|
||||
Serial.printf("getID:0x%x\n", power.getChipID());
|
||||
|
||||
// Set the minimum system operating voltage inside the PMU,
|
||||
// below this value will shut down the PMU
|
||||
// Range: 2600~3300mV
|
||||
power.setSysPowerDownVoltage(2700);
|
||||
|
||||
// Set the minimum common working voltage of the PMU VBUS input,
|
||||
// below this value will turn off the PMU
|
||||
power.setVbusVoltageLimit(XPOWERS_AXP192_VBUS_VOL_LIM_4V5);
|
||||
|
||||
// Turn off USB input current limit
|
||||
power.setVbusCurrentLimit(XPOWERS_AXP192_VBUS_CUR_LIM_OFF);
|
||||
|
||||
// DC1 700~3500mV, IMAX=1.2A
|
||||
power.setDC1Voltage(3300);
|
||||
Serial.printf("DC1 :%s Voltage:%u mV \n", power.isEnableDC1() ? "+" : "-", power.getDC1Voltage());
|
||||
|
||||
// DC2 700~2750 mV, IMAX=1.6A;
|
||||
power.setDC2Voltage(700);
|
||||
Serial.printf("DC2 :%s Voltage:%u mV \n", power.isEnableDC2() ? "+" : "-", power.getDC2Voltage());
|
||||
|
||||
// DC3 700~3500 mV,IMAX=0.7A;
|
||||
power.setDC3Voltage(3300);
|
||||
Serial.printf("DC3 :%s Voltage:%u mV \n", power.isEnableDC3() ? "+" : "-", power.getDC3Voltage());
|
||||
|
||||
|
||||
//LDO2 1800~3300 mV, 100mV/step, IMAX=200mA
|
||||
power.setLDO2Voltage(1800);
|
||||
|
||||
//LDO3 1800~3300 mV, 100mV/step, IMAX=200mA
|
||||
power.setLDO3Voltage(1800);
|
||||
|
||||
//LDOio 1800~3300 mV, 100mV/step, IMAX=50mA
|
||||
power.setLDOioVoltage(3300);
|
||||
|
||||
|
||||
// Enable PMU output channel
|
||||
// power.enableDC1();
|
||||
power.enableDC2();
|
||||
power.enableDC3();
|
||||
power.enableLDO2();
|
||||
power.enableLDO3();
|
||||
power.enableLDOio();
|
||||
|
||||
Serial.println("DCDC=======================================================================");
|
||||
Serial.printf("DC1 :%s Voltage:%u mV \n", power.isEnableDC1() ? "ENABLE" : "DISABLE", power.getDC1Voltage());
|
||||
Serial.printf("DC2 :%s Voltage:%u mV \n", power.isEnableDC2() ? "ENABLE" : "DISABLE", power.getDC2Voltage());
|
||||
Serial.printf("DC3 :%s Voltage:%u mV \n", power.isEnableDC3() ? "ENABLE" : "DISABLE", power.getDC3Voltage());
|
||||
Serial.println("LDO=======================================================================");
|
||||
Serial.printf("LDO2: %s Voltage:%u mV\n", power.isEnableLDO2() ? "ENABLE" : "DISABLE", power.getLDO2Voltage());
|
||||
Serial.printf("LDO3: %s Voltage:%u mV\n", power.isEnableLDO3() ? "ENABLE" : "DISABLE", power.getLDO3Voltage());
|
||||
Serial.printf("LDOio: %s Voltage:%u mV\n", power.isEnableLDOio() ? "ENABLE" : "DISABLE", power.getLDOioVoltage());
|
||||
Serial.println("==========================================================================");
|
||||
|
||||
// Set the time of pressing the button to turn off
|
||||
power.setPowerKeyPressOffTime(XPOWERS_AXP192_POWEROFF_4S);
|
||||
uint8_t opt = power.getPowerKeyPressOffTime();
|
||||
Serial.print("PowerKeyPressOffTime:");
|
||||
switch (opt) {
|
||||
case XPOWERS_AXP192_POWEROFF_4S: Serial.println("4 Second");
|
||||
break;
|
||||
case XPOWERS_AXP192_POWEROFF_65: Serial.println("6 Second");
|
||||
break;
|
||||
case XPOWERS_AXP192_POWEROFF_8S: Serial.println("8 Second");
|
||||
break;
|
||||
case XPOWERS_AXP192_POWEROFF_10S: Serial.println("10 Second");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Set the button power-on press time
|
||||
power.setPowerKeyPressOnTime(XPOWERS_POWERON_128MS);
|
||||
opt = power.getPowerKeyPressOnTime();
|
||||
Serial.print("PowerKeyPressOnTime:");
|
||||
switch (opt) {
|
||||
case XPOWERS_POWERON_128MS: Serial.println("128 Ms");
|
||||
break;
|
||||
case XPOWERS_POWERON_512MS: Serial.println("512 Ms");
|
||||
break;
|
||||
case XPOWERS_POWERON_1S: Serial.println("1 Second");
|
||||
break;
|
||||
case XPOWERS_POWERON_2S: Serial.println("2 Second");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.println("===========================================================================");
|
||||
|
||||
// It is necessary to disable the detection function of the TS pin on the board
|
||||
// without the battery temperature detection function, otherwise it will cause abnormal charging
|
||||
power.disableTSPinMeasure();
|
||||
|
||||
// power.enableTemperatureMeasure();
|
||||
// power.disableTemperatureMeasure();
|
||||
|
||||
// Enable internal ADC detection
|
||||
power.enableBattDetection();
|
||||
power.enableVbusVoltageMeasure();
|
||||
power.enableBattVoltageMeasure();
|
||||
power.enableSystemVoltageMeasure();
|
||||
|
||||
/*
|
||||
The default setting is CHGLED is automatically controlled by the PMU.
|
||||
- XPOWERS_CHG_LED_OFF,
|
||||
- XPOWERS_CHG_LED_BLINK_1HZ,
|
||||
- XPOWERS_CHG_LED_BLINK_4HZ,
|
||||
- XPOWERS_CHG_LED_ON,
|
||||
- XPOWERS_CHG_LED_CTRL_CHG,
|
||||
* */
|
||||
power.setChargingLedMode(XPOWERS_CHG_LED_OFF);
|
||||
|
||||
|
||||
pinMode(pmu_irq_pin, INPUT);
|
||||
attachInterrupt(pmu_irq_pin, setFlag, FALLING);
|
||||
|
||||
// Disable all interrupts
|
||||
power.disableIRQ(XPOWERS_AXP192_ALL_IRQ);
|
||||
// Clear all interrupt flags
|
||||
power.clearIrqStatus();
|
||||
// Enable the required interrupt function
|
||||
power.enableIRQ(
|
||||
XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_BAT_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_VBUS_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP192_PKEY_SHORT_IRQ | XPOWERS_AXP192_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP192_BAT_CHG_DONE_IRQ | XPOWERS_AXP192_BAT_CHG_START_IRQ | //CHARGE
|
||||
// XPOWERS_AXP192_PKEY_NEGATIVE_IRQ | XPOWERS_AXP192_PKEY_POSITIVE_IRQ | //POWER KEY
|
||||
XPOWERS_AXP192_TIMER_TIMEOUT_IRQ //Timer
|
||||
);
|
||||
|
||||
// Set constant current charge current limit
|
||||
power.setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_280MA);
|
||||
// Set stop charging termination current
|
||||
power.setChargerTerminationCurr(XPOWERS_AXP192_CHG_ITERM_LESS_10_PERCENT);
|
||||
|
||||
// Set charge cut-off voltage
|
||||
power.setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2);
|
||||
|
||||
// Cache writes and reads, as long as the PMU remains powered, the data will always be stored inside the PMU
|
||||
Serial.println("Write pmu data buffer .");
|
||||
uint8_t data[XPOWERS_AXP192_DATA_BUFFER_SIZE] = {1, 2, 3, 4, 5, 6};
|
||||
power.writeDataBuffer(data, XPOWERS_AXP192_DATA_BUFFER_SIZE);
|
||||
memset(data, 0, XPOWERS_AXP192_DATA_BUFFER_SIZE);
|
||||
|
||||
Serial.print("Read pmu data buffer :");
|
||||
power.readDataBuffer(data, XPOWERS_AXP192_DATA_BUFFER_SIZE);
|
||||
for (int i = 0; i < XPOWERS_AXP192_DATA_BUFFER_SIZE; ++i) {
|
||||
Serial.print(data[i]);
|
||||
Serial.print(",");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// Set the timing after one minute, the isWdtExpireIrq will be triggered in the loop interrupt function
|
||||
power.setTimerout(1);
|
||||
}
|
||||
|
||||
void printPMU()
|
||||
{
|
||||
Serial.print("isCharging:"); Serial.println(power.isCharging() ? "YES" : "NO");
|
||||
Serial.print("isDischarge:"); Serial.println(power.isDischarge() ? "YES" : "NO");
|
||||
Serial.print("isVbusIn:"); Serial.println(power.isVbusIn() ? "YES" : "NO");
|
||||
Serial.print("getBattVoltage:"); Serial.print(power.getBattVoltage()); Serial.println("mV");
|
||||
Serial.print("getVbusVoltage:"); Serial.print(power.getVbusVoltage()); Serial.println("mV");
|
||||
Serial.print("getSystemVoltage:"); Serial.print(power.getSystemVoltage()); Serial.println("mV");
|
||||
Serial.print("getTemperature:"); Serial.print(power.getTemperature()); Serial.println("*C");
|
||||
|
||||
if (power.isBatteryConnect()) {
|
||||
Serial.print("getBatteryPercent:"); Serial.print(power.getBatteryPercent()); Serial.println("%");
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void enterPmuSleep(void)
|
||||
{
|
||||
// Set sleep flag
|
||||
power.enableSleep();
|
||||
|
||||
power.disableDC2();
|
||||
power.disableDC3();
|
||||
|
||||
power.disableLDO2();
|
||||
power.disableLDO3();
|
||||
|
||||
// Finally, turn off the power of the control chip
|
||||
power.disableDC1();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (pmu_flag) {
|
||||
|
||||
pmu_flag = false;
|
||||
|
||||
// Get PMU Interrupt Status Register
|
||||
uint32_t status = power.getIrqStatus();
|
||||
Serial.print("STATUS => HEX:");
|
||||
Serial.print(status, HEX);
|
||||
Serial.print(" BIN:");
|
||||
Serial.println(status, BIN);
|
||||
|
||||
if (power.isAcinOverVoltageIrq()) {
|
||||
Serial.println("isAcinOverVoltageIrq");
|
||||
}
|
||||
if (power.isAcinInserIrq()) {
|
||||
Serial.println("isAcinInserIrq");
|
||||
}
|
||||
if (power.isAcinRemoveIrq()) {
|
||||
Serial.println("isAcinRemoveIrq");
|
||||
}
|
||||
if (power.isVbusOverVoltageIrq()) {
|
||||
Serial.println("isVbusOverVoltageIrq");
|
||||
}
|
||||
if (power.isVbusInsertIrq()) {
|
||||
Serial.println("isVbusInsertIrq");
|
||||
}
|
||||
if (power.isVbusRemoveIrq()) {
|
||||
Serial.println("isVbusRemoveIrq");
|
||||
}
|
||||
if (power.isVbusLowVholdIrq()) {
|
||||
Serial.println("isVbusLowVholdIrq");
|
||||
}
|
||||
if (power.isBatInsertIrq()) {
|
||||
Serial.println("isBatInsertIrq");
|
||||
}
|
||||
if (power.isBatRemoveIrq()) {
|
||||
Serial.println("isBatRemoveIrq");
|
||||
}
|
||||
if (power.isBattEnterActivateIrq()) {
|
||||
Serial.println("isBattEnterActivateIrq");
|
||||
}
|
||||
if (power.isBattExitActivateIrq()) {
|
||||
Serial.println("isBattExitActivateIrq");
|
||||
}
|
||||
if (power.isBatChargeStartIrq()) {
|
||||
Serial.println("isBatChargeStartIrq");
|
||||
}
|
||||
if (power.isBatChargeDoneIrq()) {
|
||||
Serial.println("isBatChargeDoneIrq");
|
||||
}
|
||||
if (power.isBattTempHighIrq()) {
|
||||
Serial.println("isBattTempHighIrq");
|
||||
}
|
||||
if (power.isBattTempLowIrq()) {
|
||||
Serial.println("isBattTempLowIrq");
|
||||
}
|
||||
if (power.isChipOverTemperatureIrq()) {
|
||||
Serial.println("isChipOverTemperatureIrq");
|
||||
}
|
||||
if (power.isChargingCurrentLessIrq()) {
|
||||
Serial.println("isChargingCurrentLessIrq");
|
||||
}
|
||||
if (power.isDC1VoltageLessIrq()) {
|
||||
Serial.println("isDC1VoltageLessIrq");
|
||||
}
|
||||
if (power.isDC2VoltageLessIrq()) {
|
||||
Serial.println("isDC2VoltageLessIrq");
|
||||
}
|
||||
if (power.isDC3VoltageLessIrq()) {
|
||||
Serial.println("isDC3VoltageLessIrq");
|
||||
}
|
||||
if (power.isPekeyShortPressIrq()) {
|
||||
Serial.println("isPekeyShortPress");
|
||||
|
||||
// enterPmuSleep();
|
||||
|
||||
//CHG LED mode test
|
||||
uint8_t m = power.getChargingLedMode();
|
||||
Serial.print("getChargingLedMode:");
|
||||
Serial.println(m++);
|
||||
m %= XPOWERS_CHG_LED_CTRL_CHG;
|
||||
Serial.printf("setChargingLedMode:%u", m);
|
||||
power.setChargingLedMode(m);
|
||||
|
||||
}
|
||||
if (power.isPekeyLongPressIrq()) {
|
||||
Serial.println("isPekeyLongPress");
|
||||
|
||||
}
|
||||
if (power.isNOEPowerOnIrq()) {
|
||||
Serial.println("isNOEPowerOnIrq");
|
||||
}
|
||||
if (power.isNOEPowerDownIrq()) {
|
||||
Serial.println("isNOEPowerDownIrq");
|
||||
}
|
||||
if (power.isVbusEffectiveIrq()) {
|
||||
Serial.println("isVbusEffectiveIrq");
|
||||
}
|
||||
if (power.isVbusInvalidIrq()) {
|
||||
Serial.println("isVbusInvalidIrq");
|
||||
}
|
||||
if (power.isVbusSessionIrq()) {
|
||||
Serial.println("isVbusSessionIrq");
|
||||
}
|
||||
if (power.isVbusSessionEndIrq()) {
|
||||
Serial.println("isVbusSessionEndIrq");
|
||||
}
|
||||
if (power.isLowVoltageLevel2Irq()) {
|
||||
Serial.println("isLowVoltageLevel2Irq");
|
||||
}
|
||||
if (power.isWdtExpireIrq()) {
|
||||
Serial.println("isWdtExpire");
|
||||
|
||||
printPMU();
|
||||
// Clear the timer state and continue to the next timer
|
||||
power.clearTimerFlag();
|
||||
}
|
||||
if (power.isGpio2EdgeTriggerIrq()) {
|
||||
Serial.println("isGpio2EdgeTriggerIrq");
|
||||
}
|
||||
if (power.isGpio1EdgeTriggerIrq()) {
|
||||
Serial.println("isGpio1EdgeTriggerIrq");
|
||||
}
|
||||
if (power.isGpio0EdgeTriggerIrq()) {
|
||||
Serial.println("isGpio0EdgeTriggerIrq");
|
||||
}
|
||||
// Clear PMU Interrupt Status Register
|
||||
power.clearIrqStatus();
|
||||
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
|
||||
403
XPowersLib/examples/AXP202_Example/AXP202_Example.ino
Normal file
403
XPowersLib/examples/AXP202_Example/AXP202_Example.ino
Normal file
@@ -0,0 +1,403 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 lewis he
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
#ifndef XPOWERS_NO_ERROR
|
||||
#error "Running this example is known to not damage the device! Please go and uncomment this!"
|
||||
#endif
|
||||
|
||||
#define XPOWERS_CHIP_AXP202
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Arduino.h>
|
||||
#include "XPowersLib.h"
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 22
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 35
|
||||
#endif
|
||||
|
||||
bool pmu_flag = 0;
|
||||
XPowersPMU power;
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
|
||||
void setFlag(void)
|
||||
{
|
||||
pmu_flag = true;
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
bool result = power.begin(Wire, AXP202_SLAVE_ADDRESS, i2c_sda, i2c_scl);
|
||||
|
||||
if (result == false) {
|
||||
Serial.println("power is not online..."); while (1)delay(50);
|
||||
}
|
||||
|
||||
|
||||
Serial.printf("getID:0x%x\n", power.getChipID());
|
||||
|
||||
// Set the minimum system operating voltage inside the PMU,
|
||||
// below this value will shut down the PMU
|
||||
// Range: 2600~3300mV
|
||||
power.setSysPowerDownVoltage(2700);
|
||||
|
||||
// Set the minimum common working voltage of the PMU VBUS input,
|
||||
// below this value will turn off the PMU
|
||||
power.setVbusVoltageLimit(XPOWERS_AXP202_VBUS_VOL_LIM_4V5);
|
||||
|
||||
// Turn off USB input current limit
|
||||
power.setVbusCurrentLimit(XPOWERS_AXP202_VBUS_CUR_LIM_OFF);
|
||||
|
||||
// DC2 700~3500 mV, IMAX=1.6A;
|
||||
power.setDC2Voltage(700);
|
||||
|
||||
// DC3 700~3500 mV,IMAX=0.7A;
|
||||
power.setDC3Voltage(3300);
|
||||
|
||||
//LDO2 1800~3300 mV, 100mV/step, IMAX=200mA
|
||||
power.setLDO2Voltage(1800);
|
||||
|
||||
//LDO3 700~2275 mV, 100mV/step, IMAX=200mA
|
||||
power.setLDO3Voltage(1800);
|
||||
|
||||
/* LDO4 Range:
|
||||
1250, 1300, 1400, 1500, 1600, 1700, 1800, 1900,
|
||||
2000, 2500, 2700, 2800, 3000, 3100, 3200, 3300
|
||||
*/
|
||||
power.setLDO4Voltage(3300);
|
||||
|
||||
//LDOio 1800~3300 mV, 100mV/step, IMAX=50mA
|
||||
power.setLDOioVoltage(3300);
|
||||
|
||||
|
||||
// Enable power output channel
|
||||
|
||||
power.enableDC2();
|
||||
|
||||
// power.enableDC3();
|
||||
|
||||
power.enableLDO2();
|
||||
power.enableLDO3();
|
||||
power.enableLDO4();
|
||||
power.enableLDOio();
|
||||
|
||||
Serial.println("DCDC=======================================================================");
|
||||
Serial.printf("DC2 :%s Voltage:%u mV \n", power.isEnableDC2() ? "ENABLE" : "DISABLE", power.getDC2Voltage());
|
||||
Serial.printf("DC3 :%s Voltage:%u mV \n", power.isEnableDC3() ? "ENABLE" : "DISABLE", power.getDC3Voltage());
|
||||
Serial.println("LDO=======================================================================");
|
||||
Serial.printf("LDO2: %s Voltage:%u mV\n", power.isEnableLDO2() ? "ENABLE" : "DISABLE", power.getLDO2Voltage());
|
||||
Serial.printf("LDO3: %s Voltage:%u mV\n", power.isEnableLDO3() ? "ENABLE" : "DISABLE", power.getLDO3Voltage());
|
||||
Serial.printf("LDO4: %s Voltage:%u mV\n", power.isEnableLDO4() ? "ENABLE" : "DISABLE", power.getLDO4Voltage());
|
||||
Serial.printf("LDOio: %s Voltage:%u mV\n", power.isEnableLDOio() ? "ENABLE" : "DISABLE", power.getLDOioVoltage());
|
||||
Serial.println("==========================================================================");
|
||||
|
||||
// Set the time of pressing the button to turn off
|
||||
power.setPowerKeyPressOffTime(XPOWERS_AXP202_POWEROFF_4S);
|
||||
uint8_t opt = power.getPowerKeyPressOffTime();
|
||||
Serial.print("PowerKeyPressOffTime:");
|
||||
switch (opt) {
|
||||
case XPOWERS_AXP202_POWEROFF_4S: Serial.println("4 Second");
|
||||
break;
|
||||
case XPOWERS_AXP202_POWEROFF_65: Serial.println("6 Second");
|
||||
break;
|
||||
case XPOWERS_AXP202_POWEROFF_8S: Serial.println("8 Second");
|
||||
break;
|
||||
case XPOWERS_AXP202_POWEROFF_10S: Serial.println("10 Second");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Set the button power-on press time
|
||||
power.setPowerKeyPressOnTime(XPOWERS_POWERON_128MS);
|
||||
opt = power.getPowerKeyPressOnTime();
|
||||
Serial.print("PowerKeyPressOnTime:");
|
||||
switch (opt) {
|
||||
case XPOWERS_POWERON_128MS: Serial.println("128 Ms");
|
||||
break;
|
||||
case XPOWERS_POWERON_512MS: Serial.println("512 Ms");
|
||||
break;
|
||||
case XPOWERS_POWERON_1S: Serial.println("1 Second");
|
||||
break;
|
||||
case XPOWERS_POWERON_2S: Serial.println("2 Second");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.println("===========================================================================");
|
||||
|
||||
// It is necessary to disable the detection function of the TS pin on the board
|
||||
// without the battery temperature detection function, otherwise it will cause abnormal charging
|
||||
power.disableTSPinMeasure();
|
||||
|
||||
// power.enableTemperatureMeasure();
|
||||
// power.disableTemperatureMeasure();
|
||||
|
||||
// Enable internal ADC detection
|
||||
power.enableBattDetection();
|
||||
power.enableVbusVoltageMeasure();
|
||||
power.enableBattVoltageMeasure();
|
||||
power.enableSystemVoltageMeasure();
|
||||
|
||||
/*
|
||||
The default setting is CHGLED is automatically controlled by the PMU.
|
||||
- XPOWERS_CHG_LED_OFF,
|
||||
- XPOWERS_CHG_LED_BLINK_1HZ,
|
||||
- XPOWERS_CHG_LED_BLINK_4HZ,
|
||||
- XPOWERS_CHG_LED_ON,
|
||||
- XPOWERS_CHG_LED_CTRL_CHG,
|
||||
* */
|
||||
power.setChargingLedMode(XPOWERS_CHG_LED_OFF);
|
||||
|
||||
|
||||
pinMode(pmu_irq_pin, INPUT);
|
||||
attachInterrupt(pmu_irq_pin, setFlag, FALLING);
|
||||
|
||||
// Disable all interrupts
|
||||
power.disableIRQ(XPOWERS_AXP202_ALL_IRQ);
|
||||
// Clear all interrupt flags
|
||||
power.clearIrqStatus();
|
||||
// Enable the required interrupt function
|
||||
power.enableIRQ(
|
||||
XPOWERS_AXP202_BAT_INSERT_IRQ | XPOWERS_AXP202_BAT_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP202_VBUS_INSERT_IRQ | XPOWERS_AXP202_VBUS_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP202_PKEY_SHORT_IRQ | XPOWERS_AXP202_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP202_BAT_CHG_DONE_IRQ | XPOWERS_AXP202_BAT_CHG_START_IRQ | //CHARGE
|
||||
// XPOWERS_AXP202_PKEY_NEGATIVE_IRQ | XPOWERS_AXP202_PKEY_POSITIVE_IRQ | //POWER KEY
|
||||
XPOWERS_AXP202_TIMER_TIMEOUT_IRQ //Timer
|
||||
);
|
||||
|
||||
// Set constant current charge current limit
|
||||
power.setChargerConstantCurr(XPOWERS_AXP202_CHG_CUR_280MA);
|
||||
// Set stop charging termination current
|
||||
power.setChargerTerminationCurr(XPOWERS_AXP202_CHG_ITERM_LESS_10_PERCENT);
|
||||
|
||||
// Set charge cut-off voltage
|
||||
power.setChargeTargetVoltage(XPOWERS_AXP202_CHG_VOL_4V2);
|
||||
|
||||
// Cache writes and reads, as long as the PMU remains powered, the data will always be stored inside the PMU
|
||||
Serial.println("Write pmu data buffer .");
|
||||
uint8_t data[XPOWERS_AXP202_DATA_BUFFER_SIZE] = {1, 2, 3, 4, 5, 6};
|
||||
power.writeDataBuffer(data, XPOWERS_AXP202_DATA_BUFFER_SIZE);
|
||||
memset(data, 0, XPOWERS_AXP202_DATA_BUFFER_SIZE);
|
||||
|
||||
Serial.print("Read pmu data buffer :");
|
||||
power.readDataBuffer(data, XPOWERS_AXP202_DATA_BUFFER_SIZE);
|
||||
for (int i = 0; i < XPOWERS_AXP202_DATA_BUFFER_SIZE; ++i) {
|
||||
Serial.print(data[i]);
|
||||
Serial.print(",");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// Set the timing after one minute, the isWdtExpireIrq will be triggered in the loop interrupt function
|
||||
power.setTimerout(1);
|
||||
}
|
||||
|
||||
void printPMU()
|
||||
{
|
||||
Serial.print("isCharging:"); Serial.println(power.isCharging() ? "YES" : "NO");
|
||||
Serial.print("isDischarge:"); Serial.println(power.isDischarge() ? "YES" : "NO");
|
||||
Serial.print("isVbusIn:"); Serial.println(power.isVbusIn() ? "YES" : "NO");
|
||||
Serial.print("getBattVoltage:"); Serial.print(power.getBattVoltage()); Serial.println("mV");
|
||||
Serial.print("getVbusVoltage:"); Serial.print(power.getVbusVoltage()); Serial.println("mV");
|
||||
Serial.print("getSystemVoltage:"); Serial.print(power.getSystemVoltage()); Serial.println("mV");
|
||||
Serial.print("getTemperature:"); Serial.print(power.getTemperature()); Serial.println("*C");
|
||||
|
||||
if (power.isBatteryConnect()) {
|
||||
Serial.print("getBatteryPercent:"); Serial.print(power.getBatteryPercent()); Serial.println("%");
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void enterPmuSleep(void)
|
||||
{
|
||||
// Set sleep flag
|
||||
power.enableSleep();
|
||||
|
||||
power.disableDC2();
|
||||
|
||||
power.disableLDO2();
|
||||
power.disableLDO3();
|
||||
|
||||
// Finally, turn off the power of the control chip
|
||||
power.disableDC3();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (pmu_flag) {
|
||||
|
||||
pmu_flag = false;
|
||||
|
||||
// Get power Interrupt Status Register
|
||||
uint32_t status = power.getIrqStatus();
|
||||
Serial.print("STATUS => HEX:");
|
||||
Serial.print(status, HEX);
|
||||
Serial.print(" BIN:");
|
||||
Serial.println(status, BIN);
|
||||
|
||||
if (power.isAcinOverVoltageIrq()) {
|
||||
Serial.println("isAcinOverVoltageIrq");
|
||||
}
|
||||
if (power.isAcinInserIrq()) {
|
||||
Serial.println("isAcinInserIrq");
|
||||
}
|
||||
if (power.isAcinRemoveIrq()) {
|
||||
Serial.println("isAcinRemoveIrq");
|
||||
}
|
||||
if (power.isVbusOverVoltageIrq()) {
|
||||
Serial.println("isVbusOverVoltageIrq");
|
||||
}
|
||||
if (power.isVbusInsertIrq()) {
|
||||
Serial.println("isVbusInsertIrq");
|
||||
}
|
||||
if (power.isVbusRemoveIrq()) {
|
||||
Serial.println("isVbusRemoveIrq");
|
||||
}
|
||||
if (power.isVbusLowVholdIrq()) {
|
||||
Serial.println("isVbusLowVholdIrq");
|
||||
}
|
||||
if (power.isBatInsertIrq()) {
|
||||
Serial.println("isBatInsertIrq");
|
||||
}
|
||||
if (power.isBatRemoveIrq()) {
|
||||
Serial.println("isBatRemoveIrq");
|
||||
}
|
||||
if (power.isBattEnterActivateIrq()) {
|
||||
Serial.println("isBattEnterActivateIrq");
|
||||
}
|
||||
if (power.isBattExitActivateIrq()) {
|
||||
Serial.println("isBattExitActivateIrq");
|
||||
}
|
||||
if (power.isBatChargeStartIrq()) {
|
||||
Serial.println("isBatChargeStartIrq");
|
||||
}
|
||||
if (power.isBatChargeDoneIrq()) {
|
||||
Serial.println("isBatChargeDoneIrq");
|
||||
}
|
||||
if (power.isBattTempHighIrq()) {
|
||||
Serial.println("isBattTempHighIrq");
|
||||
}
|
||||
if (power.isBattTempLowIrq()) {
|
||||
Serial.println("isBattTempLowIrq");
|
||||
}
|
||||
if (power.isChipOverTemperatureIrq()) {
|
||||
Serial.println("isChipOverTemperatureIrq");
|
||||
}
|
||||
if (power.isChargingCurrentLessIrq()) {
|
||||
Serial.println("isChargingCurrentLessIrq");
|
||||
}
|
||||
if (power.isDC1VoltageLessIrq()) {
|
||||
Serial.println("isDC1VoltageLessIrq");
|
||||
}
|
||||
if (power.isDC2VoltageLessIrq()) {
|
||||
Serial.println("isDC2VoltageLessIrq");
|
||||
}
|
||||
if (power.isDC3VoltageLessIrq()) {
|
||||
Serial.println("isDC3VoltageLessIrq");
|
||||
}
|
||||
if (power.isPekeyShortPressIrq()) {
|
||||
Serial.println("isPekeyShortPress");
|
||||
|
||||
// enterPmuSleep();
|
||||
|
||||
//CHG LED mode test
|
||||
uint8_t m = power.getChargingLedMode();
|
||||
Serial.print("getChargingLedMode:");
|
||||
Serial.println(m++);
|
||||
m %= XPOWERS_CHG_LED_CTRL_CHG;
|
||||
Serial.printf("setChargingLedMode:%u", m);
|
||||
power.setChargingLedMode(m);
|
||||
|
||||
}
|
||||
if (power.isPekeyLongPressIrq()) {
|
||||
Serial.println("isPekeyLongPress");
|
||||
|
||||
}
|
||||
if (power.isNOEPowerOnIrq()) {
|
||||
Serial.println("isNOEPowerOnIrq");
|
||||
}
|
||||
if (power.isNOEPowerDownIrq()) {
|
||||
Serial.println("isNOEPowerDownIrq");
|
||||
}
|
||||
if (power.isVbusEffectiveIrq()) {
|
||||
Serial.println("isVbusEffectiveIrq");
|
||||
}
|
||||
if (power.isVbusInvalidIrq()) {
|
||||
Serial.println("isVbusInvalidIrq");
|
||||
}
|
||||
if (power.isVbusSessionIrq()) {
|
||||
Serial.println("isVbusSessionIrq");
|
||||
}
|
||||
if (power.isVbusSessionEndIrq()) {
|
||||
Serial.println("isVbusSessionEndIrq");
|
||||
}
|
||||
if (power.isLowVoltageLevel2Irq()) {
|
||||
Serial.println("isLowVoltageLevel2Irq");
|
||||
}
|
||||
if (power.isWdtExpireIrq()) {
|
||||
Serial.println("isWdtExpire");
|
||||
|
||||
printPMU();
|
||||
// Clear the timer state and continue to the next timer
|
||||
power.clearTimerFlag();
|
||||
}
|
||||
if (power.isGpio2EdgeTriggerIrq()) {
|
||||
Serial.println("isGpio2EdgeTriggerIrq");
|
||||
}
|
||||
if (power.isGpio1EdgeTriggerIrq()) {
|
||||
Serial.println("isGpio1EdgeTriggerIrq");
|
||||
}
|
||||
if (power.isGpio0EdgeTriggerIrq()) {
|
||||
Serial.println("isGpio0EdgeTriggerIrq");
|
||||
}
|
||||
// Clear power Interrupt Status Register
|
||||
power.clearIrqStatus();
|
||||
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
|
||||
183
XPowersLib/examples/AXP2101_ADC_Example/AXP2101_ADC_Example.ino
Normal file
183
XPowersLib/examples/AXP2101_ADC_Example/AXP2101_ADC_Example.ino
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 lewis he
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
#ifndef XPOWERS_NO_ERROR
|
||||
#error "Running this example is known to not damage the device! Please go and uncomment this!"
|
||||
#endif
|
||||
// Defined using AXP2102
|
||||
#define XPOWERS_CHIP_AXP2101
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Arduino.h>
|
||||
#include "XPowersLib.h"
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 15
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 7
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 6
|
||||
#endif
|
||||
|
||||
XPowersPMU power;
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
bool pmu_flag = false;
|
||||
bool adc_switch = false;
|
||||
|
||||
void setFlag(void)
|
||||
{
|
||||
pmu_flag = true;
|
||||
}
|
||||
|
||||
|
||||
void adcOn()
|
||||
{
|
||||
power.enableTemperatureMeasure();
|
||||
// Enable internal ADC detection
|
||||
power.enableBattDetection();
|
||||
power.enableVbusVoltageMeasure();
|
||||
power.enableBattVoltageMeasure();
|
||||
power.enableSystemVoltageMeasure();
|
||||
}
|
||||
|
||||
void adcOff()
|
||||
{
|
||||
power.disableTemperatureMeasure();
|
||||
// Enable internal ADC detection
|
||||
power.disableBattDetection();
|
||||
power.disableVbusVoltageMeasure();
|
||||
power.disableBattVoltageMeasure();
|
||||
power.disableSystemVoltageMeasure();
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
bool result = power.begin(Wire, AXP2101_SLAVE_ADDRESS, i2c_sda, i2c_scl);
|
||||
|
||||
if (result == false) {
|
||||
Serial.println("PMU is not online..."); while (1)delay(50);
|
||||
}
|
||||
|
||||
// Force add pull-up
|
||||
pinMode(pmu_irq_pin, INPUT_PULLUP);
|
||||
attachInterrupt(pmu_irq_pin, setFlag, FALLING);
|
||||
|
||||
power.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
// Clear all interrupt flags
|
||||
power.clearIrqStatus();
|
||||
// Enable the required interrupt function
|
||||
power.enableIRQ(
|
||||
XPOWERS_AXP2101_PKEY_SHORT_IRQ //POWER KEY
|
||||
);
|
||||
|
||||
/*
|
||||
The default setting is CHGLED is automatically controlled by the PMU.
|
||||
- XPOWERS_CHG_LED_OFF,
|
||||
- XPOWERS_CHG_LED_BLINK_1HZ,
|
||||
- XPOWERS_CHG_LED_BLINK_4HZ,
|
||||
- XPOWERS_CHG_LED_ON,
|
||||
- XPOWERS_CHG_LED_CTRL_CHG,
|
||||
* */
|
||||
power.setChargingLedMode(XPOWERS_CHG_LED_ON);
|
||||
|
||||
//Default turn on adc
|
||||
adcOn();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
if (pmu_flag) {
|
||||
pmu_flag = false;
|
||||
// Get PMU Interrupt Status Register
|
||||
power.getIrqStatus();
|
||||
if (power.isPekeyShortPressIrq()) {
|
||||
if (adc_switch) {
|
||||
adcOn(); Serial.println("Enable ADC\n\n\n");
|
||||
} else {
|
||||
adcOff(); Serial.println("Disable ADC\n\n\n");
|
||||
}
|
||||
adc_switch = !adc_switch;
|
||||
}
|
||||
// Clear power Interrupt Status Register
|
||||
power.clearIrqStatus();
|
||||
}
|
||||
|
||||
Serial.print("power Temperature:"); Serial.print(power.getTemperature()); Serial.println("*C");
|
||||
Serial.print("isCharging:"); Serial.println(power.isCharging() ? "YES" : "NO");
|
||||
Serial.print("isDischarge:"); Serial.println(power.isDischarge() ? "YES" : "NO");
|
||||
Serial.print("isStandby:"); Serial.println(power.isStandby() ? "YES" : "NO");
|
||||
Serial.print("isVbusIn:"); Serial.println(power.isVbusIn() ? "YES" : "NO");
|
||||
Serial.print("isVbusGood:"); Serial.println(power.isVbusGood() ? "YES" : "NO");
|
||||
Serial.print("getChargerStatus:");
|
||||
uint8_t charge_status = power.getChargerStatus();
|
||||
if (charge_status == XPOWERS_AXP2101_CHG_TRI_STATE) {
|
||||
Serial.println("tri_charge");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_PRE_STATE) {
|
||||
Serial.println("pre_charge");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_CC_STATE) {
|
||||
Serial.println("constant charge");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_CV_STATE) {
|
||||
Serial.println("constant voltage");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_DONE_STATE) {
|
||||
Serial.println("charge done");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_STOP_STATE) {
|
||||
Serial.println("not charge");
|
||||
}
|
||||
|
||||
// After the ADC detection is turned off, the register will return to the last reading. The PMU will not refresh the data register
|
||||
Serial.print("getBattVoltage:"); Serial.print(power.getBattVoltage()); Serial.println("mV");
|
||||
Serial.print("getVbusVoltage:"); Serial.print(power.getVbusVoltage()); Serial.println("mV");
|
||||
Serial.print("getSystemVoltage:"); Serial.print(power.getSystemVoltage()); Serial.println("mV");
|
||||
|
||||
// The battery percentage may be inaccurate at first use, the PMU will automatically
|
||||
// learn the battery curve and will automatically calibrate the battery percentage
|
||||
// after a charge and discharge cycle
|
||||
if (power.isBatteryConnect()) {
|
||||
Serial.print("getBatteryPercent:"); Serial.print(power.getBatteryPercent()); Serial.println("%");
|
||||
}
|
||||
|
||||
// Serial.println();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 lewis he
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
#ifndef XPOWERS_NO_ERROR
|
||||
#error "Running this example is known to not damage the device! Please go and uncomment this!"
|
||||
#endif
|
||||
// Defined using AXP2102
|
||||
#define XPOWERS_CHIP_AXP2101
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Arduino.h>
|
||||
#include "XPowersLib.h"
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 22
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 35
|
||||
#endif
|
||||
|
||||
XPowersPMU power;
|
||||
|
||||
bool pmu_flag = false;
|
||||
uint8_t curIndex = 4;
|
||||
|
||||
void setFlag(void)
|
||||
{
|
||||
pmu_flag = true;
|
||||
}
|
||||
|
||||
|
||||
void printChargerConstantCurr()
|
||||
{
|
||||
const uint16_t currTable[] = {
|
||||
0, 0, 0, 0, 100, 125, 150, 175, 200, 300, 400, 500, 600, 700, 800, 900, 1000
|
||||
};
|
||||
uint8_t val = power.getChargerConstantCurr();
|
||||
Serial.printf("Setting Charge Target Current - VAL:%u CURRENT:%u\n", val, currTable[val]);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
//Start while waiting for Serial monitoring
|
||||
while (!Serial);
|
||||
|
||||
delay(3000);
|
||||
|
||||
Serial.println();
|
||||
|
||||
bool res = power.begin(Wire, AXP2101_SLAVE_ADDRESS, CONFIG_PMU_SDA, CONFIG_PMU_SCL);
|
||||
if (!res) {
|
||||
Serial.println("Failed to initialize power.....");
|
||||
while (1) {
|
||||
delay(5000);
|
||||
}
|
||||
}
|
||||
|
||||
// Set power interrupt
|
||||
pinMode(CONFIG_PMU_IRQ, INPUT);
|
||||
attachInterrupt(CONFIG_PMU_IRQ, setFlag, FALLING);
|
||||
|
||||
// Disable all interrupts
|
||||
power.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
|
||||
// Enable the required interrupt function
|
||||
power.enableIRQ(
|
||||
XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ //CHARGE
|
||||
);
|
||||
// Clear all interrupt flags
|
||||
power.clearIrqStatus();
|
||||
|
||||
// Set the minimum common working voltage of the PMU VBUS input,
|
||||
// below this value will turn off the power
|
||||
power.setVbusVoltageLimit(XPOWERS_AXP2101_VBUS_VOL_LIM_4V36);
|
||||
// Set the maximum current of the PMU VBUS input,
|
||||
// higher than this value will turn off the PMU
|
||||
power.setVbusCurrentLimit(XPOWERS_AXP2101_VBUS_CUR_LIM_1500MA);
|
||||
// Set VSY off voltage as 2600mV , Adjustment range 2600mV ~ 3300mV
|
||||
power.setSysPowerDownVoltage(2600);
|
||||
// Set the precharge charging current
|
||||
power.setPrechargeCurr(XPOWERS_AXP2101_PRECHARGE_50MA);
|
||||
// Set constant current charge current limit
|
||||
power.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_200MA);
|
||||
// Set stop charging termination current
|
||||
power.setChargerTerminationCurr(XPOWERS_AXP2101_CHG_ITERM_25MA);
|
||||
// Set charge cut-off voltage
|
||||
power.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V1);
|
||||
|
||||
/*
|
||||
The default setting is CHGLED is automatically controlled by the PMU.
|
||||
- XPOWERS_CHG_LED_OFF,
|
||||
- XPOWERS_CHG_LED_BLINK_1HZ,
|
||||
- XPOWERS_CHG_LED_BLINK_4HZ,
|
||||
- XPOWERS_CHG_LED_ON,
|
||||
- XPOWERS_CHG_LED_CTRL_CHG,
|
||||
* */
|
||||
power.setChargingLedMode(XPOWERS_CHG_LED_OFF);
|
||||
// Set cell battery voltage to 3.3V
|
||||
power.setButtonBatteryChargeVoltage(3300);
|
||||
// Enable cell battery charge function
|
||||
power.enableButtonBatteryCharge();
|
||||
// Print default setting current
|
||||
printChargerConstantCurr();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (pmu_flag) {
|
||||
pmu_flag = false;
|
||||
// Get PMU Interrupt Status Register
|
||||
power.getIrqStatus();
|
||||
if (power.isPekeyShortPressIrq()) {
|
||||
|
||||
// Set constant current charge current limit
|
||||
// For setting a current greater than 500mA, the VBUS power supply must be sufficient. If the input is lower than 5V, the charging current will be below 500mA.
|
||||
if (!power.setChargerConstantCurr(curIndex)) {
|
||||
Serial.println("Setting Charger Constant Current Failed!");
|
||||
}
|
||||
printChargerConstantCurr();
|
||||
Serial.println("===========================");
|
||||
curIndex++;
|
||||
curIndex %= (XPOWERS_AXP2101_CHG_CUR_1000MA + 1);
|
||||
if (curIndex == 0) {
|
||||
curIndex = 3;
|
||||
}
|
||||
|
||||
// Toggle CHG led
|
||||
power.setChargingLedMode(power.getChargingLedMode() != XPOWERS_CHG_LED_OFF ? XPOWERS_CHG_LED_OFF : XPOWERS_CHG_LED_ON);
|
||||
}
|
||||
// Clear PMU Interrupt Status Register
|
||||
power.clearIrqStatus();
|
||||
}
|
||||
|
||||
delay(200);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 lewis he
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
#ifndef XPOWERS_NO_ERROR
|
||||
#error "Running this example is known to not damage the device! Please go and uncomment this!"
|
||||
#endif
|
||||
// Defined using AXP2102
|
||||
#define XPOWERS_CHIP_AXP2101
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Arduino.h>
|
||||
#include "XPowersLib.h"
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 22
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 35
|
||||
#endif
|
||||
|
||||
bool pmu_flag = 0;
|
||||
XPowersPMU power;
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
|
||||
void setFlag(void)
|
||||
{
|
||||
pmu_flag = true;
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
bool result = power.begin(Wire, AXP2101_SLAVE_ADDRESS, i2c_sda, i2c_scl);
|
||||
|
||||
if (result == false) {
|
||||
Serial.println("power is not online..."); while (1)delay(50);
|
||||
}
|
||||
|
||||
Serial.printf("getID:0x%x\n", power.getChipID());
|
||||
|
||||
// Set the minimum common working voltage of the PMU VBUS input,
|
||||
// below this value will turn off the PMU
|
||||
power.setVbusVoltageLimit(XPOWERS_AXP2101_VBUS_VOL_LIM_4V36);
|
||||
|
||||
// Set the maximum current of the PMU VBUS input,
|
||||
// higher than this value will turn off the PMU
|
||||
power.setVbusCurrentLimit(XPOWERS_AXP2101_VBUS_CUR_LIM_1500MA);
|
||||
|
||||
|
||||
// Get the VSYS shutdown voltage
|
||||
uint16_t vol = power.getSysPowerDownVoltage();
|
||||
Serial.printf("-> getSysPowerDownVoltage:%u\n", vol);
|
||||
|
||||
// Set VSY off voltage as 2600mV , Adjustment range 2600mV ~ 3300mV
|
||||
power.setSysPowerDownVoltage(2600);
|
||||
|
||||
// It is necessary to disable the detection function of the TS pin on the board
|
||||
// without the battery temperature detection function, otherwise it will cause abnormal charging
|
||||
power.disableTSPinMeasure();
|
||||
|
||||
// power.enableTemperatureMeasure();
|
||||
|
||||
// Enable internal ADC detection
|
||||
power.enableBattDetection();
|
||||
power.enableVbusVoltageMeasure();
|
||||
power.enableBattVoltageMeasure();
|
||||
power.enableSystemVoltageMeasure();
|
||||
|
||||
/*
|
||||
The default setting is CHGLED is automatically controlled by the PMU.
|
||||
- XPOWERS_CHG_LED_OFF,
|
||||
- XPOWERS_CHG_LED_BLINK_1HZ,
|
||||
- XPOWERS_CHG_LED_BLINK_4HZ,
|
||||
- XPOWERS_CHG_LED_ON,
|
||||
- XPOWERS_CHG_LED_CTRL_CHG,
|
||||
* */
|
||||
power.setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
|
||||
|
||||
|
||||
// Force add pull-up
|
||||
pinMode(pmu_irq_pin, INPUT_PULLUP);
|
||||
attachInterrupt(pmu_irq_pin, setFlag, FALLING);
|
||||
|
||||
|
||||
// Disable all interrupts
|
||||
power.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
// Clear all interrupt flags
|
||||
power.clearIrqStatus();
|
||||
// Enable the required interrupt function
|
||||
power.enableIRQ(
|
||||
XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ | //CHARGE
|
||||
XPOWERS_AXP2101_WARNING_LEVEL1_IRQ | XPOWERS_AXP2101_WARNING_LEVEL2_IRQ //Low battery warning
|
||||
// XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ | XPOWERS_AXP2101_PKEY_POSITIVE_IRQ | //POWER KEY
|
||||
);
|
||||
|
||||
// Set the precharge charging current
|
||||
power.setPrechargeCurr(XPOWERS_AXP2101_PRECHARGE_200MA);
|
||||
|
||||
|
||||
// Set stop charging termination current
|
||||
power.setChargerTerminationCurr(XPOWERS_AXP2101_CHG_ITERM_25MA);
|
||||
|
||||
|
||||
// Set constant current charge current limit
|
||||
if (!power.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_1000MA)) {
|
||||
Serial.println("Setting Charger Constant Current Failed!");
|
||||
}
|
||||
|
||||
const uint16_t currTable[] = {
|
||||
0, 0, 0, 0, 100, 125, 150, 175, 200, 300, 400, 500, 600, 700, 800, 900, 1000
|
||||
};
|
||||
uint8_t val = power.getChargerConstantCurr();
|
||||
Serial.print("Setting Charge Target Current : ");
|
||||
Serial.println(currTable[val]);
|
||||
|
||||
// Set charge cut-off voltage
|
||||
power.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
|
||||
|
||||
const uint16_t tableVoltage[] = {
|
||||
0, 4000, 4100, 4200, 4350, 4400, 255
|
||||
};
|
||||
val = power.getChargeTargetVoltage();
|
||||
Serial.print("Setting Charge Target Voltage : ");
|
||||
Serial.println(tableVoltage[val]);
|
||||
|
||||
|
||||
// Set the power level to be lower than 15% and send an interrupt to the host`
|
||||
power.setLowBatWarnThreshold(10);
|
||||
|
||||
// Set the power level to be lower than 5% and turn off the power supply
|
||||
power.setLowBatShutdownThreshold(5);
|
||||
|
||||
/*
|
||||
Turn on the learning battery curve,
|
||||
And write the learned battery curve into the ROM
|
||||
*/
|
||||
power.fuelGaugeControl(true, true);
|
||||
|
||||
Serial.println();
|
||||
|
||||
delay(5000);
|
||||
}
|
||||
|
||||
void printPMU()
|
||||
{
|
||||
Serial.println("---------------------------------------------------------------------------------------------------------");
|
||||
Serial.println("Satus1 Satus2 CHARG DISC STBY VBUSIN VGOOD VBAT VBUS VSYS Percentage CHG_STATUS");
|
||||
Serial.println("(Bin) (Bin) (bool) (bool) (bool) (bool) (bool) (mV) (mV) (mV) (%) (str) ");
|
||||
Serial.println("---------------------------------------------------------------------------------------------------------");
|
||||
uint16_t statusVal = power.status();
|
||||
Serial.print("0b"); Serial.print(statusVal >> 8, BIN); Serial.print("\t");
|
||||
Serial.print("0b"); Serial.print(statusVal & 0xFF, BIN); Serial.print("\t");
|
||||
Serial.print(power.isCharging() ? "YES" : "NO "); Serial.print("\t");
|
||||
Serial.print(power.isDischarge() ? "YES" : "NO "); Serial.print("\t");
|
||||
Serial.print(power.isStandby() ? "YES" : "NO "); Serial.print("\t");
|
||||
Serial.print(power.isVbusIn() ? "YES" : "NO "); Serial.print("\t");
|
||||
Serial.print(power.isVbusGood() ? "YES" : "NO "); Serial.print("\t");
|
||||
Serial.print(power.getBattVoltage()); Serial.print("\t");
|
||||
Serial.print(power.getVbusVoltage()); Serial.print("\t");
|
||||
Serial.print(power.getSystemVoltage()); Serial.print("\t");
|
||||
|
||||
// The battery percentage may be inaccurate at first use, the PMU will automatically
|
||||
// learn the battery curve and will automatically calibrate the battery percentage
|
||||
// after a charge and discharge cycle
|
||||
Serial.print(power.getBatteryPercent()); Serial.print("\t");
|
||||
|
||||
uint8_t charge_status = power.getChargerStatus();
|
||||
if (charge_status == XPOWERS_AXP2101_CHG_TRI_STATE) {
|
||||
Serial.println("tri_charge");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_PRE_STATE) {
|
||||
Serial.println("pre_charge");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_CC_STATE) {
|
||||
Serial.println("constant charge(CC)");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_CV_STATE) {
|
||||
Serial.println("constant voltage(CV)");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_DONE_STATE) {
|
||||
Serial.println("charge done");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_STOP_STATE) {
|
||||
Serial.println("not charge");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
}
|
||||
|
||||
uint32_t printTime = 0;
|
||||
void loop()
|
||||
{
|
||||
|
||||
if (millis() > printTime) {
|
||||
printTime = millis() + 2000;
|
||||
printPMU();
|
||||
}
|
||||
|
||||
|
||||
if (pmu_flag) {
|
||||
|
||||
pmu_flag = false;
|
||||
|
||||
// Get PMU Interrupt Status Register
|
||||
uint32_t status = power.getIrqStatus();
|
||||
Serial.print("STATUS => HEX:");
|
||||
Serial.print(status, HEX);
|
||||
Serial.print(" BIN:");
|
||||
Serial.println(status, BIN);
|
||||
|
||||
if (power.isDropWarningLevel2Irq()) {
|
||||
Serial.println("isDropWarningLevel2");
|
||||
}
|
||||
if (power.isDropWarningLevel1Irq()) {
|
||||
Serial.println(" >>>> isDropWarningLevel1 <<<<");
|
||||
power.shutdown();
|
||||
}
|
||||
if (power.isGaugeWdtTimeoutIrq()) {
|
||||
Serial.println("isWdtTimeout");
|
||||
}
|
||||
if (power.isBatChargerOverTemperatureIrq()) {
|
||||
Serial.println("isBatChargeOverTemperature");
|
||||
}
|
||||
if (power.isBatWorkOverTemperatureIrq()) {
|
||||
Serial.println("isBatWorkOverTemperature");
|
||||
}
|
||||
if (power.isBatWorkUnderTemperatureIrq()) {
|
||||
Serial.println("isBatWorkUnderTemperature");
|
||||
}
|
||||
if (power.isVbusInsertIrq()) {
|
||||
Serial.println("isVbusInsert");
|
||||
uint8_t val = power.getVbusCurrentLimit();
|
||||
Serial.print("Get Vbus Current Limit = "); Serial.println(val);
|
||||
}
|
||||
if (power.isVbusRemoveIrq()) {
|
||||
Serial.println("isVbusRemove");
|
||||
uint8_t val = power.getVbusCurrentLimit();
|
||||
Serial.print("Get Vbus Current Limit = "); Serial.println(val);
|
||||
}
|
||||
if (power.isBatInsertIrq()) {
|
||||
Serial.println("isBatInsert");
|
||||
}
|
||||
if (power.isBatRemoveIrq()) {
|
||||
Serial.println("isBatRemove");
|
||||
}
|
||||
|
||||
if (power.isPekeyShortPressIrq()) {
|
||||
Serial.println("isPekeyShortPress");
|
||||
}
|
||||
|
||||
if (power.isPekeyLongPressIrq()) {
|
||||
Serial.println("isPekeyLongPress");
|
||||
}
|
||||
|
||||
if (power.isPekeyNegativeIrq()) {
|
||||
Serial.println("isPekeyNegative");
|
||||
}
|
||||
if (power.isPekeyPositiveIrq()) {
|
||||
Serial.println("isPekeyPositive");
|
||||
}
|
||||
if (power.isWdtExpireIrq()) {
|
||||
Serial.println("isWdtExpire");
|
||||
}
|
||||
if (power.isLdoOverCurrentIrq()) {
|
||||
Serial.println("isLdoOverCurrentIrq");
|
||||
}
|
||||
if (power.isBatfetOverCurrentIrq()) {
|
||||
Serial.println("isBatfetOverCurrentIrq");
|
||||
}
|
||||
if (power.isBatChargeDoneIrq()) {
|
||||
Serial.println("isBatChargeDone");
|
||||
}
|
||||
if (power.isBatChargeStartIrq()) {
|
||||
Serial.println("isBatChargeStart");
|
||||
}
|
||||
if (power.isBatDieOverTemperatureIrq()) {
|
||||
Serial.println("isBatDieOverTemperature");
|
||||
}
|
||||
if (power.isChargeOverTimeoutIrq()) {
|
||||
Serial.println("isChargeOverTimeout");
|
||||
}
|
||||
if (power.isBatOverVoltageIrq()) {
|
||||
Serial.println("isBatOverVoltage");
|
||||
}
|
||||
// Clear PMU Interrupt Status Register
|
||||
power.clearIrqStatus();
|
||||
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
|
||||
512
XPowersLib/examples/AXP2101_Example/AXP2101_Example.ino
Normal file
512
XPowersLib/examples/AXP2101_Example/AXP2101_Example.ino
Normal file
@@ -0,0 +1,512 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 lewis he
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
#ifndef XPOWERS_NO_ERROR
|
||||
#error "Running this example is known to not damage the device! Please go and uncomment this!"
|
||||
#endif
|
||||
// Defined using AXP2102
|
||||
#define XPOWERS_CHIP_AXP2101
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Arduino.h>
|
||||
#include "XPowersLib.h"
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 22
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 35
|
||||
#endif
|
||||
|
||||
bool pmu_flag = 0;
|
||||
XPowersPMU power;
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
|
||||
void setFlag(void)
|
||||
{
|
||||
pmu_flag = true;
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
bool result = power.begin(Wire, AXP2101_SLAVE_ADDRESS, i2c_sda, i2c_scl);
|
||||
|
||||
if (result == false) {
|
||||
Serial.println("power is not online..."); while (1)delay(50);
|
||||
}
|
||||
|
||||
Serial.printf("getID:0x%x\n", power.getChipID());
|
||||
|
||||
// Set the minimum common working voltage of the PMU VBUS input,
|
||||
// below this value will turn off the PMU
|
||||
power.setVbusVoltageLimit(XPOWERS_AXP2101_VBUS_VOL_LIM_4V36);
|
||||
|
||||
// Set the maximum current of the PMU VBUS input,
|
||||
// higher than this value will turn off the PMU
|
||||
power.setVbusCurrentLimit(XPOWERS_AXP2101_VBUS_CUR_LIM_1500MA);
|
||||
|
||||
|
||||
// Get the VSYS shutdown voltage
|
||||
uint16_t vol = power.getSysPowerDownVoltage();
|
||||
Serial.printf("-> getSysPowerDownVoltage:%u\n", vol);
|
||||
|
||||
// Set VSY off voltage as 2600mV , Adjustment range 2600mV ~ 3300mV
|
||||
power.setSysPowerDownVoltage(2600);
|
||||
|
||||
vol = power.getSysPowerDownVoltage();
|
||||
Serial.printf("-> getSysPowerDownVoltage:%u\n", vol);
|
||||
|
||||
|
||||
// DC1 IMAX=2A
|
||||
// 1500~3400mV,100mV/step,20steps
|
||||
power.setDC1Voltage(3300);
|
||||
Serial.printf("DC1 : %s Voltage:%u mV \n", power.isEnableDC1() ? "+" : "-", power.getDC1Voltage());
|
||||
|
||||
// DC2 IMAX=2A
|
||||
// 500~1200mV 10mV/step,71steps
|
||||
// 1220~1540mV 20mV/step,17steps
|
||||
power.setDC2Voltage(1000);
|
||||
Serial.printf("DC2 : %s Voltage:%u mV \n", power.isEnableDC2() ? "+" : "-", power.getDC2Voltage());
|
||||
|
||||
// DC3 IMAX = 2A
|
||||
// 500~1200mV,10mV/step,71steps
|
||||
// 1220~1540mV,20mV/step,17steps
|
||||
// 1600~3400mV,100mV/step,19steps
|
||||
power.setDC3Voltage(3300);
|
||||
Serial.printf("DC3 : %s Voltage:%u mV \n", power.isEnableDC3() ? "+" : "-", power.getDC3Voltage());
|
||||
|
||||
// DCDC4 IMAX=1.5A
|
||||
// 500~1200mV,10mV/step,71steps
|
||||
// 1220~1840mV,20mV/step,32steps
|
||||
power.setDC4Voltage(1000);
|
||||
Serial.printf("DC4 : %s Voltage:%u mV \n", power.isEnableDC4() ? "+" : "-", power.getDC4Voltage());
|
||||
|
||||
// DC5 IMAX=2A
|
||||
// 1200mV
|
||||
// 1400~3700mV,100mV/step,24steps
|
||||
power.setDC5Voltage(3300);
|
||||
Serial.printf("DC5 : %s Voltage:%u mV \n", power.isEnableDC5() ? "+" : "-", power.getDC5Voltage());
|
||||
|
||||
//ALDO1 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
power.setALDO1Voltage(3300);
|
||||
|
||||
//ALDO2 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
power.setALDO2Voltage(3300);
|
||||
|
||||
//ALDO3 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
power.setALDO3Voltage(3300);
|
||||
|
||||
//ALDO4 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
power.setALDO4Voltage(3300);
|
||||
|
||||
//BLDO1 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
power.setBLDO1Voltage(3300);
|
||||
|
||||
//BLDO2 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
power.setBLDO2Voltage(3300);
|
||||
|
||||
//CPUSLDO IMAX=30mA
|
||||
//500~1400mV,50mV/step,19steps
|
||||
power.setCPUSLDOVoltage(1000);
|
||||
|
||||
//DLDO1 IMAX=300mA
|
||||
//500~3400mV, 100mV/step,29steps
|
||||
power.setDLDO1Voltage(3300);
|
||||
|
||||
//DLDO2 IMAX=300mA
|
||||
//500~1400mV, 50mV/step,2steps
|
||||
power.setDLDO2Voltage(3300);
|
||||
|
||||
|
||||
// power.enableDC1();
|
||||
power.enableDC2();
|
||||
power.enableDC3();
|
||||
power.enableDC4();
|
||||
power.enableDC5();
|
||||
power.enableALDO1();
|
||||
power.enableALDO2();
|
||||
power.enableALDO3();
|
||||
power.enableALDO4();
|
||||
power.enableBLDO1();
|
||||
power.enableBLDO2();
|
||||
power.enableCPUSLDO();
|
||||
power.enableDLDO1();
|
||||
power.enableDLDO2();
|
||||
|
||||
|
||||
Serial.println("DCDC=======================================================================");
|
||||
Serial.printf("DC1 : %s Voltage:%u mV \n", power.isEnableDC1() ? "+" : "-", power.getDC1Voltage());
|
||||
Serial.printf("DC2 : %s Voltage:%u mV \n", power.isEnableDC2() ? "+" : "-", power.getDC2Voltage());
|
||||
Serial.printf("DC3 : %s Voltage:%u mV \n", power.isEnableDC3() ? "+" : "-", power.getDC3Voltage());
|
||||
Serial.printf("DC4 : %s Voltage:%u mV \n", power.isEnableDC4() ? "+" : "-", power.getDC4Voltage());
|
||||
Serial.printf("DC5 : %s Voltage:%u mV \n", power.isEnableDC5() ? "+" : "-", power.getDC5Voltage());
|
||||
Serial.println("ALDO=======================================================================");
|
||||
Serial.printf("ALDO1: %s Voltage:%u mV\n", power.isEnableALDO1() ? "+" : "-", power.getALDO1Voltage());
|
||||
Serial.printf("ALDO2: %s Voltage:%u mV\n", power.isEnableALDO2() ? "+" : "-", power.getALDO2Voltage());
|
||||
Serial.printf("ALDO3: %s Voltage:%u mV\n", power.isEnableALDO3() ? "+" : "-", power.getALDO3Voltage());
|
||||
Serial.printf("ALDO4: %s Voltage:%u mV\n", power.isEnableALDO4() ? "+" : "-", power.getALDO4Voltage());
|
||||
Serial.println("BLDO=======================================================================");
|
||||
Serial.printf("BLDO1: %s Voltage:%u mV\n", power.isEnableBLDO1() ? "+" : "-", power.getBLDO1Voltage());
|
||||
Serial.printf("BLDO2: %s Voltage:%u mV\n", power.isEnableBLDO2() ? "+" : "-", power.getBLDO2Voltage());
|
||||
Serial.println("CPUSLDO====================================================================");
|
||||
Serial.printf("CPUSLDO: %s Voltage:%u mV\n", power.isEnableCPUSLDO() ? "+" : "-", power.getCPUSLDOVoltage());
|
||||
Serial.println("DLDO=======================================================================");
|
||||
Serial.printf("DLDO1: %s Voltage:%u mV\n", power.isEnableDLDO1() ? "+" : "-", power.getDLDO1Voltage());
|
||||
Serial.printf("DLDO2: %s Voltage:%u mV\n", power.isEnableDLDO2() ? "+" : "-", power.getDLDO2Voltage());
|
||||
Serial.println("===========================================================================");
|
||||
|
||||
// Set the time of pressing the button to turn off
|
||||
power.setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
|
||||
uint8_t opt = power.getPowerKeyPressOffTime();
|
||||
Serial.print("PowerKeyPressOffTime:");
|
||||
switch (opt) {
|
||||
case XPOWERS_POWEROFF_4S: Serial.println("4 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_6S: Serial.println("6 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_8S: Serial.println("8 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_10S: Serial.println("10 Second");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Set the button power-on press time
|
||||
power.setPowerKeyPressOnTime(XPOWERS_POWERON_128MS);
|
||||
opt = power.getPowerKeyPressOnTime();
|
||||
Serial.print("PowerKeyPressOnTime:");
|
||||
switch (opt) {
|
||||
case XPOWERS_POWERON_128MS: Serial.println("128 Ms");
|
||||
break;
|
||||
case XPOWERS_POWERON_512MS: Serial.println("512 Ms");
|
||||
break;
|
||||
case XPOWERS_POWERON_1S: Serial.println("1 Second");
|
||||
break;
|
||||
case XPOWERS_POWERON_2S: Serial.println("2 Second");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.println("===========================================================================");
|
||||
|
||||
bool en;
|
||||
|
||||
// DCDC 120%(130%) high voltage turn off PMIC function
|
||||
en = power.getDCHighVoltagePowerDownEn();
|
||||
Serial.print("getDCHighVoltagePowerDownEn:");
|
||||
Serial.println(en ? "ENABLE" : "DISABLE");
|
||||
// DCDC1 85% low voltage turn off PMIC function
|
||||
en = power.getDC1LowVoltagePowerDownEn();
|
||||
Serial.print("getDC1LowVoltagePowerDownEn:");
|
||||
Serial.println(en ? "ENABLE" : "DISABLE");
|
||||
// DCDC2 85% low voltage turn off PMIC function
|
||||
en = power.getDC2LowVoltagePowerDownEn();
|
||||
Serial.print("getDC2LowVoltagePowerDownEn:");
|
||||
Serial.println(en ? "ENABLE" : "DISABLE");
|
||||
// DCDC3 85% low voltage turn off PMIC function
|
||||
en = power.getDC3LowVoltagePowerDownEn();
|
||||
Serial.print("getDC3LowVoltagePowerDownEn:");
|
||||
Serial.println(en ? "ENABLE" : "DISABLE");
|
||||
// DCDC4 85% low voltage turn off PMIC function
|
||||
en = power.getDC4LowVoltagePowerDownEn();
|
||||
Serial.print("getDC4LowVoltagePowerDownEn:");
|
||||
Serial.println(en ? "ENABLE" : "DISABLE");
|
||||
// DCDC5 85% low voltage turn off PMIC function
|
||||
en = power.getDC5LowVoltagePowerDownEn();
|
||||
Serial.print("getDC5LowVoltagePowerDownEn:");
|
||||
Serial.println(en ? "ENABLE" : "DISABLE");
|
||||
|
||||
// power.setDCHighVoltagePowerDown(true);
|
||||
// power.setDC1LowVoltagePowerDown(true);
|
||||
// power.setDC2LowVoltagePowerDown(true);
|
||||
// power.setDC3LowVoltagePowerDown(true);
|
||||
// power.setDC4LowVoltagePowerDown(true);
|
||||
// power.setDC5LowVoltagePowerDown(true);
|
||||
|
||||
// It is necessary to disable the detection function of the TS pin on the board
|
||||
// without the battery temperature detection function, otherwise it will cause abnormal charging
|
||||
power.disableTSPinMeasure();
|
||||
|
||||
// power.enableTemperatureMeasure();
|
||||
|
||||
// Enable internal ADC detection
|
||||
power.enableBattDetection();
|
||||
power.enableVbusVoltageMeasure();
|
||||
power.enableBattVoltageMeasure();
|
||||
power.enableSystemVoltageMeasure();
|
||||
|
||||
|
||||
/*
|
||||
The default setting is CHGLED is automatically controlled by the PMU.
|
||||
- XPOWERS_CHG_LED_OFF,
|
||||
- XPOWERS_CHG_LED_BLINK_1HZ,
|
||||
- XPOWERS_CHG_LED_BLINK_4HZ,
|
||||
- XPOWERS_CHG_LED_ON,
|
||||
- XPOWERS_CHG_LED_CTRL_CHG,
|
||||
* */
|
||||
power.setChargingLedMode(XPOWERS_CHG_LED_OFF);
|
||||
|
||||
|
||||
// Force add pull-up
|
||||
pinMode(pmu_irq_pin, INPUT_PULLUP);
|
||||
attachInterrupt(pmu_irq_pin, setFlag, FALLING);
|
||||
|
||||
|
||||
// Disable all interrupts
|
||||
power.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
// Clear all interrupt flags
|
||||
power.clearIrqStatus();
|
||||
// Enable the required interrupt function
|
||||
power.enableIRQ(
|
||||
XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ //CHARGE
|
||||
// XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ | XPOWERS_AXP2101_PKEY_POSITIVE_IRQ | //POWER KEY
|
||||
);
|
||||
|
||||
// Set the precharge charging current
|
||||
power.setPrechargeCurr(XPOWERS_AXP2101_PRECHARGE_50MA);
|
||||
// Set constant current charge current limit
|
||||
power.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_200MA);
|
||||
// Set stop charging termination current
|
||||
power.setChargerTerminationCurr(XPOWERS_AXP2101_CHG_ITERM_25MA);
|
||||
|
||||
// Set charge cut-off voltage
|
||||
power.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V1);
|
||||
|
||||
// Set the watchdog trigger event type
|
||||
power.setWatchdogConfig(XPOWERS_AXP2101_WDT_IRQ_TO_PIN);
|
||||
// Set watchdog timeout
|
||||
power.setWatchdogTimeout(XPOWERS_AXP2101_WDT_TIMEOUT_4S);
|
||||
// Enable watchdog to trigger interrupt event
|
||||
power.enableWatchdog();
|
||||
|
||||
// power.disableWatchdog();
|
||||
|
||||
// Enable Button Battery charge
|
||||
power.enableButtonBatteryCharge();
|
||||
|
||||
// Set Button Battery charge voltage
|
||||
power.setButtonBatteryChargeVoltage(3300);
|
||||
|
||||
}
|
||||
|
||||
void printPMU()
|
||||
{
|
||||
Serial.print("isCharging:"); Serial.println(power.isCharging() ? "YES" : "NO");
|
||||
Serial.print("isDischarge:"); Serial.println(power.isDischarge() ? "YES" : "NO");
|
||||
Serial.print("isStandby:"); Serial.println(power.isStandby() ? "YES" : "NO");
|
||||
Serial.print("isVbusIn:"); Serial.println(power.isVbusIn() ? "YES" : "NO");
|
||||
Serial.print("isVbusGood:"); Serial.println(power.isVbusGood() ? "YES" : "NO");
|
||||
Serial.print("getChargerStatus:");
|
||||
uint8_t charge_status = power.getChargerStatus();
|
||||
if (charge_status == XPOWERS_AXP2101_CHG_TRI_STATE) {
|
||||
Serial.println("tri_charge");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_PRE_STATE) {
|
||||
Serial.println("pre_charge");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_CC_STATE) {
|
||||
Serial.println("constant charge");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_CV_STATE) {
|
||||
Serial.println("constant voltage");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_DONE_STATE) {
|
||||
Serial.println("charge done");
|
||||
} else if (charge_status == XPOWERS_AXP2101_CHG_STOP_STATE) {
|
||||
Serial.println("not charge");
|
||||
}
|
||||
|
||||
Serial.print("getBattVoltage:"); Serial.print(power.getBattVoltage()); Serial.println("mV");
|
||||
Serial.print("getVbusVoltage:"); Serial.print(power.getVbusVoltage()); Serial.println("mV");
|
||||
Serial.print("getSystemVoltage:"); Serial.print(power.getSystemVoltage()); Serial.println("mV");
|
||||
|
||||
// The battery percentage may be inaccurate at first use, the PMU will automatically
|
||||
// learn the battery curve and will automatically calibrate the battery percentage
|
||||
// after a charge and discharge cycle
|
||||
if (power.isBatteryConnect()) {
|
||||
Serial.print("getBatteryPercent:"); Serial.print(power.getBatteryPercent()); Serial.println("%");
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void enterPmuSleep(void)
|
||||
{
|
||||
// Set the wake-up source to PWRKEY
|
||||
power.wakeupControl(XPOWERS_AXP2101_WAKEUP_IRQ_PIN_TO_LOW, true);
|
||||
|
||||
// Set sleep flag
|
||||
power.enableSleep();
|
||||
|
||||
power.disableDC2();
|
||||
power.disableDC3();
|
||||
power.disableDC4();
|
||||
power.disableDC5();
|
||||
|
||||
power.disableALDO1();
|
||||
power.disableALDO2();
|
||||
power.disableALDO3();
|
||||
power.disableALDO4();
|
||||
|
||||
power.disableBLDO1();
|
||||
power.disableBLDO2();
|
||||
|
||||
power.disableCPUSLDO();
|
||||
power.disableDLDO1();
|
||||
power.disableDLDO2();
|
||||
|
||||
// Finally, turn off the power of the control chip
|
||||
power.disableDC1();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
if (pmu_flag) {
|
||||
|
||||
pmu_flag = false;
|
||||
|
||||
// Get PMU Interrupt Status Register
|
||||
uint32_t status = power.getIrqStatus();
|
||||
Serial.print("STATUS => HEX:");
|
||||
Serial.print(status, HEX);
|
||||
Serial.print(" BIN:");
|
||||
Serial.println(status, BIN);
|
||||
|
||||
if (power.isDropWarningLevel2Irq()) {
|
||||
Serial.println("isDropWarningLevel2");
|
||||
}
|
||||
if (power.isDropWarningLevel1Irq()) {
|
||||
Serial.println("isDropWarningLevel1");
|
||||
}
|
||||
if (power.isGaugeWdtTimeoutIrq()) {
|
||||
Serial.println("isWdtTimeout");
|
||||
}
|
||||
if (power.isBatChargerOverTemperatureIrq()) {
|
||||
Serial.println("isBatChargeOverTemperature");
|
||||
}
|
||||
if (power.isBatWorkOverTemperatureIrq()) {
|
||||
Serial.println("isBatWorkOverTemperature");
|
||||
}
|
||||
if (power.isBatWorkUnderTemperatureIrq()) {
|
||||
Serial.println("isBatWorkUnderTemperature");
|
||||
}
|
||||
if (power.isVbusInsertIrq()) {
|
||||
Serial.println("isVbusInsert");
|
||||
}
|
||||
if (power.isVbusRemoveIrq()) {
|
||||
Serial.println("isVbusRemove");
|
||||
}
|
||||
if (power.isBatInsertIrq()) {
|
||||
Serial.println("isBatInsert");
|
||||
}
|
||||
if (power.isBatRemoveIrq()) {
|
||||
Serial.println("isBatRemove");
|
||||
}
|
||||
|
||||
if (power.isPekeyShortPressIrq()) {
|
||||
Serial.println("isPekeyShortPress");
|
||||
// enterPmuSleep();
|
||||
|
||||
Serial.print("Read pmu data buffer .");
|
||||
uint8_t data[4] = {0};
|
||||
power.readDataBuffer(data, XPOWERS_AXP2101_DATA_BUFFER_SIZE);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
Serial.print(data[i]);
|
||||
Serial.print(",");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
if (power.isPekeyLongPressIrq()) {
|
||||
Serial.println("isPekeyLongPress");
|
||||
Serial.println("write pmu data buffer .");
|
||||
uint8_t data[4] = {1, 2, 3, 4};
|
||||
power.writeDataBuffer(data, XPOWERS_AXP2101_DATA_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
if (power.isPekeyNegativeIrq()) {
|
||||
Serial.println("isPekeyNegative");
|
||||
}
|
||||
if (power.isPekeyPositiveIrq()) {
|
||||
Serial.println("isPekeyPositive");
|
||||
}
|
||||
if (power.isWdtExpireIrq()) {
|
||||
Serial.println("isWdtExpire");
|
||||
printPMU();
|
||||
}
|
||||
if (power.isLdoOverCurrentIrq()) {
|
||||
Serial.println("isLdoOverCurrentIrq");
|
||||
}
|
||||
if (power.isBatfetOverCurrentIrq()) {
|
||||
Serial.println("isBatfetOverCurrentIrq");
|
||||
}
|
||||
if (power.isBatChargeDoneIrq()) {
|
||||
Serial.println("isBatChargeDone");
|
||||
}
|
||||
if (power.isBatChargeStartIrq()) {
|
||||
Serial.println("isBatChargeStart");
|
||||
}
|
||||
if (power.isBatDieOverTemperatureIrq()) {
|
||||
Serial.println("isBatDieOverTemperature");
|
||||
}
|
||||
if (power.isChargeOverTimeoutIrq()) {
|
||||
Serial.println("isChargeOverTimeout");
|
||||
}
|
||||
if (power.isBatOverVoltageIrq()) {
|
||||
Serial.println("isBatOverVoltage");
|
||||
}
|
||||
|
||||
// Clear PMU Interrupt Status Register
|
||||
power.clearIrqStatus();
|
||||
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 lewis he
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
#ifndef XPOWERS_NO_ERROR
|
||||
#error "Running this example is known to not damage the device! Please go and uncomment this!"
|
||||
#endif
|
||||
// Defined using AXP2102
|
||||
#define XPOWERS_CHIP_AXP2101
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Arduino.h>
|
||||
#include "XPowersLib.h"
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 22
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 35
|
||||
#endif
|
||||
|
||||
bool pmu_flag = 0;
|
||||
XPowersPMU power;
|
||||
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
|
||||
void setFlag(void)
|
||||
{
|
||||
pmu_flag = true;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
bool result = power.begin(Wire, AXP2101_SLAVE_ADDRESS, i2c_sda, i2c_scl);
|
||||
|
||||
if (result == false) {
|
||||
Serial.println("power is not online..."); while (1)delay(50);
|
||||
}
|
||||
|
||||
Serial.printf("getID:0x%x\n", power.getChipID());
|
||||
|
||||
// Force add pull-up
|
||||
pinMode(pmu_irq_pin, INPUT_PULLUP);
|
||||
attachInterrupt(pmu_irq_pin, setFlag, FALLING);
|
||||
|
||||
|
||||
// Disable all interrupts
|
||||
power.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
|
||||
// Print interrupt register
|
||||
power.printIntRegister(&Serial);
|
||||
|
||||
// Clear all interrupt flags
|
||||
power.clearIrqStatus();
|
||||
|
||||
// Enable the required interrupt function
|
||||
// power.enableIRQ(
|
||||
// XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | //BATTERY
|
||||
// XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | //VBUS
|
||||
// XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | //POWER KEY
|
||||
// XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ //CHARGE
|
||||
// // XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ | XPOWERS_AXP2101_PKEY_POSITIVE_IRQ | //POWER KEY
|
||||
// );
|
||||
|
||||
power.enableIRQ(XPOWERS_AXP2101_BAT_NOR_UNDER_TEMP_IRQ);
|
||||
// Print AXP2101 interrupt control register
|
||||
power.printIntRegister(&Serial);
|
||||
|
||||
power.enableIRQ(XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ);
|
||||
// Print AXP2101 interrupt control register
|
||||
power.printIntRegister(&Serial);
|
||||
|
||||
power.enableIRQ(XPOWERS_AXP2101_BAT_OVER_VOL_IRQ);
|
||||
// Print AXP2101 interrupt control register
|
||||
power.printIntRegister(&Serial);
|
||||
|
||||
// delay(30000);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
if (pmu_flag) {
|
||||
|
||||
pmu_flag = false;
|
||||
|
||||
// Get PMU Interrupt Status Register
|
||||
uint32_t status = power.getIrqStatus();
|
||||
Serial.print("STATUS => HEX:");
|
||||
Serial.print(status, HEX);
|
||||
Serial.print(" BIN:");
|
||||
Serial.println(status, BIN);
|
||||
|
||||
if (power.isDropWarningLevel2Irq()) {
|
||||
Serial.println("isDropWarningLevel2");
|
||||
}
|
||||
if (power.isDropWarningLevel1Irq()) {
|
||||
Serial.println("isDropWarningLevel1");
|
||||
}
|
||||
if (power.isGaugeWdtTimeoutIrq()) {
|
||||
Serial.println("isWdtTimeout");
|
||||
}
|
||||
if (power.isBatChargerOverTemperatureIrq()) {
|
||||
Serial.println("isBatChargeOverTemperature");
|
||||
}
|
||||
if (power.isBatWorkOverTemperatureIrq()) {
|
||||
Serial.println("isBatWorkOverTemperature");
|
||||
}
|
||||
if (power.isBatWorkUnderTemperatureIrq()) {
|
||||
Serial.println("isBatWorkUnderTemperature");
|
||||
}
|
||||
if (power.isVbusInsertIrq()) {
|
||||
Serial.println("isVbusInsert");
|
||||
}
|
||||
if (power.isVbusRemoveIrq()) {
|
||||
Serial.println("isVbusRemove");
|
||||
}
|
||||
if (power.isBatInsertIrq()) {
|
||||
Serial.println("isBatInsert");
|
||||
}
|
||||
if (power.isBatRemoveIrq()) {
|
||||
Serial.println("isBatRemove");
|
||||
}
|
||||
if (power.isPekeyShortPressIrq()) {
|
||||
Serial.println("isPekeyShortPress");
|
||||
}
|
||||
if (power.isPekeyLongPressIrq()) {
|
||||
Serial.println("isPekeyLongPress");
|
||||
}
|
||||
if (power.isPekeyNegativeIrq()) {
|
||||
Serial.println("isPekeyNegative");
|
||||
}
|
||||
if (power.isPekeyPositiveIrq()) {
|
||||
Serial.println("isPekeyPositive");
|
||||
}
|
||||
if (power.isWdtExpireIrq()) {
|
||||
Serial.println("isWdtExpire");
|
||||
}
|
||||
if (power.isLdoOverCurrentIrq()) {
|
||||
Serial.println("isLdoOverCurrentIrq");
|
||||
}
|
||||
if (power.isBatfetOverCurrentIrq()) {
|
||||
Serial.println("isBatfetOverCurrentIrq");
|
||||
}
|
||||
if (power.isBatChargeDoneIrq()) {
|
||||
Serial.println("isBatChargeDone");
|
||||
}
|
||||
if (power.isBatChargeStartIrq()) {
|
||||
Serial.println("isBatChargeStart");
|
||||
}
|
||||
if (power.isBatDieOverTemperatureIrq()) {
|
||||
Serial.println("isBatDieOverTemperature");
|
||||
}
|
||||
if (power.isChargeOverTimeoutIrq()) {
|
||||
Serial.println("isChargeOverTimeout");
|
||||
}
|
||||
if (power.isBatOverVoltageIrq()) {
|
||||
Serial.println("isBatOverVoltage");
|
||||
}
|
||||
|
||||
// Clear PMU Interrupt Status Register
|
||||
power.clearIrqStatus();
|
||||
|
||||
// Print AXP2101 interrupt control register
|
||||
power.printIntRegister(&Serial);
|
||||
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 lewis he
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
#ifndef XPOWERS_NO_ERROR
|
||||
#error "Running this example is known to not damage the device! Please go and uncomment this!"
|
||||
#endif
|
||||
// Defined using AXP2102
|
||||
#define XPOWERS_CHIP_AXP2101
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Arduino.h>
|
||||
#include "XPowersLib.h"
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 22
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 35
|
||||
#endif
|
||||
|
||||
bool pmu_flag = 0;
|
||||
XPowersPMU power;
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
static uint32_t interval = 0;
|
||||
|
||||
void setFlag(void)
|
||||
{
|
||||
pmu_flag = true;
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
bool result = power.begin(Wire, AXP2101_SLAVE_ADDRESS, i2c_sda, i2c_scl);
|
||||
|
||||
if (result == false) {
|
||||
Serial.println("power is not online..."); while (1)delay(50);
|
||||
}
|
||||
|
||||
Serial.printf("getID:0x%x\n", power.getChipID());
|
||||
|
||||
// Set the minimum common working voltage of the PMU VBUS input,
|
||||
// below this value will turn off the PMU
|
||||
power.setVbusVoltageLimit(XPOWERS_AXP2101_VBUS_VOL_LIM_4V36);
|
||||
|
||||
// Set the maximum current of the PMU VBUS input,
|
||||
// higher than this value will turn off the PMU
|
||||
power.setVbusCurrentLimit(XPOWERS_AXP2101_VBUS_CUR_LIM_1500MA);
|
||||
|
||||
|
||||
// Get the VSYS shutdown voltage
|
||||
uint16_t vol = power.getSysPowerDownVoltage();
|
||||
Serial.printf("-> getSysPowerDownVoltage:%u\n", vol);
|
||||
|
||||
// Set VSYS off voltage as 2600mV , Adjustment range 2600mV ~ 3300mV
|
||||
power.setSysPowerDownVoltage(2600);
|
||||
|
||||
vol = power.getSysPowerDownVoltage();
|
||||
Serial.printf("-> getSysPowerDownVoltage:%u\n", vol);
|
||||
|
||||
|
||||
Serial.println("DCDC=======================================================================");
|
||||
Serial.printf("DC1 : %s Voltage:%u mV \n", power.isEnableDC1() ? "+" : "-", power.getDC1Voltage());
|
||||
Serial.printf("DC2 : %s Voltage:%u mV \n", power.isEnableDC2() ? "+" : "-", power.getDC2Voltage());
|
||||
Serial.printf("DC3 : %s Voltage:%u mV \n", power.isEnableDC3() ? "+" : "-", power.getDC3Voltage());
|
||||
Serial.printf("DC4 : %s Voltage:%u mV \n", power.isEnableDC4() ? "+" : "-", power.getDC4Voltage());
|
||||
Serial.printf("DC5 : %s Voltage:%u mV \n", power.isEnableDC5() ? "+" : "-", power.getDC5Voltage());
|
||||
Serial.println("ALDO=======================================================================");
|
||||
Serial.printf("ALDO1: %s Voltage:%u mV\n", power.isEnableALDO1() ? "+" : "-", power.getALDO1Voltage());
|
||||
Serial.printf("ALDO2: %s Voltage:%u mV\n", power.isEnableALDO2() ? "+" : "-", power.getALDO2Voltage());
|
||||
Serial.printf("ALDO3: %s Voltage:%u mV\n", power.isEnableALDO3() ? "+" : "-", power.getALDO3Voltage());
|
||||
Serial.printf("ALDO4: %s Voltage:%u mV\n", power.isEnableALDO4() ? "+" : "-", power.getALDO4Voltage());
|
||||
Serial.println("BLDO=======================================================================");
|
||||
Serial.printf("BLDO1: %s Voltage:%u mV\n", power.isEnableBLDO1() ? "+" : "-", power.getBLDO1Voltage());
|
||||
Serial.printf("BLDO2: %s Voltage:%u mV\n", power.isEnableBLDO2() ? "+" : "-", power.getBLDO2Voltage());
|
||||
Serial.println("CPUSLDO====================================================================");
|
||||
Serial.printf("CPUSLDO: %s Voltage:%u mV\n", power.isEnableCPUSLDO() ? "+" : "-", power.getCPUSLDOVoltage());
|
||||
Serial.println("DLDO=======================================================================");
|
||||
Serial.printf("DLDO1: %s Voltage:%u mV\n", power.isEnableDLDO1() ? "+" : "-", power.getDLDO1Voltage());
|
||||
Serial.printf("DLDO2: %s Voltage:%u mV\n", power.isEnableDLDO2() ? "+" : "-", power.getDLDO2Voltage());
|
||||
Serial.println("===========================================================================");
|
||||
|
||||
|
||||
|
||||
// Enable internal ADC detection
|
||||
power.enableBattDetection();
|
||||
power.enableVbusVoltageMeasure();
|
||||
power.enableBattVoltageMeasure();
|
||||
power.enableSystemVoltageMeasure();
|
||||
power.enableTemperatureMeasure();
|
||||
|
||||
|
||||
/*
|
||||
The default setting is CHGLED is automatically controlled by the PMU.
|
||||
- XPOWERS_CHG_LED_OFF,
|
||||
- XPOWERS_CHG_LED_BLINK_1HZ,
|
||||
- XPOWERS_CHG_LED_BLINK_4HZ,
|
||||
- XPOWERS_CHG_LED_ON,
|
||||
- XPOWERS_CHG_LED_CTRL_CHG,
|
||||
* */
|
||||
power.setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
|
||||
|
||||
|
||||
// Force add pull-up
|
||||
pinMode(pmu_irq_pin, INPUT_PULLUP);
|
||||
attachInterrupt(pmu_irq_pin, setFlag, FALLING);
|
||||
|
||||
|
||||
// Disable all interrupts
|
||||
power.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
// Clear all interrupt flags
|
||||
power.clearIrqStatus();
|
||||
// Enable the required interrupt function
|
||||
power.enableIRQ(
|
||||
XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ | //CHARGE
|
||||
XPOWERS_AXP2101_WARNING_LEVEL1_IRQ | XPOWERS_AXP2101_WARNING_LEVEL2_IRQ // LOW BATTER
|
||||
);
|
||||
|
||||
|
||||
// Get the default low pressure warning percentage setting
|
||||
uint8_t low_warn_per = power.getLowBatWarnThreshold();
|
||||
Serial.printf("Default low battery warning threshold is %d percentage\n", low_warn_per);
|
||||
|
||||
//
|
||||
// setLowBatWarnThreshold Range: 5% ~ 20%
|
||||
// The following data is obtained from actual testing , Please see the description below for the test method.
|
||||
// 20% ~= 3.7v
|
||||
// 15% ~= 3.6v
|
||||
// 10% ~= 3.55V
|
||||
// 5% ~= 3.5V
|
||||
// 1% ~= 3.4V
|
||||
power.setLowBatWarnThreshold(5); // Set to trigger interrupt when reaching 5%
|
||||
|
||||
// Get the low voltage warning percentage setting
|
||||
low_warn_per = power.getLowBatWarnThreshold();
|
||||
Serial.printf("Set low battery warning threshold is %d percentage\n", low_warn_per);
|
||||
|
||||
// Get the default low voltage shutdown percentage setting
|
||||
uint8_t low_shutdown_per = power.getLowBatShutdownThreshold();
|
||||
Serial.printf("Default low battery shutdown threshold is %d percentage\n", low_shutdown_per);
|
||||
|
||||
// setLowBatShutdownThreshold Range: 0% ~ 15%
|
||||
// The following data is obtained from actual testing , Please see the description below for the test method.
|
||||
// 15% ~= 3.6v
|
||||
// 10% ~= 3.55V
|
||||
// 5% ~= 3.5V
|
||||
// 1% ~= 3.4V
|
||||
power.setLowBatShutdownThreshold(1); // Set to trigger interrupt when reaching 1%
|
||||
|
||||
// Get the low voltage shutdown percentage setting
|
||||
low_shutdown_per = power.getLowBatShutdownThreshold();
|
||||
Serial.printf("Set low battery shutdown threshold is %d percentage\n", low_shutdown_per);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Measurement methods:
|
||||
* 1. Connect the battery terminal to a voltage stabilizing source
|
||||
* 2. Set voltage test voltage
|
||||
* 3. Press PWR to boot
|
||||
* 4. Read the serial output voltage percentage
|
||||
*
|
||||
* If a voltage regulator is connected during testing and the voltage is slowly reduced,
|
||||
* the voltage percentage will not change immediately. It will take a while to slowly decrease.
|
||||
* In actual production, it needs to be adjusted according to the actual situation.
|
||||
* * * */
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
if (millis() > interval) {
|
||||
|
||||
interval = millis() + 3000;
|
||||
|
||||
Serial.print("getBattVoltage:"); Serial.print(power.getBattVoltage()); Serial.println("mV");
|
||||
Serial.print("getVbusVoltage:"); Serial.print(power.getVbusVoltage()); Serial.println("mV");
|
||||
Serial.print("getSystemVoltage:"); Serial.print(power.getSystemVoltage()); Serial.println("mV");
|
||||
|
||||
// The battery percentage may be inaccurate at first use, the PMU will automatically
|
||||
// learn the battery curve and will automatically calibrate the battery percentage
|
||||
// after a charge and discharge cycle
|
||||
if (power.isBatteryConnect()) {
|
||||
Serial.print("getBatteryPercent:"); Serial.print(power.getBatteryPercent()); Serial.println("%");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
if (pmu_flag) {
|
||||
|
||||
pmu_flag = false;
|
||||
|
||||
// Get PMU Interrupt Status Register
|
||||
uint32_t status = power.getIrqStatus();
|
||||
Serial.print("STATUS => HEX:");
|
||||
Serial.print(status, HEX);
|
||||
Serial.print(" BIN:");
|
||||
Serial.println(status, BIN);
|
||||
|
||||
// When the set low-voltage battery percentage warning threshold is reached,
|
||||
// set the threshold through getLowBatWarnThreshold( 5% ~ 20% )
|
||||
if (power.isDropWarningLevel2Irq()) {
|
||||
Serial.println("The voltage percentage has reached the low voltage warning threshold!!!");
|
||||
}
|
||||
|
||||
// When the set low-voltage battery percentage shutdown threshold is reached
|
||||
// set the threshold through setLowBatShutdownThreshold()
|
||||
if (power.isDropWarningLevel1Irq()) {
|
||||
int i = 4;
|
||||
while (i--) {
|
||||
Serial.printf("The voltage percentage has reached the low voltage shutdown threshold and will shut down in %d seconds.\n", i);
|
||||
}
|
||||
// Turn off all power supplies, leaving only the RTC power supply. The RTC power supply cannot be turned off.
|
||||
power.shutdown();
|
||||
}
|
||||
if (power.isVbusInsertIrq()) {
|
||||
Serial.println("isVbusInsert");
|
||||
}
|
||||
if (power.isVbusRemoveIrq()) {
|
||||
Serial.println("isVbusRemove");
|
||||
}
|
||||
if (power.isBatInsertIrq()) {
|
||||
Serial.println("isBatInsert");
|
||||
}
|
||||
if (power.isBatRemoveIrq()) {
|
||||
Serial.println("isBatRemove");
|
||||
}
|
||||
if (power.isPekeyShortPressIrq()) {
|
||||
Serial.println("isPekeyShortPress");
|
||||
}
|
||||
|
||||
if (power.isPekeyLongPressIrq()) {
|
||||
Serial.println("isPekeyLongPress");
|
||||
}
|
||||
// Clear PMU Interrupt Status Register
|
||||
power.clearIrqStatus();
|
||||
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 lewis he
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//! @note In the experiment on T-SIM7080-ESP32, the power consumption is about 900uA after setting the PMU to sleep,
|
||||
//! and 1mA if it is not set to sleep. After setting the PMU to sleep, it can save about 100uA consumption current
|
||||
|
||||
#ifndef XPOWERS_NO_ERROR
|
||||
#error "Running this example is known to not damage the device! Please go and uncomment this!"
|
||||
#endif
|
||||
// Defined using AXP2102
|
||||
#define XPOWERS_CHIP_AXP2101
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Arduino.h>
|
||||
#include "XPowersLib.h"
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 15
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 7
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 6
|
||||
#endif
|
||||
|
||||
XPowersPMU power;
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
bool pmu_flag = false;
|
||||
bool adc_switch = false;
|
||||
|
||||
void setFlag(void)
|
||||
{
|
||||
pmu_flag = true;
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
bool result = power.begin(Wire, AXP2101_SLAVE_ADDRESS, i2c_sda, i2c_scl);
|
||||
|
||||
if (result == false) {
|
||||
Serial.println("PMU is not online..."); while (1)delay(50);
|
||||
}
|
||||
|
||||
// Force add pull-up
|
||||
pinMode(pmu_irq_pin, INPUT_PULLUP);
|
||||
attachInterrupt(pmu_irq_pin, setFlag, FALLING);
|
||||
|
||||
// Close other IRQs
|
||||
power.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
// Clear all interrupt flags
|
||||
power.clearIrqStatus();
|
||||
// Enable the required interrupt function
|
||||
power.enableIRQ(
|
||||
XPOWERS_AXP2101_PKEY_SHORT_IRQ //POWER KEY
|
||||
);
|
||||
|
||||
// Turn on the charging indicator light as a power-on indicator
|
||||
power.setChargingLedMode(XPOWERS_CHG_LED_ON);
|
||||
|
||||
// Enable chip temperature detection
|
||||
power.enableTemperatureMeasure();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (pmu_flag) {
|
||||
pmu_flag = false;
|
||||
// Get PMU Interrupt Status Register
|
||||
power.getIrqStatus();
|
||||
if (power.isPekeyShortPressIrq()) {
|
||||
|
||||
// Turn off the charging indicator to save power
|
||||
power.setChargingLedMode(XPOWERS_CHG_LED_OFF);
|
||||
|
||||
// Turn off ADC data monitoring to save power
|
||||
power.disableTemperatureMeasure();
|
||||
// Enable internal ADC detection
|
||||
power.disableBattDetection();
|
||||
power.disableVbusVoltageMeasure();
|
||||
power.disableBattVoltageMeasure();
|
||||
power.disableSystemVoltageMeasure();
|
||||
|
||||
|
||||
// Enable PMU sleep
|
||||
power.enableSleep();
|
||||
|
||||
// Reserve the MCU chip power supply, LilyGo AXP2101 usually uses DC as ESP power supply
|
||||
// power.enableDC1();
|
||||
|
||||
// Turn off the power output of other channels
|
||||
power.disableDC2();
|
||||
power.disableDC3();
|
||||
power.disableDC4();
|
||||
power.disableDC5();
|
||||
power.disableALDO1();
|
||||
power.disableALDO2();
|
||||
power.disableALDO3();
|
||||
power.disableALDO4();
|
||||
power.disableBLDO1();
|
||||
power.disableBLDO2();
|
||||
power.disableCPUSLDO();
|
||||
power.disableDLDO1();
|
||||
power.disableDLDO2();
|
||||
|
||||
// Clear PMU Interrupt Status Register
|
||||
power.clearIrqStatus();
|
||||
|
||||
// Send IRQ wakeup command
|
||||
power.enableWakeup();
|
||||
|
||||
#if !CONFIG_IDF_TARGET_ESP32S3
|
||||
Serial.println("Please implement the MCU sleep method");
|
||||
#else
|
||||
// Set ESP32 to wake up externally
|
||||
esp_sleep_enable_ext0_wakeup((gpio_num_t )pmu_irq_pin, LOW);
|
||||
|
||||
// Enable ESP32 sleep
|
||||
esp_deep_sleep_start();
|
||||
#endif
|
||||
|
||||
Serial.println("Here never prints . ");
|
||||
}
|
||||
}
|
||||
|
||||
// When not sleeping, print PMU temperature
|
||||
Serial.print("power Temperature:"); Serial.print(power.getTemperature()); Serial.println("*C");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 lewis he
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
#ifndef XPOWERS_NO_ERROR
|
||||
#error "Running this example is known to not damage the device! Please go and uncomment this!"
|
||||
#endif
|
||||
// Defined using AXP2102
|
||||
#define XPOWERS_CHIP_AXP2101
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Arduino.h>
|
||||
#include "XPowersLib.h"
|
||||
|
||||
XPowersPMU power;
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 22
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 35
|
||||
#endif
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
|
||||
uint16_t targetVol;
|
||||
uint16_t vol = 0;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
bool result = power.begin(Wire, AXP2101_SLAVE_ADDRESS, i2c_sda, i2c_scl);
|
||||
|
||||
if (result == false) {
|
||||
Serial.println("power is not online..."); while (1)delay(50);
|
||||
}
|
||||
|
||||
Serial.println("AXP2101 Power Output Test.");
|
||||
|
||||
|
||||
|
||||
power.disableDC2();
|
||||
power.disableDC3();
|
||||
power.disableDC4();
|
||||
power.disableDC5();
|
||||
power.disableALDO1();
|
||||
power.disableALDO2();
|
||||
power.disableALDO3();
|
||||
power.disableALDO4();
|
||||
power.disableBLDO1();
|
||||
power.disableBLDO2();
|
||||
power.disableCPUSLDO();
|
||||
power.disableDLDO1();
|
||||
power.disableDLDO2();
|
||||
|
||||
|
||||
// DC1 IMAX=2A
|
||||
// 1500~3400mV,100mV/step,20steps
|
||||
vol = 1500;
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
power.setDC1Voltage(vol);
|
||||
vol += 100;
|
||||
Serial.printf("DC1 :%s Voltage:%u mV \n", power.isEnableDC1() ? "ENABLE" : "DISABLE", power.getDC1Voltage());
|
||||
}
|
||||
|
||||
|
||||
// DC2 IMAX=2A
|
||||
// 500~1200mV 10mV/step,71steps
|
||||
vol = 500;
|
||||
for (int i = 0; i < 71; ++i) {
|
||||
power.setDC2Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getDC2Voltage();
|
||||
Serial.printf("[%d]DC2 :%s Voltage:%u mV \n", i, power.isEnableDC2() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 10;
|
||||
}
|
||||
|
||||
// DC2 IMAX=2A
|
||||
// 1220~1540mV 20mV/step,17steps
|
||||
vol = 1220;
|
||||
for (int i = 0; i < 17; ++i) {
|
||||
power.setDC2Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getDC2Voltage();
|
||||
Serial.printf("[%u]DC2 :%s Voltage:%u mV \n", i, power.isEnableDC2() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 20;
|
||||
}
|
||||
|
||||
// DC3 IMAX = 2A
|
||||
// 500~1200mV,10mV/step,71steps
|
||||
vol = 500;
|
||||
for (int i = 0; i < 71; ++i) {
|
||||
power.setDC3Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getDC3Voltage();
|
||||
Serial.printf("[%u]DC3 :%s Voltage:%u mV \n", i, power.isEnableDC3() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 10;
|
||||
}
|
||||
|
||||
// DC3 IMAX = 2A
|
||||
// 1220~1540mV,20mV/step,17steps
|
||||
vol = 1220;
|
||||
for (int i = 0; i < 17; ++i) {
|
||||
power.setDC3Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getDC3Voltage();
|
||||
Serial.printf("[%u]DC3 :%s Voltage:%u mV \n", i, power.isEnableDC3() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 20;
|
||||
}
|
||||
|
||||
|
||||
// DC3 IMAX = 2A
|
||||
// 1600~3400mV,100mV/step,19steps
|
||||
vol = 1600;
|
||||
for (int i = 0; i < 19; ++i) {
|
||||
power.setDC3Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getDC3Voltage();
|
||||
Serial.printf("[%u]DC3 :%s Voltage:%u mV \n", i, power.isEnableDC3() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 100;
|
||||
}
|
||||
|
||||
|
||||
// DCDC4 IMAX=1.5A
|
||||
// 500~1200mV,10mV/step,71steps
|
||||
vol = 500;
|
||||
for (int i = 0; i < 71; ++i) {
|
||||
power.setDC4Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getDC4Voltage();
|
||||
Serial.printf("[%u]DC4 :%s Voltage:%u mV \n", i, power.isEnableDC4() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 10;
|
||||
}
|
||||
|
||||
// DCDC4 IMAX=1.5A
|
||||
// 1220~1840mV,20mV/step,32steps
|
||||
vol = 1220;
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
power.setDC4Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getDC4Voltage();
|
||||
Serial.printf("[%u]DC4 :%s Voltage:%u mV \n", i, power.isEnableDC4() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 20;
|
||||
}
|
||||
|
||||
// DC5 IMAX=2A
|
||||
// 1200mV
|
||||
power.setDC5Voltage(1200);
|
||||
targetVol = power.getDC5Voltage();
|
||||
Serial.printf("[0]DC5 :%s Voltage:%u mV \n", power.isEnableDC5() ? "ENABLE" : "DISABLE", targetVol );
|
||||
|
||||
|
||||
// DC5 IMAX=2A
|
||||
// 1400~3700mV,100mV/step,24steps
|
||||
vol = 1400;
|
||||
for (int i = 0; i < 24; ++i) {
|
||||
power.setDC5Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getDC5Voltage();
|
||||
Serial.printf("[%u]DC5 :%s Voltage:%u mV \n", i, power.isEnableDC5() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 100;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//ALDO1 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
vol = 500;
|
||||
for (int i = 0; i < 31; ++i) {
|
||||
power.setALDO1Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getALDO1Voltage();
|
||||
Serial.printf("[%u]ALDO1 :%s Voltage:%u mV \n", i, power.isEnableALDO1() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 100;
|
||||
}
|
||||
|
||||
//ALDO2 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
vol = 500;
|
||||
for (int i = 0; i < 31; ++i) {
|
||||
power.setALDO2Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getALDO2Voltage();
|
||||
Serial.printf("[%u]ALDO2 :%s Voltage:%u mV \n", i, power.isEnableALDO2() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 100;
|
||||
}
|
||||
|
||||
//ALDO3 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
vol = 500;
|
||||
for (int i = 0; i < 31; ++i) {
|
||||
power.setALDO3Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getALDO3Voltage();
|
||||
Serial.printf("[%u]ALDO3 :%s Voltage:%u mV \n", i, power.isEnableALDO3() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 100;
|
||||
}
|
||||
|
||||
//ALDO4 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
vol = 500;
|
||||
for (int i = 0; i < 31; ++i) {
|
||||
power.setALDO4Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getALDO4Voltage();
|
||||
Serial.printf("[%u]ALDO4 :%s Voltage:%u mV \n", i, power.isEnableALDO4() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 100;
|
||||
}
|
||||
|
||||
//BLDO1 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
vol = 500;
|
||||
for (int i = 0; i < 31; ++i) {
|
||||
power.setBLDO1Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getBLDO1Voltage();
|
||||
Serial.printf("[%u]BLDO1 :%s Voltage:%u mV \n", i, power.isEnableBLDO1() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 100;
|
||||
}
|
||||
|
||||
//BLDO2 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
vol = 500;
|
||||
for (int i = 0; i < 31; ++i) {
|
||||
power.setBLDO2Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getBLDO2Voltage();
|
||||
Serial.printf("[%u]BLDO2 :%s Voltage:%u mV \n", i, power.isEnableBLDO2() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 100;
|
||||
}
|
||||
|
||||
|
||||
//CPUSLDO IMAX=30mA
|
||||
//500~1400mV,50mV/step,19steps
|
||||
vol = 500;
|
||||
for (int i = 0; i < 19; ++i) {
|
||||
power.setCPUSLDOVoltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getCPUSLDOVoltage();
|
||||
Serial.printf("[%u]CPUSLDO :%s Voltage:%u mV \n", i, power.isEnableCPUSLDO() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 50;
|
||||
}
|
||||
|
||||
//DLDO1 IMAX=300mA
|
||||
//500~3400mV, 100mV/step,29steps
|
||||
vol = 500;
|
||||
for (int i = 0; i < 29; ++i) {
|
||||
power.setDLDO1Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getDLDO1Voltage();
|
||||
Serial.printf("[%u]DLDO1 :%s Voltage:%u mV \n", i, power.isEnableDLDO1() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 100;
|
||||
}
|
||||
|
||||
//DLDO2 IMAX=300mA
|
||||
//500~1400mV, 50mV/step,2steps
|
||||
vol = 500;
|
||||
for (int i = 0; i < 29; ++i) {
|
||||
power.setDLDO2Voltage(vol);
|
||||
delay(1);
|
||||
targetVol = power.getDLDO2Voltage();
|
||||
Serial.printf("[%u]DLDO2 :%s Voltage:%u mV \n", i, power.isEnableDLDO2() ? "ENABLE" : "DISABLE", targetVol );
|
||||
if (targetVol != vol)Serial.println(">>> FAILED!");
|
||||
vol += 100;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
|
||||
// power.enableDC1();
|
||||
// power.enableDC2();
|
||||
// power.enableDC3();
|
||||
// power.enableDC4();
|
||||
// power.enableDC5();
|
||||
|
||||
// power.enableALDO1();
|
||||
// power.enableALDO2();
|
||||
// power.enableALDO3();
|
||||
// power.enableALDO4();
|
||||
|
||||
|
||||
// power.enableBLDO1();
|
||||
// power.enableBLDO2();
|
||||
|
||||
// power.enableCPUSLDO();
|
||||
|
||||
// power.enableDLDO1();
|
||||
// power.enableDLDO2();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
delay(10);
|
||||
}
|
||||
|
||||
176
XPowersLib/examples/BQ25896_Example/BQ25896_Example.ino
Normal file
176
XPowersLib/examples/BQ25896_Example/BQ25896_Example.ino
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* @file BQ25896_Example.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @license MIT
|
||||
* @copyright Copyright (c) 2024 Shenzhen Xin Yuan Electronic Technology Co., Ltd
|
||||
* @date 2024-06-04
|
||||
*
|
||||
*/
|
||||
|
||||
#define XPOWERS_CHIP_BQ25896
|
||||
|
||||
#include <XPowersLib.h>
|
||||
|
||||
XPowersPPM PPM;
|
||||
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 28
|
||||
#endif
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
uint32_t cycleInterval;
|
||||
bool pmu_irq = false;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
|
||||
bool result = PPM.init(Wire, i2c_sda, i2c_scl, BQ25896_SLAVE_ADDRESS);
|
||||
|
||||
if (result == false) {
|
||||
while (1) {
|
||||
Serial.println("PPM is not online...");
|
||||
delay(50);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the minimum operating voltage. Below this voltage, the PPM will protect
|
||||
PPM.setSysPowerDownVoltage(3300);
|
||||
|
||||
// Set input current limit, default is 500mA
|
||||
PPM.setInputCurrentLimit(3250);
|
||||
|
||||
Serial.printf("getInputCurrentLimit: %d mA\n", PPM.getInputCurrentLimit());
|
||||
|
||||
// Disable current limit pin
|
||||
PPM.disableCurrentLimitPin();
|
||||
|
||||
// Set the charging target voltage, Range:3840 ~ 4608mV ,step:16 mV
|
||||
PPM.setChargeTargetVoltage(4208);
|
||||
|
||||
// Set the precharge current , Range: 64mA ~ 1024mA ,step:64mA
|
||||
PPM.setPrechargeCurr(64);
|
||||
|
||||
// The premise is that Limit Pin is disabled, or it will only follow the maximum charging current set by Limi tPin.
|
||||
// Set the charging current , Range:0~5056mA ,step:64mA
|
||||
PPM.setChargerConstantCurr(1024);
|
||||
|
||||
// Get the set charging current
|
||||
PPM.getChargerConstantCurr();
|
||||
Serial.printf("getChargerConstantCurr: %d mA\n", PPM.getChargerConstantCurr());
|
||||
|
||||
|
||||
// To obtain voltage data, the ADC must be enabled first
|
||||
PPM.enableMeasure();
|
||||
|
||||
// Turn on charging function
|
||||
// If there is no battery connected, do not turn on the charging function
|
||||
PPM.enableCharge();
|
||||
|
||||
// Turn off charging function
|
||||
// If USB is used as the only power input, it is best to turn off the charging function,
|
||||
// otherwise the VSYS power supply will have a sawtooth wave, affecting the discharge output capability.
|
||||
// PPM.disableCharge();
|
||||
|
||||
|
||||
// The OTG function needs to enable OTG, and set the OTG control pin to HIGH
|
||||
// After OTG is enabled, if an external power supply is plugged in, OTG will be turned off
|
||||
|
||||
// PPM.enableOTG();
|
||||
// PPM.disableOTG();
|
||||
// pinMode(OTG_ENABLE_PIN, OUTPUT);
|
||||
// digitalWrite(OTG_ENABLE_PIN, HIGH);
|
||||
|
||||
pinMode(pmu_irq_pin, INPUT_PULLUP);
|
||||
attachInterrupt(pmu_irq_pin, []() {
|
||||
pmu_irq = true;
|
||||
}, FALLING);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (pmu_irq) {
|
||||
pmu_irq = false;
|
||||
|
||||
// Get PPM interrupt status
|
||||
PPM.getFaultStatus();
|
||||
|
||||
Serial.print("-> [");
|
||||
Serial.print(millis() / 1000);
|
||||
Serial.print("] ");
|
||||
|
||||
if (PPM.isWatchdogFault()) {
|
||||
|
||||
Serial.println("Watchdog Fault");
|
||||
|
||||
} else if (PPM.isBoostFault()) {
|
||||
|
||||
Serial.println("Boost Fault");
|
||||
|
||||
} else if (PPM.isChargeFault()) {
|
||||
|
||||
Serial.println("Charge Fault");
|
||||
|
||||
} else if (PPM.isBatteryFault()) {
|
||||
|
||||
Serial.println("Batter Fault");
|
||||
|
||||
} else if (PPM.isNTCFault()) {
|
||||
|
||||
Serial.print("NTC Fault:");
|
||||
Serial.print(PPM.getNTCStatusString());
|
||||
Serial.print(" Percentage:");
|
||||
Serial.print(PPM.getNTCPercentage()); Serial.println("%");
|
||||
} else {
|
||||
/*
|
||||
* When the battery is removed, INT will send an interrupt every 100ms. If the battery is not connected,
|
||||
* you can use PPM.disableCharge() to turn off the charging function.
|
||||
* */
|
||||
// PPM.disableCharge();
|
||||
|
||||
Serial.println("Battery remove");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtaining the battery voltage and battery charging status does not directly read the register,
|
||||
* but determines whether the charging current register is normal.
|
||||
* If read directly, the reading will be inaccurate.
|
||||
* The premise for obtaining these two states is that the NTC temperature measurement circuit is normal.
|
||||
* If the NTC detection is abnormal, it will return 0
|
||||
* * */
|
||||
if (millis() > cycleInterval) {
|
||||
Serial.printf("CHG TARGET VOLTAGE :%04dmV CURRENT:%04dmA PER_CHARGE_CUR %04dmA\n",
|
||||
PPM.getChargeTargetVoltage(), PPM.getChargerConstantCurr(), PPM.getPrechargeCurr());
|
||||
Serial.printf("VBUS:%s %04dmV VBAT:%04dmV VSYS:%04dmV\n", PPM.isVbusIn() ? "Connected" : "Disconnect",
|
||||
PPM.getVbusVoltage(),
|
||||
PPM.getBattVoltage(),
|
||||
PPM.getSystemVoltage());
|
||||
Serial.printf("BUS STATE:%d STR:%s\n", PPM.getBusStatus(), PPM.getBusStatusString());
|
||||
Serial.printf("CHG STATE:%d STR:%s CURRENT:%04dmA\n", PPM.chargeStatus(), PPM.getChargeStatusString(), PPM.getChargeCurrent());
|
||||
Serial.printf("[%lu]", millis() / 1000);
|
||||
Serial.println("----------------------------------------------------------------------------------");
|
||||
cycleInterval = millis() + 1000;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @file BQ25896_Shutdown_Example.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @license MIT
|
||||
* @copyright Copyright (c) 2024 Shenzhen Xin Yuan Electronic Technology Co., Ltd
|
||||
* @date 2024-06-04
|
||||
*
|
||||
*/
|
||||
#define XPOWERS_CHIP_BQ25896
|
||||
|
||||
#include <XPowersLib.h>
|
||||
|
||||
XPowersPPM PPM;
|
||||
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 28
|
||||
#endif
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
uint32_t cycleInterval;
|
||||
uint32_t countdown = 10;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
bool result = PPM.init(Wire, i2c_sda, i2c_scl, BQ25896_SLAVE_ADDRESS);
|
||||
if (result == false) {
|
||||
while (1) {
|
||||
Serial.println("PPM is not online...");
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (millis() > cycleInterval) {
|
||||
Serial.printf("%d\n", countdown);
|
||||
if (!(countdown--)) {
|
||||
Serial.println("Shutdown .....");
|
||||
// The shutdown function can only be used when the battery is connected alone,
|
||||
// and cannot be shut down when connected to USB.
|
||||
// It can only be powered on in the following two ways:
|
||||
// 1. Press the PPM/QON button
|
||||
// 2. Connect to USB
|
||||
PPM.shutdown();
|
||||
countdown = 10000;
|
||||
}
|
||||
cycleInterval = millis() + 1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
8
XPowersLib/examples/ESP_IDF_Example/CMakeLists.txt
Normal file
8
XPowersLib/examples/ESP_IDF_Example/CMakeLists.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
# The following five lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS ../../../XPowersLib)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(XPowersLib_Example)
|
||||
10
XPowersLib/examples/ESP_IDF_Example/Makefile
Normal file
10
XPowersLib/examples/ESP_IDF_Example/Makefile
Normal file
@@ -0,0 +1,10 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := XPowersLib_Example
|
||||
|
||||
EXTRA_COMPONENT_DIRS = ../../../XPowersLib
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
73
XPowersLib/examples/ESP_IDF_Example/README.md
Normal file
73
XPowersLib/examples/ESP_IDF_Example/README.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# XPowersLib Example
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Please put XPowersLib and esp-idf in the same level directory, after configuring the esp-idf environment variable, enter `XPowersLib/examples/ESP_IDF_Example` and run the idf.py command directly
|
||||
|
||||
|
||||
### Configure the Project
|
||||
|
||||
Open the project configuration menu (`idf.py menuconfig`).
|
||||
|
||||
In the `XPowers Configuration` menu:
|
||||
|
||||
* Select the PMU Type in the `PMU_Type` option.
|
||||
* In `PMU SCL GPIO Num` select the clock pin to connect to the PMU,the default is 22
|
||||
* In `PMU SDAGPIO Num` select the data pin connected to the PMU,the default is 21
|
||||
* Select the interrupt pin connected to the PMU in `PMU Interrupt Pin`, the default is 35
|
||||
|
||||
## How to Use Example
|
||||
|
||||
Before project configuration and build, be sure to set the correct chip target using `idf.py set-target <chip_name>`.
|
||||
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
The output information is to configure the output voltage and enable status of the PMU
|
||||
|
||||
```
|
||||
I (345) mian: I2C initialized successfully
|
||||
I (355) AXP2101: Init PMU SUCCESS!
|
||||
I (385) AXP2101: DCDC=======================================================================
|
||||
I (385) AXP2101: DC1 :ENABLE Voltage:3300 mV
|
||||
I (385) AXP2101: DC2 :DISABLE Voltage:900 mV
|
||||
I (395) AXP2101: DC3 :ENABLE Voltage:3300 mV
|
||||
I (395) AXP2101: DC4 :DISABLE Voltage:1100 mV
|
||||
I (405) AXP2101: DC5 :DISABLE Voltage:1200 mV
|
||||
I (405) AXP2101: ALDO=======================================================================
|
||||
I (415) AXP2101: ALDO1:ENABLE Voltage:1800 mV
|
||||
I (425) AXP2101: ALDO2:ENABLE Voltage:2800 mV
|
||||
I (425) AXP2101: ALDO3:ENABLE Voltage:3300 mV
|
||||
I (435) AXP2101: ALDO4:ENABLE Voltage:3000 mV
|
||||
I (435) AXP2101: BLDO=======================================================================
|
||||
I (445) AXP2101: BLDO1:ENABLE Voltage:3300 mV
|
||||
```
|
||||
|
||||
## Build process example
|
||||
|
||||
Assuming you don't have esp-idf yet
|
||||
|
||||
```
|
||||
mkdir -p ~/esp
|
||||
cd ~/esp
|
||||
git clone --recursive https://github.com/espressif/esp-idf.git
|
||||
git clone https://github.com/lewisxhe/XPowersLib.git
|
||||
cd esp-idf
|
||||
./install.sh
|
||||
. ./export.sh
|
||||
cd ..
|
||||
cd XPowersLib/examples/ESP_IDF_Example
|
||||
idf.py menuconfig
|
||||
idf.py build
|
||||
idf.py -b 921600 flash
|
||||
idf.py monitor
|
||||
|
||||
```
|
||||
5
XPowersLib/examples/ESP_IDF_Example/main/CMakeLists.txt
Normal file
5
XPowersLib/examples/ESP_IDF_Example/main/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
idf_component_register(SRCS "main.cpp"
|
||||
"port_axp192.cpp"
|
||||
"port_axp2101.cpp"
|
||||
"port_i2c.cpp"
|
||||
INCLUDE_DIRS ".")
|
||||
59
XPowersLib/examples/ESP_IDF_Example/main/Kconfig.projbuild
Normal file
59
XPowersLib/examples/ESP_IDF_Example/main/Kconfig.projbuild
Normal file
@@ -0,0 +1,59 @@
|
||||
menu "XPowersLib Configuration"
|
||||
|
||||
choice PMU_Type
|
||||
prompt "XPowers chip type"
|
||||
default XPOWERS_CHIP_AXP2101 if IDF_TARGET_ESP32
|
||||
default XPOWERS_CHIP_AXP192
|
||||
help
|
||||
Defines the default peripheral for xpowers example
|
||||
|
||||
config XPOWERS_CHIP_AXP2101
|
||||
bool "Xpowers AXP2101"
|
||||
config XPOWERS_CHIP_AXP192
|
||||
bool "Xpowers AXP192"
|
||||
endchoice
|
||||
|
||||
choice I2C_COMMUNICATION_METHOD
|
||||
prompt "XPowersLIb read and write methods"
|
||||
default I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
help
|
||||
Define XPowersLIb read and write methods
|
||||
|
||||
config I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
bool "Implemented using built-in read and write methods"
|
||||
config I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
bool "Implemented using read and write callback methods"
|
||||
endchoice
|
||||
|
||||
config I2C_MASTER_PORT_NUM
|
||||
int "PMU I2C Port Number"
|
||||
default 1
|
||||
help
|
||||
Port number for I2C Master device.
|
||||
|
||||
config I2C_MASTER_FREQUENCY
|
||||
int "Master Frequency"
|
||||
default 100000
|
||||
help
|
||||
I2C Speed of Master device.
|
||||
|
||||
config PMU_I2C_SCL
|
||||
int "PMU SCL GPIO Num"
|
||||
default 22
|
||||
help
|
||||
GPIO number for I2C PMU clock line.
|
||||
|
||||
config PMU_I2C_SDA
|
||||
int "PMU SDA GPIO Num"
|
||||
default 21
|
||||
help
|
||||
GPIO number for I2C PMU data line.
|
||||
|
||||
config PMU_INTERRUPT_PIN
|
||||
int "PMU Interrupt Pin"
|
||||
default 35
|
||||
help
|
||||
PMU interrupt pin.
|
||||
|
||||
|
||||
endmenu
|
||||
4
XPowersLib/examples/ESP_IDF_Example/main/component.mk
Normal file
4
XPowersLib/examples/ESP_IDF_Example/main/component.mk
Normal file
@@ -0,0 +1,4 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
90
XPowersLib/examples/ESP_IDF_Example/main/main.cpp
Normal file
90
XPowersLib/examples/ESP_IDF_Example/main/main.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#define PMU_INPUT_PIN (gpio_num_t)CONFIG_PMU_INTERRUPT_PIN /*!< axp power chip interrupt Pin*/
|
||||
#define PMU_INPUT_PIN_SEL (1ULL<<PMU_INPUT_PIN)
|
||||
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
#ifndef XPOWERS_NO_ERROR
|
||||
#error "Running this example is known to not damage the device! Please go and uncomment this!"
|
||||
#endif
|
||||
|
||||
static const char *TAG = "mian";
|
||||
|
||||
extern esp_err_t pmu_init();
|
||||
extern esp_err_t i2c_init(void);
|
||||
extern void pmu_isr_handler();
|
||||
|
||||
static void pmu_handler_task(void *);
|
||||
static QueueHandle_t gpio_evt_queue = NULL;
|
||||
|
||||
static void IRAM_ATTR pmu_irq_handler(void *arg)
|
||||
{
|
||||
uint32_t gpio_num = (uint32_t) arg;
|
||||
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
|
||||
}
|
||||
|
||||
static void irq_init()
|
||||
{
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_INTR_NEGEDGE;
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
io_conf.pin_bit_mask = PMU_INPUT_PIN_SEL;
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||
gpio_config(&io_conf);
|
||||
gpio_set_intr_type(PMU_INPUT_PIN, GPIO_INTR_NEGEDGE);
|
||||
//install gpio isr service
|
||||
gpio_install_isr_service(0);
|
||||
//hook isr handler for specific gpio pin
|
||||
gpio_isr_handler_add(PMU_INPUT_PIN, pmu_irq_handler, (void *) PMU_INPUT_PIN);
|
||||
|
||||
}
|
||||
|
||||
extern "C" void app_main(void)
|
||||
{
|
||||
//create a queue to handle gpio event from isr
|
||||
gpio_evt_queue = xQueueCreate(5, sizeof(uint32_t));
|
||||
|
||||
// Register PMU interrupt pins
|
||||
irq_init();
|
||||
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW || \
|
||||
((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API))
|
||||
ESP_ERROR_CHECK(i2c_init());
|
||||
ESP_LOGI(TAG, "I2C initialized successfully");
|
||||
#endif
|
||||
|
||||
ESP_ERROR_CHECK(pmu_init());
|
||||
|
||||
xTaskCreate(pmu_handler_task, "App/pwr", 4 * 1024, NULL, 10, NULL);
|
||||
|
||||
ESP_LOGI(TAG, "Run...");
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void pmu_handler_task(void *args)
|
||||
{
|
||||
uint32_t io_num;
|
||||
while (1) {
|
||||
if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
|
||||
pmu_isr_handler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
325
XPowersLib/examples/ESP_IDF_Example/main/port_axp192.cpp
Normal file
325
XPowersLib/examples/ESP_IDF_Example/main/port_axp192.cpp
Normal file
@@ -0,0 +1,325 @@
|
||||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef CONFIG_XPOWERS_CHIP_AXP192
|
||||
|
||||
#define XPOWERS_CHIP_AXP192
|
||||
#include "XPowersLib.h"
|
||||
static const char *TAG = "AXP192";
|
||||
|
||||
XPowersPMU power;
|
||||
|
||||
extern int pmu_register_read(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len);
|
||||
extern int pmu_register_write_byte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len);
|
||||
|
||||
|
||||
esp_err_t pmu_init()
|
||||
{
|
||||
//* Implemented using read and write callback methods, applicable to other platforms
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods");
|
||||
if (power.begin(AXP192_SLAVE_ADDRESS, pmu_register_read, pmu_register_write_byte)) {
|
||||
ESP_LOGI(TAG, "Init PMU SUCCESS!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Init PMU FAILED!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//* Use the built-in esp-idf communication method
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)");
|
||||
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
|
||||
// * which is useful when the bus shares multiple devices.
|
||||
extern i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
if (power.begin(bus_handle, AXP192_SLAVE_ADDRESS)) {
|
||||
ESP_LOGI(TAG, "Init PMU SUCCESS!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Init PMU FAILED!");
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)");
|
||||
|
||||
if (power.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, AXP192_SLAVE_ADDRESS, CONFIG_PMU_I2C_SDA, CONFIG_PMU_I2C_SCL)) {
|
||||
ESP_LOGI(TAG, "Init PMU SUCCESS!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Init PMU FAILED!");
|
||||
return false;
|
||||
}
|
||||
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
|
||||
#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
|
||||
ESP_LOGI(TAG, "getID:0x%x", power.getChipID());
|
||||
|
||||
// Set the minimum system operating voltage inside the PMU,
|
||||
// below this value will shut down the PMU
|
||||
// Range: 2600~3300mV
|
||||
power.setSysPowerDownVoltage(2700);
|
||||
|
||||
// Set the minimum common working voltage of the PMU VBUS input,
|
||||
// below this value will turn off the PMU
|
||||
power.setVbusVoltageLimit(XPOWERS_AXP192_VBUS_VOL_LIM_4V5);
|
||||
|
||||
// Turn off USB input current limit
|
||||
power.setVbusCurrentLimit(XPOWERS_AXP192_VBUS_CUR_LIM_OFF);
|
||||
|
||||
// DC1 700~3500mV, IMAX=1.2A
|
||||
power.setDC1Voltage(3300);
|
||||
ESP_LOGI(TAG, "DC1 :%s Voltage:%u mV ", power.isEnableDC1() ? "ENABLE" : "DISABLE", power.getDC1Voltage());
|
||||
|
||||
// DC2 700~2750mV, IMAX=1.6A;
|
||||
power.setDC2Voltage(700);
|
||||
ESP_LOGI(TAG, "DC2 :%s Voltage:%u mV ", power.isEnableDC2() ? "ENABLE" : "DISABLE", power.getDC2Voltage());
|
||||
|
||||
// DC3 700~3500mV,IMAX=0.7A;
|
||||
power.setDC3Voltage(3300);
|
||||
ESP_LOGI(TAG, "DC3 :%s Voltage:%u mV ", power.isEnableDC3() ? "ENABLE" : "DISABLE", power.getDC3Voltage());
|
||||
|
||||
|
||||
//LDO2 1800~3300V, 100mV/step, IMAX=200mA
|
||||
power.setLDO2Voltage(1800);
|
||||
|
||||
//LDO3 1800~3300V, 100mV/step, IMAX=200mA
|
||||
power.setLDO3Voltage(1800);
|
||||
|
||||
//LDOio 1800~3300V, 100mV/step, IMAX=50mA
|
||||
power.setLDOioVoltage(3300);
|
||||
|
||||
|
||||
// Enable power output channel
|
||||
// power.enableDC1();
|
||||
power.enableDC2();
|
||||
power.enableDC3();
|
||||
power.enableLDO2();
|
||||
power.enableLDO3();
|
||||
power.enableLDOio();
|
||||
|
||||
ESP_LOGI(TAG, "DCDC=======================================================================\n");
|
||||
ESP_LOGI(TAG, "DC1 :%s Voltage:%u mV \n", power.isEnableDC1() ? "ENABLE" : "DISABLE", power.getDC1Voltage());
|
||||
ESP_LOGI(TAG, "DC2 :%s Voltage:%u mV \n", power.isEnableDC2() ? "ENABLE" : "DISABLE", power.getDC2Voltage());
|
||||
ESP_LOGI(TAG, "DC3 :%s Voltage:%u mV \n", power.isEnableDC3() ? "ENABLE" : "DISABLE", power.getDC3Voltage());
|
||||
ESP_LOGI(TAG, "LDO=======================================================================\n");
|
||||
ESP_LOGI(TAG, "LDO2: %s Voltage:%u mV\n", power.isEnableLDO2() ? "ENABLE" : "DISABLE", power.getLDO2Voltage());
|
||||
ESP_LOGI(TAG, "LDO3: %s Voltage:%u mV\n", power.isEnableLDO3() ? "ENABLE" : "DISABLE", power.getLDO3Voltage());
|
||||
ESP_LOGI(TAG, "LDOio: %s Voltage:%u mV\n", power.isEnableLDOio() ? "ENABLE" : "DISABLE", power.getLDOioVoltage());
|
||||
ESP_LOGI(TAG, "==========================================================================\n");
|
||||
|
||||
// Set the time of pressing the button to turn off
|
||||
power.setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
|
||||
uint8_t opt = power.getPowerKeyPressOffTime();
|
||||
ESP_LOGI(TAG, "PowerKeyPressOffTime:");
|
||||
switch (opt) {
|
||||
case XPOWERS_POWEROFF_4S: ESP_LOGI(TAG, "4 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_6S: ESP_LOGI(TAG, "6 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_8S: ESP_LOGI(TAG, "8 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_10S: ESP_LOGI(TAG, "10 Second");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Set the button power-on press time
|
||||
power.setPowerKeyPressOnTime(XPOWERS_POWERON_128MS);
|
||||
opt = power.getPowerKeyPressOnTime();
|
||||
ESP_LOGI(TAG, "PowerKeyPressOnTime:");
|
||||
switch (opt) {
|
||||
case XPOWERS_POWERON_128MS: ESP_LOGI(TAG, "128 Ms");
|
||||
break;
|
||||
case XPOWERS_POWERON_512MS: ESP_LOGI(TAG, "512 Ms");
|
||||
break;
|
||||
case XPOWERS_POWERON_1S: ESP_LOGI(TAG, "1 Second");
|
||||
break;
|
||||
case XPOWERS_POWERON_2S: ESP_LOGI(TAG, "2 Second");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "===========================================================================");
|
||||
|
||||
// It is necessary to disable the detection function of the TS pin on the board
|
||||
// without the battery temperature detection function, otherwise it will cause abnormal charging
|
||||
power.disableTSPinMeasure();
|
||||
|
||||
// power.enableTemperatureMeasure();
|
||||
// power.disableTemperatureMeasure();
|
||||
|
||||
// Enable internal ADC detection
|
||||
power.enableBattDetection();
|
||||
power.enableVbusVoltageMeasure();
|
||||
power.enableBattVoltageMeasure();
|
||||
power.enableSystemVoltageMeasure();
|
||||
|
||||
/*
|
||||
The default setting is CHGLED is automatically controlled by the PMU.
|
||||
- XPOWERS_CHG_LED_OFF,
|
||||
- XPOWERS_CHG_LED_BLINK_1HZ,
|
||||
- XPOWERS_CHG_LED_BLINK_4HZ,
|
||||
- XPOWERS_CHG_LED_ON,
|
||||
- XPOWERS_CHG_LED_CTRL_CHG,
|
||||
* */
|
||||
power.setChargingLedMode(XPOWERS_CHG_LED_OFF);
|
||||
|
||||
// Disable all interrupts
|
||||
power.disableIRQ(XPOWERS_AXP192_ALL_IRQ);
|
||||
// Clear all interrupt flags
|
||||
power.clearIrqStatus();
|
||||
// Enable the required interrupt function
|
||||
power.enableIRQ(
|
||||
XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_BAT_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_VBUS_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP192_PKEY_SHORT_IRQ | XPOWERS_AXP192_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP192_BAT_CHG_DONE_IRQ | XPOWERS_AXP192_BAT_CHG_START_IRQ | //CHARGE
|
||||
// XPOWERS_AXP192_PKEY_NEGATIVE_IRQ | XPOWERS_AXP192_PKEY_POSITIVE_IRQ | //POWER KEY
|
||||
XPOWERS_AXP192_TIMER_TIMEOUT_IRQ //Timer
|
||||
);
|
||||
|
||||
// Set constant current charge current limit
|
||||
power.setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_280MA);
|
||||
// Set stop charging termination current
|
||||
power.setChargerTerminationCurr(XPOWERS_AXP192_CHG_ITERM_LESS_10_PERCENT);
|
||||
|
||||
// Set charge cut-off voltage
|
||||
power.setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2);
|
||||
|
||||
// Cache writes and reads, as long as the PMU remains powered, the data will always be stored inside the PMU
|
||||
ESP_LOGI(TAG, "Write pmu data buffer .");
|
||||
uint8_t data[XPOWERS_AXP192_DATA_BUFFER_SIZE] = {1, 2, 3, 4, 5, 6};
|
||||
power.writeDataBuffer(data, XPOWERS_AXP192_DATA_BUFFER_SIZE);
|
||||
memset(data, 0, XPOWERS_AXP192_DATA_BUFFER_SIZE);
|
||||
|
||||
ESP_LOGI(TAG, "Read pmu data buffer :");
|
||||
power.readDataBuffer(data, XPOWERS_AXP192_DATA_BUFFER_SIZE);
|
||||
ESP_LOG_BUFFER_HEX(TAG, data, XPOWERS_AXP192_DATA_BUFFER_SIZE);
|
||||
|
||||
// Set the timing after one minute, the isWdtExpireIrq will be triggered in the loop interrupt function
|
||||
power.setTimerout(1);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
void pmu_isr_handler()
|
||||
{
|
||||
// Get PMU Interrupt Status Register
|
||||
power.getIrqStatus();
|
||||
|
||||
if (power.isAcinOverVoltageIrq()) {
|
||||
ESP_LOGI(TAG, "isAcinOverVoltageIrq");
|
||||
}
|
||||
if (power.isAcinInserIrq()) {
|
||||
ESP_LOGI(TAG, "isAcinInserIrq");
|
||||
}
|
||||
if (power.isAcinRemoveIrq()) {
|
||||
ESP_LOGI(TAG, "isAcinRemoveIrq");
|
||||
}
|
||||
if (power.isVbusOverVoltageIrq()) {
|
||||
ESP_LOGI(TAG, "isVbusOverVoltageIrq");
|
||||
}
|
||||
if (power.isVbusInsertIrq()) {
|
||||
ESP_LOGI(TAG, "isVbusInsertIrq");
|
||||
}
|
||||
if (power.isVbusRemoveIrq()) {
|
||||
ESP_LOGI(TAG, "isVbusRemoveIrq");
|
||||
}
|
||||
if (power.isVbusLowVholdIrq()) {
|
||||
ESP_LOGI(TAG, "isVbusLowVholdIrq");
|
||||
}
|
||||
if (power.isBatInsertIrq()) {
|
||||
ESP_LOGI(TAG, "isBatInsertIrq");
|
||||
}
|
||||
if (power.isBatRemoveIrq()) {
|
||||
ESP_LOGI(TAG, "isBatRemoveIrq");
|
||||
}
|
||||
if (power.isBattEnterActivateIrq()) {
|
||||
ESP_LOGI(TAG, "isBattEnterActivateIrq");
|
||||
}
|
||||
if (power.isBattExitActivateIrq()) {
|
||||
ESP_LOGI(TAG, "isBattExitActivateIrq");
|
||||
}
|
||||
if (power.isBatChargeStartIrq()) {
|
||||
ESP_LOGI(TAG, "isBatChargeStartIrq");
|
||||
}
|
||||
if (power.isBatChargeDoneIrq()) {
|
||||
ESP_LOGI(TAG, "isBatChargeDoneIrq");
|
||||
}
|
||||
if (power.isBattTempHighIrq()) {
|
||||
ESP_LOGI(TAG, "isBattTempHighIrq");
|
||||
}
|
||||
if (power.isBattTempLowIrq()) {
|
||||
ESP_LOGI(TAG, "isBattTempLowIrq");
|
||||
}
|
||||
if (power.isChipOverTemperatureIrq()) {
|
||||
ESP_LOGI(TAG, "isChipOverTemperatureIrq");
|
||||
}
|
||||
if (power.isChargingCurrentLessIrq()) {
|
||||
ESP_LOGI(TAG, "isChargingCurrentLessIrq");
|
||||
}
|
||||
if (power.isDC1VoltageLessIrq()) {
|
||||
ESP_LOGI(TAG, "isDC1VoltageLessIrq");
|
||||
}
|
||||
if (power.isDC2VoltageLessIrq()) {
|
||||
ESP_LOGI(TAG, "isDC2VoltageLessIrq");
|
||||
}
|
||||
if (power.isDC3VoltageLessIrq()) {
|
||||
ESP_LOGI(TAG, "isDC3VoltageLessIrq");
|
||||
}
|
||||
if (power.isPekeyShortPressIrq()) {
|
||||
ESP_LOGI(TAG, "isPekeyShortPress");
|
||||
// enterPmuSleep();
|
||||
}
|
||||
if (power.isPekeyLongPressIrq()) {
|
||||
ESP_LOGI(TAG, "isPekeyLongPress");
|
||||
|
||||
}
|
||||
if (power.isNOEPowerOnIrq()) {
|
||||
ESP_LOGI(TAG, "isNOEPowerOnIrq");
|
||||
}
|
||||
if (power.isNOEPowerDownIrq()) {
|
||||
ESP_LOGI(TAG, "isNOEPowerDownIrq");
|
||||
}
|
||||
if (power.isVbusEffectiveIrq()) {
|
||||
ESP_LOGI(TAG, "isVbusEffectiveIrq");
|
||||
}
|
||||
if (power.isVbusInvalidIrq()) {
|
||||
ESP_LOGI(TAG, "isVbusInvalidIrq");
|
||||
}
|
||||
if (power.isVbusSessionIrq()) {
|
||||
ESP_LOGI(TAG, "isVbusSessionIrq");
|
||||
}
|
||||
if (power.isVbusSessionEndIrq()) {
|
||||
ESP_LOGI(TAG, "isVbusSessionEndIrq");
|
||||
}
|
||||
if (power.isLowVoltageLevel2Irq()) {
|
||||
ESP_LOGI(TAG, "isLowVoltageLevel2Irq");
|
||||
}
|
||||
if (power.isWdtExpireIrq()) {
|
||||
ESP_LOGI(TAG, "isWdtExpire");
|
||||
// Clear the timer state and continue to the next timer
|
||||
power.clearTimerFlag();
|
||||
}
|
||||
if (power.isGpio2EdgeTriggerIrq()) {
|
||||
ESP_LOGI(TAG, "isGpio2EdgeTriggerIrq");
|
||||
}
|
||||
if (power.isGpio1EdgeTriggerIrq()) {
|
||||
ESP_LOGI(TAG, "isGpio1EdgeTriggerIrq");
|
||||
}
|
||||
if (power.isGpio0EdgeTriggerIrq()) {
|
||||
ESP_LOGI(TAG, "isGpio0EdgeTriggerIrq");
|
||||
}
|
||||
// Clear PMU Interrupt Status Register
|
||||
power.clearIrqStatus();
|
||||
}
|
||||
#endif /*CONFIG_XPOWERS_AXP192_CHIP_AXP192*/
|
||||
|
||||
|
||||
263
XPowersLib/examples/ESP_IDF_Example/main/port_axp2101.cpp
Normal file
263
XPowersLib/examples/ESP_IDF_Example/main/port_axp2101.cpp
Normal file
@@ -0,0 +1,263 @@
|
||||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef CONFIG_XPOWERS_CHIP_AXP2101
|
||||
|
||||
#define XPOWERS_CHIP_AXP2101
|
||||
#include "XPowersLib.h"
|
||||
static const char *TAG = "AXP2101";
|
||||
|
||||
static XPowersPMU power;
|
||||
|
||||
extern int pmu_register_read(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len);
|
||||
extern int pmu_register_write_byte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len);
|
||||
|
||||
|
||||
esp_err_t pmu_init()
|
||||
{
|
||||
//* Implemented using read and write callback methods, applicable to other platforms
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods");
|
||||
if (power.begin(AXP2101_SLAVE_ADDRESS, pmu_register_read, pmu_register_write_byte)) {
|
||||
ESP_LOGI(TAG, "Init PMU SUCCESS!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Init PMU FAILED!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//* Use the built-in esp-idf communication method
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)");
|
||||
|
||||
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
|
||||
// * which is useful when the bus shares multiple devices.
|
||||
extern i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
if (power.begin(bus_handle, AXP2101_SLAVE_ADDRESS)) {
|
||||
ESP_LOGI(TAG, "Init PMU SUCCESS!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Init PMU FAILED!");
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)");
|
||||
|
||||
if (power.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, AXP2101_SLAVE_ADDRESS, CONFIG_PMU_I2C_SDA, CONFIG_PMU_I2C_SCL)) {
|
||||
ESP_LOGI(TAG, "Init PMU SUCCESS!");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Init PMU FAILED!");
|
||||
return false;
|
||||
}
|
||||
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
|
||||
#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
|
||||
|
||||
//Turn off not use power channel
|
||||
power.disableDC2();
|
||||
power.disableDC3();
|
||||
power.disableDC4();
|
||||
power.disableDC5();
|
||||
|
||||
power.disableALDO1();
|
||||
power.disableALDO2();
|
||||
power.disableALDO3();
|
||||
power.disableALDO4();
|
||||
power.disableBLDO1();
|
||||
power.disableBLDO2();
|
||||
|
||||
power.disableCPUSLDO();
|
||||
power.disableDLDO1();
|
||||
power.disableDLDO2();
|
||||
|
||||
|
||||
//ESP32s3 Core VDD
|
||||
power.setDC3Voltage(3300);
|
||||
power.enableDC3();
|
||||
|
||||
//Extern 3.3V VDD
|
||||
power.setDC1Voltage(3300);
|
||||
power.enableDC1();
|
||||
|
||||
// CAM DVDD 1500~1800
|
||||
power.setALDO1Voltage(1800);
|
||||
// power.setALDO1Voltage(1500);
|
||||
power.enableALDO1();
|
||||
|
||||
// CAM DVDD 2500~2800
|
||||
power.setALDO2Voltage(2800);
|
||||
power.enableALDO2();
|
||||
|
||||
// CAM AVDD 2800~3000
|
||||
power.setALDO4Voltage(3000);
|
||||
power.enableALDO4();
|
||||
|
||||
// PIR VDD 3300
|
||||
power.setALDO3Voltage(3300);
|
||||
power.enableALDO3();
|
||||
|
||||
// OLED VDD 3300
|
||||
power.setBLDO1Voltage(3300);
|
||||
power.enableBLDO1();
|
||||
|
||||
// MIC VDD 33000
|
||||
power.setBLDO2Voltage(3300);
|
||||
power.enableBLDO2();
|
||||
|
||||
ESP_LOGI(TAG, "DCDC=======================================================================\n");
|
||||
ESP_LOGI(TAG, "DC1 : %s Voltage:%u mV \n", power.isEnableDC1() ? "+" : "-", power.getDC1Voltage());
|
||||
ESP_LOGI(TAG, "DC2 : %s Voltage:%u mV \n", power.isEnableDC2() ? "+" : "-", power.getDC2Voltage());
|
||||
ESP_LOGI(TAG, "DC3 : %s Voltage:%u mV \n", power.isEnableDC3() ? "+" : "-", power.getDC3Voltage());
|
||||
ESP_LOGI(TAG, "DC4 : %s Voltage:%u mV \n", power.isEnableDC4() ? "+" : "-", power.getDC4Voltage());
|
||||
ESP_LOGI(TAG, "DC5 : %s Voltage:%u mV \n", power.isEnableDC5() ? "+" : "-", power.getDC5Voltage());
|
||||
ESP_LOGI(TAG, "ALDO=======================================================================\n");
|
||||
ESP_LOGI(TAG, "ALDO1: %s Voltage:%u mV\n", power.isEnableALDO1() ? "+" : "-", power.getALDO1Voltage());
|
||||
ESP_LOGI(TAG, "ALDO2: %s Voltage:%u mV\n", power.isEnableALDO2() ? "+" : "-", power.getALDO2Voltage());
|
||||
ESP_LOGI(TAG, "ALDO3: %s Voltage:%u mV\n", power.isEnableALDO3() ? "+" : "-", power.getALDO3Voltage());
|
||||
ESP_LOGI(TAG, "ALDO4: %s Voltage:%u mV\n", power.isEnableALDO4() ? "+" : "-", power.getALDO4Voltage());
|
||||
ESP_LOGI(TAG, "BLDO=======================================================================\n");
|
||||
ESP_LOGI(TAG, "BLDO1: %s Voltage:%u mV\n", power.isEnableBLDO1() ? "+" : "-", power.getBLDO1Voltage());
|
||||
ESP_LOGI(TAG, "BLDO2: %s Voltage:%u mV\n", power.isEnableBLDO2() ? "+" : "-", power.getBLDO2Voltage());
|
||||
ESP_LOGI(TAG, "CPUSLDO====================================================================\n");
|
||||
ESP_LOGI(TAG, "CPUSLDO: %s Voltage:%u mV\n", power.isEnableCPUSLDO() ? "+" : "-", power.getCPUSLDOVoltage());
|
||||
ESP_LOGI(TAG, "DLDO=======================================================================\n");
|
||||
ESP_LOGI(TAG, "DLDO1: %s Voltage:%u mV\n", power.isEnableDLDO1() ? "+" : "-", power.getDLDO1Voltage());
|
||||
ESP_LOGI(TAG, "DLDO2: %s Voltage:%u mV\n", power.isEnableDLDO2() ? "+" : "-", power.getDLDO2Voltage());
|
||||
ESP_LOGI(TAG, "===========================================================================\n");
|
||||
|
||||
power.clearIrqStatus();
|
||||
|
||||
power.enableVbusVoltageMeasure();
|
||||
power.enableBattVoltageMeasure();
|
||||
power.enableSystemVoltageMeasure();
|
||||
power.enableTemperatureMeasure();
|
||||
|
||||
// It is necessary to disable the detection function of the TS pin on the board
|
||||
// without the battery temperature detection function, otherwise it will cause abnormal charging
|
||||
power.disableTSPinMeasure();
|
||||
|
||||
// Disable all interrupts
|
||||
power.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
// Clear all interrupt flags
|
||||
power.clearIrqStatus();
|
||||
// Enable the required interrupt function
|
||||
power.enableIRQ(
|
||||
XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ //CHARGE
|
||||
// XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ | XPOWERS_AXP2101_PKEY_POSITIVE_IRQ | //POWER KEY
|
||||
);
|
||||
|
||||
/*
|
||||
The default setting is CHGLED is automatically controlled by the power.
|
||||
- XPOWERS_CHG_LED_OFF,
|
||||
- XPOWERS_CHG_LED_BLINK_1HZ,
|
||||
- XPOWERS_CHG_LED_BLINK_4HZ,
|
||||
- XPOWERS_CHG_LED_ON,
|
||||
- XPOWERS_CHG_LED_CTRL_CHG,
|
||||
* */
|
||||
power.setChargingLedMode(XPOWERS_CHG_LED_BLINK_1HZ);
|
||||
|
||||
// Set the precharge charging current
|
||||
power.setPrechargeCurr(XPOWERS_AXP2101_PRECHARGE_50MA);
|
||||
// Set constant current charge current limit
|
||||
power.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_200MA);
|
||||
// Set stop charging termination current
|
||||
power.setChargerTerminationCurr(XPOWERS_AXP2101_CHG_ITERM_25MA);
|
||||
|
||||
// Set charge cut-off voltage
|
||||
power.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V1);
|
||||
|
||||
// Set the watchdog trigger event type
|
||||
// power.setWatchdogConfig(XPOWERS_AXP2101_WDT_IRQ_TO_PIN);
|
||||
// Set watchdog timeout
|
||||
power.setWatchdogTimeout(XPOWERS_AXP2101_WDT_TIMEOUT_4S);
|
||||
// Enable watchdog to trigger interrupt event
|
||||
power.enableWatchdog();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
void pmu_isr_handler()
|
||||
{
|
||||
// Get PMU Interrupt Status Register
|
||||
power.getIrqStatus();
|
||||
|
||||
if (power.isDropWarningLevel2Irq()) {
|
||||
ESP_LOGI(TAG, "isDropWarningLevel2");
|
||||
}
|
||||
if (power.isDropWarningLevel1Irq()) {
|
||||
ESP_LOGI(TAG, "isDropWarningLevel1");
|
||||
}
|
||||
if (power.isGaugeWdtTimeoutIrq()) {
|
||||
ESP_LOGI(TAG, "isWdtTimeout");
|
||||
}
|
||||
if (power.isBatChargerOverTemperatureIrq()) {
|
||||
ESP_LOGI(TAG, "isBatChargeOverTemperature");
|
||||
}
|
||||
if (power.isBatWorkOverTemperatureIrq()) {
|
||||
ESP_LOGI(TAG, "isBatWorkOverTemperature");
|
||||
}
|
||||
if (power.isBatWorkUnderTemperatureIrq()) {
|
||||
ESP_LOGI(TAG, "isBatWorkUnderTemperature");
|
||||
}
|
||||
if (power.isVbusInsertIrq()) {
|
||||
ESP_LOGI(TAG, "isVbusInsert");
|
||||
}
|
||||
if (power.isVbusRemoveIrq()) {
|
||||
ESP_LOGI(TAG, "isVbusRemove");
|
||||
}
|
||||
if (power.isBatInsertIrq()) {
|
||||
ESP_LOGI(TAG, "isBatInsert");
|
||||
}
|
||||
if (power.isBatRemoveIrq()) {
|
||||
ESP_LOGI(TAG, "isBatRemove");
|
||||
}
|
||||
if (power.isPekeyShortPressIrq()) {
|
||||
ESP_LOGI(TAG, "isPekeyShortPress");
|
||||
}
|
||||
if (power.isPekeyLongPressIrq()) {
|
||||
ESP_LOGI(TAG, "isPekeyLongPress");
|
||||
}
|
||||
if (power.isPekeyNegativeIrq()) {
|
||||
ESP_LOGI(TAG, "isPekeyNegative");
|
||||
}
|
||||
if (power.isPekeyPositiveIrq()) {
|
||||
ESP_LOGI(TAG, "isPekeyPositive");
|
||||
}
|
||||
if (power.isWdtExpireIrq()) {
|
||||
ESP_LOGI(TAG, "isWdtExpire");
|
||||
}
|
||||
if (power.isLdoOverCurrentIrq()) {
|
||||
ESP_LOGI(TAG, "isLdoOverCurrentIrq");
|
||||
}
|
||||
if (power.isBatfetOverCurrentIrq()) {
|
||||
ESP_LOGI(TAG, "isBatfetOverCurrentIrq");
|
||||
}
|
||||
if (power.isBatChargeDoneIrq()) {
|
||||
ESP_LOGI(TAG, "isBatChargeDone");
|
||||
}
|
||||
if (power.isBatChargeStartIrq()) {
|
||||
ESP_LOGI(TAG, "isBatChargeStart");
|
||||
}
|
||||
if (power.isBatDieOverTemperatureIrq()) {
|
||||
ESP_LOGI(TAG, "isBatDieOverTemperature");
|
||||
}
|
||||
if (power.isChargeOverTimeoutIrq()) {
|
||||
ESP_LOGI(TAG, "isChargeOverTimeout");
|
||||
}
|
||||
if (power.isBatOverVoltageIrq()) {
|
||||
ESP_LOGI(TAG, "isBatOverVoltage");
|
||||
}
|
||||
// Clear PMU Interrupt Status Register
|
||||
power.clearIrqStatus();
|
||||
}
|
||||
|
||||
#endif /*CONFIG_XPOWERS_AXP2101_CHIP_AXP2102*/
|
||||
|
||||
209
XPowersLib/examples/ESP_IDF_Example/main/port_i2c.cpp
Normal file
209
XPowersLib/examples/ESP_IDF_Example/main/port_i2c.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_idf_version.h"
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
|
||||
#include "driver/i2c_master.h"
|
||||
#else
|
||||
#include "driver/i2c.h"
|
||||
#endif
|
||||
|
||||
static const char *TAG = "XPowersLib";
|
||||
|
||||
#define I2C_MASTER_NUM (i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM
|
||||
#define I2C_MASTER_SDA_IO (gpio_num_t)CONFIG_PMU_I2C_SDA
|
||||
#define I2C_MASTER_SCL_IO (gpio_num_t)CONFIG_PMU_I2C_SCL
|
||||
#define I2C_MASTER_FREQ_HZ CONFIG_I2C_MASTER_FREQUENCY /*!< I2C master clock frequency */
|
||||
|
||||
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
|
||||
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
||||
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
||||
#define I2C_MASTER_TIMEOUT_MS 1000
|
||||
|
||||
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
|
||||
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
|
||||
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
|
||||
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
|
||||
#define ACK_VAL (i2c_ack_type_t)0x0 /*!< I2C ack value */
|
||||
#define NACK_VAL (i2c_ack_type_t)0x1 /*!< I2C nack value */
|
||||
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
|
||||
// The new API passes the device address before initialization,
|
||||
// AXP2102, 1XP192 belong to the same address
|
||||
#define PMU_SLAVE_ADDRESS 0X34
|
||||
i2c_master_dev_handle_t i2c_device;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Read a sequence of bytes from a pmu registers
|
||||
*/
|
||||
int pmu_register_read(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
|
||||
{
|
||||
esp_err_t ret;
|
||||
if (len == 0) {
|
||||
return ESP_OK;
|
||||
}
|
||||
if (data == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
|
||||
|
||||
ret = i2c_master_transmit_receive(
|
||||
i2c_device,
|
||||
(const uint8_t *)®Addr,
|
||||
1,
|
||||
data,
|
||||
len,
|
||||
-1);
|
||||
#else
|
||||
|
||||
i2c_cmd_handle_t cmd;
|
||||
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (devAddr << 1) | WRITE_BIT, ACK_CHECK_EN);
|
||||
i2c_master_write_byte(cmd, regAddr, ACK_CHECK_EN);
|
||||
i2c_master_stop(cmd);
|
||||
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "PMU i2c_master_cmd_begin FAILED! > ");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (devAddr << 1) | READ_BIT, ACK_CHECK_EN);
|
||||
if (len > 1) {
|
||||
i2c_master_read(cmd, data, len - 1, ACK_VAL);
|
||||
}
|
||||
i2c_master_read_byte(cmd, &data[len - 1], NACK_VAL);
|
||||
i2c_master_stop(cmd);
|
||||
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "PMU READ FAILED! > ");
|
||||
}
|
||||
#endif
|
||||
return ret == ESP_OK ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a byte to a pmu register
|
||||
*/
|
||||
int pmu_register_write_byte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
|
||||
{
|
||||
esp_err_t ret;
|
||||
if (data == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
|
||||
uint8_t *write_buffer = (uint8_t *)malloc(sizeof(uint8_t) * (len + 1));
|
||||
if (!write_buffer) {
|
||||
return -1;
|
||||
}
|
||||
write_buffer[0] = regAddr;
|
||||
memcpy(write_buffer + 1, data, len);
|
||||
|
||||
ret = i2c_master_transmit(
|
||||
i2c_device,
|
||||
write_buffer,
|
||||
len + 1,
|
||||
-1);
|
||||
free(write_buffer);
|
||||
#else
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN);
|
||||
i2c_master_write_byte(cmd, regAddr, ACK_CHECK_EN);
|
||||
i2c_master_write(cmd, data, len, ACK_CHECK_EN);
|
||||
i2c_master_stop(cmd);
|
||||
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "PMU WRITE FAILED! < ");
|
||||
}
|
||||
#endif
|
||||
return ret == ESP_OK ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief i2c master initialization
|
||||
*/
|
||||
esp_err_t i2c_init(void)
|
||||
{
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods (Use higher version >= 5.0 API)");
|
||||
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
i2c_master_bus_config_t i2c_bus_config;
|
||||
memset(&i2c_bus_config, 0, sizeof(i2c_bus_config));
|
||||
i2c_bus_config.clk_source = I2C_CLK_SRC_DEFAULT;
|
||||
i2c_bus_config.i2c_port = I2C_MASTER_NUM;
|
||||
i2c_bus_config.scl_io_num = (gpio_num_t)I2C_MASTER_SCL_IO;
|
||||
i2c_bus_config.sda_io_num = (gpio_num_t)I2C_MASTER_SDA_IO;
|
||||
i2c_bus_config.glitch_ignore_cnt = 7;
|
||||
|
||||
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_config, &bus_handle));
|
||||
|
||||
i2c_device_config_t i2c_dev_conf = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = PMU_SLAVE_ADDRESS,
|
||||
.scl_speed_hz = I2C_MASTER_FREQ_HZ,
|
||||
};
|
||||
return i2c_master_bus_add_device(bus_handle, &i2c_dev_conf, &i2c_device);
|
||||
|
||||
#else
|
||||
|
||||
ESP_LOGI(TAG, "Implemented using read and write callback methods (Use lower version < 5.0 API)");
|
||||
|
||||
i2c_config_t i2c_conf ;
|
||||
memset(&i2c_conf, 0, sizeof(i2c_conf));
|
||||
i2c_conf.mode = I2C_MODE_MASTER;
|
||||
i2c_conf.sda_io_num = I2C_MASTER_SDA_IO;
|
||||
i2c_conf.scl_io_num = I2C_MASTER_SCL_IO;
|
||||
i2c_conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
|
||||
i2c_conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
|
||||
i2c_conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
|
||||
i2c_param_config(I2C_MASTER_NUM, &i2c_conf);
|
||||
return i2c_driver_install(I2C_MASTER_NUM, i2c_conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
|
||||
|
||||
#include "soc/clk_tree_defs.h"
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
|
||||
// * which is useful when the bus shares multiple devices.
|
||||
|
||||
esp_err_t i2c_init(void)
|
||||
{
|
||||
i2c_master_bus_config_t i2c_bus_config;
|
||||
memset(&i2c_bus_config, 0, sizeof(i2c_bus_config));
|
||||
i2c_bus_config.clk_source = I2C_CLK_SRC_DEFAULT;
|
||||
i2c_bus_config.i2c_port = I2C_MASTER_NUM;
|
||||
i2c_bus_config.scl_io_num = I2C_MASTER_SCL_IO;
|
||||
i2c_bus_config.sda_io_num = I2C_MASTER_SDA_IO;
|
||||
i2c_bus_config.glitch_ignore_cnt = 7;
|
||||
return i2c_new_master_bus(&i2c_bus_config, &bus_handle);
|
||||
}
|
||||
|
||||
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
|
||||
|
||||
|
||||
#endif //CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
|
||||
1403
XPowersLib/examples/ESP_IDF_Example/sdkconfig
Normal file
1403
XPowersLib/examples/ESP_IDF_Example/sdkconfig
Normal file
File diff suppressed because it is too large
Load Diff
0
XPowersLib/examples/ESP_IDF_Example/sdkconfig.ci
Normal file
0
XPowersLib/examples/ESP_IDF_Example/sdkconfig.ci
Normal file
1
XPowersLib/examples/ESP_IDF_Example/sdkconfig.defaults
Normal file
1
XPowersLib/examples/ESP_IDF_Example/sdkconfig.defaults
Normal file
@@ -0,0 +1 @@
|
||||
#
|
||||
@@ -0,0 +1,259 @@
|
||||
/**
|
||||
* @file FastCharging_BleUartDebug.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @license MIT
|
||||
* @copyright Copyright (c) 2024 Shenzhen Xin Yuan Electronic Technology Co., Ltd
|
||||
* @date 2024-07-30
|
||||
*
|
||||
*/
|
||||
|
||||
// Use SY6970
|
||||
// #define XPOWERS_CHIP_SY6970
|
||||
|
||||
// Use BQ25896
|
||||
#define XPOWERS_CHIP_BQ25896
|
||||
|
||||
#include <XPowersLib.h>
|
||||
|
||||
#ifdef ARDUINO_ARCH_NRF52
|
||||
|
||||
#include <bluefruit.h>
|
||||
#include <Adafruit_LittleFS.h>
|
||||
|
||||
PowerDeliveryHUSB238 pd;
|
||||
XPowersPPM ppm;
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 1
|
||||
#endif
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
|
||||
|
||||
BLEUart bleuart; // uart over ble
|
||||
bool find_ppm = false;
|
||||
String buffer;
|
||||
|
||||
|
||||
void disconnect_callback(uint16_t conn_handle, uint8_t reason)
|
||||
{
|
||||
Serial.println();
|
||||
Serial.print("Disconnected, reason = 0x"); Serial.println(reason, HEX);
|
||||
}
|
||||
|
||||
|
||||
void connect_callback(uint16_t conn_handle)
|
||||
{
|
||||
BLEConnection *conn = Bluefruit.Connection(conn_handle);
|
||||
Serial.println("Connected");
|
||||
|
||||
// request PHY changed to 2MB
|
||||
Serial.println("Request to change PHY");
|
||||
conn->requestPHY();
|
||||
|
||||
// request to update data length
|
||||
Serial.println("Request to change Data Length");
|
||||
conn->requestDataLengthUpdate();
|
||||
|
||||
// request mtu exchange
|
||||
Serial.println("Request to change MTU");
|
||||
|
||||
conn->requestMtuExchange(247);
|
||||
|
||||
// request connection interval of 7.5 ms
|
||||
//conn->requestConnectionParameter(6); // in unit of 1.25
|
||||
// Print out the current connection info
|
||||
Serial.printf("Connection Info: PHY = %d Mbps, Conn Interval = %.2f ms, Data Length = %d, MTU = %d\n",
|
||||
conn->getPHY(), conn->getConnectionInterval() * 1.25f, conn->getDataLength(), conn->getMtu());
|
||||
|
||||
// delay a bit for all the request to complete
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
void startAdv(void)
|
||||
{
|
||||
// Advertising packet
|
||||
|
||||
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
|
||||
Bluefruit.Advertising.addTxPower();
|
||||
|
||||
// Include bleuart 128-bit uuid
|
||||
Bluefruit.Advertising.addService(bleuart);
|
||||
|
||||
// Secondary Scan Response packet (optional)
|
||||
// Since there is no room for 'Name' in Advertising packet
|
||||
Bluefruit.ScanResponse.addName();
|
||||
|
||||
/* Start Advertising
|
||||
* - Enable auto advertising if disconnected
|
||||
* - Interval: fast mode = 20 ms, slow mode = 152.5 ms
|
||||
* - Timeout for fast mode is 30 seconds
|
||||
* - Start(timeout) with timeout = 0 will advertise forever (until connected)
|
||||
*
|
||||
* For recommended advertising interval
|
||||
* https://developer.apple.com/library/content/qa/qa1931/_index.html
|
||||
*/
|
||||
Bluefruit.Advertising.restartOnDisconnect(true);
|
||||
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
|
||||
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
|
||||
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
// while (!Serial);
|
||||
|
||||
bool result = pd.init(Wire, i2c_sda, i2c_scl, HUSB238_SLAVE_ADDRESS);
|
||||
if (result == false) {
|
||||
while (1) {
|
||||
Serial.println("USB Power Delivery controller not online...");
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
find_ppm = ppm.init(Wire);
|
||||
if (!find_ppm) {
|
||||
Serial.println("Can't find XPowers PPM Chip !");
|
||||
} else {
|
||||
Serial.println("Find XPowers ppm Chip .Reset PPM default config");
|
||||
|
||||
ppm.resetDefault();
|
||||
|
||||
ppm.disableWatchdog();
|
||||
|
||||
ppm.enableCharge();
|
||||
|
||||
ppm.disableOTG();
|
||||
|
||||
// SY6970 Range:0~5056 mA / step:64mA
|
||||
// BQ25896 Range:0~3008 mA / step:64mA
|
||||
ppm.setChargerConstantCurr(2048);
|
||||
// Disable current limit pin
|
||||
ppm.disableCurrentLimitPin();
|
||||
|
||||
// SY6970 : Range : 100 mA ~ 3250 mA
|
||||
ppm.setInputCurrentLimit(3250);
|
||||
|
||||
// ppm.disableInputCurrentLimit();
|
||||
|
||||
// Set the charging target voltage, Range:3840 ~ 4608mV ,step:16 mV
|
||||
ppm.setChargeTargetVoltage(4208);
|
||||
|
||||
ppm.enableMeasure();
|
||||
|
||||
// ppm.setHighVoltageRequestedRange(RequestRange::REQUEST_9V);
|
||||
// ppm.setSysPowerDownVoltage(3500);
|
||||
// ppm.setVinDpmThreshold(POWERS_SY6970_VINDPM_VOL_MAX);
|
||||
|
||||
}
|
||||
// Config the peripheral connection with maximum bandwidth
|
||||
// more SRAM required by SoftDevice
|
||||
// Note: All config***() function must be called before begin()
|
||||
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
|
||||
|
||||
Bluefruit.begin();
|
||||
Bluefruit.setName("PowerDelivery");
|
||||
Bluefruit.setTxPower(4); // Check bluefruit.h for supported values
|
||||
Bluefruit.Periph.setConnectCallback(connect_callback);
|
||||
Bluefruit.Periph.setDisconnectCallback(disconnect_callback);
|
||||
Bluefruit.Periph.setConnInterval(6, 12); // 7.5 - 15 ms
|
||||
|
||||
// Configure and Start BLE Uart Service
|
||||
bleuart.begin();
|
||||
|
||||
startAdv();
|
||||
|
||||
Serial.println("Please use Adafruit's Bluefruit LE app to connect in UART mode");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
buffer = "PD Vol:";
|
||||
buffer.concat(pd.getPdVoltage());
|
||||
buffer.concat("V ");
|
||||
buffer.concat("Cur:");
|
||||
buffer.concat(pd.getPdCurrent());
|
||||
buffer.concat("A\n");
|
||||
|
||||
buffer.concat("Status:");
|
||||
PowerDeliveryHUSB238::PD_Status status = pd.status();
|
||||
switch (status) {
|
||||
case PowerDeliveryHUSB238::NO_RESPONSE:
|
||||
buffer.concat("no response");
|
||||
break;
|
||||
case PowerDeliveryHUSB238::SUCCESS:
|
||||
buffer.concat("success");
|
||||
break;
|
||||
case PowerDeliveryHUSB238::INVALID_CMD:
|
||||
buffer.concat("invalid command");
|
||||
break;
|
||||
case PowerDeliveryHUSB238::NOT_SUPPORT:
|
||||
buffer.concat("not support");
|
||||
break;
|
||||
case PowerDeliveryHUSB238::TRANSACTION_FAIL:
|
||||
buffer.concat("transaction failed");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (Bluefruit.connected() && bleuart.notifyEnabled()) {
|
||||
|
||||
buffer.concat("\n");
|
||||
|
||||
if (find_ppm) {
|
||||
ppm.getFaultStatus();
|
||||
buffer.concat("NTC:"); buffer.concat(ppm.getNTCStatusString()); buffer.concat("\n");
|
||||
buffer.concat("VBUS:"); buffer.concat(ppm.getVbusVoltage()); buffer.concat("\n");
|
||||
buffer.concat("VBAT:"); buffer.concat(ppm.getBattVoltage()); buffer.concat("\n");
|
||||
buffer.concat("VSYS:"); buffer.concat(ppm.getSystemVoltage()); buffer.concat("\n");
|
||||
buffer.concat("BUS:"); buffer.concat(ppm.getBusStatusString()); buffer.concat("\n");
|
||||
buffer.concat("CHG:"); buffer.concat(ppm.getChargeStatusString()); buffer.concat("\n");
|
||||
buffer.concat("CUR:"); buffer.concat(ppm.getChargeCurrent()); buffer.concat("\n");
|
||||
}
|
||||
bleuart.write(buffer.c_str());
|
||||
|
||||
} else {
|
||||
|
||||
Serial.println(buffer);
|
||||
if (find_ppm) {
|
||||
|
||||
ppm.getFaultStatus();
|
||||
Serial.print("NTC STR:"); Serial.println(ppm.getNTCStatusString());
|
||||
Serial.printf("CHG TARGET VOLTAGE :%04dmV CURRENT:%04dmA PER_CHARGE_CUR %04dmA\n",
|
||||
ppm.getChargeTargetVoltage(), ppm.getChargerConstantCurr(), ppm.getPrechargeCurr());
|
||||
Serial.printf("VBUS:%s %04dmV VBAT:%04dmV VSYS:%04dmV\n", ppm.isVbusIn() ? "Connected" : "Disconnect",
|
||||
ppm.getVbusVoltage(),
|
||||
ppm.getBattVoltage(),
|
||||
ppm.getSystemVoltage());
|
||||
Serial.printf("BUS STATE:%d -- STR:%s\n", ppm.getBusStatus(), ppm.getBusStatusString());
|
||||
Serial.printf("CHG STATE:%d -- STR:%s CURRENT:%04dmA\n", ppm.chargeStatus(), ppm.getChargeStatusString(), ppm.getChargeCurrent());
|
||||
Serial.printf("[%lu]", millis() / 1000);
|
||||
Serial.println("----------------------------------------------------------------------------------");
|
||||
}
|
||||
}
|
||||
|
||||
delay(5000);
|
||||
}
|
||||
|
||||
#else
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
Serial.println("ble examples only support nrf platform"); delay(1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* @file PowerDeliveryHUSB238_BleUart.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @license MIT
|
||||
* @copyright Copyright (c) 2024 Shenzhen Xin Yuan Electronic Technology Co., Ltd
|
||||
* @date 2024-07-24
|
||||
*
|
||||
*/
|
||||
|
||||
#include <XPowersLib.h>
|
||||
|
||||
#ifdef ARDUINO_ARCH_NRF52
|
||||
|
||||
#include <bluefruit.h>
|
||||
#include <Adafruit_LittleFS.h>
|
||||
|
||||
PowerDeliveryHUSB238 pd;
|
||||
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 1
|
||||
#endif
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
|
||||
|
||||
BLEUart bleuart; // uart over ble
|
||||
|
||||
|
||||
void connect_callback(uint16_t conn_handle)
|
||||
{
|
||||
BLEConnection *conn = Bluefruit.Connection(conn_handle);
|
||||
Serial.println("Connected");
|
||||
|
||||
// request PHY changed to 2MB
|
||||
Serial.println("Request to change PHY");
|
||||
conn->requestPHY();
|
||||
|
||||
// request to update data length
|
||||
Serial.println("Request to change Data Length");
|
||||
conn->requestDataLengthUpdate();
|
||||
|
||||
// request mtu exchange
|
||||
Serial.println("Request to change MTU");
|
||||
conn->requestMtuExchange(247);
|
||||
|
||||
// request connection interval of 7.5 ms
|
||||
//conn->requestConnectionParameter(6); // in unit of 1.25
|
||||
|
||||
// delay a bit for all the request to complete
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
void startAdv(void)
|
||||
{
|
||||
// Advertising packet
|
||||
|
||||
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
|
||||
Bluefruit.Advertising.addTxPower();
|
||||
|
||||
// Include bleuart 128-bit uuid
|
||||
Bluefruit.Advertising.addService(bleuart);
|
||||
|
||||
// Secondary Scan Response packet (optional)
|
||||
// Since there is no room for 'Name' in Advertising packet
|
||||
Bluefruit.ScanResponse.addName();
|
||||
|
||||
/* Start Advertising
|
||||
* - Enable auto advertising if disconnected
|
||||
* - Interval: fast mode = 20 ms, slow mode = 152.5 ms
|
||||
* - Timeout for fast mode is 30 seconds
|
||||
* - Start(timeout) with timeout = 0 will advertise forever (until connected)
|
||||
*
|
||||
* For recommended advertising interval
|
||||
* https://developer.apple.com/library/content/qa/qa1931/_index.html
|
||||
*/
|
||||
Bluefruit.Advertising.restartOnDisconnect(true);
|
||||
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
|
||||
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
|
||||
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
// while (!Serial);
|
||||
|
||||
bool result = pd.init(Wire, i2c_sda, i2c_scl, HUSB238_SLAVE_ADDRESS);
|
||||
if (result == false) {
|
||||
while (1) {
|
||||
Serial.println("USB Power Delivery controller not online...");
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
// Config the peripheral connection with maximum bandwidth
|
||||
// more SRAM required by SoftDevice
|
||||
// Note: All config***() function must be called before begin()
|
||||
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
|
||||
|
||||
Bluefruit.begin();
|
||||
Bluefruit.setName("PowerDelivery");
|
||||
Bluefruit.setTxPower(4); // Check bluefruit.h for supported values
|
||||
Bluefruit.Periph.setConnectCallback(connect_callback);
|
||||
Bluefruit.Periph.setConnInterval(6, 12); // 7.5 - 15 ms
|
||||
|
||||
// Configure and Start BLE Uart Service
|
||||
bleuart.begin();
|
||||
|
||||
startAdv();
|
||||
|
||||
Serial.println("Please use Adafruit's Bluefruit LE app to connect in UART mode");
|
||||
}
|
||||
|
||||
|
||||
String buffer;
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
Serial.print("PD Voltage:"); Serial.print(pd.getPdVoltage()); Serial.print(" V");
|
||||
Serial.print(" Current: "); Serial.print(pd.getPdCurrent()); Serial.println(" A");
|
||||
|
||||
buffer = "Vol:";
|
||||
buffer.concat(pd.getPdVoltage());
|
||||
buffer.concat("V ");
|
||||
buffer.concat("Cur:");
|
||||
buffer.concat(pd.getPdCurrent());
|
||||
buffer.concat("A");
|
||||
buffer.concat("Status:");
|
||||
|
||||
|
||||
PowerDeliveryHUSB238::PD_Status status = pd.status();
|
||||
Serial.print("USB Power Delivery Status : ");
|
||||
|
||||
switch (status) {
|
||||
case PowerDeliveryHUSB238::NO_RESPONSE:
|
||||
Serial.println("no response");
|
||||
buffer.concat("no response");
|
||||
break;
|
||||
case PowerDeliveryHUSB238::SUCCESS:
|
||||
Serial.println("success");
|
||||
buffer.concat("success");
|
||||
break;
|
||||
case PowerDeliveryHUSB238::INVALID_CMD:
|
||||
Serial.println("invalid command");
|
||||
buffer.concat("invalid command");
|
||||
break;
|
||||
case PowerDeliveryHUSB238::NOT_SUPPORT:
|
||||
Serial.println("not support");
|
||||
buffer.concat("not support");
|
||||
break;
|
||||
case PowerDeliveryHUSB238::TRANSACTION_FAIL:
|
||||
Serial.println("transaction failed");
|
||||
buffer.concat("transaction failed");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
bleuart.write(buffer.c_str());
|
||||
|
||||
delay(5000);
|
||||
}
|
||||
|
||||
#else
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
Serial.println("ble examples only support nrf platform"); delay(1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @file PowerDeliveryHUSB238.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @license MIT
|
||||
* @copyright Copyright (c) 2024 Shenzhen Xin Yuan Electronic Technology Co., Ltd
|
||||
* @date 2024-07-24
|
||||
*
|
||||
*/
|
||||
#include <XPowersLib.h>
|
||||
|
||||
PowerDeliveryHUSB238 pd;
|
||||
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 1
|
||||
#endif
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
bool result = pd.init(Wire, i2c_sda, i2c_scl, HUSB238_SLAVE_ADDRESS);
|
||||
if (result == false) {
|
||||
while (1) {
|
||||
Serial.println("USB Power Delivery controller not online...");
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.print("PD Voltage:"); Serial.print(pd.getPdVoltage()); Serial.print(" V");
|
||||
Serial.print(" Current: "); Serial.print(pd.getPdCurrent()); Serial.println(" A");
|
||||
|
||||
PowerDeliveryHUSB238::PD_Status status = pd.status();
|
||||
Serial.print("USB Power Delivery Status : ");
|
||||
switch (status) {
|
||||
case PowerDeliveryHUSB238::NO_RESPONSE:
|
||||
Serial.println("no response");
|
||||
break;
|
||||
case PowerDeliveryHUSB238::SUCCESS:
|
||||
Serial.println("success");
|
||||
break;
|
||||
case PowerDeliveryHUSB238::INVALID_CMD:
|
||||
Serial.println("invalid command");
|
||||
break;
|
||||
case PowerDeliveryHUSB238::NOT_SUPPORT:
|
||||
Serial.println("not support");
|
||||
break;
|
||||
case PowerDeliveryHUSB238::TRANSACTION_FAIL:
|
||||
Serial.println("transaction failed");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
176
XPowersLib/examples/SY6970_Example/SY6970_Example.ino
Normal file
176
XPowersLib/examples/SY6970_Example/SY6970_Example.ino
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* @file SY6970_Example.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @license MIT
|
||||
* @copyright Copyright (c) 2023 Shenzhen Xin Yuan Electronic Technology Co., Ltd
|
||||
* @date 2023-08-05
|
||||
* @note SY6970 If the power supply is a separate USB power supply, VSYS can only provide a maximum load current of 500mA.
|
||||
* If it is connected to a battery, the discharge current depends on the maximum discharge current of the battery.
|
||||
*
|
||||
*/
|
||||
#define XPOWERS_CHIP_SY6970
|
||||
|
||||
#include <XPowersLib.h>
|
||||
|
||||
XPowersPPM PPM;
|
||||
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 28
|
||||
#endif
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
uint32_t cycleInterval;
|
||||
bool pmu_irq = false;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
|
||||
bool result = PPM.init(Wire, i2c_sda, i2c_scl, SY6970_SLAVE_ADDRESS);
|
||||
|
||||
if (result == false) {
|
||||
while (1) {
|
||||
Serial.println("PPM is not online...");
|
||||
delay(50);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the minimum operating voltage. Below this voltage, the PPM will protect
|
||||
PPM.setSysPowerDownVoltage(3300);
|
||||
|
||||
// Set input current limit, default is 500mA
|
||||
PPM.setInputCurrentLimit(3250);
|
||||
|
||||
Serial.printf("getInputCurrentLimit: %d mA\n", PPM.getInputCurrentLimit());
|
||||
|
||||
// Disable current limit pin
|
||||
PPM.disableCurrentLimitPin();
|
||||
|
||||
// Set the charging target voltage, Range:3840 ~ 4608mV ,step:16 mV
|
||||
PPM.setChargeTargetVoltage(4208);
|
||||
|
||||
// Set the precharge current , Range: 64mA ~ 1024mA ,step:64mA
|
||||
PPM.setPrechargeCurr(64);
|
||||
|
||||
// The premise is that Limit Pin is disabled, or it will only follow the maximum charging current set by Limi tPin.
|
||||
// Set the charging current , Range:0~5056mA ,step:64mA
|
||||
PPM.setChargerConstantCurr(1024);
|
||||
|
||||
// Get the set charging current
|
||||
PPM.getChargerConstantCurr();
|
||||
Serial.printf("getChargerConstantCurr: %d mA\n", PPM.getChargerConstantCurr());
|
||||
|
||||
|
||||
// To obtain voltage data, the ADC must be enabled first
|
||||
PPM.enableMeasure();
|
||||
|
||||
// Turn on charging function
|
||||
// If there is no battery connected, do not turn on the charging function
|
||||
PPM.enableCharge();
|
||||
|
||||
// Turn off charging function
|
||||
// If USB is used as the only power input, it is best to turn off the charging function,
|
||||
// otherwise the VSYS power supply will have a sawtooth wave, affecting the discharge output capability.
|
||||
// PPM.disableCharge();
|
||||
|
||||
|
||||
// The OTG function needs to enable OTG, and set the OTG control pin to HIGH
|
||||
// After OTG is enabled, if an external power supply is plugged in, OTG will be turned off
|
||||
|
||||
// PPM.enableOTG();
|
||||
// PPM.disableOTG();
|
||||
// pinMode(OTG_ENABLE_PIN, OUTPUT);
|
||||
// digitalWrite(OTG_ENABLE_PIN, HIGH);
|
||||
|
||||
pinMode(pmu_irq_pin, INPUT_PULLUP);
|
||||
attachInterrupt(pmu_irq_pin, []() {
|
||||
pmu_irq = true;
|
||||
}, FALLING);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (pmu_irq) {
|
||||
pmu_irq = false;
|
||||
// Get PPM interrupt status
|
||||
PPM.getFaultStatus();
|
||||
|
||||
Serial.print("-> [");
|
||||
Serial.print(millis() / 1000);
|
||||
Serial.print("] ");
|
||||
|
||||
if (PPM.isWatchdogFault()) {
|
||||
|
||||
Serial.println("Watchdog Fault");
|
||||
|
||||
} else if (PPM.isBoostFault()) {
|
||||
|
||||
Serial.println("Boost Fault");
|
||||
|
||||
} else if (PPM.isChargeFault()) {
|
||||
|
||||
Serial.println("Charge Fault");
|
||||
|
||||
} else if (PPM.isBatteryFault()) {
|
||||
|
||||
Serial.println("Batter Fault");
|
||||
|
||||
} else if (PPM.isNTCFault()) {
|
||||
|
||||
Serial.print("NTC Fault:");
|
||||
Serial.print(PPM.getNTCStatusString());
|
||||
Serial.print(" Percentage:");
|
||||
Serial.print(PPM.getNTCPercentage()); Serial.println("%");
|
||||
} else {
|
||||
/*
|
||||
* When the battery is removed, INT will send an interrupt every 100ms. If the battery is not connected,
|
||||
* you can use PPM.disableCharge() to turn off the charging function.
|
||||
* */
|
||||
// PPM.disableCharge();
|
||||
|
||||
Serial.println("Battery remove");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtaining the battery voltage and battery charging status does not directly read the register,
|
||||
* but determines whether the charging current register is normal.
|
||||
* If read directly, the reading will be inaccurate.
|
||||
* The premise for obtaining these two states is that the NTC temperature measurement circuit is normal.
|
||||
* If the NTC detection is abnormal, it will return 0
|
||||
* * */
|
||||
if (millis() > cycleInterval) {
|
||||
Serial.printf("CHG TARGET VOLTAGE :%04dmV CURRENT:%04dmA PER_CHARGE_CUR %04dmA\n",
|
||||
PPM.getChargeTargetVoltage(), PPM.getChargerConstantCurr(), PPM.getPrechargeCurr());
|
||||
Serial.printf("VBUS:%s %04dmV VBAT:%04dmV VSYS:%04dmV\n", PPM.isVbusIn() ? "Connected" : "Disconnect",
|
||||
PPM.getVbusVoltage(),
|
||||
PPM.getBattVoltage(),
|
||||
PPM.getSystemVoltage());
|
||||
Serial.printf("BUS STATE:%d STR:%s\n", PPM.getBusStatus(), PPM.getBusStatusString());
|
||||
Serial.printf("CHG STATE:%d STR:%s CURRENT:%04dmA\n", PPM.chargeStatus(), PPM.getChargeStatusString(), PPM.getChargeCurrent());
|
||||
Serial.printf("[%lu]", millis() / 1000);
|
||||
Serial.println("----------------------------------------------------------------------------------");
|
||||
cycleInterval = millis() + 1000;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @file SY6970_Shutdown_Example.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @license MIT
|
||||
* @copyright Copyright (c) 2024 Shenzhen Xin Yuan Electronic Technology Co., Ltd
|
||||
* @date 2024-05-23
|
||||
*
|
||||
*/
|
||||
#define XPOWERS_CHIP_SY6970
|
||||
|
||||
#include <XPowersLib.h>
|
||||
|
||||
XPowersPPM PPM;
|
||||
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 28
|
||||
#endif
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
uint32_t cycleInterval;
|
||||
uint32_t countdown = 10;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
bool result = PPM.init(Wire, i2c_sda, i2c_scl, SY6970_SLAVE_ADDRESS);
|
||||
if (result == false) {
|
||||
while (1) {
|
||||
Serial.println("PPM is not online...");
|
||||
delay(50);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (millis() > cycleInterval) {
|
||||
Serial.printf("%d\n", countdown);
|
||||
if (!(countdown--)) {
|
||||
Serial.println("Shutdown .....");
|
||||
// The shutdown function can only be used when the battery is connected alone,
|
||||
// and cannot be shut down when connected to USB.
|
||||
// It can only be powered on in the following two ways:
|
||||
// 1. Press the /QON button
|
||||
// 2. Connect to USB
|
||||
PPM.shutdown();
|
||||
countdown = 10000;
|
||||
}
|
||||
cycleInterval = millis() + 1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @file SY6970_Watchdog_Example.ino
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @license MIT
|
||||
* @copyright Copyright (c) 2023 Shenzhen Xin Yuan Electronic Technology Co., Ltd
|
||||
* @date 2023-08-31
|
||||
*
|
||||
*/
|
||||
#define XPOWERS_CHIP_SY6970
|
||||
|
||||
#include <XPowersLib.h>
|
||||
|
||||
XPowersPPM PPM;
|
||||
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 15
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 10
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 28
|
||||
#endif
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
uint32_t cycleInterval;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
|
||||
// Begin SY6970 PPM , Default disable watchdog timer
|
||||
bool result = PPM.init(Wire, i2c_sda, i2c_scl, SY6970_SLAVE_ADDRESS);
|
||||
|
||||
if (result == false) {
|
||||
while (1) {
|
||||
Serial.println("PPM is not online...");
|
||||
delay(50);
|
||||
}
|
||||
}
|
||||
|
||||
// Disable battery charge function
|
||||
PPM.disableCharge();
|
||||
|
||||
/*
|
||||
* Example:
|
||||
* PPM.enableWatchdog(PowersSY6970::TIMER_OUT_40SEC);
|
||||
* Optional parameters:
|
||||
* PowersSY6970::TIMER_OUT_40SEC, //40 Second
|
||||
* PowersSY6970::TIMER_OUT_80SEC, //80 Second
|
||||
* PowersSY6970::TIMER_OUT_160SEC, //160 Second
|
||||
* * */
|
||||
// Enable SY6970 PPM watchdog function
|
||||
PPM.enableWatchdog(PowersSY6970::TIMER_OUT_40SEC);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Feed watchdog , If the dog is not fed, the PPM will restart after a timeout, and all PPM settings will be restored to their default values
|
||||
Serial.print(millis() / 1000); Serial.println(" Second");
|
||||
PPM.feedWatchdog();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,516 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 lewis he
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
#ifndef XPOWERS_NO_ERROR
|
||||
#error "Running this example is known to not damage the device! Please go and uncomment this!"
|
||||
#endif
|
||||
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include "XPowersLib.h"
|
||||
|
||||
|
||||
#ifndef CONFIG_PMU_SDA
|
||||
#define CONFIG_PMU_SDA 21
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_SCL
|
||||
#define CONFIG_PMU_SCL 22
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 35
|
||||
#endif
|
||||
|
||||
// Use the XPowersLibInterface standard to use the xpowers API
|
||||
XPowersLibInterface *power = NULL;
|
||||
|
||||
bool pmu_flag = 0;
|
||||
|
||||
const uint8_t i2c_sda = CONFIG_PMU_SDA;
|
||||
const uint8_t i2c_scl = CONFIG_PMU_SCL;
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
|
||||
void setFlag(void)
|
||||
{
|
||||
pmu_flag = true;
|
||||
}
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
|
||||
if (!power) {
|
||||
power = new XPowersAXP2101(Wire, i2c_sda, i2c_scl);
|
||||
if (!power->init()) {
|
||||
Serial.printf("Warning: Failed to find AXP2101 power management\n");
|
||||
delete power;
|
||||
power = NULL;
|
||||
} else {
|
||||
Serial.printf("AXP2101 PMU init succeeded, using AXP2101 PMU\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!power) {
|
||||
power = new XPowersAXP192(Wire, i2c_sda, i2c_scl);
|
||||
if (!power->init()) {
|
||||
Serial.printf("Warning: Failed to find AXP192 power management\n");
|
||||
delete power;
|
||||
power = NULL;
|
||||
} else {
|
||||
Serial.printf("AXP192 PMU init succeeded, using AXP192 PMU\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!power) {
|
||||
power = new XPowersAXP202(Wire, i2c_sda, i2c_scl);
|
||||
if (!power->init()) {
|
||||
Serial.printf("Warning: Failed to find AXP202 power management\n");
|
||||
delete power;
|
||||
power = NULL;
|
||||
} else {
|
||||
Serial.printf("AXP202 PMU init succeeded, using AXP202 PMU\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!power) {
|
||||
Serial.println("PMU not detected, please check.."); while (1)delay(50);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//The following AXP192 power supply setting voltage is based on esp32 T-beam
|
||||
if (power->getChipModel() == XPOWERS_AXP192) {
|
||||
|
||||
// lora radio power channel
|
||||
power->setPowerChannelVoltage(XPOWERS_LDO2, 3300);
|
||||
power->enablePowerOutput(XPOWERS_LDO2);
|
||||
|
||||
|
||||
// oled module power channel,
|
||||
// disable it will cause abnormal communication between boot and AXP power supply,
|
||||
// do not turn it off
|
||||
power->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
|
||||
// enable oled power
|
||||
power->enablePowerOutput(XPOWERS_DCDC1);
|
||||
|
||||
// gnss module power channel
|
||||
power->setPowerChannelVoltage(XPOWERS_LDO3, 3300);
|
||||
// power->enablePowerOutput(XPOWERS_LDO3);
|
||||
|
||||
|
||||
//protected oled power source
|
||||
power->setProtectedChannel(XPOWERS_DCDC1);
|
||||
//protected esp32 power source
|
||||
power->setProtectedChannel(XPOWERS_DCDC3);
|
||||
|
||||
//disable not use channel
|
||||
power->disablePowerOutput(XPOWERS_DCDC2);
|
||||
|
||||
//disable all axp chip interrupt
|
||||
power->disableIRQ(XPOWERS_AXP192_ALL_IRQ);
|
||||
|
||||
|
||||
//
|
||||
/* Set the constant current charging current of AXP192
|
||||
opt:
|
||||
XPOWERS_AXP192_CHG_CUR_100MA,
|
||||
XPOWERS_AXP192_CHG_CUR_190MA,
|
||||
XPOWERS_AXP192_CHG_CUR_280MA,
|
||||
XPOWERS_AXP192_CHG_CUR_360MA,
|
||||
XPOWERS_AXP192_CHG_CUR_450MA,
|
||||
XPOWERS_AXP192_CHG_CUR_550MA,
|
||||
XPOWERS_AXP192_CHG_CUR_630MA,
|
||||
XPOWERS_AXP192_CHG_CUR_700MA,
|
||||
XPOWERS_AXP192_CHG_CUR_780MA,
|
||||
XPOWERS_AXP192_CHG_CUR_880MA,
|
||||
XPOWERS_AXP192_CHG_CUR_960MA,
|
||||
XPOWERS_AXP192_CHG_CUR_1000MA,
|
||||
XPOWERS_AXP192_CHG_CUR_1080MA,
|
||||
XPOWERS_AXP192_CHG_CUR_1160MA,
|
||||
XPOWERS_AXP192_CHG_CUR_1240MA,
|
||||
XPOWERS_AXP192_CHG_CUR_1320MA,
|
||||
*/
|
||||
power->setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_550MA);
|
||||
|
||||
|
||||
}
|
||||
// The following AXP202 power supply voltage setting is based on esp32 T-Watch
|
||||
else if (power->getChipModel() == XPOWERS_AXP202) {
|
||||
|
||||
power->disablePowerOutput(XPOWERS_DCDC2); //not elicited
|
||||
|
||||
//Display backlight
|
||||
power->setPowerChannelVoltage(XPOWERS_LDO2, 3300);
|
||||
power->enablePowerOutput(XPOWERS_LDO2);
|
||||
|
||||
// Shiled Vdd
|
||||
power->setPowerChannelVoltage(XPOWERS_LDO3, 3300);
|
||||
power->enablePowerOutput(XPOWERS_LDO3);
|
||||
|
||||
// S7xG GNSS Vdd
|
||||
power->setPowerChannelVoltage(XPOWERS_LDO4, 1800);
|
||||
power->enablePowerOutput(XPOWERS_LDO4);
|
||||
|
||||
|
||||
//
|
||||
/* Set the constant current charging current of AXP202
|
||||
opt:
|
||||
XPOWERS_AXP202_CHG_CUR_100MA,
|
||||
XPOWERS_AXP202_CHG_CUR_190MA,
|
||||
XPOWERS_AXP202_CHG_CUR_280MA,
|
||||
XPOWERS_AXP202_CHG_CUR_360MA,
|
||||
XPOWERS_AXP202_CHG_CUR_450MA,
|
||||
XPOWERS_AXP202_CHG_CUR_550MA,
|
||||
XPOWERS_AXP202_CHG_CUR_630MA,
|
||||
XPOWERS_AXP202_CHG_CUR_700MA,
|
||||
XPOWERS_AXP202_CHG_CUR_780MA,
|
||||
XPOWERS_AXP202_CHG_CUR_880MA,
|
||||
XPOWERS_AXP202_CHG_CUR_960MA,
|
||||
XPOWERS_AXP202_CHG_CUR_1000MA,
|
||||
XPOWERS_AXP202_CHG_CUR_1080MA,
|
||||
XPOWERS_AXP202_CHG_CUR_1160MA,
|
||||
XPOWERS_AXP202_CHG_CUR_1240MA,
|
||||
XPOWERS_AXP202_CHG_CUR_1320MA,
|
||||
*/
|
||||
power->setChargerConstantCurr(XPOWERS_AXP202_CHG_CUR_550MA);
|
||||
|
||||
}
|
||||
// The following AXP192 power supply voltage setting is based on esp32s3 T-beam
|
||||
else if (power->getChipModel() == XPOWERS_AXP2101) {
|
||||
|
||||
// gnss module power channel
|
||||
power->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
|
||||
power->enablePowerOutput(XPOWERS_ALDO4);
|
||||
|
||||
// lora radio power channel
|
||||
power->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
|
||||
power->enablePowerOutput(XPOWERS_ALDO3);
|
||||
|
||||
// m.2 interface
|
||||
power->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
|
||||
power->enablePowerOutput(XPOWERS_DCDC3);
|
||||
|
||||
// power->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
|
||||
// power->enablePowerOutput(XPOWERS_DCDC4);
|
||||
|
||||
//not use channel
|
||||
power->disablePowerOutput(XPOWERS_DCDC2); //not elicited
|
||||
power->disablePowerOutput(XPOWERS_DCDC5); //not elicited
|
||||
power->disablePowerOutput(XPOWERS_DLDO1); //Invalid power channel, it does not exist
|
||||
power->disablePowerOutput(XPOWERS_DLDO2); //Invalid power channel, it does not exist
|
||||
power->disablePowerOutput(XPOWERS_VBACKUP);
|
||||
|
||||
//disable all axp chip interrupt
|
||||
power->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
|
||||
/* Set the constant current charging current of AXP2101
|
||||
opt:
|
||||
XPOWERS_AXP2101_CHG_CUR_100MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_125MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_150MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_175MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_200MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_300MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_400MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_500MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_600MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_700MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_800MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_900MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_1000MA,
|
||||
*/
|
||||
power->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA);
|
||||
|
||||
}
|
||||
|
||||
Serial.println("=======================================================================\n");
|
||||
if (power->isChannelAvailable(XPOWERS_DCDC1)) {
|
||||
Serial.printf("DC1 : %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_DCDC1));
|
||||
}
|
||||
if (power->isChannelAvailable(XPOWERS_DCDC2)) {
|
||||
Serial.printf("DC2 : %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_DCDC2));
|
||||
}
|
||||
if (power->isChannelAvailable(XPOWERS_DCDC3)) {
|
||||
Serial.printf("DC3 : %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_DCDC3));
|
||||
}
|
||||
if (power->isChannelAvailable(XPOWERS_DCDC4)) {
|
||||
Serial.printf("DC4 : %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_DCDC4));
|
||||
}
|
||||
if (power->isChannelAvailable(XPOWERS_LDO2)) {
|
||||
Serial.printf("LDO2 : %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_LDO2));
|
||||
}
|
||||
if (power->isChannelAvailable(XPOWERS_LDO3)) {
|
||||
Serial.printf("LDO3 : %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_LDO3));
|
||||
}
|
||||
if (power->isChannelAvailable(XPOWERS_LDO4)) {
|
||||
Serial.printf("LDO4 : %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_LDO4) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_LDO4));
|
||||
}
|
||||
if (power->isChannelAvailable(XPOWERS_LDO5)) {
|
||||
Serial.printf("LDO5 : %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_LDO5) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_LDO5));
|
||||
}
|
||||
if (power->isChannelAvailable(XPOWERS_ALDO1)) {
|
||||
Serial.printf("ALDO1: %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_ALDO1));
|
||||
}
|
||||
if (power->isChannelAvailable(XPOWERS_ALDO2)) {
|
||||
Serial.printf("ALDO2: %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_ALDO2));
|
||||
}
|
||||
if (power->isChannelAvailable(XPOWERS_ALDO3)) {
|
||||
Serial.printf("ALDO3: %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_ALDO3));
|
||||
}
|
||||
if (power->isChannelAvailable(XPOWERS_ALDO4)) {
|
||||
Serial.printf("ALDO4: %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_ALDO4));
|
||||
}
|
||||
if (power->isChannelAvailable(XPOWERS_BLDO1)) {
|
||||
Serial.printf("BLDO1: %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_BLDO1));
|
||||
}
|
||||
if (power->isChannelAvailable(XPOWERS_BLDO2)) {
|
||||
Serial.printf("BLDO2: %s Voltage:%u mV \n", power->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", power->getPowerChannelVoltage(XPOWERS_BLDO2));
|
||||
}
|
||||
Serial.println("=======================================================================\n");
|
||||
|
||||
|
||||
//Set up the charging voltage, AXP2101/AXP192 4.2V gear is the same
|
||||
// XPOWERS_AXP192_CHG_VOL_4V2 = XPOWERS_AXP2101_CHG_VOL_4V2
|
||||
power->setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2);
|
||||
|
||||
// Set VSY off voltage as 2600mV , Adjustment range 2600mV ~ 3300mV
|
||||
power->setSysPowerDownVoltage(2600);
|
||||
|
||||
// Get the VSYS shutdown voltage
|
||||
uint16_t vol = power->getSysPowerDownVoltage();
|
||||
Serial.printf("-> getSysPowerDownVoltage:%u\n", vol);
|
||||
|
||||
|
||||
|
||||
// Set the time of pressing the button to turn off
|
||||
power->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
|
||||
uint8_t opt = power->getPowerKeyPressOffTime();
|
||||
Serial.print("PowerKeyPressOffTime:");
|
||||
switch (opt) {
|
||||
case XPOWERS_POWEROFF_4S: Serial.println("4 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_6S: Serial.println("6 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_8S: Serial.println("8 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_10S: Serial.println("10 Second");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the button power-on press time
|
||||
power->setPowerKeyPressOnTime(XPOWERS_POWERON_128MS);
|
||||
opt = power->getPowerKeyPressOnTime();
|
||||
Serial.print("PowerKeyPressOnTime:");
|
||||
switch (opt) {
|
||||
case XPOWERS_POWERON_128MS: Serial.println("128 Ms");
|
||||
break;
|
||||
case XPOWERS_POWERON_512MS: Serial.println("512 Ms");
|
||||
break;
|
||||
case XPOWERS_POWERON_1S: Serial.println("1 Second");
|
||||
break;
|
||||
case XPOWERS_POWERON_2S: Serial.println("2 Second");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.println("===========================================================================");
|
||||
|
||||
// It is necessary to disable the detection function of the TS pin on the board
|
||||
// without the battery temperature detection function, otherwise it will cause abnormal charging
|
||||
power->disableTSPinMeasure();
|
||||
|
||||
// Enable internal ADC detection
|
||||
power->enableBattDetection();
|
||||
power->enableVbusVoltageMeasure();
|
||||
power->enableBattVoltageMeasure();
|
||||
power->enableSystemVoltageMeasure();
|
||||
|
||||
|
||||
/*
|
||||
The default setting is CHGLED is automatically controlled by the PMU.
|
||||
- XPOWERS_CHG_LED_OFF,
|
||||
- XPOWERS_CHG_LED_BLINK_1HZ,
|
||||
- XPOWERS_CHG_LED_BLINK_4HZ,
|
||||
- XPOWERS_CHG_LED_ON,
|
||||
- XPOWERS_CHG_LED_CTRL_CHG,
|
||||
* */
|
||||
power->setChargingLedMode(XPOWERS_CHG_LED_OFF);
|
||||
|
||||
|
||||
pinMode(pmu_irq_pin, INPUT);
|
||||
attachInterrupt(pmu_irq_pin, setFlag, FALLING);
|
||||
|
||||
// Clear all interrupt flags
|
||||
power->clearIrqStatus();
|
||||
|
||||
|
||||
/*
|
||||
// call specific interrupt request
|
||||
|
||||
uint64_t pmuIrqMask = 0;
|
||||
|
||||
if (power->getChipModel() == XPOWERS_AXP192) {
|
||||
|
||||
pmuIrqMask = XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_VBUS_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_BAT_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP192_PKEY_SHORT_IRQ | XPOWERS_AXP192_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP192_BAT_CHG_START_IRQ | XPOWERS_AXP192_BAT_CHG_DONE_IRQ ; //CHARGE
|
||||
} else if (power->getChipModel() == XPOWERS_AXP2101) {
|
||||
|
||||
pmuIrqMask = XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ; //CHARGE
|
||||
}
|
||||
// Enable the required interrupt function
|
||||
power->enableIRQ(pmuIrqMask);
|
||||
|
||||
*/
|
||||
|
||||
// Call the interrupt request through the interface class
|
||||
power->disableInterrupt(XPOWERS_ALL_INT);
|
||||
|
||||
power->enableInterrupt(XPOWERS_USB_INSERT_INT |
|
||||
XPOWERS_USB_REMOVE_INT |
|
||||
XPOWERS_BATTERY_INSERT_INT |
|
||||
XPOWERS_BATTERY_REMOVE_INT |
|
||||
XPOWERS_PWR_BTN_CLICK_INT |
|
||||
XPOWERS_CHARGE_START_INT |
|
||||
XPOWERS_CHARGE_DONE_INT);
|
||||
|
||||
|
||||
// Access the subclass method by getting the model
|
||||
uint8_t chipType = power->getChipModel();
|
||||
switch (chipType) {
|
||||
case XPOWERS_AXP192: {
|
||||
XPowersAXP192 *axp192 = static_cast<XPowersAXP192 *>(power);
|
||||
axp192->enableCoulomb();
|
||||
uint32_t data = axp192->getBattChargeCoulomb();
|
||||
float chargeCurrent = axp192->getBatteryChargeCurrent();
|
||||
float dischargeCurrent = axp192->getBattDischargeCurrent();
|
||||
Serial.printf("AXP192 GetBattChargeCoulomb : %X\n", data);
|
||||
Serial.printf("AXP192 GetBatteryChargeCurrent:%.2f mA\n", chargeCurrent);
|
||||
Serial.printf("AXP192 GetBattDischargeCurrent:%.2f mA\n", dischargeCurrent);
|
||||
}
|
||||
break;
|
||||
case XPOWERS_AXP202: {
|
||||
XPowersAXP202 *axp202 = static_cast<XPowersAXP202 *>(power);
|
||||
axp202->enableCoulomb();
|
||||
uint32_t data = axp202->getBattChargeCoulomb();
|
||||
Serial.printf("AX202 GetBattChargeCoulomb : %X\n", data);
|
||||
}
|
||||
break;
|
||||
case XPOWERS_AXP2101: {
|
||||
XPowersAXP2101 *axp2101 = static_cast<XPowersAXP2101 *>(power);
|
||||
axp2101->fuelGaugeControl(true, true);
|
||||
axp2101->setPrechargeCurr(XPOWERS_AXP2101_PRECHARGE_50MA);
|
||||
axp2101->setChargerTerminationCurr(XPOWERS_AXP2101_CHG_ITERM_25MA);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void printPMU()
|
||||
{
|
||||
Serial.print("isCharging:"); Serial.println(power->isCharging() ? "YES" : "NO");
|
||||
Serial.print("isDischarge:"); Serial.println(power->isDischarge() ? "YES" : "NO");
|
||||
Serial.print("isVbusIn:"); Serial.println(power->isVbusIn() ? "YES" : "NO");
|
||||
Serial.print("getBattVoltage:"); Serial.print(power->getBattVoltage()); Serial.println("mV");
|
||||
Serial.print("getVbusVoltage:"); Serial.print(power->getVbusVoltage()); Serial.println("mV");
|
||||
Serial.print("getSystemVoltage:"); Serial.print(power->getSystemVoltage()); Serial.println("mV");
|
||||
|
||||
// The battery percentage may be inaccurate at first use, the PMU will automatically
|
||||
// learn the battery curve and will automatically calibrate the battery percentage
|
||||
// after a charge and discharge cycle
|
||||
if (power->isBatteryConnect()) {
|
||||
Serial.print("getBatteryPercent:"); Serial.print(power->getBatteryPercent()); Serial.println("%");
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
if (pmu_flag) {
|
||||
|
||||
pmu_flag = false;
|
||||
|
||||
// Get PMU Interrupt Status Register
|
||||
uint32_t status = power->getIrqStatus();
|
||||
Serial.print("STATUS => HEX:");
|
||||
Serial.print(status, HEX);
|
||||
Serial.print(" BIN:");
|
||||
Serial.println(status, BIN);
|
||||
|
||||
if (power->isVbusInsertIrq()) {
|
||||
Serial.println("isVbusInsert");
|
||||
}
|
||||
if (power->isVbusRemoveIrq()) {
|
||||
Serial.println("isVbusRemove");
|
||||
}
|
||||
if (power->isBatInsertIrq()) {
|
||||
Serial.println("isBatInsert");
|
||||
}
|
||||
if (power->isBatRemoveIrq()) {
|
||||
Serial.println("isBatRemove");
|
||||
}
|
||||
if (power->isPekeyShortPressIrq()) {
|
||||
Serial.println("isPekeyShortPress");
|
||||
}
|
||||
if (power->isPekeyLongPressIrq()) {
|
||||
Serial.println("isPekeyLongPress");
|
||||
}
|
||||
if (power->isBatChargeDoneIrq()) {
|
||||
Serial.println("isBatChargeDone");
|
||||
}
|
||||
if (power->isBatChargeStartIrq()) {
|
||||
Serial.println("isBatChargeStart");
|
||||
}
|
||||
// Clear PMU Interrupt Status Register
|
||||
power->clearIrqStatus();
|
||||
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
|
||||
31
XPowersLib/examples/XPowersLibInterface_Linux/Makefile
Normal file
31
XPowersLib/examples/XPowersLibInterface_Linux/Makefile
Normal file
@@ -0,0 +1,31 @@
|
||||
EXAMPLE_DIR = .
|
||||
SRC_DIR = ../../src
|
||||
DIR_BIN = ./build
|
||||
|
||||
OBJ_C = $(wildcard ${SRC_DIR}/*.cpp ${EXAMPLE_DIR}/*.cpp)
|
||||
OBJ_O = $(patsubst %.cpp,${DIR_BIN}/%.o,$(notdir ${OBJ_C}))
|
||||
|
||||
TARGET = main
|
||||
|
||||
DEBUG = -DXPOWERS_NO_ERROR
|
||||
|
||||
$(shell mkdir -p $(DIR_BIN))
|
||||
|
||||
# Change to the directory where the g++ compilation chain is located
|
||||
SDK_PATH = /mnt/c/Users/lewis/Desktop/liunx/
|
||||
CC = $(SDK_PATH)/luckfox-pico/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin/arm-rockchip830-linux-uclibcgnueabihf-g++
|
||||
MSG = -g -O0 -Wall
|
||||
CFLAGS += $(MSG) $(DEBUG)
|
||||
|
||||
${TARGET}:${OBJ_O}
|
||||
$(CC) $(CFLAGS) $(OBJ_O) -o $@ $(LIB)
|
||||
|
||||
${DIR_BIN}/%.o:$(EXAMPLE_DIR)/%.cpp
|
||||
$(CC) $(CFLAGS) -c $< -o $@ -I $(SRC_DIR)
|
||||
|
||||
${DIR_BIN}/%.o:$(SRC_DIR)/%.cpp
|
||||
$(CC) $(CFLAGS) -c $< -o $@ $(LIB)
|
||||
|
||||
clean :
|
||||
rm $(DIR_BIN)/*.*
|
||||
rm $(TARGET)
|
||||
159
XPowersLib/examples/XPowersLibInterface_Linux/liunx_gpio.cpp
Normal file
159
XPowersLib/examples/XPowersLibInterface_Linux/liunx_gpio.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* @file linux_gpio.cpp
|
||||
* @author Lewis He (lewishe@outlook.com)
|
||||
* @license MIT
|
||||
* @copyright Copyright (c) 2023 Shenzhen Xinyuan Electronic Technology Co., Ltd
|
||||
* @date 2023-11-20
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
|
||||
int linux_gpio_export(int pin);
|
||||
int linux_gpio_unexport(int pin);
|
||||
int linux_gpio_direction(int pin, int dir);
|
||||
int linux_gpio_write(int pin, int value);
|
||||
int linux_gpio_read(int pin);
|
||||
int linux_gpio_edge(int pin, int edge);
|
||||
|
||||
int linux_gpio_export(int pin)
|
||||
{
|
||||
char buffer[64];
|
||||
int len;
|
||||
int fd;
|
||||
fd = open("/sys/class/gpio/export", O_WRONLY);
|
||||
if (fd < 0) {
|
||||
printf("Failed to open export for writing!\n");
|
||||
return (-1);
|
||||
}
|
||||
len = snprintf(buffer, sizeof(buffer), "%d", pin);
|
||||
printf("%s,%d,%d\n", buffer, sizeof(buffer), len);
|
||||
if (write(fd, buffer, len) < 0) {
|
||||
printf("Failed to export gpio!");
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int linux_gpio_unexport(int pin)
|
||||
{
|
||||
char buffer[64];
|
||||
int len;
|
||||
int fd;
|
||||
fd = open("/sys/class/gpio/unexport", O_WRONLY);
|
||||
if (fd < 0) {
|
||||
printf("Failed to open unexport for writing!\n");
|
||||
return -1;
|
||||
}
|
||||
len = snprintf(buffer, sizeof(buffer), "%d", pin);
|
||||
if (write(fd, buffer, len) < 0) {
|
||||
printf("Failed to unexport gpio!");
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// dir: 0-->IN, 1-->OUT
|
||||
int linux_gpio_direction(int pin, int dir)
|
||||
{
|
||||
const char dir_str[] = "in\0out";
|
||||
char path[64];
|
||||
int fd;
|
||||
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", pin);
|
||||
fd = open(path, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
printf("Failed to open gpio direction for writing!\n");
|
||||
return -1;
|
||||
}
|
||||
if (write(fd, &dir_str[dir == 0 ? 0 : 3], dir == 0 ? 2 : 3) < 0) {
|
||||
printf("Failed to set direction!\n");
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// value: 0-->LOW, 1-->HIGH
|
||||
int linux_gpio_write(int pin, int value)
|
||||
{
|
||||
const char values_str[] = "01";
|
||||
char path[64];
|
||||
int fd;
|
||||
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);
|
||||
fd = open(path, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
printf("Failed to open gpio value for writing!\n");
|
||||
return -1;
|
||||
}
|
||||
if (write(fd, &values_str[value == 0 ? 0 : 1], 1) < 0) {
|
||||
printf("Failed to write value!\n");
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int linux_gpio_read(int pin)
|
||||
{
|
||||
char path[64];
|
||||
char value_str[3];
|
||||
int fd;
|
||||
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
printf("Failed to open gpio value for reading!\n");
|
||||
return -1;
|
||||
}
|
||||
if (read(fd, value_str, 3) < 0) {
|
||||
printf("Failed to read value!\n");
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
return (atoi(value_str));
|
||||
}
|
||||
|
||||
// 0-->none, 1-->rising, 2-->falling, 3-->both
|
||||
int linux_gpio_edge(int pin, int edge)
|
||||
{
|
||||
const char dir_str[] = "none\0rising\0falling\0both";
|
||||
unsigned char ptr = 0;
|
||||
char path[64];
|
||||
int fd;
|
||||
switch (edge) {
|
||||
case 0:
|
||||
ptr = 0;
|
||||
break;
|
||||
case 1:
|
||||
ptr = 5;
|
||||
break;
|
||||
case 2:
|
||||
ptr = 12;
|
||||
break;
|
||||
case 3:
|
||||
ptr = 20;
|
||||
break;
|
||||
default:
|
||||
ptr = 0;
|
||||
}
|
||||
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/edge", pin);
|
||||
fd = open(path, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
printf("Failed to open gpio edge for writing!\n");
|
||||
return -1;
|
||||
}
|
||||
if (write(fd, &dir_str[ptr], strlen(&dir_str[ptr])) < 0) {
|
||||
printf("Failed to set edge!\n");
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
532
XPowersLib/examples/XPowersLibInterface_Linux/main.cpp
Normal file
532
XPowersLib/examples/XPowersLibInterface_Linux/main.cpp
Normal file
@@ -0,0 +1,532 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 lewis he
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
! WARN:
|
||||
Please do not run the example without knowing the external load voltage of the PMU,
|
||||
it may burn your external load, please check the voltage setting before running the example,
|
||||
if there is any loss, please bear it by yourself
|
||||
*/
|
||||
#ifndef XPOWERS_NO_ERROR
|
||||
#error "Running this example is known to not damage the device! Please go and uncomment this!"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h> //define O_RDWR
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/poll.h>
|
||||
#include "XPowersLib.h"
|
||||
|
||||
#ifndef CONFIG_PMU_IRQ
|
||||
#define CONFIG_PMU_IRQ 55
|
||||
#endif
|
||||
|
||||
extern int linux_gpio_edge(int pin, int edge);
|
||||
extern int linux_gpio_direction(int pin, int dir);
|
||||
extern int linux_gpio_export(int pin);
|
||||
extern int linux_gpio_unexport(int pin);
|
||||
|
||||
const uint8_t pmu_irq_pin = CONFIG_PMU_IRQ;
|
||||
|
||||
// Change to the hardware I2C device name you need to use
|
||||
const char *i2c_device = "/dev/i2c-3";
|
||||
int hardware_i2c_fd = -1;
|
||||
|
||||
|
||||
int linux_i2c_read_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
|
||||
{
|
||||
uint8_t tmp[1] = {regAddr};
|
||||
// Write reg address
|
||||
write(hardware_i2c_fd, tmp, 1);
|
||||
// Read reg data
|
||||
return read(hardware_i2c_fd, data, len);
|
||||
}
|
||||
|
||||
int linux_i2c_write_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
|
||||
{
|
||||
uint8_t tmp[1] = {regAddr};
|
||||
// Write reg address
|
||||
write(hardware_i2c_fd, tmp, 1);
|
||||
// Write data buffer
|
||||
return write(hardware_i2c_fd, data, len);
|
||||
}
|
||||
|
||||
|
||||
// Use the XPowersLibInterface standard to use the xpowers API
|
||||
XPowersLibInterface *PMU = NULL;
|
||||
|
||||
void printPMU()
|
||||
{
|
||||
printf("isCharging:%s\n", PMU->isCharging() ? "YES" : "NO");
|
||||
printf("isDischarge:%s\n", PMU->isDischarge() ? "YES" : "NO");
|
||||
printf("isVbusIn:%s\n", PMU->isVbusIn() ? "YES" : "NO");
|
||||
printf("getBattVoltage:%u mV\n", PMU->getBattVoltage());
|
||||
printf("getVbusVoltage:%u mV\n", PMU->getVbusVoltage());
|
||||
printf("getSystemVoltage:%u mV\n", PMU->getSystemVoltage());
|
||||
|
||||
// The battery percentage may be inaccurate at first use, the PMU will automatically
|
||||
// learn the battery curve and will automatically calibrate the battery percentage
|
||||
// after a charge and discharge cycle
|
||||
if (PMU->isBatteryConnect()) {
|
||||
printf("getBatteryPercent:%d%%", PMU->getBatteryPercent());
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
// Open I2C device
|
||||
if ((hardware_i2c_fd = open(i2c_device, O_RDWR)) < 0) {
|
||||
perror("Failed to open i2c device.\n");
|
||||
exit(1);
|
||||
} else {
|
||||
printf("open : %s\r\n", i2c_device);
|
||||
}
|
||||
|
||||
if (!PMU) {
|
||||
if (ioctl(hardware_i2c_fd, I2C_SLAVE, AXP2101_SLAVE_ADDRESS) < 0) {
|
||||
printf("Failed to access bus.\n");
|
||||
exit(1);
|
||||
}
|
||||
PMU = new XPowersAXP2101(AXP2101_SLAVE_ADDRESS, linux_i2c_read_callback, linux_i2c_write_callback);
|
||||
if (!PMU->init()) {
|
||||
printf("Warning: Failed to find AXP2101 power management\n");
|
||||
delete PMU;
|
||||
PMU = NULL;
|
||||
} else {
|
||||
printf("AXP2101 PMU init succeeded, using AXP2101 PMU\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!PMU) {
|
||||
if (ioctl(hardware_i2c_fd, I2C_SLAVE, AXP192_SLAVE_ADDRESS) < 0) {
|
||||
printf("Failed to access bus.\n");
|
||||
exit(1);
|
||||
}
|
||||
PMU = new XPowersAXP192(AXP192_SLAVE_ADDRESS, linux_i2c_read_callback, linux_i2c_write_callback);
|
||||
if (!PMU->init()) {
|
||||
printf("Warning: Failed to find AXP192 power management\n");
|
||||
delete PMU;
|
||||
PMU = NULL;
|
||||
} else {
|
||||
printf("AXP192 PMU init succeeded, using AXP192 PMU\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!PMU) {
|
||||
if (ioctl(hardware_i2c_fd, I2C_SLAVE, AXP202_SLAVE_ADDRESS) < 0) {
|
||||
printf("Failed to access bus.\n");
|
||||
exit(1);
|
||||
}
|
||||
PMU = new XPowersAXP202(AXP202_SLAVE_ADDRESS, linux_i2c_read_callback, linux_i2c_write_callback);
|
||||
printf("Warning: Failed to find AXP202 power management\n");
|
||||
delete PMU;
|
||||
PMU = NULL;
|
||||
} else {
|
||||
printf("AXP202 PMU init succeeded, using AXP202 PMU\n");
|
||||
}
|
||||
|
||||
if (!PMU) {
|
||||
printf("PMU not detected, please check..\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//The following AXP192 power supply setting voltage is based on esp32 T-beam
|
||||
if (PMU->getChipModel() == XPOWERS_AXP192) {
|
||||
|
||||
// lora radio power channel
|
||||
PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_LDO2);
|
||||
|
||||
|
||||
// oled module power channel,
|
||||
// disable it will cause abnormal communication between boot and AXP power supply,
|
||||
// do not turn it off
|
||||
PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
|
||||
// enable oled power
|
||||
PMU->enablePowerOutput(XPOWERS_DCDC1);
|
||||
|
||||
// gnss module power channel
|
||||
PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300);
|
||||
// PMU->enablePowerOutput(XPOWERS_LDO3);
|
||||
|
||||
|
||||
//protected oled power source
|
||||
PMU->setProtectedChannel(XPOWERS_DCDC1);
|
||||
//protected esp32 power source
|
||||
PMU->setProtectedChannel(XPOWERS_DCDC3);
|
||||
|
||||
//disable not use channel
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC2);
|
||||
|
||||
//disable all axp chip interrupt
|
||||
PMU->disableIRQ(XPOWERS_AXP192_ALL_IRQ);
|
||||
|
||||
|
||||
//
|
||||
/* Set the constant current charging current of AXP192
|
||||
opt:
|
||||
XPOWERS_AXP192_CHG_CUR_100MA,
|
||||
XPOWERS_AXP192_CHG_CUR_190MA,
|
||||
XPOWERS_AXP192_CHG_CUR_280MA,
|
||||
XPOWERS_AXP192_CHG_CUR_360MA,
|
||||
XPOWERS_AXP192_CHG_CUR_450MA,
|
||||
XPOWERS_AXP192_CHG_CUR_550MA,
|
||||
XPOWERS_AXP192_CHG_CUR_630MA,
|
||||
XPOWERS_AXP192_CHG_CUR_700MA,
|
||||
XPOWERS_AXP192_CHG_CUR_780MA,
|
||||
XPOWERS_AXP192_CHG_CUR_880MA,
|
||||
XPOWERS_AXP192_CHG_CUR_960MA,
|
||||
XPOWERS_AXP192_CHG_CUR_1000MA,
|
||||
XPOWERS_AXP192_CHG_CUR_1080MA,
|
||||
XPOWERS_AXP192_CHG_CUR_1160MA,
|
||||
XPOWERS_AXP192_CHG_CUR_1240MA,
|
||||
XPOWERS_AXP192_CHG_CUR_1320MA,
|
||||
*/
|
||||
PMU->setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_550MA);
|
||||
|
||||
|
||||
}
|
||||
// The following AXP202 power supply voltage setting is based on esp32 T-Watch
|
||||
else if (PMU->getChipModel() == XPOWERS_AXP202) {
|
||||
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC2); //not elicited
|
||||
|
||||
//Display backlight
|
||||
PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_LDO2);
|
||||
|
||||
// Shiled Vdd
|
||||
PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_LDO3);
|
||||
|
||||
// S7xG GNSS Vdd
|
||||
PMU->setPowerChannelVoltage(XPOWERS_LDO4, 1800);
|
||||
PMU->enablePowerOutput(XPOWERS_LDO4);
|
||||
|
||||
|
||||
//
|
||||
/* Set the constant current charging current of AXP202
|
||||
opt:
|
||||
XPOWERS_AXP202_CHG_CUR_100MA,
|
||||
XPOWERS_AXP202_CHG_CUR_190MA,
|
||||
XPOWERS_AXP202_CHG_CUR_280MA,
|
||||
XPOWERS_AXP202_CHG_CUR_360MA,
|
||||
XPOWERS_AXP202_CHG_CUR_450MA,
|
||||
XPOWERS_AXP202_CHG_CUR_550MA,
|
||||
XPOWERS_AXP202_CHG_CUR_630MA,
|
||||
XPOWERS_AXP202_CHG_CUR_700MA,
|
||||
XPOWERS_AXP202_CHG_CUR_780MA,
|
||||
XPOWERS_AXP202_CHG_CUR_880MA,
|
||||
XPOWERS_AXP202_CHG_CUR_960MA,
|
||||
XPOWERS_AXP202_CHG_CUR_1000MA,
|
||||
XPOWERS_AXP202_CHG_CUR_1080MA,
|
||||
XPOWERS_AXP202_CHG_CUR_1160MA,
|
||||
XPOWERS_AXP202_CHG_CUR_1240MA,
|
||||
XPOWERS_AXP202_CHG_CUR_1320MA,
|
||||
*/
|
||||
PMU->setChargerConstantCurr(XPOWERS_AXP202_CHG_CUR_550MA);
|
||||
|
||||
}
|
||||
// The following AXP192 power supply voltage setting is based on esp32s3 T-beam
|
||||
else if (PMU->getChipModel() == XPOWERS_AXP2101) {
|
||||
|
||||
// gnss module power channel
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO4);
|
||||
|
||||
// lora radio power channel
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO3);
|
||||
|
||||
// m.2 interface
|
||||
PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_DCDC3);
|
||||
|
||||
// PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
|
||||
// PMU->enablePowerOutput(XPOWERS_DCDC4);
|
||||
|
||||
//not use channel
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC2); //not elicited
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC5); //not elicited
|
||||
PMU->disablePowerOutput(XPOWERS_DLDO1); //Invalid power channel, it does not exist
|
||||
PMU->disablePowerOutput(XPOWERS_DLDO2); //Invalid power channel, it does not exist
|
||||
PMU->disablePowerOutput(XPOWERS_VBACKUP);
|
||||
|
||||
//disable all axp chip interrupt
|
||||
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
|
||||
/* Set the constant current charging current of AXP2101
|
||||
opt:
|
||||
XPOWERS_AXP2101_CHG_CUR_100MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_125MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_150MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_175MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_200MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_300MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_400MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_500MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_600MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_700MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_800MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_900MA,
|
||||
XPOWERS_AXP2101_CHG_CUR_1000MA,
|
||||
*/
|
||||
PMU->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA);
|
||||
|
||||
}
|
||||
|
||||
printf("=======================================================================\n");
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC1)) {
|
||||
printf("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC2)) {
|
||||
printf("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC3)) {
|
||||
printf("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC4)) {
|
||||
printf("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_LDO2)) {
|
||||
printf("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO2));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_LDO3)) {
|
||||
printf("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO3));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_LDO4)) {
|
||||
printf("LDO4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO4));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_LDO5)) {
|
||||
printf("LDO5 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO5) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO5));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO1)) {
|
||||
printf("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO2)) {
|
||||
printf("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO3)) {
|
||||
printf("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO4)) {
|
||||
printf("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_BLDO1)) {
|
||||
printf("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_BLDO2)) {
|
||||
printf("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
|
||||
}
|
||||
printf("=======================================================================\n");
|
||||
|
||||
|
||||
//Set up the charging voltage, AXP2101/AXP192 4.2V gear is the same
|
||||
// XPOWERS_AXP192_CHG_VOL_4V2 = XPOWERS_AXP2101_CHG_VOL_4V2
|
||||
PMU->setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2);
|
||||
|
||||
// Set VSY off voltage as 2600mV , Adjustment range 2600mV ~ 3300mV
|
||||
PMU->setSysPowerDownVoltage(2600);
|
||||
|
||||
// Get the VSYS shutdown voltage
|
||||
uint16_t vol = PMU->getSysPowerDownVoltage();
|
||||
printf("-> getSysPowerDownVoltage:%u\n", vol);
|
||||
|
||||
|
||||
|
||||
// Set the time of pressing the button to turn off
|
||||
PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
|
||||
uint8_t opt = PMU->getPowerKeyPressOffTime();
|
||||
printf("PowerKeyPressOffTime:");
|
||||
switch (opt) {
|
||||
case XPOWERS_POWEROFF_4S: printf("4 Second\n");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_6S: printf("6 Second\n");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_8S: printf("8 Second\n");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_10S: printf("10 Second\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the button power-on press time
|
||||
PMU->setPowerKeyPressOnTime(XPOWERS_POWERON_128MS);
|
||||
opt = PMU->getPowerKeyPressOnTime();
|
||||
printf("PowerKeyPressOnTime:");
|
||||
switch (opt) {
|
||||
case XPOWERS_POWERON_128MS: printf("128 Ms\n");
|
||||
break;
|
||||
case XPOWERS_POWERON_512MS: printf("512 Ms\n");
|
||||
break;
|
||||
case XPOWERS_POWERON_1S: printf("1 Second\n");
|
||||
break;
|
||||
case XPOWERS_POWERON_2S: printf("2 Second\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("===========================================================================");
|
||||
|
||||
// It is necessary to disable the detection function of the TS pin on the board
|
||||
// without the battery temperature detection function, otherwise it will cause abnormal charging
|
||||
PMU->disableTSPinMeasure();
|
||||
|
||||
// Enable internal ADC detection
|
||||
PMU->enableBattDetection();
|
||||
PMU->enableVbusVoltageMeasure();
|
||||
PMU->enableBattVoltageMeasure();
|
||||
PMU->enableSystemVoltageMeasure();
|
||||
|
||||
|
||||
/*
|
||||
The default setting is CHGLED is automatically controlled by the PMU.
|
||||
- XPOWERS_CHG_LED_OFF,
|
||||
- XPOWERS_CHG_LED_BLINK_1HZ,
|
||||
- XPOWERS_CHG_LED_BLINK_4HZ,
|
||||
- XPOWERS_CHG_LED_ON,
|
||||
- XPOWERS_CHG_LED_CTRL_CHG,
|
||||
* */
|
||||
PMU->setChargingLedMode(XPOWERS_CHG_LED_OFF);
|
||||
|
||||
|
||||
// Clear all interrupt flags
|
||||
PMU->clearIrqStatus();
|
||||
|
||||
|
||||
/*
|
||||
// call specific interrupt request
|
||||
|
||||
uint64_t pmuIrqMask = 0;
|
||||
|
||||
if (PMU->getChipModel() == XPOWERS_AXP192) {
|
||||
|
||||
pmuIrqMask = XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_VBUS_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_BAT_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP192_PKEY_SHORT_IRQ | XPOWERS_AXP192_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP192_BAT_CHG_START_IRQ | XPOWERS_AXP192_BAT_CHG_DONE_IRQ ; //CHARGE
|
||||
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
|
||||
|
||||
pmuIrqMask = XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ; //CHARGE
|
||||
}
|
||||
// Enable the required interrupt function
|
||||
PMU->enableIRQ(pmuIrqMask);
|
||||
|
||||
*/
|
||||
|
||||
// Call the interrupt request through the interface class
|
||||
PMU->disableInterrupt(XPOWERS_ALL_INT);
|
||||
|
||||
PMU->enableInterrupt(XPOWERS_USB_INSERT_INT |
|
||||
XPOWERS_USB_REMOVE_INT |
|
||||
XPOWERS_BATTERY_INSERT_INT |
|
||||
XPOWERS_BATTERY_REMOVE_INT |
|
||||
XPOWERS_PWR_BTN_CLICK_INT |
|
||||
XPOWERS_CHARGE_START_INT |
|
||||
XPOWERS_CHARGE_DONE_INT);
|
||||
|
||||
// Attach PMU irq to gpio interrupt
|
||||
linux_gpio_unexport(pmu_irq_pin);
|
||||
linux_gpio_export(pmu_irq_pin);
|
||||
linux_gpio_direction(pmu_irq_pin, INPUT);
|
||||
linux_gpio_edge(pmu_irq_pin, FALLING);
|
||||
|
||||
struct pollfd fdset[1];
|
||||
char buf[64];
|
||||
int fd, ret;
|
||||
|
||||
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", pmu_irq_pin);
|
||||
fd = open(buf, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
printf("Failed to open gpio value for reading!\n");
|
||||
return -1;
|
||||
}
|
||||
fdset[0].fd = fd;
|
||||
fdset[0].events = POLLPRI;
|
||||
|
||||
while (1) {
|
||||
ret = read(fd, buf, 10);
|
||||
if (ret == -1) {
|
||||
printf("read failed\n");
|
||||
}
|
||||
|
||||
ret = poll(fdset, 1, 0);
|
||||
if (ret == -1) {
|
||||
printf("poll failed\n");
|
||||
}
|
||||
|
||||
if (fdset[0].revents & POLLPRI) {
|
||||
ret = lseek(fd, 0, SEEK_SET);
|
||||
if (ret == -1) {
|
||||
printf("lseek failed\n");
|
||||
}
|
||||
|
||||
// Get PMU Interrupt Status Register
|
||||
uint32_t status = PMU->getIrqStatus();
|
||||
printf("STATUS => HEX:0x%X\n", status);
|
||||
|
||||
if (PMU->isVbusInsertIrq()) {
|
||||
printf("isVbusInsert\n");
|
||||
}
|
||||
if (PMU->isVbusRemoveIrq()) {
|
||||
printf("isVbusRemove\n");
|
||||
}
|
||||
if (PMU->isBatInsertIrq()) {
|
||||
printf("isBatInsert\n");
|
||||
}
|
||||
if (PMU->isBatRemoveIrq()) {
|
||||
printf("isBatRemove\n");
|
||||
}
|
||||
if (PMU->isPekeyShortPressIrq()) {
|
||||
printf("isPekeyShortPress\n");
|
||||
}
|
||||
if (PMU->isPekeyLongPressIrq()) {
|
||||
printf("isPekeyLongPress\n");
|
||||
}
|
||||
if (PMU->isBatChargeDoneIrq()) {
|
||||
printf("isBatChargeDone\n");
|
||||
}
|
||||
if (PMU->isBatChargeStartIrq()) {
|
||||
printf("isBatChargeStart\n");
|
||||
}
|
||||
// Clear PMU Interrupt Status Register
|
||||
PMU->clearIrqStatus();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user