/** * * @license MIT License * * Copyright (c) 2022 lewis he * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * @file XPowersAXP202.tpp * @author Lewis He (lewishe@outlook.com) * @date 2023-03-28 * */ #if defined(ARDUINO) #include #else #include #endif /*ARDUINO*/ #include "XPowersCommon.tpp" #include "REG/AXP202Constants.h" #include "XPowersLibInterface.hpp" typedef enum { XPOWERS_AXP202_BOOT_TIME_128MS, XPOWERS_AXP202_BOOT_TIME_512MS, XPOWERS_AXP202_BOOT_TIME_1S, XPOWERS_AXP202_BOOT_TIME_2S, } xpowers_axp202_boot_time_t; typedef enum { XPOWERS_AXP202_CHG_ITERM_LESS_10_PERCENT, XPOWERS_AXP202_CHG_ITERM_LESS_15_PERCENT, } xpowers_axp202_chg_iterm_t; typedef enum { XPOWERS_AXP202_PRECHG_TIMEOUT_30MIN, XPOWERS_AXP202_PRECHG_TIMEOUT_40MIN, XPOWERS_AXP202_PRECHG_TIMEOUT_50MIN, XPOWERS_AXP202_PRECHG_TIMEOUT_60MIN, } xpoers_axp202_prechg_to_t; typedef enum { XPOWERS_AXP202_POWEROFF_4S, XPOWERS_AXP202_POWEROFF_65, XPOWERS_AXP202_POWEROFF_8S, XPOWERS_AXP202_POWEROFF_10S, } xpowers_axp202_pekey_poweroff_arg_t; typedef enum { XPOWERS_AXP202_LONGPRESS_1000MS, XPOWERS_AXP202_LONGPRESS_1500MS, XPOWERS_AXP202_LONGPRESS_2000MS, XPOWERS_AXP202_LONGPRESS_2500MS, } xpowers_axp202_pekey_long_press_t; typedef enum { XPOWERS_AXP202_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, public XPowersLibInterface { friend class XPowersCommon; typedef enum { MONITOR_TS_PIN = _BV(0), MONITOR_APS_VOLTAGE = _BV(1), MONITOR_USB_CURRENT = _BV(2), MONITOR_USB_VOLTAGE = _BV(3), MONITOR_AC_CURRENT = _BV(4), MONITOR_AC_VOLTAGE = _BV(5), MONITOR_BAT_CURRENT = _BV(6), MONITOR_BAT_VOLTAGE = _BV(7), MONITOR_ADC_IO3 = _BV(8), MONITOR_ADC_IO2 = _BV(9), MONITOR_ADC_IO1 = _BV(10), MONITOR_ADC_IO0 = _BV(11), MONITOR_TEMPERATURE = _BV(16), } axp202_adc_func_t; public: #if defined(ARDUINO) XPowersAXP202(TwoWire &w, int sda = SDA, int scl = SCL, uint8_t addr = AXP202_SLAVE_ADDRESS) { __wire = &w; __sda = sda; __scl = scl; __addr = addr; } #endif XPowersAXP202(uint8_t addr, iic_fptr_t readRegCallback, iic_fptr_t writeRegCallback) { thisReadRegCallback = readRegCallback; thisWriteRegCallback = writeRegCallback; __addr = addr; } XPowersAXP202() { #if defined(ARDUINO) __wire = &Wire; __sda = SDA; __scl = SCL; #endif __addr = AXP202_SLAVE_ADDRESS; } ~XPowersAXP202() { log_i("~XPowersAXP202"); deinit(); } #if defined(ARDUINO) bool init(TwoWire &w, int sda = SDA, int scl = SCL, uint8_t addr = AXP202_SLAVE_ADDRESS) { __wire = &w; __sda = sda; __scl = scl; __addr = addr; return begin(); } #endif bool init() { return begin(); } void deinit() { end(); } uint16_t status() { return readRegister(XPOWERS_AXP202_STATUS); } bool isAcinVbusStart() { return getRegisterBit(XPOWERS_AXP202_STATUS, 0); } bool isDischarge() { return !getRegisterBit(XPOWERS_AXP202_STATUS, 2); } bool isVbusIn(void) { return getRegisterBit(XPOWERS_AXP202_STATUS, 5); } bool isAcinEfficient() { return getRegisterBit(XPOWERS_AXP202_STATUS, 6); } bool isAcinIn() { return getRegisterBit(XPOWERS_AXP202_STATUS, 7); } bool isOverTemperature() { return getRegisterBit(XPOWERS_AXP202_MODE_CHGSTATUS, 7); } bool isCharging(void) { return getRegisterBit(XPOWERS_AXP202_MODE_CHGSTATUS, 6); } bool isBatteryConnect(void) { return getRegisterBit(XPOWERS_AXP202_MODE_CHGSTATUS, 5); } bool isBattInActiveMode() { return getRegisterBit(XPOWERS_AXP202_MODE_CHGSTATUS, 3); } bool isChargeCurrLessPreset() { return getRegisterBit(XPOWERS_AXP202_MODE_CHGSTATUS, 2); } void enableVbusVoltageLimit() { setRegisterBit(XPOWERS_AXP202_IPS_SET, 6); } void disableVbusVoltageLimit() { clrRegisterBit(XPOWERS_AXP202_IPS_SET, 6); } /** * @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 }; };