Initial commit of Arduino libraries

This commit is contained in:
Sam
2025-05-23 10:47:41 +10:00
commit 5bfce5fc3e
2476 changed files with 1108481 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
set(src_dirs ./src)
set(include_dirs ./src
./src/REG)
idf_component_register(SRC_DIRS ${src_dirs} INCLUDE_DIRS ${include_dirs})

59
XPowersLib/Kconfig Normal file
View 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 XPowersLib_ESP_IDF_API
prompt "XPowers library esp-idf api version"
default XPOWERS_ESP_IDF_NEW_API
help
Define API version
config XPOWERS_ESP_IDF_NEW_API
bool "Use esp-idf higher version (>= 5.0) API"
config XPOWERS_ESP_IDF_OLD_API
bool "Use esp-idf lower version ( < 5.0) API , Compatible with lower versions of esp-idf"
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

21
XPowersLib/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
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.

View File

@@ -0,0 +1,312 @@
'''
@license 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.
@file AXP192_AllFunction.py
@author Lewis He (lewishe@outlook.com)
@date 2022-10-20
'''
from AXP192 import *
import time
SDA = None
SCL = None
IRQ = None
I2CBUS = None
if implementation.name == 'micropython':
from machine import Pin, I2C
SDA = 21
SCL = 22
IRQ = 35
I2CBUS = I2C(0, scl=Pin(SCL), sda=Pin(SDA))
if implementation.name == 'circuitpython':
import digitalio
from board import *
import busio
SDA = IO15
SCL = IO7
IRQ = IO6
I2CBUS = busio.I2C(SCL, SDA)
pmu_flag = False
irq = None
def __callback(args):
global pmu_flag
pmu_flag = True
# print('callback')
PMU = AXP192(I2CBUS, addr=AXP192_SLAVE_ADDRESS)
print('getID:%s' % hex(PMU.getChipID()))
# Set the minimum system operating voltage inside the PMU,
# below this value will shut down the PMU
# Range: 2600~3300mV
PMU.setSysPowerDownVoltage(2600)
# Set the minimum common working voltage of the PMU VBUS input,
# below this value will turn off the PMU
PMU.setVbusVoltageLimit(PMU.XPOWERS_AXP192_VBUS_VOL_LIM_4V5)
# Turn off USB input current limit
PMU.setVbusCurrentLimit(PMU.XPOWERS_AXP192_VBUS_CUR_LIM_OFF)
# DC1 700~3500mV, IMAX=1.2A
PMU.setDC1Voltage(3300)
# print('DC1 : %s Voltage:%u mV ' % PMU.isEnableDC1() ? '+': '-', PMU.getDC1Voltage())
print('DC1 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC1()], PMU.getDC1Voltage()))
# DC2 700~2750 mV, IMAX=1.6A
PMU.setDC2Voltage(2750)
print(PMU.isEnableDC2())
print('DC2 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC2()], PMU.getDC2Voltage()))
# DC3 700~3500mV,IMAX=0.7A
PMU.setDC3Voltage(3300)
print('DC3 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC3()], PMU.getDC3Voltage()))
# LDO2 1800~3300 mV, 100mV/step, IMAX=200mA
PMU.setLDO2Voltage(1800)
# LDO3 1800~3300 mV, 100mV/step, IMAX=200mA
PMU.setLDO3Voltage(1800)
# LDOio 1800~3300 mV, 100mV/step, IMAX=50mA
PMU.setLDOioVoltage(3300)
# Enable power output channel
PMU.enableDC1()
PMU.enableDC2()
PMU.enableDC3()
PMU.enableLDO2()
PMU.enableLDO3()
PMU.enableLDOio()
print('===================================')
print('DC1 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC1()], PMU.getDC1Voltage()))
print('DC2 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC2()], PMU.getDC2Voltage()))
print('DC3 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC3()], PMU.getDC3Voltage()))
print('===================================')
print('LDO2 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableLDO2()], PMU.getLDO2Voltage()))
print('LDO3 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableLDO3()], PMU.getLDO3Voltage()))
print('LDOio : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableLDOio()], PMU.getLDOioVoltage()))
print('===================================')
# Set the time of pressing the button to turn off
powerOff = ['4', '6', '8', '10']
PMU.setPowerKeyPressOffTime(PMU.XPOWERS_POWEROFF_6S)
opt = PMU.getPowerKeyPressOffTime()
print('PowerKeyPressOffTime: %s Sceond' % powerOff[opt])
# Set the button power-on press time
powerOn = ['128ms', '512ms', '1000ms', '2000ms']
PMU.setPowerKeyPressOnTime(PMU.XPOWERS_POWERON_2S)
opt = PMU.getPowerKeyPressOnTime()
print('PowerKeyPressOnTime: %s ' % powerOn[opt])
print('===================================')
# 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()
PMU.enableTemperatureMeasure()
# PMU.disableTemperatureMeasure()
# 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(PMU.XPOWERS_CHG_LED_OFF)
# Disable all interrupts
PMU.disableIRQ(PMU.XPOWERS_AXP192_ALL_IRQ)
# Clear all interrupt flags
PMU.clearIrqStatus()
# Enable the required interrupt function
PMU.enableIRQ(
PMU.XPOWERS_AXP192_BAT_INSERT_IRQ | PMU.XPOWERS_AXP192_BAT_REMOVE_IRQ | # BATTERY
PMU.XPOWERS_AXP192_VBUS_INSERT_IRQ | PMU.XPOWERS_AXP192_VBUS_REMOVE_IRQ | # VBUS
PMU.XPOWERS_AXP192_PKEY_SHORT_IRQ | PMU.XPOWERS_AXP192_PKEY_LONG_IRQ | # POWER KEY
PMU.XPOWERS_AXP192_BAT_CHG_DONE_IRQ | PMU.XPOWERS_AXP192_BAT_CHG_START_IRQ | # CHARGE
# PMU.XPOWERS_AXP192_PKEY_NEGATIVE_IRQ | PMU.XPOWERS_AXP192_PKEY_POSITIVE_IRQ | # POWER KEY
PMU.XPOWERS_AXP192_TIMER_TIMEOUT_IRQ # Timer
)
# Set constant current charge current limit
PMU.setChargerConstantCurr(PMU.XPOWERS_AXP192_CHG_CUR_280MA)
# Set stop charging termination current
PMU.setChargerTerminationCurr(PMU.XPOWERS_AXP192_CHG_ITERM_LESS_10_PERCENT)
# Set charge cut-off voltage
PMU.setChargeTargetVoltage(PMU.XPOWERS_AXP192_CHG_VOL_4V2)
PMU.clearIrqStatus()
# Set the timing after one minute, the isWdtExpireIrq will be triggered in the loop interrupt function
PMU.setTimerout(1)
data = [1, 2, 3, 4]
print('Write buffer to pmu')
PMU.writeDataBuffer(data, 4)
print('Read buffer from pmu')
tmp = PMU.readDataBuffer(4)
print(tmp)
if implementation.name == 'micropython':
irq = Pin(IRQ, Pin.IN, Pin.PULL_UP)
irq.irq(trigger=Pin.IRQ_FALLING, handler=__callback)
if implementation.name == 'circuitpython':
irq = digitalio.DigitalInOut(IRQ)
irq.switch_to_input()
while True:
if implementation.name == 'circuitpython':
if irq.value == False:
pmu_flag = True
if pmu_flag:
pmu_flag = False
mask = PMU.getIrqStatus()
print('pmu_flag:', end='')
print(bin(mask))
if PMU.isAcinOverVoltageIrq():
print("IRQ ---> isAcinOverVoltageIrq")
if PMU.isAcinInserIrq():
print("IRQ ---> isAcinInserIrq")
if PMU.isAcinRemoveIrq():
print("IRQ ---> isAcinRemoveIrq")
if PMU.isVbusOverVoltageIrq():
print("IRQ ---> isVbusOverVoltageIrq")
if PMU.isVbusInsertIrq():
print("IRQ ---> isVbusInsertIrq")
if PMU.isVbusRemoveIrq():
print("IRQ ---> isVbusRemoveIrq")
if PMU.isVbusLowVholdIrq():
print("IRQ ---> isVbusLowVholdIrq")
if PMU.isBatInsertIrq():
print("IRQ ---> isBatInsertIrq")
if PMU.isBatRemoveIrq():
print("IRQ ---> isBatRemoveIrq")
if PMU.isBattEnterActivateIrq():
print("IRQ ---> isBattEnterActivateIrq")
if PMU.isBattExitActivateIrq():
print("IRQ ---> isBattExitActivateIrq")
if PMU.isBatChargeStartIrq():
print("IRQ ---> isBatChargeStartIrq")
if PMU.isBatChargeDoneIrq():
print("IRQ ---> isBatChargeDoneIrq")
if PMU.isBattTempHighIrq():
print("IRQ ---> isBattTempHighIrq")
if PMU.isBattTempLowIrq():
print("IRQ ---> isBattTempLowIrq")
if PMU.isChipOverTemperatureIrq():
print("IRQ ---> isChipOverTemperatureIrq")
if PMU.isChargingCurrentLessIrq():
print("IRQ ---> isChargingCurrentLessIrq")
if PMU.isDC1VoltageLessIrq():
print("IRQ ---> isDC1VoltageLessIrq")
if PMU.isDC2VoltageLessIrq():
print("IRQ ---> isDC2VoltageLessIrq")
if PMU.isDC3VoltageLessIrq():
print("IRQ ---> isDC3VoltageLessIrq")
if PMU.isPekeyShortPressIrq():
print("IRQ ---> isPekeyShortPress")
if PMU.isPekeyLongPressIrq():
print("IRQ ---> isPekeyLongPress")
if PMU.isNOEPowerOnIrq():
print("IRQ ---> isNOEPowerOnIrq")
if PMU.isNOEPowerDownIrq():
print("IRQ ---> isNOEPowerDownIrq")
if PMU.isVbusEffectiveIrq():
print("IRQ ---> isVbusEffectiveIrq")
if PMU.isVbusInvalidIrq():
print("IRQ ---> isVbusInvalidIrq")
if PMU.isVbusSessionIrq():
print("IRQ ---> isVbusSessionIrq")
if PMU.isVbusSessionEndIrq():
print("IRQ ---> isVbusSessionEndIrq")
if PMU.isLowVoltageLevel2Irq():
print("IRQ ---> isLowVoltageLevel2Irq")
if PMU.isWdtExpireIrq():
print("IRQ ---> isWdtExpire")
# Clear the timer state and continue to the next timer
PMU.clearTimerFlag()
if PMU.isGpio2EdgeTriggerIrq():
print("IRQ ---> isGpio2EdgeTriggerIrq")
if PMU.isGpio1EdgeTriggerIrq():
print("IRQ ---> isGpio1EdgeTriggerIrq")
if PMU.isGpio0EdgeTriggerIrq():
print("IRQ ---> isGpio0EdgeTriggerIrq")
# Clear PMU Interrupt Status Register
PMU.clearIrqStatus()
PMU.setChargingLedMode((PMU.XPOWERS_CHG_LED_OFF, PMU.XPOWERS_CHG_LED_ON)[
PMU.getChargingLedMode() == PMU.XPOWERS_CHG_LED_OFF])
print("getBattVoltage:{0}mV".format(PMU.getBattVoltage()))
print("getSystemVoltage:{0}mV".format(PMU.getSystemVoltage()))
print("getBatteryPercent:{0}%".format(PMU.getBatteryPercent()))
print("getTemperature:{0}%".format(PMU.getTemperature()))
print("isCharging:{0}".format(PMU.isCharging()))
print("isDischarge:{0}".format(PMU.isDischarge()))
print("isVbusIn:{0}".format(PMU.isVbusIn()))
time.sleep(0.8)

View File

@@ -0,0 +1,64 @@
'''
@license 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.
@file AXP192_AnalogRead.py
@author Lewis He (lewishe@outlook.com)
@date 2022-10-20
'''
from AXP192 import *
import time
SDA = None
SCL = None
I2CBUS = None
if implementation.name == 'micropython':
from machine import Pin, I2C
SDA = 21
SCL = 22
IRQ = 35
I2CBUS = I2C(scl=Pin(SCL), sda=Pin(SDA))
if implementation.name == 'circuitpython':
from board import *
import busio
SDA = IO15
SCL = IO7
IRQ = IO6
I2CBUS = busio.I2C(SCL, SDA)
PMU = AXP192(I2CBUS, addr=AXP192_SLAVE_ADDRESS)
print('getID:%s' % hex(PMU.getChipID()))
val = 0
while True:
IO0 = PMU.analogRead(PMU.PMU_GPIO0)
IO1 = PMU.analogRead(PMU.PMU_GPIO1)
# IO2 = PMU.analogRead(PMU_GPIO2) # not support
# IO3 = PMU.analogRead(PMU_GPIO3) # not support
# IO4 = PMU.analogRead(PMU_GPIO4) # not support
# IO5 = PMU.analogRead(PMU_GPIO5) # not support
print('IO0:{0} IO1:{1} '.format(IO0, IO1))
time.sleep(1.5)

View File

@@ -0,0 +1,74 @@
'''
@license 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.
@file AXP192_GpioInput.py
@author Lewis He (lewishe@outlook.com)
@date 2022-10-20
'''
from AXP192 import *
import time
SDA = None
SCL = None
IRQ = None
I2CBUS = None
if implementation.name == 'micropython':
from machine import Pin, I2C
SDA = 21
SCL = 22
IRQ = 35
I2CBUS = I2C(scl=Pin(SCL), sda=Pin(SDA))
if implementation.name == 'circuitpython':
from board import *
import busio
SDA = IO15
SCL = IO7
IRQ = IO6
I2CBUS = busio.I2C(SCL, SDA)
PMU = AXP192(I2CBUS, addr=AXP192_SLAVE_ADDRESS)
print('getID:%s' % hex(PMU.getChipID()))
PMU.pinMode(PMU.PMU_GPIO0, PMU.INPUT_PULLDOWN)
PMU.pinMode(PMU.PMU_GPIO1, PMU.INPUT_PULLDOWN)
PMU.pinMode(PMU.PMU_GPIO2, PMU.INPUT_PULLDOWN)
PMU.pinMode(PMU.PMU_GPIO3, PMU.INPUT)
PMU.pinMode(PMU.PMU_GPIO4, PMU.INPUT)
PMU.pinMode(PMU.PMU_GPIO5, PMU.INPUT)
print('AXP192 GPIO 3 ~ 5 is a floating input, please ensure there is an external pull-up or pull-down resistor')
while True:
IO0 = PMU.digitalRead(PMU.PMU_GPIO0)
IO1 = PMU.digitalRead(PMU.PMU_GPIO1)
IO2 = PMU.digitalRead(PMU.PMU_GPIO2)
IO3 = PMU.digitalRead(PMU.PMU_GPIO3)
IO4 = PMU.digitalRead(PMU.PMU_GPIO4)
IO5 = PMU.digitalRead(PMU.PMU_GPIO5)
print('IO0:{0} IO1:{1} IO2:{2} IO3:{3} IO4:{4} IO5:{5} '.format(
IO0, IO1, IO2, IO3, IO4, IO5))
time.sleep(1.5)

View File

@@ -0,0 +1,369 @@
'''
@license 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.
@file AXP2101_AllFunction.py
@author Lewis He (lewishe@outlook.com)
@date 2022-10-20
'''
from AXP2101 import *
import time
SDA = None
SCL = None
IRQ = None
I2CBUS = None
if implementation.name == 'micropython':
from machine import Pin, I2C
SDA = 21
SCL = 22
IRQ = 35
I2CBUS = I2C(scl=Pin(SCL), sda=Pin(SDA))
if implementation.name == 'circuitpython':
import digitalio
import board
import busio
SDA = board.IO42
SCL = board.IO41
IRQ = board.IO6
I2CBUS = busio.I2C(SCL, SDA)
pmu_flag = False
irq = None
def __callback(args):
global pmu_flag
pmu_flag = True
# print('callback')
PMU = AXP2101(I2CBUS, addr=AXP2101_SLAVE_ADDRESS)
id = PMU.getChipID()
if id != XPOWERS_AXP2101_CHIP_ID:
print("PMU is not online...")
while True:
pass
print('getID:%s' % hex(PMU.getChipID()))
# Set the minimum common working voltage of the PMU VBUS input,
# below this value will turn off the PMU
PMU.setVbusVoltageLimit(PMU.XPOWERS_AXP2101_VBUS_VOL_LIM_4V36)
# Set the maximum current of the PMU VBUS input,
# higher than this value will turn off the PMU
PMU.setVbusCurrentLimit(PMU.XPOWERS_AXP2101_VBUS_CUR_LIM_1500MA)
# Get the VSYS shutdown voltage
vol = PMU.getSysPowerDownVoltage()
print('-> getSysPowerDownVoltage:%u' % vol)
# Set VSY off voltage as 2600mV, Adjustment range 2600mV ~ 3300mV
PMU.setSysPowerDownVoltage(2600)
vol = PMU.getSysPowerDownVoltage()
print('-> getSysPowerDownVoltage:%u' % vol)
# DC1 IMAX = 2A
# 1500~3400mV, 100mV/step, 20steps
PMU.setDC1Voltage(3300)
# print('DC1 : %s Voltage:%u mV ' % PMU.isEnableDC1() ? '+': '-', PMU.getDC1Voltage())
print('DC1 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC1()], PMU.getDC1Voltage()))
# DC2 IMAX = 2A
# 500~1200mV 10mV/step, 71steps
# 1220~1540mV 20mV/step, 17steps
PMU.setDC2Voltage(1000)
print(PMU.isEnableDC2())
print('DC2 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC2()], PMU.getDC2Voltage()))
# DC3 IMAX = 2A
# 500~1200mV, 10mV/step, 71steps
# 1220~1540mV, 20mV/step, 17steps
# 1600~3400mV, 100mV/step, 19steps
PMU.setDC3Voltage(3300)
print('DC3 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC3()], PMU.getDC3Voltage()))
# DCDC4 IMAX = 1.5A
# 500~1200mV, 10mV/step, 71steps
# 1220~1840mV, 20mV/step, 32steps
PMU.setDC4Voltage(1000)
print('DC4 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC4()], PMU.getDC4Voltage()))
# DC5 IMAX = 2A
# 1200mV
# 1400~3700mV, 100mV/step, 24steps
PMU.setDC5Voltage(3300)
print('DC5 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC5()], PMU.getDC5Voltage()))
# ALDO1 IMAX = 300mA
# 500~3500mV, 100mV/step, 31steps
PMU.setALDO1Voltage(3300)
# ALDO2 IMAX = 300mA
# 500~3500mV, 100mV/step, 31steps
PMU.setALDO2Voltage(3300)
# ALDO3 IMAX = 300mA
# 500~3500mV, 100mV/step, 31steps
PMU.setALDO3Voltage(3300)
# ALDO4 IMAX = 300mA
# 500~3500mV, 100mV/step, 31steps
PMU.setALDO4Voltage(3300)
# BLDO1 IMAX = 300mA
# 500~3500mV, 100mV/step, 31steps
PMU.setBLDO1Voltage(3300)
# BLDO2 IMAX = 300mA
# 500~3500mV, 100mV/step, 31steps
PMU.setBLDO2Voltage(3300)
# CPUSLDO IMAX = 30mA
# 500~1400mV, 50mV/step, 19steps
PMU.setCPUSLDOVoltage(1000)
# DLDO1 IMAX = 300mA
# 500~3400mV, 100mV/step, 29steps
PMU.setDLDO1Voltage(3300)
# DLDO2 IMAX = 300mA
# 500~1400mV, 50mV/step, 2steps
PMU.setDLDO2Voltage(3300)
# PMU.enableDC1()
PMU.enableDC2()
PMU.enableDC3()
PMU.enableDC4()
PMU.enableDC5()
PMU.enableALDO1()
PMU.enableALDO2()
PMU.enableALDO3()
PMU.enableALDO4()
PMU.enableBLDO1()
PMU.enableBLDO2()
PMU.enableCPUSLDO()
PMU.enableDLDO1()
PMU.enableDLDO2()
print('===================================')
print('DC1 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC1()], PMU.getDC1Voltage()))
print('DC2 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC2()], PMU.getDC2Voltage()))
print('DC3 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC3()], PMU.getDC3Voltage()))
print('DC4 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC4()], PMU.getDC4Voltage()))
print('DC5 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDC5()], PMU.getDC5Voltage()))
print('===================================')
print('ALDO1 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableALDO1()], PMU.getALDO1Voltage()))
print('ALDO2 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableALDO2()], PMU.getALDO2Voltage()))
print('ALDO3 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableALDO3()], PMU.getALDO3Voltage()))
print('ALDO4 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableALDO4()], PMU.getALDO4Voltage()))
print('===================================')
print('BLDO1 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableBLDO1()], PMU.getBLDO1Voltage()))
print('BLDO2 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableBLDO2()], PMU.getBLDO2Voltage()))
print('===================================')
print('CPUSLDO: {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableCPUSLDO()], PMU.getCPUSLDOVoltage()))
print('===================================')
print('DLDO1 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDLDO1()], PMU.getDLDO1Voltage()))
print('DLDO2 : {0} Voltage:{1} mV '.format(
('-', '+')[PMU.isEnableDLDO2()], PMU.getDLDO2Voltage()))
print('===================================')
# Set the time of pressing the button to turn off
powerOff = ['4', '6', '8', '10']
PMU.setPowerKeyPressOffTime(PMU.XPOWERS_POWEROFF_6S)
opt = PMU.getPowerKeyPressOffTime()
print('PowerKeyPressOffTime: %s Sceond' % powerOff[opt])
# Set the button power-on press time
powerOn = ['128ms', '512ms', '1000ms', '2000ms']
PMU.setPowerKeyPressOnTime(PMU.XPOWERS_POWERON_2S)
opt = PMU.getPowerKeyPressOnTime()
print('PowerKeyPressOnTime: %s ' % powerOn[opt])
print('===================================')
# DCDC 120 % (130 %) high voltage turn off PMIC function
en = PMU.getDCHighVoltagePowerDownEn()
print('getDCHighVoltagePowerDownEn:%s' % ('DISABLE', 'ENABLE')[en])
# DCDC1 85 % low voltage turn off PMIC function
en = PMU.getDC1LowVoltagePowerDownEn()
print('getDC1LowVoltagePowerDownEn:%s' % ('DISABLE', 'ENABLE')[en])
# DCDC2 85 % low voltage turn off PMIC function
en = PMU.getDC2LowVoltagePowerDownEn()
print('getDC2LowVoltagePowerDownEn:%s' % ('DISABLE', 'ENABLE')[en])
# DCDC3 85 % low voltage turn off PMIC function
en = PMU.getDC3LowVoltagePowerDownEn()
print('getDC3LowVoltagePowerDownEn:%s' % ('DISABLE', 'ENABLE')[en])
# DCDC4 85 % low voltage turn off PMIC function
en = PMU.getDC4LowVoltagePowerDownEn()
print('getDC4LowVoltagePowerDownEn:%s' % ('DISABLE', 'ENABLE')[en])
# DCDC5 85 % low voltage turn off PMIC function
en = PMU.getDC5LowVoltagePowerDownEn()
print('getDC5LowVoltagePowerDownEn:%s' % ('DISABLE', 'ENABLE')[en])
# PMU.setDCHighVoltagePowerDown(true)
# PMU.setDC1LowVoltagePowerDown(true)
# PMU.setDC2LowVoltagePowerDown(true)
# PMU.setDC3LowVoltagePowerDown(true)
# PMU.setDC4LowVoltagePowerDown(true)
# PMU.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
PMU.disableTSPinMeasure()
# PMU.enableTemperatureMeasure()
# 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(PMU.XPOWERS_CHG_LED_OFF)
# Disable all interrupts
PMU.disableIRQ(PMU.XPOWERS_AXP2101_ALL_IRQ)
# Clear all interrupt flags
PMU.clearIrqStatus()
# Enable the required interrupt function
PMU.enableIRQ(
PMU.XPOWERS_AXP2101_BAT_INSERT_IRQ | PMU.XPOWERS_AXP2101_BAT_REMOVE_IRQ | # BATTERY
PMU.XPOWERS_AXP2101_VBUS_INSERT_IRQ | PMU.XPOWERS_AXP2101_VBUS_REMOVE_IRQ | # VBUS
PMU.XPOWERS_AXP2101_PKEY_SHORT_IRQ | PMU.XPOWERS_AXP2101_PKEY_LONG_IRQ | # POWER KEY
PMU.XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | PMU.XPOWERS_AXP2101_BAT_CHG_START_IRQ # CHARGE
# PMU.XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ | PMU.XPOWERS_AXP2101_PKEY_POSITIVE_IRQ | # POWER KEY
)
# Set the precharge charging current
PMU.setPrechargeCurr(PMU.XPOWERS_AXP2101_PRECHARGE_50MA)
# Set constant current charge current limit
PMU.setChargerConstantCurr(PMU.XPOWERS_AXP2101_CHG_CUR_200MA)
# Set stop charging termination current
PMU.setChargerTerminationCurr(PMU.XPOWERS_AXP2101_CHG_ITERM_25MA)
# Set charge cut-off voltage
PMU.setChargeTargetVoltage(PMU.XPOWERS_AXP2101_CHG_VOL_4V1)
# Set the watchdog trigger event type
PMU.setWatchdogConfig(PMU.XPOWERS_AXP2101_WDT_IRQ_TO_PIN)
# Set watchdog timeout
PMU.setWatchdogTimeout(PMU.XPOWERS_AXP2101_WDT_TIMEOUT_4S)
# Enable watchdog to trigger interrupt event
# PMU.enableWatchdog()
PMU.disableWatchdog()
PMU.clearIrqStatus()
data = [1, 2, 3, 4]
print('Write buffer to pmu')
PMU.writeDataBuffer(data, 4)
print('Read buffer from pmu')
tmp = PMU.readDataBuffer(4)
print(tmp)
if implementation.name == 'micropython':
irq = Pin(IRQ, Pin.IN, Pin.PULL_UP)
irq.irq(trigger=Pin.IRQ_FALLING, handler=__callback)
if implementation.name == 'circuitpython':
irq = digitalio.DigitalInOut(IRQ)
irq.switch_to_input()
while True:
if implementation.name == 'circuitpython':
if irq.value == False:
pmu_flag = True
if pmu_flag:
pmu_flag = False
mask = PMU.getIrqStatus()
print('pmu_flag:', end='')
print(bin(mask))
if PMU.isPekeyShortPressIrq():
print("IRQ ---> isPekeyShortPress")
if PMU.isPekeyLongPressIrq():
print("IRQ ---> isPekeyLongPress")
if PMU.isPekeyNegativeIrq():
print("IRQ ---> isPekeyNegative")
if PMU.isPekeyPositiveIrq():
print("IRQ ---> isPekeyPositive")
if PMU.isWdtExpireIrq():
print("IRQ ---> isWdtExpire")
PMU.clearIrqStatus()
PMU.setChargingLedMode((PMU.XPOWERS_CHG_LED_OFF, PMU.XPOWERS_CHG_LED_ON)[
PMU.getChargingLedMode() == PMU.XPOWERS_CHG_LED_OFF])
print("getBattVoltage:{0}mV".format(PMU.getBattVoltage()))
print("getSystemVoltage:{0}mV".format(PMU.getSystemVoltage()))
print("getBatteryPercent:{0}%".format(PMU.getBatteryPercent()))
print("isCharging:{0}".format(PMU.isCharging()))
print("isDischarge:{0}".format(PMU.isDischarge()))
print("isStandby:{0}".format(PMU.isStandby()))
time.sleep(0.8)

View File

@@ -0,0 +1,184 @@
'''
@license 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.
@file AXP2101_Interrupt.py
@author Lewis He (lewishe@outlook.com)
@date 2022-10-20
'''
from AXP2101 import *
import time
SDA = None
SCL = None
I2CBUS = None
if implementation.name == 'micropython':
from machine import Pin, I2C
SDA = 21
SCL = 22
IRQ = 35
I2CBUS = I2C(scl=Pin(SCL), sda=Pin(SDA))
if implementation.name == 'circuitpython':
import digitalio
import board
import busio
SDA = board.IO42
SCL = board.IO41
IRQ = board.IO6
I2CBUS = busio.I2C(SCL, SDA)
irq = None
pmu_flag = False
def __callback(args):
global pmu_flag
pmu_flag = True
PMU = AXP2101(I2CBUS, addr=AXP2101_SLAVE_ADDRESS)
print('getID:%s' % hex(PMU.getChipID()))
PMU.disableIRQ(PMU.XPOWERS_AXP2101_ALL_IRQ)
# Clear all interrupt flags
PMU.clearIrqStatus()
PMU.printIntRegister()
PMU.enableIRQ(PMU.XPOWERS_AXP2101_PKEY_SHORT_IRQ |
PMU.XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ)
# Print AXP2101 interrupt control register
PMU.printIntRegister()
# PMU.enableIRQ(
# PMU.XPOWERS_AXP2101_BAT_INSERT_IRQ | PMU.XPOWERS_AXP2101_BAT_REMOVE_IRQ | # BATTERY
# PMU.XPOWERS_AXP2101_VBUS_INSERT_IRQ | PMU.XPOWERS_AXP2101_VBUS_REMOVE_IRQ | # VBUS
# PMU.XPOWERS_AXP2101_PKEY_SHORT_IRQ | PMU.XPOWERS_AXP2101_PKEY_LONG_IRQ | # POWER KEY
# PMU.XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | PMU.XPOWERS_AXP2101_BAT_CHG_START_IRQ # CHARGE
# )
PMU.enableIRQ(PMU.XPOWERS_AXP2101_BAT_NOR_UNDER_TEMP_IRQ)
# Print AXP2101 interrupt control register
PMU.printIntRegister()
PMU.enableIRQ(PMU.XPOWERS_AXP2101_PKEY_SHORT_IRQ |
PMU.XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ)
# Print AXP2101 interrupt control register
PMU.printIntRegister()
PMU.enableIRQ(PMU.XPOWERS_AXP2101_BAT_OVER_VOL_IRQ)
# Print AXP2101 interrupt control register
PMU.printIntRegister()
if implementation.name == 'micropython':
irq = Pin(IRQ, Pin.IN, Pin.PULL_UP)
irq.irq(trigger=Pin.IRQ_FALLING, handler=__callback)
if implementation.name == 'circuitpython':
irq = digitalio.DigitalInOut(IRQ)
irq.switch_to_input()
while True:
if implementation.name == 'circuitpython':
if irq.value == False:
pmu_flag = True
if pmu_flag:
pmu_flag = False
# Get PMU Interrupt Status Register
status = PMU.getIrqStatus()
print("STATUS => HEX:")
print(hex(status))
if PMU.isDropWarningLevel2Irq():
print("isDropWarningLevel2")
if PMU.isDropWarningLevel1Irq():
print("isDropWarningLevel1")
if PMU.isGaugeWdtTimeoutIrq():
print("isWdtTimeout")
if PMU.isBatChargerOverTemperatureIrq():
print("isBatChargeOverTemperature")
if PMU.isBatWorkOverTemperatureIrq():
print("isBatWorkOverTemperature")
if PMU.isBatWorkUnderTemperatureIrq():
print("isBatWorkUnderTemperature")
if PMU.isVbusInsertIrq():
print("isVbusInsert")
if PMU.isVbusRemoveIrq():
print("isVbusRemove")
if PMU.isBatInsertIrq():
print("isBatInsert")
if PMU.isBatRemoveIrq():
print("isBatRemove")
if PMU.isPekeyShortPressIrq():
print("isPekeyShortPress")
if PMU.isPekeyLongPressIrq():
print("isPekeyLongPress")
if PMU.isPekeyNegativeIrq():
print("isPekeyNegative")
if PMU.isPekeyPositiveIrq():
print("isPekeyPositive")
if PMU.isWdtExpireIrq():
print("isWdtExpire")
if PMU.isLdoOverCurrentIrq():
print("isLdoOverCurrentIrq")
if PMU.isBatfetOverCurrentIrq():
print("isBatfetOverCurrentIrq")
if PMU.isBatChargeDoneIrq():
print("isBatChargeDone")
if PMU.isBatChargeStartIrq():
print("isBatChargeStart")
if PMU.isBatDieOverTemperatureIrq():
print("isBatDieOverTemperature")
if PMU.isChargeOverTimeoutIrq():
print("isChargeOverTimeout")
if PMU.isBatOverVoltageIrq():
print("isBatOverVoltage")
# Clear PMU Interrupt Status Register
PMU.clearIrqStatus()
# Print AXP2101 interrupt control register
PMU.printIntRegister()
time.sleep(0.2)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,110 @@
'''
@license 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.
@file I2CInterface.py
@author Lewis He (lewishe@outlook.com)
@date 2022-10-20
'''
from sys import implementation
if implementation.name == 'micropython':
from machine import Pin, I2C
if implementation.name == 'circuitpython':
from adafruit_bus_device import i2c_device
class I2CInterface:
def __init__(self, i2c_bus: I2C, addr: int) -> None:
if implementation.name == 'micropython':
print('micropython')
self._bus = i2c_bus
if implementation.name == 'circuitpython':
print('circuitpython')
self._bus = i2c_device.I2CDevice(i2c_bus, addr)
self._address = addr
def _BV(self, bit) -> int:
return (1 << bit)
def _IS_BIT_SET(self, val, mask) -> bool:
return bool((((val) & (mask)) == (mask)))
def writeRegister(self, reg: int, val: int) -> None:
if implementation.name == 'micropython':
buf = bytearray(1)
buf[0] = val
self._bus.writeto_mem(
self._address, (reg & 0xFF), buf)
elif implementation.name == 'circuitpython':
buf = bytearray(2)
buf[0] = reg & 0xFF
buf[1] = val & 0xFF
with self._bus as i2c:
i2c.write(buf, start=0, end=2)
def readRegister(self, reg: int, length: int = 1) -> list:
if implementation.name == 'micropython':
buf = bytearray(length)
self._bus.readfrom_mem_into(
self._address, (reg & 0xFF), buf)
return list(buf)
elif implementation.name == 'circuitpython':
with self._bus as i2c:
i2c.write(bytes([reg & 0xFF]))
result = bytearray(length)
i2c.readinto(result)
return result
def getRegisterBit(self, reg, bit) -> bool:
val = self.readRegister(reg)[0]
return val & self._BV(bit)
def setRegisterBit(self, reg: int, bit: int):
val = self.readRegister(reg)[0]
self.writeRegister(reg, (val | (self._BV(bit))))
def clrRegisterBit(self, reg: int, bit: int):
val = self.readRegister(reg)[0]
self.writeRegister(reg, (val & (~self._BV(bit))))
def readRegisterH8L4(self, highReg, lowReg) -> int:
h8 = self.readRegister(highReg)[0]
l4 = self.readRegister(lowReg)[0]
return (h8 << 4) | (l4 & 0x0F)
def readRegisterH8L5(self, highReg, lowReg) -> int:
h8 = self.readRegister(highReg)[0]
l5 = self.readRegister(lowReg)[0]
return (h8 << 5) | (l5 & 0x1F)
def readRegisterH6L8(self, highReg, lowReg) -> int:
h6 = self.readRegister(highReg)[0]
l8 = self.readRegister(lowReg)[0]
return ((h6 & 0x3F) << 8) | l8
def readRegisterH5L8(self, highReg, lowReg) -> int:
h5 = self.readRegister(highReg)[0]
l8 = self.readRegister(lowReg)[0]
return ((h5 & 0x1F) << 8) | l8

71
XPowersLib/README.md Normal file
View File

@@ -0,0 +1,71 @@
```
__ __ _____ _ _ _
\ \ / / | __ \ | | (_) |
\ V /_____| |__) |____ _____ _ __ ___| | _| |__
> <______| ___/ _ \ \ /\ / / _ \ '__/ __| | | | '_ \
/ . \ | | | (_) \ V V / __/ | \__ \ |____| | |_) |
/_/ \_\ |_| \___/ \_/\_/ \___|_| |___/______|_|_.__/
```
[![Build esp-idf](https://github.com/lewisxhe/XPowersLib/actions/workflows/esp-idf.yml/badge.svg)](https://github.com/lewisxhe/XPowersLib/actions/workflows/esp-idf.yml)
[![Build PlatformIO](https://github.com/lewisxhe/XPowersLib/actions/workflows/pio.yml/badge.svg)](https://github.com/lewisxhe/XPowersLib/actions/workflows/pio.yml)
[![Build Arduino](https://github.com/lewisxhe/XPowersLib/actions/workflows/arduino_ci.yml/badge.svg)](https://github.com/lewisxhe/XPowersLib/actions/workflows/arduino_ci.yml)
[![arduino-library-badge](https://www.ardu-badge.com/badge/XPowersLib.svg?)](https://www.ardu-badge.com/XPowersLib)
[![LICENSE](https://img.shields.io/github/license/lewisxhe/XPowersLib)](https://github.com/lewisxhe/XPowersLib/blob/master/LICENSE)
[![ISSUES](https://img.shields.io/github/issues/lewisxhe/XPowersLib)](https://github.com/lewisxhe/XPowersLib/issues)
[![FROK](https://img.shields.io/github/forks/lewisxhe/XPowersLib)](https://github.com/lewisxhe/XPowersLib/graphs/contributors)
[![STAR](https://img.shields.io/github/stars/lewisxhe/XPowersLib)](https://github.com/lewisxhe/XPowersLib/stargazers)
[![releases](https://img.shields.io/github/release/lewisxhe/XPowersLib)](https://github.com/lewisxhe/XPowersLib/releases)
```
🎉 LilyGo invests time and resources to provide this open source code, please support LilyGo
and open source hardware by purchasing products from LilyGo!
Written by Lewis He for LilyGo. MIT license, all text above must be included in
any redistribution
```
# ❗️❗️❗️ 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
```
✨ Library specially written for XPowers, supporting **CircuitPython**, **Micropython**, **Arduino**, **ESP-IDF**
✨ Through esp32,esp32s3 verification,other platforms have not been tested. Due to the many functions of the chip,it cannot be verified one by one.
# Chip Resource List
| CHIP | AXP192 | AXP202 | AXP2101 | Remarks |
| ---------- | ----------------- | ----------------- | ----------------------------------------------------------- | ---------------- |
| DC1 | 0.7V-3.5V /1.2A | X | 1.5-3.4V /2A | |
| DC2 | 0.7-2.275V /1.6A | 0.7-2.275V /1.6A | 0.5-1.2V,1.22-1.54V /2A | |
| DC3 | 0.7-3.5V /0.7A | 0.7-3.5V /1.2A | 0.5-1.2V,1.22-1.54V,1.6-3.4V /2A | |
| DC4 | x | x | 0.5-1.2V,1.22-1.84V /1.5A | |
| DC5 | x | x | 1.2V,1.4-3.7V /1A | |
| LDO1(VRTC) | 3.3V /30mA | 3.3V /30mA | 1.8V /30mA | |
| LDO2 | 1.8V-3.3V /200mA | 1.8V-3.3V /200mA | x | |
| LDO3 | 1.8-3.3V /200mA | 0.7-3.5V /200mA | x | |
| LDO4 | X | 1.8V-3.3V /200mA | x | |
| LDO5/IO0 | 1.8-3.3V /50mA | 1.8-3.3V /50mA | x | |
| ALDO1 | x | x | 0.5-3.5V /300mA | |
| ALDO2 | x | x | 0.5-3.5V /300mA | |
| ALDO3 | x | x | 0.5-3.5V /300mA | |
| ALDO4 | x | x | 0.5-3.5V /300mA | |
| BLDO1 | x | x | 0.5-3.5V /300mA | |
| BLDO2 | x | x | 0.5-3.5V /300mA | |
| DLDO1 | x | x | (LDO Mode)0.5-3.3V/ 0.5-1.4V/300mA,(SW Mode)Switch Function | Dependent on DC1 |
| DLDO2 | x | x | (LDO Mode)0.5-3.3V/ 0.5-1.4V/300mA,(SW Mode)Switch Function | Dependent on DC4 |
| CPUSLDO | x | x | 0.5-1.4V /30mA | Dependent on DC4 |
# AXP2101 Notes:
* Whether DLDO1/DLDO2/RTCLDO2/GPIO1 can be used depends on the chip. It is not available by default. RTCLDO1 has a default voltage, which is generally 1.8V by default. The voltage value cannot be changed or turned off through the register.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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);
}

View 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);
}

View 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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View 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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View 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;
}
}

View File

@@ -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;
}
}

View 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)

View 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

View 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
```

View File

@@ -0,0 +1,5 @@
idf_component_register(SRCS "main.cpp"
"port_axp192.cpp"
"port_axp2101.cpp"
"port_i2c.cpp"
INCLUDE_DIRS ".")

View 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

View File

@@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View 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();
}
}
}

View 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*/

View 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*/

View 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 *)&regAddr,
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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
#

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View 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)

View 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;
}

View 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;
}

1166
XPowersLib/keywords.txt Normal file

File diff suppressed because it is too large Load Diff

145
XPowersLib/library.json Normal file
View File

@@ -0,0 +1,145 @@
{
"name": "XPowersLib",
"version": "0.2.8",
"description": "Arduino, CircuitPython, MicroPython, esp-idf and other frameworks power management series library",
"keywords": "AXP192,AXP202,AXP2101,SY6970,BQ25896,HUSB238",
"authors": [
{
"name": "LewisHe",
"url": "https://github.com/lewisxhe",
"maintainer": true
}
],
"repository": {
"type": "git",
"url": "https://github.com/lewisxhe/XPowersLib.git"
},
"homepage": "https://github.com/lewisxhe/XPowersLib",
"export": {
"include": [
"LICENSE",
"library.json",
"library.properties",
"README.md",
"keywords.txt",
"src/*",
"examples/*"
]
},
"examples": [
{
"name": "AXP192_Example",
"base": "examples/AXP192_Example",
"files": ["AXP192_Example.ino"]
},
{
"name": "AXP202_Example",
"base": "examples/AXP202_Example",
"files": ["AXP202_Example.ino"]
},
{
"name": "AXP2101_Charge_Example",
"base": "examples/AXP2101_Charge_Example",
"files": ["AXP2101_Charge_Example.ino"]
},
{
"name": "AXP2101_Example",
"base": "examples/AXP2101_Example",
"files": ["AXP2101_Example.ino"]
},
{
"name": "AXP2101_InterruptExample",
"base": "examples/AXP2101_InterruptExample",
"files": ["AXP2101_InterruptExample.ino"]
},
{
"name": "AXP2101_Voltage_Example",
"base": "examples/AXP2101_Voltage_Example",
"files": ["AXP2101_Voltage_Example.ino"]
},
{
"name": "AXP2101_ADC_Example",
"base": "examples/AXP2101_ADC_Example",
"files": ["AXP2101_ADC_Example.ino"]
},
{
"name": "AXP2101_Sleep_Example",
"base": "examples/AXP2101_Sleep_Example",
"files": ["AXP2101_Sleep_Example.ino"]
},
{
"name": "AXP2101_Charge_Current_Setting",
"base": "examples/AXP2101_Charge_Current_Setting",
"files": ["AXP2101_Charge_Current_Setting.ino"]
},
{
"name": "AXP2101_LowBatteryWarningExample",
"base": "examples/AXP2101_LowBatteryWarningExample",
"files": ["AXP2101_LowBatteryWarningExample.ino"]
},
{
"name": "ESP_IDF_Example",
"base": "examples/ESP_IDF_Example/main",
"files": [
"main.cpp",
"port_axp192.cpp",
"port_axp2101.cpp",
"port_i2c.cpp"
]
},
{
"name": "XPowersLibInterface_Example",
"base": "examples/XPowersLibInterface_Example",
"files": ["XPowersLibInterface_Example.ino"]
},
{
"name": "SY6970_Example",
"base": "examples/SY6970_Example",
"files": ["SY6970_Example.ino"]
},
{
"name": "SY6970_Watchdog_Example",
"base": "examples/SY6970_Watchdog_Example",
"files": ["SY6970_Watchdog_Example.ino"]
},
{
"name": "SY6970_Shutdown_Example",
"base": "examples/SY6970_Shutdown_Example",
"files": ["SY6970_Shutdown_Example.ino"]
},
{
"name": "BQ25896_Example",
"base": "examples/BQ25896_Example",
"files": ["BQ25896_Example.ino"]
},
{
"name": "BQ25896_Shutdown_Example",
"base": "examples/BQ25896_Shutdown_Example",
"files": ["BQ25896_Shutdown_Example.ino"]
},
{
"name": "FastCharging_BleUartDebug",
"base": "examples/FastCharging_BleUartDebug",
"files": ["FastCharging_BleUartDebug.ino"]
},
{
"name": "PowerDeliveryHUSB238_BleUart",
"base": "examples/PowerDeliveryHUSB238_BleUart",
"files": ["PowerDeliveryHUSB238_BleUart.ino"]
},
{
"name": "PowerDeliveryHUSB238_Example",
"base": "examples/PowerDeliveryHUSB238_Example",
"files": ["PowerDeliveryHUSB238_Example.ino"]
},
{
"name": "XPowersLibInterface_Linux",
"base": "examples/XPowersLibInterface_Linux",
"files": ["main.cpp"]
}
],
"frameworks": ["arduino", "espidf"],
"platforms": "ststm32,espressif32,nordicnrf52",
"headers": "XPowersLib.h",
"license": "MIT"
}

View File

@@ -0,0 +1,9 @@
name=XPowersLib
version=0.2.8
author=Lewis He
maintainer=Lewis He <lewishe@outlook.com>
sentence=Arduino, CircuitPython, MicroPython, esp-idf and other frameworks power management series library
paragraph=Support AXP192,AXP202,AXP2101,SY6970,BQ25896,HUSB238 Chip
category=Communication
url=https://github.com/lewisxhe/XPowersLib
architectures=*

95
XPowersLib/platformio.ini Normal file
View File

@@ -0,0 +1,95 @@
;PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
; src_dir = examples/AXP192_Example
; src_dir = examples/AXP202_Example
; src_dir = examples/AXP2101_Charge_Example
; src_dir = examples/AXP2101_Charge_Current_Setting
; src_dir = examples/AXP2101_Example
; src_dir = examples/AXP2101_InterruptExample
; src_dir = examples/AXP2101_Voltage_Example
; src_dir = examples/AXP2101_ADC_Example
; src_dir = examples/AXP2101_Sleep_Example
; src_dir = examples/XPowersLibInterface_Example
; src_dir = examples/SY6970_Example
; src_dir = examples/SY6970_Watchdog_Example
; src_dir = examples/SY6970_Shutdown_Example
; src_dir = examples/BQ25896_Example
; src_dir = examples/BQ25896_Shutdown_Example
; src_dir = examples/PowerDeliveryHUSB238_Example
; src_dir = examples/PowerDeliveryHUSB238_BleUart
src_dir = examples/FastCharging_BleUartDebug
; default_envs = esp32s3
; default_envs = esp32dev
; default_envs = nucleo_f411re
default_envs = nrf52840
[env]
lib_extra_dirs = .
upload_speed = 921600
monitor_speed = 115200
build_flags =
; -DCONFIG_PMU_SDA=1
; -DCONFIG_PMU_SCL=2
; T-EPD47 S3
; -DCONFIG_PMU_SDA=6
; -DCONFIG_PMU_SCL=5
; -DCONFIG_PMU_IRQ=15
-DCONFIG_PMU_SDA=33
-DCONFIG_PMU_SCL=35
-DCONFIG_PMU_IRQ=15
; -UARDUINO_USB_CDC_ON_BOOT
; -DARDUINO_USB_CDC_ON_BOOT=1
-Wtype-limits
-Wall
-Werror
[env:esp32dev]
platform = espressif32
framework = arduino
board = esp32dev
[env:esp32s3]
platform = espressif32
framework = arduino
board = esp32-s3-devkitc-1
[env:nucleo_f411re]
platform = ststm32
framework = arduino
board = nucleo_f411re
upload_protocol = stlink
[env:nrf52840]
platform = nordicnrf52
board = nrf52840_dk_adafruit
framework = arduino
upload_protocol = nrfutil
monitor_speed = 115200
; upload_protocol = nrfjprog
; upload_protocol = jlink
build_flags =
${env.build_flags}
; -DCFG_DEBUG=1
; -DCFG_LOGGER=0
; -DCFG_SYSVIEW=0
lib_deps =
Adafruit TinyUSB Library
Wire
SPI

View File

@@ -0,0 +1,171 @@
/**
*
* @license 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.
*
* @file PowerDeliveryHUSB238.tpp
* @author Lewis He (lewishe@outlook.com)
* @date 2024-07-24
*
*/
#if defined(ARDUINO)
#include <Arduino.h>
#else
#include <math.h>
#endif /*ARDUINO*/
#include "XPowersCommon.tpp"
#include "REG/HUSB238Constants.h"
class PowerDeliveryHUSB238 :
public XPowersCommon<PowerDeliveryHUSB238>
{
friend class XPowersCommon<PowerDeliveryHUSB238>;
public:
enum PD_Status {
NO_RESPONSE,
SUCCESS,
INVALID_CMD,
NOT_SUPPORT,
TRANSACTION_FAIL
};
enum PD_Voltage {
PD_5V = 1,
PD_9V,
PD_12V,
PD_15V,
PD_18V,
PD_20V
};
#if defined(ARDUINO)
PowerDeliveryHUSB238(TwoWire &w, int sda = SDA, int scl = SCL, uint8_t addr = HUSB238_SLAVE_ADDRESS)
{
__wire = &w;
__sda = sda;
__scl = scl;
__addr = addr;
}
#endif
PowerDeliveryHUSB238(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback)
{
thisReadRegCallback = readRegCallback;
thisWriteRegCallback = writeRegCallback;
__addr = addr;
}
PowerDeliveryHUSB238()
{
#if defined(ARDUINO)
__wire = &Wire;
__sda = SDA;
__scl = SCL;
#endif
__addr = HUSB238_SLAVE_ADDRESS;
}
~PowerDeliveryHUSB238()
{
log_i("~PowerDeliveryHUSB238");
deinit();
}
#if defined(ARDUINO)
bool init(TwoWire &w, int sda = SDA, int scl = SCL, uint8_t addr = HUSB238_SLAVE_ADDRESS)
{
__wire = &w;
__sda = sda;
__scl = scl;
__addr = addr;
return begin();
}
#endif
void deinit()
{
end();
}
uint8_t getPdVoltage()
{
int val = readRegister(HUSB238_PD_STATUS0);
if (val == -1)return 0;
val &= 0xF0;
val >>= 4;
return pd_voltage_list[val];
}
float getPdCurrent()
{
int val = readRegister(HUSB238_PD_STATUS0);
if (val == -1)return 0;
val &= 0x0F;
return pd_current_list[val];
}
void setPdVoltage(PD_Voltage vol)
{
writeRegister(HUSB238_SRC_PDO, vol);
writeRegister(HUSB238_GO_COMMAND, 0x01);
}
void resetPdVoltage()
{
writeRegister(HUSB238_GO_COMMAND, 0x10);
}
bool attach()
{
return getRegisterBit(HUSB238_PD_STATUS1, 6);
}
PD_Status status()
{
int val = readRegister(HUSB238_PD_STATUS1);
if (val == -1)return NO_RESPONSE;
val >>= 3;
val &= 0x03;
return static_cast<PD_Status>(val);
}
private:
const uint8_t pd_voltage_list[7] = {0, 5, 9, 12, 15, 18, 20};
const float pd_current_list[16] = {
0.5, 0.7, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
2.75, 3, 3.25, 3.5, 4, 4.5, 5
};
bool initImpl()
{
return readRegister(HUSB238_PD_STATUS0) != -1;
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,994 @@
/**
*
* @license 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.
*
* @file PowersSY6970.tpp
* @author Lewis He (lewishe@outlook.com)
* @date 2023-07-20
*
*/
#if defined(ARDUINO)
#include <Arduino.h>
#else
#include <math.h>
#endif /*ARDUINO*/
#include "XPowersCommon.tpp"
#include "REG/GeneralPPMConstants.h"
#include "REG/SY6970Constants.h"
class PowersSY6970 :
public XPowersCommon<PowersSY6970>
{
friend class XPowersCommon<PowersSY6970>;
public:
enum BusStatus {
BUS_STATE_NOINPUT,
BUS_STATE_USB_SDP,
BUS_STATE_USB_CDP,
BUS_STATE_USB_DCP,
BUS_STATE_HVDCP,
BUS_STATE_ADAPTER,
BUS_STATE_NO_STANDARD_ADAPTER,
BUS_STATE_OTG
} ;
enum ChargeStatus {
CHARGE_STATE_NO_CHARGE,
CHARGE_STATE_PRE_CHARGE,
CHARGE_STATE_FAST_CHARGE,
CHARGE_STATE_DONE,
CHARGE_STATE_UNKOWN,
} ;
enum NTCStatus {
BUCK_NTC_NORMAL = 0,
BUCK_NTC_WARM = 2,
BUCK_NTC_COOL = 3,
BUCK_NTC_COLD = 5,
BUCK_NTC_HOT = 6,
};
enum BoostNTCStatus {
BOOST_NTC_NORMAL = 0,
BOOST_NTC_COLD = 5,
BOOST_NTC_HOT = 6,
};
enum Timeout {
TIMER_OUT_40SEC, //40 Second
TIMER_OUT_80SEC, //80 Second
TIMER_OUT_160SEC, //160 Second
} ;
enum MeasureMode {
ONE_SHORT,
CONTINUOUS,
};
enum BoostFreq {
BOOST_FREQ_1500KHZ,
BOOST_FREQ_500KHZ,
};
enum RequestRange {
REQUEST_9V,
REQUEST_12V,
};
enum FastChargeTimer {
FAST_CHARGE_TIMER_5H,
FAST_CHARGE_TIMER_8H,
FAST_CHARGE_TIMER_12H,
FAST_CHARGE_TIMER_20H,
};
enum BoostCurrentLimit {
BOOST_CUR_LIMIT_500MA,
BOOST_CUR_LIMIT_750MA,
BOOST_CUR_LIMIT_1200MA,
BOOST_CUR_LIMIT_1400MA,
BOOST_CUR_LIMIT_1650MA,
BOOST_CUR_LIMIT_1875MA,
BOOST_CUR_LIMIT_2150MA,
BOOST_CUR_LIMIT_2450MA,
} ;
#if defined(ARDUINO)
PowersSY6970(TwoWire &w, int sda = SDA, int scl = SCL, uint8_t addr = SY6970_SLAVE_ADDRESS)
{
__wire = &w;
__sda = sda;
__scl = scl;
__addr = addr;
}
#endif
PowersSY6970(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback)
{
thisReadRegCallback = readRegCallback;
thisWriteRegCallback = writeRegCallback;
__addr = addr;
}
PowersSY6970()
{
#if defined(ARDUINO)
__wire = &Wire;
__sda = SDA;
__scl = SCL;
#endif
__addr = SY6970_SLAVE_ADDRESS;
}
~PowersSY6970()
{
log_i("~PowersSY6970");
deinit();
}
#if defined(ARDUINO)
bool init(TwoWire &w, int sda = SDA, int scl = SCL, uint8_t addr = SY6970_SLAVE_ADDRESS)
{
__wire = &w;
__sda = sda;
__scl = scl;
__addr = addr;
__irq_mask = 0;
return begin();
}
#endif
const char *getChipName()
{
return getChipID() == SY6970_DEV_REV ? "SY6970" : "Unkown";
}
uint8_t getChipID()
{
int res = readRegister(POWERS_PPM_REG_14H);
return (res & 0x03);
}
void resetDefault()
{
setRegisterBit(POWERS_PPM_REG_14H, 7);
}
bool init()
{
return begin();
}
void deinit()
{
end();
}
///REG0B
bool isVbusIn()
{
return getBusStatus() != BUS_STATE_NOINPUT;
}
bool isOTG()
{
return getBusStatus() == BUS_STATE_OTG;
}
bool isCharging(void)
{
return chargeStatus() != CHARGE_STATE_NO_CHARGE;
}
bool isChargeDone()
{
return chargeStatus() != CHARGE_STATE_DONE;
}
bool isBatteryConnect(void) __attribute__((error("Not implemented")))
{
//TODO:
return false;
}
bool isPowerGood()
{
return getRegisterBit(POWERS_PPM_REG_0BH, 2);
}
bool isEnableCharge()
{
return getRegisterBit(POWERS_PPM_REG_03H, 4);
}
void disableCharge()
{
__user_disable_charge = true;
clrRegisterBit(POWERS_PPM_REG_03H, 4);
}
void enableCharge()
{
__user_disable_charge = false;
setRegisterBit(POWERS_PPM_REG_03H, 4);
}
bool isEnableOTG()
{
return getRegisterBit(POWERS_PPM_REG_03H, 5);
}
void disableOTG()
{
clrRegisterBit(POWERS_PPM_REG_03H, 5);
/*
* After turning on the OTG function, the charging function will
* be automatically disabled. If the user does not disable the charging
* function, the charging function will be automatically enabled after
* turning off the OTG output.
* */
if (!__user_disable_charge) {
setRegisterBit(POWERS_PPM_REG_03H, 4);
}
}
bool enableOTG()
{
if (isVbusIn())
return false;
return setRegisterBit(POWERS_PPM_REG_03H, 5);
}
void feedWatchdog()
{
setRegisterBit(POWERS_PPM_REG_03H, 6);
}
bool setSysPowerDownVoltage(uint16_t millivolt)
{
if (millivolt % POWERS_SY6970_SYS_VOL_STEPS) {
log_e("Mistake ! The steps is must %u mV", POWERS_SY6970_SYS_VOL_STEPS);
return false;
}
if (millivolt < POWERS_SY6970_SYS_VOFF_VOL_MIN) {
log_e("Mistake ! SYS minimum output voltage is %umV", POWERS_SY6970_SYS_VOFF_VOL_MIN);
return false;
} else if (millivolt > POWERS_SY6970_SYS_VOFF_VOL_MAX) {
log_e("Mistake ! SYS maximum output voltage is %umV", POWERS_SY6970_SYS_VOFF_VOL_MAX);
return false;
}
int val = readRegister(POWERS_PPM_REG_03H);
if (val == -1)return false;
val &= 0xF1;
val |= (millivolt - POWERS_SY6970_SYS_VOFF_VOL_MIN) / POWERS_SY6970_SYS_VOL_STEPS;
val <<= 1;
return 0 == writeRegister(POWERS_PPM_REG_03H, val);
}
uint16_t getSysPowerDownVoltage()
{
int val = readRegister(POWERS_PPM_REG_03H);
if (val == -1)return 0;
val &= 0x0E;
val >>= 1;
return (val * POWERS_SY6970_SYS_VOL_STEPS) + POWERS_SY6970_SYS_VOFF_VOL_MIN;
}
// Charging Termination Enable
void enableChargingTermination()
{
setRegisterBit(POWERS_PPM_REG_07H, 7);
}
// Charging Termination Enable
void disableChargingTermination()
{
clrRegisterBit(POWERS_PPM_REG_07H, 7);
}
// Charging Termination Enable
bool isEnableChargingTermination()
{
return getRegisterBit(POWERS_PPM_REG_07H, 7);
}
// disableStatPin
void disableStatLed()
{
setRegisterBit(POWERS_PPM_REG_07H, 6);
}
void enableStatLed()
{
clrRegisterBit(POWERS_PPM_REG_07H, 6);
}
bool isEnableStatLed()
{
return getRegisterBit(POWERS_PPM_REG_07H, 6) == false;
}
void disableWatchdog()
{
int regVal = readRegister(POWERS_PPM_REG_07H);
regVal &= 0xCF;
writeRegister(POWERS_PPM_REG_07H, regVal);
}
void enableWatchdog(enum Timeout val)
{
int regVal = readRegister(POWERS_PPM_REG_07H);
regVal &= 0xCF;
switch (val) {
case TIMER_OUT_40SEC:
writeRegister(POWERS_PPM_REG_07H, regVal | 0x10);
break;
case TIMER_OUT_80SEC:
writeRegister(POWERS_PPM_REG_07H, regVal | 0x20);
break;
case TIMER_OUT_160SEC:
writeRegister(POWERS_PPM_REG_07H, regVal | 0x30);
break;
default:
break;
}
}
void disableChargingSafetyTimer()
{
clrRegisterBit(POWERS_PPM_REG_07H, 3);
}
void enableChargingSafetyTimer()
{
setRegisterBit(POWERS_PPM_REG_07H, 3);
}
bool isEnableChargingSafetyTimer()
{
return getRegisterBit(POWERS_PPM_REG_07H, 3);
}
void setFastChargeTimer(FastChargeTimer timer)
{
int val;
switch (timer) {
case FAST_CHARGE_TIMER_5H:
case FAST_CHARGE_TIMER_8H:
case FAST_CHARGE_TIMER_12H:
case FAST_CHARGE_TIMER_20H:
val = readRegister(POWERS_PPM_REG_07H);
if (val == -1)
return;
val &= 0xF1;
val |= (timer << 1);
writeRegister(POWERS_PPM_REG_07H, val);
break;
default:
break;
}
}
FastChargeTimer getFastChargeTimer()
{
int val = readRegister(POWERS_PPM_REG_07H);
return static_cast<FastChargeTimer>((val & 0x0E) >> 1);
}
// Return Battery Load status
bool isEnableBatLoad()
{
return getRegisterBit(POWERS_PPM_REG_03H, 7);
}
// Battery Load (10mA) Disable
void disableBatLoad()
{
clrRegisterBit(POWERS_PPM_REG_03H, 7);
}
// Battery Load (10mA) Enable
void enableBatLoad()
{
setRegisterBit(POWERS_PPM_REG_03H, 7);
}
BusStatus getBusStatus()
{
int val = readRegister(POWERS_PPM_REG_0BH);
return (BusStatus)((val >> 5) & 0x07);
}
const char *getBusStatusString()
{
BusStatus status = getBusStatus();
switch (status) {
case BUS_STATE_NOINPUT:
return "No input";
case BUS_STATE_USB_SDP:
return "USB Host SDP";
case BUS_STATE_USB_CDP:
return "USB CDP";
case BUS_STATE_USB_DCP:
return "USB DCP";
case BUS_STATE_HVDCP:
return "HVDCP";
case BUS_STATE_ADAPTER:
case BUS_STATE_NO_STANDARD_ADAPTER:
return "Adapter";
case BUS_STATE_OTG:
return "OTG";
default:
return "Unknown";
}
}
ChargeStatus chargeStatus()
{
int val = readRegister(POWERS_PPM_REG_0BH);
if (val == -1)return CHARGE_STATE_UNKOWN;
return static_cast<ChargeStatus>((val >> 3) & 0x03);
}
const char *getChargeStatusString()
{
ChargeStatus status = chargeStatus();
switch (status) {
case CHARGE_STATE_NO_CHARGE:
return "Not Charging";
case CHARGE_STATE_PRE_CHARGE:
return "Pre-charge";
case CHARGE_STATE_FAST_CHARGE:
return "Fast Charging";
case CHARGE_STATE_DONE:
return "Charge Termination Done";
default:
return "Unknown";
}
}
uint8_t getNTCStatus()
{
return (__irq_mask & 0x07);
}
const char *getNTCStatusString()
{
uint8_t status = getNTCStatus();
if (isOTG()) {
// Boost mode
switch (status) {
case BOOST_NTC_NORMAL:
return "Boost mode NTC normal";
case BOOST_NTC_COLD:
return "Boost mode NTC cold";
case BOOST_NTC_HOT:
return "Boost mode NTC hot";
default:
break;
}
} else {
// Buck mode
switch (status) {
case BUCK_NTC_NORMAL:
return "Buck mode NTC normal";
case BUCK_NTC_WARM:
return "Buck mode NTC warm";
case BUCK_NTC_COOL:
case BUCK_NTC_COLD:
return "Buck mode NTC cold";
case BUCK_NTC_HOT:
return "Buck mode NTC hot";
default:
break;
}
}
return "Unknown";
}
bool enableADCMeasure() __attribute__((deprecated("The enableADCMeasure method will be replaced by enableMeasure in the future. Please update it to enableMeasure.")))
{
return enableMeasure();
}
bool enableMeasure(MeasureMode mode = CONTINUOUS)
{
int val = readRegister(POWERS_PPM_REG_02H);
switch (mode) {
case CONTINUOUS:
val |= _BV(6);
break;
case ONE_SHORT:
val &= (~_BV(6));
default:
break;
}
val |= _BV(7);
return writeRegister(POWERS_PPM_REG_02H, val) != -1;
}
bool disableADCMeasure()
{
int val = readRegister(POWERS_PPM_REG_02H);
if (val == -1) {
return false;
}
val &= (~_BV(7));
return writeRegister(POWERS_PPM_REG_02H, val) != 1;
}
bool setBoostFreq(BoostFreq freq)
{
switch (freq) {
case BOOST_FREQ_500KHZ:
return setRegisterBit(POWERS_PPM_REG_02H, 5);
case BOOST_FREQ_1500KHZ:
return clrRegisterBit(POWERS_PPM_REG_02H, 5);
default:
break;
}
return false;
}
BoostFreq getBoostFreq()
{
return getRegisterBit(POWERS_PPM_REG_02H, 5) ? BOOST_FREQ_500KHZ : BOOST_FREQ_1500KHZ;
}
void enableInputCurrentLimit()
{
setRegisterBit(POWERS_PPM_REG_02H, 4);
}
void disableInputCurrentLimit()
{
clrRegisterBit(POWERS_PPM_REG_02H, 4);
}
void enableHVDCP()
{
setRegisterBit(POWERS_PPM_REG_02H, 3);
}
void disableHVDCP()
{
clrRegisterBit(POWERS_PPM_REG_02H, 3);
}
bool isEnableHVDCP()
{
return getRegisterBit(POWERS_PPM_REG_02H, 3);
}
void setHighVoltageRequestedRange(RequestRange range)
{
switch (range) {
case REQUEST_9V:
clrRegisterBit(POWERS_PPM_REG_02H, 2);
break;
case REQUEST_12V:
setRegisterBit(POWERS_PPM_REG_02H, 2);
break;
default:
break;
}
}
RequestRange getHighVoltageRequestedRange()
{
return getRegisterBit(POWERS_PPM_REG_02H, 2) ? REQUEST_12V : REQUEST_9V;
}
// Enable Force DP/DM detection
void enableDetectionDPDM()
{
setRegisterBit(POWERS_PPM_REG_02H, 1);
}
// Disable Force DP/DM detection
void disableDetectionDPDM()
{
clrRegisterBit(POWERS_PPM_REG_02H, 1);
}
// Get Force DP/DM detection
bool isEnableDetectionDPDM()
{
return getRegisterBit(POWERS_PPM_REG_02H, 1);
}
// Enable DPDM detection when BUS is plugged-in.
void enableAutoDetectionDPDM()
{
setRegisterBit(POWERS_PPM_REG_02H, 0);
}
// Disable DPDM detection when BUS is plugged-in.
void disableAutoDetectionDPDM()
{
clrRegisterBit(POWERS_PPM_REG_02H, 0);
}
// Get DPDM detection when BUS is plugged-in.
bool isEnableAutoDetectionDPDM()
{
return getRegisterBit(POWERS_PPM_REG_02H, 0);
}
bool setInputCurrentLimit(uint16_t milliampere)
{
if (milliampere % POWERS_SY6970_IN_CURRENT_STEP) {
log_e("Mistake ! The steps is must %u mA", POWERS_SY6970_IN_CURRENT_STEP);
return false;
}
if (milliampere < POWERS_SY6970_IN_CURRENT_MIN) {
milliampere = POWERS_SY6970_IN_CURRENT_MIN;
}
if (milliampere > POWERS_SY6970_IN_CURRENT_MAX) {
milliampere = POWERS_SY6970_IN_CURRENT_MAX;
}
int val = readRegister(POWERS_PPM_REG_00H);
if (val == -1)
return false;
val &= 0xC0;
milliampere = ((milliampere - POWERS_SY6970_IN_CURRENT_MIN) / POWERS_SY6970_IN_CURRENT_STEP);
val |= milliampere;
return writeRegister(POWERS_PPM_REG_00H, val) != -1;
}
uint32_t getInputCurrentLimit()
{
int val = readRegister(POWERS_PPM_REG_00H);
if (val == -1)
return false;
val &= 0x3F;
return (val * POWERS_SY6970_IN_CURRENT_STEP) + POWERS_SY6970_IN_CURRENT_MIN;
}
// USB input path is disabled and can only be reset by disconnecting
// the power supply, otherwise the power cannot be turned on
void enterHizMode()
{
setRegisterBit(POWERS_PPM_REG_00H, 7);
}
void exitHizMode()
{
clrRegisterBit(POWERS_PPM_REG_00H, 7);
}
bool isHizMode()
{
return getRegisterBit(POWERS_PPM_REG_00H, 7);
}
void enableCurrentLimitPin()
{
setRegisterBit(POWERS_PPM_REG_00H, 6);
}
void disableCurrentLimitPin()
{
clrRegisterBit(POWERS_PPM_REG_00H, 6);
}
bool isEnableCurrentLimitPin()
{
return getRegisterBit(POWERS_PPM_REG_00H, 6);
}
uint16_t getVbusVoltage()
{
if (!isVbusIn()) {
return 0;
}
int val = readRegister(POWERS_PPM_REG_11H);
return (POWERS_SY6970_VBUS_MASK_VAL(val) * POWERS_SY6970_VBUS_VOL_STEP) + POWERS_SY6970_VBUS_BASE_VAL;
}
uint16_t getBattVoltage()
{
int val = readRegister(POWERS_PPM_REG_0EH);
val = POWERS_SY6970_VBAT_MASK_VAL(val);
if (val == 0)return 0;
return (val * POWERS_SY6970_VBAT_VOL_STEP) + POWERS_SY6970_VBAT_BASE_VAL;
}
uint16_t getSystemVoltage()
{
int val = readRegister(POWERS_PPM_REG_0FH);
return (POWERS_SY6970_VSYS_MASK_VAL(val) * POWERS_SY6970_VSYS_VOL_STEP) + POWERS_SY6970_VSYS_BASE_VAL;
}
float getNTCPercentage()
{
int val = readRegister(POWERS_PPM_REG_10H);
return (POWERS_SY6970_NTC_MASK_VAL(val) * POWERS_SY6970_NTC_VOL_STEP) + POWERS_SY6970_NTC_BASE_VAL;
}
uint16_t getChargeCurrent()
{
ChargeStatus status = chargeStatus();
if (status == CHARGE_STATE_NO_CHARGE) {
return 0;
}
//* If the charger is disconnected, the value in the register
//* will remain the last value and will not be updated to 0.
int val = readRegister(POWERS_PPM_REG_12H);
if (val == 0)return 0;
val = (val & 0x7F);
return (val * POWERS_SY6970_CHG_STEP_VAL) ;
}
// Range: 64mA ~ 1024 mA ,step:64mA
bool setPrechargeCurr(uint16_t milliampere)
{
if (milliampere % POWERS_SY6970_PRE_CHG_CUR_STEP) {
log_e("Mistake ! The steps is must %u mA", POWERS_SY6970_PRE_CHG_CUR_STEP);
return false;
}
if (milliampere < POWERS_SY6970_PRE_CHG_CURRENT_MIN) {
milliampere = POWERS_SY6970_PRE_CHG_CURRENT_MIN;
}
if (milliampere > POWERS_SY6970_PRE_CHG_CURRENT_MAX) {
milliampere = POWERS_SY6970_PRE_CHG_CURRENT_MAX;
}
int val = readRegister(POWERS_PPM_REG_05H);
val &= 0x0F;
milliampere = ((milliampere - POWERS_SY6970_PRE_CHG_CUR_BASE) / POWERS_SY6970_PRE_CHG_CUR_STEP);
val |= milliampere << 4;
return writeRegister(POWERS_PPM_REG_05H, val) != -1;
}
uint16_t getPrechargeCurr(void)
{
int val = readRegister(POWERS_PPM_REG_05H);
val &= 0xF0;
val >>= 4;
return POWERS_SY6970_PRE_CHG_CUR_STEP + (val * POWERS_SY6970_PRE_CHG_CUR_STEP);
}
uint16_t getChargerConstantCurr()
{
int val = readRegister(POWERS_PPM_REG_04H);
val &= 0x7F;
return val * POWERS_SY6970_FAST_CHG_CUR_STEP;
}
/**
* @brief setChargerConstantCurr
* @note
* @param milliampere: SY6970 Range:0~5056 mA / step:64mA
* @retval true : success false : failed
*/
bool setChargerConstantCurr(uint16_t milliampere)
{
if (milliampere % POWERS_SY6970_FAST_CHG_CUR_STEP) {
log_e("Mistake ! The steps is must %u mA", POWERS_SY6970_FAST_CHG_CUR_STEP);
return false;
}
if (milliampere > POWERS_SY6970_FAST_CHG_CURRENT_MAX) {
milliampere = POWERS_SY6970_FAST_CHG_CURRENT_MAX;
}
int val = readRegister(POWERS_PPM_REG_04H);
val &= 0x80;
val |= (milliampere / POWERS_SY6970_FAST_CHG_CUR_STEP);
return writeRegister(POWERS_PPM_REG_04H, val) != -1;
}
uint16_t getChargeTargetVoltage()
{
int val = readRegister(POWERS_PPM_REG_06H);
val = (val & 0xFC) >> 2;
if (val > 0x30) {
return POWERS_SY6970_FAST_CHG_VOL_MAX;
}
return val * POWERS_SY6970_CHG_VOL_STEP + POWERS_SY6970_CHG_VOL_BASE;
}
// Range:3840 ~ 4608mV ,step:16 mV
bool setChargeTargetVoltage(uint16_t millivolt)
{
if (millivolt % POWERS_SY6970_CHG_VOL_STEP) {
log_e("Mistake ! The steps is must %u mV", POWERS_SY6970_CHG_VOL_STEP);
return false;
}
if (millivolt < POWERS_SY6970_FAST_CHG_VOL_MIN) {
millivolt = POWERS_SY6970_FAST_CHG_VOL_MIN;
}
if (millivolt > POWERS_SY6970_FAST_CHG_VOL_MAX) {
millivolt = POWERS_SY6970_FAST_CHG_VOL_MAX;
}
int val = readRegister(POWERS_PPM_REG_06H);
val &= 0x03;
val |= (((millivolt - POWERS_SY6970_CHG_VOL_BASE) / POWERS_SY6970_CHG_VOL_STEP) << 2);
return writeRegister(POWERS_PPM_REG_06H, val) != -1;
}
// Turn off the battery power supply path. It can only be turned off when the
// battery is powered. It cannot be turned off when USB is connected.
// The device can only be powered on by pressing the PWR button or by connecting the power supply.
void shutdown()
{
disableBatterPowerPath();
}
// Close battery power path
void disableBatterPowerPath()
{
setRegisterBit(POWERS_PPM_REG_09H, 5); //Force BATFET Off : BATFET_DIS
}
// Enable battery power path
void enableBatterPowerPath()
{
clrRegisterBit(POWERS_PPM_REG_09H, 5); //Force BATFET Off : BATFET_DIS
}
// Boost Mode Voltage Regulation: 4550 mV ~ 5510 mV
bool setBoostVoltage(uint16_t millivolt)
{
if (millivolt % POWERS_SY6970_BOOTS_VOL_STEP) {
log_e("Mistake ! The steps is must %u mV", POWERS_SY6970_BOOTS_VOL_STEP);
return false;
}
if (millivolt < POWERS_SY6970_BOOST_VOL_MIN) {
millivolt = POWERS_SY6970_BOOST_VOL_MIN;
}
if (millivolt > POWERS_SY6970_BOOST_VOL_MAX) {
millivolt = POWERS_SY6970_BOOST_VOL_MAX;
}
int val = readRegister(POWERS_PPM_REG_0AH);
val &= 0xF0;
val |= (((millivolt - POWERS_SY6970_BOOTS_VOL_BASE) / POWERS_SY6970_BOOTS_VOL_STEP) << 4);
return writeRegister(POWERS_PPM_REG_0AH, val) != -1;
}
// Boost Current Limit: 500mA ~ 2450mA
bool setBoostCurrentLimit(BoostCurrentLimit milliampere)
{
if (milliampere > BOOST_CUR_LIMIT_2450MA) {
return false;
}
int val = readRegister(POWERS_PPM_REG_0AH);
val &= 0x03;
val |= milliampere;
return writeRegister(POWERS_PPM_REG_0AH, val) != -1;
}
uint8_t getFaultStatus(void)
{
int val = readRegister(POWERS_PPM_REG_0CH);
if (val == -1) {
return 0;
}
__irq_mask = val;
return __irq_mask;
}
void getReadOnlyRegisterValue()
{
#if defined(ARDUINO) && !defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_ARCH_ZEPHYR) //debug ..
static uint8_t last_val[8] = {0};
const uint8_t regis[] = {
POWERS_PPM_REG_0BH,
POWERS_PPM_REG_0CH,
// POWERS_PPM_REG_0EH, //BATTERY VOLTAGE
// POWERS_PPM_REG_0FH, //SYSTEM VOLTAGE
// POWERS_PPM_REG_10H, //NTC PERCENTAGE
// POWERS_PPM_REG_11H, //VBUS VOLTAGE
POWERS_PPM_REG_12H,
POWERS_PPM_REG_13H
};
Serial.println();
Serial.println("-------------------------");
for (uint32_t i = 0; i < sizeof(regis) / sizeof(regis[0]); ++i) {
int val = readRegister(regis[i]);
if (val == -1) {
continue;
}
if (last_val[i] != val) {
Serial.printf("\t---> REG%02X Prev:0x%02X ", regis[i], last_val[i]);
Serial.print(" BIN:"); Serial.print(last_val[i], BIN);
Serial.printf(" Curr: 0x%02X", val);
Serial.print(" BIN:"); Serial.println(val, BIN);
last_val[i] = val;
}
Serial.printf("\tREG%02XH:0x%X BIN:0b", regis[i], val);
Serial.println(val, BIN);
}
Serial.println("-------------------------");
#endif
}
bool isWatchdogFault()
{
return POWERS_SY6970_IRQ_WTD_FAULT(__irq_mask);
}
bool isBoostFault()
{
return POWERS_SY6970_IRQ_BOOST_FAULT(__irq_mask);
}
bool isChargeFault()
{
return POWERS_SY6970_IRQ_CHG_FAULT(__irq_mask);
}
bool isBatteryFault()
{
return POWERS_SY6970_IRQ_BAT_FAULT(__irq_mask);
}
bool isNTCFault()
{
return POWERS_SY6970_IRQ_NTC_FAULT(__irq_mask);
}
bool setVinDpmThreshold(uint16_t millivolt)
{
if (millivolt % POWERS_SY6970_VINDPM_VOL_STEPS) {
log_e("Mistake ! The steps is must %u mV", POWERS_SY6970_VINDPM_VOL_STEPS);
return false;
}
if (millivolt < POWERS_SY6970_VINDPM_VOL_MIN) {
millivolt = POWERS_SY6970_VINDPM_VOL_MIN;
}
if (millivolt > POWERS_SY6970_VINDPM_VOL_MAX) {
millivolt = POWERS_SY6970_VINDPM_VOL_MAX;
}
int val = readRegister(POWERS_PPM_REG_0DH);
val &= 0x80;
val |= (((millivolt - POWERS_SY6970_VINDPM_VOL_BASE) / POWERS_SY6970_VINDPM_VOL_STEPS));
return writeRegister(POWERS_PPM_REG_0DH, val) != -1;
}
private:
bool initImpl()
{
__user_disable_charge = false;
uint8_t rev = getChipID();
if (rev != SY6970_DEV_REV) {
return false;
}
// Set the minimum operating voltage. Below this voltage, the PMU will protect
// setSysPowerDownVoltage(3300);
//Default disable Watchdog
disableWatchdog();
return true;
}
bool __user_disable_charge;
uint32_t __irq_mask;
};

View File

@@ -0,0 +1,182 @@
#pragma once
#define AXP192_SLAVE_ADDRESS (0x34)
#define XPOWERS_AXP192_CHIP_ID (0x03)
#define XPOWERS_AXP192_STATUS (0x00)
#define XPOWERS_AXP192_MODE_CHGSTATUS (0x01)
#define XPOWERS_AXP192_OTG_STATUS (0x02)
#define XPOWERS_AXP192_IC_TYPE (0x03)
#define XPOWERS_AXP192_DATA_BUFFER1 (0x06)
#define XPOWERS_AXP192_DATA_BUFFER2 (0x07)
#define XPOWERS_AXP192_DATA_BUFFER3 (0x08)
#define XPOWERS_AXP192_DATA_BUFFER4 (0x09)
#define XPOWERS_AXP192_DATA_BUFFER5 (0x0A)
#define XPOWERS_AXP192_DATA_BUFFER6 (0x0B)
#define XPOWERS_AXP192_DATA_BUFFER_SIZE (6)
#define XPOWERS_AXP192_LDO23_DC123_EXT_CTL (0x12)
#define XPOWERS_AXP192_DC2OUT_VOL (0x23)
#define XPOWERS_AXP192_DC2_DVM (0x25)
#define XPOWERS_AXP192_DC3OUT_VOL (0x27)
#define XPOWERS_AXP192_LDO24OUT_VOL (0x28)
#define XPOWERS_AXP192_LDO3OUT_VOL (0x29)
#define XPOWERS_AXP192_IPS_SET (0x30)
#define XPOWERS_AXP192_VOFF_SET (0x31)
#define XPOWERS_AXP192_OFF_CTL (0x32)
#define XPOWERS_AXP192_CHARGE1 (0x33)
#define XPOWERS_AXP192_CHARGE2 (0x34)
#define XPOWERS_AXP192_BACKUP_CHG (0x35)
#define XPOWERS_AXP192_POK_SET (0x36)
#define XPOWERS_AXP192_DCDC_FREQSET (0x37)
#define XPOWERS_AXP192_VLTF_CHGSET (0x38)
#define XPOWERS_AXP192_VHTF_CHGSET (0x39)
#define XPOWERS_AXP192_APS_WARNING1 (0x3A)
#define XPOWERS_AXP192_APS_WARNING2 (0x3B)
#define XPOWERS_AXP192_TLTF_DISCHGSET (0x3C)
#define XPOWERS_AXP192_THTF_DISCHGSET (0x3D)
#define XPOWERS_AXP192_DCDC_MODESET (0x80)
#define XPOWERS_AXP192_ADC_EN1 (0x82)
#define XPOWERS_AXP192_ADC_EN2 (0x83)
#define XPOWERS_AXP192_ADC_SPEED (0x84)
#define XPOWERS_AXP192_ADC_INPUTRANGE (0x85)
#define XPOWERS_AXP192_ADC_IRQ_RETFSET (0x86)
#define XPOWERS_AXP192_ADC_IRQ_FETFSET (0x87)
#define XPOWERS_AXP192_TIMER_CTL (0x8A)
#define XPOWERS_AXP192_VBUS_DET_SRP (0x8B)
#define XPOWERS_AXP192_HOTOVER_CTL (0x8F)
#define XPOWERS_AXP192_PWM1_FREQ_SET (0x98)
#define XPOWERS_AXP192_PWM1_DUTY_SET1 (0x99)
#define XPOWERS_AXP192_PWM1_DUTY_SET2 (0x9A)
#define XPOWERS_AXP192_PWM2_FREQ_SET (0x9B)
#define XPOWERS_AXP192_PWM2_DUTY_SET1 (0x9C)
#define XPOWERS_AXP192_PWM2_DUTY_SET2 (0x9D)
// INTERRUPT REGISTER
#define XPOWERS_AXP192_INTEN1 (0x40)
#define XPOWERS_AXP192_INTEN2 (0x41)
#define XPOWERS_AXP192_INTEN3 (0x42)
#define XPOWERS_AXP192_INTEN4 (0x43)
#define XPOWERS_AXP192_INTEN5 (0x4A)
// INTERRUPT STATUS REGISTER
#define XPOWERS_AXP192_INTSTS1 (0x44)
#define XPOWERS_AXP192_INTSTS2 (0x45)
#define XPOWERS_AXP192_INTSTS3 (0x46)
#define XPOWERS_AXP192_INTSTS4 (0x47)
#define XPOWERS_AXP192_INTSTS5 (0x4D)
#define XPOWERS_AXP192_INTSTS_CNT (5)
#define XPOWERS_AXP192_DC1_VLOTAGE (0x26)
#define XPOWERS_AXP192_LDO23OUT_VOL (0x28)
#define XPOWERS_AXP192_GPIO0_CTL (0x90)
#define XPOWERS_AXP192_GPIO0_VOL (0x91)
#define XPOWERS_AXP192_GPIO1_CTL (0X92)
#define XPOWERS_AXP192_GPIO2_CTL (0x93)
#define XPOWERS_AXP192_GPIO012_SIGNAL (0x94)
#define XPOWERS_AXP192_GPIO34_CTL (0x95)
#define XPOWERS_AXP192_GPIO34_SIGNAL (0x96)
#define XPOWERS_AXP192_GPIO012_PULLDOWN (0x97)
#define XPOWERS_AXP192_GPIO5_CTL (0x9E)
#define XPOWERS_AXP192_GPIO0_VOL_ADC_H8 (0x64)
#define XPOWERS_AXP192_GPIO0_VOL_ADC_L4 (0x65)
#define XPOWERS_AXP192_GPIO1_VOL_ADC_H8 (0x66)
#define XPOWERS_AXP192_GPIO1_VOL_ADC_L4 (0x67)
#define XPOWERS_AXP192_GPIO2_VOL_ADC_H8 (0x68)
#define XPOWERS_AXP192_GPIO2_VOL_ADC_L4 (0x69)
#define XPOWERS_AXP192_GPIO3_VOL_ADC_H8 (0x6A)
#define XPOWERS_AXP192_GPIO3_VOL_ADC_L4 (0x6B)
#define XPOWERS_AXP192_GPIO0_STEP (0.5F)
#define XPOWERS_AXP192_GPIO1_STEP (0.5F)
#define XPOWERS_AXP192_TS_IN_H8 (0x62)
#define XPOWERS_AXP192_TS_IN_L4 (0x63)
#define XPOWERS_AXP192_BAT_AVERCHGCUR_H8 (0x7A)
#define XPOWERS_AXP192_BAT_AVERCHGCUR_L5 (0x7B)
#define XPOWERS_AXP192_ACIN_VOL_H8 (0x56)
#define XPOWERS_AXP192_ACIN_VOL_L4 (0x57)
#define XPOWERS_AXP192_ACIN_CUR_H8 (0x58)
#define XPOWERS_AXP192_ACIN_CUR_L4 (0x59)
#define XPOWERS_AXP192_VBUS_VOL_H8 (0x5A)
#define XPOWERS_AXP192_VBUS_VOL_L4 (0x5B)
#define XPOWERS_AXP192_VBUS_CUR_H8 (0x5C)
#define XPOWERS_AXP192_VBUS_CUR_L4 (0x5D)
#define XPOWERS_AXP192_BAT_AVERDISCHGCUR_H8 (0x7C)
#define XPOWERS_AXP192_BAT_AVERDISCHGCUR_L5 (0x7D)
#define XPOWERS_AXP192_APS_AVERVOL_H8 (0x7E)
#define XPOWERS_AXP192_APS_AVERVOL_L4 (0x7F)
#define XPOWERS_AXP192_BAT_AVERVOL_H8 (0x78)
#define XPOWERS_AXP192_BAT_AVERVOL_L4 (0x79)
#define XPOWERS_AXP192_BAT_CHGCOULOMB3 (0xB0)
#define XPOWERS_AXP192_BAT_CHGCOULOMB2 (0xB1)
#define XPOWERS_AXP192_BAT_CHGCOULOMB1 (0xB2)
#define XPOWERS_AXP192_BAT_CHGCOULOMB0 (0xB3)
#define XPOWERS_AXP192_BAT_DISCHGCOULOMB3 (0xB4)
#define XPOWERS_AXP192_BAT_DISCHGCOULOMB2 (0xB5)
#define XPOWERS_AXP192_BAT_DISCHGCOULOMB1 (0xB6)
#define XPOWERS_AXP192_BAT_DISCHGCOULOMB0 (0xB7)
#define XPOWERS_AXP192_COULOMB_CTL (0xB8)
#define XPOWERS_AXP192_BATT_VOLTAGE_STEP (1.1F)
#define XPOWERS_AXP192_BATT_DISCHARGE_CUR_STEP (0.5F)
#define XPOWERS_AXP192_BATT_CHARGE_CUR_STEP (0.5F)
#define XPOWERS_AXP192_ACIN_VOLTAGE_STEP (1.7F)
#define XPOWERS_AXP192_ACIN_CUR_STEP (0.625F)
#define XPOWERS_AXP192_VBUS_VOLTAGE_STEP (1.7F)
#define XPOWERS_AXP192_VBUS_CUR_STEP (0.375F)
#define XPOWERS_AXP192_APS_VOLTAGE_STEP (1.4F)
#define XPOWERS_AXP192_TS_PIN_OUT_STEP (0.8F)
#define XPOWERS_AXP192_LDO2_VOL_MIN (1800u)
#define XPOWERS_AXP192_LDO2_VOL_MAX (3300u)
#define XPOWERS_AXP192_LDO2_VOL_STEPS (100u)
#define XPOWERS_AXP192_LDO2_VOL_BIT_MASK (4u)
#define XPOWERS_AXP192_LDO3_VOL_MIN (1800u)
#define XPOWERS_AXP192_LDO3_VOL_MAX (3300u)
#define XPOWERS_AXP192_LDO3_VOL_STEPS (100u)
#define XPOWERS_AXP192_DC1_VOL_STEPS (25u)
#define XPOWERS_AXP192_DC1_VOL_MIN (700u)
#define XPOWERS_AXP192_DC1_VOL_MAX (3500u)
#define XPOWERS_AXP192_DC2_VOL_STEPS (25u)
#define XPOWERS_AXP192_DC2_VOL_MIN (700u)
#define XPOWERS_AXP192_DC2_VOL_MAX (3500u)
#define XPOWERS_AXP192_DC3_VOL_STEPS (25u)
#define XPOWERS_AXP192_DC3_VOL_MIN (700u)
#define XPOWERS_AXP192_DC3_VOL_MAX (3500u)
#define XPOWERS_AXP192_LDOIO_VOL_STEPS (100)
#define XPOWERS_AXP192_LDOIO_VOL_MIN (1800)
#define XPOWERS_AXP192_LDOIO_VOL_MAX (3300)
#define XPOWERS_AXP192_SYS_VOL_STEPS (100)
#define XPOWERS_AXP192_VOFF_VOL_MIN (2600)
#define XPOWERS_AXP192_VOFF_VOL_MAX (3300)
#define XPOWERS_AXP192_CHG_EXT_CURR_MIN (300)
#define XPOWERS_AXP192_CHG_EXT_CURR_MAX (1000)
#define XPOWERS_AXP192_CHG_EXT_CURR_STEP (100)
#define XPOWERS_AXP192_INTERNAL_TEMP_H8 (0x5E)
#define XPOWERS_AXP192_INTERNAL_TEMP_L4 (0x5F)
#define XPOWERS_AXP192_INTERNAL_TEMP_STEP (0.1F)
#define XPOWERS_AXP192_INERNAL_TEMP_OFFSET (144.7)

View File

@@ -0,0 +1,192 @@
#pragma once
#define AXP202_SLAVE_ADDRESS (0x35)
#define XPOWERS_AXP202_CHIP_ID (0x41)
#define XPOWERS_AXP202_STATUS (0x00)
#define XPOWERS_AXP202_MODE_CHGSTATUS (0x01)
#define XPOWERS_AXP202_OTG_STATUS (0x02)
#define XPOWERS_AXP202_IC_TYPE (0x03)
#define XPOWERS_AXP202_DATA_BUFFER1 (0x04)
#define XPOWERS_AXP202_DATA_BUFFER2 (0x05)
#define XPOWERS_AXP202_DATA_BUFFER3 (0x06)
#define XPOWERS_AXP202_DATA_BUFFER4 (0x07)
#define XPOWERS_AXP202_DATA_BUFFER5 (0x08)
#define XPOWERS_AXP202_DATA_BUFFER6 (0x09)
#define XPOWERS_AXP202_DATA_BUFFER7 (0x0A)
#define XPOWERS_AXP202_DATA_BUFFER8 (0x0B)
#define XPOWERS_AXP202_DATA_BUFFER9 (0x0C)
#define XPOWERS_AXP202_DATA_BUFFERA (0x0D)
#define XPOWERS_AXP202_DATA_BUFFERB (0x0E)
#define XPOWERS_AXP202_DATA_BUFFERC (0x0F)
#define XPOWERS_AXP202_LDO234_DC23_CTL (0x12)
#define XPOWERS_AXP202_DC2OUT_VOL (0x23)
#define XPOWERS_AXP202_LDO3_DC2_DVM (0x25)
#define XPOWERS_AXP202_DC3OUT_VOL (0x27)
#define XPOWERS_AXP202_LDO24OUT_VOL (0x28)
#define XPOWERS_AXP202_LDO3OUT_VOL (0x29)
#define XPOWERS_AXP202_IPS_SET (0x30)
#define XPOWERS_AXP202_VOFF_SET (0x31)
#define XPOWERS_AXP202_OFF_CTL (0x32)
#define XPOWERS_AXP202_CHARGE1 (0x33)
#define XPOWERS_AXP202_CHARGE2 (0x34)
#define XPOWERS_AXP202_BACKUP_CHG (0x35)
#define XPOWERS_AXP202_POK_SET (0x36)
#define XPOWERS_AXP202_DCDC_FREQSET (0x37)
#define XPOWERS_AXP202_VLTF_CHGSET (0x38)
#define XPOWERS_AXP202_VHTF_CHGSET (0x39)
#define XPOWERS_AXP202_APS_WARNING1 (0x3A)
#define XPOWERS_AXP202_APS_WARNING2 (0x3B)
#define XPOWERS_AXP202_TLTF_DISCHGSET (0x3C)
#define XPOWERS_AXP202_THTF_DISCHGSET (0x3D)
#define XPOWERS_AXP202_DCDC_MODESET (0x80)
#define XPOWERS_AXP202_ADC_EN1 (0x82)
#define XPOWERS_AXP202_ADC_EN2 (0x83)
#define XPOWERS_AXP202_ADC_SPEED (0x84)
#define XPOWERS_AXP202_ADC_INPUTRANGE (0x85)
#define XPOWERS_AXP202_ADC_IRQ_RETFSET (0x86)
#define XPOWERS_AXP202_ADC_IRQ_FETFSET (0x87)
#define XPOWERS_AXP202_TIMER_CTL (0x8A)
#define XPOWERS_AXP202_VBUS_DET_SRP (0x8B)
#define XPOWERS_AXP202_HOTOVER_CTL (0x8F)
#define XPOWERS_AXP202_DATA_BUFFER_SIZE (12)
#define XPOWERS_AXP202_GPIO0_CTL (0x90)
#define XPOWERS_AXP202_GPIO0_VOL (0x91)
#define XPOWERS_AXP202_GPIO1_CTL (0x92)
#define XPOWERS_AXP202_GPIO2_CTL (0x93)
#define XPOWERS_AXP202_GPIO012_SIGNAL (0x94)
#define XPOWERS_AXP202_GPIO3_CTL (0x95)
// INTERRUPT REGISTER
#define XPOWERS_AXP202_INTEN1 (0x40)
#define XPOWERS_AXP202_INTEN2 (0x41)
#define XPOWERS_AXP202_INTEN3 (0x42)
#define XPOWERS_AXP202_INTEN4 (0x43)
#define XPOWERS_AXP202_INTEN5 (0x44)
//INTERRUPT STATUS REGISTER
#define XPOWERS_AXP202_INTSTS1 (0x48)
#define XPOWERS_AXP202_INTSTS2 (0x49)
#define XPOWERS_AXP202_INTSTS3 (0x4A)
#define XPOWERS_AXP202_INTSTS4 (0x4B)
#define XPOWERS_AXP202_INTSTS5 (0x4C)
#define XPOWERS_AXP202_INTSTS_CNT (5)
//AXP ADC DATA REGISTER
#define XPOWERS_AXP202_GPIO0_VOL_ADC_H8 (0x64)
#define XPOWERS_AXP202_GPIO0_VOL_ADC_L4 (0x65)
#define XPOWERS_AXP202_GPIO1_VOL_ADC_H8 (0x66)
#define XPOWERS_AXP202_GPIO1_VOL_ADC_L4 (0x67)
#define XPOWERS_AXP202_GPIO0_STEP (0.5F)
#define XPOWERS_AXP202_GPIO1_STEP (0.5F)
#define XPOWERS_AXP202_BAT_AVERVOL_H8 (0x78)
#define XPOWERS_AXP202_BAT_AVERVOL_L4 (0x79)
#define XPOWERS_AXP202_BAT_AVERCHGCUR_H8 (0x7A)
#define XPOWERS_AXP202_BAT_AVERCHGCUR_L4 (0x7B)
#define XPOWERS_AXP202_BAT_AVERCHGCUR_L5 (0x7B)
#define XPOWERS_AXP202_ACIN_VOL_H8 (0x56)
#define XPOWERS_AXP202_ACIN_VOL_L4 (0x57)
#define XPOWERS_AXP202_ACIN_CUR_H8 (0x58)
#define XPOWERS_AXP202_ACIN_CUR_L4 (0x59)
#define XPOWERS_AXP202_VBUS_VOL_H8 (0x5A)
#define XPOWERS_AXP202_VBUS_VOL_L4 (0x5B)
#define XPOWERS_AXP202_VBUS_CUR_H8 (0x5C)
#define XPOWERS_AXP202_VBUS_CUR_L4 (0x5D)
#define XPOWERS_AXP202_INTERNAL_TEMP_H8 (0x5E)
#define XPOWERS_AXP202_INTERNAL_TEMP_L4 (0x5F)
#define XPOWERS_AXP202_TS_IN_H8 (0x62)
#define XPOWERS_AXP202_TS_IN_L4 (0x63)
#define XPOWERS_AXP202_GPIO0_VOL_ADC_H8 (0x64)
#define XPOWERS_AXP202_GPIO0_VOL_ADC_L4 (0x65)
#define XPOWERS_AXP202_GPIO1_VOL_ADC_H8 (0x66)
#define XPOWERS_AXP202_GPIO1_VOL_ADC_L4 (0x67)
#define XPOWERS_AXP202_BAT_AVERDISCHGCUR_H8 (0x7C)
#define XPOWERS_AXP202_BAT_AVERDISCHGCUR_L5 (0x7D)
#define XPOWERS_AXP202_APS_AVERVOL_H8 (0x7E)
#define XPOWERS_AXP202_APS_AVERVOL_L4 (0x7F)
#define XPOWERS_AXP202_INT_BAT_CHGCUR_H8 (0xA0)
#define XPOWERS_AXP202_INT_BAT_CHGCUR_L4 (0xA1)
#define XPOWERS_AXP202_EXT_BAT_CHGCUR_H8 (0xA2)
#define XPOWERS_AXP202_EXT_BAT_CHGCUR_L4 (0xA3)
#define XPOWERS_AXP202_INT_BAT_DISCHGCUR_H8 (0xA4)
#define XPOWERS_AXP202_INT_BAT_DISCHGCUR_L4 (0xA5)
#define XPOWERS_AXP202_EXT_BAT_DISCHGCUR_H8 (0xA6)
#define XPOWERS_AXP202_EXT_BAT_DISCHGCUR_L4 (0xA7)
#define XPOWERS_AXP202_BAT_CHGCOULOMB3 (0xB0)
#define XPOWERS_AXP202_BAT_CHGCOULOMB2 (0xB1)
#define XPOWERS_AXP202_BAT_CHGCOULOMB1 (0xB2)
#define XPOWERS_AXP202_BAT_CHGCOULOMB0 (0xB3)
#define XPOWERS_AXP202_BAT_DISCHGCOULOMB3 (0xB4)
#define XPOWERS_AXP202_BAT_DISCHGCOULOMB2 (0xB5)
#define XPOWERS_AXP202_BAT_DISCHGCOULOMB1 (0xB6)
#define XPOWERS_AXP202_BAT_DISCHGCOULOMB0 (0xB7)
#define XPOWERS_AXP202_COULOMB_CTL (0xB8)
#define XPOWERS_AXP202_BATT_PERCENTAGE (0xB9)
#define XPOWERS_AXP202_BAT_POWERH8 (0x70)
#define XPOWERS_AXP202_BAT_POWERM8 (0x71)
#define XPOWERS_AXP202_BAT_POWERL8 (0x72)
#define XPOWERS_AXP202_BATT_VOLTAGE_STEP (1.1F)
#define XPOWERS_AXP202_BATT_DISCHARGE_CUR_STEP (0.5F)
#define XPOWERS_AXP202_BATT_CHARGE_CUR_STEP (0.5F)
#define XPOWERS_AXP202_ACIN_VOLTAGE_STEP (1.7F)
#define XPOWERS_AXP202_ACIN_CUR_STEP (0.625F)
#define XPOWERS_AXP202_VBUS_VOLTAGE_STEP (1.7F)
#define XPOWERS_AXP202_VBUS_CUR_STEP (0.375F)
#define XPOWERS_AXP202_INTERNAL_TEMP_STEP (0.1F)
#define XPOWERS_AXP202_APS_VOLTAGE_STEP (1.4F)
#define XPOWERS_AXP202_TS_PIN_OUT_STEP (0.8F)
#define XPOWERS_AXP202_LDO2_VOL_MIN (1800u)
#define XPOWERS_AXP202_LDO2_VOL_MAX (3300u)
#define XPOWERS_AXP202_LDO2_VOL_STEPS (100u)
#define XPOWERS_AXP202_LDO2_VOL_BIT_MASK (4u)
#define XPOWERS_AXP202_LDO3_VOL_MIN (1800u)
#define XPOWERS_AXP202_LDO3_VOL_MAX (3300u)
#define XPOWERS_AXP202_LDO3_VOL_STEPS (100u)
#define XPOWERS_AXP202_DC2_VOL_STEPS (25u)
#define XPOWERS_AXP202_DC2_VOL_MIN (700u)
#define XPOWERS_AXP202_DC2_VOL_MAX (3500u)
#define XPOWERS_AXP202_DC3_VOL_STEPS (25u)
#define XPOWERS_AXP202_DC3_VOL_MIN (700u)
#define XPOWERS_AXP202_DC3_VOL_MAX (3500u)
#define XPOWERS_AXP202_LDOIO_VOL_STEPS (100)
#define XPOWERS_AXP202_LDOIO_VOL_MIN (1800)
#define XPOWERS_AXP202_LDOIO_VOL_MAX (3300)
#define XPOWERS_AXP202_SYS_VOL_STEPS (100)
#define XPOWERS_AXP202_VOFF_VOL_MIN (2600)
#define XPOWERS_AXP202_VOFF_VOL_MAX (3300)
#define XPOWERS_AXP202_CHG_EXT_CURR_MIN (300)
#define XPOWERS_AXP202_CHG_EXT_CURR_MAX (1000)
#define XPOWERS_AXP202_CHG_EXT_CURR_STEP (100)
#define XPOWERS_AXP202_INERNAL_TEMP_OFFSET (144.7)

View File

@@ -0,0 +1,242 @@
#pragma once
#define AXP2101_SLAVE_ADDRESS (0x34)
#define XPOWERS_AXP2101_CHIP_ID (0x4A)
#define XPOWERS_AXP2101_STATUS1 (0x00)
#define XPOWERS_AXP2101_STATUS2 (0x01)
#define XPOWERS_AXP2101_IC_TYPE (0x03)
#define XPOWERS_AXP2101_DATA_BUFFER1 (0x04)
#define XPOWERS_AXP2101_DATA_BUFFER2 (0x05)
#define XPOWERS_AXP2101_DATA_BUFFER3 (0x06)
#define XPOWERS_AXP2101_DATA_BUFFER4 (0x07)
#define XPOWERS_AXP2101_DATA_BUFFER_SIZE (4u)
#define XPOWERS_AXP2101_COMMON_CONFIG (0x10)
#define XPOWERS_AXP2101_BATFET_CTRL (0x12)
#define XPOWERS_AXP2101_DIE_TEMP_CTRL (0x13)
#define XPOWERS_AXP2101_MIN_SYS_VOL_CTRL (0x14)
#define XPOWERS_AXP2101_INPUT_VOL_LIMIT_CTRL (0x15)
#define XPOWERS_AXP2101_INPUT_CUR_LIMIT_CTRL (0x16)
#define XPOWERS_AXP2101_RESET_FUEL_GAUGE (0x17)
#define XPOWERS_AXP2101_CHARGE_GAUGE_WDT_CTRL (0x18)
#define XPOWERS_AXP2101_WDT_CTRL (0x19)
#define XPOWERS_AXP2101_LOW_BAT_WARN_SET (0x1A)
#define XPOWERS_AXP2101_PWRON_STATUS (0x20)
#define XPOWERS_AXP2101_PWROFF_STATUS (0x21)
#define XPOWERS_AXP2101_PWROFF_EN (0x22)
#define XPOWERS_AXP2101_DC_OVP_UVP_CTRL (0x23)
#define XPOWERS_AXP2101_VOFF_SET (0x24)
#define XPOWERS_AXP2101_PWROK_SEQU_CTRL (0x25)
#define XPOWERS_AXP2101_SLEEP_WAKEUP_CTRL (0x26)
#define XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL (0x27)
#define XPOWERS_AXP2101_FAST_PWRON_SET0 (0x28)
#define XPOWERS_AXP2101_FAST_PWRON_SET1 (0x29)
#define XPOWERS_AXP2101_FAST_PWRON_SET2 (0x2A)
#define XPOWERS_AXP2101_FAST_PWRON_CTRL (0x2B)
#define XPOWERS_AXP2101_ADC_CHANNEL_CTRL (0x30)
#define XPOWERS_AXP2101_ADC_DATA_RELUST0 (0x34)
#define XPOWERS_AXP2101_ADC_DATA_RELUST1 (0x35)
#define XPOWERS_AXP2101_ADC_DATA_RELUST2 (0x36)
#define XPOWERS_AXP2101_ADC_DATA_RELUST3 (0x37)
#define XPOWERS_AXP2101_ADC_DATA_RELUST4 (0x38)
#define XPOWERS_AXP2101_ADC_DATA_RELUST5 (0x39)
#define XPOWERS_AXP2101_ADC_DATA_RELUST6 (0x3A)
#define XPOWERS_AXP2101_ADC_DATA_RELUST7 (0x3B)
#define XPOWERS_AXP2101_ADC_DATA_RELUST8 (0x3C)
#define XPOWERS_AXP2101_ADC_DATA_RELUST9 (0x3D)
//XPOWERS INTERRUPT REGISTER
#define XPOWERS_AXP2101_INTEN1 (0x40)
#define XPOWERS_AXP2101_INTEN2 (0x41)
#define XPOWERS_AXP2101_INTEN3 (0x42)
//XPOWERS INTERRUPT STATUS REGISTER
#define XPOWERS_AXP2101_INTSTS1 (0x48)
#define XPOWERS_AXP2101_INTSTS2 (0x49)
#define XPOWERS_AXP2101_INTSTS3 (0x4A)
#define XPOWERS_AXP2101_INTSTS_CNT (3)
#define XPOWERS_AXP2101_TS_PIN_CTRL (0x50)
#define XPOWERS_AXP2101_TS_HYSL2H_SET (0x52)
#define XPOWERS_AXP2101_TS_LYSL2H_SET (0x53)
#define XPOWERS_AXP2101_VLTF_CHG_SET (0x54)
#define XPOWERS_AXP2101_VHLTF_CHG_SET (0x55)
#define XPOWERS_AXP2101_VLTF_WORK_SET (0x56)
#define XPOWERS_AXP2101_VHLTF_WORK_SET (0x57)
#define XPOWERS_AXP2101_JIETA_EN_CTRL (0x58)
#define XPOWERS_AXP2101_JIETA_SET0 (0x59)
#define XPOWERS_AXP2101_JIETA_SET1 (0x5A)
#define XPOWERS_AXP2101_JIETA_SET2 (0x5B)
#define XPOWERS_AXP2101_IPRECHG_SET (0x61)
#define XPOWERS_AXP2101_ICC_CHG_SET (0x62)
#define XPOWERS_AXP2101_ITERM_CHG_SET_CTRL (0x63)
#define XPOWERS_AXP2101_CV_CHG_VOL_SET (0x64)
#define XPOWERS_AXP2101_THE_REGU_THRES_SET (0x65)
#define XPOWERS_AXP2101_CHG_TIMEOUT_SET_CTRL (0x67)
#define XPOWERS_AXP2101_BAT_DET_CTRL (0x68)
#define XPOWERS_AXP2101_CHGLED_SET_CTRL (0x69)
#define XPOWERS_AXP2101_BTN_VOL_MIN (2600)
#define XPOWERS_AXP2101_BTN_VOL_MAX (3300)
#define XPOWERS_AXP2101_BTN_VOL_STEPS (100)
#define XPOWERS_AXP2101_BTN_BAT_CHG_VOL_SET (0x6A)
#define XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL (0x80)
#define XPOWERS_AXP2101_DC_FORCE_PWM_CTRL (0x81)
#define XPOWERS_AXP2101_DC_VOL0_CTRL (0x82)
#define XPOWERS_AXP2101_DC_VOL1_CTRL (0x83)
#define XPOWERS_AXP2101_DC_VOL2_CTRL (0x84)
#define XPOWERS_AXP2101_DC_VOL3_CTRL (0x85)
#define XPOWERS_AXP2101_DC_VOL4_CTRL (0x86)
#define XPOWERS_AXP2101_LDO_ONOFF_CTRL0 (0x90)
#define XPOWERS_AXP2101_LDO_ONOFF_CTRL1 (0x91)
#define XPOWERS_AXP2101_LDO_VOL0_CTRL (0x92)
#define XPOWERS_AXP2101_LDO_VOL1_CTRL (0x93)
#define XPOWERS_AXP2101_LDO_VOL2_CTRL (0x94)
#define XPOWERS_AXP2101_LDO_VOL3_CTRL (0x95)
#define XPOWERS_AXP2101_LDO_VOL4_CTRL (0x96)
#define XPOWERS_AXP2101_LDO_VOL5_CTRL (0x97)
#define XPOWERS_AXP2101_LDO_VOL6_CTRL (0x98)
#define XPOWERS_AXP2101_LDO_VOL7_CTRL (0x99)
#define XPOWERS_AXP2101_LDO_VOL8_CTRL (0x9A)
#define XPOWERS_AXP2101_BAT_PARAME (0xA1)
#define XPOWERS_AXP2101_FUEL_GAUGE_CTRL (0xA2)
#define XPOWERS_AXP2101_BAT_PERCENT_DATA (0xA4)
// DCDC 1~5
#define XPOWERS_AXP2101_DCDC1_VOL_MIN (1500)
#define XPOWERS_AXP2101_DCDC1_VOL_MAX (3400)
#define XPOWERS_AXP2101_DCDC1_VOL_STEPS (100u)
#define XPOWERS_AXP2101_DCDC2_VOL1_MIN (500u)
#define XPOWERS_AXP2101_DCDC2_VOL1_MAX (1200u)
#define XPOWERS_AXP2101_DCDC2_VOL2_MIN (1220u)
#define XPOWERS_AXP2101_DCDC2_VOL2_MAX (1540u)
#define XPOWERS_AXP2101_DCDC2_VOL_STEPS1 (10u)
#define XPOWERS_AXP2101_DCDC2_VOL_STEPS2 (20u)
#define XPOWERS_AXP2101_DCDC2_VOL_STEPS1_BASE (0u)
#define XPOWERS_AXP2101_DCDC2_VOL_STEPS2_BASE (71)
#define XPOWERS_AXP2101_DCDC3_VOL1_MIN (500u)
#define XPOWERS_AXP2101_DCDC3_VOL1_MAX (1200u)
#define XPOWERS_AXP2101_DCDC3_VOL2_MIN (1220u)
#define XPOWERS_AXP2101_DCDC3_VOL2_MAX (1540u)
#define XPOWERS_AXP2101_DCDC3_VOL3_MIN (1600u)
#define XPOWERS_AXP2101_DCDC3_VOL3_MAX (3400u)
#define XPOWERS_AXP2101_DCDC3_VOL_MIN (500)
#define XPOWERS_AXP2101_DCDC3_VOL_MAX (3400)
#define XPOWERS_AXP2101_DCDC3_VOL_STEPS1 (10u)
#define XPOWERS_AXP2101_DCDC3_VOL_STEPS2 (20u)
#define XPOWERS_AXP2101_DCDC3_VOL_STEPS3 (100u)
#define XPOWERS_AXP2101_DCDC3_VOL_STEPS1_BASE (0u)
#define XPOWERS_AXP2101_DCDC3_VOL_STEPS2_BASE (71)
#define XPOWERS_AXP2101_DCDC3_VOL_STEPS3_BASE (88)
#define XPOWERS_AXP2101_DCDC4_VOL1_MIN (500u)
#define XPOWERS_AXP2101_DCDC4_VOL1_MAX (1200u)
#define XPOWERS_AXP2101_DCDC4_VOL2_MIN (1220u)
#define XPOWERS_AXP2101_DCDC4_VOL2_MAX (1840u)
#define XPOWERS_AXP2101_DCDC4_VOL_STEPS1 (10u)
#define XPOWERS_AXP2101_DCDC4_VOL_STEPS2 (20u)
#define XPOWERS_AXP2101_DCDC4_VOL_STEPS1_BASE (0u)
#define XPOWERS_AXP2101_DCDC4_VOL_STEPS2_BASE (71)
#define XPOWERS_AXP2101_DCDC5_VOL_1200MV (1200)
#define XPOWERS_AXP2101_DCDC5_VOL_VAL (0x19)
#define XPOWERS_AXP2101_DCDC5_VOL_MIN (1400)
#define XPOWERS_AXP2101_DCDC5_VOL_MAX (3700)
#define XPOWERS_AXP2101_DCDC5_VOL_STEPS (100u)
#define XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_MIN (2600)
#define XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_MAX (3300)
#define XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_STEPS (100)
// ALDO 1~4
#define XPOWERS_AXP2101_ALDO1_VOL_MIN (500)
#define XPOWERS_AXP2101_ALDO1_VOL_MAX (3500)
#define XPOWERS_AXP2101_ALDO1_VOL_STEPS (100u)
#define XPOWERS_AXP2101_ALDO2_VOL_MIN (500)
#define XPOWERS_AXP2101_ALDO2_VOL_MAX (3500)
#define XPOWERS_AXP2101_ALDO2_VOL_STEPS (100u)
#define XPOWERS_AXP2101_ALDO3_VOL_MIN (500)
#define XPOWERS_AXP2101_ALDO3_VOL_MAX (3500)
#define XPOWERS_AXP2101_ALDO3_VOL_STEPS (100u)
#define XPOWERS_AXP2101_ALDO4_VOL_MIN (500)
#define XPOWERS_AXP2101_ALDO4_VOL_MAX (3500)
#define XPOWERS_AXP2101_ALDO4_VOL_STEPS (100u)
// BLDO 1~2
#define XPOWERS_AXP2101_BLDO1_VOL_MIN (500)
#define XPOWERS_AXP2101_BLDO1_VOL_MAX (3500)
#define XPOWERS_AXP2101_BLDO1_VOL_STEPS (100u)
#define XPOWERS_AXP2101_BLDO2_VOL_MIN (500)
#define XPOWERS_AXP2101_BLDO2_VOL_MAX (3500)
#define XPOWERS_AXP2101_BLDO2_VOL_STEPS (100u)
// CPUSLDO
#define XPOWERS_AXP2101_CPUSLDO_VOL_MIN (500)
#define XPOWERS_AXP2101_CPUSLDO_VOL_MAX (1400)
#define XPOWERS_AXP2101_CPUSLDO_VOL_STEPS (50)
// DLDO 1~2
#define XPOWERS_AXP2101_DLDO1_VOL_MIN (500)
#define XPOWERS_AXP2101_DLDO1_VOL_MAX (3400)
#define XPOWERS_AXP2101_DLDO1_VOL_STEPS (100u)
#define XPOWERS_AXP2101_DLDO2_VOL_MIN (500)
#define XPOWERS_AXP2101_DLDO2_VOL_MAX (3400)
#define XPOWERS_AXP2101_DLDO2_VOL_STEPS (100u)
#define XPOWERS_AXP2101_CONVERSION(raw) (22.0 + (7274 - raw) / 20.0)

View File

@@ -0,0 +1,95 @@
#pragma once
#define AXP216_SLAVE_ADDRESS (0x34)
#define XPOWERS_AXP216_CHIP_ID (0x41)
//CONTROL REGISTER
#define XPOWERS_AXP216_STATUS (0x00)
#define XPOWERS_AXP216_MODE_CHGSTATUS (0x01)
#define XPOWERS_AXP216_DATA_BUFFER1 (0x04)
#define XPOWERS_AXP216_DATA_BUFFER2 (0x05)
#define XPOWERS_AXP216_DATA_BUFFER3 (0x06)
#define XPOWERS_AXP216_DATA_BUFFER4 (0x07)
#define XPOWERS_AXP216_DATA_BUFFER5 (0x08)
#define XPOWERS_AXP216_DATA_BUFFER6 (0x09)
#define XPOWERS_AXP216_DATA_BUFFER7 (0x0A)
#define XPOWERS_AXP216_DATA_BUFFER8 (0x0B)
#define XPOWERS_AXP216_DATA_BUFFER9 (0x0C)
#define XPOWERS_AXP216_DATA_BUFFERA (0x0D)
#define XPOWERS_AXP216_DATA_BUFFERB (0x0E)
#define XPOWERS_AXP216_DATA_BUFFERC (0x0F)
#define XPOWERS_AXP216_IC_TYPE (0x03)
#define XPOWERS_AXP216_DC12345_ALDO12_CTL (0x10)
#define XPOWERS_AXP216_LDO123_CTL (0x12)
#define XPOWERS_AXP216_OUTPUT_CTL (0x13)
#define XPOWERS_AXP216_ELDO1_VCTL (0x19)
#define XPOWERS_AXP216_ELDO2_VCTL (0x1A)
#define XPOWERS_AXP216_DCDC1_VCTL (0x21)
#define XPOWERS_AXP216_DCDC2_VCTL (0x22)
#define XPOWERS_AXP216_DCDC3_VCTL (0x23)
#define XPOWERS_AXP216_DCDC4_VCTL (0x24)
#define XPOWERS_AXP216_DCDC5_VCTL (0x25)
#define XPOWERS_AXP216_DCDC23_VOLX (0x27)
#define XPOWERS_AXP216_ALDO1_VCTL (0x28)
#define XPOWERS_AXP216_ALDO2_VCTL (0x29)
#define XPOWERS_AXP216_ALDO3_VCTL (0x2A)
#define XPOWERS_AXP216_VBUS_IPSOUT (0x30)
#define XPOWERS_AXP216_VOFF_SET (0x31)
#define XPOWERS_AXP216_OFF_CTL (0x32)
#define XPOWERS_AXP216_CHARGE1 (0x33)
#define XPOWERS_AXP216_CHARGE2 (0x34)
#define XPOWERS_AXP216_CHARGE3 (0x35)
#define XPOWERS_AXP216_PEK_SET (0x36)
#define XPOWERS_AXP216_OFFLEVEL (0x37)
#define XPOWERS_AXP216_VLTF_CHGSET (0x38)
#define XPOWERS_AXP216_VHTF_CHGSET (0x39)
#define XPOWERS_AXP216_DCDC_FREQ (0x3B)
#define XPOWERS_AXP216_TLTF_DISCHGSET (0x3C)
#define XPOWERS_AXP216_THTF_DISCHGSET (0x3D)
#define XPOWERS_AXP216_DCDC_MODESET (0x80)
#define XPOWERS_AXP216_ADC_CTL (0x82)
#define XPOWERS_AXP216_ADC_SPEED (0x84)
#define XPOWERS_AXP216_TS_ADC (0x85)
#define XPOWERS_AXP216_TIMER_CTL (0x8A)
#define XPOWERS_AXP216_HOTOVER_CTL (0x8F)
//GPIO REGISTER
#define XPOWERS_AXP216_GPIO1_CTL (0x92)
#define XPOWERS_AXP216_GPIO1_LDO_CTL (0x93)
#define XPOWERS_AXP216_GPIO01_STATUS (0x94)
#define XPOWERS_AXP216_GPIO1_PULLDOWN_CTL (0x97)
//XPOWERS INTERRUPT REGISTER
#define XPOWERS_AXP216_INTEN1 (0x40)
#define XPOWERS_AXP216_INTEN2 (0x41)
#define XPOWERS_AXP216_INTEN3 (0x42)
#define XPOWERS_AXP216_INTEN4 (0x43)
#define XPOWERS_AXP216_INTEN5 (0x44)
//XPOWERS INTERRUPT STATUS REGISTER
#define XPOWERS_AXP216_INTSTS1 (0x48)
#define XPOWERS_AXP216_INTSTS2 (0x49)
#define XPOWERS_AXP216_INTSTS3 (0x4A)
#define XPOWERS_AXP216_INTSTS4 (0x4B)
#define XPOWERS_AXP216_INTSTS5 (0x4C)
//XPOWERS ADC DATA REGISTER
#define XPOWERS_AXP216_INTERNAL_TEMP_H8 (0x56)
#define XPOWERS_AXP216_INTERNAL_TEMP_L4 (0x57)
#define XPOWERS_AXP216_TS_IN_H8 (0x58)
#define XPOWERS_AXP216_TS_IN_L4 (0x59)
#define XPOWERS_AXP216_BAT_VOLTAGE_H8 (0x78)
#define XPOWERS_AXP216_BAT_VOLTAGE_L4 (0x79)
#define XPOWERS_AXP216_BAT_CHGCURCUR_H8 (0x7A)
#define XPOWERS_AXP216_BAT_CHGCURCUR_L4 (0x7B)
#define XPOWERS_AXP216_BAT_DISCHGCUR_H8 (0x7C)
#define XPOWERS_AXP216_BAT_DISCHGCUR_L4 (0x7D)
#define XPOWERS_AXP216_FUEL_GAUGE_CTRL (0xB8)
#define XPOWERS_AXP216_FUEL_GAUGE_REULST (0xB9)
#define XPOWERS_AXP216_BAT_CAPACITY_0 (0xE0)
#define XPOWERS_AXP216_BAT_CAPACITY_1 (0xE1)
#define XPOWERS_AXP216_BAT_LOW_WARNING_CTRL (0xE6)

View File

@@ -0,0 +1,111 @@
/**
*
* @license 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.
*
* @file BQ25896Constants.h
* @author Lewis He (lewishe@outlook.com)
* @date 2023-07-20
*
*/
#pragma once
// https://www.ti.com/product/BQ25896
#define BQ25896_SLAVE_ADDRESS (0x6B)
#define BQ25896_DEV_REV (0x02)
#define POWERS_BQ25896_VBUS_MASK_VAL(val) (val & 0x7F)
#define POWERS_BQ25896_VBAT_MASK_VAL(val) (val & 0x7F)
#define POWERS_BQ25896_VSYS_MASK_VAL(val) (val & 0x7F)
#define POWERS_BQ25896_NTC_MASK_VAL(val) (val & 0x7F)
#define POWERS_BQ25896_VBUS_BASE_VAL (2600)
#define POWERS_BQ25896_VBAT_BASE_VAL (2304)
#define POWERS_BQ25896_VSYS_BASE_VAL (2304)
#define POWERS_BQ25896_NTC_BASE_VAL (21)
#define POWERS_BQ25896_VBUS_VOL_STEP (100)
#define POWERS_BQ25896_VBAT_VOL_STEP (20)
#define POWERS_BQ25896_VSYS_VOL_STEP (20)
#define POWERS_BQ25896_NTC_VOL_STEP (0.465)
#define POWERS_BQ25896_CHG_STEP_VAL (50)
#define POWERS_BQ25896_FAST_CHG_CUR_STEP (64)
#define POWERS_BQ25896_FAST_CHG_CURRENT_MIN (0)
#define POWERS_BQ25896_FAST_CHG_CURRENT_MAX (3008)
#define POWERS_BQ25896_PRE_CHG_CUR_BASE (64)
#define POWERS_BQ25896_PRE_CHG_CUR_STEP (64)
#define POWERS_BQ25896_PRE_CHG_CURRENT_MIN (64)
#define POWERS_BQ25896_PRE_CHG_CURRENT_MAX (1024)
#define POWERS_BQ25896_TERM_CHG_CUR_BASE (64)
#define POWERS_BQ25896_TERM_CHG_CUR_STEP (64)
#define POWERS_BQ25896_TERM_CHG_CURRENT_MIN (64)
#define POWERS_BQ25896_TERM_CHG_CURRENT_MAX (1024)
#define POWERS_BQ25896_CHG_VOL_BASE (3840)
#define POWERS_BQ25896_CHG_VOL_STEP (16)
#define POWERS_BQ25896_FAST_CHG_VOL_MIN (3840)
#define POWERS_BQ25896_FAST_CHG_VOL_MAX (4608)
#define POWERS_BQ25896_SYS_VOL_STEPS (100)
#define POWERS_BQ25896_SYS_VOFF_VOL_MIN (3000)
#define POWERS_BQ25896_SYS_VOFF_VOL_MAX (3700)
#define POWERS_BQ25896_IN_CURRENT_STEP (50)
#define POWERS_BQ25896_IN_CURRENT_MIN (100)
#define POWERS_BQ25896_IN_CURRENT_MAX (3250)
#define POWERS_BQ25896_IN_CURRENT_OPT_STEP (50)
#define POWERS_BQ25896_IN_CURRENT_OPT_MIN (100)
#define POWERS_BQ25896_IN_CURRENT_OPT_MAX (3250)
#define POWERS_BQ25896_IN_CURRENT_OFFSET_STEP (100)
#define POWERS_BQ25896_IN_CURRENT_OFFSET_MAX (3100)
#define POWERS_BQ25896_BOOTS_VOL_BASE (4550)
#define POWERS_BQ25896_BOOTS_VOL_STEP (64)
#define POWERS_BQ25896_BOOST_VOL_MIN (4550)
#define POWERS_BQ25896_BOOST_VOL_MAX (5510)
#define POWERS_BQ25896_IRQ_WTD_FAULT(x) (bool)(( x & 0xFF ) >> 7)
#define POWERS_BQ25896_IRQ_BOOST_FAULT(x) (bool)(( x & 0xFF ) >> 6)
#define POWERS_BQ25896_IRQ_CHG_FAULT(x) (( x >> 4 ) & 0x03)
#define POWERS_BQ25896_IRQ_BAT_FAULT(x) (bool)(( x & 0xFF ) >> 3)
#define POWERS_BQ25896_IRQ_NTC_FAULT(x) (bool)(( x & 0xFF ) & 0x03)
#define POWERS_BQ25896_VINDPM_VOL_BASE (4550)
#define POWERS_BQ25896_VINDPM_VOL_STEPS (100)
#define POWERS_BQ25896_VINDPM_VOL_MIN (3900)
#define POWERS_BQ25896_VINDPM_VOL_MAX (15300)
#define POWERS_BQ25896_BAT_COMP_STEPS (20)
#define POWERS_BQ25896_BAT_COMP_MAX (140)
#define POWERS_BQ25896_VCLAMP_STEPS (32)
#define POWERS_BQ25896_VCLAMP_MAX (224)

View File

@@ -0,0 +1,78 @@
/**
*
* @license 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.
*
* @file GeneralPPMConstants.h
* @author Lewis He (lewishe@outlook.com)
* @date 2024-10-29
*
*/
#pragma once
#define POWERS_PPM_REG_00H (0x00)
#define POWERS_PPM_REG_01H (0x01)
#define POWERS_PPM_REG_02H (0x02)
#define POWERS_PPM_REG_03H (0x03)
#define POWERS_PPM_REG_04H (0x04)
#define POWERS_PPM_REG_05H (0x05)
#define POWERS_PPM_REG_06H (0x06)
#define POWERS_PPM_REG_07H (0x07)
#define POWERS_PPM_REG_08H (0x08)
#define POWERS_PPM_REG_09H (0x09)
#define POWERS_PPM_REG_0AH (0x0A)
// Read only STATUS REG
#define POWERS_PPM_REG_0BH (0x0B)
// Read only CHARGE IRQ REG
#define POWERS_PPM_REG_0CH (0x0C)
// Absolute VINDPM Threshold
#define POWERS_PPM_REG_0DH (0x0D)
// Read only BATTERY VOLTAGE
#define POWERS_PPM_REG_0EH (0x0E)
// Read only SYSTEM VOLTAGE
#define POWERS_PPM_REG_0FH (0x0F)
// Read only NTC PERCENTAGE
#define POWERS_PPM_REG_10H (0x10)
// Read only VBUS VOLTAGE
#define POWERS_PPM_REG_11H (0x11)
// Read only CHARGE CURRENT
#define POWERS_PPM_REG_12H (0x12)
// Read only VINDPM/IINDPM STATUS/CURR LIMIT SETTING
#define POWERS_PPM_REG_13H (0x13)
// RESET REG
#define POWERS_PPM_REG_14H (0x14)

View File

@@ -0,0 +1,45 @@
/**
*
* @license 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.
*
* @file HUSB238Constants.h
* @author Lewis He (lewishe@outlook.com)
* @date 2024-07-24
*
*/
#pragma once
#define HUSB238_SLAVE_ADDRESS (0x8)
#define HUSB238_PD_STATUS0 (0x0)
#define HUSB238_PD_STATUS1 (0x1)
#define HUSB238_SRC_PDO_5V (0x2)
#define HUSB238_SRC_PDO_9V (0x3)
#define HUSB238_SRC_PDO_12V (0x4)
#define HUSB238_SRC_PDO_15V (0x5)
#define HUSB238_SRC_PDO_18V (0x6)
#define HUSB238_SRC_PDO_20V (0x7)
#define HUSB238_SRC_PDO (0x8)
#define HUSB238_GO_COMMAND (0x9)

View File

@@ -0,0 +1,88 @@
/**
*
* @license 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.
*
* @file SY6970Constants.h
* @author Lewis He (lewishe@outlook.com)
* @date 2023-07-20
*
*/
#pragma once
#define SY6970_SLAVE_ADDRESS (0x6A)
#define SY6970_DEV_REV (0x00)
#define POWERS_SY6970_VBUS_MASK_VAL(val) (val & 0x7F)
#define POWERS_SY6970_VBAT_MASK_VAL(val) (val & 0x7F)
#define POWERS_SY6970_VSYS_MASK_VAL(val) (val & 0x7F)
#define POWERS_SY6970_NTC_MASK_VAL(val) (val & 0x7F)
#define POWERS_SY6970_VBUS_BASE_VAL (2600)
#define POWERS_SY6970_VBAT_BASE_VAL (2304)
#define POWERS_SY6970_VSYS_BASE_VAL (2304)
#define POWERS_SY6970_NTC_BASE_VAL (21)
#define POWERS_SY6970_VBUS_VOL_STEP (100)
#define POWERS_SY6970_VBAT_VOL_STEP (20)
#define POWERS_SY6970_VSYS_VOL_STEP (20)
#define POWERS_SY6970_NTC_VOL_STEP (0.465)
#define POWERS_SY6970_CHG_STEP_VAL (50)
#define POWERS_SY6970_PRE_CHG_CUR_BASE (64)
#define POWERS_SY6970_FAST_CHG_CUR_STEP (64)
#define POWERS_SY6970_PRE_CHG_CUR_STEP (64)
#define POWERS_SY6970_FAST_CHG_CURRENT_MAX (5056)
#define POWERS_SY6970_PRE_CHG_CURRENT_MIN (64)
#define POWERS_SY6970_PRE_CHG_CURRENT_MAX (1024)
#define POWERS_SY6970_CHG_VOL_BASE (3840)
#define POWERS_SY6970_CHG_VOL_STEP (16)
#define POWERS_SY6970_FAST_CHG_VOL_MIN (3840)
#define POWERS_SY6970_FAST_CHG_VOL_MAX (4608)
#define POWERS_SY6970_SYS_VOL_STEPS (100)
#define POWERS_SY6970_SYS_VOFF_VOL_MIN (3000)
#define POWERS_SY6970_SYS_VOFF_VOL_MAX (3700)
#define POWERS_SY6970_IN_CURRENT_STEP (50)
#define POWERS_SY6970_IN_CURRENT_MIN (100)
#define POWERS_SY6970_IN_CURRENT_MAX (3250)
#define POWERS_SY6970_BOOTS_VOL_BASE (4550)
#define POWERS_SY6970_BOOTS_VOL_STEP (64)
#define POWERS_SY6970_BOOST_VOL_MIN (4550)
#define POWERS_SY6970_BOOST_VOL_MAX (5510)
#define POWERS_SY6970_IRQ_WTD_FAULT(x) (bool)(( x & 0xFF ) >> 7)
#define POWERS_SY6970_IRQ_BOOST_FAULT(x) (bool)(( x & 0xFF ) >> 6)
#define POWERS_SY6970_IRQ_CHG_FAULT(x) (bool)(( x & 0xFF ) >> 5)
#define POWERS_SY6970_IRQ_BAT_FAULT(x) (bool)(( x & 0xFF ) >> 4)
#define POWERS_SY6970_IRQ_NTC_FAULT(x) (bool)(( x & 0xFF ) & 0x03)
#define POWERS_SY6970_VINDPM_VOL_BASE (4550)
#define POWERS_SY6970_VINDPM_VOL_STEPS (100)
#define POWERS_SY6970_VINDPM_VOL_MIN (3900)
#define POWERS_SY6970_VINDPM_VOL_MAX (15300)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,519 @@
/**
*
* @license 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.
*
* @file XPowersCommon.h
* @author Lewis He (lewishe@outlook.com)
* @date 2022-05-07
*
*/
#pragma once
#include <stdint.h>
#if defined(ARDUINO)
#include <Wire.h>
#elif defined(ESP_PLATFORM)
#include "esp_log.h"
#include "esp_err.h"
#include <cstring>
#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"
#define XPOWERSLIB_I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define XPOWERSLIB_I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define XPOWERSLIB_I2C_MASTER_TIMEOUT_MS 1000
#endif //ESP_IDF_VERSION
#endif //ESP_PLATFORM
#define XPOWERSLIB_I2C_MASTER_SPEED 400000
#ifdef _BV
#undef _BV
#endif
#define _BV(b) (1ULL << (uint64_t)(b))
#ifndef constrain
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
#endif
#define XPOWERS_ATTR_NOT_IMPLEMENTED __attribute__((error("Not implemented")))
#define IS_BIT_SET(val,mask) (((val)&(mask)) == (mask))
#if !defined(ARDUINO)
#ifdef linux
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define log_e(__info,...) printf("error :" __info,##__VA_ARGS__)
#define log_i(__info,...) printf("info :" __info,##__VA_ARGS__)
#define log_d(__info,...) printf("debug :" __info,##__VA_ARGS__)
#else
#define log_e(...)
#define log_i(...)
#define log_d(...)
#endif
#define LOW 0x0
#define HIGH 0x1
//GPIO FUNCTIONS
#define INPUT 0x01
#define OUTPUT 0x03
#define PULLUP 0x04
#define INPUT_PULLUP 0x05
#define PULLDOWN 0x08
#define INPUT_PULLDOWN 0x09
#define RISING 0x01
#define FALLING 0x02
#endif
#if defined(ARDUINO_ARCH_MBED) || defined(ARDUINO_ARCH_ZEPHYR)
#define log_e(...)
#define log_i(...)
#define log_d(...)
#endif
#ifndef ESP32
#ifdef LOG_FILE_LINE_INFO
#undef LOG_FILE_LINE_INFO
#endif
#define LOG_FILE_LINE_INFO __FILE__, __LINE__
#ifndef log_e
#define log_e(fmt, ...) Serial.printf("[E][%s:%d] " fmt "\n", LOG_FILE_LINE_INFO, ##__VA_ARGS__)
#endif
#ifndef log_i
#define log_i(fmt, ...) Serial.printf("[I][%s:%d] " fmt "\n", LOG_FILE_LINE_INFO, ##__VA_ARGS__)
#endif
#ifndef log_d
#define log_d(fmt, ...) Serial.printf("[D][%s:%d] " fmt "\n", LOG_FILE_LINE_INFO, ##__VA_ARGS__)
#endif
#endif
#if defined(NRF52840_XXAA) || defined(NRF52832_XXAA)
#ifndef SDA
#define SDA (0xFF)
#endif
#ifndef SCL
#define SCL (0xFF)
#endif
#endif
typedef int (*iic_fptr_t)(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len);
template <class chipType>
class XPowersCommon
{
public:
#if defined(ARDUINO)
bool begin(TwoWire &w, uint8_t addr, int sda, int scl)
{
if (__has_init)return thisChip().initImpl();
__has_init = true;
__sda = sda;
__scl = scl;
__wire = &w;
#if defined(NRF52840_XXAA) || defined(NRF52832_XXAA)
if (__sda != 0xFF && __scl != 0xFF) {
#if !defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_ARCH_ZEPHYR)
__wire->setPins(__sda, __scl);
#endif /* ARDUINO_ARCH_MBED || ZEPHYR */
}
__wire->begin();
#elif defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_STM32)
if (__sda != 0xFF && __scl != 0xFF) {
__wire->end();
__wire->setSDA(__sda);
__wire->setSCL(__scl);
}
__wire->begin();
#elif defined(ARDUINO_ARCH_ESP32)
__wire->begin(__sda, __scl);
#else
__wire->begin();
#endif
__addr = addr;
return thisChip().initImpl();
}
#elif defined(ESP_PLATFORM)
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_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.
bool begin(i2c_master_bus_handle_t i2c_dev_bus_handle, uint8_t addr)
{
log_i("Using ESP-IDF Driver interface.");
if (i2c_dev_bus_handle == NULL) return false;
if (__has_init)return thisChip().initImpl();
thisReadRegCallback = NULL;
thisWriteRegCallback = NULL;
/*
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 = port_num;
i2c_bus_config.scl_io_num = (gpio_num_t)__scl;
i2c_bus_config.sda_io_num = (gpio_num_t)__sda;
i2c_bus_config.glitch_ignore_cnt = 7;
i2c_new_master_bus(&i2c_bus_config, &bus_handle);
*/
bus_handle = i2c_dev_bus_handle;
i2c_device_config_t i2c_dev_conf = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = addr,
.scl_speed_hz = XPOWERSLIB_I2C_MASTER_SPEED,
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,3,0))
// New fields since esp-idf-v5.3-beta1
.scl_wait_us = 0,
.flags = {
. disable_ack_check = 0
}
#endif
};
if (ESP_OK != i2c_master_bus_add_device(bus_handle,
&i2c_dev_conf,
&__i2c_device)) {
return false;
}
__has_init = thisChip().initImpl();
if (!__has_init) {
// Initialization failed, delete device
i2c_master_bus_rm_device(__i2c_device);
}
return __has_init;
}
#else //ESP 4.X
bool begin(i2c_port_t port_num, uint8_t addr, int sda, int scl)
{
__i2c_num = port_num;
log_i("Using ESP-IDF Driver interface.");
if (__has_init)return thisChip().initImpl();
__sda = sda;
__scl = scl;
__addr = addr;
thisReadRegCallback = NULL;
thisWriteRegCallback = NULL;
i2c_config_t i2c_conf;
memset(&i2c_conf, 0, sizeof(i2c_conf));
i2c_conf.mode = I2C_MODE_MASTER;
i2c_conf.sda_io_num = sda;
i2c_conf.scl_io_num = scl;
i2c_conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
i2c_conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
i2c_conf.master.clk_speed = XPOWERSLIB_I2C_MASTER_SPEED;
/**
* @brief Without checking whether the initialization is successful,
* I2C may be initialized externally,
* so just make sure there is an initialization here.
*/
i2c_param_config(__i2c_num, &i2c_conf);
i2c_driver_install(__i2c_num,
i2c_conf.mode,
XPOWERSLIB_I2C_MASTER_RX_BUF_DISABLE,
XPOWERSLIB_I2C_MASTER_TX_BUF_DISABLE, 0);
__has_init = thisChip().initImpl();
return __has_init;
}
#endif //ESP 5.X
#endif //ESP_PLATFORM
bool begin(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback)
{
if (__has_init)return thisChip().initImpl();
__has_init = true;
thisReadRegCallback = readRegCallback;
thisWriteRegCallback = writeRegCallback;
__addr = addr;
return thisChip().initImpl();
}
int readRegister(uint8_t reg)
{
uint8_t val = 0;
return readRegister(reg, &val, 1) == -1 ? -1 : val;
}
int writeRegister(uint8_t reg, uint8_t val)
{
return writeRegister(reg, &val, 1);
}
int readRegister(uint8_t reg, uint8_t *buf, uint8_t length)
{
if (thisReadRegCallback) {
return thisReadRegCallback(__addr, reg, buf, length);
}
#if defined(ARDUINO)
if (__wire) {
__wire->beginTransmission(__addr);
__wire->write(reg);
if (__wire->endTransmission() != 0) {
return -1;
}
__wire->requestFrom(__addr, length);
return __wire->readBytes(buf, length) == length ? 0 : -1;
}
#elif defined(ESP_PLATFORM)
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
if (ESP_OK == i2c_master_transmit_receive(
__i2c_device,
(const uint8_t *)&reg,
1,
buf,
length,
-1)) {
return 0;
}
#else //ESP_IDF_VERSION
if (ESP_OK == i2c_master_write_read_device(__i2c_num,
__addr,
(uint8_t *)&reg,
1,
buf,
length,
XPOWERSLIB_I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS)) {
return 0;
}
#endif //ESP_IDF_VERSION
#endif //ESP_PLATFORM
return -1;
}
int writeRegister(uint8_t reg, uint8_t *buf, uint8_t length)
{
if (thisWriteRegCallback) {
return thisWriteRegCallback(__addr, reg, buf, length);
}
#if defined(ARDUINO)
if (__wire) {
__wire->beginTransmission(__addr);
__wire->write(reg);
__wire->write(buf, length);
return (__wire->endTransmission() == 0) ? 0 : -1;
}
return -1;
#elif defined(ESP_PLATFORM)
uint8_t *write_buffer = (uint8_t *)malloc(sizeof(uint8_t) * (length + 1));
if (!write_buffer) {
return -1;
}
write_buffer[0] = reg;
memcpy(write_buffer + 1, buf, length);
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
if (ESP_OK != i2c_master_transmit(
__i2c_device,
write_buffer,
length + 1,
-1)) {
free(write_buffer);
return -1;
}
#else //ESP_IDF_VERSION
if (ESP_OK != i2c_master_write_to_device(__i2c_num,
__addr,
write_buffer,
length + 1,
XPOWERSLIB_I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS)) {
free(write_buffer);
return -1;
}
#endif //ESP_IDF_VERSION
free(write_buffer);
return 0;
#endif //ESP_PLATFORM
}
bool inline clrRegisterBit(uint8_t registers, uint8_t bit)
{
int val = readRegister(registers);
if (val == -1) {
return false;
}
return writeRegister(registers, (val & (~_BV(bit)))) == 0;
}
bool inline setRegisterBit(uint8_t registers, uint8_t bit)
{
int val = readRegister(registers);
if (val == -1) {
return false;
}
return writeRegister(registers, (val | (_BV(bit)))) == 0;
}
bool inline getRegisterBit(uint8_t registers, uint8_t bit)
{
int val = readRegister(registers);
if (val == -1) {
return false;
}
return val & _BV(bit);
}
uint16_t inline readRegisterH8L4(uint8_t highReg, uint8_t lowReg)
{
int h8 = readRegister(highReg);
int l4 = readRegister(lowReg);
if (h8 == -1 || l4 == -1)return 0;
return (h8 << 4) | (l4 & 0x0F);
}
uint16_t inline readRegisterH8L5(uint8_t highReg, uint8_t lowReg)
{
int h8 = readRegister(highReg);
int l5 = readRegister(lowReg);
if (h8 == -1 || l5 == -1)return 0;
return (h8 << 5) | (l5 & 0x1F);
}
uint16_t inline readRegisterH6L8(uint8_t highReg, uint8_t lowReg)
{
int h6 = readRegister(highReg);
int l8 = readRegister(lowReg);
if (h6 == -1 || l8 == -1)return 0;
return ((h6 & 0x3F) << 8) | l8;
}
uint16_t inline readRegisterH5L8(uint8_t highReg, uint8_t lowReg)
{
int h5 = readRegister(highReg);
int l8 = readRegister(lowReg);
if (h5 == -1 || l8 == -1)return 0;
return ((h5 & 0x1F) << 8) | l8;
}
/*
* CRTP Helper
*/
protected:
bool begin()
{
#if defined(ARDUINO)
if (__has_init) return thisChip().initImpl();
__has_init = true;
if (__wire) {
log_i("SDA:%d SCL:%d", __sda, __scl);
#if defined(NRF52840_XXAA) || defined(NRF52832_XXAA)
if (__sda != 0xFF && __scl != 0xFF) {
#if !defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_ARCH_ZEPHYR)
__wire->setPins(__sda, __scl);
#endif /* ARDUINO_ARCH_MBED || ZEPHYR */
}
__wire->begin();
#elif defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_STM32)
if (__sda != 0xFF && __scl != 0xFF) {
__wire->end();
__wire->setSDA(__sda);
__wire->setSCL(__scl);
}
__wire->begin();
#elif defined(ARDUINO_ARCH_ESP32)
__wire->begin(__sda, __scl);
#else
__wire->begin();
#endif
}
#endif /*ARDUINO*/
return thisChip().initImpl();
}
void end()
{
#if defined(ARDUINO)
if (__wire) {
#if defined(ESP_IDF_VERSION)
#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(4,4,0)
__wire->end();
#endif /*ESP_IDF_VERSION*/
#endif /*ESP_IDF_VERSION*/
}
#endif /*ARDUINO*/
}
inline const chipType &thisChip() const
{
return static_cast<const chipType &>(*this);
}
inline chipType &thisChip()
{
return static_cast<chipType &>(*this);
}
protected:
bool __has_init = false;
#if defined(ARDUINO)
TwoWire *__wire = NULL;
#elif defined(ESP_PLATFORM)
i2c_port_t __i2c_num;
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
i2c_master_bus_handle_t bus_handle;
i2c_master_dev_handle_t __i2c_device;
#endif //ESP_IDF_VERSION
#endif //ESP_PLATFORM
int __sda = -1;
int __scl = -1;
uint8_t __addr = 0xFF;
iic_fptr_t thisReadRegCallback = NULL;
iic_fptr_t thisWriteRegCallback = NULL;
};

View File

@@ -0,0 +1,57 @@
/**
*
* @license 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.
*
* @file XPowersLib.h
* @author Lewis He (lewishe@outlook.com)
* @date 2024-10-30
*
*/
#pragma once
#if defined(XPOWERS_CHIP_AXP192)
#include "XPowersAXP192.tpp"
typedef XPowersAXP192 XPowersPMU;
#elif defined(XPOWERS_CHIP_AXP202)
#include "XPowersAXP202.tpp"
typedef XPowersAXP202 XPowersPMU;
#elif defined(XPOWERS_CHIP_AXP2101)
#include "XPowersAXP2101.tpp"
typedef XPowersAXP2101 XPowersPMU;
#elif defined(XPOWERS_CHIP_SY6970)
#include "PowersSY6970.tpp"
typedef PowersSY6970 XPowersPPM;
#elif defined(XPOWERS_CHIP_BQ25896)
#include "PowersBQ25896.tpp"
typedef PowersBQ25896 XPowersPPM;
#else
#include "XPowersAXP192.tpp"
#include "XPowersAXP202.tpp"
#include "XPowersAXP2101.tpp"
#include "PowersSY6970.tpp"
#endif
#include "PowerDeliveryHUSB238.hpp"
#include "XPowersLib_Version.h"

View File

@@ -0,0 +1,173 @@
/**
*
* @license 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.
*
* @file XPowersLibInterface.cpp
* @author Lewis He (lewishe@outlook.com)
* @date 2022-08-28
*
*/
#if defined(ARDUINO)
#include <Arduino.h>
#endif
#include "XPowersLibInterface.hpp"
bool XPowersLibInterface::isChannelAvailable(uint8_t channel)
{
if (__chipModel == XPOWERS_AXP192) {
switch (channel) {
case XPOWERS_DCDC1:
case XPOWERS_DCDC2:
case XPOWERS_DCDC3:
case XPOWERS_LDO2:
case XPOWERS_LDO3:
case XPOWERS_LDOIO:
return true;
default:
return false;
}
} else if (__chipModel == XPOWERS_AXP202) {
switch (channel) {
case XPOWERS_DCDC2:
case XPOWERS_DCDC3:
case XPOWERS_LDO2:
case XPOWERS_LDO3:
case XPOWERS_LDO4:
case XPOWERS_LDO5:
return true;
default:
return false;
}
} else if (__chipModel == XPOWERS_AXP2101) {
switch (channel) {
case XPOWERS_DCDC1:
case XPOWERS_DCDC2:
case XPOWERS_DCDC3:
case XPOWERS_DCDC4:
case XPOWERS_DCDC5:
case XPOWERS_ALDO1:
case XPOWERS_ALDO2:
case XPOWERS_ALDO3:
case XPOWERS_ALDO4:
case XPOWERS_BLDO1:
case XPOWERS_BLDO2:
case XPOWERS_VBACKUP:
case XPOWERS_CPULDO:
return true;
default:
// DLDO is not available, will also return false
return false;
}
}
return false;
}
void XPowersLibInterface::setProtectedChannel(uint8_t channel)
{
__protectedMask |= _BV(channel);
}
void XPowersLibInterface::setUnprotectChannel(uint8_t channel)
{
__protectedMask &= (~_BV(channel));
}
bool XPowersLibInterface::getProtectedChannel(uint8_t channel)
{
return __protectedMask & _BV(channel);
}
uint16_t XPowersLibInterface::getVbusVoltage()
{
return 0;
}
static uint64_t inline check_params(uint32_t opt, uint32_t params, uint64_t mask)
{
return ((opt & params) == params) ? mask : 0;
}
bool XPowersLibInterface::enableInterrupt(uint32_t option)
{
return setInterruptMask(option, true);
}
bool XPowersLibInterface::disableInterrupt(uint32_t option)
{
return setInterruptMask(option, false);
}
bool XPowersLibInterface::setInterruptMask(uint32_t option, bool enable)
{
uint64_t params = 0;
switch (__chipModel) {
case XPOWERS_AXP173:
break;
case XPOWERS_AXP192:
params |= check_params(option, XPOWERS_USB_INSERT_INT, XPOWERS_AXP192_VBUS_INSERT_IRQ);
params |= check_params(option, XPOWERS_USB_REMOVE_INT, XPOWERS_AXP192_VBUS_REMOVE_IRQ);
params |= check_params(option, XPOWERS_BATTERY_INSERT_INT, XPOWERS_AXP192_BAT_INSERT_IRQ);
params |= check_params(option, XPOWERS_BATTERY_REMOVE_INT, XPOWERS_AXP192_BAT_REMOVE_IRQ);
params |= check_params(option, XPOWERS_CHARGE_START_INT, XPOWERS_AXP192_BAT_CHG_START_IRQ);
params |= check_params(option, XPOWERS_CHARGE_DONE_INT, XPOWERS_AXP192_BAT_CHG_DONE_IRQ);
params |= check_params(option, XPOWERS_PWR_BTN_CLICK_INT, XPOWERS_AXP192_PKEY_SHORT_IRQ);
params |= check_params(option, XPOWERS_PWR_BTN_LONGPRESSED_INT, XPOWERS_AXP192_PKEY_LONG_IRQ);
params |= check_params(option, XPOWERS_ALL_INT, XPOWERS_AXP192_ALL_IRQ);
return enable ? enableIRQ(params) : disableIRQ(params);
break;
case XPOWERS_AXP202:
params |= check_params(option, XPOWERS_USB_INSERT_INT, XPOWERS_AXP202_VBUS_INSERT_IRQ);
params |= check_params(option, XPOWERS_USB_REMOVE_INT, XPOWERS_AXP202_VBUS_REMOVE_IRQ);
params |= check_params(option, XPOWERS_BATTERY_INSERT_INT, XPOWERS_AXP202_BAT_INSERT_IRQ);
params |= check_params(option, XPOWERS_BATTERY_REMOVE_INT, XPOWERS_AXP202_BAT_REMOVE_IRQ);
params |= check_params(option, XPOWERS_CHARGE_START_INT, XPOWERS_AXP202_BAT_CHG_START_IRQ);
params |= check_params(option, XPOWERS_CHARGE_DONE_INT, XPOWERS_AXP202_BAT_CHG_DONE_IRQ);
params |= check_params(option, XPOWERS_PWR_BTN_CLICK_INT, XPOWERS_AXP202_PKEY_SHORT_IRQ);
params |= check_params(option, XPOWERS_PWR_BTN_LONGPRESSED_INT, XPOWERS_AXP202_PKEY_LONG_IRQ);
params |= check_params(option, XPOWERS_ALL_INT, XPOWERS_AXP202_ALL_IRQ);
return enable ? enableIRQ(params) : disableIRQ(params);
break;
case XPOWERS_AXP216:
break;
case XPOWERS_AXP2101:
params |= check_params(option, XPOWERS_USB_INSERT_INT, XPOWERS_AXP2101_VBUS_INSERT_IRQ);
params |= check_params(option, XPOWERS_USB_REMOVE_INT, XPOWERS_AXP2101_VBUS_REMOVE_IRQ);
params |= check_params(option, XPOWERS_BATTERY_INSERT_INT, XPOWERS_AXP2101_BAT_INSERT_IRQ);
params |= check_params(option, XPOWERS_BATTERY_REMOVE_INT, XPOWERS_AXP2101_BAT_REMOVE_IRQ);
params |= check_params(option, XPOWERS_CHARGE_START_INT, XPOWERS_AXP2101_BAT_CHG_START_IRQ);
params |= check_params(option, XPOWERS_CHARGE_DONE_INT, XPOWERS_AXP2101_BAT_CHG_DONE_IRQ);
params |= check_params(option, XPOWERS_PWR_BTN_CLICK_INT, XPOWERS_AXP2101_PKEY_SHORT_IRQ);
params |= check_params(option, XPOWERS_PWR_BTN_LONGPRESSED_INT, XPOWERS_AXP2101_PKEY_LONG_IRQ);
params |= check_params(option, XPOWERS_ALL_INT, XPOWERS_AXP2101_ALL_IRQ);
return enable ? enableIRQ(params) : disableIRQ(params);
break;
default:
break;
}
return false;
}

View File

@@ -0,0 +1,670 @@
/**
*
* @license 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.
*
* @file XPowersLibInterface.hpp
* @author Lewis He (lewishe@outlook.com)
* @date 2022-08-28
*
*/
#pragma once
#include <stdint.h>
#include "XPowersParams.hpp"
/*
| CHIP | AXP173 | AXP192 | AXP202 | AXP2101 |
| ---------- | ----------------- | ----------------- | ----------------- | -------------------------------------- |
| DC1 | 0.7V-3.5V /1.2A | 0.7V-3.5V /1.2A | X | 1.5-3.4V /2A |
| DC2 | 0.7-2.275V/0.6A | 0.7-2.275V /1.6A | 0.7-2.275V /1.6A | 0.5-1.2V,1.22-1.54V /2A |
| DC3 | X | 0.7-3.5V /0.7A | 0.7-3.5V /1.2A | 0.5-1.2V,1.22-1.54V,1.6-3.4V /2A |
| DC4 | X | x | x | 0.5-1.2V,1.22-1.84V /1.5A |
| DC5 | X | x | x | 1.2V,1.4-3.7V /1A |
| LDO1(VRTC) | 3.3V /30mA | 3.3V /30mA | 3.3V /30mA | 1.8V /30mA |
| LDO2 | 1.8V-3.3V /200mA | 1.8V-3.3V /200mA | 1.8V-3.3V /200mA | x |
| LDO3 | 1.8V-3.3V /200mA | 1.8-3.3V /200mA | 0.7-3.5V /200mA | x |
| LDO4 | 0.7-3.5V /500mA | X | 1.8V-3.3V /200mA | x |
| LDO5/IO0 | X | 1.8-3.3V /50mA | 1.8-3.3V /50mA | x |
| ALDO1 | x | x | x | 0.5-3.5V /300mA |
| ALDO2 | x | x | x | 0.5-3.5V /300mA |
| ALDO3 | x | x | x | 0.5-3.5V /300mA |
| ALDO4 | x | x | x | 0.5-3.5V /300mA |
| BLDO1 | x | x | x | 0.5-3.5V /300mA |
| BLDO2 | x | x | x | 0.5-3.5V /300mA |
| DLDO1 | x | x | x | 0.5-3.3V/ 0.5-1.4V /300mA |
| DLDO1 | x | x | x | 0.5-3.3V/ 0.5-1.4V /300mA |
| CPUSLDO | x | x | x | 0.5-1.4V /30mA |
| | | | | |
*/
// @brief Each chip resource is different,please refer to the table above
typedef enum __XPowersPowerChannel {
XPOWERS_DCDC1,
XPOWERS_DCDC2,
XPOWERS_DCDC3,
XPOWERS_DCDC4,
XPOWERS_DCDC5,
XPOWERS_LDO1,
XPOWERS_LDO2,
XPOWERS_LDO3,
XPOWERS_LDO4,
XPOWERS_LDO5,
XPOWERS_LDOIO,
XPOWERS_ALDO1,
XPOWERS_ALDO2,
XPOWERS_ALDO3,
XPOWERS_ALDO4,
XPOWERS_BLDO1,
XPOWERS_BLDO2,
XPOWERS_DLDO1,
XPOWERS_DLDO2,
XPOWERS_VBACKUP,
XPOWERS_CPULDO,
} XPowersPowerChannel_t;
// @brief Chip type
typedef enum __XPowersChipModel {
XPOWERS_AXP173,
XPOWERS_AXP192,
XPOWERS_AXP202,
XPOWERS_AXP216,
XPOWERS_AXP2101,
XPOWERS_UNDEFINED,
} XPowersChipModel_t;
/**
* @brief Compatible with subclasses of the Meshtastic-devic project
*/
class HasBatteryLevel
{
public:
/**
* @brief Get battery percentage
* @retval 0~100% , -1 no battery is connected
*/
virtual int getBatteryPercent()
{
return -1;
}
/**
* @brief Get battery Voltage
* @retval Voltage unit: millivolt , 0 is no battery is connected
*/
virtual uint16_t getBattVoltage()
{
return 0;
}
/**
* @brief Query whether the current battery is connected
* @retval true to access,false to not access
*/
virtual bool isBatteryConnect()
{
return false;
}
/**
* @brief Query whether the current USB is connected
* @retval true to access,false to not access
*/
virtual bool isVbusIn()
{
return false;
}
/**
* @brief Query whether it is currently in charging state
* @retval true to charge,false to not charge
*/
virtual bool isCharging()
{
return false;
}
};
// @brief Power resource interface class
class XPowersLibInterface : public HasBatteryLevel
{
public:
XPowersLibInterface() : __chipModel(XPOWERS_UNDEFINED), __protectedMask(0) {};
virtual ~XPowersLibInterface() {}
/**
* @brief Calling the XPowersLibInterface interface class
* requires calling init for initialization
* @retval
*/
virtual bool init() = 0;
/**
* @brief When calling the XPowersLibInterface interface class,
* calling deinit releases the Wire handle
* @retval None
*/
virtual void deinit() = 0;
/**
* @brief Set the PMU sleep flag,
* need to manually close the power channel after setting
* @retval true success false failed
*/
virtual bool enableSleep() = 0;
/**
* @brief Set shutdown, calling shutdown will turn off all power channels,
* only VRTC belongs to normal power supply
* @retval None
*/
virtual void shutdown() = 0;
/**
* @brief Get PMU status register
* @note
* @retval register value
*/
virtual uint16_t status() = 0;
/**
* @brief Query chip ID
* @retval Chip ID
*/
virtual uint8_t getChipID() = 0;
//Status function
/**
* @brief Query whether it is currently in charging state
* @retval true to charge,false to not charge
*/
// virtual bool isCharging() = 0;
/**
* @brief Query whether the current USB is connected
* @retval true to access,false to not access
*/
// virtual bool isVbusIn() = 0;
/**
* @brief Query whether the current battery is connected
* @retval true to access,false to not access
*/
// virtual bool isBatteryConnect() = 0;
/**
* @brief Query whether the current is in the discharge state
* @retval true the battery is discharged,false is not discharged
*/
virtual bool isDischarge() = 0;
//Power Channel Control
/**
* @brief Turn on the power channel
* @param channel: Parameters See XPowersPowerChannel_t enumeration
* @retval true success false failed
*/
virtual bool enablePowerOutput(uint8_t channel) = 0;
/**
* @brief Turn off the power channel
* @param channel: Parameters See XPowersPowerChannel_t enumeration
* @retval true success false failed
*/
virtual bool disablePowerOutput(uint8_t channel) = 0;
/**
* @brief Get whether the power channel is enabled
* @param channel: Parameters See XPowersPowerChannel_t enumeration
* @retval true success false failed
*/
virtual bool isPowerChannelEnable(uint8_t channel) = 0;
/**
* @brief Get the set voltage of the power channel
* @param channel: Parameters See XPowersPowerChannel_t enumeration
* @retval true success false failed
*/
virtual uint16_t getPowerChannelVoltage(uint8_t channel) = 0;
/**
* @brief Set the output voltage of a channel power supply
* @param channel: Parameters See XPowersPowerChannel_t enumeration
* @retval true success false failed
*/
virtual bool setPowerChannelVoltage(uint8_t channel, uint16_t millivolt) = 0;
/**
* @brief Set a channel power protection,after setting this channel
* will not be able to be set and closed
* @param channel: Parameters See XPowersPowerChannel_t enumeration
*/
virtual void setProtectedChannel(uint8_t channel);
/**
* @brief Unprotect the channel, call this to unprotect the channel lock
* @param channel: Parameters See XPowersPowerChannel_t enumeration
*/
virtual void setUnprotectChannel(uint8_t channel);
/**
* * @brief Get whether a channel power supply has been protected
* @param channel: Parameters See XPowersPowerChannel_t enumeration
* @retval true is set,false is not set
*/
virtual bool getProtectedChannel(uint8_t channel);
/**
* @brief Query whether the PMU input parameter channel is valid
* @param channel: Parameters See XPowersPowerChannel_t enumeration
* @retval true valid false invalid
*/
virtual bool isChannelAvailable(uint8_t channel);
//battery
/**
* @brief Get battery Voltage
* @retval Voltage unit: millivolt , 0 is no battery is connected
*/
// virtual uint16_t getBattVoltage() = 0;
/**
* @brief Get battery percentage
* @retval 0~100% , -1 no battery is connected
*/
// virtual int getBatteryPercent(void);
// Vbus
/**
* @brief Get PMU VBUS/USB Voltage
* @retval Voltage unit: millivolt , 0 is no vbus is connected
*/
virtual uint16_t getVbusVoltage();
/**
* @brief Set VBUS Current Input Limit.
* @param opt: View the related chip type xpowers_axpxxx_vbus_cur_limit_t enumeration
* parameters in "XPowersParams.hpp"
* @retval true valid false invalid
*/
virtual bool setVbusCurrentLimit(uint8_t opt) = 0;
/**
* @brief Get VBUS Current Input Limit.
* @retval View the related chip type xpowers_axpxxx_vbus_cur_limit_t enumeration
* parameters in "XPowersParams.hpp"
*/
virtual uint8_t getVbusCurrentLimit(void) = 0;
/**
* @brief Set VBUS Voltage Input Limit.
* @param opt: View the related chip type xpowers_axpxxx_vbus_vol_limit_t enumeration
* parameters in "XPowersParams.hpp"
*
*/
virtual void setVbusVoltageLimit(uint8_t opt) = 0;
/**
* @brief Get VBUS Voltage Input Limit.
* @retval View the related chip type xpowers_axpxxx_vbus_vol_limit_t enumeration
* parameters in "XPowersParams.hpp"
*/
virtual uint8_t getVbusVoltageLimit(void) = 0;
// SYS
/**
* @brief Get PMU SYS main Voltage
* @retval Voltage unit: millivolt
*/
virtual uint16_t getSystemVoltage() = 0;
/**
* @brief Set PMU Low Voltage Shutdown Threshold
* @param millivolt: 2600mV ~ 3300mV
* @retval true valid false invalid
*/
virtual bool setSysPowerDownVoltage(uint16_t millivolt) = 0;
/**
* @brief Get PMU Low Voltage Shutdown Threshold
* @retval Voltage unit: millivolt
*/
virtual uint16_t getSysPowerDownVoltage() = 0;
/**
* @brief Set charge target voltage.
* @param opt: View the related chip type xpowers_axpxxx_chg_vol_t enumeration
* parameters in "XPowersParams.hpp"
* @retval true valid false invalid
*/
virtual bool setChargeTargetVoltage(uint8_t opt) = 0;
/**
* @brief Get charge target voltage.
* @retval View the related chip type xpowers_axpxxx_chg_vol_t enumeration
* parameters in "XPowersParams.hpp"
* parameters in "XPowersParams.hpp"
*/
virtual uint8_t getChargeTargetVoltage() = 0;
/**
* @brief Set charge current.
* @param opt: View the related chip type xpowers_axpxxx_chg_curr_t enumeration
* parameters in "XPowersParams.hpp"
* @retval true valid false invalid
*/
virtual bool setChargerConstantCurr(uint8_t opt) = 0;
/**
* @brief Get charge current.
* @retval View the related chip type xpowers_axpxxx_chg_curr_t enumeration
* parameters in "XPowersParams.hpp"
*/
virtual uint8_t getChargerConstantCurr() = 0;
//!PMU Interrupt control
/*
* Example of interrupt usage
* if (pmuInterrupt) {
* pmuInterrupt = false;
*
* Read interrupt status
* uint64_t mask = PMU->getIrqStatus();
* Serial.print("IRQ Mask:0b");
* Serial.println(mask,BIN);
*
* if (PMU->isPekeyShortPressIrq()) {
* Serial.println("isPekeyShortPressIrq");
* }
* if (PMU->isBatChargeStartIrq()) {
* Serial.println("isBatChargeStart");
* }
* ......
*
* After reading the interrupt status,you need to manually clear the status register
* PMU->clearIrqStatus();
* }
* * * */
/**
* @brief Get the interrupt controller mask value.
* @retval Mask value corresponds to xpowers_axpxxx_irq_t ,
*/
virtual uint64_t getIrqStatus() = 0;
/**
* @brief Clear interrupt controller state.
*/
virtual void clearIrqStatus() = 0;
/**
* @brief Enable PMU interrupt control mask .
* @param opt: View the related chip type xpowers_axpxxx_irq_t enumeration
* parameters in "XPowersParams.hpp"
* @retval true valid false invalid
*/
virtual bool enableIRQ(uint64_t opt) = 0;
/**
* @brief Disable PMU interrupt control mask .
* @param opt: View the related chip type xpowers_axpxxx_irq_t enumeration
* parameters in "XPowersParams.hpp"
* @retval true valid false invalid
*/
virtual bool disableIRQ(uint64_t opt) = 0;
/**
* @brief .
* @param opt: View the related chip type xpowers_interrupt_enum_t enumeration
* parameters in "XPowersParams.hpp"
* @retval true valid false invalid
*/
bool enableInterrupt(uint32_t opt);
/**
* @brief .
* @param opt: View the related chip type xpowers_interrupt_enum_t enumeration
* parameters in "XPowersParams.hpp"
* @retval true valid false invalid
*/
bool disableInterrupt(uint32_t opt);
/**
* @brief .
* @param opt: View the related chip type xpowers_interrupt_enum_t enumeration
* parameters in "XPowersParams.hpp"
* @retval true valid false invalid
*/
bool setInterruptMask(uint32_t option, bool enable);
/**
* @brief Interrupt response when PMU PEKEY is short pressed
* @retval true valid false invalid
*/
virtual bool isPekeyShortPressIrq() = 0;
/**
* @brief Interrupt response when PMU PEKEY is long pressed
* @retval true valid false invalid
*/
virtual bool isPekeyLongPressIrq() = 0;
/**
* @brief Interrupt response when PMU battery is connected
* @retval true valid false invalid
*/
virtual bool isBatInsertIrq() = 0;
/**
* @brief Interrupt response when PMU battery is removed
* @retval true valid false invalid
*/
virtual bool isBatRemoveIrq() = 0;
/**
* @brief Interrupt response when PMU USB is plugged in
* @retval true valid false invalid
*/
virtual bool isVbusInsertIrq() = 0;
/**
* @brief Interrupt response when PMU USB is removed
* @retval true valid false invalid
*/
virtual bool isVbusRemoveIrq() = 0;
/**
* @brief Interrupt response when PMU charging is complete
* @retval true valid false invalid
*/
virtual bool isBatChargeDoneIrq() = 0;
/**
* @brief Interrupt response when PMU charging starts
* @retval true valid false invalid
*/
virtual bool isBatChargeStartIrq() = 0;
//Data collection function
/**
* @brief Enable battery detection function,the default is on
* @retval true success false failed
*/
virtual bool enableBattDetection() = 0;
/**
* @brief Disable battery detection
* @retval true success false failed
*/
virtual bool disableBattDetection() = 0;
/**
* @brief Enable USB input voltage detection
* @retval true success false failed
*/
virtual bool enableVbusVoltageMeasure(void) = 0;
/**
* @brief Disable USB input voltage detection
* @retval true success false failed
*/
virtual bool disableVbusVoltageMeasure(void) = 0;
/**
* @brief Enable system voltage detection
* @retval true success false failed
*/
virtual bool enableSystemVoltageMeasure(void) = 0;
/**
* @brief Disable system voltage detection
* @retval true success false failed
*/
virtual bool disableSystemVoltageMeasure(void) = 0;
/**
* @brief Enable PMU internal temperature sensor detection
* @retval true success false failed
*/
virtual bool enableTemperatureMeasure(void) = 0;
/**
* @brief Disable PMU internal temperature sensor detection
* @retval true success false failed
*/
virtual bool disableTemperatureMeasure(void) = 0;
/**
* @brief Enable battery input voltage detection
* @retval true success false failed
*/
virtual bool enableBattVoltageMeasure(void) = 0;
/**
* @brief Disable battery input voltage detection
* @retval true success false failed
*/
virtual bool disableBattVoltageMeasure(void) = 0;
/**
* @brief Enable NTC thermistor detection (requires hardware support)
* @retval true success false failed
*/
virtual bool enableTSPinMeasure(void) = 0;
/**
* @brief Disable NTC thermistor detection (requires hardware support)
* @retval true success false failed
*/
virtual bool disableTSPinMeasure(void) = 0;
// Charge indicator function
/**
* @brief Set charging led mode
* @param opt: View the related chip type xpowers_chg_led_mode_t enumeration
* parameters in "XPowersParams.hpp"
*/
virtual void setChargingLedMode(uint8_t mode) = 0;
// PMU PEKEY settings
/**
* @brief Set PEKEY press power on time
* @param opt: View the related chip type xpowers_press_on_time_t enumeration
* parameters in "XPowersParams.hpp"
* @retval true success false failed
*/
virtual bool setPowerKeyPressOnTime(uint8_t opt) = 0;
/**
* @brief Get PEKEY press power on time
* @retval View the related chip type xpowers_press_on_time_t enumeration
* parameters in "XPowersParams.hpp"
*/
virtual uint8_t getPowerKeyPressOnTime() = 0;
/**
* @brief Set PEKEY press power off time
* @param opt: View the related chip type xpowers_press_off_time_t enumeration
* parameters in "XPowersParams.hpp"
* @retval true success false failed
*/
virtual bool setPowerKeyPressOffTime(uint8_t opt) = 0;
/**
* @brief Get PEKEY press power off time
* @retval View the related chip type xpowers_press_off_time_t enumeration
* parameters in "XPowersParams.hpp"
*/
virtual uint8_t getPowerKeyPressOffTime() = 0;
/**
* @brief Get the chip model
* @retval See XPowersChipModel_t enumeration
*/
uint8_t getChipModel()
{
return __chipModel;
}
protected:
void setChipModel(uint8_t m)
{
__chipModel = m;
}
uint8_t __chipModel;
uint32_t __protectedMask;
};

View File

@@ -0,0 +1,54 @@
/**
*
* @license 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.
*
* @file XPowersLib_Version.h
* @author Lewis He (lewishe@outlook.com)
* @date 2024-12-12
*
*/
#pragma once
/** Major version number (X.x.x) */
#define XPOWERSLIB_VERSION_MAJOR 0
/** Minor version number (x.X.x) */
#define XPOWERSLIB_VERSION_MINOR 2
/** Patch version number (x.x.X) */
#define XPOWERSLIB_VERSION_PATCH 7
/**
* Macro to convert XPowersLib version number into an integer
*
* To be used in comparisons, such as XPOWERSLIB_VERSION >= XPOWERSLIB_VERSION_VAL(2, 0, 0)
*/
#define XPOWERSLIB_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
/**
* Current XPowersLib version, as an integer
*
* To be used in comparisons, such as XPOWERSLIB_VERSION >= XPOWERSLIB_VERSION_VAL(2, 0, 0)
*/
#define XPOWERSLIB_VERSION XPOWERSLIB_VERSION_VAL(XPOWERSLIB_VERSION_MAJOR, \
XPOWERSLIB_VERSION_MINOR, \
XPOWERSLIB_VERSION_PATCH)

View File

@@ -0,0 +1,444 @@
/**
*
* @license 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.
*
* @file XPowersParams.hpp
* @author Lewis He (lewishe@outlook.com)
* @date 2022-08-28
*
*/
#pragma once
#ifdef _BV
#undef _BV
#endif
#define _BV(b) (1ULL << (uint64_t)(b))
//TODO:Unified interface functions and parameters
/**
* @brief PMU PEKEY Press off time parameters.
*/
typedef enum __xpowers_press_off_time {
XPOWERS_POWEROFF_4S,
XPOWERS_POWEROFF_6S,
XPOWERS_POWEROFF_8S,
XPOWERS_POWEROFF_10S,
} xpowers_press_off_time_t;
/**
* @brief PMU PEKEY Press on time parameters.
*/
typedef enum __xpowers_press_on_time {
XPOWERS_POWERON_128MS,
XPOWERS_POWERON_512MS,
XPOWERS_POWERON_1S,
XPOWERS_POWERON_2S,
} xpowers_press_on_time_t;
/**
* @brief Charging led mode parameters.
*/
typedef enum __xpowers_chg_led_mode {
XPOWERS_CHG_LED_OFF,
XPOWERS_CHG_LED_BLINK_1HZ,
XPOWERS_CHG_LED_BLINK_4HZ,
XPOWERS_CHG_LED_ON,
XPOWERS_CHG_LED_CTRL_CHG, // The charging indicator is controlled by the charger
} xpowers_chg_led_mode_t;
/**
* @brief axp2101 charge target voltage parameters.
*/
typedef enum __xpowers_axp2101_chg_vol {
XPOWERS_AXP2101_CHG_VOL_4V = 1,
XPOWERS_AXP2101_CHG_VOL_4V1,
XPOWERS_AXP2101_CHG_VOL_4V2,
XPOWERS_AXP2101_CHG_VOL_4V35,
XPOWERS_AXP2101_CHG_VOL_4V4,
XPOWERS_AXP2101_CHG_VOL_MAX
} xpowers_axp2101_chg_vol_t;
/**
* @brief axp2101 charge currnet voltage parameters.
*/
typedef enum __xpowers_axp2101_chg_curr {
XPOWERS_AXP2101_CHG_CUR_0MA,
XPOWERS_AXP2101_CHG_CUR_100MA = 4,
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,
} xpowers_axp2101_chg_curr_t;
/**
* @brief axp192 charge target voltage parameters.
*/
typedef enum __xpowers_axp192_chg_vol {
XPOWERS_AXP192_CHG_VOL_4V1,
XPOWERS_AXP192_CHG_VOL_4V15,
XPOWERS_AXP192_CHG_VOL_4V2,
XPOWERS_AXP192_CHG_VOL_4V36,
XPOWERS_AXP192_CHG_VOL_MAX,
} xpowers_axp192_chg_vol_t;
/**
* @brief axp202 charge target voltage parameters.
*/
typedef enum __xpowers_axp202_chg_vol {
XPOWERS_AXP202_CHG_VOL_4V1,
XPOWERS_AXP202_CHG_VOL_4V15,
XPOWERS_AXP202_CHG_VOL_4V2,
XPOWERS_AXP202_CHG_VOL_4V36,
XPOWERS_AXP202_CHG_VOL_MAX,
} xpowers_axp202_chg_vol_t;
/**
* @brief axp192 charge currnet voltage parameters.
*/
typedef enum __xpowers_axp192_chg_curr {
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,
} xpowers_axp192_chg_curr_t;
/**
* @brief axp202 charge currnet voltage parameters.
*/
typedef enum __xpowers_axp202_chg_curr {
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,
} xpowers_axp202_chg_curr_t;
/**
* @brief axp2101 vbus currnet limit parameters.
*/
typedef enum {
XPOWERS_AXP2101_VBUS_CUR_LIM_100MA,
XPOWERS_AXP2101_VBUS_CUR_LIM_500MA,
XPOWERS_AXP2101_VBUS_CUR_LIM_900MA,
XPOWERS_AXP2101_VBUS_CUR_LIM_1000MA,
XPOWERS_AXP2101_VBUS_CUR_LIM_1500MA,
XPOWERS_AXP2101_VBUS_CUR_LIM_2000MA,
} xpowers_axp2101_vbus_cur_limit_t;
/**
* @brief axp192 vbus currnet limit parameters.
*/
typedef enum {
XPOWERS_AXP192_VBUS_CUR_LIM_500MA,
XPOWERS_AXP192_VBUS_CUR_LIM_100MA,
XPOWERS_AXP192_VBUS_CUR_LIM_OFF,
} xpowers_axp192_vbus_cur_limit_t;
/**
* @brief axp202 vbus currnet limit parameters.
*/
typedef enum {
XPOWERS_AXP202_VBUS_CUR_LIM_900MA,
XPOWERS_AXP202_VBUS_CUR_LIM_500MA,
XPOWERS_AXP202_VBUS_CUR_LIM_100MA,
XPOWERS_AXP202_VBUS_CUR_LIM_OFF,
} xpowers_axp202_vbus_cur_limit_t;
typedef enum {
XPOWERS_AXP192_VBUS_VOL_LIM_4V,
XPOWERS_AXP192_VBUS_VOL_LIM_4V1,
XPOWERS_AXP192_VBUS_VOL_LIM_4V2,
XPOWERS_AXP192_VBUS_VOL_LIM_4V3,
XPOWERS_AXP192_VBUS_VOL_LIM_4V4,
XPOWERS_AXP192_VBUS_VOL_LIM_4V5,
XPOWERS_AXP192_VBUS_VOL_LIM_4V6,
XPOWERS_AXP192_VBUS_VOL_LIM_4V7,
} xpowers_axp192_vbus_vol_limit_t;
typedef enum {
XPOWERS_AXP202_VBUS_VOL_LIM_4V,
XPOWERS_AXP202_VBUS_VOL_LIM_4V1,
XPOWERS_AXP202_VBUS_VOL_LIM_4V2,
XPOWERS_AXP202_VBUS_VOL_LIM_4V3,
XPOWERS_AXP202_VBUS_VOL_LIM_4V4,
XPOWERS_AXP202_VBUS_VOL_LIM_4V5,
XPOWERS_AXP202_VBUS_VOL_LIM_4V6,
XPOWERS_AXP202_VBUS_VOL_LIM_4V7,
} xpowers_axp202_vbus_vol_limit_t;
typedef enum {
XPOWERS_AXP2101_VBUS_VOL_LIM_3V88,
XPOWERS_AXP2101_VBUS_VOL_LIM_3V96,
XPOWERS_AXP2101_VBUS_VOL_LIM_4V04,
XPOWERS_AXP2101_VBUS_VOL_LIM_4V12,
XPOWERS_AXP2101_VBUS_VOL_LIM_4V20,
XPOWERS_AXP2101_VBUS_VOL_LIM_4V28,
XPOWERS_AXP2101_VBUS_VOL_LIM_4V36,
XPOWERS_AXP2101_VBUS_VOL_LIM_4V44,
XPOWERS_AXP2101_VBUS_VOL_LIM_4V52,
XPOWERS_AXP2101_VBUS_VOL_LIM_4V60,
XPOWERS_AXP2101_VBUS_VOL_LIM_4V68,
XPOWERS_AXP2101_VBUS_VOL_LIM_4V76,
XPOWERS_AXP2101_VBUS_VOL_LIM_4V84,
XPOWERS_AXP2101_VBUS_VOL_LIM_4V92,
XPOWERS_AXP2101_VBUS_VOL_LIM_5V,
XPOWERS_AXP2101_VBUS_VOL_LIM_5V08,
} xpower_apx2101_vbus_vol_limit_t;
/**
* @brief XPowersLibInterface interrupt control mask parameters.
* Common interrupt interfaces
* @Example: enableInterrupt(XPOWERS_USB_INSERT_INT|XPOWERS_USB_REMOVE_INT);
* disableInterrupt(XPOWERS_CHARGE_START_INT|XPOWERS_PWR_BTN_CLICK_INT);
*/
typedef enum __xpowers_interrupt_enum {
XPOWERS_USB_INSERT_INT = _BV(0),
XPOWERS_USB_REMOVE_INT = _BV(1),
XPOWERS_BATTERY_INSERT_INT = _BV(2),
XPOWERS_BATTERY_REMOVE_INT = _BV(3),
XPOWERS_CHARGE_START_INT = _BV(4),
XPOWERS_CHARGE_DONE_INT = _BV(5),
XPOWERS_PWR_BTN_CLICK_INT = _BV(6),
XPOWERS_PWR_BTN_LONGPRESSED_INT = _BV(7),
XPOWERS_ALL_INT = _BV(8),
} xpowers_interrupt_enum_t;
/**
* @brief axp192 interrupt control mask parameters.
*/
typedef enum __xpowers_axp192_irq {
//! IRQ1 REG 40H
XPOWERS_AXP192_VBUS_VHOLD_LOW_IRQ = _BV(1), //VBUS is available, but lower than V HOLD, IRQ enable
XPOWERS_AXP192_VBUS_REMOVE_IRQ = _BV(2), //VBUS removed, IRQ enable
XPOWERS_AXP192_VBUS_INSERT_IRQ = _BV(3), //VBUS connected, IRQ enable
XPOWERS_AXP192_VBUS_OVER_VOL_IRQ = _BV(4), //VBUS over-voltage, IRQ enable
XPOWERS_AXP192_ACIN_REMOVED_IRQ = _BV(5), //ACIN removed, IRQ enable
XPOWERS_AXP192_ACIN_CONNECT_IRQ = _BV(6), //ACIN connected, IRQ enable
XPOWERS_AXP192_ACIN_OVER_VOL_IRQ = _BV(7), //ACIN over-voltage, IRQ enable
//! IRQ2 REG 41H
XPOWERS_AXP192_BATT_LOW_TEMP_IRQ = _BV(8), //Battery low-temperature, IRQ enable
XPOWERS_AXP192_BATT_OVER_TEMP_IRQ = _BV(9), //Battery over-temperature, IRQ enable
XPOWERS_AXP192_BAT_CHG_DONE_IRQ = _BV(10), //Charge finished, IRQ enable
XPOWERS_AXP192_BAT_CHG_START_IRQ = _BV(11), //Be charging, IRQ enable
XPOWERS_AXP192_BATT_EXIT_ACTIVATE_IRQ = _BV(12), //Exit battery activate mode, IRQ enable
XPOWERS_AXP192_BATT_ACTIVATE_IRQ = _BV(13), //Battery activate mode, IRQ enable
XPOWERS_AXP192_BAT_REMOVE_IRQ = _BV(14), //Battery removed, IRQ enable
XPOWERS_AXP192_BAT_INSERT_IRQ = _BV(15), //Battery connected, IRQ enable
//! IRQ3 REG 42H
XPOWERS_AXP192_PKEY_LONG_IRQ = _BV(16), //PEK long press, IRQ enable
XPOWERS_AXP192_PKEY_SHORT_IRQ = _BV(17), //PEK short press, IRQ enable
//**Reserved and unchangeable BIT 2
XPOWERS_AXP192_DC3_LOW_VOL_IRQ = _BV(19), //DC-DC3output voltage is lower than the set value, IRQ enable
XPOWERS_AXP192_DC2_LOW_VOL_IRQ = _BV(20), //DC-DC2 output voltage is lower than the set value, IRQ enable
XPOWERS_AXP192_DC1_LOW_VOL_IRQ = _BV(21), //DC-DC1 output voltage is lower than the set value, IRQ enable
XPOWERS_AXP192_CHARGE_LOW_CUR_IRQ = _BV(22), //Charge current is lower than the set current, IRQ enable
XPOWERS_AXP192_CHIP_TEMP_HIGH_IRQ = _BV(23), //XPOWERS internal over-temperature, IRQ enable
//! IRQ4 REG 43H
XPOWERS_AXP192_APS_LOW_VOL_LEVEL_IRQ = _BV(24), //APS low-voltage, IRQ enable
//**Reserved and unchangeable BIT 1
XPOWERS_AXP192_VBUS_SESSION_END_IRQ = _BV(26), //VBUS Session End IRQ enable
XPOWERS_AXP192_VBUS_SESSION_AB_IRQ = _BV(27), //VBUS Session A/B IRQ enable
XPOWERS_AXP192_VBUS_INVALID_IRQ = _BV(28), //VBUS invalid, IRQ enable
XPOWERS_AXP192_VBUS_VAILD_IRQ = _BV(29), //VBUS valid, IRQ enable
XPOWERS_AXP192_NOE_OFF_IRQ = _BV(30), //N_OE shutdown, IRQ enable
XPOWERS_AXP192_NOE_ON_IRQ = _BV(31), //N_OE startup, IRQ enable
//! IRQ5 REG 4AH
XPOWERS_AXP192_GPIO0_EDGE_TRIGGER_IRQ = _BV(32), //GPIO0 input edge trigger, IRQ enable
XPOWERS_AXP192_GPIO1_EDGE_TRIGGER_IRQ = _BV(33), //GPIO1input edge trigger or ADC input, IRQ enable
XPOWERS_AXP192_GPIO2_EDGE_TRIGGER_IRQ = _BV(34), //GPIO2input edge trigger, IRQ enable
//**Reserved and unchangeable BIT 3
//**Reserved and unchangeable BIT 4
//**Reserved and unchangeable BIT 5
//**Reserved and unchangeable BIT 6
XPOWERS_AXP192_TIMER_TIMEOUT_IRQ = _BV(39), //Timer timeout, IRQ enable
XPOWERS_AXP192_ALL_IRQ = (0xFFFFFFFFFFULL)
} xpowers_axp192_irq_t;
/**
* @brief axp2101 interrupt control mask parameters.
*/
typedef enum __xpowers_axp2101_irq {
//! IRQ1 REG 40H
XPOWERS_AXP2101_BAT_NOR_UNDER_TEMP_IRQ = _BV(0), // Battery Under Temperature in Work
XPOWERS_AXP2101_BAT_NOR_OVER_TEMP_IRQ = _BV(1), // Battery Over Temperature in Work mode
XPOWERS_AXP2101_BAT_CHG_UNDER_TEMP_IRQ = _BV(2), // Battery Under Temperature in Charge mode IRQ(bcut_irq)
XPOWERS_AXP2101_BAT_CHG_OVER_TEMP_IRQ = _BV(3), // Battery Over Temperature in Charge mode IRQ(bcot_irq) enable
XPOWERS_AXP2101_GAUGE_NEW_SOC_IRQ = _BV(4), // Gauge New SOC IRQ(lowsoc_irq) enable ???
XPOWERS_AXP2101_WDT_TIMEOUT_IRQ = _BV(5), // Gauge Watchdog Timeout IRQ(gwdt_irq) enable
XPOWERS_AXP2101_WARNING_LEVEL1_IRQ = _BV(6), // SOC drop to Warning Level1 IRQ(socwl1_irq) enable
XPOWERS_AXP2101_WARNING_LEVEL2_IRQ = _BV(7), // SOC drop to Warning Level2 IRQ(socwl2_irq) enable
//! IRQ2 REG 41H
XPOWERS_AXP2101_PKEY_POSITIVE_IRQ = _BV(8), // POWERON Positive Edge IRQ(ponpe_irq_en) enable
XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ = _BV(9), // POWERON Negative Edge IRQ(ponne_irq_en) enable
XPOWERS_AXP2101_PKEY_LONG_IRQ = _BV(10), // POWERON Long PRESS IRQ(ponlp_irq) enable
XPOWERS_AXP2101_PKEY_SHORT_IRQ = _BV(11), // POWERON Short PRESS IRQ(ponsp_irq_en) enable
XPOWERS_AXP2101_BAT_REMOVE_IRQ = _BV(12), // Battery Remove IRQ(bremove_irq) enable
XPOWERS_AXP2101_BAT_INSERT_IRQ = _BV(13), // Battery Insert IRQ(binsert_irq) enabl
XPOWERS_AXP2101_VBUS_REMOVE_IRQ = _BV(14), // VBUS Remove IRQ(vremove_irq) enabl
XPOWERS_AXP2101_VBUS_INSERT_IRQ = _BV(15), // VBUS Insert IRQ(vinsert_irq) enable
//! IRQ3 REG 42H
XPOWERS_AXP2101_BAT_OVER_VOL_IRQ = _BV(16), // Battery Over Voltage Protection IRQ(bovp_irq) enable
XPOWERS_AXP2101_CHAGER_TIMER_IRQ = _BV(17), // Charger Safety Timer1/2 expire IRQ(chgte_irq) enable
XPOWERS_AXP2101_DIE_OVER_TEMP_IRQ = _BV(18), // DIE Over Temperature level1 IRQ(dotl1_irq) enable
XPOWERS_AXP2101_BAT_CHG_START_IRQ = _BV(19), // Charger start IRQ(chgst_irq) enable
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ = _BV(20), // Battery charge done IRQ(chgdn_irq) enable
XPOWERS_AXP2101_BATFET_OVER_CURR_IRQ = _BV(21), // BATFET Over Current Protection IRQ(bocp_irq) enable
XPOWERS_AXP2101_LDO_OVER_CURR_IRQ = _BV(22), // LDO Over Current IRQ(ldooc_irq) enable
XPOWERS_AXP2101_WDT_EXPIRE_IRQ = _BV(23), // Watchdog Expire IRQ(wdexp_irq) enable
XPOWERS_AXP2101_ALL_IRQ = (0xFFFFFFFFUL)
} xpowers_axp2101_irq_t;
/**
* @brief axp202 interrupt control mask parameters.
*/
typedef enum __xpowers_axp202_irq {
//! IRQ1 REG 40H
XPOWERS_AXP202_VBUS_VHOLD_LOW_IRQ = _BV(1), //VBUS is available, but lower than V HOLD, IRQ enable
XPOWERS_AXP202_VBUS_REMOVE_IRQ = _BV(2), //VBUS removed, IRQ enable
XPOWERS_AXP202_VBUS_INSERT_IRQ = _BV(3), //VBUS connected, IRQ enable
XPOWERS_AXP202_VBUS_OVER_VOL_IRQ = _BV(4), //VBUS over-voltage, IRQ enable
XPOWERS_AXP202_ACIN_REMOVED_IRQ = _BV(5), //ACIN removed, IRQ enable
XPOWERS_AXP202_ACIN_CONNECT_IRQ = _BV(6), //ACIN connected, IRQ enable
XPOWERS_AXP202_ACIN_OVER_VOL_IRQ = _BV(7), //ACIN over-voltage, IRQ enable
//! IRQ2 REG 41H
XPOWERS_AXP202_BATT_LOW_TEMP_IRQ = _BV(8), //Battery low-temperature, IRQ enable
XPOWERS_AXP202_BATT_OVER_TEMP_IRQ = _BV(9), //Battery over-temperature, IRQ enable
XPOWERS_AXP202_BAT_CHG_DONE_IRQ = _BV(10), //Charge finished, IRQ enable
XPOWERS_AXP202_BAT_CHG_START_IRQ = _BV(11), //Be charging, IRQ enable
XPOWERS_AXP202_BATT_EXIT_ACTIVATE_IRQ = _BV(12), //Exit battery activate mode, IRQ enable
XPOWERS_AXP202_BATT_ACTIVATE_IRQ = _BV(13), //Battery activate mode, IRQ enable
XPOWERS_AXP202_BAT_REMOVE_IRQ = _BV(14), //Battery removed, IRQ enable
XPOWERS_AXP202_BAT_INSERT_IRQ = _BV(15), //Battery connected, IRQ enable
//! IRQ3 REG 42H
XPOWERS_AXP202_PKEY_LONG_IRQ = _BV(16), //PEK long press, IRQ enable
XPOWERS_AXP202_PKEY_SHORT_IRQ = _BV(17), //PEK short press, IRQ enable
XPOWERS_AXP202_LDO3_LOW_VOL_IRQ = _BV(18), //LDO3output voltage is lower than the set value, IRQ enable
XPOWERS_AXP202_DC3_LOW_VOL_IRQ = _BV(19), //DC-DC3output voltage is lower than the set value, IRQ enable
XPOWERS_AXP202_DC2_LOW_VOL_IRQ = _BV(20), //DC-DC2 output voltage is lower than the set value, IRQ enable
//**Reserved and unchangeable BIT 5
XPOWERS_AXP202_CHARGE_LOW_CUR_IRQ = _BV(22), //Charge current is lower than the set current, IRQ enable
XPOWERS_AXP202_CHIP_TEMP_HIGH_IRQ = _BV(23), //AXP202 internal over-temperature, IRQ enable
//! IRQ4 REG 43H
XPOWERS_AXP202_APS_LOW_VOL_LEVEL2_IRQ = _BV(24), //APS low-voltage, IRQ enableLEVEL2
XPOWERS_APX202_APS_LOW_VOL_LEVEL1_IRQ = _BV(25), //APS low-voltage, IRQ enableLEVEL1
XPOWERS_AXP202_VBUS_SESSION_END_IRQ = _BV(26), //VBUS Session End IRQ enable
XPOWERS_AXP202_VBUS_SESSION_AB_IRQ = _BV(27), //VBUS Session A/B IRQ enable
XPOWERS_AXP202_VBUS_INVALID_IRQ = _BV(28), //VBUS invalid, IRQ enable
XPOWERS_AXP202_VBUS_VAILD_IRQ = _BV(29), //VBUS valid, IRQ enable
XPOWERS_AXP202_NOE_OFF_IRQ = _BV(30), //N_OE shutdown, IRQ enable
XPOWERS_AXP202_NOE_ON_IRQ = _BV(31), //N_OE startup, IRQ enable
//! IRQ5 REG 44H
XPOWERS_AXP202_GPIO0_EDGE_TRIGGER_IRQ = _BV(32), //GPIO0 input edge trigger, IRQ enable
XPOWERS_AXP202_GPIO1_EDGE_TRIGGER_IRQ = _BV(33), //GPIO1input edge trigger or ADC input, IRQ enable
XPOWERS_AXP202_GPIO2_EDGE_TRIGGER_IRQ = _BV(34), //GPIO2input edge trigger, IRQ enable
XPOWERS_AXP202_GPIO3_EDGE_TRIGGER_IRQ = _BV(35), //GPIO3 input edge trigger, IRQ enable
//**Reserved and unchangeable BIT 4
XPOWERS_AXP202_PKEY_NEGATIVE_IRQ = _BV(37), //PEK press falling edge, IRQ enable
XPOWERS_AXP202_PKEY_POSITIVE_IRQ = _BV(38), //PEK press rising edge, IRQ enable
XPOWERS_AXP202_TIMER_TIMEOUT_IRQ = _BV(39), //Timer timeout, IRQ enable
XPOWERS_AXP202_ALL_IRQ = (0xFFFFFFFFFFULL)
} xpowers_axp202_irq_t;

View File

@@ -0,0 +1,55 @@
cd ../../
pwd
examples=($(find examples/* -maxdepth 1 -type d -printf "%f\n" | grep -E "^(SY6970|BQ25896)"))
# examples=($(find examples/* -maxdepth 1 -type d -printf "%f\n" | awk '/^ESP_IDF/ {next} ;/^main/ {next} ;!/Linux$/'))
# echo "Filtered directories:"
# for example in "${examples[@]}"; do
# echo "$example"
# done
# exit
envs=(
# "esp32s3"
"nrf52840"
)
pio run -t clean
for env in ${envs[@]}
do
for value in ${examples[@]}
do
if [ -f "$value/.skip."$env ];then
echo "Skip" $value
continue
fi
export PLATFORMIO_SRC_DIR="examples/$value"
export PLATFORMIO_BUILD_FLAGS="-D XPOWERS_NO_ERROR"
echo "PLATFORMIO_SRC_DIR=$PLATFORMIO_SRC_DIR , ENV: $env"
pio run -e $env
if [ $? -ne 0 ]; then
echo "Build env: $env $PLATFORMIO_SRC_DIR Failed!"
exit -1
else
echo "Build env: $env $PLATFORMIO_SRC_DIR Successed!"
fi
done
done
echo "Build directories:"
for example in "${examples[@]}"; do
echo "$example"
done