From a2d9fd0f6a6f9ac0d138dd58c92385d869662d3e Mon Sep 17 00:00:00 2001 From: 916BGAI <916772719@qq.com> Date: Thu, 15 Aug 2024 15:59:27 +0800 Subject: [PATCH 1/3] Reverse cst7xx touchscreen posx and posy --- .../dts_riscv/sg2002_licheervnano_sd.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/boards/sg200x/sg2002_licheervnano_sd/dts_riscv/sg2002_licheervnano_sd.dts b/build/boards/sg200x/sg2002_licheervnano_sd/dts_riscv/sg2002_licheervnano_sd.dts index da5e5d7a5..5af42d75a 100644 --- a/build/boards/sg200x/sg2002_licheervnano_sd/dts_riscv/sg2002_licheervnano_sd.dts +++ b/build/boards/sg200x/sg2002_licheervnano_sd/dts_riscv/sg2002_licheervnano_sd.dts @@ -129,8 +129,8 @@ display-coords = <0 0 480 640>; hynitron,display-coords = <368 552>; pos-swap = <0>; - posx-reverse = <0>; - posy-reverse = <0>; + posx-reverse = <1>; + posy-reverse = <1>; status = "okay"; }; }; From ebfa11ffba6ec3c297eac8b13d22c9d26841afd9 Mon Sep 17 00:00:00 2001 From: 916BGAI <916772719@qq.com> Date: Thu, 15 Aug 2024 16:32:37 +0800 Subject: [PATCH 2/3] Add AXP2101 PMU support --- .../cvitek/SG200X/overlay/etc/init.d/S99pmu | 13 + .../configs/cvitek_SG200X_32bit_defconfig | 2 + .../cvitek_SG200X_musl_riscv64_defconfig | 2 + buildroot/package/Config.in | 1 + buildroot/package/axp2101/Config.in | 5 + buildroot/package/axp2101/axp2101.mk | 20 + buildroot/package/axp2101/src/Makefile | 28 + .../src/XPowersLib/PowerDeliveryHUSB238.hpp | 171 + .../axp2101/src/XPowersLib/PowersSY6970.tpp | 1009 ++++++ .../src/XPowersLib/REG/AXP192Constants.h | 182 + .../src/XPowersLib/REG/AXP202Constants.h | 192 + .../src/XPowersLib/REG/AXP2101Constants.h | 242 ++ .../src/XPowersLib/REG/AXP216Constants.h | 95 + .../src/XPowersLib/REG/HUSB238Constants.h | 45 + .../src/XPowersLib/REG/SY6970Constants.h | 126 + .../axp2101/src/XPowersLib/XPowersAXP192.tpp | 2087 +++++++++++ .../axp2101/src/XPowersLib/XPowersAXP202.tpp | 1704 +++++++++ .../axp2101/src/XPowersLib/XPowersAXP2101.tpp | 3084 +++++++++++++++++ .../axp2101/src/XPowersLib/XPowersCommon.tpp | 512 +++ .../axp2101/src/XPowersLib/XPowersLib.h | 37 + .../src/XPowersLib/XPowersLibInterface.cpp | 173 + .../src/XPowersLib/XPowersLibInterface.hpp | 654 ++++ .../axp2101/src/XPowersLib/XPowersParams.hpp | 399 +++ buildroot/package/axp2101/src/include/main.h | 3 + buildroot/package/axp2101/src/src/main.cpp | 241 ++ 25 files changed, 11027 insertions(+) create mode 100755 buildroot/board/cvitek/SG200X/overlay/etc/init.d/S99pmu create mode 100644 buildroot/package/axp2101/Config.in create mode 100644 buildroot/package/axp2101/axp2101.mk create mode 100644 buildroot/package/axp2101/src/Makefile create mode 100644 buildroot/package/axp2101/src/XPowersLib/PowerDeliveryHUSB238.hpp create mode 100644 buildroot/package/axp2101/src/XPowersLib/PowersSY6970.tpp create mode 100644 buildroot/package/axp2101/src/XPowersLib/REG/AXP192Constants.h create mode 100644 buildroot/package/axp2101/src/XPowersLib/REG/AXP202Constants.h create mode 100644 buildroot/package/axp2101/src/XPowersLib/REG/AXP2101Constants.h create mode 100644 buildroot/package/axp2101/src/XPowersLib/REG/AXP216Constants.h create mode 100644 buildroot/package/axp2101/src/XPowersLib/REG/HUSB238Constants.h create mode 100644 buildroot/package/axp2101/src/XPowersLib/REG/SY6970Constants.h create mode 100644 buildroot/package/axp2101/src/XPowersLib/XPowersAXP192.tpp create mode 100644 buildroot/package/axp2101/src/XPowersLib/XPowersAXP202.tpp create mode 100644 buildroot/package/axp2101/src/XPowersLib/XPowersAXP2101.tpp create mode 100644 buildroot/package/axp2101/src/XPowersLib/XPowersCommon.tpp create mode 100644 buildroot/package/axp2101/src/XPowersLib/XPowersLib.h create mode 100644 buildroot/package/axp2101/src/XPowersLib/XPowersLibInterface.cpp create mode 100644 buildroot/package/axp2101/src/XPowersLib/XPowersLibInterface.hpp create mode 100644 buildroot/package/axp2101/src/XPowersLib/XPowersParams.hpp create mode 100644 buildroot/package/axp2101/src/include/main.h create mode 100644 buildroot/package/axp2101/src/src/main.cpp diff --git a/buildroot/board/cvitek/SG200X/overlay/etc/init.d/S99pmu b/buildroot/board/cvitek/SG200X/overlay/etc/init.d/S99pmu new file mode 100755 index 000000000..d36b26518 --- /dev/null +++ b/buildroot/board/cvitek/SG200X/overlay/etc/init.d/S99pmu @@ -0,0 +1,13 @@ +#!/bin/sh + +if [ "$1" = "start" ] +then + . /etc/profile + panel_value=$(grep '^panel=' /boot/uEnv.txt | cut -d '=' -f 2) + if [ "$panel_value" = "MaixCam_Pro" ] + then + echo "init axp2101 pmu" + exec /usr/bin/axp2101 + fi + exit 0 +fi diff --git a/buildroot/configs/cvitek_SG200X_32bit_defconfig b/buildroot/configs/cvitek_SG200X_32bit_defconfig index a264f4d7f..abea1f64b 100644 --- a/buildroot/configs/cvitek_SG200X_32bit_defconfig +++ b/buildroot/configs/cvitek_SG200X_32bit_defconfig @@ -389,6 +389,8 @@ BR2_PACKAGE_PYTHON_INTELHEX=y BR2_PACKAGE_VIM=y BR2_PACKAGE_VIM_RUNTIME=y +BR2_PACKAGE_AXP2101=y + BR2_TARGET_ROOTFS_EXT2=y BR2_TARGET_ROOTFS_EXT2_4=y BR2_TARGET_ROOTFS_EXT2_SIZE="900M" diff --git a/buildroot/configs/cvitek_SG200X_musl_riscv64_defconfig b/buildroot/configs/cvitek_SG200X_musl_riscv64_defconfig index 5449bfe16..9b68cf510 100644 --- a/buildroot/configs/cvitek_SG200X_musl_riscv64_defconfig +++ b/buildroot/configs/cvitek_SG200X_musl_riscv64_defconfig @@ -594,6 +594,8 @@ BR2_PACKAGE_PYTHON_ZEROCONF=y BR2_PACKAGE_VIM=y BR2_PACKAGE_VIM_RUNTIME=y +BR2_PACKAGE_AXP2101=y + BR2_TARGET_ROOTFS_EXT2=y BR2_TARGET_ROOTFS_EXT2_4=y BR2_TARGET_ROOTFS_EXT2_SIZE="900M" diff --git a/buildroot/package/Config.in b/buildroot/package/Config.in index cdef51d09..c15ccc803 100644 --- a/buildroot/package/Config.in +++ b/buildroot/package/Config.in @@ -2680,6 +2680,7 @@ menu "System tools" source "package/atop/Config.in" source "package/attr/Config.in" source "package/audit/Config.in" + source "package/axp2101/Config.in" source "package/balena-engine/Config.in" source "package/bubblewrap/Config.in" source "package/cgroupfs-mount/Config.in" diff --git a/buildroot/package/axp2101/Config.in b/buildroot/package/axp2101/Config.in new file mode 100644 index 000000000..cec73e27b --- /dev/null +++ b/buildroot/package/axp2101/Config.in @@ -0,0 +1,5 @@ +config BR2_PACKAGE_AXP2101 + bool "axp2101" + help + If you say Y here you get support for the X-Powers AXP2101 power + management ICs (PMICs) controlled with I2C. diff --git a/buildroot/package/axp2101/axp2101.mk b/buildroot/package/axp2101/axp2101.mk new file mode 100644 index 000000000..ec2e0cc1d --- /dev/null +++ b/buildroot/package/axp2101/axp2101.mk @@ -0,0 +1,20 @@ +################################################################################ +# +# axp2101 +# +################################################################################ + +AXP2101_VERSION = 1.0.0 +AXP2101_SITE = $(TOPDIR)/package/axp2101/src +AXP2101_SITE_METHOD = local +AXP2101_CFLAGS = -Iinclude -IXPowersLib -IXPowersLib/REG -Wall -Wextra + +define AXP2101_BUILD_CMDS + $(MAKE) $(TARGET_CONFIGURE_OPTS) CFLAGS="$(AXP2101_CFLAGS)" -C $(@D) +endef + +define AXP2101_INSTALL_TARGET_CMDS + $(INSTALL) -D -m 0755 $(@D)/axp2101 $(TARGET_DIR)/usr/bin/axp2101 +endef + +$(eval $(generic-package)) diff --git a/buildroot/package/axp2101/src/Makefile b/buildroot/package/axp2101/src/Makefile new file mode 100644 index 000000000..a584795df --- /dev/null +++ b/buildroot/package/axp2101/src/Makefile @@ -0,0 +1,28 @@ +APP_DIR = ./src +SRC_DIR = ./XPowersLib +DIR_BIN = ./bin + +OBJ_C = $(wildcard ${SRC_DIR}/*.cpp ${APP_DIR}/*.cpp) +OBJ_O = $(patsubst %.cpp,${DIR_BIN}/%.o,$(notdir ${OBJ_C})) + +TARGET = axp2101 + +DEBUG = -DXPOWERS_NO_ERROR + +$(shell mkdir -p $(DIR_BIN)) + +MSG = -g -O0 -Wall +CFLAGS += $(MSG) $(DEBUG) + +${TARGET}:${OBJ_O} + $(CXX) $(CFLAGS) $(OBJ_O) -o $@ $(LIB) + +${DIR_BIN}/%.o:$(APP_DIR)/%.cpp + $(CXX) $(CFLAGS) -c $< -o $@ -I $(SRC_DIR) + +${DIR_BIN}/%.o:$(SRC_DIR)/%.cpp + $(CXX) $(CFLAGS) -c $< -o $@ $(LIB) + +clean : + rm $(DIR_BIN)/*.* + rm $(TARGET) diff --git a/buildroot/package/axp2101/src/XPowersLib/PowerDeliveryHUSB238.hpp b/buildroot/package/axp2101/src/XPowersLib/PowerDeliveryHUSB238.hpp new file mode 100644 index 000000000..2caf1d7e1 --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/PowerDeliveryHUSB238.hpp @@ -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 +#else +#include +#endif /*ARDUINO*/ +#include "XPowersCommon.tpp" +#include "REG/HUSB238Constants.h" + +class PowerDeliveryHUSB238 : + public XPowersCommon +{ + friend class XPowersCommon; + +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(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; + } + +}; + + + diff --git a/buildroot/package/axp2101/src/XPowersLib/PowersSY6970.tpp b/buildroot/package/axp2101/src/XPowersLib/PowersSY6970.tpp new file mode 100644 index 000000000..f99a96ab8 --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/PowersSY6970.tpp @@ -0,0 +1,1009 @@ +/** + * + * @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 +#else +#include +#endif /*ARDUINO*/ +#include "XPowersCommon.tpp" +#include "REG/SY6970Constants.h" +// #include "XPowersLibInterface.hpp" + +enum PowersSY6970BusStatus { + POWERS_SY_NOINPUT, + POWERS_SY_USB_SDP, + POWERS_SY_USB_CDP, + POWERS_SY_USB_DCP, + POWERS_SY_HVDCP, + POWERS_SY_UNKONW_ADAPTER, + POWERS_SY_NO_STANDARD_ADAPTER, + POWERS_SY_OTG +} ; + +enum PowersSY6970ChargeStatus { + POWERS_SY_NO_CHARGE, + POWERS_SY_PRE_CHARGE, + POWERS_SY_FAST_CHARGE, + POWERS_SY_CHARGE_DONE, + POWERS_SY_CHARGE_UNKOWN, +} ; + +enum PowersSY6970NTCStatus { + POWERS_SY_BUCK_NTC_NORMAL = 0, + POWERS_SY_BUCK_NTC_WARM = 2, + POWERS_SY_BUCK_NTC_COOL = 3, + POWERS_SY_BUCK_NTC_COLD = 5, + POWERS_SY_BUCK_NTC_HOT = 6, +}; + +enum PowersSY6970BoostNTCStatus { + POWERS_SY_BOOST_NTC_NORMAL = 0, + POWERS_SY_BOOST_NTC_COLD = 5, + POWERS_SY_BOOST_NTC_HOT = 6, +}; + +enum SY6970_WDT_Timeout { + SY6970_WDT_TIMEROUT_40SEC, //40 Second + SY6970_WDT_TIMEROUT_80SEC, //80 Second + SY6970_WDT_TIMEROUT_160SEC, //160 Second +} ; + +enum ADCMeasure { + SY6970_ADC_ONE_SHORT, + SY6970_ADC_CONTINUOUS, +}; + +enum BoostFreq { + SY6970_BOOST_FREQ_1500KHZ, + SY6970_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, +} ; + +class PowersSY6970 : + public XPowersCommon //, public XPowersLibInterface +{ + friend class XPowersCommon; + +public: + + +#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 + + uint8_t getChipID() + { + int res = readRegister(POWERS_SY6970_REG_14H); + return (res & 0x03); + } + + void resetDefault() + { + setRegisterBit(POWERS_SY6970_REG_14H, 7); + } + + bool init() + { + return begin(); + } + + void deinit() + { + end(); + } + + ///REG0B + bool isVbusIn() + { + return getBusStatus() != POWERS_SY_NOINPUT; + } + + bool isOTG() + { + return getBusStatus() == POWERS_SY_OTG; + } + + bool isCharging(void) + { + return chargeStatus() != POWERS_SY_NO_CHARGE; + } + + bool isChargeDone() + { + return chargeStatus() != POWERS_SY_CHARGE_DONE; + } + + bool isBatteryConnect(void) __attribute__((error("Not implemented"))) + { + //TODO: + return false; + } + + bool isPowerGood() + { + return getRegisterBit(POWERS_SY6970_REG_0BH, 2); + } + + bool isEnableCharge() + { + return getRegisterBit(POWERS_SY6970_REG_03H, 4); + } + + void disableCharge() + { + __user_disable_charge = true; + clrRegisterBit(POWERS_SY6970_REG_03H, 4); + } + + void enableCharge() + { + __user_disable_charge = false; + setRegisterBit(POWERS_SY6970_REG_03H, 4); + } + + bool isEnableOTG() + { + return getRegisterBit(POWERS_SY6970_REG_03H, 5); + } + + void disableOTG() + { + clrRegisterBit(POWERS_SY6970_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_SY6970_REG_03H, 4); + } + } + + bool enableOTG() + { + if (isVbusIn()) + return false; + return setRegisterBit(POWERS_SY6970_REG_03H, 5); + } + + void feedWatchdog() + { + setRegisterBit(POWERS_SY6970_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_SY6970_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_SY6970_REG_03H, val); + + } + + uint16_t getSysPowerDownVoltage() + { + int val = readRegister(POWERS_SY6970_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_SY6970_REG_07H, 7); + } + + // Charging Termination Enable + void disableChargingTermination() + { + clrRegisterBit(POWERS_SY6970_REG_07H, 7); + } + + // Charging Termination Enable + bool isEnableChargingTermination() + { + return getRegisterBit(POWERS_SY6970_REG_07H, 7); + } + + void disableStatLed() + { + setRegisterBit(POWERS_SY6970_REG_07H, 6); + } + + void enableStatLed() + { + clrRegisterBit(POWERS_SY6970_REG_07H, 6); + } + + bool isEnableStatLed() + { + return getRegisterBit(POWERS_SY6970_REG_07H, 6) == false; + } + + void disableWatchdog() + { + int regVal = readRegister(POWERS_SY6970_REG_07H); + regVal &= 0xCF; + writeRegister(POWERS_SY6970_REG_07H, regVal); + } + + void enableWatchdog(enum SY6970_WDT_Timeout val = SY6970_WDT_TIMEROUT_40SEC ) + { + int regVal = readRegister(POWERS_SY6970_REG_07H); + regVal &= 0xCF; + switch (val) { + case SY6970_WDT_TIMEROUT_40SEC: + writeRegister(POWERS_SY6970_REG_07H, regVal | 0x10); + break; + case SY6970_WDT_TIMEROUT_80SEC: + writeRegister(POWERS_SY6970_REG_07H, regVal | 0x20); + break; + case SY6970_WDT_TIMEROUT_160SEC: + writeRegister(POWERS_SY6970_REG_07H, regVal | 0x30); + break; + default: + break; + } + } + + + void disableChargingSafetyTimer() + { + clrRegisterBit(POWERS_SY6970_REG_07H, 3); + } + + void enableChargingSafetyTimer() + { + setRegisterBit(POWERS_SY6970_REG_07H, 3); + } + + bool isEnableChargingSafetyTimer() + { + return getRegisterBit(POWERS_SY6970_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_SY6970_REG_07H); + if (val == -1) + return; + val &= 0xF1; + val |= (timer << 1); + writeRegister(POWERS_SY6970_REG_07H, val); + break; + default: + break; + } + } + + FastChargeTimer getFastChargeTimer() + { + int val = readRegister(POWERS_SY6970_REG_07H); + return static_cast((val & 0x0E) >> 1); + } + + // Return Battery Load status + bool isEnableBatLoad() + { + return getRegisterBit(POWERS_SY6970_REG_03H, 7); + } + + // Battery Load (10mA) Disable + void disableBatLoad() + { + clrRegisterBit(POWERS_SY6970_REG_03H, 7); + } + + // Battery Load (10mA) Enable + void enableBatLoad() + { + setRegisterBit(POWERS_SY6970_REG_03H, 7); + } + + PowersSY6970BusStatus getBusStatus() + { + int val = readRegister(POWERS_SY6970_REG_0BH); + return (PowersSY6970BusStatus)((val >> 5) & 0x07); + } + + const char *getBusStatusString() + { + PowersSY6970BusStatus status = getBusStatus(); + switch (status) { + case POWERS_SY_NOINPUT: + return "No input"; + case POWERS_SY_USB_SDP: + return "USB Host SDP"; + case POWERS_SY_USB_CDP: + return "USB CDP"; + case POWERS_SY_USB_DCP: + return "USB DCP"; + case POWERS_SY_HVDCP: + return "HVDCP"; + case POWERS_SY_UNKONW_ADAPTER: + return "Unknown Adapter"; + case POWERS_SY_NO_STANDARD_ADAPTER: + return "Non-Standard Adapter"; + case POWERS_SY_OTG: + return "OTG"; + default: + return "Unknown"; + } + } + + PowersSY6970ChargeStatus chargeStatus() + { + int val = readRegister(POWERS_SY6970_REG_0BH); + if (val == -1)return POWERS_SY_CHARGE_UNKOWN; + PowersSY6970ChargeStatus status = (PowersSY6970ChargeStatus)((val >> 3) & 0x03); + + /* + * Directly obtaining the register cannot produce accurate results. + * Add check to determine whether there is charging current to determine whether it is in the charging state. + * */ + if (getChargeCurrent() > 0 && status != POWERS_SY_NO_CHARGE) { + return status; + } + return POWERS_SY_NO_CHARGE; + } + + const char *getChargeStatusString() + { + PowersSY6970ChargeStatus status = chargeStatus(); + switch (status) { + case POWERS_SY_NO_CHARGE: + return "Not Charging"; + case POWERS_SY_PRE_CHARGE: + return "Pre-charge"; + case POWERS_SY_FAST_CHARGE: + return "Fast Charging"; + case POWERS_SY_CHARGE_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 POWERS_SY_BOOST_NTC_NORMAL: + return "Boost mode NTC normal"; + case POWERS_SY_BOOST_NTC_COLD: + return "Boost mode NTC cold"; + case POWERS_SY_BOOST_NTC_HOT: + return "Boost mode NTC hot"; + default: + break; + } + } else { + // Buck mode + switch (status) { + case POWERS_SY_BUCK_NTC_NORMAL: + return "Buck mode NTC normal"; + case POWERS_SY_BUCK_NTC_WARM: + return "Buck mode NTC warm"; + case POWERS_SY_BUCK_NTC_COOL: + case POWERS_SY_BUCK_NTC_COLD: + return "Buck mode NTC cold"; + case POWERS_SY_BUCK_NTC_HOT: + return "Buck mode NTC hot"; + default: + break; + } + } + return "Unknown"; + } + + bool enableADCMeasure(ADCMeasure mode = SY6970_ADC_CONTINUOUS) + { + int val = readRegister(POWERS_SY6970_REG_02H); + switch (mode) { + case SY6970_ADC_CONTINUOUS: + val |= _BV(6); + break; + case SY6970_ADC_ONE_SHORT: + default: + break; + } + val |= _BV(7); + return writeRegister(POWERS_SY6970_REG_02H, val) != -1; + } + + bool disableADCMeasure() + { + int val = readRegister(POWERS_SY6970_REG_02H); + if (val == -1) { + return false; + } + val &= (~_BV(7)); + return writeRegister(POWERS_SY6970_REG_02H, val) != 1; + } + + bool setBoostFreq(BoostFreq freq) + { + switch (freq) { + case SY6970_BOOST_FREQ_500KHZ: + return setRegisterBit(POWERS_SY6970_REG_02H, 5); + case SY6970_BOOST_FREQ_1500KHZ: + return clrRegisterBit(POWERS_SY6970_REG_02H, 5); + default: + break; + } + return false; + } + + BoostFreq getBoostFreq() + { + return getRegisterBit(POWERS_SY6970_REG_02H, 5) ? SY6970_BOOST_FREQ_500KHZ : SY6970_BOOST_FREQ_1500KHZ; + } + + void enableInputCurrentLimit() + { + setRegisterBit(POWERS_SY6970_REG_02H, 4); + } + + void disableInputCurrentLimit() + { + clrRegisterBit(POWERS_SY6970_REG_02H, 4); + } + + void enableHVDCP() + { + setRegisterBit(POWERS_SY6970_REG_02H, 3); + } + + void disableHVDCP() + { + clrRegisterBit(POWERS_SY6970_REG_02H, 3); + } + + bool isEnableHVDCP() + { + return getRegisterBit(POWERS_SY6970_REG_02H, 3); + } + + void setHighVoltageRequestedRange(RequestRange range) + { + switch (range) { + case REQUEST_9V: + clrRegisterBit(POWERS_SY6970_REG_02H, 2); + break; + case REQUEST_12V: + setRegisterBit(POWERS_SY6970_REG_02H, 2); + break; + default: + break; + } + } + + RequestRange getHighVoltageRequestedRange() + { + return getRegisterBit(POWERS_SY6970_REG_02H, 2) ? REQUEST_12V : REQUEST_9V; + } + + // Enable Force DP/DM detection + void enableDetectionDPDM() + { + setRegisterBit(POWERS_SY6970_REG_02H, 1); + } + + // Disable Force DP/DM detection + void disableDetectionDPDM() + { + clrRegisterBit(POWERS_SY6970_REG_02H, 1); + } + + // Get Force DP/DM detection + bool isEnableDetectionDPDM() + { + return getRegisterBit(POWERS_SY6970_REG_02H, 1); + } + + // Enable DPDM detection when BUS is plugged-in. + void enableAutoDetectionDPDM() + { + setRegisterBit(POWERS_SY6970_REG_02H, 0); + } + + // Disable DPDM detection when BUS is plugged-in. + void disableAutoDetectionDPDM() + { + clrRegisterBit(POWERS_SY6970_REG_02H, 0); + } + + // Get DPDM detection when BUS is plugged-in. + bool isEnableAutoDetectionDPDM() + { + return getRegisterBit(POWERS_SY6970_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_SY6970_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_SY6970_REG_00H, val) != -1; + } + + uint32_t getInputCurrentLimit() + { + int val = readRegister(POWERS_SY6970_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 enableHIZ() + { + setRegisterBit(POWERS_SY6970_REG_00H, 7); + } + + void disableHIZ() + { + clrRegisterBit(POWERS_SY6970_REG_00H, 7); + } + + bool isHIZ() + { + return getRegisterBit(POWERS_SY6970_REG_00H, 7); + } + + void enableCurrentLimitPin() + { + setRegisterBit(POWERS_SY6970_REG_00H, 6); + } + + void disableCurrentLimitPin() + { + clrRegisterBit(POWERS_SY6970_REG_00H, 6); + } + + bool isEnableCurrentLimitPin() + { + return getRegisterBit(POWERS_SY6970_REG_00H, 6); + } + + uint16_t getVbusVoltage() + { + if (!isVbusIn()) { + return 0; + } + int val = readRegister(POWERS_SY6970_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_SY6970_REG_0EH); + val = POWERS_SY6970_VBAT_MASK_VAL(val); + if (val == 0)return 0; + /* + * Directly obtaining the register cannot produce accurate results. + * Adding check to determine whether there is charging current determines whether there is a battery. + * */ + if (getChargeCurrent() != 0) { + return (val * POWERS_SY6970_VBAT_VOL_STEP) + POWERS_SY6970_VBAT_BASE_VAL; + } + return 0; + } + + uint16_t getSystemVoltage() + { + int val = readRegister(POWERS_SY6970_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_SY6970_REG_10H); + return (POWERS_SY6970_NTC_MASK_VAL(val) * POWERS_SY6970_NTC_VOL_STEP) + POWERS_SY6970_NTC_BASE_VAL; + } + + uint16_t getChargeCurrent() + { + int val = readRegister(POWERS_SY6970_REG_12H); + if (val == 0)return 0; + val = (val & 0x7F); + return (val * POWERS_SY6970_CHG_STEP_VAL) ; + + } + + // Range: 64mA ~ 1024mA ,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_PRE_CHG_CURRENT_MIN) { + milliampere = POWERS_PRE_CHG_CURRENT_MIN; + } + if (milliampere > POWERS_PRE_CHG_CURRENT_MAX) { + milliampere = POWERS_PRE_CHG_CURRENT_MAX; + } + int val = readRegister(POWERS_SY6970_REG_05H); + val &= 0x0F; + milliampere = ((milliampere - POWERS_SY6970_PRE_CHG_CUR_BASE) / POWERS_SY6970_PRE_CHG_CUR_STEP); + val |= milliampere << 4; + return writeRegister(POWERS_SY6970_REG_05H, val) != -1; + } + + uint16_t getPrechargeCurr(void) + { + int val = readRegister(POWERS_SY6970_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_SY6970_REG_04H); + val &= 0x7F; + return val * POWERS_SY6970_FAST_CHG_CUR_STEP; + } + + // Range:0~5056mA ,step:64mA + 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_FAST_CHG_CURRENT_MAX) { + milliampere = POWERS_FAST_CHG_CURRENT_MAX; + } + + int val = readRegister(POWERS_SY6970_REG_04H); + val &= 0x80; + val |= (milliampere / POWERS_SY6970_FAST_CHG_CUR_STEP); + return writeRegister(POWERS_SY6970_REG_04H, val) != -1; + } + + uint16_t getChargeTargetVoltage() + { + int val = readRegister(POWERS_SY6970_REG_06H); + val = (val & 0xFC) >> 2; + if (val > 0x30) { + return POWERS_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_FAST_CHG_VOL_MIN) { + millivolt = POWERS_FAST_CHG_VOL_MIN; + } + if (millivolt > POWERS_FAST_CHG_VOL_MAX) { + millivolt = POWERS_FAST_CHG_VOL_MAX; + } + int val = readRegister(POWERS_SY6970_REG_06H); + val &= 0x03; + val |= (((millivolt - POWERS_SY6970_CHG_VOL_BASE) / POWERS_SY6970_CHG_VOL_STEP) << 2); + return writeRegister(POWERS_SY6970_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. + void shutdown() + { + disableBATFET(); + } + + // Close battery power path + void disableBATFET() + { + setRegisterBit(POWERS_SY6970_REG_09H, 5); //Force BATFET Off : BATFET_DIS + } + + // Enable battery power path + void enableBATFET() + { + clrRegisterBit(POWERS_SY6970_REG_09H, 5); //Force BATFET Off : BATFET_DIS + } + + // Boost Mode Voltage Regulation: 4550mV ~ 5510mV + 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_SY6970_REG_0AH); + val &= 0x03; + val |= (((millivolt - POWERS_SY6970_BOOTS_VOL_BASE) / POWERS_SY6970_BOOTS_VOL_STEP) << 2); + return writeRegister(POWERS_SY6970_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_SY6970_REG_0AH); + val &= 0x03; + val |= milliampere; + return writeRegister(POWERS_SY6970_REG_0AH, val) != -1; + } + + uint64_t getIrqStatus(void) + { + int val = readRegister(POWERS_SY6970_REG_0CH); + if (val == -1) { + return 0; + } + __irq_mask = val; + + val = readRegister(POWERS_SY6970_REG_0BH); + if (val == -1) { + return 0; + } + __irq_mask |= ((val >> 7) & 0x1) << 8; + return __irq_mask; + } + + void getReadOnlyRegisterValue() + { +#ifdef ARDUINO //debug .. + static uint8_t last_val[8] = {0}; + const uint8_t regis[] = { + POWERS_SY6970_REG_0BH, + POWERS_SY6970_REG_0CH, + // POWERS_SY6970_REG_0EH, //BATTERY VOLTAGE + // POWERS_SY6970_REG_0FH, //SYSTEM VOLTAGE + // POWERS_SY6970_REG_10H, //NTC PERCENTAGE + // POWERS_SY6970_REG_11H, //VBUS VOLTAGE + POWERS_SY6970_REG_12H, + POWERS_SY6970_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); + } + + // True: In VSYSMIN regulation (BATVSYSMIN) + bool isVsysLowVoltageWarning() + { + uint8_t tmp = __irq_mask >> 8; + return (bool)(tmp & 0x01); + } + + 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_SY6970_REG_0DH); + val &= 0x80; + val |= (((millivolt - POWERS_SY6970_VINDPM_VOL_BASE) / POWERS_SY6970_VINDPM_VOL_STEPS)); + return writeRegister(POWERS_SY6970_REG_0DH, val) != -1; + } + + +private: + + bool initImpl() + { + __user_disable_charge = false; + + uint8_t rev = getChipID(); + if (rev != SY6970_DEV_REV && rev != BQ25896_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; +}; + + + +typedef PowersSY6970 XPowersPPM; diff --git a/buildroot/package/axp2101/src/XPowersLib/REG/AXP192Constants.h b/buildroot/package/axp2101/src/XPowersLib/REG/AXP192Constants.h new file mode 100644 index 000000000..c6f2a76ed --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/REG/AXP192Constants.h @@ -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) \ No newline at end of file diff --git a/buildroot/package/axp2101/src/XPowersLib/REG/AXP202Constants.h b/buildroot/package/axp2101/src/XPowersLib/REG/AXP202Constants.h new file mode 100644 index 000000000..ea2d0fb33 --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/REG/AXP202Constants.h @@ -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) + + + + + + + + + + + + diff --git a/buildroot/package/axp2101/src/XPowersLib/REG/AXP2101Constants.h b/buildroot/package/axp2101/src/XPowersLib/REG/AXP2101Constants.h new file mode 100644 index 000000000..dd85810cb --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/REG/AXP2101Constants.h @@ -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) + diff --git a/buildroot/package/axp2101/src/XPowersLib/REG/AXP216Constants.h b/buildroot/package/axp2101/src/XPowersLib/REG/AXP216Constants.h new file mode 100644 index 000000000..117694928 --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/REG/AXP216Constants.h @@ -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) diff --git a/buildroot/package/axp2101/src/XPowersLib/REG/HUSB238Constants.h b/buildroot/package/axp2101/src/XPowersLib/REG/HUSB238Constants.h new file mode 100644 index 000000000..a6cf96ce5 --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/REG/HUSB238Constants.h @@ -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) + + diff --git a/buildroot/package/axp2101/src/XPowersLib/REG/SY6970Constants.h b/buildroot/package/axp2101/src/XPowersLib/REG/SY6970Constants.h new file mode 100644 index 000000000..98bab5649 --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/REG/SY6970Constants.h @@ -0,0 +1,126 @@ +/** + * + * @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) +// https://www.ti.com/product/BQ25896 +#define BQ25896_SLAVE_ADDRESS (0x6B) +// https://www.sg-micro.com/cnproduct/SGM41511 +#define SGM41511_SLAVE_ADDRESS (0x6B) + +#define SY6970_DEV_REV (0x00) +#define BQ25896_DEV_REV (0x02) + +#define POWERS_SY6970_REG_00H (0x00) +#define POWERS_SY6970_REG_01H (0x01) +#define POWERS_SY6970_REG_02H (0x02) +#define POWERS_SY6970_REG_03H (0x03) +#define POWERS_SY6970_REG_04H (0x04) +#define POWERS_SY6970_REG_05H (0x05) +#define POWERS_SY6970_REG_06H (0x06) +#define POWERS_SY6970_REG_07H (0x07) +#define POWERS_SY6970_REG_08H (0x08) +#define POWERS_SY6970_REG_09H (0x09) +#define POWERS_SY6970_REG_0AH (0x0A) +// Read only STATUS REG +#define POWERS_SY6970_REG_0BH (0x0B) +// Read only CHARGE IRQ REG +#define POWERS_SY6970_REG_0CH (0x0C) +// Absolute VINDPM Threshold +#define POWERS_SY6970_REG_0DH (0x0D) +// Read only BATTERY VOLTAGE +#define POWERS_SY6970_REG_0EH (0x0E) +// Read only SYSTEM VOLTAGE +#define POWERS_SY6970_REG_0FH (0x0F) +// Read only NTC PERCENTAGE +#define POWERS_SY6970_REG_10H (0x10) +// Read only VBUS VOLTAGE +#define POWERS_SY6970_REG_11H (0x11) +// Read only CHARGE CURRENT +#define POWERS_SY6970_REG_12H (0x12) +// Read only VINDPM/IINDPM STATUS/CURR LIMIT SETTING +#define POWERS_SY6970_REG_13H (0x13) +// RESET REG +#define POWERS_SY6970_REG_14H (0x14) + +#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_FAST_CHG_CURRENT_MIN (0) +#define POWERS_FAST_CHG_CURRENT_MAX (5056) + +#define POWERS_PRE_CHG_CURRENT_MIN (64) +#define POWERS_PRE_CHG_CURRENT_MAX (1024) + +#define POWERS_SY6970_CHG_VOL_BASE (3840) +#define POWERS_SY6970_CHG_VOL_STEP (16) +#define POWERS_FAST_CHG_VOL_MIN (3840) +#define POWERS_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) \ No newline at end of file diff --git a/buildroot/package/axp2101/src/XPowersLib/XPowersAXP192.tpp b/buildroot/package/axp2101/src/XPowersLib/XPowersAXP192.tpp new file mode 100644 index 000000000..615152b67 --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/XPowersAXP192.tpp @@ -0,0 +1,2087 @@ +/** + * + * @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 XPowersAXP192.tpp + * @author Lewis He (lewishe@outlook.com) + * @date 2022-05-07 + * + */ +#if defined(ARDUINO) +#include +#else +#include +#endif /*ARDUINO*/ +#include "XPowersCommon.tpp" +#include "REG/AXP192Constants.h" +#include "XPowersLibInterface.hpp" + +typedef enum { + XPOWERS_AXP192_BOOT_TIME_128MS, + XPOWERS_AXP192_BOOT_TIME_512MS, + XPOWERS_AXP192_BOOT_TIME_1S, + XPOWERS_AXP192_BOOT_TIME_2S, +} xpowers_axp192_boot_time_t; + + + + +typedef enum { + XPOWERS_AXP192_CHG_ITERM_LESS_10_PERCENT, + XPOWERS_AXP192_CHG_ITERM_LESS_15_PERCENT, +} xpowers_axp192_chg_iterm_t; + + +typedef enum { + XPOWERS_AXP192_PRECHG_TIMEOUT_30MIN, + XPOWERS_AXP192_PRECHG_TIMEOUT_40MIN, + XPOWERS_AXP192_PRECHG_TIMEOUT_50MIN, + XPOWERS_AXP192_PRECHG_TIMEOUT_60MIN, +} xpoers_axp192_prechg_to_t; + +typedef enum { + XPOWERS_AXP192_POWEROFF_4S, + XPOWERS_AXP192_POWEROFF_65, + XPOWERS_AXP192_POWEROFF_8S, + XPOWERS_AXP192_POWEROFF_10S, +} xpowers_axp192_pekey_poweroff_arg_t; + + +typedef enum { + XPOWERS_AXP192_LONGPRESS_1000MS, + XPOWERS_AXP192_LONGPRESS_1500MS, + XPOWERS_AXP192_LONGPRESS_2000MS, + XPOWERS_AXP192_LONGPRESS_2500MS, +} xpowers_axp192_pekey_long_press_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_AXP192_CHG_CONS_TIMEOUT_7H, + XPOWERS_AXP192_CHG_CONS_TIMEOUT_8H, + XPOWERS_AXP192_CHG_CONS_TIMEOUT_9H, + XPOWERS_AXP192_CHG_CONS_TIMEOUT_10H, +} xpowers_axp192_chg_cons_to_t; + + +typedef enum { + XPOWERS_AXP192_BACKUP_BAT_VOL_3V1, + XPOWERS_AXP192_BACKUP_BAT_VOL_3V, + XPOWERS_AXP192_BACKUP_BAT_VOL_3V0, //!NEED FIX,DATASHEET ERROR! + XPOWERS_AXP192_BACKUP_BAT_VOL_2V5, +} xpowers_axp192_backup_batt_vol_t; + +typedef enum { + XPOWERS_AXP192_BACKUP_BAT_CUR_50UA, + XPOWERS_AXP192_BACKUP_BAT_CUR_100UA, + XPOWERS_AXP192_BACKUP_BAT_CUR_200UA, + XPOWERS_AXP192_BACKUP_BAT_CUR_400UA, +} xpowers_axp192_backup_batt_curr_t; + +typedef struct { + uint8_t mode; +} xpowers_axp192_gpio_t; + + +class XPowersAXP192 : + public XPowersCommon, public XPowersLibInterface +{ + friend class XPowersCommon; + + + typedef enum { + PMU_GPIO0, + PMU_GPIO1, + PMU_GPIO2, + PMU_GPIO3, + PMU_GPIO4, + PMU_GPIO5, + PMU_TS_PIN + } xpowers_axp192_num_t; + + typedef enum { + MONITOR_TS_PIN = _BV(0), + MONITOR_APS_VOLTAGE = _BV(1), + MONITOR_USB_CURRENT = _BV(2), + MONITOR_USB_VOLTAGE = _BV(3), + MONITOR_AC_CURRENT = _BV(4), + MONITOR_AC_VOLTAGE = _BV(5), + MONITOR_BAT_CURRENT = _BV(6), + MONITOR_BAT_VOLTAGE = _BV(7), + MONITOR_ADC_IO3 = _BV(8), + MONITOR_ADC_IO2 = _BV(9), + MONITOR_ADC_IO1 = _BV(10), + MONITOR_ADC_IO0 = _BV(11), + MONITOR_TEMPERATURE = _BV(16), + } axp192_adc_func_t; + + typedef struct { + uint8_t mode; + } xpowers_gpio_t; + + +public: + + +#if defined(ARDUINO) + XPowersAXP192(TwoWire &w, int sda = SDA, int scl = SCL, uint8_t addr = AXP192_SLAVE_ADDRESS) + { + __wire = &w; + __sda = sda; + __scl = scl; + __addr = addr; + } +#endif + + XPowersAXP192(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) + { + thisReadRegCallback = readRegCallback; + thisWriteRegCallback = writeRegCallback; + __addr = addr; + } + + XPowersAXP192() + { +#if defined(ARDUINO) + __wire = &Wire; + __sda = SDA; + __scl = SCL; +#endif + __addr = AXP192_SLAVE_ADDRESS; + } + + ~XPowersAXP192() + { + log_i("~XPowersAXP192"); + deinit(); + } + +#if defined(ARDUINO) + bool init(TwoWire &w, int sda = SDA, int scl = SCL, uint8_t addr = AXP192_SLAVE_ADDRESS) + { + __wire = &w; + __sda = sda; + __scl = scl; + __addr = addr; + return begin(); + } +#endif + + bool init() + { + return begin(); + } + + void deinit() + { + end(); + } + + uint16_t status() + { + return readRegister(XPOWERS_AXP192_STATUS); + } + + bool isAcinVbusStart() + { + return getRegisterBit(XPOWERS_AXP192_STATUS, 0); + } + + bool isDischarge() + { + return !getRegisterBit(XPOWERS_AXP192_STATUS, 2); + } + + bool isVbusIn(void) + { + return getRegisterBit(XPOWERS_AXP192_STATUS, 5); + } + + bool isAcinEfficient() + { + return getRegisterBit(XPOWERS_AXP192_STATUS, 6); + } + + bool isAcinIn() + { + return getRegisterBit(XPOWERS_AXP192_STATUS, 7); + } + + bool isOverTemperature() + { + return getRegisterBit(XPOWERS_AXP192_MODE_CHGSTATUS, 7); + } + + bool isCharging(void) + { + return getRegisterBit(XPOWERS_AXP192_MODE_CHGSTATUS, 6); + } + + bool isBatteryConnect(void) + { + return getRegisterBit(XPOWERS_AXP192_MODE_CHGSTATUS, 5); + } + + bool isBattInActiveMode() + { + return getRegisterBit(XPOWERS_AXP192_MODE_CHGSTATUS, 3); + } + + bool isChargeCurrLessPreset() + { + return getRegisterBit(XPOWERS_AXP192_MODE_CHGSTATUS, 2); + } + + void enableVbusVoltageLimit() + { + setRegisterBit(XPOWERS_AXP192_IPS_SET, 6); + } + + void disableVbusVoltageLimit() + { + clrRegisterBit(XPOWERS_AXP192_IPS_SET, 6); + } + + void setVbusVoltageLimit(xpowers_axp192_vbus_vol_limit_t opt) + { + int val = readRegister(XPOWERS_AXP192_IPS_SET); + if (val == -1)return; + val &= 0xC7; + writeRegister(XPOWERS_AXP192_IPS_SET, val | (opt << 3)); + } + + /** + * @brief Set VBUS Current Input Limit. + * @param opt: View the related chip type xpowers_axp192_vbus_cur_limit_t enumeration + * parameters in "XPowersParams.hpp" + * @retval true valid false invalid + */ + bool setVbusCurrentLimit(uint8_t opt) + { + switch (opt) { + case XPOWERS_AXP192_VBUS_CUR_LIM_500MA: + setRegisterBit(XPOWERS_AXP192_IPS_SET, 1); + return clrRegisterBit(XPOWERS_AXP192_IPS_SET, 0); + case XPOWERS_AXP192_VBUS_CUR_LIM_100MA: + setRegisterBit(XPOWERS_AXP192_IPS_SET, 1); + return setRegisterBit(XPOWERS_AXP192_IPS_SET, 0); + case XPOWERS_AXP192_VBUS_CUR_LIM_OFF: + return clrRegisterBit(XPOWERS_AXP192_IPS_SET, 1); + default: + break; + } + return false; + } + + + /** + * @brief Get VBUS Current Input Limit. + * @retval View the related chip type xpowers_axp192_vbus_cur_limit_t enumeration + * parameters in "XPowersParams.hpp" + */ + uint8_t getVbusCurrentLimit(void) + { + if (getRegisterBit(XPOWERS_AXP192_IPS_SET, 1) == 0) { + return XPOWERS_AXP192_VBUS_CUR_LIM_OFF; + } + if (getRegisterBit(XPOWERS_AXP192_IPS_SET, 0)) { + return XPOWERS_AXP192_VBUS_CUR_LIM_100MA; + } + return XPOWERS_AXP192_VBUS_CUR_LIM_500MA; + } + + + // Set the minimum system operating voltage inside the PMU, + // below this value will shut down the PMU,Adjustment range 2600mV ~ 3300mV + bool setSysPowerDownVoltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP192_SYS_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP192_SYS_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP192_VOFF_VOL_MIN) { + log_e("Mistake ! SYS minimum output voltage is %umV", XPOWERS_AXP192_VOFF_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP192_VOFF_VOL_MAX) { + log_e("Mistake ! SYS maximum output voltage is %umV", XPOWERS_AXP192_VOFF_VOL_MAX); + return false; + } + + int val = readRegister(XPOWERS_AXP192_VOFF_SET); + if (val == -1)return false; + val &= 0xF8; + val |= (millivolt - XPOWERS_AXP192_VOFF_VOL_MIN) / XPOWERS_AXP192_SYS_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP192_VOFF_SET, val); + } + + uint16_t getSysPowerDownVoltage() + { + int val = readRegister(XPOWERS_AXP192_VOFF_SET); + if (val == -1)return 0; + val &= 0x07; + return (val * XPOWERS_AXP192_SYS_VOL_STEPS) + XPOWERS_AXP192_VOFF_VOL_MIN; + } + + + /** + * @brief Set shutdown, calling shutdown will turn off all power channels, + * only VRTC belongs to normal power supply + * @retval None + */ + void shutdown() + { + setRegisterBit(XPOWERS_AXP192_OFF_CTL, 7); + } + + + /* + * Charge setting + */ + void enableCharge() + { + setRegisterBit(XPOWERS_AXP192_CHARGE1, 7); + } + + void disableCharge() + { + clrRegisterBit(XPOWERS_AXP192_CHARGE1, 7); + } + + + + + + /** + * @brief Set charge target voltage. + * @param opt: See xpowers_axp192_chg_vol_t enum for details. + * @retval + */ + bool setChargeTargetVoltage(uint8_t opt) + { + if (opt >= XPOWERS_AXP192_CHG_VOL_MAX)return false; + int val = readRegister(XPOWERS_AXP192_CHARGE1); + if (val == -1) return false; + val &= 0x9F; + return 0 == writeRegister(XPOWERS_AXP192_CHARGE1, val | (opt << 5)); + } + + /** + * @brief Get charge target voltage settings. + * @retval See xpowers_axp192_chg_vol_t enum for details. + */ + uint8_t getChargeTargetVoltage() + { + int val = readRegister(XPOWERS_AXP192_CHARGE1); + if (val == -1) return 0; + return (val & 0x60) >> 5; + } + + /** + * @brief Set charge current settings. + * @retval See xpowers_axp192_chg_curr_t enum for details. + */ + bool setChargerConstantCurr(uint8_t opt) + { + if (opt > 0x0F)return false; + int val = readRegister(XPOWERS_AXP192_CHARGE1); + if (val == -1) { + return false; + } + val &= 0xF0; + return 0 == writeRegister(XPOWERS_AXP192_CHARGE1, val | opt); + } + + /** + * @brief Get charge current settings. + * @retval See xpowers_axp192_chg_curr_t enum for details. + */ + uint8_t getChargerConstantCurr(void) + { + int val = readRegister(XPOWERS_AXP192_CHARGE1) & 0x0F; + if (val == -1)return XPOWERS_AXP192_CHG_CUR_780MA; + return val; + } + + void setChargerTerminationCurr(xpowers_axp192_chg_iterm_t opt) + { + switch (opt) { + case XPOWERS_AXP192_CHG_ITERM_LESS_10_PERCENT: + clrRegisterBit(XPOWERS_AXP192_CHARGE1, 0); + break; + case XPOWERS_AXP192_CHG_ITERM_LESS_15_PERCENT: + setRegisterBit(XPOWERS_AXP192_CHARGE1, 0); + break; + default: + break; + } + } + + uint8_t getChargerTerminationCurr() + { + return getRegisterBit(XPOWERS_AXP192_CHARGE1, 4); + } + + bool setPrechargeTimeout(xpoers_axp192_prechg_to_t opt) + { + int val = readRegister(XPOWERS_AXP192_CHARGE2); + if (val == -1)return false; + val &= 0x3F; + return 0 == writeRegister(XPOWERS_AXP192_CHARGE2, val | (opt << 6)); + } + + // External channel charge current setting,Range:300~1000mA + bool setChargerExternChannelCurr(uint16_t milliampere) + { + if (milliampere % XPOWERS_AXP192_CHG_EXT_CURR_STEP) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP192_CHG_EXT_CURR_STEP); + return false; + } + if (milliampere < XPOWERS_AXP192_CHG_EXT_CURR_MIN) { + log_e("Mistake ! The minimum external path charge current setting is: %umA", XPOWERS_AXP192_CHG_EXT_CURR_MIN); + return false; + } else if (milliampere > XPOWERS_AXP192_CHG_EXT_CURR_MAX) { + log_e("Mistake ! The maximum external channel charge current setting is: %umA", XPOWERS_AXP192_CHG_EXT_CURR_MAX); + return false; + } + int val = readRegister(XPOWERS_AXP192_CHARGE2); + if (val == -1)return false; + val &= 0xC7; + val |= ((milliampere - XPOWERS_AXP192_CHG_EXT_CURR_MIN ) / XPOWERS_AXP192_CHG_EXT_CURR_STEP); + return 0 == writeRegister(XPOWERS_AXP192_CHARGE2, val); + } + + bool enableChargerExternChannel() + { + return setRegisterBit(XPOWERS_AXP192_CHARGE2, 2); + } + + bool disableChargerExternChannel() + { + return clrRegisterBit(XPOWERS_AXP192_CHARGE2, 2); + } + + // Timeout setting in constant current mode + bool setChargerConstantTimeout(xpowers_axp192_chg_cons_to_t opt) + { + int val = readRegister(XPOWERS_AXP192_CHARGE2); + if (val == -1)return false; + val &= 0xFC; + return 0 == writeRegister(XPOWERS_AXP192_CHARGE2, val | opt); + } + + bool enableBackupBattCharger() + { + return setRegisterBit(XPOWERS_AXP192_BACKUP_CHG, 7); + } + + + bool disableBackupBattCharger() + { + return clrRegisterBit(XPOWERS_AXP192_BACKUP_CHG, 7); + } + + bool isEanbleBackupCharger() + { + return getRegisterBit(XPOWERS_AXP192_BACKUP_CHG, 7); + } + + bool setBackupBattChargerVoltage(xpowers_axp192_backup_batt_vol_t opt) + { + int val = readRegister(XPOWERS_AXP192_BACKUP_CHG); + if (val == -1)return false; + val &= 0x9F; + return 0 == writeRegister(XPOWERS_AXP192_BACKUP_CHG, val | (opt << 5)); + } + + bool setBackupBattChargerCurr(xpowers_axp192_backup_batt_curr_t opt) + { + int val = readRegister(XPOWERS_AXP192_BACKUP_CHG); + if (val == -1)return false; + val &= 0xFC; + return 0 == writeRegister(XPOWERS_AXP192_BACKUP_CHG, val | opt); + } + + /* + * Temperature + */ + float getTemperature() + { + return readRegisterH8L4(XPOWERS_AXP192_INTERNAL_TEMP_H8, XPOWERS_AXP192_INTERNAL_TEMP_L4) + * XPOWERS_AXP192_INTERNAL_TEMP_STEP - XPOWERS_AXP192_INERNAL_TEMP_OFFSET; + } + + bool enableTemperatureMeasure() + { + return setRegisterBit(XPOWERS_AXP192_ADC_EN2, 7); + } + + bool disableTemperatureMeasure() + { + return clrRegisterBit(XPOWERS_AXP192_ADC_EN2, 7); + } + + /* + * Power control LDOio functions + */ + bool isEnableLDOio(void) + { + int val = readRegister(XPOWERS_AXP192_GPIO0_CTL); + return (val & 0x02); + } + + bool enableLDOio(void) + { + int val = readRegister(XPOWERS_AXP192_GPIO0_CTL) & 0xF8; + return 0 == writeRegister(XPOWERS_AXP192_GPIO0_CTL, val | 0x02); + } + + bool disableLDOio(void) + { + int val = readRegister(XPOWERS_AXP192_GPIO0_CTL) & 0xF8; + return 0 == writeRegister(XPOWERS_AXP192_GPIO0_CTL, val); + } + + bool setLDOioVoltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP192_LDOIO_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP192_LDOIO_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP192_LDOIO_VOL_MIN) { + log_e("Mistake ! LDOIO minimum output voltage is %umV", XPOWERS_AXP192_LDOIO_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP192_LDOIO_VOL_MAX) { + log_e("Mistake ! LDOIO maximum output voltage is %umV", XPOWERS_AXP192_LDOIO_VOL_MAX); + return false; + } + int val = readRegister(XPOWERS_AXP192_GPIO0_VOL); + if (val == -1)return false; + val |= (((millivolt - XPOWERS_AXP192_LDOIO_VOL_MIN) / XPOWERS_AXP192_LDOIO_VOL_STEPS) << 4); + return 0 == writeRegister(XPOWERS_AXP192_GPIO0_VOL, val); + } + + uint16_t getLDOioVoltage(void) + { + int val = readRegister(XPOWERS_AXP192_GPIO0_VOL); + if (val == -1)return 0; + val >>= 4; + val *= XPOWERS_AXP192_LDOIO_VOL_STEPS; + val += XPOWERS_AXP192_LDOIO_VOL_MIN; + return val; + } + + /* + * Power control LDO2 functions + */ + bool isEnableLDO2(void) + { + return getRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 2); + } + + bool enableLDO2(void) + { + return setRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 2); + } + + bool disableLDO2(void) + { + return clrRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 2); + } + + bool setLDO2Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP192_LDO2_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP192_LDO2_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP192_LDO2_VOL_MIN) { + log_e("Mistake ! LDO2 minimum output voltage is %umV", XPOWERS_AXP192_LDO2_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP192_LDO2_VOL_MAX) { + log_e("Mistake ! LDO2 maximum output voltage is %umV", XPOWERS_AXP192_LDO2_VOL_MAX); + return false; + } + + int val = readRegister(XPOWERS_AXP192_LDO23OUT_VOL); + if (val == -1) return false; + val &= 0x0F; + return 0 == writeRegister(XPOWERS_AXP192_LDO23OUT_VOL, val | (((millivolt - XPOWERS_AXP192_LDO2_VOL_MIN) / XPOWERS_AXP192_LDO2_VOL_STEPS) << XPOWERS_AXP192_LDO2_VOL_BIT_MASK)); + } + + uint16_t getLDO2Voltage(void) + { + int val = readRegister(XPOWERS_AXP192_LDO23OUT_VOL) & 0xF0; + return (val >> XPOWERS_AXP192_LDO2_VOL_BIT_MASK) * XPOWERS_AXP192_LDO2_VOL_STEPS + XPOWERS_AXP192_LDO2_VOL_MIN; + } + + /* + * Power control LDO3 functions + */ + bool isEnableLDO3(void) + { + return getRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 3); + } + + bool enableLDO3(void) + { + return setRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 3); + } + + bool disableLDO3(void) + { + return clrRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 3); + } + + + bool setLDO3Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP192_LDO3_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP192_LDO3_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP192_LDO3_VOL_MIN) { + log_e("Mistake ! LDO3 minimum output voltage is %umV", XPOWERS_AXP192_LDO3_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP192_LDO3_VOL_MAX) { + log_e("Mistake ! LDO3 maximum output voltage is %umV", XPOWERS_AXP192_LDO3_VOL_MAX); + return false; + } + + int val = readRegister(XPOWERS_AXP192_LDO23OUT_VOL) & 0xF0; + return 0 == writeRegister(XPOWERS_AXP192_LDO23OUT_VOL, val | ((millivolt - XPOWERS_AXP192_LDO3_VOL_MIN) / XPOWERS_AXP192_LDO3_VOL_STEPS)); + } + + uint16_t getLDO3Voltage(void) + { + int val = readRegister(XPOWERS_AXP192_LDO23OUT_VOL); + if (val == -1)return 0; + val &= 0x0F; + return (val * XPOWERS_AXP192_LDO3_VOL_STEPS) + XPOWERS_AXP192_LDO3_VOL_MIN; + } + + /* + * Power control DCDC1 functions + */ + void setDC1PwmMode(void) + { + int val = readRegister(XPOWERS_AXP192_DCDC_MODESET) & 0xF7; + writeRegister(XPOWERS_AXP192_DCDC_MODESET, val | 0x08); + } + + void setDC1AutoMode(void) + { + int val = readRegister(XPOWERS_AXP192_DCDC_MODESET) & 0xF7; + writeRegister(XPOWERS_AXP192_DCDC_MODESET, val); + } + + bool isEnableDC1(void) + { + return getRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 0); + } + + bool enableDC1(void) + { + return setRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 0); + } + + bool disableDC1(void) + { + return clrRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 0); + } + + bool setDC1Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP192_DC1_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP192_DC1_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP192_DC1_VOL_STEPS) { + log_e("Mistake ! DCDC1 minimum output voltage is %umV", XPOWERS_AXP192_DC1_VOL_STEPS); + return false; + } else if (millivolt > XPOWERS_AXP192_DC1_VOL_MAX) { + log_e("Mistake ! DCDC1 maximum output voltage is %umV", XPOWERS_AXP192_DC1_VOL_MAX); + return false; + } + + int val = readRegister(XPOWERS_AXP192_DC1_VLOTAGE); + if (val == -1)return false; + val &= 0x80; + val |= (millivolt - XPOWERS_AXP192_DC1_VOL_MIN) / XPOWERS_AXP192_DC1_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP192_DC1_VLOTAGE, val); + } + + uint16_t getDC1Voltage(void) + { + int val = readRegister(XPOWERS_AXP192_DC1_VLOTAGE) & 0x7F; + return val * XPOWERS_AXP192_DC1_VOL_STEPS + XPOWERS_AXP192_DC1_VOL_MIN; + } + + /* + * Power control DCDC2 functions + */ + void setDC2PwmMode(void) + { + int val = readRegister(XPOWERS_AXP192_DCDC_MODESET) & 0xFB; + writeRegister(XPOWERS_AXP192_DCDC_MODESET, val | 0x04); + } + + void setDC2AutoMode(void) + { + int val = readRegister(XPOWERS_AXP192_DCDC_MODESET) & 0xFB; + writeRegister(XPOWERS_AXP192_DCDC_MODESET, val); + } + + void enableDC2VRC(void) + { + int val = readRegister(XPOWERS_AXP192_DC2_DVM); + writeRegister(XPOWERS_AXP192_DC2_DVM, val | 0x04); + } + + void disableDC2VRC(void) + { + int val = readRegister(XPOWERS_AXP192_DC2_DVM); + writeRegister(XPOWERS_AXP192_DC2_DVM, val & 0xFB); + } + + bool setDC2VRC(uint8_t opts) + { + if (opts > 1) { + return false; + } + int val = readRegister(XPOWERS_AXP192_DC2_DVM) & 0xFE; + writeRegister(XPOWERS_AXP192_DC2_DVM, val | opts); + } + + bool isEanbleDC2VRC(void) + { + return (readRegister(XPOWERS_AXP192_DC2_DVM) & 0x04) == 0x04; + } + + bool isEnableDC2(void) + { + return getRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 4); + } + + bool enableDC2(void) + { + return setRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 4); + } + + bool disableDC2(void) + { + return clrRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 4); + } + + bool setDC2Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP192_DC2_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP192_DC2_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP192_DC2_VOL_MIN) { + log_e("Mistake ! DCDC2 minimum output voltage is %umV", XPOWERS_AXP192_DC2_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP192_DC2_VOL_MAX) { + log_e("Mistake ! DCDC2 maximum output voltage is %umV", XPOWERS_AXP192_DC2_VOL_MAX); + return false; + } + int val = readRegister(XPOWERS_AXP192_DC2OUT_VOL); + if (val == -1)return false; + val &= 0x80; + val |= (millivolt - XPOWERS_AXP192_DC2_VOL_MIN) / XPOWERS_AXP192_DC2_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP192_DC2OUT_VOL, val); + } + + uint16_t getDC2Voltage(void) + { + int val = readRegister(XPOWERS_AXP192_DC2OUT_VOL); + if (val == -1)return 0; + return (val * XPOWERS_AXP192_DC2_VOL_STEPS) + XPOWERS_AXP192_DC2_VOL_MIN; + } + + /* + * Power control DCDC3 functions + */ + void setDC3PwmMode(void) + { + int val = readRegister(XPOWERS_AXP192_DCDC_MODESET) & 0xFD; + writeRegister(XPOWERS_AXP192_DCDC_MODESET, val | 0x02); + } + + void setDC3AutoMode(void) + { + int val = readRegister(XPOWERS_AXP192_DCDC_MODESET) & 0xFD; + writeRegister(XPOWERS_AXP192_DCDC_MODESET, val); + } + + bool isEnableDC3(void) + { + return getRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 1); + } + + bool enableDC3(void) + { + return setRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 1); + } + + bool disableDC3(void) + { + return clrRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 1); + } + + bool setDC3Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP192_DC3_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP192_DC3_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP192_DC3_VOL_MIN) { + log_e("Mistake ! DCDC3 minimum output voltage is %umV", XPOWERS_AXP192_DC3_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP192_DC3_VOL_MAX) { + log_e("Mistake ! DCDC3 maximum output voltage is %umV", XPOWERS_AXP192_DC3_VOL_MAX); + return false; + } + return 0 == writeRegister(XPOWERS_AXP192_DC3OUT_VOL, (millivolt - XPOWERS_AXP192_DC3_VOL_MIN) / XPOWERS_AXP192_DC3_VOL_STEPS); + } + + uint16_t getDC3Voltage(void) + { + int val = readRegister(XPOWERS_AXP192_DC3OUT_VOL); + if (val == -1)return 0; + return (val * XPOWERS_AXP192_DC3_VOL_STEPS) + XPOWERS_AXP192_DC3_VOL_MIN; + } + + /* + * Power control EXTEN functions + */ + bool enableExternalPin(void) + { + return setRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 6); + } + + bool disableExternalPin(void) + { + return clrRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 6); + } + + bool isEnableExternalPin(void) + { + return getRegisterBit(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, 6); + } + + /* + * Interrupt status functions + */ + + /** + * @brief Get the interrupt controller mask value. + * @retval Mask value corresponds to xpowers_axp192_irq_t , + */ + uint64_t getIrqStatus(void) + { + statusRegister[0] = readRegister(XPOWERS_AXP192_INTSTS1); + statusRegister[1] = readRegister(XPOWERS_AXP192_INTSTS2); + statusRegister[2] = readRegister(XPOWERS_AXP192_INTSTS3); + statusRegister[3] = readRegister(XPOWERS_AXP192_INTSTS4); + statusRegister[4] = readRegister(XPOWERS_AXP192_INTSTS5); + return ((uint64_t)statusRegister[4]) << 32 | + ((uint64_t)statusRegister[3]) << 24 | + ((uint64_t)statusRegister[2]) << 16 | + ((uint64_t)statusRegister[1]) << 8 | + ((uint64_t)statusRegister[0]); + } + + /** + * @brief Clear interrupt controller state. + */ + void clearIrqStatus(void) + { + for (int i = 0; i < 4; i++) { + writeRegister(XPOWERS_AXP192_INTSTS1 + i, 0xFF); + } + writeRegister(XPOWERS_AXP192_INTSTS5, 0xFF); + } + + /** + * @brief Eanble PMU interrupt control mask . + * @param opt: View the related chip type xpowers_axp192_irq_t enumeration + * parameters in "XPowersParams.hpp" + * @retval + */ + bool enableIRQ(uint64_t opt) + { + return setInterruptImpl(opt, true); + } + + /** + * @brief Disable PMU interrupt control mask . + * @param opt: View the related chip type xpowers_axp192_irq_t enumeration + * parameters in "XPowersParams.hpp" + * @retval + */ + bool disableIRQ(uint64_t opt) + { + return setInterruptImpl(opt, false); + } + + bool isAcinOverVoltageIrq(void) + { + return (bool)(statusRegister[0] & _BV(7)); + } + + bool isAcinInserIrq(void) + { + return (bool)(statusRegister[0] & _BV(6)); + } + + bool isAcinRemoveIrq(void) + { + return (bool)(statusRegister[0] & _BV(5)); + } + + bool isVbusOverVoltageIrq(void) + { + return (bool)(statusRegister[0] & _BV(4)); + } + + bool isVbusInsertIrq(void) + { + return (bool)(statusRegister[0] & _BV(3)); + } + + bool isVbusRemoveIrq(void) + { + return (bool)(statusRegister[0] & _BV(2)); + } + + bool isVbusLowVholdIrq(void) + { + return (bool)(statusRegister[0] & _BV(1)); + } + + bool isBatInsertIrq(void) + { + return (bool)(statusRegister[1] & _BV(7)); + } + + bool isBatRemoveIrq(void) + { + return (bool)(statusRegister[1] & _BV(6)); + } + + bool isBattEnterActivateIrq(void) + { + return (bool)(statusRegister[1] & _BV(5)); + } + + bool isBattExitActivateIrq(void) + { + return (bool)(statusRegister[1] & _BV(4)); + } + + bool isBatChagerStartIrq(void) + { + return (bool)(statusRegister[1] & _BV(3)); + } + + bool isBatChagerDoneIrq(void) + { + return (bool)(statusRegister[1] & _BV(2)); + } + + bool isBattTempHighIrq(void) + { + return (bool)(statusRegister[1] & _BV(1)); + } + + bool isBattTempLowIrq(void) + { + return (bool)(statusRegister[1] & _BV(0)); + } + + bool isChipOverTemperatureIrq(void) + { + return (bool)(statusRegister[2] & _BV(7)); + } + + bool isChargingCurrentLessIrq(void) + { + return (bool)(statusRegister[2] & _BV(6)); + } + + bool isDC1VoltageLessIrq(void) + { + return (bool)(statusRegister[2] & _BV(5)); + } + + bool isDC2VoltageLessIrq(void) + { + return (bool)(statusRegister[2] & _BV(4)); + } + + bool isDC3VoltageLessIrq(void) + { + return (bool)(statusRegister[2] & _BV(3)); + } + + bool isPekeyShortPressIrq(void) + { + return (bool)(statusRegister[2] & _BV(1)); + } + + bool isPekeyLongPressIrq(void) + { + return (bool)(statusRegister[2] & _BV(0)); + } + + bool isNOEPowerOnIrq(void) + { + return (bool)(statusRegister[3] & _BV(7)); + } + + bool isNOEPowerDownIrq(void) + { + return (bool)(statusRegister[3] & _BV(6)); + } + + bool isVbusEffectiveIrq(void) + { + return (bool)(statusRegister[3] & _BV(5)); + } + + bool isVbusInvalidIrq(void) + { + return (bool)(statusRegister[3] & _BV(4)); + } + + bool isVbusSessionIrq(void) + { + return (bool)(statusRegister[3] & _BV(3)); + } + + bool isVbusSessionEndIrq(void) + { + return (bool)(statusRegister[3] & _BV(2)); + } + + bool isLowVoltageLevel2Irq(void) + { + return (bool)(statusRegister[3] & _BV(0)); + } + + //IRQ5 REGISTER : + bool isWdtExpireIrq(void) + { + return (bool)(statusRegister[4] & _BV(7)); + } + + bool isGpio2EdgeTriggerIrq(void) + { + return (bool)(statusRegister[4] & _BV(2)); + } + + bool isGpio1EdgeTriggerIrq(void) + { + return (bool)(statusRegister[4] & _BV(1)); + } + + bool isGpio0EdgeTriggerIrq(void) + { + return (bool)(statusRegister[4] & _BV(0)); + } + + /* + * ADC Functions + */ + + bool enableBattDetection() + { + return setRegisterBit(XPOWERS_AXP192_OFF_CTL, 6); + } + + bool disableBattDetection() + { + return clrRegisterBit(XPOWERS_AXP192_OFF_CTL, 6); + } + + bool enableVbusVoltageMeasure() + { + return setSignalCaptureImpl(MONITOR_USB_CURRENT | MONITOR_USB_VOLTAGE, true); + } + + bool disableVbusVoltageMeasure() + { + return setSignalCaptureImpl(MONITOR_USB_CURRENT | MONITOR_USB_VOLTAGE, false); + } + + bool enableBattVoltageMeasure() + { + return setSignalCaptureImpl(MONITOR_BAT_CURRENT | MONITOR_BAT_VOLTAGE, true); + } + + bool disableBattVoltageMeasure() + { + return setSignalCaptureImpl(MONITOR_BAT_CURRENT | MONITOR_BAT_VOLTAGE, false); + } + + bool enableSystemVoltageMeasure() + { + return setSignalCaptureImpl(MONITOR_APS_VOLTAGE, true); + } + + bool disableSystemVoltageMeasure() + { + return setSignalCaptureImpl(MONITOR_APS_VOLTAGE, false); + } + + bool enableTSPinMeasure() + { + return setSignalCaptureImpl(MONITOR_TS_PIN, true); + } + + bool disableTSPinMeasure() + { + return setSignalCaptureImpl(MONITOR_TS_PIN, false); + } + + bool enableAdcChannel(uint32_t opts) + { + return setSignalCaptureImpl(opts, true); + } + + bool disableAdcChannel(uint32_t opts) + { + return setSignalCaptureImpl(opts, false); + } + + uint16_t getVbusVoltage() + { + if (!isVbusIn()) { + return 0; + } + return readRegisterH8L4(XPOWERS_AXP192_VBUS_VOL_H8, + XPOWERS_AXP192_VBUS_VOL_L4 + ) * XPOWERS_AXP192_VBUS_VOLTAGE_STEP; + } + + float getVbusCurrent() + { + if (!isVbusIn()) { + return 0; + } + return readRegisterH8L4(XPOWERS_AXP192_VBUS_CUR_H8, + XPOWERS_AXP192_VBUS_CUR_L4 + ) * XPOWERS_AXP192_VBUS_CUR_STEP; + } + + uint16_t getBattVoltage() + { + if (!isBatteryConnect()) { + return 0; + } + return readRegisterH8L4(XPOWERS_AXP192_BAT_AVERVOL_H8, + XPOWERS_AXP192_BAT_AVERVOL_L4 + ) * XPOWERS_AXP192_BATT_VOLTAGE_STEP; + } + + float getBattDischargeCurrent() + { + if (!isBatteryConnect()) { + return 0; + } + return readRegisterH8L5(XPOWERS_AXP192_BAT_AVERDISCHGCUR_H8, + XPOWERS_AXP192_BAT_AVERDISCHGCUR_L5) * XPOWERS_AXP192_BATT_DISCHARGE_CUR_STEP; + } + + uint16_t getAcinVoltage() + { + if (!isAcinIn()) { + return 0; + } + return readRegisterH8L4(XPOWERS_AXP192_ACIN_VOL_H8, XPOWERS_AXP192_ACIN_VOL_L4) * XPOWERS_AXP192_ACIN_VOLTAGE_STEP; + } + + float getAcinCurrent() + { + if (!isAcinIn()) { + return 0; + } + return readRegisterH8L4(XPOWERS_AXP192_ACIN_CUR_H8, XPOWERS_AXP192_ACIN_CUR_L4) * XPOWERS_AXP192_ACIN_CUR_STEP; + } + + uint16_t getSystemVoltage() + { + return readRegisterH8L4(XPOWERS_AXP192_APS_AVERVOL_H8, XPOWERS_AXP192_APS_AVERVOL_L4) * XPOWERS_AXP192_APS_VOLTAGE_STEP; + } + + /* + * Timer Control + */ + void setTimerout(uint8_t minute) + { + writeRegister(XPOWERS_AXP192_TIMER_CTL, 0x80 | minute); + } + + void disableTimer() + { + writeRegister(XPOWERS_AXP192_TIMER_CTL, 0x80); + } + + void clearTimerFlag() + { + setRegisterBit(XPOWERS_AXP192_TIMER_CTL, 7); + } + + /* + * Data Buffer + */ + bool writeDataBuffer(uint8_t *data, uint8_t size) + { + if (size > XPOWERS_AXP192_DATA_BUFFER_SIZE)return false; + for (int i = 0; i < size; ++i) { + writeRegister(XPOWERS_AXP192_DATA_BUFFER1 + i, data[i]); + } + return true; + } + + bool readDataBuffer(uint8_t *data, uint8_t size) + { + if (size > XPOWERS_AXP192_DATA_BUFFER_SIZE)return false; + for (int i = 0; i < size; ++i) { + data[i] = readRegister(XPOWERS_AXP192_DATA_BUFFER1 + i); + } + return true; + } + + /* + * Charge led functions + */ + + /** + * @brief Set charging led mode. + * @retval See xpowers_chg_led_mode_t enum for details. + */ + void setChargingLedMode(uint8_t mode) + { + int val; + switch (mode) { + case XPOWERS_CHG_LED_OFF: + case XPOWERS_CHG_LED_BLINK_1HZ: + case XPOWERS_CHG_LED_BLINK_4HZ: + case XPOWERS_CHG_LED_ON: + val = readRegister(XPOWERS_AXP192_OFF_CTL); + if (val == -1)return; + val &= 0xC7; + val |= 0x08; //use manual ctrl + val |= (mode << 4); + writeRegister(XPOWERS_AXP192_OFF_CTL, val); + break; + case XPOWERS_CHG_LED_CTRL_CHG: + clrRegisterBit(XPOWERS_AXP192_OFF_CTL, 3); + break; + default: + break; + } + } + + uint8_t getChargingLedMode() + { + if (!getRegisterBit(XPOWERS_AXP192_OFF_CTL, 3)) { + return XPOWERS_CHG_LED_CTRL_CHG; + } + int val = readRegister(XPOWERS_AXP192_OFF_CTL); + if (val == -1)return XPOWERS_CHG_LED_OFF; + val &= 0x30; + return val >> 4; + } + + /* + * Coulomb counter control + */ + void enableCoulomb() + { + setRegisterBit(XPOWERS_AXP192_COULOMB_CTL, 7); + } + + void disableCoulomb() + { + clrRegisterBit(XPOWERS_AXP192_COULOMB_CTL, 7); + } + + void stopCoulomb() + { + setRegisterBit(XPOWERS_AXP192_COULOMB_CTL, 6); + } + + void clearCoulomb() + { + setRegisterBit(XPOWERS_AXP192_COULOMB_CTL, 5); + } + + uint32_t getBattChargeCoulomb() + { + int data[4]; + data[0] = readRegister(XPOWERS_AXP192_BAT_CHGCOULOMB3); + data[1] = readRegister(XPOWERS_AXP192_BAT_CHGCOULOMB2); + data[2] = readRegister(XPOWERS_AXP192_BAT_CHGCOULOMB1); + data[3] = readRegister(XPOWERS_AXP192_BAT_CHGCOULOMB0); + for (int i = 0; i < 4; ++i) { + if (data[i] == -1)return 0; + } + return ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) | ((uint32_t)data[2] << 8) | (uint32_t)data[3]; + } + + uint32_t getBattDischargeCoulomb() + { + int data[4]; + data[0] = readRegister(XPOWERS_AXP192_BAT_DISCHGCOULOMB3); + data[1] = readRegister(XPOWERS_AXP192_BAT_DISCHGCOULOMB2); + data[2] = readRegister(XPOWERS_AXP192_BAT_DISCHGCOULOMB1); + data[3] = readRegister(XPOWERS_AXP192_BAT_DISCHGCOULOMB0); + for (int i = 0; i < 4; ++i) { + if (data[i] == -1)return 0; + } + return ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) | ((uint32_t)data[2] << 8) | (uint32_t)data[3]; + } + + uint8_t getAdcSamplingRate(void) + { + int val = readRegister(XPOWERS_AXP192_ADC_SPEED); + if (val == -1)return 0; + return 25 * (int)pow(2, (val & 0xC0) >> 6); + } + + float getCoulombData(void) + { + uint32_t charge = getBattChargeCoulomb(), discharge = getBattDischargeCoulomb(); + uint8_t rate = getAdcSamplingRate(); + float result = 65536.0 * 0.5 * ((float)charge - (float)discharge) / 3600.0 / rate; + return result; + } + + /* + * GPIO control functions + */ + float getBatteryChargeCurrent(void) + { + return readRegisterH8L5( + XPOWERS_AXP192_BAT_AVERCHGCUR_H8, + XPOWERS_AXP192_BAT_AVERCHGCUR_L5 + ) * XPOWERS_AXP192_BATT_CHARGE_CUR_STEP; + } + + uint16_t getGpio0Voltage() + { + return readRegisterH8L4(XPOWERS_AXP192_GPIO0_VOL_ADC_H8, XPOWERS_AXP192_GPIO0_VOL_ADC_L4) * XPOWERS_AXP192_GPIO0_STEP * 1000; + } + + uint16_t getGpio1Voltage() + { + return readRegisterH8L4(XPOWERS_AXP192_GPIO1_VOL_ADC_H8, XPOWERS_AXP192_GPIO1_VOL_ADC_L4) * XPOWERS_AXP192_GPIO1_STEP * 1000; + } + + int8_t pwmSetup(uint8_t channel, uint8_t freq, uint16_t duty) + { + // PWM输出频率 = 2.25MHz / (X+1) / Y1 + // PWM输出占空比 = Y2 / Y1 + switch (channel) { + case 0: + writeRegister(XPOWERS_AXP192_PWM1_FREQ_SET, freq); + writeRegister(XPOWERS_AXP192_PWM1_DUTY_SET1, duty >> 8); + writeRegister(XPOWERS_AXP192_PWM1_DUTY_SET2, duty & 0xFF); + break; + case 1: + writeRegister(XPOWERS_AXP192_PWM2_FREQ_SET, freq); + writeRegister(XPOWERS_AXP192_PWM2_DUTY_SET1, duty >> 8); + writeRegister(XPOWERS_AXP192_PWM2_DUTY_SET2, duty & 0xFF); + break; + default: + return -1; + break; + } + return 0; + } + + int8_t pwmEnable(uint8_t channel) + { + int val = 0; + switch (channel) { + case 0: + val = readRegister(XPOWERS_AXP192_GPIO1_CTL) & 0xF8; + writeRegister(XPOWERS_AXP192_GPIO1_CTL, val | 0x02); + return 0; + case 1: + val = readRegister(XPOWERS_AXP192_GPIO2_CTL) & 0xF8; + writeRegister(XPOWERS_AXP192_GPIO2_CTL, val | 0x02); + return 0; + default: + break; + } + return -1; + } + + int getBatteryPercent(void) + { + if (!isBatteryConnect()) { + return -1; + } + const static int table[11] = { + 3000, 3650, 3700, 3740, 3760, 3795, + 3840, 3910, 3980, 4070, 4150 + }; + uint16_t voltage = getBattVoltage(); + if (voltage < table[0]) + return 0; + for (int i = 0; i < 11; i++) { + if (voltage < table[i]) + return i * 10 - (10UL * (int)(table[i] - voltage)) / + (int)(table[i] - table[i - 1]);; + } + return 100; + } + + uint8_t getChipID(void) + { + return readRegister(XPOWERS_AXP192_IC_TYPE); + } + + + + + + /* + * GPIO setting + */ + int8_t pinMode(uint8_t pin, uint8_t mode) + { + int val = 0; + switch (pin) { + case PMU_GPIO0: + /* + * 000: NMOS open-drain output + * 001: Universal input function + * 010: Low noise LDO + * 011: reserved + * 100: ADC input + * 101: Low output + * 11X: Floating + * * */ + if (mode == INPUT || mode == INPUT_PULLDOWN) { + if (gpio[pin].mode != INPUT) { + gpio[pin].mode = INPUT; + } + val = readRegister(XPOWERS_AXP192_GPIO0_CTL) & 0xF8; + writeRegister(XPOWERS_AXP192_GPIO0_CTL, val | 0x01); + //Set pull-down mode + val = readRegister(XPOWERS_AXP192_GPIO012_PULLDOWN) & 0xFE; + if (mode == INPUT_PULLDOWN ) { + writeRegister(XPOWERS_AXP192_GPIO012_PULLDOWN, val | 0x01); + } else { + writeRegister(XPOWERS_AXP192_GPIO012_PULLDOWN, val); + } + } + break; + + case PMU_GPIO1: + /* + * 000: NMOS open-drain output + * 001: Universal input function + * 010: PWM1 output, high level is VINT, not Can add less than 100K pull-down resistance + * 011: reserved + * 100: ADC input + * 101: Low output + * 11X: Floating + * * */ + if (mode == INPUT || mode == INPUT_PULLDOWN) { + if (gpio[pin].mode != INPUT) { + gpio[pin].mode = INPUT; + } + val = readRegister(XPOWERS_AXP192_GPIO1_CTL) & 0xF8; + writeRegister(XPOWERS_AXP192_GPIO1_CTL, val | 0x01); + + //Set pull-down mode + val = readRegister(XPOWERS_AXP192_GPIO012_PULLDOWN) & 0xFD; + if (mode == INPUT_PULLDOWN ) { + writeRegister(XPOWERS_AXP192_GPIO012_PULLDOWN, val | 0x02); + } else { + writeRegister(XPOWERS_AXP192_GPIO012_PULLDOWN, val); + } + } + break; + + case PMU_GPIO2: + /* + * 000: NMOS open-drain output + * 001: Universal input function + * 010: PWM2 output, high level is VINT, not Can add less than 100K pull-down resistance + * 011: reserved + * 100: ADC input + * 101: Low output + * 11X: Floating + * */ + if (mode == INPUT || mode == INPUT_PULLDOWN) { + if (gpio[pin].mode != INPUT) { + gpio[pin].mode = INPUT; + } + val = readRegister(XPOWERS_AXP192_GPIO2_CTL) & 0xF8; + writeRegister(XPOWERS_AXP192_GPIO2_CTL, val | 0x01); + + //Set pull-down mode + val = readRegister(XPOWERS_AXP192_GPIO012_PULLDOWN) & 0xFB; + if (mode == INPUT_PULLDOWN ) { + writeRegister(XPOWERS_AXP192_GPIO012_PULLDOWN, val | 0x04); + } else { + writeRegister(XPOWERS_AXP192_GPIO012_PULLDOWN, val); + } + } + break; + + case PMU_GPIO3: + /* + * 00: External charging control + * 01: NMOS open-drain output port 3 + * 10: Universal input port 3 + * 11: ADC input + * * */ + if (mode == INPUT) { + if (gpio[pin].mode != INPUT) { + gpio[pin].mode = INPUT; + } + val = readRegister(XPOWERS_AXP192_GPIO34_CTL) & 0xFC; + writeRegister(XPOWERS_AXP192_GPIO34_CTL, val | 0x82 ); + } + break; + + case PMU_GPIO4: + /* + * 00: External charging control + * 01: NMOS open-drain output port 4 + * 10: Universal input port 4 + * 11: undefined + * * */ + if (mode == INPUT) { + if (gpio[pin].mode != INPUT) { + gpio[pin].mode = INPUT; + } + val = readRegister(XPOWERS_AXP192_GPIO34_CTL) & 0xF3; + writeRegister(XPOWERS_AXP192_GPIO34_CTL, val | 0x88 ); + } + break; + case PMU_GPIO5: + if (mode == INPUT) { + if (gpio[pin].mode != INPUT) { + gpio[pin].mode = INPUT; + } + val = readRegister(XPOWERS_AXP192_GPIO5_CTL) & 0xBF; + writeRegister(XPOWERS_AXP192_GPIO5_CTL, val | 0x40); + } + break; + default: + break; + } + return 0; + } + + uint8_t digitalRead(uint8_t pin) + { + switch (pin) { + case PMU_GPIO0: + return getRegisterBit(XPOWERS_AXP192_GPIO012_SIGNAL, 4); + case PMU_GPIO1: + return getRegisterBit(XPOWERS_AXP192_GPIO012_SIGNAL, 5); + case PMU_GPIO2: + return getRegisterBit(XPOWERS_AXP192_GPIO012_SIGNAL, 6); + case PMU_GPIO3: + return getRegisterBit(XPOWERS_AXP192_GPIO34_SIGNAL, 4); + case PMU_GPIO4: + return getRegisterBit(XPOWERS_AXP192_GPIO34_SIGNAL, 5); + case PMU_GPIO5: + return getRegisterBit(XPOWERS_AXP192_GPIO5_CTL, 4); + default: + break; + } + return 0; + } + + void digitalWrite(uint8_t pin, uint8_t val) + { + int reg = 0; + switch (pin) { + case PMU_GPIO0: + if (gpio[pin].mode != OUTPUT) { + gpio[pin].mode = OUTPUT; + } + reg = readRegister(XPOWERS_AXP192_GPIO0_CTL) & 0xFE; + writeRegister(XPOWERS_AXP192_GPIO0_CTL, val ? (reg | 0x01) : reg); + break; + case PMU_GPIO1: + if (gpio[pin].mode != OUTPUT) { + gpio[pin].mode = OUTPUT; + } + reg = readRegister(XPOWERS_AXP192_GPIO1_CTL) & 0xFD; + writeRegister(XPOWERS_AXP192_GPIO1_CTL, val ? (reg | 0x01) : reg); + break; + case PMU_GPIO2: + if (gpio[pin].mode != OUTPUT) { + gpio[pin].mode = OUTPUT; + } + reg = readRegister(XPOWERS_AXP192_GPIO2_CTL) & 0xFB; + writeRegister(XPOWERS_AXP192_GPIO2_CTL, val ? (reg | 0x01) : reg); + break; + case PMU_GPIO3: + if (gpio[pin].mode != OUTPUT) { + gpio[pin].mode = OUTPUT; + reg = readRegister(XPOWERS_AXP192_GPIO34_CTL) & 0xFC; + writeRegister(XPOWERS_AXP192_GPIO34_CTL, reg | 0x01); + } + reg = readRegister(XPOWERS_AXP192_GPIO34_SIGNAL) & 0xF7; + writeRegister(XPOWERS_AXP192_GPIO34_SIGNAL, val ? (val | 0x08) : reg); + break; + case PMU_GPIO4: + if (gpio[pin].mode != OUTPUT) { + gpio[pin].mode = OUTPUT; + reg = readRegister(XPOWERS_AXP192_GPIO34_CTL) & 0xF3; + writeRegister(XPOWERS_AXP192_GPIO34_CTL, reg | 0x04); + } + reg = readRegister(XPOWERS_AXP192_GPIO34_SIGNAL) & 0xEF; + writeRegister(XPOWERS_AXP192_GPIO34_SIGNAL, val ? (val | 0x10) : reg); + break; + case PMU_GPIO5: + if (gpio[pin].mode != OUTPUT) { + gpio[pin].mode = OUTPUT; + reg = readRegister(XPOWERS_AXP192_GPIO5_CTL) & 0xBF; + writeRegister(XPOWERS_AXP192_GPIO5_CTL, reg); + } + reg = readRegister(XPOWERS_AXP192_GPIO5_CTL) & 0xDF; + writeRegister(XPOWERS_AXP192_GPIO5_CTL, val ? (reg | 0x20) : reg); + break; + default: + break; + } + } + +#if 0 + // ! Need FIX + uint16_t analogRead(uint8_t pin) + { + switch (pin) { + case PMU_GPIO0: + if (gpio[pin].mode != ANALOG) { + // Enable GPIO ADC Function + uint8_t val = readRegister(XPOWERS_AXP192_GPIO0_CTL) & 0xF8; + writeRegister(XPOWERS_AXP192_GPIO0_CTL, val | 0x04); + + //Enable ADC2 / GPIO0 + // val = readRegister(XPOWERS_AXP192_ADC_EN2) | 0x08; + // writeRegister(XPOWERS_AXP192_ADC_EN2, val ); + setRegisterBit(XPOWERS_AXP192_ADC_EN2, 3); + + // Set adc input range 0~2.0475V + val = readRegister(XPOWERS_AXP192_ADC_INPUTRANGE) & 0xFE; + writeRegister(XPOWERS_AXP192_ADC_INPUTRANGE, val); + gpio[pin].mode = ANALOG; + } + return readRegisterH8L4(XPOWERS_AXP192_GPIO0_VOL_ADC_H8, XPOWERS_AXP192_GPIO0_VOL_ADC_L4); + + case PMU_GPIO1: + if (gpio[pin].mode != ANALOG) { + // Enable GPIO ADC Function + uint8_t val = readRegister(XPOWERS_AXP192_GPIO1_CTL) & 0xF8; + writeRegister(XPOWERS_AXP192_GPIO1_CTL, val | 0x04); + + //Enable ADC2 / GPIO1 + // val = readRegister(XPOWERS_AXP192_ADC_EN2) | 0x04; + // writeRegister(XPOWERS_AXP192_ADC_EN2, val ); + setRegisterBit(XPOWERS_AXP192_ADC_EN2, 2); + + + // Set adc input range 0~2.0475V + val = readRegister(XPOWERS_AXP192_ADC_INPUTRANGE) & 0xFD; + writeRegister(XPOWERS_AXP192_ADC_INPUTRANGE, val); + gpio[pin].mode = ANALOG; + } + return readRegisterH8L4(XPOWERS_AXP192_GPIO1_VOL_ADC_H8, XPOWERS_AXP192_GPIO1_VOL_ADC_L4); + + case PMU_GPIO2: + if (gpio[pin].mode != ANALOG) { + // Enable GPIO ADC Function + uint8_t val = readRegister(XPOWERS_AXP192_GPIO1_CTL) & 0xF8; + writeRegister(XPOWERS_AXP192_GPIO1_CTL, val | 0x04); + //Enable ADC2 / GPIO1 + // val = readRegister(XPOWERS_AXP192_ADC_EN2) | 0x02; + // writeRegister(XPOWERS_AXP192_ADC_EN2, val ); + setRegisterBit(XPOWERS_AXP192_ADC_EN2, 1); + + // Set adc input range 0~2.0475V + val = readRegister(XPOWERS_AXP192_ADC_INPUTRANGE) & 0xFB; + writeRegister(XPOWERS_AXP192_ADC_INPUTRANGE, val); + gpio[pin].mode = ANALOG; + } + return readRegisterH8L4(XPOWERS_AXP192_GPIO2_VOL_ADC_H8, XPOWERS_AXP192_GPIO2_VOL_ADC_L4); + + + case PMU_GPIO3: + if (gpio[pin].mode != ANALOG) { + // Enable GPIO ADC Function + uint8_t val = readRegister(XPOWERS_AXP192_GPIO1_CTL) & 0xF8; + writeRegister(XPOWERS_AXP192_GPIO1_CTL, val | 0x04); + + //Enable ADC2 / GPIO1 + // val = readRegister(XPOWERS_AXP192_ADC_EN2) | 0X01; + // writeRegister(XPOWERS_AXP192_ADC_EN2, val ); + setRegisterBit(XPOWERS_AXP192_ADC_EN2, 0); + + // Set adc input range 0~2.0475V + val = readRegister(XPOWERS_AXP192_ADC_INPUTRANGE) & 0xF7; + writeRegister(XPOWERS_AXP192_ADC_INPUTRANGE, val); + gpio[pin].mode = ANALOG; + } + return readRegisterH8L4(XPOWERS_AXP192_GPIO3_VOL_ADC_H8, XPOWERS_AXP192_GPIO3_VOL_ADC_L4); + + case PMU_TS_PIN: + if (gpio[pin].mode != ANALOG) { + // Enable TS PIN ADC Function + setRegisterBit(XPOWERS_AXP192_ADC_SPEED, 2); + // uint8_t val = readRegister(XPOWERS_AXP192_ADC_SPEED) & 0xFB; + // writeRegister(XPOWERS_AXP192_ADC_SPEED, val | 0x04); + gpio[pin].mode = ANALOG; + } + return readRegisterH8L4(XPOWERS_AXP192_TS_IN_H8, XPOWERS_AXP192_TS_IN_L4); + break; + default: + break; + } + return 0; + } +#endif + + + /** + * Sleep function + */ + bool enableSleep() + { + return setRegisterBit(XPOWERS_AXP192_VOFF_SET, 3); + } + + /* + * Pekey function + */ + + /** + * @brief Set the PEKEY power-on long press time. + * @param opt: See xpowers_press_on_time_t enum for details. + * @retval + */ + bool setPowerKeyPressOnTime(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP192_POK_SET); + if (val == -1)return false; + return 0 == writeRegister(XPOWERS_AXP192_POK_SET, (val & 0x3F) | (opt << 6)); + } + + /** + * @brief Get the PEKEY power-on long press time. + * @retval See xpowers_press_on_time_t enum for details. + */ + uint8_t getPowerKeyPressOnTime() + { + int val = readRegister(XPOWERS_AXP192_POK_SET); + if (val == -1)return 0; + return (val & 0xC0) >> 6; + } + + /** + * @brief Set the PEKEY power-off long press time. + * @param opt: See xpowers_press_off_time_t enum for details. + * @retval + */ + bool setPowerKeyPressOffTime(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP192_POK_SET); + if (val == -1)return false; + return 0 == writeRegister(XPOWERS_AXP192_POK_SET, (val & 0xFC) | opt); + } + + /** + * @brief Get the PEKEY power-off long press time. + * @retval See xpowers_press_off_time_t enum for details. + */ + uint8_t getPowerKeyPressOffTime() + { + int val = readRegister(XPOWERS_AXP192_POK_SET); + if (val == -1)return 0; + return (val & 0x03); + } + + + void setPowerKeyLongPressOnTime(xpowers_axp192_pekey_long_press_t opt) + { + int val = readRegister(XPOWERS_AXP192_POK_SET); + if (val == -1)return; + writeRegister(XPOWERS_AXP192_POK_SET, (val & 0xCF) | (opt << 4)); + } + + void enablePowerKeyLongPressPowerOff() + { + setRegisterBit(XPOWERS_AXP192_POK_SET, 3); + } + + void disablePowerKeyLongPressPowerOff() + { + clrRegisterBit(XPOWERS_AXP192_POK_SET, 3); + } + + +protected: + + uint16_t getPowerChannelVoltage(uint8_t channel) + { + switch (channel) { + case XPOWERS_DCDC1: + return getDC1Voltage(); + case XPOWERS_DCDC2: + return getDC2Voltage(); + case XPOWERS_DCDC3: + return getDC3Voltage(); + case XPOWERS_LDO2: + return getLDO2Voltage(); + case XPOWERS_LDO3: + return getLDO3Voltage(); + case XPOWERS_LDOIO: + return getLDOioVoltage(); + default: + break; + } + return 0; + } + + bool inline enablePowerOutput(uint8_t channel) + { + /* + return 0 == writeRegister(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, + val | readRegister(XPOWERS_AXP192_LDO23_DC123_EXT_CTL)); + */ + switch (channel) { + case XPOWERS_DCDC1: + return enableDC1(); + case XPOWERS_DCDC2: + return enableDC2(); + case XPOWERS_DCDC3: + return enableDC3(); + case XPOWERS_LDO2: + return enableLDO2(); + case XPOWERS_LDO3: + return enableLDO3(); + case XPOWERS_LDOIO: + return enableLDOio(); + case XPOWERS_VBACKUP: + return enableBackupBattCharger(); + default: + break; + } + return false; + } + + bool inline disablePowerOutput(uint8_t channel) + { + /* + return 0 == writeRegister(XPOWERS_AXP192_LDO23_DC123_EXT_CTL, + val & readRegister(XPOWERS_AXP192_LDO23_DC123_EXT_CTL)); + */ + if (getProtectedChannel(channel)) { + log_e("Failed to disable the power channel, the power channel has been protected"); + return false; + } + switch (channel) { + case XPOWERS_DCDC1: + return disableDC1(); + case XPOWERS_DCDC2: + return disableDC2(); + case XPOWERS_DCDC3: + return disableDC3(); + case XPOWERS_LDO2: + return disableLDO2(); + case XPOWERS_LDO3: + return disableLDO3(); + case XPOWERS_LDOIO: + return disableLDOio(); + case XPOWERS_VBACKUP: + return disableBackupBattCharger(); + default: + break; + } + return false; + } + + bool inline isPowerChannelEnable(uint8_t channel) + { + switch (channel) { + case XPOWERS_DCDC1: + return isEnableDC1(); + case XPOWERS_DCDC2: + return isEnableDC2(); + case XPOWERS_DCDC3: + return isEnableDC3(); + case XPOWERS_LDO2: + return isEnableLDO2(); + case XPOWERS_LDO3: + return isEnableLDO3(); + case XPOWERS_LDOIO: + return isEnableLDOio(); + case XPOWERS_VBACKUP: + return isEanbleBackupCharger(); + default: + break; + } + return false; + } + + + bool inline setPowerChannelVoltage(uint8_t channel, uint16_t millivolt) + { + if (getProtectedChannel(channel)) { + log_e("Failed to set the power channel, the power channel has been protected"); + return false; + } + switch (channel) { + case XPOWERS_DCDC1: + return setDC1Voltage(millivolt); + case XPOWERS_DCDC2: + return setDC2Voltage(millivolt); + case XPOWERS_DCDC3: + return setDC3Voltage(millivolt); + case XPOWERS_LDO2: + return setLDO2Voltage(millivolt); + case XPOWERS_LDO3: + return setLDO3Voltage(millivolt); + case XPOWERS_LDOIO: + return setLDOioVoltage(millivolt); + case XPOWERS_VBACKUP: + //TODO: + // return setBackupBattChargerVoltage(millivolt); + default: + break; + } + return false; + } + + bool inline getPowerEnable(uint8_t val) + { + return (bool)(readRegister(XPOWERS_AXP192_LDO23_DC123_EXT_CTL) & val); + } + + bool initImpl() + { + if (getChipID() == XPOWERS_AXP192_CHIP_ID) { + setChipModel(XPOWERS_AXP192); + return true; + } + return false; + } + + + /* + * Interrupt control functions + */ + bool setInterruptImpl(uint64_t opts, bool enable) + { + int res = 0; + int data = 0, value = 0; + + log_d("%s %s - 0x%lx\n", __func__, enable ? "ENABLE" : "DISABLE", (unsigned long)opts); + + if (opts & 0xFF) { + value = opts & 0xFF; + data = readRegister(XPOWERS_AXP192_INTEN1); + res |= writeRegister(XPOWERS_AXP192_INTEN1, enable ? (data | value) : (data & (~value))); + } + + if (opts & 0xFF00) { + value = opts >> 8; + data = readRegister(XPOWERS_AXP192_INTEN2); + res |= writeRegister(XPOWERS_AXP192_INTEN2, enable ? (data | value) : (data & (~value))); + } + + if (opts & 0xFF0000) { + value = opts >> 16; + data = readRegister(XPOWERS_AXP192_INTEN3); + res |= writeRegister(XPOWERS_AXP192_INTEN3, enable ? (data | value) : (data & (~value))); + } + + if (opts & 0xFF000000) { + value = opts >> 24; + data = readRegister(XPOWERS_AXP192_INTEN4); + res |= writeRegister(XPOWERS_AXP192_INTEN4, enable ? (data | value) : (data & (~value))); + } + + if (opts & 0xFF00000000) { + value = opts >> 32; + data = readRegister(XPOWERS_AXP192_INTEN5); + res |= writeRegister(XPOWERS_AXP192_INTEN5, enable ? (data | value) : (data & (~value))); + } + return res == 0; + } + + /* + * Signal Capture control functions + */ + bool setSignalCaptureImpl(uint32_t opts, bool enable) + { + int value = 0; + if (opts & 0xFF) { + value = readRegister(XPOWERS_AXP192_ADC_EN1); + writeRegister(XPOWERS_AXP192_ADC_EN1, enable ? (value | opts) : (value & (~opts))); + } + if (opts & 0xFF00) { + opts >>= 8; + value = readRegister(XPOWERS_AXP192_ADC_EN2); + writeRegister(XPOWERS_AXP192_ADC_EN2, enable ? (value | opts) : (value & (~opts))); + } + return true; + } + + const char *getChipNameImpl(void) + { + return "AXP192"; + } + + +private: + const uint16_t chargeTargetVol[4] = {4100, 4150, 4200, 4360}; + uint8_t statusRegister[5]; + xpowers_gpio_t gpio[6]; +}; + + + diff --git a/buildroot/package/axp2101/src/XPowersLib/XPowersAXP202.tpp b/buildroot/package/axp2101/src/XPowersLib/XPowersAXP202.tpp new file mode 100644 index 000000000..6faf5c377 --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/XPowersAXP202.tpp @@ -0,0 +1,1704 @@ +/** + * + * @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 XPowersAXP202.tpp + * @author Lewis He (lewishe@outlook.com) + * @date 2023-03-28 + * + */ +#if defined(ARDUINO) +#include +#else +#include +#endif /*ARDUINO*/ +#include "XPowersCommon.tpp" +#include "REG/AXP202Constants.h" +#include "XPowersLibInterface.hpp" + + +typedef enum { + XPOWERS_AXP202_BOOT_TIME_128MS, + XPOWERS_AXP202_BOOT_TIME_512MS, + XPOWERS_AXP202_BOOT_TIME_1S, + XPOWERS_AXP202_BOOT_TIME_2S, +} xpowers_axp202_boot_time_t; + + + + + +typedef enum { + XPOWERS_AXP202_CHG_ITERM_LESS_10_PERCENT, + XPOWERS_AXP202_CHG_ITERM_LESS_15_PERCENT, +} xpowers_axp202_chg_iterm_t; + + +typedef enum { + XPOWERS_AXP202_PRECHG_TIMEOUT_30MIN, + XPOWERS_AXP202_PRECHG_TIMEOUT_40MIN, + XPOWERS_AXP202_PRECHG_TIMEOUT_50MIN, + XPOWERS_AXP202_PRECHG_TIMEOUT_60MIN, +} xpoers_axp202_prechg_to_t; + +typedef enum { + XPOWERS_AXP202_POWEROFF_4S, + XPOWERS_AXP202_POWEROFF_65, + XPOWERS_AXP202_POWEROFF_8S, + XPOWERS_AXP202_POWEROFF_10S, +} xpowers_axp202_pekey_poweroff_arg_t; + + +typedef enum { + XPOWERS_AXP202_LONGPRESS_1000MS, + XPOWERS_AXP202_LONGPRESS_1500MS, + XPOWERS_AXP202_LONGPRESS_2000MS, + XPOWERS_AXP202_LONGPRESS_2500MS, +} xpowers_axp202_pekey_long_press_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_AXP202_CHG_CONS_TIMEOUT_7H, + XPOWERS_AXP202_CHG_CONS_TIMEOUT_8H, + XPOWERS_AXP202_CHG_CONS_TIMEOUT_9H, + XPOWERS_AXP202_CHG_CONS_TIMEOUT_10H, +} xpowers_axp202_chg_cons_to_t; + + +typedef enum { + XPOWERS_AXP202_BACKUP_BAT_VOL_3V1, + XPOWERS_AXP202_BACKUP_BAT_VOL_3V, + XPOWERS_AXP202_BACKUP_BAT_VOL_3V0, //!NEED FIX,DATASHEET ERROR! + XPOWERS_AXP202_BACKUP_BAT_VOL_2V5, +} xpowers_axp202_backup_batt_vol_t; + +typedef enum { + XPOWERS_AXP202_BACKUP_BAT_CUR_50UA, + XPOWERS_AXP202_BACKUP_BAT_CUR_100UA, + XPOWERS_AXP202_BACKUP_BAT_CUR_200UA, + XPOWERS_AXP202_BACKUP_BAT_CUR_400UA, +} xpowers_axp202_backup_batt_curr_t; + + +class XPowersAXP202 : + public XPowersCommon, public XPowersLibInterface +{ + friend class XPowersCommon; + + typedef enum { + MONITOR_TS_PIN = _BV(0), + MONITOR_APS_VOLTAGE = _BV(1), + MONITOR_USB_CURRENT = _BV(2), + MONITOR_USB_VOLTAGE = _BV(3), + MONITOR_AC_CURRENT = _BV(4), + MONITOR_AC_VOLTAGE = _BV(5), + MONITOR_BAT_CURRENT = _BV(6), + MONITOR_BAT_VOLTAGE = _BV(7), + MONITOR_ADC_IO3 = _BV(8), + MONITOR_ADC_IO2 = _BV(9), + MONITOR_ADC_IO1 = _BV(10), + MONITOR_ADC_IO0 = _BV(11), + MONITOR_TEMPERATURE = _BV(16), + } axp202_adc_func_t; + +public: + +#if defined(ARDUINO) + XPowersAXP202(TwoWire &w, int sda = SDA, int scl = SCL, uint8_t addr = AXP202_SLAVE_ADDRESS) + { + __wire = &w; + __sda = sda; + __scl = scl; + __addr = addr; + } +#endif + + XPowersAXP202(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) + { + thisReadRegCallback = readRegCallback; + thisWriteRegCallback = writeRegCallback; + __addr = addr; + } + + XPowersAXP202() + { +#if defined(ARDUINO) + __wire = &Wire; + __sda = SDA; + __scl = SCL; +#endif + __addr = AXP202_SLAVE_ADDRESS; + } + + ~XPowersAXP202() + { + log_i("~XPowersAXP202"); + deinit(); + } + +#if defined(ARDUINO) + bool init(TwoWire &w, int sda = SDA, int scl = SCL, uint8_t addr = AXP202_SLAVE_ADDRESS) + { + __wire = &w; + __sda = sda; + __scl = scl; + __addr = addr; + return begin(); + } +#endif + + bool init() + { + return begin(); + } + + void deinit() + { + end(); + } + + uint16_t status() + { + return readRegister(XPOWERS_AXP202_STATUS); + } + + bool isAcinVbusStart() + { + return getRegisterBit(XPOWERS_AXP202_STATUS, 0); + } + + bool isDischarge() + { + return !getRegisterBit(XPOWERS_AXP202_STATUS, 2); + } + + bool isVbusIn(void) + { + return getRegisterBit(XPOWERS_AXP202_STATUS, 5); + } + + bool isAcinEfficient() + { + return getRegisterBit(XPOWERS_AXP202_STATUS, 6); + } + + bool isAcinIn() + { + return getRegisterBit(XPOWERS_AXP202_STATUS, 7); + } + + bool isOverTemperature() + { + return getRegisterBit(XPOWERS_AXP202_MODE_CHGSTATUS, 7); + } + + bool isCharging(void) + { + return getRegisterBit(XPOWERS_AXP202_MODE_CHGSTATUS, 6); + } + + bool isBatteryConnect(void) + { + return getRegisterBit(XPOWERS_AXP202_MODE_CHGSTATUS, 5); + } + + bool isBattInActiveMode() + { + return getRegisterBit(XPOWERS_AXP202_MODE_CHGSTATUS, 3); + } + + bool isChargeCurrLessPreset() + { + return getRegisterBit(XPOWERS_AXP202_MODE_CHGSTATUS, 2); + } + + void enableVbusVoltageLimit() + { + setRegisterBit(XPOWERS_AXP202_IPS_SET, 6); + } + + void disableVbusVoltageLimit() + { + clrRegisterBit(XPOWERS_AXP202_IPS_SET, 6); + } + + void setVbusVoltageLimit(xpowers_axp202_vbus_vol_limit_t opt) + { + int val = readRegister(XPOWERS_AXP202_IPS_SET); + if (val == -1)return; + val &= 0xC7; + writeRegister(XPOWERS_AXP202_IPS_SET, val | (opt << 3)); + } + + /** + * @brief Set VBUS Current Input Limit. + * @param opt: View the related chip type xpowers_axp202_vbus_cur_limit_t enumeration + * parameters in "XPowersParams.hpp" + * @retval true valid false invalid + */ + bool setVbusCurrentLimit(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP202_IPS_SET); + if (val == -1)return false; + val &= 0xFC; + switch (opt) { + case XPOWERS_AXP202_VBUS_CUR_LIM_900MA: + return writeRegister(XPOWERS_AXP202_IPS_SET, val); + case XPOWERS_AXP202_VBUS_CUR_LIM_500MA: + return writeRegister(XPOWERS_AXP202_IPS_SET, val | 0x01); + case XPOWERS_AXP202_VBUS_CUR_LIM_100MA: + return writeRegister(XPOWERS_AXP202_IPS_SET, val | 0x02); + case XPOWERS_AXP202_VBUS_CUR_LIM_OFF: + return writeRegister(XPOWERS_AXP202_IPS_SET, val | 0x03); + default: + break; + } + return false; + } + + + /** + * @brief Get VBUS Current Input Limit. + * @retval View the related chip type xpowers_axp202_vbus_cur_limit_t enumeration + * parameters in "XPowersParams.hpp" + */ + uint8_t getVbusCurrentLimit(void) + { + int val = readRegister(XPOWERS_AXP202_IPS_SET); + if (val == -1)return false; + val &= 0x03; + return val; + } + + + // Set the minimum system operating voltage inside the PMU, + // below this value will shut down the PMU,Adjustment range 2600mV ~ 3300mV + bool setSysPowerDownVoltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP202_SYS_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP202_SYS_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP202_VOFF_VOL_MIN) { + log_e("Mistake ! SYS minimum output voltage is %umV", XPOWERS_AXP202_VOFF_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP202_VOFF_VOL_MAX) { + log_e("Mistake ! SYS maximum output voltage is %umV", XPOWERS_AXP202_VOFF_VOL_MAX); + return false; + } + + int val = readRegister(XPOWERS_AXP202_VOFF_SET); + if (val == -1)return false; + val &= 0xF8; + val |= (millivolt - XPOWERS_AXP202_VOFF_VOL_MIN) / XPOWERS_AXP202_SYS_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP202_VOFF_SET, val); + } + + uint16_t getSysPowerDownVoltage() + { + int val = readRegister(XPOWERS_AXP202_VOFF_SET); + if (val == -1)return 0; + val &= 0x07; + return (val * XPOWERS_AXP202_SYS_VOL_STEPS) + XPOWERS_AXP202_VOFF_VOL_MIN; + } + + /** + * @brief Set shutdown, calling shutdown will turn off all power channels, + * only VRTC belongs to normal power supply + * @retval None + */ + void shutdown() + { + setRegisterBit(XPOWERS_AXP202_OFF_CTL, 7); + } + + /* + * Charge setting + */ + void enableCharge() + { + setRegisterBit(XPOWERS_AXP202_CHARGE1, 7); + } + + void disableCharge() + { + clrRegisterBit(XPOWERS_AXP202_CHARGE1, 7); + } + + /** + * @brief Set charge target voltage. + * @param opt: See xpowers_axp202_chg_vol_t enum for details. + * @retval + */ + bool setChargeTargetVoltage(uint8_t opt) + { + if (opt >= XPOWERS_AXP202_CHG_VOL_MAX)return false; + int val = readRegister(XPOWERS_AXP202_CHARGE1); + if (val == -1) return false; + val &= 0x9F; + return 0 == writeRegister(XPOWERS_AXP202_CHARGE1, val | (opt << 5)); + } + + /** + * @brief Get charge target voltage settings. + * @retval See xpowers_axp202_chg_vol_t enum for details. + */ + uint8_t getChargeTargetVoltage() + { + int val = readRegister(XPOWERS_AXP202_CHARGE1); + if (val == -1) return 0; + return (val & 0x60) >> 5; + } + + /** + * @brief Set charge current settings. + * @retval See xpowers_axp202_chg_curr_t enum for details. + */ + bool setChargerConstantCurr(uint8_t opt) + { + if (opt > 0x0F)return false; + int val = readRegister(XPOWERS_AXP202_CHARGE1); + if (val == -1) { + return false; + } + val &= 0xF0; + return 0 == writeRegister(XPOWERS_AXP202_CHARGE1, val | opt); + } + + /** + * @brief Get charge current settings. + * @retval See xpowers_axp202_chg_curr_t enum for details. + */ + uint8_t getChargerConstantCurr(void) + { + int val = readRegister(XPOWERS_AXP202_CHARGE1) & 0x0F; + // if (val == -1)return XPOWERS_AXP202_CHG_CUR_780MA; + //todo: + return val; + } + + void setChargerTerminationCurr(xpowers_axp202_chg_iterm_t opt) + { + switch (opt) { + case XPOWERS_AXP202_CHG_ITERM_LESS_10_PERCENT: + clrRegisterBit(XPOWERS_AXP202_CHARGE1, 0); + break; + case XPOWERS_AXP202_CHG_ITERM_LESS_15_PERCENT: + setRegisterBit(XPOWERS_AXP202_CHARGE1, 0); + break; + default: + break; + } + } + + uint8_t getChargerTerminationCurr() + { + return getRegisterBit(XPOWERS_AXP202_CHARGE1, 4); + } + + bool setPrechargeTimeout(xpoers_axp202_prechg_to_t opt) + { + int val = readRegister(XPOWERS_AXP202_CHARGE2); + if (val == -1)return false; + val &= 0x3F; + return 0 == writeRegister(XPOWERS_AXP202_CHARGE2, val | (opt << 6)); + } + + // External channel charge current setting,Range:300~1000mA + bool setChargerExternChannelCurr(uint16_t milliampere) + { + if (milliampere % XPOWERS_AXP202_CHG_EXT_CURR_STEP) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP202_CHG_EXT_CURR_STEP); + return false; + } + if (milliampere < XPOWERS_AXP202_CHG_EXT_CURR_MIN) { + log_e("Mistake ! The minimum external path charge current setting is: %umA", XPOWERS_AXP202_CHG_EXT_CURR_MIN); + return false; + } else if (milliampere > XPOWERS_AXP202_CHG_EXT_CURR_MAX) { + log_e("Mistake ! The maximum external channel charge current setting is: %umA", XPOWERS_AXP202_CHG_EXT_CURR_MAX); + return false; + } + int val = readRegister(XPOWERS_AXP202_CHARGE2); + if (val == -1)return false; + val &= 0xC7; + val |= ((milliampere - XPOWERS_AXP202_CHG_EXT_CURR_MIN ) / XPOWERS_AXP202_CHG_EXT_CURR_STEP); + return 0 == writeRegister(XPOWERS_AXP202_CHARGE2, val); + } + + bool enableChargerExternChannel() + { + return setRegisterBit(XPOWERS_AXP202_CHARGE2, 2); + } + + bool disableChargerExternChannel() + { + return clrRegisterBit(XPOWERS_AXP202_CHARGE2, 2); + } + + // Timeout setting in constant current mode + bool setChargerConstantTimeout(xpowers_axp202_chg_cons_to_t opt) + { + int val = readRegister(XPOWERS_AXP202_CHARGE2); + if (val == -1)return false; + val &= 0xFC; + return 0 == writeRegister(XPOWERS_AXP202_CHARGE2, val | opt); + } + + bool enableBackupBattCharger() + { + return setRegisterBit(XPOWERS_AXP202_BACKUP_CHG, 7); + } + + + bool disableBackupBattCharger() + { + return clrRegisterBit(XPOWERS_AXP202_BACKUP_CHG, 7); + } + + bool isEanbleBackupCharger() + { + return getRegisterBit(XPOWERS_AXP202_BACKUP_CHG, 7); + } + + bool setBackupBattChargerVoltage(xpowers_axp202_backup_batt_vol_t opt) + { + int val = readRegister(XPOWERS_AXP202_BACKUP_CHG); + if (val == -1)return false; + val &= 0x9F; + return 0 == writeRegister(XPOWERS_AXP202_BACKUP_CHG, val | (opt << 5)); + } + + bool setBackupBattChargerCurr(xpowers_axp202_backup_batt_curr_t opt) + { + int val = readRegister(XPOWERS_AXP202_BACKUP_CHG); + if (val == -1)return false; + val &= 0xFC; + return 0 == writeRegister(XPOWERS_AXP202_BACKUP_CHG, val | opt); + } + + /* + * Temperature + */ + float getTemperature() + { + return readRegisterH8L4(XPOWERS_AXP202_INTERNAL_TEMP_H8, XPOWERS_AXP202_INTERNAL_TEMP_L4) + * XPOWERS_AXP202_INTERNAL_TEMP_STEP - XPOWERS_AXP202_INERNAL_TEMP_OFFSET; + } + + bool enableTemperatureMeasure() + { + return setRegisterBit(XPOWERS_AXP202_ADC_EN2, 7); + } + + bool disableTemperatureMeasure() + { + return clrRegisterBit(XPOWERS_AXP202_ADC_EN2, 7); + } + + /* + * Power control LDOio functions + */ + bool isEnableLDOio(void) + { + int val = readRegister(XPOWERS_AXP202_GPIO0_CTL); + return (val & 0x02); + } + + bool enableLDOio(void) + { + int val = readRegister(XPOWERS_AXP202_GPIO0_CTL) & 0xF8; + return 0 == writeRegister(XPOWERS_AXP202_GPIO0_CTL, val | 0x02); + } + + bool disableLDOio(void) + { + int val = readRegister(XPOWERS_AXP202_GPIO0_CTL) & 0xF8; + return 0 == writeRegister(XPOWERS_AXP202_GPIO0_CTL, val); + } + + bool setLDOioVoltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP202_LDOIO_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP202_LDOIO_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP202_LDOIO_VOL_MIN) { + log_e("Mistake ! LDOIO minimum output voltage is %umV", XPOWERS_AXP202_LDOIO_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP202_LDOIO_VOL_MAX) { + log_e("Mistake ! LDOIO maximum output voltage is %umV", XPOWERS_AXP202_LDOIO_VOL_MAX); + return false; + } + int val = readRegister(XPOWERS_AXP202_GPIO0_VOL); + if (val == -1)return false; + val |= (((millivolt - XPOWERS_AXP202_LDOIO_VOL_MIN) / XPOWERS_AXP202_LDOIO_VOL_STEPS) << 4); + return 0 == writeRegister(XPOWERS_AXP202_GPIO0_VOL, val); + } + + uint16_t getLDOioVoltage(void) + { + int val = readRegister(XPOWERS_AXP202_GPIO0_VOL); + if (val == -1)return 0; + val >>= 4; + val *= XPOWERS_AXP202_LDOIO_VOL_STEPS; + val += XPOWERS_AXP202_LDOIO_VOL_MIN; + return val; + } + + /* + * Power control LDO2 functions + */ + bool isEnableLDO2(void) + { + return getRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 2); + } + + bool enableLDO2(void) + { + return setRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 2); + } + + bool disableLDO2(void) + { + return clrRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 2); + } + + bool setLDO2Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP202_LDO2_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP202_LDO2_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP202_LDO2_VOL_MIN) { + log_e("Mistake ! LDO2 minimum output voltage is %umV", XPOWERS_AXP202_LDO2_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP202_LDO2_VOL_MAX) { + log_e("Mistake ! LDO2 maximum output voltage is %umV", XPOWERS_AXP202_LDO2_VOL_MAX); + return false; + } + + int val = readRegister(XPOWERS_AXP202_LDO24OUT_VOL); + if (val == -1) return false; + val &= 0x0F; + return 0 == writeRegister(XPOWERS_AXP202_LDO24OUT_VOL, val | (((millivolt - XPOWERS_AXP202_LDO2_VOL_MIN) / XPOWERS_AXP202_LDO2_VOL_STEPS) << XPOWERS_AXP202_LDO2_VOL_BIT_MASK)); + } + + uint16_t getLDO2Voltage(void) + { + int val = readRegister(XPOWERS_AXP202_LDO24OUT_VOL) & 0xF0; + return (val >> XPOWERS_AXP202_LDO2_VOL_BIT_MASK) * XPOWERS_AXP202_LDO2_VOL_STEPS + XPOWERS_AXP202_LDO2_VOL_MIN; + } + + /* + * Power control LDO3 functions + */ + bool isEnableLDO3(void) + { + return getRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 6); + } + + bool enableLDO3(void) + { + return setRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 6); + } + + bool disableLDO3(void) + { + return clrRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 6); + } + + + bool setLDO3Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP202_LDO3_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP202_LDO3_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP202_LDO3_VOL_MIN) { + log_e("Mistake ! LDO3 minimum output voltage is %umV", XPOWERS_AXP202_LDO3_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP202_LDO3_VOL_MAX) { + log_e("Mistake ! LDO3 maximum output voltage is %umV", XPOWERS_AXP202_LDO3_VOL_MAX); + return false; + } + int val = readRegister(XPOWERS_AXP202_LDO3OUT_VOL) & 0x80; + return 0 == writeRegister(XPOWERS_AXP202_LDO3OUT_VOL, val | ((millivolt - XPOWERS_AXP202_LDO3_VOL_MIN) / XPOWERS_AXP202_LDO3_VOL_STEPS)); + } + + uint16_t getLDO3Voltage(void) + { + int val = readRegister(XPOWERS_AXP202_LDO3OUT_VOL); + if (val == -1)return 0; + // Returns the voltage value of VBUS if in pass-through mode + if (val & 0x80) { + log_i("ldo3 pass-through mode"); + return getVbusVoltage(); + } + val &= 0x7F; + return (val * XPOWERS_AXP202_LDO3_VOL_STEPS) + XPOWERS_AXP202_LDO3_VOL_MIN; + } + + /* + * Power control LDO4 functions + */ + bool isEnableLDO4(void) + { + return getRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 3); + } + + bool enableLDO4(void) + { + return setRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 3); + } + + bool disableLDO4(void) + { + return clrRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 3); + } + + // Support setting voltage + // 1.25 + // 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 + // 2.5 2.7 2.8 3.0 3.1 3.2 3.3 + bool setLDO4Voltage(uint16_t millivolt) + { + int index = -1; + for (int i = 0; i < 16; ++i) { + if (ldo4_table[i] == millivolt) { + index = i; + break; + } + } + if (index == -1) { + log_e("Mistake ! Out of adjustment range"); + return false; + } + int val = readRegister(XPOWERS_AXP202_LDO24OUT_VOL) ; + if (val == -1) { + return false; + } + return 0 == writeRegister(XPOWERS_AXP202_LDO24OUT_VOL, (val & 0xF0) | index); + } + + uint16_t getLDO4Voltage(void) + { + int val = readRegister(XPOWERS_AXP202_LDO24OUT_VOL); + if (val == -1)return 0; + val &= 0x0F; + return ldo4_table[val]; + } + + /* + * Power control DCDC2 functions + */ + void setDC2PwmMode(void) + { + int val = readRegister(XPOWERS_AXP202_DCDC_MODESET) & 0xFB; + writeRegister(XPOWERS_AXP202_DCDC_MODESET, val | 0x04); + } + + void setDC2AutoMode(void) + { + int val = readRegister(XPOWERS_AXP202_DCDC_MODESET) & 0xFB; + writeRegister(XPOWERS_AXP202_DCDC_MODESET, val); + } + + void enableDC2VRC(void) + { + // int val = readRegister(XPOWERS_AXP202_DC2_DVM); + // writeRegister(XPOWERS_AXP202_DC2_DVM, val | 0x04); + } + + void disableDC2VRC(void) + { + // int val = readRegister(XPOWERS_AXP202_DC2_DVM); + // writeRegister(XPOWERS_AXP202_DC2_DVM, val & 0xFB); + } + + bool setDC2VRC(uint8_t opts) + { + // if (opts > 1) { + // return false; + // } + // int val = readRegister(XPOWERS_AXP202_DC2_DVM) & 0xFE; + // writeRegister(XPOWERS_AXP202_DC2_DVM, val | opts); + return false; + } + + bool isEanbleDC2VRC(void) + { + // return (readRegister(XPOWERS_AXP202_DC2_DVM) & 0x04) == 0x04; + return 0; + } + + bool isEnableDC2(void) + { + return getRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 4); + } + + bool enableDC2(void) + { + return setRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 4); + } + + bool disableDC2(void) + { + return clrRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 4); + } + + bool setDC2Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP202_DC2_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP202_DC2_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP202_DC2_VOL_MIN) { + log_e("Mistake ! DCDC2 minimum output voltage is %umV", XPOWERS_AXP202_DC2_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP202_DC2_VOL_MAX) { + log_e("Mistake ! DCDC2 maximum output voltage is %umV", XPOWERS_AXP202_DC2_VOL_MAX); + return false; + } + int val = readRegister(XPOWERS_AXP202_DC2OUT_VOL); + if (val == -1)return false; + val &= 0x80; + val |= (millivolt - XPOWERS_AXP202_DC2_VOL_MIN) / XPOWERS_AXP202_DC2_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP202_DC2OUT_VOL, val); + } + + uint16_t getDC2Voltage(void) + { + int val = readRegister(XPOWERS_AXP202_DC2OUT_VOL); + if (val == -1)return 0; + return (val * XPOWERS_AXP202_DC2_VOL_STEPS) + XPOWERS_AXP202_DC2_VOL_MIN; + } + + /* + * Power control DCDC3 functions + */ + void setDC3PwmMode(void) + { + int val = readRegister(XPOWERS_AXP202_DCDC_MODESET) & 0xFD; + writeRegister(XPOWERS_AXP202_DCDC_MODESET, val | 0x02); + } + + void setDC3AutoMode(void) + { + int val = readRegister(XPOWERS_AXP202_DCDC_MODESET) & 0xFD; + writeRegister(XPOWERS_AXP202_DCDC_MODESET, val); + } + + bool isEnableDC3(void) + { + return getRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 1); + } + + bool enableDC3(void) + { + return setRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 1); + } + + bool disableDC3(void) + { + return clrRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 1); + } + + bool setDC3Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP202_DC3_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP202_DC3_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP202_DC3_VOL_MIN) { + log_e("Mistake ! DCDC3 minimum output voltage is %umV", XPOWERS_AXP202_DC3_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP202_DC3_VOL_MAX) { + log_e("Mistake ! DCDC3 maximum output voltage is %umV", XPOWERS_AXP202_DC3_VOL_MAX); + return false; + } + return 0 == writeRegister(XPOWERS_AXP202_DC3OUT_VOL, (millivolt - XPOWERS_AXP202_DC3_VOL_MIN) / XPOWERS_AXP202_DC3_VOL_STEPS); + } + + uint16_t getDC3Voltage(void) + { + int val = readRegister(XPOWERS_AXP202_DC3OUT_VOL); + if (val == -1)return 0; + return (val * XPOWERS_AXP202_DC3_VOL_STEPS) + XPOWERS_AXP202_DC3_VOL_MIN; + } + + /* + * Power control EXTEN functions + */ + bool enableExternalPin(void) + { + return setRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 6); + } + + bool disableExternalPin(void) + { + return clrRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 6); + } + + bool isEnableExternalPin(void) + { + return getRegisterBit(XPOWERS_AXP202_LDO234_DC23_CTL, 6); + } + + /* + * Interrupt status functions + */ + + /** + * @brief Get the interrupt controller mask value. + * @retval Mask value corresponds to xpowers_axp202_irq_t , + */ + uint64_t getIrqStatus(void) + { + statusRegister[0] = readRegister(XPOWERS_AXP202_INTSTS1); + statusRegister[1] = readRegister(XPOWERS_AXP202_INTSTS2); + statusRegister[2] = readRegister(XPOWERS_AXP202_INTSTS3); + statusRegister[3] = readRegister(XPOWERS_AXP202_INTSTS4); + statusRegister[4] = readRegister(XPOWERS_AXP202_INTSTS5); + return ((uint64_t)statusRegister[4]) << 32 | + ((uint64_t)statusRegister[3]) << 24 | + ((uint64_t)statusRegister[2]) << 16 | + ((uint64_t)statusRegister[1]) << 8 | + ((uint64_t)statusRegister[0]); + } + + /** + * @brief Clear interrupt controller state. + */ + void clearIrqStatus(void) + { + for (int i = 0; i < 4; i++) { + writeRegister(XPOWERS_AXP202_INTSTS1 + i, 0xFF); + } + writeRegister(XPOWERS_AXP202_INTSTS5, 0xFF); + } + + /** + * @brief Eanble PMU interrupt control mask . + * @param opt: View the related chip type xpowers_axp202_irq_t enumeration + * parameters in "XPowersParams.hpp" + * @retval + */ + bool enableIRQ(uint64_t opt) + { + return setInterruptImpl(opt, true); + } + + /** + * @brief Disable PMU interrupt control mask . + * @param opt: View the related chip type xpowers_axp202_irq_t enumeration + * parameters in "XPowersParams.hpp" + * @retval + */ + bool disableIRQ(uint64_t opt) + { + return setInterruptImpl(opt, false); + } + + bool isAcinOverVoltageIrq(void) + { + return (bool)(statusRegister[0] & _BV(7)); + } + + bool isAcinInserIrq(void) + { + return (bool)(statusRegister[0] & _BV(6)); + } + + bool isAcinRemoveIrq(void) + { + return (bool)(statusRegister[0] & _BV(5)); + } + + bool isVbusOverVoltageIrq(void) + { + return (bool)(statusRegister[0] & _BV(4)); + } + + bool isVbusInsertIrq(void) + { + return (bool)(statusRegister[0] & _BV(3)); + } + + bool isVbusRemoveIrq(void) + { + return (bool)(statusRegister[0] & _BV(2)); + } + + bool isVbusLowVholdIrq(void) + { + return (bool)(statusRegister[0] & _BV(1)); + } + + bool isBatInsertIrq(void) + { + return (bool)(statusRegister[1] & _BV(7)); + } + + bool isBatRemoveIrq(void) + { + return (bool)(statusRegister[1] & _BV(6)); + } + + bool isBattEnterActivateIrq(void) + { + return (bool)(statusRegister[1] & _BV(5)); + } + + bool isBattExitActivateIrq(void) + { + return (bool)(statusRegister[1] & _BV(4)); + } + + bool isBatChagerStartIrq(void) + { + return (bool)(statusRegister[1] & _BV(3)); + } + + bool isBatChagerDoneIrq(void) + { + return (bool)(statusRegister[1] & _BV(2)); + } + + bool isBattTempHighIrq(void) + { + return (bool)(statusRegister[1] & _BV(1)); + } + + bool isBattTempLowIrq(void) + { + return (bool)(statusRegister[1] & _BV(0)); + } + + bool isChipOverTemperatureIrq(void) + { + return (bool)(statusRegister[2] & _BV(7)); + } + + bool isChargingCurrentLessIrq(void) + { + return (bool)(statusRegister[2] & _BV(6)); + } + + bool isDC1VoltageLessIrq(void) + { + return (bool)(statusRegister[2] & _BV(5)); + } + + bool isDC2VoltageLessIrq(void) + { + return (bool)(statusRegister[2] & _BV(4)); + } + + bool isDC3VoltageLessIrq(void) + { + return (bool)(statusRegister[2] & _BV(3)); + } + + bool isPekeyShortPressIrq(void) + { + return (bool)(statusRegister[2] & _BV(1)); + } + + bool isPekeyLongPressIrq(void) + { + return (bool)(statusRegister[2] & _BV(0)); + } + + bool isNOEPowerOnIrq(void) + { + return (bool)(statusRegister[3] & _BV(7)); + } + + bool isNOEPowerDownIrq(void) + { + return (bool)(statusRegister[3] & _BV(6)); + } + + bool isVbusEffectiveIrq(void) + { + return (bool)(statusRegister[3] & _BV(5)); + } + + bool isVbusInvalidIrq(void) + { + return (bool)(statusRegister[3] & _BV(4)); + } + + bool isVbusSessionIrq(void) + { + return (bool)(statusRegister[3] & _BV(3)); + } + + bool isVbusSessionEndIrq(void) + { + return (bool)(statusRegister[3] & _BV(2)); + } + + bool isLowVoltageLevel2Irq(void) + { + return (bool)(statusRegister[3] & _BV(0)); + } + + //IRQ5 REGISTER : + bool isWdtExpireIrq(void) + { + return (bool)(statusRegister[4] & _BV(7)); + } + + bool isGpio2EdgeTriggerIrq(void) + { + return (bool)(statusRegister[4] & _BV(2)); + } + + bool isGpio1EdgeTriggerIrq(void) + { + return (bool)(statusRegister[4] & _BV(1)); + } + + bool isGpio0EdgeTriggerIrq(void) + { + return (bool)(statusRegister[4] & _BV(0)); + } + + /* + * ADC Functions + */ + + bool enableBattDetection() + { + return setRegisterBit(XPOWERS_AXP202_OFF_CTL, 6); + } + + bool disableBattDetection() + { + return clrRegisterBit(XPOWERS_AXP202_OFF_CTL, 6); + } + + bool enableVbusVoltageMeasure() + { + return setSignalCaptureImpl(MONITOR_USB_CURRENT | MONITOR_USB_VOLTAGE, true); + } + + bool disableVbusVoltageMeasure() + { + return setSignalCaptureImpl(MONITOR_USB_CURRENT | MONITOR_USB_VOLTAGE, false); + } + + bool enableBattVoltageMeasure() + { + return setSignalCaptureImpl(MONITOR_BAT_CURRENT | MONITOR_BAT_VOLTAGE, true); + } + + bool disableBattVoltageMeasure() + { + return setSignalCaptureImpl(MONITOR_BAT_CURRENT | MONITOR_BAT_VOLTAGE, false); + } + + bool enableSystemVoltageMeasure() + { + return setSignalCaptureImpl(MONITOR_APS_VOLTAGE, true); + } + + bool disableSystemVoltageMeasure() + { + return setSignalCaptureImpl(MONITOR_APS_VOLTAGE, false); + } + + bool enableTSPinMeasure() + { + return setSignalCaptureImpl(MONITOR_TS_PIN, true); + } + + bool disableTSPinMeasure() + { + return setSignalCaptureImpl(MONITOR_TS_PIN, false); + } + + bool enableAdcChannel(uint32_t opts) + { + return setSignalCaptureImpl(opts, true); + } + + bool disableAdcChannel(uint32_t opts) + { + return setSignalCaptureImpl(opts, false); + } + + uint16_t getVbusVoltage() + { + if (!isVbusIn()) { + return 0; + } + return readRegisterH8L4(XPOWERS_AXP202_VBUS_VOL_H8, + XPOWERS_AXP202_VBUS_VOL_L4 + ) * XPOWERS_AXP202_VBUS_VOLTAGE_STEP; + } + + float getVbusCurrent() + { + if (!isVbusIn()) { + return 0; + } + return readRegisterH8L4(XPOWERS_AXP202_VBUS_CUR_H8, + XPOWERS_AXP202_VBUS_CUR_L4 + ) * XPOWERS_AXP202_VBUS_CUR_STEP; + } + + uint16_t getBattVoltage() + { + if (!isBatteryConnect()) { + return 0; + } + return readRegisterH8L4(XPOWERS_AXP202_BAT_AVERVOL_H8, + XPOWERS_AXP202_BAT_AVERVOL_L4 + ) * XPOWERS_AXP202_BATT_VOLTAGE_STEP; + } + + float getBattDischargeCurrent() + { + if (!isBatteryConnect()) { + return 0; + } + return readRegisterH8L5(XPOWERS_AXP202_BAT_AVERDISCHGCUR_H8, + XPOWERS_AXP202_BAT_AVERDISCHGCUR_L5) * XPOWERS_AXP202_BATT_DISCHARGE_CUR_STEP; + } + + uint16_t getAcinVoltage() + { + if (!isAcinIn()) { + return 0; + } + return readRegisterH8L4(XPOWERS_AXP202_ACIN_VOL_H8, XPOWERS_AXP202_ACIN_VOL_L4) * XPOWERS_AXP202_ACIN_VOLTAGE_STEP; + } + + float getAcinCurrent() + { + if (!isAcinIn()) { + return 0; + } + return readRegisterH8L4(XPOWERS_AXP202_ACIN_CUR_H8, XPOWERS_AXP202_ACIN_CUR_L4) * XPOWERS_AXP202_ACIN_CUR_STEP; + } + + uint16_t getSystemVoltage() + { + return readRegisterH8L4(XPOWERS_AXP202_APS_AVERVOL_H8, XPOWERS_AXP202_APS_AVERVOL_L4) * XPOWERS_AXP202_APS_VOLTAGE_STEP; + } + + /* + * Timer Control + */ + void setTimerout(uint8_t minute) + { + writeRegister(XPOWERS_AXP202_TIMER_CTL, 0x80 | minute); + } + + void disableTimer() + { + writeRegister(XPOWERS_AXP202_TIMER_CTL, 0x80); + } + + void clearTimerFlag() + { + setRegisterBit(XPOWERS_AXP202_TIMER_CTL, 7); + } + + /* + * Data Buffer + */ + bool writeDataBuffer(uint8_t *data, uint8_t size) + { + if (size > XPOWERS_AXP202_DATA_BUFFER_SIZE)return false; + for (int i = 0; i < size; ++i) { + writeRegister(XPOWERS_AXP202_DATA_BUFFER1 + i, data[i]); + } + return true; + } + + bool readDataBuffer(uint8_t *data, uint8_t size) + { + if (size > XPOWERS_AXP202_DATA_BUFFER_SIZE)return false; + for (int i = 0; i < size; ++i) { + data[i] = readRegister(XPOWERS_AXP202_DATA_BUFFER1 + i); + } + return true; + } + + /* + * Charge led functions + */ + + /** + * @brief Set charging led mode. + * @retval See xpowers_chg_led_mode_t enum for details. + */ + void setChargingLedMode(uint8_t mode) + { + int val; + switch (mode) { + case XPOWERS_CHG_LED_OFF: + case XPOWERS_CHG_LED_BLINK_1HZ: + case XPOWERS_CHG_LED_BLINK_4HZ: + case XPOWERS_CHG_LED_ON: + val = readRegister(XPOWERS_AXP202_OFF_CTL); + if (val == -1)return; + val &= 0xC7; + val |= 0x08; //use manual ctrl + val |= (mode << 4); + writeRegister(XPOWERS_AXP202_OFF_CTL, val); + break; + case XPOWERS_CHG_LED_CTRL_CHG: + clrRegisterBit(XPOWERS_AXP202_OFF_CTL, 3); + break; + default: + break; + } + } + + uint8_t getChargingLedMode() + { + if (!getRegisterBit(XPOWERS_AXP202_OFF_CTL, 3)) { + return XPOWERS_CHG_LED_CTRL_CHG; + } + int val = readRegister(XPOWERS_AXP202_OFF_CTL); + if (val == -1)return XPOWERS_CHG_LED_OFF; + val &= 0x30; + return val >> 4; + } + + /* + * Coulomb counter control + */ + void enableCoulomb() + { + setRegisterBit(XPOWERS_AXP202_COULOMB_CTL, 7); + } + + void disableCoulomb() + { + clrRegisterBit(XPOWERS_AXP202_COULOMB_CTL, 7); + } + + void stopCoulomb() + { + setRegisterBit(XPOWERS_AXP202_COULOMB_CTL, 6); + } + + void clearCoulomb() + { + setRegisterBit(XPOWERS_AXP202_COULOMB_CTL, 5); + } + + uint32_t getBattChargeCoulomb() + { + int data[4]; + data[0] = readRegister(XPOWERS_AXP202_BAT_CHGCOULOMB3); + data[1] = readRegister(XPOWERS_AXP202_BAT_CHGCOULOMB2); + data[2] = readRegister(XPOWERS_AXP202_BAT_CHGCOULOMB1); + data[3] = readRegister(XPOWERS_AXP202_BAT_CHGCOULOMB0); + for (int i = 0; i < 4; ++i) { + if (data[i] == -1)return 0; + } + return ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) | ((uint32_t)data[2] << 8) | (uint32_t)data[3]; + } + + uint32_t getBattDischargeCoulomb() + { + int data[4]; + data[0] = readRegister(XPOWERS_AXP202_BAT_DISCHGCOULOMB3); + data[1] = readRegister(XPOWERS_AXP202_BAT_DISCHGCOULOMB2); + data[2] = readRegister(XPOWERS_AXP202_BAT_DISCHGCOULOMB1); + data[3] = readRegister(XPOWERS_AXP202_BAT_DISCHGCOULOMB0); + for (int i = 0; i < 4; ++i) { + if (data[i] == -1)return 0; + } + return ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) | ((uint32_t)data[2] << 8) | (uint32_t)data[3]; + } + + uint8_t getAdcSamplingRate(void) + { + int val = readRegister(XPOWERS_AXP202_ADC_SPEED); + if (val == -1)return 0; + return 25 * (int)pow(2, (val & 0xC0) >> 6); + } + + float getCoulombData(void) + { + uint32_t charge = getBattChargeCoulomb(), discharge = getBattDischargeCoulomb(); + uint8_t rate = getAdcSamplingRate(); + float result = 65536.0 * 0.5 * ((float)charge - (float)discharge) / 3600.0 / rate; + return result; + } + + /* + * GPIO control functions + */ + float getBatteryChargeCurrent(void) + { + return readRegisterH8L5( + XPOWERS_AXP202_BAT_AVERCHGCUR_H8, + XPOWERS_AXP202_BAT_AVERCHGCUR_L5 + ) * XPOWERS_AXP202_BATT_CHARGE_CUR_STEP; + } + + uint16_t getGpio0Voltage() + { + return readRegisterH8L4(XPOWERS_AXP202_GPIO0_VOL_ADC_H8, XPOWERS_AXP202_GPIO0_VOL_ADC_L4) * XPOWERS_AXP202_GPIO0_STEP * 1000; + } + + uint16_t getGpio1Voltage() + { + return readRegisterH8L4(XPOWERS_AXP202_GPIO1_VOL_ADC_H8, XPOWERS_AXP202_GPIO1_VOL_ADC_L4) * XPOWERS_AXP202_GPIO1_STEP * 1000; + } + + int getBatteryPercent(void) + { + if (!isBatteryConnect()) { + return -1; + } + const static int table[11] = { + 3000, 3650, 3700, 3740, 3760, 3795, + 3840, 3910, 3980, 4070, 4150 + }; + uint16_t voltage = getBattVoltage(); + if (voltage < table[0]) + return 0; + for (int i = 0; i < 11; i++) { + if (voltage < table[i]) + return i * 10 - (10UL * (int)(table[i] - voltage)) / + (int)(table[i] - table[i - 1]);; + } + return 100; + } + + uint8_t getChipID(void) + { + return readRegister(XPOWERS_AXP202_IC_TYPE); + } + + + /** + * Sleep function + */ + bool enableSleep() + { + return setRegisterBit(XPOWERS_AXP202_VOFF_SET, 3); + } + + /* + * Pekey function + */ + + /** + * @brief Set the PEKEY power-on long press time. + * @param opt: See xpowers_press_on_time_t enum for details. + * @retval + */ + bool setPowerKeyPressOnTime(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP202_POK_SET); + if (val == -1)return false; + return 0 == writeRegister(XPOWERS_AXP202_POK_SET, (val & 0x3F) | (opt << 6)); + } + + /** + * @brief Get the PEKEY power-on long press time. + * @retval See xpowers_press_on_time_t enum for details. + */ + uint8_t getPowerKeyPressOnTime() + { + int val = readRegister(XPOWERS_AXP202_POK_SET); + if (val == -1)return 0; + return (val & 0xC0) >> 6; + } + + /** + * @brief Set the PEKEY power-off long press time. + * @param opt: See xpowers_press_off_time_t enum for details. + * @retval + */ + bool setPowerKeyPressOffTime(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP202_POK_SET); + if (val == -1)return false; + return 0 == writeRegister(XPOWERS_AXP202_POK_SET, (val & 0xFC) | opt); + } + + /** + * @brief Get the PEKEY power-off long press time. + * @retval See xpowers_press_off_time_t enum for details. + */ + uint8_t getPowerKeyPressOffTime() + { + int val = readRegister(XPOWERS_AXP202_POK_SET); + if (val == -1)return 0; + return (val & 0x03); + } + + + void setPowerKeyLongPressOnTime(xpowers_axp202_pekey_long_press_t opt) + { + int val = readRegister(XPOWERS_AXP202_POK_SET); + if (val == -1)return; + writeRegister(XPOWERS_AXP202_POK_SET, (val & 0xCF) | (opt << 4)); + } + + void enablePowerKeyLongPressPowerOff() + { + setRegisterBit(XPOWERS_AXP202_POK_SET, 3); + } + + void disablePowerKeyLongPressPowerOff() + { + clrRegisterBit(XPOWERS_AXP202_POK_SET, 3); + } + + +protected: + + uint16_t getPowerChannelVoltage(uint8_t channel) + { + switch (channel) { + case XPOWERS_DCDC2: + return getDC2Voltage(); + case XPOWERS_DCDC3: + return getDC3Voltage(); + case XPOWERS_LDO2: + return getLDO2Voltage(); + case XPOWERS_LDO3: + return getLDO3Voltage(); + case XPOWERS_LDO4: + return getLDO4Voltage(); + case XPOWERS_LDOIO: + return getLDOioVoltage(); + default: + break; + } + return 0; + } + + bool inline enablePowerOutput(uint8_t channel) + { + switch (channel) { + case XPOWERS_DCDC2: + return enableDC2(); + case XPOWERS_DCDC3: + return enableDC3(); + case XPOWERS_LDO2: + return enableLDO2(); + case XPOWERS_LDO3: + return enableLDO3(); + case XPOWERS_LDO4: + return enableLDO4(); + case XPOWERS_LDOIO: + return enableLDOio(); + case XPOWERS_VBACKUP: + return enableBackupBattCharger(); + default: + break; + } + return false; + } + + bool inline disablePowerOutput(uint8_t channel) + { + if (getProtectedChannel(channel)) { + log_e("Failed to disable the power channel, the power channel has been protected"); + return false; + } + switch (channel) { + case XPOWERS_DCDC2: + return disableDC2(); + case XPOWERS_DCDC3: + return disableDC3(); + case XPOWERS_LDO2: + return disableLDO2(); + case XPOWERS_LDO3: + return disableLDO3(); + case XPOWERS_LDO4: + return disableLDO4(); + case XPOWERS_LDOIO: + return disableLDOio(); + case XPOWERS_VBACKUP: + return disableBackupBattCharger(); + default: + break; + } + return false; + } + + bool inline isPowerChannelEnable(uint8_t channel) + { + switch (channel) { + case XPOWERS_DCDC2: + return isEnableDC2(); + case XPOWERS_DCDC3: + return isEnableDC3(); + case XPOWERS_LDO2: + return isEnableLDO2(); + case XPOWERS_LDO3: + return isEnableLDO3(); + case XPOWERS_LDO4: + return isEnableLDO4(); + case XPOWERS_LDOIO: + return isEnableLDOio(); + case XPOWERS_VBACKUP: + return isEanbleBackupCharger(); + default: + break; + } + return false; + } + + + bool inline setPowerChannelVoltage(uint8_t channel, uint16_t millivolt) + { + if (getProtectedChannel(channel)) { + log_e("Failed to set the power channel, the power channel has been protected"); + return false; + } + switch (channel) { + case XPOWERS_DCDC2: + return setDC2Voltage(millivolt); + case XPOWERS_DCDC3: + return setDC3Voltage(millivolt); + case XPOWERS_LDO2: + return setLDO2Voltage(millivolt); + case XPOWERS_LDO3: + return setLDO3Voltage(millivolt); + case XPOWERS_LDO4: + return setLDO4Voltage(millivolt); + case XPOWERS_LDOIO: + return setLDOioVoltage(millivolt); + case XPOWERS_VBACKUP: + //TODO: + // return setBackupBattChargerVoltage(millivolt); + default: + break; + } + return false; + } + + bool initImpl() + { + if (getChipID() == XPOWERS_AXP202_CHIP_ID) { + setChipModel(XPOWERS_AXP202); + return true; + } + return false; + } + + + /* + * Interrupt control functions + */ + bool setInterruptImpl(uint64_t opts, bool enable) + { + int res = 0; + int data = 0, value = 0; + + log_d("%s %s - 0x%lx\n", __func__, enable ? "ENABLE" : "DISABLE", (unsigned long)opts); + + if (opts & 0xFF) { + value = opts & 0xFF; + data = readRegister(XPOWERS_AXP202_INTEN1); + res |= writeRegister(XPOWERS_AXP202_INTEN1, enable ? (data | value) : (data & (~value))); + } + + if (opts & 0xFF00) { + value = opts >> 8; + data = readRegister(XPOWERS_AXP202_INTEN2); + res |= writeRegister(XPOWERS_AXP202_INTEN2, enable ? (data | value) : (data & (~value))); + } + + if (opts & 0xFF0000) { + value = opts >> 16; + data = readRegister(XPOWERS_AXP202_INTEN3); + res |= writeRegister(XPOWERS_AXP202_INTEN3, enable ? (data | value) : (data & (~value))); + } + + if (opts & 0xFF000000) { + value = opts >> 24; + data = readRegister(XPOWERS_AXP202_INTEN4); + res |= writeRegister(XPOWERS_AXP202_INTEN4, enable ? (data | value) : (data & (~value))); + } + + if (opts & 0xFF00000000) { + value = opts >> 32; + data = readRegister(XPOWERS_AXP202_INTEN5); + res |= writeRegister(XPOWERS_AXP202_INTEN5, enable ? (data | value) : (data & (~value))); + } + return res == 0; + } + + /* + * Signal Capture control functions + */ + bool setSignalCaptureImpl(uint32_t opts, bool enable) + { + int value = 0; + if (opts & 0xFF) { + value = readRegister(XPOWERS_AXP202_ADC_EN1); + writeRegister(XPOWERS_AXP202_ADC_EN1, enable ? (value | opts) : (value & (~opts))); + } + if (opts & 0xFF00) { + opts >>= 8; + value = readRegister(XPOWERS_AXP202_ADC_EN2); + writeRegister(XPOWERS_AXP202_ADC_EN2, enable ? (value | opts) : (value & (~opts))); + } + return true; + } + + const char *getChipNameImpl(void) + { + return "AXP202"; + } + + + +private: + const uint16_t chargeTargetVol[4] = {4100, 4150, 4200, 4360}; + uint8_t statusRegister[5]; + const uint16_t ldo4_table[16] = { + 1250, 1300, 1400, 1500, 1600, 1700, 1800, 1900, + 2000, 2500, 2700, 2800, 3000, 3100, 3200, 3300 + }; +}; + + + diff --git a/buildroot/package/axp2101/src/XPowersLib/XPowersAXP2101.tpp b/buildroot/package/axp2101/src/XPowersLib/XPowersAXP2101.tpp new file mode 100644 index 000000000..4013e823f --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/XPowersAXP2101.tpp @@ -0,0 +1,3084 @@ +/** + * + * @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 XPowersAXP2101.tpp + * @author Lewis He (lewishe@outlook.com) + * @date 2022-05-07 + * + */ + +#if defined(ARDUINO) +#include +#endif /*ARDUINO*/ + +#include "XPowersCommon.tpp" +#include "REG/AXP2101Constants.h" +#include "XPowersLibInterface.hpp" + +typedef enum { + XPOWERS_AXP2101_IRQ_TIME_1S, + XPOWERS_AXP2101_IRQ_TIME_1S5, + XPOWERS_AXP2101_IRQ_TIME_2S, + XPOWERS_AXP2101_PRESSOFF_2S5, +} xpowers_irq_time_t; + + + +typedef enum { + XPOWERS_AXP2101_PRECHARGE_0MA, + XPOWERS_AXP2101_PRECHARGE_25MA, + XPOWERS_AXP2101_PRECHARGE_50MA, + XPOWERS_AXP2101_PRECHARGE_75MA, + XPOWERS_AXP2101_PRECHARGE_100MA, + XPOWERS_AXP2101_PRECHARGE_125MA, + XPOWERS_AXP2101_PRECHARGE_150MA, + XPOWERS_AXP2101_PRECHARGE_175MA, + XPOWERS_AXP2101_PRECHARGE_200MA, +} xpowers_prechg_t; + +typedef enum { + XPOWERS_AXP2101_CHG_ITERM_0MA, + XPOWERS_AXP2101_CHG_ITERM_25MA, + XPOWERS_AXP2101_CHG_ITERM_50MA, + XPOWERS_AXP2101_CHG_ITERM_75MA, + XPOWERS_AXP2101_CHG_ITERM_100MA, + XPOWERS_AXP2101_CHG_ITERM_125MA, + XPOWERS_AXP2101_CHG_ITERM_150MA, + XPOWERS_AXP2101_CHG_ITERM_175MA, + XPOWERS_AXP2101_CHG_ITERM_200MA, +} xpowers_axp2101_chg_iterm_t; + + +typedef enum { + XPOWERS_AXP2101_THREMAL_60DEG, + XPOWERS_AXP2101_THREMAL_80DEG, + XPOWERS_AXP2101_THREMAL_100DEG, + XPOWERS_AXP2101_THREMAL_120DEG, +} xpowers_thermal_t; + +typedef enum { + XPOWERS_AXP2101_CHG_TRI_STATE, //tri_charge + XPOWERS_AXP2101_CHG_PRE_STATE, //pre_charge + XPOWERS_AXP2101_CHG_CC_STATE, //constant charge + XPOWERS_AXP2101_CHG_CV_STATE, //constant voltage + XPOWERS_AXP2101_CHG_DONE_STATE, //charge done + XPOWERS_AXP2101_CHG_STOP_STATE, //not chargin +} xpowers_chg_status_t; + +typedef enum { + XPOWERS_AXP2101_WAKEUP_IRQ_PIN_TO_LOW = _BV(4), + XPOWERS_AXP2101_WAKEUP_PWROK_TO_LOW = _BV(3), + XPOWERS_AXP2101_WAKEUP_DC_DLO_SELECT = _BV(2), +} xpowers_wakeup_t; + +typedef enum { + XPOWERS_AXP2101_FAST_DCDC1, + XPOWERS_AXP2101_FAST_DCDC2, + XPOWERS_AXP2101_FAST_DCDC3, + XPOWERS_AXP2101_FAST_DCDC4, + XPOWERS_AXP2101_FAST_DCDC5, + XPOWERS_AXP2101_FAST_ALDO1, + XPOWERS_AXP2101_FAST_ALDO2, + XPOWERS_AXP2101_FAST_ALDO3, + XPOWERS_AXP2101_FAST_ALDO4, + XPOWERS_AXP2101_FAST_BLDO1, + XPOWERS_AXP2101_FAST_BLDO2, + XPOWERS_AXP2101_FAST_CPUSLDO, + XPOWERS_AXP2101_FAST_DLDO1, + XPOWERS_AXP2101_FAST_DLDO2, +} xpowers_fast_on_opt_t; + + +typedef enum { + XPOWERS_AXP2101_SEQUENCE_LEVEL_0, + XPOWERS_AXP2101_SEQUENCE_LEVEL_1, + XPOWERS_AXP2101_SEQUENCE_LEVEL_2, + XPOWERS_AXP2101_SEQUENCE_DISABLE, +} xpower_start_sequence_t; + +typedef enum { + XPOWERS_AXP2101_WDT_IRQ_TO_PIN, //Just interrupt to pin + XPOWERS_AXP2101_WDT_IRQ_AND_RSET, //IRQ to pin and reset pmu system + XPOWERS_AXP2101_WDT_IRQ_AND_RSET_PD_PWROK, //IRQ to pin and reset pmu system,pull down pwrok + XPOWERS_AXP2101_WDT_IRQ_AND_RSET_ALL_OFF, //IRQ to pin and reset pmu system,turn off dcdc & ldo ,pull down pwrok +} xpowers_wdt_config_t; + +typedef enum { + XPOWERS_AXP2101_WDT_TIMEOUT_1S, + XPOWERS_AXP2101_WDT_TIMEOUT_2S, + XPOWERS_AXP2101_WDT_TIMEOUT_4S, + XPOWERS_AXP2101_WDT_TIMEOUT_8S, + XPOWERS_AXP2101_WDT_TIMEOUT_16S, + XPOWERS_AXP2101_WDT_TIMEOUT_32S, + XPOWERS_AXP2101_WDT_TIMEOUT_64S, + XPOWERS_AXP2101_WDT_TIMEOUT_128S, +} xpowers_wdt_timeout_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_vbus_vol_limit_t; + +typedef enum { + XPOWERS_AXP2101_VSYS_VOL_4V1, + XPOWERS_AXP2101_VSYS_VOL_4V2, + XPOWERS_AXP2101_VSYS_VOL_4V3, + XPOWERS_AXP2101_VSYS_VOL_4V4, + XPOWERS_AXP2101_VSYS_VOL_4V5, + XPOWERS_AXP2101_VSYS_VOL_4V6, + XPOWERS_AXP2101_VSYS_VOL_4V7, + XPOWERS_AXP2101_VSYS_VOL_4V8, +} xpower_chg_dpm_t; + +typedef enum { + XPOWER_POWERON_SRC_POWERON_LOW, //POWERON low for on level when POWERON Mode as POWERON Source + XPOWER_POWERON_SRC_IRQ_LOW, //IRQ PIN Pull-down as POWERON Source + XPOWER_POWERON_SRC_VBUS_INSERT, //Vbus Insert and Good as POWERON Source + XPOWER_POWERON_SRC_BAT_CHARGE, //Vbus Insert and Good as POWERON Source + XPOWER_POWERON_SRC_BAT_INSERT, //Battery Insert and Good as POWERON Source + XPOWER_POWERON_SRC_ENMODE, //POWERON always high when EN Mode as POWERON Source + XPOWER_POWERON_SRC_UNKONW, //Unkonw +} xpower_power_on_source_t; + +typedef enum { + XPOWER_POWEROFF_SRC_PWEKEY_PULLDOWN, //POWERON Pull down for off level when POWERON Mode as POWEROFF Source + XPOWER_POWEROFF_SRC_SOFT_OFF, //Software configuration as POWEROFF Source + XPOWER_POWEROFF_SRC_PWEKEY_LOW, //POWERON always low when EN Mode as POWEROFF Source + XPOWER_POWEROFF_SRC_UNDER_VSYS, //Vsys Under Voltage as POWEROFF Source + XPOWER_POWEROFF_SRC_OVER_VBUS, //VBUS Over Voltage as POWEROFF Source + XPOWER_POWEROFF_SRC_UNDER_VOL, //DCDC Under Voltage as POWEROFF Source + XPOWER_POWEROFF_SRC_OVER_VOL, //DCDC Over Voltage as POWEROFF Source + XPOWER_POWEROFF_SRC_OVER_TEMP, //Die Over Temperature as POWEROFF Source + XPOWER_POWEROFF_SRC_UNKONW, //Unkonw +} xpower_power_off_source_t; + +typedef enum { + XPOWER_PWROK_DELAY_8MS, + XPOWER_PWROK_DELAY_16MS, + XPOWER_PWROK_DELAY_32MS, + XPOWER_PWROK_DELAY_64MS, +} xpower_pwrok_delay_t; + +class XPowersAXP2101 : + public XPowersCommon, public XPowersLibInterface +{ + friend class XPowersCommon; + +public: + + +#if defined(ARDUINO) + XPowersAXP2101(TwoWire &w, int sda = SDA, int scl = SCL, uint8_t addr = AXP2101_SLAVE_ADDRESS) + { + __wire = &w; + __sda = sda; + __scl = scl; + __addr = addr; + } + +#endif + + XPowersAXP2101(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) + { + thisReadRegCallback = readRegCallback; + thisWriteRegCallback = writeRegCallback; + __addr = addr; + } + + XPowersAXP2101() + { +#if defined(ARDUINO) + __wire = &Wire; + __sda = SDA; + __scl = SCL; +#endif + __addr = AXP2101_SLAVE_ADDRESS; + } + + ~XPowersAXP2101() + { + log_i("~XPowersAXP2101"); + deinit(); + } + +#if defined(ARDUINO) + bool init(TwoWire &w, int sda = SDA, int scl = SCL, uint8_t addr = AXP2101_SLAVE_ADDRESS) + { + __wire = &w; + __sda = sda; + __scl = scl; + __addr = addr; + return begin(); + } +#endif + + bool init() + { + return begin(); + } + + void deinit() + { + end(); + } + + /* + * PMU status functions + */ + uint16_t status() + { + uint16_t status1 = readRegister(XPOWERS_AXP2101_STATUS1) & 0x1F; + uint16_t status2 = readRegister(XPOWERS_AXP2101_STATUS2) & 0x1F;; + return (status1 << 8) | (status2); + } + + bool isVbusGood(void) + { + return getRegisterBit(XPOWERS_AXP2101_STATUS1, 5); + } + + bool getBatfetState(void) + { + return getRegisterBit(XPOWERS_AXP2101_STATUS1, 4); + } + + // getBatPresentState + bool isBatteryConnect(void) + { + return getRegisterBit(XPOWERS_AXP2101_STATUS1, 3); + } + + bool isBatInActiveModeState(void) + { + return getRegisterBit(XPOWERS_AXP2101_STATUS1, 2); + } + + bool getThermalRegulationStatus(void) + { + return getRegisterBit(XPOWERS_AXP2101_STATUS1, 1); + } + + bool getCurrnetLimitStatus(void) + { + return getRegisterBit(XPOWERS_AXP2101_STATUS1, 0); + } + + bool isCharging(void) + { + return (readRegister(XPOWERS_AXP2101_STATUS2) >> 5) == 0x01; + } + + bool isDischarge(void) + { + return (readRegister(XPOWERS_AXP2101_STATUS2) >> 5) == 0x02; + } + + bool isStandby(void) + { + return (readRegister(XPOWERS_AXP2101_STATUS2) >> 5) == 0x00; + } + + bool isPowerOn(void) + { + return getRegisterBit(XPOWERS_AXP2101_STATUS2, 4); + } + + bool isPowerOff(void) + { + return getRegisterBit(XPOWERS_AXP2101_STATUS2, 4); + } + + bool isVbusIn(void) + { + return getRegisterBit(XPOWERS_AXP2101_STATUS2, 3) == 0 && isVbusGood(); + } + + xpowers_chg_status_t getChargerStatus(void) + { + int val = readRegister(XPOWERS_AXP2101_STATUS2); + if (val == -1)return XPOWERS_AXP2101_CHG_STOP_STATE; + val &= 0x07; + return (xpowers_chg_status_t)val; + } + + /* + * Data Buffer + */ + + bool writeDataBuffer(uint8_t *data, uint8_t size) + { + if (size > XPOWERS_AXP2101_DATA_BUFFER_SIZE)return false; + return writeRegister(XPOWERS_AXP2101_DATA_BUFFER1, data, size); + } + + bool readDataBuffer(uint8_t *data, uint8_t size) + { + if (size > XPOWERS_AXP2101_DATA_BUFFER_SIZE)return false; + return readRegister(XPOWERS_AXP2101_DATA_BUFFER1, data, size); + } + + /* + * PMU common configuration + */ + + /** + * @brief Internal off-discharge enable for DCDC & LDO & SWITCH + */ + + void enableInternalDischarge(void) + { + setRegisterBit(XPOWERS_AXP2101_COMMON_CONFIG, 5); + } + + void disableInternalDischarge(void) + { + clrRegisterBit(XPOWERS_AXP2101_COMMON_CONFIG, 5); + } + + + /** + * @brief PWROK PIN pull low to Restart + */ + void enablePwrOkPinPullLow(void) + { + setRegisterBit(XPOWERS_AXP2101_COMMON_CONFIG, 3); + } + + void disablePwrOkPinPullLow(void) + { + clrRegisterBit(XPOWERS_AXP2101_COMMON_CONFIG, 3); + } + + void enablePwronShutPMIC(void) + { + setRegisterBit(XPOWERS_AXP2101_COMMON_CONFIG, 2); + } + + void disablePwronShutPMIC(void) + { + clrRegisterBit(XPOWERS_AXP2101_COMMON_CONFIG, 2); + } + + + /** + * @brief Restart the SoC System, POWOFF/POWON and reset the related registers + * @retval None + */ + void reset(void) + { + setRegisterBit(XPOWERS_AXP2101_COMMON_CONFIG, 1); + } + + /** + * @brief Set shutdown, calling shutdown will turn off all power channels, + * only VRTC belongs to normal power supply + * @retval None + */ + void shutdown(void) + { + setRegisterBit(XPOWERS_AXP2101_COMMON_CONFIG, 0); + } + + /** + * @brief BATFET control / REG 12H + * @note DIE Over Temperature Protection Level1 Configuration + * @param opt: 0:115 , 1:125 , 2:135 + * @retval None + */ + void setBatfetDieOverTempLevel1(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP2101_BATFET_CTRL); + if (val == -1)return; + val &= 0xF9; + writeRegister(XPOWERS_AXP2101_BATFET_CTRL, val | (opt << 1)); + } + + uint8_t getBatfetDieOverTempLevel1(void) + { + return (readRegister(XPOWERS_AXP2101_BATFET_CTRL) & 0x06); + } + + void enableBatfetDieOverTempDetect(void) + { + setRegisterBit(XPOWERS_AXP2101_BATFET_CTRL, 0); + } + + void disableBatfetDieOverTempDetect(void) + { + clrRegisterBit(XPOWERS_AXP2101_BATFET_CTRL, 0); + } + + /** + * @param opt: 0:115 , 1:125 , 2:135 + */ + void setDieOverTempLevel1(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP2101_DIE_TEMP_CTRL); + if (val == -1)return; + val &= 0xF9; + writeRegister(XPOWERS_AXP2101_DIE_TEMP_CTRL, val | (opt << 1)); + } + + uint8_t getDieOverTempLevel1(void) + { + return (readRegister(XPOWERS_AXP2101_DIE_TEMP_CTRL) & 0x06); + } + + void enableDieOverTempDetect(void) + { + setRegisterBit(XPOWERS_AXP2101_DIE_TEMP_CTRL, 0); + } + + void disableDieOverTempDetect(void) + { + clrRegisterBit(XPOWERS_AXP2101_DIE_TEMP_CTRL, 0); + } + + // Linear Charger Vsys voltage dpm + void setLinearChargerVsysDpm(xpower_chg_dpm_t opt) + { + int val = readRegister(XPOWERS_AXP2101_MIN_SYS_VOL_CTRL); + if (val == -1)return; + val &= 0x8F; + writeRegister(XPOWERS_AXP2101_MIN_SYS_VOL_CTRL, val | (opt << 4)); + } + + uint8_t getLinearChargerVsysDpm(void) + { + int val = readRegister(XPOWERS_AXP2101_MIN_SYS_VOL_CTRL); + if (val == -1)return 0; + val &= 0x70; + return (val & 0x70) >> 4; + } + + // Set the minimum common working voltage of the PMU VBUS input, + // below this value will turn off the PMU + void setVbusVoltageLimit(xpower_vbus_vol_limit_t opt) + { + int val = readRegister(XPOWERS_AXP2101_INPUT_VOL_LIMIT_CTRL); + if (val == -1)return; + val &= 0xF0; + writeRegister(XPOWERS_AXP2101_INPUT_VOL_LIMIT_CTRL, val | (opt & 0x0F)); + } + + uint8_t getVbusVoltageLimit(void) + { + return (readRegister(XPOWERS_AXP2101_INPUT_VOL_LIMIT_CTRL) & 0x0F); + } + + /** + * @brief Set VBUS Current Input Limit. + * @param opt: View the related chip type xpowers_axp2101_vbus_cur_limit_t enumeration + * parameters in "XPowersParams.hpp" + * @retval true valid false invalid + */ + bool setVbusCurrentLimit(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP2101_INPUT_CUR_LIMIT_CTRL); + if (val == -1)return false; + val &= 0xF8; + return 0 == writeRegister(XPOWERS_AXP2101_INPUT_CUR_LIMIT_CTRL, val | (opt & 0x07)); + } + + /** + * @brief Get VBUS Current Input Limit. + * @retval View the related chip type xpowers_axp2101_vbus_cur_limit_t enumeration + * parameters in "XPowersParams.hpp" + */ + uint8_t getVbusCurrentLimit(void) + { + return (readRegister(XPOWERS_AXP2101_INPUT_CUR_LIMIT_CTRL) & 0x07); + } + + /** + * @brief Reset the fuel gauge + */ + void resetGauge(void) + { + setRegisterBit(XPOWERS_AXP2101_RESET_FUEL_GAUGE, 3); + } + + /** + * @brief reset the gauge besides reset + */ + void resetGaugeBesides(void) + { + setRegisterBit(XPOWERS_AXP2101_RESET_FUEL_GAUGE, 2); + } + + /** + * @brief Gauge Module + */ + void enableGauge(void) + { + setRegisterBit(XPOWERS_AXP2101_CHARGE_GAUGE_WDT_CTRL, 3); + } + + void disableGauge(void) + { + clrRegisterBit(XPOWERS_AXP2101_CHARGE_GAUGE_WDT_CTRL, 3); + } + + /** + * @brief Button Battery charge + */ + bool enableButtonBatteryCharge(void) + { + return setRegisterBit(XPOWERS_AXP2101_CHARGE_GAUGE_WDT_CTRL, 2); + } + + bool disableButtonBatteryCharge(void) + { + return clrRegisterBit(XPOWERS_AXP2101_CHARGE_GAUGE_WDT_CTRL, 2); + } + + bool isEanbleButtonBatteryCharge() + { + return getRegisterBit(XPOWERS_AXP2101_CHARGE_GAUGE_WDT_CTRL, 2); + } + + + //Button battery charge termination voltage setting + bool setButtonBatteryChargeVoltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP2101_BTN_VOL_STEPS) { + log_e("Mistake ! Button battery charging step voltage is %u mV", XPOWERS_AXP2101_BTN_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP2101_BTN_VOL_MIN) { + log_e("Mistake ! The minimum charge termination voltage of the coin cell battery is %u mV", XPOWERS_AXP2101_BTN_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP2101_BTN_VOL_MAX) { + log_e("Mistake ! The minimum charge termination voltage of the coin cell battery is %u mV", XPOWERS_AXP2101_BTN_VOL_MAX); + return false; + } + int val = readRegister(XPOWERS_AXP2101_BTN_BAT_CHG_VOL_SET); + if (val == -1)return 0; + val &= 0xF8; + val |= (millivolt - XPOWERS_AXP2101_BTN_VOL_MIN) / XPOWERS_AXP2101_BTN_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP2101_BTN_BAT_CHG_VOL_SET, val); + } + + uint16_t getButtonBatteryVoltage(void) + { + int val = readRegister(XPOWERS_AXP2101_BTN_BAT_CHG_VOL_SET); + if (val == -1)return 0; + return (val & 0x07) * XPOWERS_AXP2101_BTN_VOL_STEPS + XPOWERS_AXP2101_BTN_VOL_MIN; + } + + + /** + * @brief Cell Battery charge + */ + void enableCellbatteryCharge(void) + { + setRegisterBit(XPOWERS_AXP2101_CHARGE_GAUGE_WDT_CTRL, 1); + } + + void disableCellbatteryCharge(void) + { + clrRegisterBit(XPOWERS_AXP2101_CHARGE_GAUGE_WDT_CTRL, 1); + } + + /** + * @brief Watchdog Module + */ + void enableWatchdog(void) + { + setRegisterBit(XPOWERS_AXP2101_CHARGE_GAUGE_WDT_CTRL, 0); + enableIRQ(XPOWERS_AXP2101_WDT_EXPIRE_IRQ); + } + + void disableWatchdog(void) + { + disableIRQ(XPOWERS_AXP2101_WDT_EXPIRE_IRQ); + clrRegisterBit(XPOWERS_AXP2101_CHARGE_GAUGE_WDT_CTRL, 0); + } + + /** + * @brief Watchdog Config + * @note + * @param opt: 0: IRQ Only 1: IRQ and System reset 2: IRQ, System Reset and Pull down PWROK 1s 3: IRQ, System Reset, DCDC/LDO PWROFF & PWRON + * @retval None + */ + void setWatchdogConfig(xpowers_wdt_config_t opt) + { + int val = readRegister(XPOWERS_AXP2101_WDT_CTRL); + if (val == -1)return; + val &= 0xCF; + writeRegister(XPOWERS_AXP2101_WDT_CTRL, val | (opt << 4)); + } + + uint8_t getWatchConfig(void) + { + return (readRegister(XPOWERS_AXP2101_WDT_CTRL) & 0x30) >> 4; + } + + void clrWatchdog(void) + { + setRegisterBit(XPOWERS_AXP2101_WDT_CTRL, 3); + } + + + void setWatchdogTimeout(xpowers_wdt_timeout_t opt) + { + int val = readRegister(XPOWERS_AXP2101_WDT_CTRL); + if (val == -1)return; + val &= 0xF8; + writeRegister(XPOWERS_AXP2101_WDT_CTRL, val | opt); + } + + uint8_t getWatchdogTimerout(void) + { + return readRegister(XPOWERS_AXP2101_WDT_CTRL) & 0x07; + } + + /** + * @brief Low battery warning threshold 5-20%, 1% per step + * @param percentage: 5 ~ 20 + * @retval None + */ + void setLowBatWarnThreshold(uint8_t percentage) + { + if (percentage < 5 || percentage > 20)return; + int val = readRegister(XPOWERS_AXP2101_LOW_BAT_WARN_SET); + if (val == -1)return; + val &= 0x0F; + writeRegister(XPOWERS_AXP2101_LOW_BAT_WARN_SET, val | ((percentage - 5) << 4)); + } + + uint8_t getLowBatWarnThreshold(void) + { + int val = readRegister(XPOWERS_AXP2101_LOW_BAT_WARN_SET); + if (val == -1)return 0; + val &= 0xF0; + val >>= 4; + return val; + } + + /** + * @brief Low battery shutdown threshold 0-15%, 1% per step + * @param opt: 0 ~ 15 + * @retval None + */ + void setLowBatShutdownThreshold(uint8_t opt) + { + if (opt > 15) { + opt = 15; + } + int val = readRegister(XPOWERS_AXP2101_LOW_BAT_WARN_SET); + if (val == -1)return; + val &= 0xF0; + writeRegister(XPOWERS_AXP2101_LOW_BAT_WARN_SET, val | opt); + } + + uint8_t getLowBatShutdownThreshold(void) + { + return (readRegister(XPOWERS_AXP2101_LOW_BAT_WARN_SET) & 0x0F); + } + + //! PWRON statu 20 + // POWERON always high when EN Mode as POWERON Source + bool isPoweronAlwaysHighSource() + { + return getRegisterBit(XPOWERS_AXP2101_PWRON_STATUS, 5); + } + + // Battery Insert and Good as POWERON Source + bool isBattInsertOnSource() + { + return getRegisterBit(XPOWERS_AXP2101_PWRON_STATUS, 4); + } + + // Battery Voltage > 3.3V when Charged as Source + bool isBattNormalOnSource() + { + return getRegisterBit(XPOWERS_AXP2101_PWRON_STATUS, 3); + } + + // Vbus Insert and Good as POWERON Source + bool isVbusInsertOnSource() + { + return getRegisterBit(XPOWERS_AXP2101_PWRON_STATUS, 2); + } + + // IRQ PIN Pull-down as POWERON Source + bool isIrqLowOnSource() + { + return getRegisterBit(XPOWERS_AXP2101_PWRON_STATUS, 1); + } + + // POWERON low for on level when POWERON Mode as POWERON Source + bool isPwronLowOnSource() + { + return getRegisterBit(XPOWERS_AXP2101_PWRON_STATUS, 0); + } + + xpower_power_on_source_t getPowerOnSource() + { + int val = readRegister(XPOWERS_AXP2101_PWRON_STATUS); + if (val == -1) return XPOWER_POWERON_SRC_UNKONW; + return (xpower_power_on_source_t)val; + } + + //! PWROFF status 21 + // Die Over Temperature as POWEROFF Source + bool isOverTemperatureOffSource() + { + return getRegisterBit(XPOWERS_AXP2101_PWROFF_STATUS, 7); + } + + // DCDC Over Voltage as POWEROFF Source + bool isDcOverVoltageOffSource() + { + return getRegisterBit(XPOWERS_AXP2101_PWROFF_STATUS, 6); + } + + // DCDC Under Voltage as POWEROFF Source + bool isDcUnderVoltageOffSource() + { + return getRegisterBit(XPOWERS_AXP2101_PWROFF_STATUS, 5); + } + + // VBUS Over Voltage as POWEROFF Source + bool isVbusOverVoltageOffSource() + { + return getRegisterBit(XPOWERS_AXP2101_PWROFF_STATUS, 4); + } + + // Vsys Under Voltage as POWEROFF Source + bool isVsysUnderVoltageOffSource() + { + return getRegisterBit(XPOWERS_AXP2101_PWROFF_STATUS, 3); + } + + // POWERON always low when EN Mode as POWEROFF Source + bool isPwronAlwaysLowOffSource() + { + return getRegisterBit(XPOWERS_AXP2101_PWROFF_STATUS, 2); + } + + // Software configuration as POWEROFF Source + bool isSwConfigOffSource() + { + return getRegisterBit(XPOWERS_AXP2101_PWROFF_STATUS, 1); + } + + // POWERON Pull down for off level when POWERON Mode as POWEROFF Source + bool isPwrSourcePullDown() + { + return getRegisterBit(XPOWERS_AXP2101_PWROFF_STATUS, 0); + } + + xpower_power_off_source_t getPowerOffSource() + { + int val = readRegister(XPOWERS_AXP2101_PWROFF_STATUS); + if (val == -1) return XPOWER_POWEROFF_SRC_UNKONW; + return (xpower_power_off_source_t)val; + } + + //!REG 22H + void enableOverTemperatureLevel2PowerOff() + { + setRegisterBit(XPOWERS_AXP2101_PWROFF_EN, 2); + } + + void disableOverTemperaturePowerOff() + { + clrRegisterBit(XPOWERS_AXP2101_PWROFF_EN, 2); + } + + // CHANGE: void enablePwrOnOverVolOffLevelPowerOff() + void enableLongPressShutdown() + { + setRegisterBit(XPOWERS_AXP2101_PWROFF_EN, 1); + } + + // CHANGE: void disablePwrOnOverVolOffLevelPowerOff() + void disableLongPressShutdown() + { + clrRegisterBit(XPOWERS_AXP2101_PWROFF_EN, 1); + } + + //CHANGE: void enablePwrOffSelectFunction() + void setLongPressRestart() + { + setRegisterBit(XPOWERS_AXP2101_PWROFF_EN, 0); + } + + //CHANGE: void disablePwrOffSelectFunction() + void setLongPressPowerOFF() + { + clrRegisterBit(XPOWERS_AXP2101_PWROFF_EN, 0); + } + + //!REG 23H + // DCDC 120%(130%) high voltage turn off PMIC function + void enableDCHighVoltageTurnOff() + { + setRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 5); + } + + void disableDCHighVoltageTurnOff() + { + clrRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 5); + } + + // DCDC5 85% low voltage turn Off PMIC function + void enableDC5LowVoltageTurnOff() + { + setRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 4); + } + + void disableDC5LowVoltageTurnOff() + { + clrRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 4); + } + + // DCDC4 85% low voltage turn Off PMIC function + void enableDC4LowVoltageTurnOff() + { + setRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 3); + } + + void disableDC4LowVoltageTurnOff() + { + clrRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 3); + } + + // DCDC3 85% low voltage turn Off PMIC function + void enableDC3LowVoltageTurnOff() + { + setRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 2); + } + + void disableDC3LowVoltageTurnOff() + { + clrRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 2); + } + + // DCDC2 85% low voltage turn Off PMIC function + void enableDC2LowVoltageTurnOff() + { + setRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 1); + } + + void disableDC2LowVoltageTurnOff() + { + clrRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 1); + } + + // DCDC1 85% low voltage turn Off PMIC function + void enableDC1LowVoltageTurnOff() + { + setRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 0); + } + + void disableDC1LowVoltageTurnOff() + { + clrRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 0); + } + + + // Set the minimum system operating voltage inside the PMU, + // below this value will shut down the PMU,Adjustment range 2600mV~3300mV + bool setSysPowerDownVoltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_MIN) { + log_e("Mistake ! The minimum settable voltage of VSYS is %u mV", XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_MIN); + return false; + } else if (millivolt > XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_MAX) { + log_e("Mistake ! The maximum settable voltage of VSYS is %u mV", XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_MAX); + return false; + } + int val = readRegister(XPOWERS_AXP2101_VOFF_SET); + if (val == -1)return false; + val &= 0xF8; + return 0 == writeRegister(XPOWERS_AXP2101_VOFF_SET, val | ((millivolt - XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_MIN) / XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_STEPS)); + } + + uint16_t getSysPowerDownVoltage(void) + { + int val = readRegister(XPOWERS_AXP2101_VOFF_SET); + if (val == -1)return false; + return (val & 0x07) * XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_STEPS + XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_MIN; + } + + // PWROK setting and PWROFF sequence control 25. + // Check the PWROK Pin enable after all dcdc/ldo output valid 128ms + void enablePwrOk() + { + setRegisterBit(XPOWERS_AXP2101_PWROK_SEQU_CTRL, 4); + } + + void disablePwrOk() + { + clrRegisterBit(XPOWERS_AXP2101_PWROK_SEQU_CTRL, 4); + } + + // POWEROFF Delay 4ms after PWROK enable + void eanblePowerOffDelay() + { + setRegisterBit(XPOWERS_AXP2101_PWROK_SEQU_CTRL, 3); + } + + // POWEROFF Delay 4ms after PWROK disable + void disablePowerOffDelay() + { + clrRegisterBit(XPOWERS_AXP2101_PWROK_SEQU_CTRL, 3); + } + + // POWEROFF Sequence Control the reverse of the Startup + void eanblePowerSequence() + { + setRegisterBit(XPOWERS_AXP2101_PWROK_SEQU_CTRL, 2); + } + + // POWEROFF Sequence Control at the same time + void disablePowerSequence() + { + clrRegisterBit(XPOWERS_AXP2101_PWROK_SEQU_CTRL, 2); + } + + // Delay of PWROK after all power output good + bool setPwrOkDelay(xpower_pwrok_delay_t opt) + { + int val = readRegister(XPOWERS_AXP2101_PWROK_SEQU_CTRL); + if (val == -1)return false; + val &= 0xFC; + return 0 == writeRegister(XPOWERS_AXP2101_PWROK_SEQU_CTRL, val | opt); + } + + xpower_pwrok_delay_t getPwrOkDelay() + { + int val = readRegister(XPOWERS_AXP2101_PWROK_SEQU_CTRL); + if (val == -1)return XPOWER_PWROK_DELAY_8MS; + return (xpower_pwrok_delay_t)(val & 0x03); + } + + // Sleep and 26 + void wakeupControl(xpowers_wakeup_t opt, bool enable) + { + int val = readRegister(XPOWERS_AXP2101_SLEEP_WAKEUP_CTRL); + if (val == -1)return; + enable ? (val |= opt) : (val &= (~opt)); + writeRegister(XPOWERS_AXP2101_SLEEP_WAKEUP_CTRL, val); + } + + bool enableWakeup(void) + { + return setRegisterBit(XPOWERS_AXP2101_SLEEP_WAKEUP_CTRL, 1); + } + + bool disableWakeup(void) + { + return clrRegisterBit(XPOWERS_AXP2101_SLEEP_WAKEUP_CTRL, 1); + } + + bool enableSleep(void) + { + return setRegisterBit(XPOWERS_AXP2101_SLEEP_WAKEUP_CTRL, 0); + } + + bool disableSleep(void) + { + return clrRegisterBit(XPOWERS_AXP2101_SLEEP_WAKEUP_CTRL, 0); + } + + + // RQLEVEL/OFFLEVEL/ONLEVEL setting 27 + /** + * @brief IRQLEVEL configur + * @param opt: 0:1s 1:1.5s 2:2s 3:2.5s + */ + void setIrqLevel(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL); + if (val == -1)return; + val &= 0xFC; + writeRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL, val | (opt << 4)); + } + + /** + * @brief OFFLEVEL configuration + * @param opt: 0:4s 1:6s 2:8s 3:10s + */ + void setOffLevel(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL, val | (opt << 2)); + } + + /** + * @brief ONLEVEL configuration + * @param opt: 0:128ms 1:512ms 2:1s 3:2s + */ + void setOnLevel(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL, val | opt); + } + + // Fast pwron setting 0 28 + // Fast Power On Start Sequence + void setDc4FastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET0); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET0, val | ((opt & 0x3) << 6)); + } + + void setDc3FastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET0); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET0, val | ((opt & 0x3) << 4)); + } + void setDc2FastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET0); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET0, val | ((opt & 0x3) << 2)); + } + void setDc1FastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET0); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET0, val | (opt & 0x3)); + } + + // Fast pwron setting 1 29 + void setAldo3FastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET1); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET1, val | ((opt & 0x3) << 6)); + } + void setAldo2FastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET1); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET1, val | ((opt & 0x3) << 4)); + } + void setAldo1FastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET1); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET1, val | ((opt & 0x3) << 2)); + } + + void setDc5FastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET1); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET1, val | (opt & 0x3)); + } + + // Fast pwron setting 2 2A + void setCpuldoFastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET2); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET2, val | ((opt & 0x3) << 6)); + } + + void setBldo2FastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET2); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET2, val | ((opt & 0x3) << 4)); + } + + void setBldo1FastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET2); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET2, val | ((opt & 0x3) << 2)); + } + + void setAldo4FastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET2); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET2, val | (opt & 0x3)); + } + + // Fast pwron setting 3 2B + void setDldo2FastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_CTRL); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_CTRL, val | ((opt & 0x3) << 2)); + } + + void setDldo1FastStartSequence(xpower_start_sequence_t opt) + { + int val = readRegister(XPOWERS_AXP2101_FAST_PWRON_CTRL); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_FAST_PWRON_CTRL, val | (opt & 0x3)); + } + + /** + * @brief Setting Fast Power On Start Sequence + */ + void setFastPowerOnLevel(xpowers_fast_on_opt_t opt, xpower_start_sequence_t seq_level) + { + uint8_t val = 0; + switch (opt) { + case XPOWERS_AXP2101_FAST_DCDC1: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET0); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET0, val | seq_level); + break; + case XPOWERS_AXP2101_FAST_DCDC2: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET0); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET0, val | (seq_level << 2)); + break; + case XPOWERS_AXP2101_FAST_DCDC3: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET0); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET0, val | (seq_level << 4)); + break; + case XPOWERS_AXP2101_FAST_DCDC4: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET0); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET0, val | (seq_level << 6)); + break; + case XPOWERS_AXP2101_FAST_DCDC5: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET1); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET1, val | seq_level); + break; + case XPOWERS_AXP2101_FAST_ALDO1: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET1); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET1, val | (seq_level << 2)); + break; + case XPOWERS_AXP2101_FAST_ALDO2: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET1); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET1, val | (seq_level << 4)); + break; + case XPOWERS_AXP2101_FAST_ALDO3: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET1); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET1, val | (seq_level << 6)); + break; + case XPOWERS_AXP2101_FAST_ALDO4: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET2); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET2, val | seq_level); + break; + case XPOWERS_AXP2101_FAST_BLDO1: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET2); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET2, val | (seq_level << 2)); + break; + case XPOWERS_AXP2101_FAST_BLDO2: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET2); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET2, val | (seq_level << 4)); + break; + case XPOWERS_AXP2101_FAST_CPUSLDO: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET2); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET2, val | (seq_level << 6)); + break; + case XPOWERS_AXP2101_FAST_DLDO1: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_CTRL); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_CTRL, val | seq_level); + break; + case XPOWERS_AXP2101_FAST_DLDO2: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_CTRL); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_CTRL, val | (seq_level << 2)); + break; + default: + break; + } + } + + void disableFastPowerOn(xpowers_fast_on_opt_t opt) + { + uint8_t val = 0; + switch (opt) { + case XPOWERS_AXP2101_FAST_DCDC1: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET0); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET0, val & 0xFC); + break; + case XPOWERS_AXP2101_FAST_DCDC2: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET0); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET0, val & 0xF3); + break; + case XPOWERS_AXP2101_FAST_DCDC3: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET0); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET0, val & 0xCF); + break; + case XPOWERS_AXP2101_FAST_DCDC4: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET0); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET0, val & 0x3F); + break; + case XPOWERS_AXP2101_FAST_DCDC5: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET1); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET1, val & 0xFC); + break; + case XPOWERS_AXP2101_FAST_ALDO1: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET1); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET1, val & 0xF3); + break; + case XPOWERS_AXP2101_FAST_ALDO2: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET1); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET1, val & 0xCF); + break; + case XPOWERS_AXP2101_FAST_ALDO3: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET1); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET1, val & 0x3F); + break; + case XPOWERS_AXP2101_FAST_ALDO4: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET2); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET2, val & 0xFC); + break; + case XPOWERS_AXP2101_FAST_BLDO1: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET2); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET2, val & 0xF3); + break; + case XPOWERS_AXP2101_FAST_BLDO2: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET2); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET2, val & 0xCF); + break; + case XPOWERS_AXP2101_FAST_CPUSLDO: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_SET2); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_SET2, val & 0x3F); + break; + case XPOWERS_AXP2101_FAST_DLDO1: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_CTRL); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_CTRL, val & 0xFC); + break; + case XPOWERS_AXP2101_FAST_DLDO2: + val = readRegister(XPOWERS_AXP2101_FAST_PWRON_CTRL); + writeRegister(XPOWERS_AXP2101_FAST_PWRON_CTRL, val & 0xF3); + break; + default: + break; + } + } + + void enableFastPowerOn(void) + { + setRegisterBit(XPOWERS_AXP2101_FAST_PWRON_CTRL, 7); + } + + void disableFastPowerOn(void) + { + clrRegisterBit(XPOWERS_AXP2101_FAST_PWRON_CTRL, 7); + } + + void enableFastWakeup(void) + { + setRegisterBit(XPOWERS_AXP2101_FAST_PWRON_CTRL, 6); + } + + void disableFastWakeup(void) + { + clrRegisterBit(XPOWERS_AXP2101_FAST_PWRON_CTRL, 6); + } + + // DCDC 120%(130%) high voltage turn off PMIC function + void setDCHighVoltagePowerDowm(bool en) + { + en ? setRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 5) : clrRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 5); + } + + bool getDCHighVoltagePowerDowmEn() + { + return getRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 5); + } + + // DCDCS force PWM control + void setDcUVPDebounceTime(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL); + val &= 0xFC; + writeRegister(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL, val | opt); + } + + void settDC1WorkModeToPwm(uint8_t enable) + { + enable ? + setRegisterBit(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL, 2) + : clrRegisterBit(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL, 2); + } + + void settDC2WorkModeToPwm(uint8_t enable) + { + enable ? setRegisterBit(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL, 3) + : clrRegisterBit(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL, 3); + } + + void settDC3WorkModeToPwm(uint8_t enable) + { + enable ? + setRegisterBit(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL, 4) + : clrRegisterBit(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL, 4); + } + + void settDC4WorkModeToPwm( uint8_t enable) + { + enable ? + setRegisterBit(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL, 5) + : clrRegisterBit(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL, 5); + } + + //1 = 100khz 0=50khz + void setDCFreqSpreadRange(uint8_t opt) + { + opt ? + setRegisterBit(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL, 6) + : clrRegisterBit(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL, 6); + } + + void setDCFreqSpreadRangeEn(bool en) + { + en ? + setRegisterBit(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL, 7) + : clrRegisterBit(XPOWERS_AXP2101_DC_FORCE_PWM_CTRL, 7); + } + + void enableCCM() + { + setRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 6); + } + + void disableCCM() + { + clrRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 6); + } + + bool isEanbleCCM() + { + return getRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 6); + } + + enum DVMRamp { + XPOWERS_AXP2101_DVM_RAMP_15_625US, + XPOWERS_AXP2101_DVM_RAMP_31_250US, + }; + + //args:enum DVMRamp + void setDVMRamp(uint8_t opt) + { + if (opt > 2)return; + opt == 0 ? clrRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 5) : setRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 5); + } + + + + /* + * Power control DCDC1 functions + */ + bool isEnableDC1(void) + { + return getRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 0); + } + + bool enableDC1(void) + { + return setRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 0); + } + + bool disableDC1(void) + { + return clrRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 0); + } + + bool setDC1Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP2101_DCDC1_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP2101_DCDC1_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP2101_DCDC1_VOL_MIN) { + log_e("Mistake ! DC1 minimum voltage is %u mV", XPOWERS_AXP2101_DCDC1_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP2101_DCDC1_VOL_MAX) { + log_e("Mistake ! DC1 maximum voltage is %u mV", XPOWERS_AXP2101_DCDC1_VOL_MAX); + return false; + } + return 0 == writeRegister(XPOWERS_AXP2101_DC_VOL0_CTRL, (millivolt - XPOWERS_AXP2101_DCDC1_VOL_MIN) / XPOWERS_AXP2101_DCDC1_VOL_STEPS); + } + + uint16_t getDC1Voltage(void) + { + return (readRegister(XPOWERS_AXP2101_DC_VOL0_CTRL) & 0x1F) * XPOWERS_AXP2101_DCDC1_VOL_STEPS + XPOWERS_AXP2101_DCDC1_VOL_MIN; + } + + + + // DCDC1 85% low voltage turn off PMIC function + void setDC1LowVoltagePowerDowm(bool en) + { + en ? setRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 0) : clrRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 0); + } + + bool getDC1LowVoltagePowerDowmEn() + { + return getRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 0); + } + + /* + * Power control DCDC2 functions + */ + bool isEnableDC2(void) + { + return getRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 1); + } + + bool enableDC2(void) + { + return setRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 1); + } + + bool disableDC2(void) + { + return clrRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 1); + } + + bool setDC2Voltage(uint16_t millivolt) + { + int val = readRegister(XPOWERS_AXP2101_DC_VOL1_CTRL); + if (val == -1)return 0; + val &= 0x80; + if (millivolt >= XPOWERS_AXP2101_DCDC2_VOL1_MIN && millivolt <= XPOWERS_AXP2101_DCDC2_VOL1_MAX) { + if (millivolt % XPOWERS_AXP2101_DCDC2_VOL_STEPS1) { + log_e("Mistake ! The steps is must %umV", XPOWERS_AXP2101_DCDC2_VOL_STEPS1); + return false; + } + return 0 == writeRegister(XPOWERS_AXP2101_DC_VOL1_CTRL, val | (millivolt - XPOWERS_AXP2101_DCDC2_VOL1_MIN) / XPOWERS_AXP2101_DCDC2_VOL_STEPS1); + } else if (millivolt >= XPOWERS_AXP2101_DCDC2_VOL2_MIN && millivolt <= XPOWERS_AXP2101_DCDC2_VOL2_MAX) { + if (millivolt % XPOWERS_AXP2101_DCDC2_VOL_STEPS2) { + log_e("Mistake ! The steps is must %umV", XPOWERS_AXP2101_DCDC2_VOL_STEPS2); + return false; + } + val |= (((millivolt - XPOWERS_AXP2101_DCDC2_VOL2_MIN) / XPOWERS_AXP2101_DCDC2_VOL_STEPS2) + XPOWERS_AXP2101_DCDC2_VOL_STEPS2_BASE); + return 0 == writeRegister(XPOWERS_AXP2101_DC_VOL1_CTRL, val); + } + return false; + } + + uint16_t getDC2Voltage(void) + { + int val = readRegister(XPOWERS_AXP2101_DC_VOL1_CTRL); + if (val == -1)return 0; + val &= 0x7F; + if (val < XPOWERS_AXP2101_DCDC2_VOL_STEPS2_BASE) { + return (val * XPOWERS_AXP2101_DCDC2_VOL_STEPS1) + XPOWERS_AXP2101_DCDC2_VOL1_MIN; + } else { + return (val * XPOWERS_AXP2101_DCDC2_VOL_STEPS2) - 200; + } + return 0; + } + + uint8_t getDC2WorkMode(void) + { + return getRegisterBit(XPOWERS_AXP2101_DCDC2_VOL_STEPS2, 7); + } + + void setDC2LowVoltagePowerDowm(bool en) + { + en ? setRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 1) : clrRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 1); + } + + bool getDC2LowVoltagePowerDowmEn() + { + return getRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 1); + } + + /* + * Power control DCDC3 functions + */ + + bool isEnableDC3(void) + { + return getRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 2); + } + + bool enableDC3(void) + { + return setRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 2); + } + + bool disableDC3(void) + { + return clrRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 2); + } + + /** + 0.5~1.2V,10mV/step,71steps + 1.22~1.54V,20mV/step,17steps + 1.6~3.4V,100mV/step,19steps + */ + bool setDC3Voltage(uint16_t millivolt) + { + int val = readRegister(XPOWERS_AXP2101_DC_VOL2_CTRL); + if (val == -1)return false; + val &= 0x80; + if (millivolt >= XPOWERS_AXP2101_DCDC3_VOL1_MIN && millivolt <= XPOWERS_AXP2101_DCDC3_VOL1_MAX) { + if (millivolt % XPOWERS_AXP2101_DCDC3_VOL_STEPS1) { + log_e("Mistake ! The steps is must %umV", XPOWERS_AXP2101_DCDC3_VOL_STEPS1); + return false; + } + return 0 == writeRegister(XPOWERS_AXP2101_DC_VOL2_CTRL, val | (millivolt - XPOWERS_AXP2101_DCDC3_VOL_MIN) / XPOWERS_AXP2101_DCDC3_VOL_STEPS1); + } else if (millivolt >= XPOWERS_AXP2101_DCDC3_VOL2_MIN && millivolt <= XPOWERS_AXP2101_DCDC3_VOL2_MAX) { + if (millivolt % XPOWERS_AXP2101_DCDC3_VOL_STEPS2) { + log_e("Mistake ! The steps is must %umV", XPOWERS_AXP2101_DCDC3_VOL_STEPS2); + return false; + } + val |= (((millivolt - XPOWERS_AXP2101_DCDC3_VOL2_MIN) / XPOWERS_AXP2101_DCDC3_VOL_STEPS2) + XPOWERS_AXP2101_DCDC3_VOL_STEPS2_BASE); + return 0 == writeRegister(XPOWERS_AXP2101_DC_VOL2_CTRL, val); + } else if (millivolt >= XPOWERS_AXP2101_DCDC3_VOL3_MIN && millivolt <= XPOWERS_AXP2101_DCDC3_VOL3_MAX) { + if (millivolt % XPOWERS_AXP2101_DCDC3_VOL_STEPS3) { + log_e("Mistake ! The steps is must %umV", XPOWERS_AXP2101_DCDC3_VOL_STEPS3); + return false; + } + val |= (((millivolt - XPOWERS_AXP2101_DCDC3_VOL3_MIN) / XPOWERS_AXP2101_DCDC3_VOL_STEPS3) + XPOWERS_AXP2101_DCDC3_VOL_STEPS3_BASE); + return 0 == writeRegister(XPOWERS_AXP2101_DC_VOL2_CTRL, val); + } + return false; + } + + + uint16_t getDC3Voltage(void) + { + int val = readRegister(XPOWERS_AXP2101_DC_VOL2_CTRL) & 0x7F; + if (val == -1) + return 0; + if (val < XPOWERS_AXP2101_DCDC3_VOL_STEPS2_BASE) { + return (val * XPOWERS_AXP2101_DCDC3_VOL_STEPS1) + XPOWERS_AXP2101_DCDC3_VOL_MIN; + } else if (val >= XPOWERS_AXP2101_DCDC3_VOL_STEPS2_BASE && val < XPOWERS_AXP2101_DCDC3_VOL_STEPS3_BASE) { + return (val * XPOWERS_AXP2101_DCDC3_VOL_STEPS2) - 200; + } else { + return (val * XPOWERS_AXP2101_DCDC3_VOL_STEPS3) - 7200; + } + return 0; + } + + uint8_t getDC3WorkMode(void) + { + return getRegisterBit(XPOWERS_AXP2101_DC_VOL2_CTRL, 7); + } + + // DCDC3 85% low voltage turn off PMIC function + void setDC3LowVoltagePowerDowm(bool en) + { + en ? setRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 2) : clrRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 2); + } + + bool getDC3LowVoltagePowerDowmEn() + { + return getRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 2); + } + + + /* + * Power control DCDC4 functions + */ + /** + 0.5~1.2V,10mV/step,71steps + 1.22~1.84V,20mV/step,32steps + */ + bool isEnableDC4(void) + { + return getRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 3); + } + + bool enableDC4(void) + { + return setRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 3); + } + + bool disableDC4(void) + { + return clrRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 3); + } + + bool setDC4Voltage(uint16_t millivolt) + { + int val = readRegister(XPOWERS_AXP2101_DC_VOL3_CTRL); + if (val == -1)return false; + val &= 0x80; + if (millivolt >= XPOWERS_AXP2101_DCDC4_VOL1_MIN && millivolt <= XPOWERS_AXP2101_DCDC4_VOL1_MAX) { + if (millivolt % XPOWERS_AXP2101_DCDC4_VOL_STEPS1) { + log_e("Mistake ! The steps is must %umV", XPOWERS_AXP2101_DCDC4_VOL_STEPS1); + return false; + } + return 0 == writeRegister(XPOWERS_AXP2101_DC_VOL3_CTRL, val | (millivolt - XPOWERS_AXP2101_DCDC4_VOL1_MIN) / XPOWERS_AXP2101_DCDC4_VOL_STEPS1); + + } else if (millivolt >= XPOWERS_AXP2101_DCDC4_VOL2_MIN && millivolt <= XPOWERS_AXP2101_DCDC4_VOL2_MAX) { + if (millivolt % XPOWERS_AXP2101_DCDC4_VOL_STEPS2) { + log_e("Mistake ! The steps is must %umV", XPOWERS_AXP2101_DCDC4_VOL_STEPS2); + return false; + } + val |= (((millivolt - XPOWERS_AXP2101_DCDC4_VOL2_MIN) / XPOWERS_AXP2101_DCDC4_VOL_STEPS2) + XPOWERS_AXP2101_DCDC4_VOL_STEPS2_BASE); + return 0 == writeRegister(XPOWERS_AXP2101_DC_VOL3_CTRL, val); + + } + return false; + } + + uint16_t getDC4Voltage(void) + { + int val = readRegister(XPOWERS_AXP2101_DC_VOL3_CTRL); + if (val == -1)return 0; + val &= 0x7F; + if (val < XPOWERS_AXP2101_DCDC4_VOL_STEPS2_BASE) { + return (val * XPOWERS_AXP2101_DCDC4_VOL_STEPS1) + XPOWERS_AXP2101_DCDC4_VOL1_MIN; + } else { + return (val * XPOWERS_AXP2101_DCDC4_VOL_STEPS2) - 200; + } + return 0; + } + + // DCDC4 85% low voltage turn off PMIC function + void setDC4LowVoltagePowerDowm(bool en) + { + en ? setRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 3) : clrRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 3); + } + + bool getDC4LowVoltagePowerDowmEn() + { + return getRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 3); + } + + /* + * Power control DCDC5 functions,Output to gpio pin + */ + bool isEnableDC5(void) + { + return getRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 4); + } + + bool enableDC5(void) + { + return setRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 4); + } + + bool disableDC5(void) + { + return clrRegisterBit(XPOWERS_AXP2101_DC_ONOFF_DVM_CTRL, 4); + } + + bool setDC5Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP2101_DCDC5_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP2101_DCDC5_VOL_STEPS); + return false; + } + if (millivolt != XPOWERS_AXP2101_DCDC5_VOL_1200MV && millivolt < XPOWERS_AXP2101_DCDC5_VOL_MIN) { + log_e("Mistake ! DC5 minimum voltage is %umV ,%umV", XPOWERS_AXP2101_DCDC5_VOL_1200MV, XPOWERS_AXP2101_DCDC5_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP2101_DCDC5_VOL_MAX) { + log_e("Mistake ! DC5 maximum voltage is %umV", XPOWERS_AXP2101_DCDC5_VOL_MAX); + return false; + } + + int val = readRegister(XPOWERS_AXP2101_DC_VOL4_CTRL); + if (val == -1)return false; + val &= 0xE0; + if (millivolt == XPOWERS_AXP2101_DCDC5_VOL_1200MV) { + return 0 == writeRegister(XPOWERS_AXP2101_DC_VOL4_CTRL, val | XPOWERS_AXP2101_DCDC5_VOL_VAL); + } + val |= (millivolt - XPOWERS_AXP2101_DCDC5_VOL_MIN) / XPOWERS_AXP2101_DCDC5_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP2101_DC_VOL4_CTRL, val); + } + + uint16_t getDC5Voltage(void) + { + int val = readRegister(XPOWERS_AXP2101_DC_VOL4_CTRL) ; + if (val == -1)return 0; + val &= 0x1F; + if (val == XPOWERS_AXP2101_DCDC5_VOL_VAL)return XPOWERS_AXP2101_DCDC5_VOL_1200MV; + return (val * XPOWERS_AXP2101_DCDC5_VOL_STEPS) + XPOWERS_AXP2101_DCDC5_VOL_MIN; + } + + bool isDC5FreqCompensationEn(void) + { + return getRegisterBit(XPOWERS_AXP2101_DC_VOL4_CTRL, 5); + } + + void enableDC5FreqCompensation() + { + setRegisterBit(XPOWERS_AXP2101_DC_VOL4_CTRL, 5); + } + + void disableFreqCompensation() + { + clrRegisterBit(XPOWERS_AXP2101_DC_VOL4_CTRL, 5); + } + + // DCDC4 85% low voltage turn off PMIC function + void setDC5LowVoltagePowerDowm(bool en) + { + en ? setRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 4) : clrRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 4); + } + + bool getDC5LowVoltagePowerDowmEn() + { + return getRegisterBit(XPOWERS_AXP2101_DC_OVP_UVP_CTRL, 4); + } + + /* + * Power control ALDO1 functions + */ + bool isEnableALDO1(void) + { + return getRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 0); + } + + bool enableALDO1(void) + { + return setRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 0); + } + + bool disableALDO1(void) + { + return clrRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 0); + } + + bool setALDO1Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP2101_ALDO1_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP2101_ALDO1_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP2101_ALDO1_VOL_MIN) { + log_e("Mistake ! ALDO1 minimum output voltage is %umV", XPOWERS_AXP2101_ALDO1_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP2101_ALDO1_VOL_MAX) { + log_e("Mistake ! ALDO1 maximum output voltage is %umV", XPOWERS_AXP2101_ALDO1_VOL_MAX); + return false; + } + uint16_t val = readRegister(XPOWERS_AXP2101_LDO_VOL0_CTRL) & 0xE0; + val |= (millivolt - XPOWERS_AXP2101_ALDO1_VOL_MIN) / XPOWERS_AXP2101_ALDO1_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP2101_LDO_VOL0_CTRL, val); + } + + uint16_t getALDO1Voltage(void) + { + uint16_t val = readRegister(XPOWERS_AXP2101_LDO_VOL0_CTRL) & 0x1F; + return val * XPOWERS_AXP2101_ALDO1_VOL_STEPS + XPOWERS_AXP2101_ALDO1_VOL_MIN; + } + + /* + * Power control ALDO2 functions + */ + bool isEnableALDO2(void) + { + return getRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 1); + } + + bool enableALDO2(void) + { + return setRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 1); + } + + bool disableALDO2(void) + { + return clrRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 1); + } + + bool setALDO2Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP2101_ALDO2_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP2101_ALDO2_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP2101_ALDO2_VOL_MIN) { + log_e("Mistake ! ALDO2 minimum output voltage is %umV", XPOWERS_AXP2101_ALDO2_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP2101_ALDO2_VOL_MAX) { + log_e("Mistake ! ALDO2 maximum output voltage is %umV", XPOWERS_AXP2101_ALDO2_VOL_MAX); + return false; + } + uint16_t val = readRegister(XPOWERS_AXP2101_LDO_VOL1_CTRL) & 0xE0; + val |= (millivolt - XPOWERS_AXP2101_ALDO2_VOL_MIN) / XPOWERS_AXP2101_ALDO2_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP2101_LDO_VOL1_CTRL, val); + } + + uint16_t getALDO2Voltage(void) + { + uint16_t val = readRegister(XPOWERS_AXP2101_LDO_VOL1_CTRL) & 0x1F; + return val * XPOWERS_AXP2101_ALDO2_VOL_STEPS + XPOWERS_AXP2101_ALDO2_VOL_MIN; + } + + /* + * Power control ALDO3 functions + */ + bool isEnableALDO3(void) + { + return getRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 2); + } + + bool enableALDO3(void) + { + return setRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 2); + } + + bool disableALDO3(void) + { + return clrRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 2); + } + + bool setALDO3Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP2101_ALDO3_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP2101_ALDO3_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP2101_ALDO3_VOL_MIN) { + log_e("Mistake ! ALDO3 minimum output voltage is %umV", XPOWERS_AXP2101_ALDO3_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP2101_ALDO3_VOL_MAX) { + log_e("Mistake ! ALDO3 maximum output voltage is %umV", XPOWERS_AXP2101_ALDO3_VOL_MAX); + return false; + } + uint16_t val = readRegister(XPOWERS_AXP2101_LDO_VOL2_CTRL) & 0xE0; + val |= (millivolt - XPOWERS_AXP2101_ALDO3_VOL_MIN) / XPOWERS_AXP2101_ALDO3_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP2101_LDO_VOL2_CTRL, val); + } + + uint16_t getALDO3Voltage(void) + { + uint16_t val = readRegister(XPOWERS_AXP2101_LDO_VOL2_CTRL) & 0x1F; + return val * XPOWERS_AXP2101_ALDO3_VOL_STEPS + XPOWERS_AXP2101_ALDO3_VOL_MIN; + } + + /* + * Power control ALDO4 functions + */ + bool isEnableALDO4(void) + { + return getRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 3); + } + + bool enableALDO4(void) + { + return setRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 3); + } + + bool disableALDO4(void) + { + return clrRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 3); + } + + bool setALDO4Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP2101_ALDO4_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP2101_ALDO4_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP2101_ALDO4_VOL_MIN) { + log_e("Mistake ! ALDO4 minimum output voltage is %umV", XPOWERS_AXP2101_ALDO4_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP2101_ALDO4_VOL_MAX) { + log_e("Mistake ! ALDO4 maximum output voltage is %umV", XPOWERS_AXP2101_ALDO4_VOL_MAX); + return false; + } + uint16_t val = readRegister(XPOWERS_AXP2101_LDO_VOL3_CTRL) & 0xE0; + val |= (millivolt - XPOWERS_AXP2101_ALDO4_VOL_MIN) / XPOWERS_AXP2101_ALDO4_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP2101_LDO_VOL3_CTRL, val); + } + + uint16_t getALDO4Voltage(void) + { + uint16_t val = readRegister(XPOWERS_AXP2101_LDO_VOL3_CTRL) & 0x1F; + return val * XPOWERS_AXP2101_ALDO4_VOL_STEPS + XPOWERS_AXP2101_ALDO4_VOL_MIN; + } + + /* + * Power control BLDO1 functions + */ + bool isEnableBLDO1(void) + { + return getRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 4); + } + + bool enableBLDO1(void) + { + return setRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 4); + } + + bool disableBLDO1(void) + { + return clrRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 4); + } + + bool setBLDO1Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP2101_BLDO1_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP2101_BLDO1_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP2101_BLDO1_VOL_MIN) { + log_e("Mistake ! BLDO1 minimum output voltage is %umV", XPOWERS_AXP2101_BLDO1_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP2101_BLDO1_VOL_MAX) { + log_e("Mistake ! BLDO1 maximum output voltage is %umV", XPOWERS_AXP2101_BLDO1_VOL_MAX); + return false; + } + int val = readRegister(XPOWERS_AXP2101_LDO_VOL4_CTRL); + if (val == -1)return false; + val &= 0xE0; + val |= (millivolt - XPOWERS_AXP2101_BLDO1_VOL_MIN) / XPOWERS_AXP2101_BLDO1_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP2101_LDO_VOL4_CTRL, val); + } + + uint16_t getBLDO1Voltage(void) + { + int val = readRegister(XPOWERS_AXP2101_LDO_VOL4_CTRL); + if (val == -1)return 0; + val &= 0x1F; + return val * XPOWERS_AXP2101_BLDO1_VOL_STEPS + XPOWERS_AXP2101_BLDO1_VOL_MIN; + } + + /* + * Power control BLDO2 functions + */ + bool isEnableBLDO2(void) + { + return getRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 5); + } + + bool enableBLDO2(void) + { + return setRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 5); + } + + bool disableBLDO2(void) + { + return clrRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 5); + } + + bool setBLDO2Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP2101_BLDO2_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP2101_BLDO2_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP2101_BLDO2_VOL_MIN) { + log_e("Mistake ! BLDO2 minimum output voltage is %umV", XPOWERS_AXP2101_BLDO2_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP2101_BLDO2_VOL_MAX) { + log_e("Mistake ! BLDO2 maximum output voltage is %umV", XPOWERS_AXP2101_BLDO2_VOL_MAX); + return false; + } + uint16_t val = readRegister(XPOWERS_AXP2101_LDO_VOL5_CTRL) & 0xE0; + val |= (millivolt - XPOWERS_AXP2101_BLDO2_VOL_MIN) / XPOWERS_AXP2101_BLDO2_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP2101_LDO_VOL5_CTRL, val); + } + + uint16_t getBLDO2Voltage(void) + { + int val = readRegister(XPOWERS_AXP2101_LDO_VOL5_CTRL); + if (val == -1)return 0; + val &= 0x1F; + return val * XPOWERS_AXP2101_BLDO2_VOL_STEPS + XPOWERS_AXP2101_BLDO2_VOL_MIN; + } + + /* + * Power control CPUSLDO functions + */ + bool isEnableCPUSLDO(void) + { + return getRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 6); + } + + bool enableCPUSLDO(void) + { + return setRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 6); + } + + bool disableCPUSLDO(void) + { + return clrRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 6); + } + + bool setCPUSLDOVoltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP2101_CPUSLDO_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP2101_CPUSLDO_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP2101_CPUSLDO_VOL_MIN) { + log_e("Mistake ! CPULDO minimum output voltage is %umV", XPOWERS_AXP2101_CPUSLDO_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP2101_CPUSLDO_VOL_MAX) { + log_e("Mistake ! CPULDO maximum output voltage is %umV", XPOWERS_AXP2101_CPUSLDO_VOL_MAX); + return false; + } + uint16_t val = readRegister(XPOWERS_AXP2101_LDO_VOL6_CTRL) & 0xE0; + val |= (millivolt - XPOWERS_AXP2101_CPUSLDO_VOL_MIN) / XPOWERS_AXP2101_CPUSLDO_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP2101_LDO_VOL6_CTRL, val); + } + + uint16_t getCPUSLDOVoltage(void) + { + int val = readRegister(XPOWERS_AXP2101_LDO_VOL6_CTRL); + if (val == -1)return 0; + val &= 0x1F; + return val * XPOWERS_AXP2101_CPUSLDO_VOL_STEPS + XPOWERS_AXP2101_CPUSLDO_VOL_MIN; + } + + + /* + * Power control DLDO1 functions + */ + bool isEnableDLDO1(void) + { + return getRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 7); + } + + bool enableDLDO1(void) + { + return setRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 7); + } + + bool disableDLDO1(void) + { + return clrRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL0, 7); + } + + bool setDLDO1Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP2101_DLDO1_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP2101_DLDO1_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP2101_DLDO1_VOL_MIN) { + log_e("Mistake ! DLDO1 minimum output voltage is %umV", XPOWERS_AXP2101_DLDO1_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP2101_DLDO1_VOL_MAX) { + log_e("Mistake ! DLDO1 maximum output voltage is %umV", XPOWERS_AXP2101_DLDO1_VOL_MAX); + return false; + } + uint16_t val = readRegister(XPOWERS_AXP2101_LDO_VOL7_CTRL) & 0xE0; + val |= (millivolt - XPOWERS_AXP2101_DLDO1_VOL_MIN) / XPOWERS_AXP2101_DLDO1_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP2101_LDO_VOL7_CTRL, val); + } + + uint16_t getDLDO1Voltage(void) + { + int val = readRegister(XPOWERS_AXP2101_LDO_VOL7_CTRL); + if (val == -1)return 0; + val &= 0x1F; + return val * XPOWERS_AXP2101_DLDO1_VOL_STEPS + XPOWERS_AXP2101_DLDO1_VOL_MIN; + } + + /* + * Power control DLDO2 functions + */ + bool isEnableDLDO2(void) + { + return getRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL1, 0); + } + + bool enableDLDO2(void) + { + return setRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL1, 0); + } + + bool disableDLDO2(void) + { + return clrRegisterBit(XPOWERS_AXP2101_LDO_ONOFF_CTRL1, 0); + } + + bool setDLDO2Voltage(uint16_t millivolt) + { + if (millivolt % XPOWERS_AXP2101_DLDO2_VOL_STEPS) { + log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP2101_DLDO2_VOL_STEPS); + return false; + } + if (millivolt < XPOWERS_AXP2101_DLDO2_VOL_MIN) { + log_e("Mistake ! DLDO2 minimum output voltage is %umV", XPOWERS_AXP2101_DLDO2_VOL_MIN); + return false; + } else if (millivolt > XPOWERS_AXP2101_DLDO2_VOL_MAX) { + log_e("Mistake ! DLDO2 maximum output voltage is %umV", XPOWERS_AXP2101_DLDO2_VOL_MAX); + return false; + } + uint16_t val = readRegister(XPOWERS_AXP2101_LDO_VOL8_CTRL) & 0xE0; + val |= (millivolt - XPOWERS_AXP2101_DLDO2_VOL_MIN) / XPOWERS_AXP2101_DLDO2_VOL_STEPS; + return 0 == writeRegister(XPOWERS_AXP2101_LDO_VOL8_CTRL, val); + } + + uint16_t getDLDO2Voltage(void) + { + int val = readRegister(XPOWERS_AXP2101_LDO_VOL8_CTRL); + if (val == -1)return 0; + val &= 0x1F; + return val * XPOWERS_AXP2101_DLDO2_VOL_STEPS + XPOWERS_AXP2101_DLDO2_VOL_MIN; + } + + + /* + * Power ON OFF IRQ TIMMING Control method + */ + + void setIrqLevelTime(xpowers_irq_time_t opt) + { + int val = readRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL); + if (val == -1)return; + val &= 0xCF; + writeRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL, val | (opt << 4)); + } + + xpowers_irq_time_t getIrqLevelTime(void) + { + return (xpowers_irq_time_t)((readRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL) & 0x30) >> 4); + } + + /** + * @brief Set the PEKEY power-on long press time. + * @param opt: See xpowers_press_on_time_t enum for details. + * @retval + */ + bool setPowerKeyPressOnTime(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL); + if (val == -1)return false; + val &= 0xFC; + return 0 == writeRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL, val | opt); + } + + /** + * @brief Get the PEKEY power-on long press time. + * @retval See xpowers_press_on_time_t enum for details. + */ + uint8_t getPowerKeyPressOnTime(void) + { + int val = readRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL); + if (val == -1)return 0; + return (val & 0x03) ; + } + + /** + * @brief Set the PEKEY power-off long press time. + * @param opt: See xpowers_press_off_time_t enum for details. + * @retval + */ + bool setPowerKeyPressOffTime(uint8_t opt) + { + int val = readRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL); + if (val == -1)return false; + val &= 0xF3; + return 0 == writeRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL, val | (opt << 2)); + } + + /** + * @brief Get the PEKEY power-off long press time. + * @retval See xpowers_press_off_time_t enum for details. + */ + uint8_t getPowerKeyPressOffTime(void) + { + return ((readRegister(XPOWERS_AXP2101_IRQ_OFF_ON_LEVEL_CTRL) & 0x0C) >> 2); + } + + /* + * ADC Control method + */ + bool enableGeneralAdcChannel(void) + { + return setRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 5); + } + + bool disableGeneralAdcChannel(void) + { + return clrRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 5); + } + + bool enableTemperatureMeasure(void) + { + return setRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 4); + } + + bool disableTemperatureMeasure(void) + { + return clrRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 4); + } + + float getTemperature(void) + { + uint16_t raw = readRegisterH6L8(XPOWERS_AXP2101_ADC_DATA_RELUST8, XPOWERS_AXP2101_ADC_DATA_RELUST9); + return XPOWERS_AXP2101_CONVERSION(raw); + } + + bool enableSystemVoltageMeasure(void) + { + return setRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 3); + } + + bool disableSystemVoltageMeasure(void) + { + return clrRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 3); + } + + uint16_t getSystemVoltage(void) + { + return readRegisterH6L8(XPOWERS_AXP2101_ADC_DATA_RELUST6, XPOWERS_AXP2101_ADC_DATA_RELUST7); + } + + bool enableVbusVoltageMeasure(void) + { + return setRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 2); + } + + bool disableVbusVoltageMeasure(void) + { + return clrRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 2); + } + + uint16_t getVbusVoltage(void) + { + if (!isVbusIn()) { + return 0; + } + return readRegisterH6L8(XPOWERS_AXP2101_ADC_DATA_RELUST4, XPOWERS_AXP2101_ADC_DATA_RELUST5); + } + + bool enableTSPinMeasure(void) + { + return setRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 1); + } + + bool disableTSPinMeasure(void) + { + return clrRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 1); + } + + bool enableTSPinLowFreqSample(void) + { + return setRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 7); + } + + bool disableTSPinLowFreqSample(void) + { + return clrRegisterBit(XPOWERS_AXP2101_ADC_DATA_RELUST2, 7); + } + + uint16_t getTsTemperature(void) + { + return readRegisterH6L8(XPOWERS_AXP2101_ADC_DATA_RELUST2, XPOWERS_AXP2101_ADC_DATA_RELUST3); + } + + bool enableBattVoltageMeasure(void) + { + return setRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 0); + } + + bool disableBattVoltageMeasure(void) + { + return clrRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 0); + } + + bool enableBattDetection(void) + { + return setRegisterBit(XPOWERS_AXP2101_BAT_DET_CTRL, 0); + } + + bool disableBattDetection(void) + { + return clrRegisterBit(XPOWERS_AXP2101_BAT_DET_CTRL, 0); + } + + uint16_t getBattVoltage(void) + { + if (!isBatteryConnect()) { + return 0; + } + return readRegisterH5L8(XPOWERS_AXP2101_ADC_DATA_RELUST0, XPOWERS_AXP2101_ADC_DATA_RELUST1); + } + + int getBatteryPercent(void) + { + if (!isBatteryConnect()) { + return -1; + } + return readRegister(XPOWERS_AXP2101_BAT_PERCENT_DATA); + } + + /* + * CHG LED setting and control + */ + // void enableChargingLed(void) + // { + // setRegisterBit(XPOWERS_AXP2101_CHGLED_SET_CTRL, 0); + // } + + // void disableChargingLed(void) + // { + // clrRegisterBit(XPOWERS_AXP2101_CHGLED_SET_CTRL, 0); + // } + + /** + * @brief Set charging led mode. + * @retval See xpowers_chg_led_mode_t enum for details. + */ + void setChargingLedMode(uint8_t mode) + { + int val; + switch (mode) { + case XPOWERS_CHG_LED_OFF: + // clrRegisterBit(XPOWERS_AXP2101_CHGLED_SET_CTRL, 0); + // break; + case XPOWERS_CHG_LED_BLINK_1HZ: + case XPOWERS_CHG_LED_BLINK_4HZ: + case XPOWERS_CHG_LED_ON: + val = readRegister(XPOWERS_AXP2101_CHGLED_SET_CTRL); + if (val == -1)return; + val &= 0xC8; + val |= 0x05; //use manual ctrl + val |= (mode << 4); + writeRegister(XPOWERS_AXP2101_CHGLED_SET_CTRL, val); + break; + case XPOWERS_CHG_LED_CTRL_CHG: + val = readRegister(XPOWERS_AXP2101_CHGLED_SET_CTRL); + if (val == -1)return; + val &= 0xF9; + writeRegister(XPOWERS_AXP2101_CHGLED_SET_CTRL, val | 0x01); // use type A mode + // writeRegister(XPOWERS_AXP2101_CHGLED_SET_CTRL, val | 0x02); // use type B mode + break; + default: + break; + } + } + + uint8_t getChargingLedMode() + { + int val = readRegister(XPOWERS_AXP2101_CHGLED_SET_CTRL); + if (val == -1)return XPOWERS_CHG_LED_OFF; + val >>= 1; + if ((val & 0x02) == 0x02) { + val >>= 4; + return val & 0x03; + } + return XPOWERS_CHG_LED_CTRL_CHG; + } + + /** + * @brief 预充电充电电流限制 + * @note Precharge current limit 25*N mA + * @param opt: 25 * opt + * @retval None + */ + void setPrechargeCurr(xpowers_prechg_t opt) + { + int val = readRegister(XPOWERS_AXP2101_IPRECHG_SET); + if (val == -1)return; + val &= 0xFC; + writeRegister(XPOWERS_AXP2101_IPRECHG_SET, val | opt); + } + + xpowers_prechg_t getPrechargeCurr(void) + { + return (xpowers_prechg_t)(readRegister(XPOWERS_AXP2101_IPRECHG_SET) & 0x03); + } + + + /** + * @brief Set charge current. + * @param opt: See xpowers_axp2101_chg_curr_t enum for details. + * @retval + */ + bool setChargerConstantCurr(uint8_t opt) + { + if (opt > XPOWERS_AXP2101_CHG_CUR_1000MA)return false; + int val = readRegister(XPOWERS_AXP2101_ICC_CHG_SET); + if (val == -1)return false; + val &= 0xE0; + return 0 == writeRegister(XPOWERS_AXP2101_ICC_CHG_SET, val | opt); + } + + /** + * @brief Get charge current settings. + * @retval See xpowers_axp2101_chg_curr_t enum for details. + */ + uint8_t getChargerConstantCurr(void) + { + int val = readRegister(XPOWERS_AXP2101_ICC_CHG_SET); + if (val == -1)return 0; + return val & 0x1F; + } + + /** + * @brief 充电终止电流限制 + * @note Charging termination of current limit + * @retval + */ + void setChargerTerminationCurr(xpowers_axp2101_chg_iterm_t opt) + { + int val = readRegister(XPOWERS_AXP2101_ITERM_CHG_SET_CTRL); + if (val == -1)return; + val &= 0xF0; + writeRegister(XPOWERS_AXP2101_ITERM_CHG_SET_CTRL, val | opt); + } + + xpowers_axp2101_chg_iterm_t getChargerTerminationCurr(void) + { + return (xpowers_axp2101_chg_iterm_t)(readRegister(XPOWERS_AXP2101_ITERM_CHG_SET_CTRL) & 0x0F); + } + + void enableChargerTerminationLimit(void) + { + int val = readRegister(XPOWERS_AXP2101_ITERM_CHG_SET_CTRL); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_ITERM_CHG_SET_CTRL, val | 0x10); + } + + void disableChargerTerminationLimit(void) + { + int val = readRegister(XPOWERS_AXP2101_ITERM_CHG_SET_CTRL); + if (val == -1)return; + writeRegister(XPOWERS_AXP2101_ITERM_CHG_SET_CTRL, val & 0xEF); + } + + bool isChargerTerminationLimit(void) + { + return getRegisterBit(XPOWERS_AXP2101_ITERM_CHG_SET_CTRL, 4); + } + + + /** + * @brief Set charge target voltage. + * @param opt: See xpowers_axp2101_chg_vol_t enum for details. + * @retval + */ + bool setChargeTargetVoltage(uint8_t opt) + { + if (opt >= XPOWERS_AXP2101_CHG_VOL_MAX)return false; + int val = readRegister(XPOWERS_AXP2101_CV_CHG_VOL_SET); + if (val == -1)return false; + val &= 0xF8; + return 0 == writeRegister(XPOWERS_AXP2101_CV_CHG_VOL_SET, val | opt); + } + + /** + * @brief Get charge target voltage settings. + * @retval See xpowers_axp2101_chg_vol_t enum for details. + */ + uint8_t getChargeTargetVoltage(void) + { + return (readRegister(XPOWERS_AXP2101_CV_CHG_VOL_SET) & 0x07); + } + + + /** + * @brief 设定热阈值 + * @note Thermal regulation threshold setting + */ + void setThermaThreshold(xpowers_thermal_t opt) + { + int val = readRegister(XPOWERS_AXP2101_THE_REGU_THRES_SET); + if (val == -1)return; + val &= 0xFC; + writeRegister(XPOWERS_AXP2101_THE_REGU_THRES_SET, val | opt); + } + + xpowers_thermal_t getThermaThreshold(void) + { + return (xpowers_thermal_t)(readRegister(XPOWERS_AXP2101_THE_REGU_THRES_SET) & 0x03); + } + + uint8_t getBatteryParameter() + { + return readRegister(XPOWERS_AXP2101_BAT_PARAME); + } + + void fuelGaugeControl(bool writeROM, bool enable) + { + if (writeROM) { + clrRegisterBit(XPOWERS_AXP2101_FUEL_GAUGE_CTRL, 4); + } else { + setRegisterBit(XPOWERS_AXP2101_FUEL_GAUGE_CTRL, 4); + } + if (enable) { + setRegisterBit(XPOWERS_AXP2101_FUEL_GAUGE_CTRL, 0); + } else { + clrRegisterBit(XPOWERS_AXP2101_FUEL_GAUGE_CTRL, 0); + } + } + + /* + * Interrupt status/control functions + */ + + /** + * @brief Get the interrupt controller mask value. + * @retval Mask value corresponds to xpowers_axp2101_irq_t , + */ + uint64_t getIrqStatus(void) + { + statusRegister[0] = readRegister(XPOWERS_AXP2101_INTSTS1); + statusRegister[1] = readRegister(XPOWERS_AXP2101_INTSTS2); + statusRegister[2] = readRegister(XPOWERS_AXP2101_INTSTS3); + return (uint32_t)(statusRegister[0] << 16) | (uint32_t)(statusRegister[1] << 8) | (uint32_t)(statusRegister[2]); + } + + + /** + * @brief Clear interrupt controller state. + */ + void clearIrqStatus() + { + for (int i = 0; i < XPOWERS_AXP2101_INTSTS_CNT; i++) { + writeRegister(XPOWERS_AXP2101_INTSTS1 + i, 0xFF); + statusRegister[i] = 0; + } + } + + /* + * @brief Debug interrupt setting register + * */ +#ifdef ARDUINO + void printIntRegister(Stream *stream) + { + for (int i = 0; i < XPOWERS_AXP2101_INTSTS_CNT; i++) { + uint8_t val = readRegister(XPOWERS_AXP2101_INTEN1 + i); + stream->print("INT["); stream->print(i); + stream->print(']'); + stream->print(" HEX: "); stream->print(val, HEX); + stream->print(" BIN:0b"); stream->println(val, BIN); + } + } +#else + void printIntRegister() + { + for (int i = 0; i < XPOWERS_AXP2101_INTSTS_CNT; i++) { + uint8_t val = readRegister(XPOWERS_AXP2101_INTEN1 + i); + printf("INT[%d] HEX:0x%X\n", i, val); + } + } +#endif + + /** + * @brief Eanble PMU interrupt control mask . + * @param opt: View the related chip type xpowers_axp2101_irq_t enumeration + * parameters in "XPowersParams.hpp" + * @retval + */ + bool enableIRQ(uint64_t opt) + { + return setInterruptImpl(opt, true); + } + + /** + * @brief Disable PMU interrupt control mask . + * @param opt: View the related chip type xpowers_axp2101_irq_t enumeration + * parameters in "XPowersParams.hpp" + * @retval + */ + bool disableIRQ(uint64_t opt) + { + return setInterruptImpl(opt, false); + } + + //IRQ STATUS 0 + bool isDropWarningLevel2Irq(void) + { + uint8_t mask = XPOWERS_AXP2101_WARNING_LEVEL2_IRQ; + if (intRegister[0] & mask) { + return IS_BIT_SET(statusRegister[0], mask); + } + return false; + } + + bool isDropWarningLevel1Irq(void) + { + uint8_t mask = XPOWERS_AXP2101_WARNING_LEVEL1_IRQ; + if (intRegister[0] & mask) { + return IS_BIT_SET(statusRegister[0], mask); + } + return false; + } + + bool isGaugeWdtTimeoutIrq() + { + uint8_t mask = XPOWERS_AXP2101_WDT_TIMEOUT_IRQ; + if (intRegister[0] & mask) { + return IS_BIT_SET(statusRegister[0], mask); + } + return false; + } + + bool isBatChargerOverTemperatureIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_BAT_CHG_OVER_TEMP_IRQ; + if (intRegister[0] & mask) { + return IS_BIT_SET(statusRegister[0], mask); + } + return false; + } + + bool isBatChargerUnderTemperatureIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_BAT_CHG_UNDER_TEMP_IRQ; + if (intRegister[0] & mask) { + return IS_BIT_SET(statusRegister[0], mask); + } + return false; + } + + bool isBatWorkOverTemperatureIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_BAT_NOR_OVER_TEMP_IRQ; + if (intRegister[0] & mask) { + return IS_BIT_SET(statusRegister[0], mask); + } + return false; + } + + bool isBatWorkUnderTemperatureIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_BAT_NOR_UNDER_TEMP_IRQ; + if (intRegister[0] & mask) { + return IS_BIT_SET(statusRegister[0], mask); + } + return false; + } + + //IRQ STATUS 1 + bool isVbusInsertIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_VBUS_INSERT_IRQ >> 8; + if (intRegister[1] & mask) { + return IS_BIT_SET(statusRegister[1], mask); + } + return false; + } + + bool isVbusRemoveIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_VBUS_REMOVE_IRQ >> 8; + if (intRegister[1] & mask) { + return IS_BIT_SET(statusRegister[1], mask); + } + return false; + } + + bool isBatInsertIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_BAT_INSERT_IRQ >> 8; + if (intRegister[1] & mask) { + return IS_BIT_SET(statusRegister[1], mask); + } + return false; + } + + bool isBatRemoveIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_BAT_REMOVE_IRQ >> 8; + if (intRegister[1] & mask) { + return IS_BIT_SET(statusRegister[1], mask); + } + return false; + } + + bool isPekeyShortPressIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_PKEY_SHORT_IRQ >> 8; + if (intRegister[1] & mask) { + return IS_BIT_SET(statusRegister[1], mask); + } + return false; + + } + + bool isPekeyLongPressIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_PKEY_LONG_IRQ >> 8; + if (intRegister[1] & mask) { + return IS_BIT_SET(statusRegister[1], mask); + } + return false; + } + + bool isPekeyNegativeIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ >> 8; + if (intRegister[1] & mask) { + return IS_BIT_SET(statusRegister[1], mask); + } + return false; + } + + bool isPekeyPositiveIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_PKEY_POSITIVE_IRQ >> 8; + if (intRegister[1] & mask) { + return IS_BIT_SET(statusRegister[1], mask); + } + return false; + } + + //IRQ STATUS 2 + bool isWdtExpireIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_WDT_EXPIRE_IRQ >> 16; + if (intRegister[2] & mask) { + return IS_BIT_SET(statusRegister[2], mask); + } + return false; + } + + bool isLdoOverCurrentIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_LDO_OVER_CURR_IRQ >> 16; + if (intRegister[2] & mask) { + return IS_BIT_SET(statusRegister[2], mask); + } + return false; + } + + bool isBatfetOverCurrentIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_BATFET_OVER_CURR_IRQ >> 16; + if (intRegister[2] & mask) { + return IS_BIT_SET(statusRegister[2], mask); + } + return false; + } + + bool isBatChagerDoneIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_BAT_CHG_DONE_IRQ >> 16; + if (intRegister[2] & mask) { + return IS_BIT_SET(statusRegister[2], mask); + } + return false; + } + + bool isBatChagerStartIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_BAT_CHG_START_IRQ >> 16; + if (intRegister[2] & mask) { + return IS_BIT_SET(statusRegister[2], mask); + } + return false; + } + + bool isBatDieOverTemperatureIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_DIE_OVER_TEMP_IRQ >> 16; + if (intRegister[2] & mask) { + return IS_BIT_SET(statusRegister[2], mask); + } + return false; + } + + bool isChagerOverTimeoutIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_CHAGER_TIMER_IRQ >> 16; + if (intRegister[2] & mask) { + return IS_BIT_SET(statusRegister[2], mask); + } + return false; + } + + bool isBatOverVoltageIrq(void) + { + uint8_t mask = XPOWERS_AXP2101_BAT_OVER_VOL_IRQ >> 16; + if (intRegister[2] & mask) { + return IS_BIT_SET(statusRegister[2], mask); + } + return false; + } + + + uint8_t getChipID(void) + { + return readRegister(XPOWERS_AXP2101_IC_TYPE); + } + +protected: + + uint16_t getPowerChannelVoltage(uint8_t channel) + { + switch (channel) { + case XPOWERS_DCDC1: + return getDC1Voltage(); + case XPOWERS_DCDC2: + return getDC2Voltage(); + case XPOWERS_DCDC3: + return getDC3Voltage(); + case XPOWERS_DCDC4: + return getDC4Voltage(); + case XPOWERS_DCDC5: + return getDC5Voltage(); + case XPOWERS_ALDO1: + return getALDO1Voltage(); + case XPOWERS_ALDO2: + return getALDO2Voltage(); + case XPOWERS_ALDO3: + return getALDO3Voltage(); + case XPOWERS_ALDO4: + return getALDO4Voltage(); + case XPOWERS_BLDO1: + return getBLDO1Voltage(); + case XPOWERS_BLDO2: + return getBLDO2Voltage(); + case XPOWERS_DLDO1: + return getDLDO1Voltage(); + case XPOWERS_DLDO2: + return getDLDO2Voltage(); + case XPOWERS_VBACKUP: + return getButtonBatteryVoltage(); + default: + break; + } + return 0; + } + + bool inline enablePowerOutput(uint8_t channel) + { + switch (channel) { + case XPOWERS_DCDC1: + return enableDC1(); + case XPOWERS_DCDC2: + return enableDC2(); + case XPOWERS_DCDC3: + return enableDC3(); + case XPOWERS_DCDC4: + return enableDC4(); + case XPOWERS_DCDC5: + return enableDC5(); + case XPOWERS_ALDO1: + return enableALDO1(); + case XPOWERS_ALDO2: + return enableALDO2(); + case XPOWERS_ALDO3: + return enableALDO3(); + case XPOWERS_ALDO4: + return enableALDO4(); + case XPOWERS_BLDO1: + return enableBLDO1(); + case XPOWERS_BLDO2: + return enableBLDO2(); + case XPOWERS_DLDO1: + return enableDLDO1(); + case XPOWERS_DLDO2: + return enableDLDO2(); + case XPOWERS_VBACKUP: + return enableButtonBatteryCharge(); + default: + break; + } + return false; + } + + bool inline disablePowerOutput(uint8_t channel) + { + if (getProtectedChannel(channel)) { + log_e("Failed to disable the power channel, the power channel has been protected"); + return false; + } + switch (channel) { + case XPOWERS_DCDC1: + return disableDC1(); + case XPOWERS_DCDC2: + return disableDC2(); + case XPOWERS_DCDC3: + return disableDC3(); + case XPOWERS_DCDC4: + return disableDC4(); + case XPOWERS_DCDC5: + return disableDC5(); + case XPOWERS_ALDO1: + return disableALDO1(); + case XPOWERS_ALDO2: + return disableALDO2(); + case XPOWERS_ALDO3: + return disableALDO3(); + case XPOWERS_ALDO4: + return disableALDO4(); + case XPOWERS_BLDO1: + return disableBLDO1(); + case XPOWERS_BLDO2: + return disableBLDO2(); + case XPOWERS_DLDO1: + return disableDLDO1(); + case XPOWERS_DLDO2: + return disableDLDO2(); + case XPOWERS_VBACKUP: + return disableButtonBatteryCharge(); + case XPOWERS_CPULDO: + return disableCPUSLDO(); + default: + break; + } + return false; + } + + bool inline isPowerChannelEnable(uint8_t channel) + { + switch (channel) { + case XPOWERS_DCDC1: + return isEnableDC1(); + case XPOWERS_DCDC2: + return isEnableDC2(); + case XPOWERS_DCDC3: + return isEnableDC3(); + case XPOWERS_DCDC4: + return isEnableDC4(); + case XPOWERS_DCDC5: + return isEnableDC5(); + case XPOWERS_ALDO1: + return isEnableALDO1(); + case XPOWERS_ALDO2: + return isEnableALDO2(); + case XPOWERS_ALDO3: + return isEnableALDO3(); + case XPOWERS_ALDO4: + return isEnableALDO4(); + case XPOWERS_BLDO1: + return isEnableBLDO1(); + case XPOWERS_BLDO2: + return isEnableBLDO2(); + case XPOWERS_DLDO1: + return isEnableDLDO1(); + case XPOWERS_DLDO2: + return isEnableDLDO2(); + case XPOWERS_VBACKUP: + return isEanbleButtonBatteryCharge(); + case XPOWERS_CPULDO: + return isEnableCPUSLDO(); + default: + break; + } + return false; + } + + bool inline setPowerChannelVoltage(uint8_t channel, uint16_t millivolt) + { + if (getProtectedChannel(channel)) { + log_e("Failed to set the power channel, the power channel has been protected"); + return false; + } + switch (channel) { + case XPOWERS_DCDC1: + return setDC1Voltage(millivolt); + case XPOWERS_DCDC2: + return setDC2Voltage(millivolt); + case XPOWERS_DCDC3: + return setDC3Voltage(millivolt); + case XPOWERS_DCDC4: + return setDC4Voltage(millivolt); + case XPOWERS_DCDC5: + return setDC5Voltage(millivolt); + case XPOWERS_ALDO1: + return setALDO1Voltage(millivolt); + case XPOWERS_ALDO2: + return setALDO2Voltage(millivolt); + case XPOWERS_ALDO3: + return setALDO3Voltage(millivolt); + case XPOWERS_ALDO4: + return setALDO4Voltage(millivolt); + case XPOWERS_BLDO1: + return setBLDO1Voltage(millivolt); + case XPOWERS_BLDO2: + return setBLDO1Voltage(millivolt); + case XPOWERS_DLDO1: + return setDLDO1Voltage(millivolt); + case XPOWERS_DLDO2: + return setDLDO1Voltage(millivolt); + case XPOWERS_VBACKUP: + return setButtonBatteryChargeVoltage(millivolt); + case XPOWERS_CPULDO: + return setCPUSLDOVoltage(millivolt); + default: + break; + } + return false; + } + + bool initImpl() + { + if (getChipID() == XPOWERS_AXP2101_CHIP_ID) { + setChipModel(XPOWERS_AXP2101); + disableTSPinMeasure(); //Disable NTC temperature detection by default + return true; + } + return false; + } + + /* + * Interrupt control functions + */ + bool setInterruptImpl(uint32_t opts, bool enable) + { + int res = 0; + uint8_t data = 0, value = 0; + log_d("%s - HEX:0x%x \n", enable ? "ENABLE" : "DISABLE", opts); + if (opts & 0x0000FF) { + value = opts & 0xFF; + // log_d("Write INT0: %x\n", value); + data = readRegister(XPOWERS_AXP2101_INTEN1); + intRegister[0] = enable ? (data | value) : (data & (~value)); + res |= writeRegister(XPOWERS_AXP2101_INTEN1, intRegister[0]); + } + if (opts & 0x00FF00) { + value = opts >> 8; + // log_d("Write INT1: %x\n", value); + data = readRegister(XPOWERS_AXP2101_INTEN2); + intRegister[1] = enable ? (data | value) : (data & (~value)); + res |= writeRegister(XPOWERS_AXP2101_INTEN2, intRegister[1]); + } + if (opts & 0xFF0000) { + value = opts >> 16; + // log_d("Write INT2: %x\n", value); + data = readRegister(XPOWERS_AXP2101_INTEN3); + intRegister[2] = enable ? (data | value) : (data & (~value)); + res |= writeRegister(XPOWERS_AXP2101_INTEN3, intRegister[2]); + } + return res == 0; + } + + const char *getChipNameImpl(void) + { + return "AXP2101"; + } + +private: + uint8_t statusRegister[XPOWERS_AXP2101_INTSTS_CNT]; + uint8_t intRegister[XPOWERS_AXP2101_INTSTS_CNT]; +}; + + + diff --git a/buildroot/package/axp2101/src/XPowersLib/XPowersCommon.tpp b/buildroot/package/axp2101/src/XPowersLib/XPowersCommon.tpp new file mode 100644 index 000000000..ccf171bda --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/XPowersCommon.tpp @@ -0,0 +1,512 @@ +/** + * + * @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 + +#if defined(ARDUINO) +#include +#elif defined(ESP_PLATFORM) +#include "esp_log.h" +#include "esp_err.h" +#include +#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 +#include +#include +#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 + +#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 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) { + __wire->setPins(__sda, __scl); + } + __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)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,4,0)) + // New fields since esp-idf-v5.3-beta1 + .scl_wait_us = 0, +#endif + .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 *)®, + 1, + buf, + length, + -1)) { + return 0; + } +#else //ESP_IDF_VERSION + if (ESP_OK == i2c_master_write_read_device(__i2c_num, + __addr, + (uint8_t *)®, + 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 + return 0; + } + + + 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) { + __wire->setPins(__sda, __scl); + } + __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(*this); + } + + inline chipType &thisChip() + { + return static_cast(*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; +}; diff --git a/buildroot/package/axp2101/src/XPowersLib/XPowersLib.h b/buildroot/package/axp2101/src/XPowersLib/XPowersLib.h new file mode 100644 index 000000000..94526f24a --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/XPowersLib.h @@ -0,0 +1,37 @@ +/** + * @file XPowersLib.h + * @author Lewis He (lewishe@outlook.com) + * @license MIT + * @copyright Copyright (c) 2022 + * @date 2022-05-07 + * + */ + +#ifndef __XPOWERSLIB_H__ +#define __XPOWERSLIB_H__ + + +#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; +#else +#include "XPowersAXP192.tpp" +#include "XPowersAXP202.tpp" +#include "XPowersAXP2101.tpp" +#include "PowersSY6970.tpp" +#include "PowerDeliveryHUSB238.hpp" +#endif + + + + + + + +#endif /*__XPOWERSLIB_H__*/ \ No newline at end of file diff --git a/buildroot/package/axp2101/src/XPowersLib/XPowersLibInterface.cpp b/buildroot/package/axp2101/src/XPowersLib/XPowersLibInterface.cpp new file mode 100644 index 000000000..e6f5fe4de --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/XPowersLibInterface.cpp @@ -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 +#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; +} \ No newline at end of file diff --git a/buildroot/package/axp2101/src/XPowersLib/XPowersLibInterface.hpp b/buildroot/package/axp2101/src/XPowersLib/XPowersLibInterface.hpp new file mode 100644 index 000000000..e3188c676 --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/XPowersLibInterface.hpp @@ -0,0 +1,654 @@ +/** + * + * @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 +#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 satatus 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; + + + // 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->isBatChagerStartIrq()) { + * Serial.println("isBatChagerStart"); + * } + * ...... + * + * 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 Eanble 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 isBatChagerDoneIrq() = 0; + + /** + * @brief Interrupt response when PMU charging starts + * @retval true valid false invalid + */ + virtual bool isBatChagerStartIrq() = 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; + +}; + diff --git a/buildroot/package/axp2101/src/XPowersLib/XPowersParams.hpp b/buildroot/package/axp2101/src/XPowersLib/XPowersParams.hpp new file mode 100644 index 000000000..348032a3e --- /dev/null +++ b/buildroot/package/axp2101/src/XPowersLib/XPowersParams.hpp @@ -0,0 +1,399 @@ +/** + * + * @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; + +/** + * @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 enable(LEVEL2) + XPOWERS_APX202_APS_LOW_VOL_LEVEL1_IRQ = _BV(25), //APS low-voltage, IRQ enable(LEVEL1) + 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; + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/buildroot/package/axp2101/src/include/main.h b/buildroot/package/axp2101/src/include/main.h new file mode 100644 index 000000000..45dcbb04b --- /dev/null +++ b/buildroot/package/axp2101/src/include/main.h @@ -0,0 +1,3 @@ +#pragma once + + diff --git a/buildroot/package/axp2101/src/src/main.cpp b/buildroot/package/axp2101/src/src/main.cpp new file mode 100644 index 000000000..681fcdbb4 --- /dev/null +++ b/buildroot/package/axp2101/src/src/main.cpp @@ -0,0 +1,241 @@ +#include "main.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "XPowersLib.h" + +#define I2C_BUS (4) +#define AXP2101_SLAVE_ADDRESS (0x34) + +int i2c_dev = -1; +XPowersLibInterface *PMU = NULL; + +static int linux_i2c_read_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len); +static int linux_i2c_write_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len); +static void printPMU(); + +static int open_i2c_bus(int bus) +{ + char filename[20]; + snprintf(filename, 19, "/dev/i2c-%d", bus); + int file = open(filename, O_RDWR); + if (file < 0) { + perror("Failed to open the i2c bus"); + } + return file; +} + +static int set_i2c_slave(int file, int addr) +{ + if (ioctl(file, I2C_SLAVE, addr) < 0) { + perror("Failed to acquire bus access and/or talk to slave"); + return -1; + } + return 0; +} + +int main(int argc, char* argv[]) +{ + printf("Init axp2101 pmu\n"); + + i2c_dev = open_i2c_bus(I2C_BUS); + if (i2c_dev < 0) { + printf("open i2c bus error\n"); + return -1; + } else { + printf("open i2c bus success\n"); + } + + if (set_i2c_slave(i2c_dev, AXP2101_SLAVE_ADDRESS) < 0) { + close(i2c_dev); + printf("set i2c slave error\n"); + return 1; + } else { + printf("set i2c slave success\n"); + } + + if (!PMU) { + if (ioctl(i2c_dev, 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"); + } + } + + // DCDC1 --> VDD3V3_SYS + PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300); + PMU->enablePowerOutput(XPOWERS_DCDC1); + + // DCDC2 --> Disable + PMU->disablePowerOutput(XPOWERS_DCDC2); + + // DCDC3 --> VDD0V9_CPU + PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 1000); + PMU->enablePowerOutput(XPOWERS_DCDC3); + + // DCDC4 --> VDD1V35_DRAM + PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 1340); + PMU->enablePowerOutput(XPOWERS_DCDC4); + + // DCDC5 --> DCDC5_FB + PMU->setPowerChannelVoltage(XPOWERS_DCDC5, 1200); + PMU->enablePowerOutput(XPOWERS_DCDC5); + + // ALDO1 --> VDD1V8_SYS + PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 1800); + PMU->enablePowerOutput(XPOWERS_ALDO1); + + // ALDO2 ~ ALDO4 --> Disable + PMU->disablePowerOutput(XPOWERS_ALDO2); + PMU->disablePowerOutput(XPOWERS_ALDO3); + PMU->disablePowerOutput(XPOWERS_ALDO4); + + // BLDO1 ~ BLDO2 --> Disable + PMU->disablePowerOutput(XPOWERS_BLDO1); + PMU->disablePowerOutput(XPOWERS_BLDO2); + + // DLDO1 ~ DLDO2 --> Disable + PMU->disablePowerOutput(XPOWERS_DLDO1); + PMU->disablePowerOutput(XPOWERS_DLDO2); + + // CPUSLDO --> Disable + PMU->disablePowerOutput(XPOWERS_CPULDO); + + // VBACKUP + PMU->setPowerChannelVoltage(XPOWERS_VBACKUP, 3100); + PMU->enablePowerOutput(XPOWERS_VBACKUP); + + printf("=======He================================================================\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_DCDC5)) { + printf("DC5 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC5) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC5)); + } + 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)); + } + if (PMU->isChannelAvailable(XPOWERS_BLDO1)) { + printf("DLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DLDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DLDO1)); + } + if (PMU->isChannelAvailable(XPOWERS_BLDO2)) { + printf("DLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DLDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DLDO2)); + } + if (PMU->isChannelAvailable(XPOWERS_CPULDO)) { + printf("CPUSLDO: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_CPULDO) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_CPULDO)); + } + if (PMU->isChannelAvailable(XPOWERS_VBACKUP)) { + printf("VBACKUP: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_VBACKUP) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_VBACKUP)); + } + printf("=======================================================================\n"); + + PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ); + PMU->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_1000MA); + PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2); + PMU->setSysPowerDownVoltage(2600); + PMU->setVbusCurrentLimit(XPOWERS_AXP2101_VBUS_CUR_LIM_1500MA); + + // Set the time of pressing the button to turn off + PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S); + // Set the button power-on press time + PMU->setPowerKeyPressOnTime(XPOWERS_POWERON_128MS); + PMU->disableTSPinMeasure(); + PMU->enableBattDetection(); + PMU->enableVbusVoltageMeasure(); + PMU->enableBattVoltageMeasure(); + PMU->enableSystemVoltageMeasure(); + + // printPMU(); + + return 0; +} + +static int linux_i2c_read_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len) +{ + if (write(i2c_dev, ®Addr, 1) != 1) { + perror("Failed to write to the i2c device"); + close(i2c_dev); + return -1; + } + + if (read(i2c_dev, data, len) != len) { + perror("Failed to read from the i2c device"); + close(i2c_dev); + return -1; + } + + return 0; +} + +static int linux_i2c_write_callback(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len) +{ + uint8_t buffer[len + 1]; + buffer[0] = regAddr; + for (int i = 0; i < len; i++) { + buffer[i + 1] = data[i]; + } + + if (write(i2c_dev, buffer, len + 1) != len + 1) { + perror("Failed to write to the i2c device"); + close(i2c_dev); + return -1; + } + + return 0; +} + +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"); +} From e26614ad36cd8fbc744c5b72a4d03549c83c4254 Mon Sep 17 00:00:00 2001 From: 916BGAI <916772719@qq.com> Date: Tue, 20 Aug 2024 17:17:25 +0800 Subject: [PATCH 3/3] Optimize cst7xx touch accuracy --- linux_5.10/drivers/input/touchscreen/hyn/hyn_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux_5.10/drivers/input/touchscreen/hyn/hyn_core.c b/linux_5.10/drivers/input/touchscreen/hyn/hyn_core.c index b824f943b..9567d3f1b 100644 --- a/linux_5.10/drivers/input/touchscreen/hyn/hyn_core.c +++ b/linux_5.10/drivers/input/touchscreen/hyn/hyn_core.c @@ -283,7 +283,7 @@ static void touch_updata(u8 idx,u8 event) input_mt_report_slot_state(dev, MT_TOOL_FINGER, 1); input_report_abs(dev, ABS_MT_TRACKING_ID, rep_frame->pos_info[idx].pos_id); input_report_abs(dev, ABS_MT_POSITION_X, rep_frame->pos_info[idx].pos_x); - input_report_abs(dev, ABS_MT_POSITION_Y, rep_frame->pos_info[idx].pos_y); + input_report_abs(dev, ABS_MT_POSITION_Y, rep_frame->pos_info[idx].pos_y+25); input_report_abs(dev, ABS_MT_TOUCH_MAJOR, zpress>>3); input_report_abs(dev, ABS_MT_WIDTH_MAJOR, zpress>>3); input_report_abs(dev, ABS_MT_PRESSURE, zpress);