2094 lines
62 KiB
C++
2094 lines
62 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 XPowersAXP192.tpp
|
|
* @author Lewis He (lewishe@outlook.com)
|
|
* @date 2022-05-07
|
|
*
|
|
*/
|
|
#if defined(ARDUINO)
|
|
#include <Arduino.h>
|
|
#else
|
|
#include <math.h>
|
|
#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_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<XPowersAXP192>, public XPowersLibInterface
|
|
{
|
|
friend class XPowersCommon<XPowersAXP192>;
|
|
|
|
|
|
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);
|
|
}
|
|
|
|
/**
|
|
* @brief Set VBUS Voltage Input Limit.
|
|
* @param opt: View the related chip type xpowers_axp192_vbus_vol_limit_t enumeration
|
|
* parameters in "XPowersParams.hpp"
|
|
*/
|
|
void setVbusVoltageLimit(uint8_t opt)
|
|
{
|
|
int val = readRegister(XPOWERS_AXP192_IPS_SET);
|
|
if (val == -1)return;
|
|
val &= 0xC7;
|
|
writeRegister(XPOWERS_AXP192_IPS_SET, val | (opt << 3));
|
|
}
|
|
|
|
/**
|
|
* @brief Get VBUS Voltage Input Limit.
|
|
* @retval View the related chip type xpowers_axp192_vbus_vol_limit_t enumeration
|
|
* parameters in "XPowersParams.hpp"
|
|
*/
|
|
uint8_t getVbusVoltageLimit(void)
|
|
{
|
|
return (readRegister(XPOWERS_AXP192_IPS_SET) >> 3 ) & 0x7;
|
|
}
|
|
|
|
/**
|
|
* @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 isEnableBackupCharger()
|
|
{
|
|
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 12-bit ADC
|
|
*/
|
|
float getTemperature(uint16_t * raw_ptr = nullptr)
|
|
{
|
|
uint16_t raw = readRegisterH8L4(XPOWERS_AXP192_INTERNAL_TEMP_H8, XPOWERS_AXP192_INTERNAL_TEMP_L4);
|
|
if (raw == UINT16_MAX || raw > 4095) return NAN;
|
|
if (raw_ptr) *raw_ptr = raw;
|
|
return raw * XPOWERS_AXP192_INTERNAL_TEMP_STEP - XPOWERS_AXP192_INTERNAL_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 isEnableDC2VRC(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 Enable 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 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_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 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_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%llx\n", __func__, enable ? "ENABLE" : "DISABLE", 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];
|
|
};
|
|
|
|
|
|
|