Files
klubhaus-doorbell/libraries/XPowersLib/src/XPowersAXP202.tpp
2026-02-12 00:45:31 -08:00

1736 lines
47 KiB
C++

/**
*
* @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 <Arduino.h>
#else
#include <math.h>
#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_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;
typedef enum {
XPOWERS_AXP202_LDO3_MODE_LDO,
XPOWERS_AXP202_LDO3_MODE_DCIN
} xpowers_axp202_ldo3_mode_t;
class XPowersAXP202 :
public XPowersCommon<XPowersAXP202>, public XPowersLibInterface
{
friend class XPowersCommon<XPowersAXP202>;
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);
}
/**
* @brief Set VBUS Voltage Input Limit.
* @param opt: View the related chip type xpowers_axp202_vbus_vol_limit_t enumeration
* parameters in "XPowersParams.hpp"
*/
void setVbusVoltageLimit(uint8_t opt)
{
int val = readRegister(XPOWERS_AXP202_IPS_SET);
if (val == -1)return;
val &= 0xC7;
writeRegister(XPOWERS_AXP202_IPS_SET, val | (opt << 3));
}
/**
* @brief Get VBUS Voltage Input Limit.
* @retval View the related chip type xpowers_axp202_vbus_vol_limit_t enumeration
* parameters in "XPowersParams.hpp"
*/
uint8_t getVbusVoltageLimit(void)
{
return (readRegister(XPOWERS_AXP202_IPS_SET) >> 3 ) & 0x7;
}
/**
* @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 isEnableBackupCharger()
{
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 12-bit ADC
*/
float getTemperature(uint16_t * raw_ptr = nullptr)
{
uint16_t raw = readRegisterH8L4(XPOWERS_AXP202_INTERNAL_TEMP_H8, XPOWERS_AXP202_INTERNAL_TEMP_L4);
if (raw == UINT16_MAX || raw > 4095) return NAN;
if (raw_ptr) *raw_ptr = raw;
return raw * XPOWERS_AXP202_INTERNAL_TEMP_STEP - XPOWERS_AXP202_INTERNAL_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);
}
//! Only AXP202 support
bool isLDO3LDOMode(void)
{
return getRegisterBit(XPOWERS_AXP202_LDO3OUT_VOL, 7);
}
//! Only AXP202 support
void setLDO3Mode(xpowers_axp202_ldo3_mode_t mode)
{
switch (mode) {
case XPOWERS_AXP202_LDO3_MODE_LDO:
clrRegisterBit(XPOWERS_AXP202_LDO3OUT_VOL, 7);
break;
case XPOWERS_AXP202_LDO3_MODE_DCIN:
setRegisterBit(XPOWERS_AXP202_LDO3OUT_VOL, 7);
break;
default:
break;
}
}
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 isEnableDC2VRC(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 Enable 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 isBatChargeStartIrq(void)
{
return (bool)(statusRegister[1] & _BV(3));
}
bool isBatChargeDoneIrq(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 isEnableBackupCharger();
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%llx\n", __func__, enable ? "ENABLE" : "DISABLE", 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
};
};