1685 lines
65 KiB
Python
1685 lines
65 KiB
Python
'''
|
|
@license MIT License
|
|
|
|
Copyright (c) 2022 lewis he
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
|
|
@file AXP192.py
|
|
@author Lewis He (lewishe@outlook.com)
|
|
@date 2022-10-20
|
|
|
|
'''
|
|
|
|
from I2CInterface import *
|
|
import math
|
|
|
|
_AXP192_CHIP_ID = const(0x03)
|
|
_AXP192_STATUS = const(0x00)
|
|
_AXP192_MODE_CHGSTATUS = const(0x01)
|
|
_AXP192_OTG_STATUS = const(0x02)
|
|
_AXP192_IC_TYPE = const(0x03)
|
|
_AXP192_DATA_BUFFER1 = const(0x06)
|
|
_AXP192_DATA_BUFFER2 = const(0x07)
|
|
_AXP192_DATA_BUFFER3 = const(0x08)
|
|
_AXP192_DATA_BUFFER4 = const(0x09)
|
|
_AXP192_DATA_BUFFER5 = const(0x0A)
|
|
_AXP192_DATA_BUFFER6 = const(0x0B)
|
|
_AXP192_DATA_BUFFER_SIZE = const(6)
|
|
_AXP192_LDO23_DC123_EXT_CTL = const(0x12)
|
|
_AXP192_DC2OUT_VOL = const(0x23)
|
|
_AXP192_DC2_DVM = const(0x25)
|
|
_AXP192_DC3OUT_VOL = const(0x27)
|
|
_AXP192_LDO24OUT_VOL = const(0x28)
|
|
_AXP192_LDO3OUT_VOL = const(0x29)
|
|
_AXP192_IPS_SET = const(0x30)
|
|
_AXP192_VOFF_SET = const(0x31)
|
|
_AXP192_OFF_CTL = const(0x32)
|
|
_AXP192_CHARGE1 = const(0x33)
|
|
_AXP192_CHARGE2 = const(0x34)
|
|
_AXP192_BACKUP_CHG = const(0x35)
|
|
_AXP192_POK_SET = const(0x36)
|
|
_AXP192_DCDC_FREQSET = const(0x37)
|
|
_AXP192_VLTF_CHGSET = const(0x38)
|
|
_AXP192_VHTF_CHGSET = const(0x39)
|
|
_AXP192_APS_WARNING1 = const(0x3A)
|
|
_AXP192_APS_WARNING2 = const(0x3B)
|
|
_AXP192_TLTF_DISCHGSET = const(0x3C)
|
|
_AXP192_THTF_DISCHGSET = const(0x3D)
|
|
_AXP192_DCDC_MODESET = const(0x80)
|
|
_AXP192_ADC_EN1 = const(0x82)
|
|
_AXP192_ADC_EN2 = const(0x83)
|
|
_AXP192_ADC_SPEED = const(0x84)
|
|
_AXP192_ADC_INPUTRANGE = const(0x85)
|
|
_AXP192_ADC_IRQ_RETFSET = const(0x86)
|
|
_AXP192_ADC_IRQ_FETFSET = const(0x87)
|
|
_AXP192_TIMER_CTL = const(0x8A)
|
|
_AXP192_VBUS_DET_SRP = const(0x8B)
|
|
_AXP192_HOTOVER_CTL = const(0x8F)
|
|
_AXP192_PWM1_FREQ_SET = const(0x98)
|
|
_AXP192_PWM1_DUTY_SET1 = const(0x99)
|
|
_AXP192_PWM1_DUTY_SET2 = const(0x9A)
|
|
_AXP192_PWM2_FREQ_SET = const(0x9B)
|
|
_AXP192_PWM2_DUTY_SET1 = const(0x9C)
|
|
_AXP192_PWM2_DUTY_SET2 = const(0x9D)
|
|
# INTERRUPT REGISTER
|
|
_AXP192_INTEN1 = const(0x40)
|
|
_AXP192_INTEN2 = const(0x41)
|
|
_AXP192_INTEN3 = const(0x42)
|
|
_AXP192_INTEN4 = const(0x43)
|
|
_AXP192_INTEN5 = const(0x4A)
|
|
# INTERRUPT STATUS REGISTER
|
|
_AXP192_INTSTS1 = const(0x44)
|
|
_AXP192_INTSTS2 = const(0x45)
|
|
_AXP192_INTSTS3 = const(0x46)
|
|
_AXP192_INTSTS4 = const(0x47)
|
|
_AXP192_INTSTS5 = const(0x4D)
|
|
_AXP192_INTSTS_CNT = const(5)
|
|
_AXP192_DC1_VLOTAGE = const(0x26)
|
|
_AXP192_LDO23OUT_VOL = const(0x28)
|
|
_AXP192_GPIO0_CTL = const(0x90)
|
|
_AXP192_GPIO0_VOL = const(0x91)
|
|
_AXP192_GPIO1_CTL = const(0X92)
|
|
_AXP192_GPIO2_CTL = const(0x93)
|
|
_AXP192_GPIO012_SIGNAL = const(0x94)
|
|
_AXP192_GPIO34_CTL = const(0x95)
|
|
_AXP192_GPIO34_SIGNAL = const(0x96)
|
|
_AXP192_GPIO012_PULLDOWN = const(0x97)
|
|
_AXP192_GPIO5_CTL = const(0x9E)
|
|
_AXP192_GPIO0_VOL_ADC_H8 = const(0x64)
|
|
_AXP192_GPIO0_VOL_ADC_L4 = const(0x65)
|
|
_AXP192_GPIO1_VOL_ADC_H8 = const(0x66)
|
|
_AXP192_GPIO1_VOL_ADC_L4 = const(0x67)
|
|
_AXP192_GPIO2_VOL_ADC_H8 = const(0x68)
|
|
_AXP192_GPIO2_VOL_ADC_L4 = const(0x69)
|
|
_AXP192_GPIO3_VOL_ADC_H8 = const(0x6A)
|
|
_AXP192_GPIO3_VOL_ADC_L4 = const(0x6B)
|
|
_AXP192_GPIO_COUNT = const(5)
|
|
_AXP192_GPIO0_STEP = const(0.5)
|
|
_AXP192_GPIO1_STEP = const(0.5)
|
|
_AXP192_TS_IN_H8 = const(0x62)
|
|
_AXP192_TS_IN_L4 = const(0x63)
|
|
_AXP192_BAT_AVERCHGCUR_H8 = const(0x7A)
|
|
_AXP192_BAT_AVERCHGCUR_L5 = const(0x7B)
|
|
_AXP192_ACIN_VOL_H8 = const(0x56)
|
|
_AXP192_ACIN_VOL_L4 = const(0x57)
|
|
_AXP192_ACIN_CUR_H8 = const(0x58)
|
|
_AXP192_ACIN_CUR_L4 = const(0x59)
|
|
_AXP192_VBUS_VOL_H8 = const(0x5A)
|
|
_AXP192_VBUS_VOL_L4 = const(0x5B)
|
|
_AXP192_VBUS_CUR_H8 = const(0x5C)
|
|
_AXP192_VBUS_CUR_L4 = const(0x5D)
|
|
_AXP192_BAT_AVERDISCHGCUR_H8 = const(0x7C)
|
|
_AXP192_BAT_AVERDISCHGCUR_L5 = const(0x7D)
|
|
_AXP192_APS_AVERVOL_H8 = const(0x7E)
|
|
_AXP192_APS_AVERVOL_L4 = const(0x7F)
|
|
_AXP192_BAT_AVERVOL_H8 = const(0x78)
|
|
_AXP192_BAT_AVERVOL_L4 = const(0x79)
|
|
_AXP192_BAT_CHGCOULOMB3 = const(0xB0)
|
|
_AXP192_BAT_CHGCOULOMB2 = const(0xB1)
|
|
_AXP192_BAT_CHGCOULOMB1 = const(0xB2)
|
|
_AXP192_BAT_CHGCOULOMB0 = const(0xB3)
|
|
_AXP192_BAT_DISCHGCOULOMB3 = const(0xB4)
|
|
_AXP192_BAT_DISCHGCOULOMB2 = const(0xB5)
|
|
_AXP192_BAT_DISCHGCOULOMB1 = const(0xB6)
|
|
_AXP192_BAT_DISCHGCOULOMB0 = const(0xB7)
|
|
_AXP192_COULOMB_CTL = const(0xB8)
|
|
_AXP192_BATT_VOLTAGE_STEP = const(1.1)
|
|
_AXP192_BATT_DISCHARGE_CUR_STEP = const(0.5)
|
|
_AXP192_BATT_CHARGE_CUR_STEP = const(0.5)
|
|
_AXP192_ACIN_VOLTAGE_STEP = const(1.7)
|
|
_AXP192_ACIN_CUR_STEP = const(0.625)
|
|
_AXP192_VBUS_VOLTAGE_STEP = const(1.7)
|
|
_AXP192_VBUS_CUR_STEP = const(0.375)
|
|
_AXP192_APS_VOLTAGE_STEP = const(1.4)
|
|
_AXP192_TS_PIN_OUT_STEP = const(0.8)
|
|
_AXP192_LDO2_VOL_MIN = const(1800)
|
|
_AXP192_LDO2_VOL_MAX = const(3300)
|
|
_AXP192_LDO2_VOL_STEPS = const(100)
|
|
_AXP192_LDO2_VOL_BIT_MASK = const(4)
|
|
_AXP192_LDO3_VOL_MIN = const(1800)
|
|
_AXP192_LDO3_VOL_MAX = const(3300)
|
|
_AXP192_LDO3_VOL_STEPS = const(100)
|
|
_AXP192_DC1_VOL_STEPS = const(25)
|
|
_AXP192_DC1_VOL_MIN = const(700)
|
|
_AXP192_DC1_VOL_MAX = const(3500)
|
|
_AXP192_DC2_VOL_STEPS = const(25)
|
|
_AXP192_DC2_VOL_MIN = const(700)
|
|
_AXP192_DC2_VOL_MAX = const(3500)
|
|
_AXP192_DC3_VOL_STEPS = const(25)
|
|
_AXP192_DC3_VOL_MIN = const(700)
|
|
_AXP192_DC3_VOL_MAX = const(3500)
|
|
_AXP192_LDOIO_VOL_STEPS = const(100)
|
|
_AXP192_LDOIO_VOL_MIN = const(1800)
|
|
_AXP192_LDOIO_VOL_MAX = const(3300)
|
|
_AXP192_SYS_VOL_STEPS = const(100)
|
|
_AXP192_VOFF_VOL_MIN = const(2600)
|
|
_AXP192_VOFF_VOL_MAX = const(3300)
|
|
_AXP192_CHG_EXT_CURR_MIN = const(300)
|
|
_AXP192_CHG_EXT_CURR_MAX = const(1000)
|
|
_AXP192_CHG_EXT_CURR_STEP = const(100)
|
|
_AXP192_INTERNAL_TEMP_H8 = const(0x5E)
|
|
_AXP192_INTERNAL_TEMP_L4 = const(0x5)
|
|
_AXP192_INTERNAL_TEMP_STEP = const(0.1)
|
|
_AXP192_INERNAL_TEMP_OFFSET = const(144.7)
|
|
|
|
_MONITOR_TS_PIN = const(1 << 0)
|
|
_MONITOR_APS_VOLTAGE = const(1 << 1)
|
|
_MONITOR_USB_CURRENT = const(1 << 2)
|
|
_MONITOR_USB_VOLTAGE = const(1 << 3)
|
|
_MONITOR_AC_CURRENT = const(1 << 4)
|
|
_MONITOR_AC_VOLTAGE = const(1 << 5)
|
|
_MONITOR_BAT_CURRENT = const(1 << 6)
|
|
_MONITOR_BAT_VOLTAGE = const(1 << 7)
|
|
_MONITOR_ADC_IO3 = const(1 << 8)
|
|
_MONITOR_ADC_IO2 = const(1 << 9)
|
|
_MONITOR_ADC_IO1 = const(1 << 10)
|
|
_MONITOR_ADC_IO0 = const(1 << 11)
|
|
_MONITOR_TEMPERATURE = const(1 << 16)
|
|
|
|
AXP192_SLAVE_ADDRESS = const(0x34)
|
|
|
|
|
|
class PMU_Gpio:
|
|
def __init__(self) -> None:
|
|
self.mode = 0
|
|
self.val = 0
|
|
|
|
|
|
class AXP192(I2CInterface):
|
|
|
|
# ARGS ARGS ARGS ARGS ARGS ARGS ARGS ARGS ARGS
|
|
"""VBUS voltage limit values"""
|
|
XPOWERS_AXP192_VBUS_VOL_LIM_4V = const(0)
|
|
XPOWERS_AXP192_VBUS_VOL_LIM_4V1 = const(1)
|
|
XPOWERS_AXP192_VBUS_VOL_LIM_4V2 = const(2)
|
|
XPOWERS_AXP192_VBUS_VOL_LIM_4V3 = const(3)
|
|
XPOWERS_AXP192_VBUS_VOL_LIM_4V4 = const(4)
|
|
XPOWERS_AXP192_VBUS_VOL_LIM_4V5 = const(5)
|
|
XPOWERS_AXP192_VBUS_VOL_LIM_4V6 = const(6)
|
|
XPOWERS_AXP192_VBUS_VOL_LIM_4V7 = const(7)
|
|
|
|
"""Power button press shutdown time values"""
|
|
XPOWERS_POWEROFF_4S = const(0)
|
|
XPOWERS_POWEROFF_6S = const(1)
|
|
XPOWERS_POWEROFF_8S = const(2)
|
|
XPOWERS_POWEROFF_10S = const(3)
|
|
|
|
"""Power on time value when the power button is pressed"""
|
|
XPOWERS_POWERON_128MS = const(0)
|
|
XPOWERS_POWERON_512MS = const(1)
|
|
XPOWERS_POWERON_1S = const(2)
|
|
XPOWERS_POWERON_2S = const(3)
|
|
|
|
XPOWERS_AXP192_CHG_ITERM_LESS_10_PERCENT = const(0)
|
|
XPOWERS_AXP192_CHG_ITERM_LESS_15_PERCENT = const(1)
|
|
|
|
"""Precharge timeout limit values"""
|
|
XPOWERS_AXP192_PRECHG_TIMEOUT_30MIN = const(0)
|
|
XPOWERS_AXP192_PRECHG_TIMEOUT_40MIN = const(1)
|
|
XPOWERS_AXP192_PRECHG_TIMEOUT_50MIN = const(2)
|
|
XPOWERS_AXP192_PRECHG_TIMEOUT_60MIN = const(3)
|
|
|
|
"""PowerKey longpress timeout values"""
|
|
XPOWERS_AXP192_LONGPRESS_1000MS = const(0)
|
|
XPOWERS_AXP192_LONGPRESS_1500MS = const(1)
|
|
XPOWERS_AXP192_LONGPRESS_2000MS = const(2)
|
|
XPOWERS_AXP192_LONGPRESS_2500MS = const(3)
|
|
|
|
"""PMU LED indicator function values"""
|
|
XPOWERS_CHG_LED_OFF = const(0)
|
|
XPOWERS_CHG_LED_BLINK_1HZ = const(1)
|
|
XPOWERS_CHG_LED_BLINK_4HZ = const(2)
|
|
XPOWERS_CHG_LED_ON = const(3)
|
|
XPOWERS_CHG_LED_CTRL_CHG = const(4)
|
|
|
|
XPOWERS_AXP192_CHG_CONS_TIMEOUT_7H = const(0)
|
|
XPOWERS_AXP192_CHG_CONS_TIMEOUT_8H = const(1)
|
|
XPOWERS_AXP192_CHG_CONS_TIMEOUT_9H = const(2)
|
|
XPOWERS_AXP192_CHG_CONS_TIMEOUT_10H = const(3)
|
|
|
|
"""PMU backup battery voltage values"""
|
|
XPOWERS_AXP192_BACKUP_BAT_VOL_3V1 = const(0)
|
|
XPOWERS_AXP192_BACKUP_BAT_VOL_3V = const(1)
|
|
# !NEED FIXDATASHEET ERROR!
|
|
XPOWERS_AXP192_BACKUP_BAT_VOL_3V0 = const(2)
|
|
XPOWERS_AXP192_BACKUP_BAT_VOL_2V5 = const(3)
|
|
|
|
"""PMU backup battery current values"""
|
|
XPOWERS_AXP192_BACKUP_BAT_CUR_50UA = const(0)
|
|
XPOWERS_AXP192_BACKUP_BAT_CUR_100UA = const(1)
|
|
XPOWERS_AXP192_BACKUP_BAT_CUR_200UA = const(2)
|
|
XPOWERS_AXP192_BACKUP_BAT_CUR_400UA = const(3)
|
|
|
|
"""PMU gpio values"""
|
|
PMU_GPIO0 = const(0)
|
|
PMU_GPIO1 = const(1)
|
|
PMU_GPIO2 = const(2)
|
|
PMU_GPIO3 = const(3)
|
|
PMU_GPIO4 = const(4)
|
|
PMU_GPIO5 = const(5)
|
|
PMU_TS_PIN = const(6)
|
|
|
|
"""Charging voltage limit values"""
|
|
XPOWERS_AXP192_CHG_VOL_4V1 = const(0)
|
|
XPOWERS_AXP192_CHG_VOL_4V15 = const(1)
|
|
XPOWERS_AXP192_CHG_VOL_4V2 = const(2)
|
|
XPOWERS_AXP192_CHG_VOL_4V36 = const(3)
|
|
|
|
"""Charging current limit values"""
|
|
XPOWERS_AXP192_CHG_CUR_100MA = const(0)
|
|
XPOWERS_AXP192_CHG_CUR_190MA = const(1)
|
|
XPOWERS_AXP192_CHG_CUR_280MA = const(2)
|
|
XPOWERS_AXP192_CHG_CUR_360MA = const(3)
|
|
XPOWERS_AXP192_CHG_CUR_450MA = const(4)
|
|
XPOWERS_AXP192_CHG_CUR_550MA = const(5)
|
|
XPOWERS_AXP192_CHG_CUR_630MA = const(6)
|
|
XPOWERS_AXP192_CHG_CUR_700MA = const(7)
|
|
XPOWERS_AXP192_CHG_CUR_780MA = const(8)
|
|
XPOWERS_AXP192_CHG_CUR_880MA = const(9)
|
|
XPOWERS_AXP192_CHG_CUR_960MA = const(10)
|
|
XPOWERS_AXP192_CHG_CUR_1000MA = const(11)
|
|
XPOWERS_AXP192_CHG_CUR_1080MA = const(12)
|
|
XPOWERS_AXP192_CHG_CUR_1160MA = const(13)
|
|
XPOWERS_AXP192_CHG_CUR_1240MA = const(14)
|
|
XPOWERS_AXP192_CHG_CUR_1320MA = const(15)
|
|
|
|
"""VBUS current limit values"""
|
|
XPOWERS_AXP192_VBUS_CUR_LIM_500MA = const(0)
|
|
XPOWERS_AXP192_VBUS_CUR_LIM_100MA = const(1)
|
|
XPOWERS_AXP192_VBUS_CUR_LIM_OFF = const(2)
|
|
|
|
"""PMU interrupt control mask values"""
|
|
#! IRQ1 REG 40H
|
|
# VBUS is available, but lower than V HOLD, IRQ enable
|
|
XPOWERS_AXP192_VBUS_VHOLD_LOW_IRQ = const(1 << 1)
|
|
# VBUS removed, IRQ enable
|
|
XPOWERS_AXP192_VBUS_REMOVE_IRQ = const(1 << 2)
|
|
# VBUS connected, IRQ enable
|
|
XPOWERS_AXP192_VBUS_INSERT_IRQ = const(1 << 3)
|
|
# VBUS over-voltage, IRQ enable
|
|
XPOWERS_AXP192_VBUS_OVER_VOL_IRQ = const(1 << 4)
|
|
# ACIN removed, IRQ enable
|
|
XPOWERS_AXP192_ACIN_REMOVED_IRQ = const(1 << 5)
|
|
# ACIN connected, IRQ enable
|
|
XPOWERS_AXP192_ACIN_CONNECT_IRQ = const(1 << 6)
|
|
# ACIN over-voltage, IRQ enable
|
|
XPOWERS_AXP192_ACIN_OVER_VOL_IRQ = const(1 << 7)
|
|
#! IRQ2 REG 41H
|
|
# Battery low-temperature, IRQ enable
|
|
XPOWERS_AXP192_BATT_LOW_TEMP_IRQ = const(1 << 8)
|
|
# Battery over-temperature, IRQ enable
|
|
XPOWERS_AXP192_BATT_OVER_TEMP_IRQ = const(1 << 9)
|
|
# Charge finished, IRQ enable
|
|
XPOWERS_AXP192_BAT_CHG_DONE_IRQ = const(1 << 10)
|
|
# Be charging, IRQ enable
|
|
XPOWERS_AXP192_BAT_CHG_START_IRQ = const(1 << 11)
|
|
# Exit battery activate mode, IRQ enable
|
|
XPOWERS_AXP192_BATT_EXIT_ACTIVATE_IRQ = const(1 << 12)
|
|
# Battery activate mode, IRQ enable
|
|
XPOWERS_AXP192_BATT_ACTIVATE_IRQ = const(1 << 13)
|
|
# Battery removed, IRQ enable
|
|
XPOWERS_AXP192_BAT_REMOVE_IRQ = const(1 << 14)
|
|
# Battery connected, IRQ enable
|
|
XPOWERS_AXP192_BAT_INSERT_IRQ = const(1 << 15)
|
|
#! IRQ3 REG 42H
|
|
# PEK long press, IRQ enable
|
|
XPOWERS_AXP192_PKEY_LONG_IRQ = const(1 << 16)
|
|
# PEK short press, IRQ enable
|
|
XPOWERS_AXP192_PKEY_SHORT_IRQ = const(1 << 17)
|
|
# **Reserved and unchangeable BIT 2
|
|
# DC-DC3output voltage is lower than the set value, IRQ enable
|
|
XPOWERS_AXP192_DC3_LOW_VOL_IRQ = const(1 << 19)
|
|
# DC-DC2 output voltage is lower than the set value, IRQ enable
|
|
XPOWERS_AXP192_DC2_LOW_VOL_IRQ = const(1 << 20)
|
|
# DC-DC1 output voltage is lower than the set value, IRQ enable
|
|
XPOWERS_AXP192_DC1_LOW_VOL_IRQ = const(1 << 21)
|
|
# Charge current is lower than the set current, IRQ enable
|
|
XPOWERS_AXP192_CHARGE_LOW_CUR_IRQ = const(1 << 22)
|
|
# XPOWERS internal over-temperature, IRQ enable
|
|
XPOWERS_AXP192_CHIP_TEMP_HIGH_IRQ = const(1 << 23)
|
|
#! IRQ4 REG 43H
|
|
# APS low-voltage, IRQ enable
|
|
XPOWERS_AXP192_APS_LOW_VOL_LEVEL_IRQ = const(1 << 24)
|
|
# **Reserved and unchangeable BIT 1
|
|
# VBUS Session End IRQ enable
|
|
XPOWERS_AXP192_VBUS_SESSION_END_IRQ = const(1 << 26)
|
|
# VBUS Session A/B IRQ enable
|
|
XPOWERS_AXP192_VBUS_SESSION_AB_IRQ = const(1 << 27)
|
|
# VBUS invalid, IRQ enable
|
|
XPOWERS_AXP192_VBUS_INVALID_IRQ = const(1 << 28)
|
|
# VBUS valid, IRQ enable
|
|
XPOWERS_AXP192_VBUS_VAILD_IRQ = const(1 << 29)
|
|
# N_OE shutdown, IRQ enable
|
|
XPOWERS_AXP192_NOE_OFF_IRQ = const(1 << 30)
|
|
# N_OE startup, IRQ enable
|
|
XPOWERS_AXP192_NOE_ON_IRQ = const(1 << 31)
|
|
#! IRQ5 REG 4AH
|
|
# GPIO0 input edge trigger, IRQ enable
|
|
XPOWERS_AXP192_GPIO0_EDGE_TRIGGER_IRQ = const(1 << 32)
|
|
# GPIO1input edge trigger or ADC input, IRQ enable
|
|
XPOWERS_AXP192_GPIO1_EDGE_TRIGGER_IRQ = const(1 << 33)
|
|
# GPIO2input edge trigger, IRQ enable
|
|
XPOWERS_AXP192_GPIO2_EDGE_TRIGGER_IRQ = const(1 << 34)
|
|
# **Reserved and unchangeable BIT 3
|
|
# **Reserved and unchangeable BIT 4
|
|
# **Reserved and unchangeable BIT 5
|
|
# **Reserved and unchangeable BIT 6
|
|
# Timer timeout, IRQ enable
|
|
XPOWERS_AXP192_TIMER_TIMEOUT_IRQ = const(1 << 39)
|
|
XPOWERS_AXP192_ALL_IRQ = const(0xFFFFFFFFFF)
|
|
|
|
LOW = const(0x0)
|
|
HIGH = const(0x1)
|
|
|
|
# GPIO FUNCTIONS
|
|
INPUT = const(0x01)
|
|
OUTPUT = const(0x03)
|
|
PULLUP = const(0x04)
|
|
INPUT_PULLUP = const(0x05)
|
|
PULLDOWN = const(0x08)
|
|
INPUT_PULLDOWN = const(0x09)
|
|
ANALOG = const(0x10)
|
|
|
|
# INT
|
|
RISING = const(0x01)
|
|
FALLING = const(0x02)
|
|
|
|
def __init__(self, i2c_bus: I2C, addr: int = AXP192_SLAVE_ADDRESS) -> None:
|
|
super().__init__(i2c_bus, addr)
|
|
print('AXP192 __init__')
|
|
|
|
if self.getChipID() != _AXP192_CHIP_ID:
|
|
raise RuntimeError(
|
|
"Failed to find %s - check your wiring!" % self.__class__.__name__
|
|
)
|
|
|
|
self.statusRegister = [0] * _AXP192_INTSTS_CNT
|
|
|
|
self.intRegister = [0] * _AXP192_INTSTS_CNT
|
|
self.gpio = [PMU_Gpio(), PMU_Gpio(), PMU_Gpio(),
|
|
PMU_Gpio(), PMU_Gpio(), PMU_Gpio()]
|
|
|
|
def isAcinVbusStart(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_STATUS, 0))
|
|
|
|
def isDischarge(self) -> bool:
|
|
return not bool(super().getRegisterBit(_AXP192_STATUS, 2))
|
|
|
|
def isVbusIn(void) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_STATUS, 5))
|
|
|
|
def isAcinEfficient(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_STATUS, 6))
|
|
|
|
def isAcinIn(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_STATUS, 7))
|
|
|
|
def isOverTemperature(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_MODE_CHGSTATUS, 7))
|
|
|
|
def isCharging(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_MODE_CHGSTATUS, 6))
|
|
|
|
def isBatteryConnect(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_MODE_CHGSTATUS, 5))
|
|
|
|
def isBattInActiveMode(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_MODE_CHGSTATUS, 3))
|
|
|
|
def isChargeCurrLessPreset(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_MODE_CHGSTATUS, 2))
|
|
|
|
def enableVbusVoltageLimit(self) -> None:
|
|
super().setRegisterBit(_AXP192_IPS_SET, 6)
|
|
|
|
def disableVbusVoltageLimit(self) -> None:
|
|
super().clrRegisterBit(_AXP192_IPS_SET, 6)
|
|
|
|
def setVbusVoltageLimit(self, opt: int) -> None:
|
|
val = super().readRegister(_AXP192_IPS_SET)[0]
|
|
val &= 0xC7
|
|
super().writeRegister(_AXP192_IPS_SET, val | (opt << 3))
|
|
|
|
# @brief Set VBUS Current Input Limit.
|
|
# @param opt: View the related chip type _AXP192_vbus_cur_limit_t enumeration
|
|
# parameters in "XPowersParams.hpp"
|
|
|
|
def setVbusCurrentLimit(self, opt: int) -> None:
|
|
if opt == self.XPOWERS_AXP192_VBUS_CUR_LIM_500MA:
|
|
super().setRegisterBit(_AXP192_IPS_SET, 1)
|
|
super().clrRegisterBit(_AXP192_IPS_SET, 0)
|
|
elif opt == self.XPOWERS_AXP192_VBUS_CUR_LIM_100MA:
|
|
super().setRegisterBit(_AXP192_IPS_SET, 1)
|
|
super().setRegisterBit(_AXP192_IPS_SET, 0)
|
|
elif opt == self.XPOWERS_AXP192_VBUS_CUR_LIM_OFF:
|
|
super().clrRegisterBit(_AXP192_IPS_SET, 1)
|
|
|
|
# @brief Get VBUS Current Input Limit.
|
|
# @retval View the related chip type _AXP192_vbus_cur_limit_t enumeration
|
|
# parameters in "XPowersParams.hpp"
|
|
def getVbusCurrentLimit(self) -> int:
|
|
if super().getRegisterBit(_AXP192_IPS_SET, 1) == 0:
|
|
return self.XPOWERS_AXP192_VBUS_CUR_LIM_OFF
|
|
if super().getRegisterBit(_AXP192_IPS_SET, 0):
|
|
return self.XPOWERS_AXP192_VBUS_CUR_LIM_100MA
|
|
return self.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
|
|
def setSysPowerDownVoltage(self, millivolt: int) -> bool:
|
|
if millivolt % _AXP192_SYS_VOL_STEPS:
|
|
raise ValueError("Mistake ! The steps is must %u mV" %
|
|
_AXP192_SYS_VOL_STEPS)
|
|
if millivolt < _AXP192_VOFF_VOL_MIN:
|
|
raise ValueError("Mistake ! SYS minimum output voltage is %umV" %
|
|
_AXP192_VOFF_VOL_MIN)
|
|
elif millivolt > _AXP192_VOFF_VOL_MAX:
|
|
raise ValueError("Mistake ! SYS maximum output voltage is %umV" %
|
|
_AXP192_VOFF_VOL_MAX)
|
|
val = super().readRegister(_AXP192_VOFF_SET)[0]
|
|
val &= 0xF8
|
|
val |= (int)((millivolt - _AXP192_VOFF_VOL_MIN) /
|
|
_AXP192_SYS_VOL_STEPS)
|
|
super().writeRegister(_AXP192_VOFF_SET, val)
|
|
|
|
def getSysPowerDownVoltage(self) -> int:
|
|
val = super().readRegister(_AXP192_VOFF_SET)[0]
|
|
val &= 0x07
|
|
return (val * _AXP192_SYS_VOL_STEPS) + _AXP192_VOFF_VOL_MIN
|
|
|
|
# @brief Set shutdown, calling shutdown will turn off all power channels,
|
|
# only VRTC belongs to normal power supply
|
|
def shutdown(self) -> None:
|
|
super().setRegisterBit(_AXP192_OFF_CTL, 7)
|
|
|
|
# Charge setting
|
|
def enableCharge(self) -> None:
|
|
super().setRegisterBit(_AXP192_CHARGE1, 7)
|
|
|
|
def disableCharge(self) -> None:
|
|
super().clrRegisterBit(_AXP192_CHARGE1, 7)
|
|
|
|
# @brief Set charge target voltage.
|
|
# @param opt: See _AXP192_chg_vol_t enum for details.
|
|
def setChargeTargetVoltage(self, opt: int) -> None:
|
|
if not 0 <= opt <= 3:
|
|
raise ValueError(
|
|
"Charger target voltage must be a value within 0-3!")
|
|
val = super().readRegister(_AXP192_CHARGE1)[0]
|
|
val &= 0x9F
|
|
super().writeRegister(_AXP192_CHARGE1, val | (opt << 5))
|
|
|
|
# @brief Get charge target voltage settings.
|
|
# @retval See _AXP192_chg_vol_t enum for details.
|
|
def getChargeTargetVoltage(self) -> int:
|
|
val = super().readRegister(_AXP192_CHARGE1)[0]
|
|
return (val & 0x60) >> 5
|
|
|
|
# @brief Set charge current settings.
|
|
# @retval See _AXP192_chg_curr_t enum for details.
|
|
|
|
def setChargerConstantCurr(self, opt: int) -> bool:
|
|
if not 0 <= opt <= 15:
|
|
raise ValueError(
|
|
"Charger current must be a value within 0-15!")
|
|
val = super().readRegister(_AXP192_CHARGE1)[0]
|
|
val &= 0xF0
|
|
super().writeRegister(_AXP192_CHARGE1, val | opt)
|
|
|
|
# @brief Get charge current settings.
|
|
# @retval See _AXP192_chg_curr_t enum for details.
|
|
def getChargerConstantCurr(self) -> int:
|
|
val = super().readRegister(_AXP192_CHARGE1)[0] & 0x0F
|
|
return val
|
|
|
|
def setChargerTerminationCurr(self, opt: int) -> None:
|
|
if opt == self.XPOWERS_AXP192_CHG_ITERM_LESS_10_PERCENT:
|
|
super().clrRegisterBit(_AXP192_CHARGE1, 0)
|
|
elif opt == self.XPOWERS_AXP192_CHG_ITERM_LESS_15_PERCENT:
|
|
super().setRegisterBit(_AXP192_CHARGE1, 0)
|
|
|
|
def getChargerTerminationCurr(self) -> int:
|
|
return super().getRegisterBit(_AXP192_CHARGE1, 4)
|
|
|
|
def setPrechargeTimeout(self, opt: int):
|
|
val = super().readRegister(_AXP192_CHARGE2)[0]
|
|
val &= 0x3F
|
|
super().writeRegister(_AXP192_CHARGE2, val | (opt << 6))
|
|
|
|
# External channel charge current setting,Range:300~1000mA
|
|
def setChargerExternChannelCurr(self, milliampere: int) -> None:
|
|
if milliampere % _AXP192_CHG_EXT_CURR_STEP:
|
|
raise ValueError("Mistake ! The steps is must %u mV" %
|
|
_AXP192_CHG_EXT_CURR_STEP)
|
|
if milliampere < _AXP192_CHG_EXT_CURR_MIN:
|
|
raise ValueError("Mistake ! The minimum external path charge current setting is: %umA" %
|
|
_AXP192_CHG_EXT_CURR_MIN)
|
|
elif milliampere > _AXP192_CHG_EXT_CURR_MAX:
|
|
raise ValueError("Mistake ! The maximum external channel charge current setting is: %umA" %
|
|
_AXP192_CHG_EXT_CURR_MAX)
|
|
val = super().readRegister(_AXP192_CHARGE2)[0]
|
|
val &= 0xC7
|
|
val |= (int)((milliampere - _AXP192_CHG_EXT_CURR_MIN) /
|
|
_AXP192_CHG_EXT_CURR_STEP)
|
|
super().writeRegister(_AXP192_CHARGE2, val)
|
|
|
|
def enableChargerExternChannel(self) -> None:
|
|
super().setRegisterBit(_AXP192_CHARGE2, 2)
|
|
|
|
def disableChargerExternChannel(self) -> None:
|
|
super().clrRegisterBit(_AXP192_CHARGE2, 2)
|
|
|
|
# Timeout setting in constant current mode
|
|
def setChargerConstantTimeout(self, opt: int) -> None:
|
|
val = super().readRegister(_AXP192_CHARGE2)[0]
|
|
val &= 0xFC
|
|
super().writeRegister(_AXP192_CHARGE2, val | opt)
|
|
|
|
def enableBackupBattCharger(self) -> None:
|
|
super().setRegisterBit(_AXP192_BACKUP_CHG, 7)
|
|
|
|
def disableBackupBattCharger(self) -> None:
|
|
super().clrRegisterBit(_AXP192_BACKUP_CHG, 7)
|
|
|
|
def isEnableBackupCharger(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_BACKUP_CHG, 7))
|
|
|
|
def setBackupBattChargerVoltage(self, opt: int) -> int:
|
|
val = super().readRegister(_AXP192_BACKUP_CHG)[0]
|
|
val &= 0x9F
|
|
super().writeRegister(_AXP192_BACKUP_CHG, val | (opt << 5))
|
|
|
|
def setBackupBattChargerCurr(self, opt: int):
|
|
val = super().readRegister(_AXP192_BACKUP_CHG)[0]
|
|
val &= 0xFC
|
|
super().writeRegister(_AXP192_BACKUP_CHG, val | opt)
|
|
|
|
# Temperature
|
|
def getTemperature(self) -> float:
|
|
return super().readRegisterH8L4(_AXP192_INTERNAL_TEMP_H8, _AXP192_INTERNAL_TEMP_L4) * _AXP192_INTERNAL_TEMP_STEP - _AXP192_INERNAL_TEMP_OFFSET
|
|
|
|
def enableTemperatureMeasure(self) -> None:
|
|
super().setRegisterBit(_AXP192_ADC_EN2, 7)
|
|
|
|
def disableTemperatureMeasure(self) -> None:
|
|
super().clrRegisterBit(_AXP192_ADC_EN2, 7)
|
|
|
|
# Power control LDOio functions
|
|
def isEnableLDOio(self) -> bool:
|
|
return bool(super().readRegister(_AXP192_GPIO0_CTL)[0] & 0x02)
|
|
|
|
def enableLDOio(self) -> None:
|
|
val = super().readRegister(_AXP192_GPIO0_CTL)[0] & 0xF8
|
|
super().writeRegister(_AXP192_GPIO0_CTL, val | 0x02)
|
|
|
|
def disableLDOio(self) -> None:
|
|
val = super().readRegister(_AXP192_GPIO0_CTL)[0] & 0xF8
|
|
super().writeRegister(_AXP192_GPIO0_CTL, val)
|
|
|
|
def setLDOioVoltage(self, millivolt: int) -> None:
|
|
if millivolt % _AXP192_LDOIO_VOL_STEPS:
|
|
raise ValueError("Mistake ! The steps is must %u mV" %
|
|
_AXP192_LDOIO_VOL_STEPS)
|
|
if millivolt < _AXP192_LDOIO_VOL_MIN:
|
|
raise ValueError("Mistake ! LDOIO minimum output voltage is %umV" %
|
|
_AXP192_LDOIO_VOL_MIN)
|
|
elif millivolt > _AXP192_LDOIO_VOL_MAX:
|
|
raise ValueError("Mistake ! LDOIO maximum output voltage is %umV" %
|
|
_AXP192_LDOIO_VOL_MAX)
|
|
val = super().readRegister(_AXP192_GPIO0_VOL)[0]
|
|
val |= ((int)((millivolt - _AXP192_LDOIO_VOL_MIN) /
|
|
_AXP192_LDOIO_VOL_STEPS) << 4)
|
|
super().writeRegister(_AXP192_GPIO0_VOL, val)
|
|
|
|
def getLDOioVoltage(self) -> int:
|
|
val = super().readRegister(_AXP192_GPIO0_VOL)[0]
|
|
val >>= 4
|
|
val *= _AXP192_LDOIO_VOL_STEPS
|
|
val += _AXP192_LDOIO_VOL_MIN
|
|
return val
|
|
|
|
# Power control LDO2 functions
|
|
def isEnableLDO2(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 2))
|
|
|
|
def enableLDO2(self) -> None:
|
|
super().setRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 2)
|
|
|
|
def disableLDO2(self) -> None:
|
|
super().clrRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 2)
|
|
|
|
def setLDO2Voltage(self, millivolt: int) -> None:
|
|
if millivolt % _AXP192_LDO2_VOL_STEPS:
|
|
raise ValueError("Mistake ! The steps is must %u mV" %
|
|
_AXP192_LDO2_VOL_STEPS)
|
|
if millivolt < _AXP192_LDO2_VOL_MIN:
|
|
raise ValueError("Mistake ! LDO2 minimum output voltage is %umV" %
|
|
_AXP192_LDO2_VOL_MIN)
|
|
elif millivolt > _AXP192_LDO2_VOL_MAX:
|
|
raise ValueError("Mistake ! LDO2 maximum output voltage is %umV" %
|
|
_AXP192_LDO2_VOL_MAX)
|
|
val = super().readRegister(_AXP192_LDO23OUT_VOL)[0]
|
|
val &= 0x0F
|
|
super().writeRegister(_AXP192_LDO23OUT_VOL, val | ((int)((millivolt -
|
|
_AXP192_LDO2_VOL_MIN) / _AXP192_LDO2_VOL_STEPS) << _AXP192_LDO2_VOL_BIT_MASK))
|
|
|
|
def getLDO2Voltage(self) -> int:
|
|
val = super().readRegister(_AXP192_LDO23OUT_VOL)[0] & 0xF0
|
|
return (val >> _AXP192_LDO2_VOL_BIT_MASK) * _AXP192_LDO2_VOL_STEPS + _AXP192_LDO2_VOL_MIN
|
|
|
|
# Power control LDO3 functions
|
|
|
|
def isEnableLDO3(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 3))
|
|
|
|
def enableLDO3(self) -> None:
|
|
super().setRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 3)
|
|
|
|
def disableLDO3(self) -> None:
|
|
super().clrRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 3)
|
|
|
|
def setLDO3Voltage(self, millivolt: int) -> None:
|
|
if millivolt % _AXP192_LDO3_VOL_STEPS:
|
|
raise ValueError("Mistake ! The steps is must %u mV" %
|
|
_AXP192_LDO3_VOL_STEPS)
|
|
if millivolt < _AXP192_LDO3_VOL_MIN:
|
|
raise ValueError("Mistake ! LDO3 minimum output voltage is %umV" %
|
|
_AXP192_LDO3_VOL_MIN)
|
|
elif millivolt > _AXP192_LDO3_VOL_MAX:
|
|
raise ValueError("Mistake ! LDO3 maximum output voltage is %umV" %
|
|
_AXP192_LDO3_VOL_MAX)
|
|
val = super().readRegister(_AXP192_LDO23OUT_VOL)[0] & 0xF0
|
|
super().writeRegister(_AXP192_LDO23OUT_VOL, val | (int)(
|
|
(millivolt - _AXP192_LDO3_VOL_MIN) / _AXP192_LDO3_VOL_STEPS))
|
|
|
|
def getLDO3Voltage(self) -> int:
|
|
val = super().readRegister(_AXP192_LDO23OUT_VOL)[0]
|
|
val &= 0x0F
|
|
return (val * _AXP192_LDO3_VOL_STEPS) + _AXP192_LDO3_VOL_MIN
|
|
|
|
# Power control DCDC1 functions
|
|
def setDC1PwmMode(self) -> None:
|
|
val = super().readRegister(_AXP192_DCDC_MODESET)[0] & 0xF7
|
|
super().writeRegister(_AXP192_DCDC_MODESET, val | 0x08)
|
|
|
|
def setDC1AutoMode(self) -> None:
|
|
val = super().readRegister(_AXP192_DCDC_MODESET)[0] & 0xF7
|
|
super().writeRegister(_AXP192_DCDC_MODESET, val)
|
|
|
|
def isEnableDC1(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 0))
|
|
|
|
def enableDC1(self) -> None:
|
|
super().setRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 0)
|
|
|
|
def disableDC1(self) -> None:
|
|
super().clrRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 0)
|
|
|
|
def setDC1Voltage(self, millivolt) -> None:
|
|
if millivolt % _AXP192_DC1_VOL_STEPS:
|
|
raise ValueError("Mistake ! The steps is must %u mV" %
|
|
_AXP192_DC1_VOL_STEPS)
|
|
if millivolt < _AXP192_DC1_VOL_STEPS:
|
|
raise ValueError("Mistake ! DCDC1 minimum output voltage is %umV" %
|
|
_AXP192_DC1_VOL_STEPS)
|
|
elif millivolt > _AXP192_DC1_VOL_MAX:
|
|
raise ValueError("Mistake ! DCDC1 maximum output voltage is %umV" %
|
|
_AXP192_DC1_VOL_MAX)
|
|
val = super().readRegister(_AXP192_DC1_VLOTAGE)[0]
|
|
val &= 0x80
|
|
val |= (int)((millivolt - _AXP192_DC1_VOL_MIN) /
|
|
_AXP192_DC1_VOL_STEPS)
|
|
super().writeRegister(_AXP192_DC1_VLOTAGE, val)
|
|
|
|
def getDC1Voltage(self) -> int:
|
|
val = super().readRegister(_AXP192_DC1_VLOTAGE)[0] & 0x7F
|
|
return val * _AXP192_DC1_VOL_STEPS + _AXP192_DC1_VOL_MIN
|
|
|
|
# Power control DCDC2 functions
|
|
|
|
def setDC2PwmMode(self) -> None:
|
|
val = super().readRegister(_AXP192_DCDC_MODESET)[0] & 0xFB
|
|
super().writeRegister(_AXP192_DCDC_MODESET, val | 0x04)
|
|
|
|
def setDC2AutoMode(self) -> None:
|
|
val = super().readRegister(_AXP192_DCDC_MODESET)[0] & 0xFB
|
|
super().writeRegister(_AXP192_DCDC_MODESET, val)
|
|
|
|
def enableDC2VRC(self) -> None:
|
|
val = super().readRegister(_AXP192_DC2_DVM)[0]
|
|
super().writeRegister(_AXP192_DC2_DVM, val | 0x04)
|
|
|
|
def disableDC2VRC(self) -> None:
|
|
val = super().readRegister(_AXP192_DC2_DVM)[0]
|
|
super().writeRegister(_AXP192_DC2_DVM, val & 0xFB)
|
|
|
|
def setDC2VRC(self, opts: int) -> None:
|
|
if opts > 1:
|
|
raise ValueError(
|
|
"DCDC VRC a value within 0-1!")
|
|
val = super().readRegister(_AXP192_DC2_DVM)[0] & 0xFE
|
|
super().writeRegister(_AXP192_DC2_DVM, val | opts)
|
|
|
|
def isEnableDC2VRC(self) -> bool:
|
|
return (super().readRegister(_AXP192_DC2_DVM)[0] & 0x04) == 0x04
|
|
|
|
def isEnableDC2(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 4))
|
|
|
|
def enableDC2(self) -> None:
|
|
super().setRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 4)
|
|
|
|
def disableDC2(self) -> None:
|
|
super().clrRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 4)
|
|
|
|
def setDC2Voltage(self, millivolt: int) -> None:
|
|
if millivolt % _AXP192_DC2_VOL_STEPS:
|
|
raise ValueError("Mistake ! The steps is must %u mV" %
|
|
_AXP192_DC2_VOL_STEPS)
|
|
if millivolt < _AXP192_DC2_VOL_MIN:
|
|
raise ValueError("Mistake ! DCDC2 minimum output voltage is %umV" %
|
|
_AXP192_DC2_VOL_MIN)
|
|
elif millivolt > _AXP192_DC2_VOL_MAX:
|
|
raise ValueError("Mistake ! DCDC2 maximum output voltage is %umV" %
|
|
_AXP192_DC2_VOL_MAX)
|
|
val = super().readRegister(_AXP192_DC2OUT_VOL)[0]
|
|
val &= 0x80
|
|
val |= (int)((millivolt - _AXP192_DC2_VOL_MIN) /
|
|
_AXP192_DC2_VOL_STEPS)
|
|
super().writeRegister(_AXP192_DC2OUT_VOL, val)
|
|
|
|
def getDC2Voltage(self) -> int:
|
|
val = super().readRegister(_AXP192_DC2OUT_VOL)[0]
|
|
return (val * _AXP192_DC2_VOL_STEPS) + _AXP192_DC2_VOL_MIN
|
|
|
|
# Power control DCDC3 functions
|
|
def setDC3PwmMode(self) -> None:
|
|
val = super().readRegister(_AXP192_DCDC_MODESET)[0] & 0xFD
|
|
super().writeRegister(_AXP192_DCDC_MODESET, val | 0x02)
|
|
|
|
def setDC3AutoMode(self) -> None:
|
|
val = super().readRegister(_AXP192_DCDC_MODESET)[0] & 0xFD
|
|
super().writeRegister(_AXP192_DCDC_MODESET, val)
|
|
|
|
def isEnableDC3(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 1))
|
|
|
|
def enableDC3(self) -> None:
|
|
super().setRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 1)
|
|
|
|
def disableDC3(self) -> None:
|
|
super().clrRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 1)
|
|
|
|
def setDC3Voltage(self, millivolt: int) -> None:
|
|
if millivolt % _AXP192_DC3_VOL_STEPS:
|
|
raise ValueError("Mistake ! The steps is must %u mV" %
|
|
_AXP192_DC3_VOL_STEPS)
|
|
if millivolt < _AXP192_DC3_VOL_MIN:
|
|
raise ValueError("Mistake ! DCDC3 minimum output voltage is %umV" %
|
|
_AXP192_DC3_VOL_MIN)
|
|
elif millivolt > _AXP192_DC3_VOL_MAX:
|
|
raise ValueError("Mistake ! DCDC3 maximum output voltage is %umV" %
|
|
_AXP192_DC3_VOL_MAX)
|
|
super().writeRegister(_AXP192_DC3OUT_VOL, (int)(
|
|
(millivolt - _AXP192_DC3_VOL_MIN) / _AXP192_DC3_VOL_STEPS))
|
|
|
|
def getDC3Voltage(self) -> int:
|
|
val = super().readRegister(_AXP192_DC3OUT_VOL)[0]
|
|
return (val * _AXP192_DC3_VOL_STEPS) + _AXP192_DC3_VOL_MIN
|
|
|
|
# Power control EXTEN functions
|
|
def enableExternalPin(self) -> None:
|
|
super().setRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 6)
|
|
|
|
def disableExternalPin(self) -> None:
|
|
super().clrRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 6)
|
|
|
|
def isEnableExternalPin(self) -> bool:
|
|
return bool(super().getRegisterBit(_AXP192_LDO23_DC123_EXT_CTL, 6))
|
|
|
|
# Interrupt status functions
|
|
# @brief Get the interrupt controller mask value.
|
|
# @retval Mask value corresponds to _AXP192_irq_t ,
|
|
def getIrqStatus(self) -> int:
|
|
self.statusRegister = super().readRegister(_AXP192_INTSTS1, 5)
|
|
return (self.statusRegister[4]) << 32 |\
|
|
(self.statusRegister[3]) << 24 |\
|
|
(self.statusRegister[2]) << 16 |\
|
|
(self.statusRegister[1]) << 8 |\
|
|
(self.statusRegister[0])
|
|
|
|
# @brief Clear interrupt controller state.
|
|
def clearIrqStatus(self) -> None:
|
|
for i in range(_AXP192_INTSTS_CNT-1):
|
|
super().writeRegister(_AXP192_INTSTS1 + i, 0xFF)
|
|
super().writeRegister(_AXP192_INTSTS5, 0xFF)
|
|
|
|
# @brief Enable PMU interrupt control mask .
|
|
# @ param opt: View the related chip type _AXP192_irq_t enumeration
|
|
# parameters in "XPowersParams.hpp"
|
|
def enableIRQ(self, opt: int) -> None:
|
|
self._setInterruptImpl(opt, True)
|
|
|
|
# @brief Disable PMU interrupt control mask .
|
|
# @ param opt: View the related chip type _AXP192_irq_t enumeration
|
|
# parameters in "XPowersParams.hpp"
|
|
def disableIRQ(self, opt: int) -> None:
|
|
self._setInterruptImpl(opt, False)
|
|
|
|
# IRQ STATUS 0
|
|
def isAcinOverVoltageIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_ACIN_OVER_VOL_IRQ
|
|
if self.intRegister[0] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[0], mask)
|
|
else:
|
|
return False
|
|
|
|
def isAcinInserIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_ACIN_CONNECT_IRQ
|
|
if self.intRegister[0] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[0], mask)
|
|
else:
|
|
return False
|
|
|
|
def isAcinRemoveIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_ACIN_REMOVED_IRQ
|
|
if self.intRegister[0] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[0], mask)
|
|
else:
|
|
return False
|
|
|
|
def isVbusOverVoltageIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_VBUS_OVER_VOL_IRQ
|
|
if self.intRegister[0] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[0], mask)
|
|
else:
|
|
return False
|
|
|
|
def isVbusInsertIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_VBUS_INSERT_IRQ
|
|
if self.intRegister[0] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[0], mask)
|
|
else:
|
|
return False
|
|
|
|
def isVbusRemoveIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_VBUS_REMOVE_IRQ
|
|
if self.intRegister[0] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[0], mask)
|
|
else:
|
|
return False
|
|
|
|
def isVbusLowVholdIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_VBUS_VHOLD_LOW_IRQ
|
|
if self.intRegister[0] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[0], mask)
|
|
else:
|
|
return False
|
|
|
|
# IRQ STATUS 1
|
|
|
|
def isBatInsertIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_BAT_INSERT_IRQ >> 8
|
|
if self.intRegister[1] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[1], mask)
|
|
else:
|
|
return False
|
|
|
|
def isBatRemoveIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_BAT_REMOVE_IRQ >> 8
|
|
if self.intRegister[1] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[1], mask)
|
|
else:
|
|
return False
|
|
|
|
def isBattEnterActivateIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_BATT_ACTIVATE_IRQ >> 8
|
|
if self.intRegister[1] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[1], mask)
|
|
else:
|
|
return False
|
|
|
|
def isBattExitActivateIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_BATT_EXIT_ACTIVATE_IRQ >> 8
|
|
if self.intRegister[1] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[1], mask)
|
|
else:
|
|
return False
|
|
|
|
def isBatChargeStartIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_BAT_CHG_START_IRQ >> 8
|
|
if self.intRegister[1] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[1], mask)
|
|
else:
|
|
return False
|
|
|
|
def isBatChargeDoneIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_BAT_CHG_DONE_IRQ >> 8
|
|
if self.intRegister[1] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[1], mask)
|
|
else:
|
|
return False
|
|
|
|
def isBattTempHighIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_BATT_OVER_TEMP_IRQ >> 8
|
|
if self.intRegister[1] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[1], mask)
|
|
else:
|
|
return False
|
|
|
|
def isBattTempLowIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_BATT_LOW_TEMP_IRQ >> 8
|
|
if self.intRegister[1] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[1], mask)
|
|
else:
|
|
return False
|
|
|
|
# IRQ STATUS 2
|
|
def isChipOverTemperatureIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_CHIP_TEMP_HIGH_IRQ >> 16
|
|
if self.intRegister[2] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[2], mask)
|
|
else:
|
|
return False
|
|
|
|
def isChargingCurrentLessIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_CHARGE_LOW_CUR_IRQ >> 16
|
|
if self.intRegister[2] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[2], mask)
|
|
else:
|
|
return False
|
|
|
|
def isDC1VoltageLessIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_DC1_LOW_VOL_IRQ >> 16
|
|
if self.intRegister[2] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[2], mask)
|
|
else:
|
|
return False
|
|
|
|
def isDC2VoltageLessIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_DC2_LOW_VOL_IRQ >> 16
|
|
if self.intRegister[2] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[2], mask)
|
|
else:
|
|
return False
|
|
|
|
def isDC3VoltageLessIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_DC3_LOW_VOL_IRQ >> 16
|
|
if self.intRegister[2] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[2], mask)
|
|
else:
|
|
return False
|
|
|
|
def isPekeyShortPressIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_PKEY_SHORT_IRQ >> 16
|
|
if self.intRegister[2] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[2], mask)
|
|
else:
|
|
return False
|
|
|
|
def isPekeyLongPressIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_PKEY_LONG_IRQ >> 16
|
|
if self.intRegister[2] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[2], mask)
|
|
else:
|
|
return False
|
|
|
|
# IRQ STATUS 3
|
|
|
|
def isNOEPowerOnIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_NOE_ON_IRQ >> 24
|
|
if self.intRegister[3] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[3], mask)
|
|
else:
|
|
return False
|
|
|
|
def isNOEPowerDownIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_NOE_OFF_IRQ >> 24
|
|
if self.intRegister[3] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[3], mask)
|
|
else:
|
|
return False
|
|
|
|
def isVbusEffectiveIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_VBUS_VAILD_IRQ >> 24
|
|
if self.intRegister[3] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[3], mask)
|
|
else:
|
|
return False
|
|
|
|
def isVbusInvalidIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_VBUS_INVALID_IRQ >> 24
|
|
if self.intRegister[3] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[3], mask)
|
|
else:
|
|
return False
|
|
|
|
def isVbusSessionIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_VBUS_SESSION_AB_IRQ >> 24
|
|
if self.intRegister[3] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[3], mask)
|
|
else:
|
|
return False
|
|
|
|
def isVbusSessionEndIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_VBUS_SESSION_END_IRQ >> 24
|
|
if self.intRegister[3] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[3], mask)
|
|
else:
|
|
return False
|
|
|
|
def isLowVoltageLevel2Irq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_APS_LOW_VOL_LEVEL_IRQ >> 24
|
|
if self.intRegister[3] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[3], mask)
|
|
else:
|
|
return False
|
|
|
|
# IRQ STATUS 4
|
|
def isWdtExpireIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_TIMER_TIMEOUT_IRQ >> 32
|
|
if self.intRegister[4] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[4], mask)
|
|
else:
|
|
return False
|
|
|
|
def isGpio2EdgeTriggerIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_GPIO2_EDGE_TRIGGER_IRQ >> 32
|
|
if self.intRegister[4] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[4], mask)
|
|
else:
|
|
return False
|
|
|
|
def isGpio1EdgeTriggerIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_GPIO1_EDGE_TRIGGER_IRQ >> 32
|
|
if self.intRegister[4] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[4], mask)
|
|
else:
|
|
return False
|
|
|
|
def isGpio0EdgeTriggerIrq(self) -> bool:
|
|
mask = self.XPOWERS_AXP192_GPIO0_EDGE_TRIGGER_IRQ >> 32
|
|
if self.intRegister[4] & mask:
|
|
return super()._IS_BIT_SET(self.statusRegister[4], mask)
|
|
else:
|
|
return False
|
|
|
|
# ADC Functions
|
|
def enableBattDetection(self) -> None:
|
|
super().setRegisterBit(_AXP192_OFF_CTL, 6)
|
|
|
|
def disableBattDetection(self) -> None:
|
|
super().clrRegisterBit(_AXP192_OFF_CTL, 6)
|
|
|
|
def enableVbusVoltageMeasure(self) -> None:
|
|
self._setSignalCaptureImpl(
|
|
_MONITOR_USB_CURRENT | _MONITOR_USB_VOLTAGE, True)
|
|
|
|
def disableVbusVoltageMeasure(self) -> None:
|
|
self._setSignalCaptureImpl(
|
|
_MONITOR_USB_CURRENT | _MONITOR_USB_VOLTAGE, False)
|
|
|
|
def enableBattVoltageMeasure(self) -> None:
|
|
self._setSignalCaptureImpl(
|
|
_MONITOR_BAT_CURRENT | _MONITOR_BAT_VOLTAGE, True)
|
|
|
|
def disableBattVoltageMeasure(self) -> None:
|
|
self._setSignalCaptureImpl(
|
|
_MONITOR_BAT_CURRENT | _MONITOR_BAT_VOLTAGE, False)
|
|
|
|
def enableSystemVoltageMeasure(self) -> None:
|
|
self._setSignalCaptureImpl(_MONITOR_APS_VOLTAGE, True)
|
|
|
|
def disableSystemVoltageMeasure(self) -> None:
|
|
self._setSignalCaptureImpl(_MONITOR_APS_VOLTAGE, False)
|
|
|
|
def enableTSPinMeasure(self) -> None:
|
|
self._setSignalCaptureImpl(_MONITOR_TS_PIN, True)
|
|
|
|
def disableTSPinMeasure(self) -> None:
|
|
self._setSignalCaptureImpl(_MONITOR_TS_PIN, False)
|
|
|
|
def enableAdcChannel(self, opts: int) -> None:
|
|
self._setSignalCaptureImpl(opts, True)
|
|
|
|
def disableAdcChannel(self, opts: int) -> None:
|
|
self._setSignalCaptureImpl(opts, False)
|
|
|
|
def getVbusVoltage(self) -> int:
|
|
if not self.isVbusIn():
|
|
return 0
|
|
return super().readRegisterH8L4(_AXP192_VBUS_VOL_H8,
|
|
_AXP192_VBUS_VOL_L4
|
|
) * _AXP192_VBUS_VOLTAGE_STEP
|
|
|
|
def getVbusCurrent(self) -> float:
|
|
if not self.isVbusIn():
|
|
return 0
|
|
return super().readRegisterH8L4(_AXP192_VBUS_CUR_H8,
|
|
_AXP192_VBUS_CUR_L4
|
|
) * _AXP192_VBUS_CUR_STEP
|
|
|
|
def getBattVoltage(self) -> float:
|
|
if not self.isBatteryConnect():
|
|
return 0
|
|
return super().readRegisterH8L4(_AXP192_BAT_AVERVOL_H8,
|
|
_AXP192_BAT_AVERVOL_L4
|
|
) * _AXP192_BATT_VOLTAGE_STEP
|
|
|
|
def getBattDischargeCurrent(self) -> float:
|
|
if not self.isBatteryConnect():
|
|
return 0
|
|
return super().readRegisterH8L5(_AXP192_BAT_AVERDISCHGCUR_H8,
|
|
_AXP192_BAT_AVERDISCHGCUR_L5) * _AXP192_BATT_DISCHARGE_CUR_STEP
|
|
|
|
def getAcinVoltage(self) -> float:
|
|
if not self.isAcinIn():
|
|
return 0
|
|
return super().readRegisterH8L4(_AXP192_ACIN_VOL_H8, _AXP192_ACIN_VOL_L4) * _AXP192_ACIN_VOLTAGE_STEP
|
|
|
|
def getAcinCurrent(self) -> float:
|
|
if not self.isAcinIn():
|
|
return 0
|
|
return super().readRegisterH8L4(_AXP192_ACIN_CUR_H8, _AXP192_ACIN_CUR_L4) * _AXP192_ACIN_CUR_STEP
|
|
|
|
def getSystemVoltage(self) -> float:
|
|
return super().readRegisterH8L4(_AXP192_APS_AVERVOL_H8, _AXP192_APS_AVERVOL_L4) * _AXP192_APS_VOLTAGE_STEP
|
|
|
|
# Timer Control
|
|
def setTimerout(self, minute: int) -> None:
|
|
super().writeRegister(_AXP192_TIMER_CTL, 0x80 | minute)
|
|
|
|
def disableTimer(self) -> None:
|
|
super().writeRegister(_AXP192_TIMER_CTL, 0x80)
|
|
|
|
def clearTimerFlag(self) -> None:
|
|
super().setRegisterBit(_AXP192_TIMER_CTL, 7)
|
|
|
|
# Data Buffer
|
|
def writeDataBuffer(self, data: list, size: int) -> None:
|
|
if size > _AXP192_DATA_BUFFER_SIZE:
|
|
raise ValueError('Out of range!')
|
|
for i in range(size):
|
|
super().writeRegister(_AXP192_DATA_BUFFER1 + i, data[i])
|
|
|
|
def readDataBuffer(self, size: int) -> list:
|
|
if size > _AXP192_DATA_BUFFER_SIZE:
|
|
raise ValueError('Out of range!')
|
|
data = [0]*size
|
|
for i in range(size):
|
|
data[i] = super().readRegister(_AXP192_DATA_BUFFER1 + i)[0]
|
|
return list(data)
|
|
|
|
# Charge led functions
|
|
# @brief Set charging led mode.
|
|
# @retval See xpowers_chg_led_mode_t enum for details.
|
|
def setChargingLedMode(self, mode: int) -> None:
|
|
range = [self.XPOWERS_CHG_LED_OFF, self.XPOWERS_CHG_LED_BLINK_1HZ,
|
|
self.XPOWERS_CHG_LED_BLINK_4HZ, self.XPOWERS_CHG_LED_ON]
|
|
if mode in range:
|
|
val = super().readRegister(_AXP192_OFF_CTL)[0]
|
|
val &= 0xC7
|
|
val |= 0x08 # use manual ctrl
|
|
val |= (mode << 4)
|
|
super().writeRegister(_AXP192_OFF_CTL, val)
|
|
else:
|
|
super().clrRegisterBit(_AXP192_OFF_CTL, 3)
|
|
|
|
def getChargingLedMode(self) -> int:
|
|
if not bool(super().getRegisterBit(_AXP192_OFF_CTL, 3)):
|
|
return self.XPOWERS_CHG_LED_CTRL_CHG
|
|
val = super().readRegister(_AXP192_OFF_CTL)[0]
|
|
val &= 0x30
|
|
return val >> 4
|
|
|
|
# Coulomb counter control
|
|
def enableCoulomb(self) -> None:
|
|
super().setRegisterBit(_AXP192_COULOMB_CTL, 7)
|
|
|
|
def disableCoulomb(self) -> None:
|
|
super().clrRegisterBit(_AXP192_COULOMB_CTL, 7)
|
|
|
|
def stopCoulomb(self) -> None:
|
|
super().setRegisterBit(_AXP192_COULOMB_CTL, 6)
|
|
|
|
def clearCoulomb(self) -> None:
|
|
super().setRegisterBit(_AXP192_COULOMB_CTL, 5)
|
|
|
|
def getBattChargeCoulomb(self) -> int:
|
|
data = [0]*4
|
|
data[0] = super().readRegister(_AXP192_BAT_CHGCOULOMB3)[0]
|
|
data[1] = super().readRegister(_AXP192_BAT_CHGCOULOMB2)[0]
|
|
data[2] = super().readRegister(_AXP192_BAT_CHGCOULOMB1)[0]
|
|
data[3] = super().readRegister(_AXP192_BAT_CHGCOULOMB0)[0]
|
|
return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]
|
|
|
|
def getBattDischargeCoulomb(self) -> int:
|
|
data = [0]*4
|
|
data[0] = super().readRegister(_AXP192_BAT_DISCHGCOULOMB3)[0]
|
|
data[1] = super().readRegister(_AXP192_BAT_DISCHGCOULOMB2)[0]
|
|
data[2] = super().readRegister(_AXP192_BAT_DISCHGCOULOMB1)[0]
|
|
data[3] = super().readRegister(_AXP192_BAT_DISCHGCOULOMB0)[0]
|
|
return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]
|
|
|
|
def getAdcSamplingRate(self) -> int:
|
|
val = super().readRegister(_AXP192_ADC_SPEED)[0]
|
|
return 25 * math.pow(2, (val & 0xC0) >> 6)
|
|
|
|
def getCoulombData(self) -> float:
|
|
charge = self.getBattChargeCoulomb()
|
|
discharge = self.getBattDischargeCoulomb()
|
|
rate = self.getAdcSamplingRate()
|
|
return 65536.0 * 0.5 * (charge - discharge) / 3600.0 / rate
|
|
|
|
# GPIO control functions
|
|
def getBatteryChargeCurrent(self) -> float:
|
|
return super().readRegisterH8L5(
|
|
_AXP192_BAT_AVERCHGCUR_H8,
|
|
_AXP192_BAT_AVERCHGCUR_L5
|
|
) * _AXP192_BATT_CHARGE_CUR_STEP
|
|
|
|
def getGpio0Voltage(self) -> int:
|
|
return super().readRegisterH8L4(_AXP192_GPIO0_VOL_ADC_H8, _AXP192_GPIO0_VOL_ADC_L4) * _AXP192_GPIO0_STEP * 1000
|
|
|
|
def getGpio1Voltage(self) -> int:
|
|
return super().readRegisterH8L4(_AXP192_GPIO1_VOL_ADC_H8, _AXP192_GPIO1_VOL_ADC_L4) * _AXP192_GPIO1_STEP * 1000
|
|
|
|
def pwmSetup(self, channel: int, freq: int, duty: int) -> None:
|
|
# PWM输出频率 = 2.25MHz / (X+1) / Y1
|
|
# PWM输出占空比 = Y2 / Y1
|
|
if channel == 0:
|
|
super().writeRegister(_AXP192_PWM1_FREQ_SET, freq)
|
|
super().writeRegister(_AXP192_PWM1_DUTY_SET1, duty >> 8)
|
|
super().writeRegister(_AXP192_PWM1_DUTY_SET2, duty & 0xFF)
|
|
elif channel == 1:
|
|
super().writeRegister(_AXP192_PWM2_FREQ_SET, freq)
|
|
super().writeRegister(_AXP192_PWM2_DUTY_SET1, duty >> 8)
|
|
super().writeRegister(_AXP192_PWM2_DUTY_SET2, duty & 0xFF)
|
|
|
|
def pwmEnable(self, channel) -> None:
|
|
if channel == 0:
|
|
val = super().readRegister(_AXP192_GPIO1_CTL)[0] & 0xF8
|
|
super().writeRegister(_AXP192_GPIO1_CTL, val | 0x02)
|
|
elif channel == 1:
|
|
val = super().readRegister(_AXP192_GPIO2_CTL)[0] & 0xF8
|
|
super().writeRegister(_AXP192_GPIO2_CTL, val | 0x02)
|
|
|
|
def getBatteryPercent(self) -> int:
|
|
if not self.isBatteryConnect():
|
|
return -1
|
|
table = [3000, 3650, 3700, 3740, 3760, 3795,
|
|
3840, 3910, 3980, 4070, 4150]
|
|
voltage = self.getBattVoltage()
|
|
if voltage < table[0]:
|
|
return 0
|
|
for i in range(11):
|
|
if voltage < table[i]:
|
|
return i * 10 - (10 * (int)(table[i] - voltage)) / (int)(table[i] - table[i - 1])
|
|
return 100
|
|
|
|
def getChipID(self) -> int:
|
|
return super().readRegister(_AXP192_IC_TYPE)[0]
|
|
|
|
# GPIO setting
|
|
|
|
def pinMode(self, pin: int, mode: int) -> None:
|
|
if pin == self.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 == self.INPUT or mode == self.INPUT_PULLDOWN:
|
|
if self.gpio[pin].mode != self.INPUT:
|
|
self.gpio[pin].mode = self.INPUT
|
|
val = super().readRegister(_AXP192_GPIO0_CTL)[0] & 0xF8
|
|
super().writeRegister(_AXP192_GPIO0_CTL, val | 0x01)
|
|
# Set pull-down mode
|
|
val = super().readRegister(_AXP192_GPIO012_PULLDOWN)[0] & 0xFE
|
|
if mode == self.INPUT_PULLDOWN:
|
|
super().writeRegister(_AXP192_GPIO012_PULLDOWN, val | 0x01)
|
|
else:
|
|
super().writeRegister(_AXP192_GPIO012_PULLDOWN, val)
|
|
|
|
elif pin == self.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 == self.INPUT or mode == self.INPUT_PULLDOWN:
|
|
if self.gpio[pin].mode != self.INPUT:
|
|
self.gpio[pin].mode = self.INPUT
|
|
val = super().readRegister(_AXP192_GPIO1_CTL)[0] & 0xF8
|
|
super().writeRegister(_AXP192_GPIO1_CTL, val | 0x01)
|
|
# Set pull-down mode
|
|
val = super().readRegister(_AXP192_GPIO012_PULLDOWN)[0] & 0xFD
|
|
if mode == self.INPUT_PULLDOWN:
|
|
super().writeRegister(_AXP192_GPIO012_PULLDOWN, val | 0x02)
|
|
else:
|
|
super().writeRegister(_AXP192_GPIO012_PULLDOWN, val)
|
|
|
|
elif pin == self.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 == self.INPUT or mode == self.INPUT_PULLDOWN:
|
|
if self.gpio[pin].mode != self.INPUT:
|
|
self.gpio[pin].mode = self.INPUT
|
|
val = super().readRegister(_AXP192_GPIO2_CTL)[0] & 0xF8
|
|
super().writeRegister(_AXP192_GPIO2_CTL, val | 0x01)
|
|
|
|
# Set pull-down mode
|
|
val = super().readRegister(_AXP192_GPIO012_PULLDOWN)[0] & 0xFB
|
|
if mode == self.INPUT_PULLDOWN:
|
|
super().writeRegister(_AXP192_GPIO012_PULLDOWN, val | 0x04)
|
|
else:
|
|
super().writeRegister(_AXP192_GPIO012_PULLDOWN, val)
|
|
elif pin == self.PMU_GPIO3:
|
|
'''
|
|
* 00: External charging control
|
|
* 01: NMOS open-drain output port 3
|
|
* 10: Universal input port 3
|
|
* 11: ADC input
|
|
'''
|
|
if mode == self.INPUT:
|
|
if self.gpio[pin].mode != self.INPUT:
|
|
self.gpio[pin].mode = self.INPUT
|
|
val = super().readRegister(_AXP192_GPIO34_CTL)[0] & 0xFC
|
|
super().writeRegister(_AXP192_GPIO34_CTL, val | 0x82)
|
|
|
|
elif pin == self.PMU_GPIO4:
|
|
'''
|
|
* 00: External charging control
|
|
* 01: NMOS open-drain output port 4
|
|
* 10: Universal input port 4
|
|
* 11: undefined
|
|
'''
|
|
if mode == self.INPUT:
|
|
if self.gpio[pin].mode != self.INPUT:
|
|
self.gpio[pin].mode = self.INPUT
|
|
val = super().readRegister(_AXP192_GPIO34_CTL)[0] & 0xF3
|
|
super().writeRegister(_AXP192_GPIO34_CTL, val | 0x88)
|
|
|
|
elif pin == self.PMU_GPIO5:
|
|
if mode == self.INPUT:
|
|
if self.gpio[pin].mode != self.INPUT:
|
|
self.gpio[pin].mode = self.INPUT
|
|
|
|
val = super().readRegister(_AXP192_GPIO5_CTL)[0] & 0xBF
|
|
super().writeRegister(_AXP192_GPIO5_CTL, val | 0x40)
|
|
else:
|
|
print('gpio is invalid')
|
|
|
|
def digitalRead(self, pin: int) -> bool:
|
|
if pin == self.PMU_GPIO0:
|
|
return bool(super().getRegisterBit(_AXP192_GPIO012_SIGNAL, 4))
|
|
elif pin == self.PMU_GPIO1:
|
|
return bool(super().getRegisterBit(_AXP192_GPIO012_SIGNAL, 5))
|
|
elif pin == self.PMU_GPIO2:
|
|
return bool(super().getRegisterBit(_AXP192_GPIO012_SIGNAL, 6))
|
|
elif pin == self.PMU_GPIO3:
|
|
return bool(super().getRegisterBit(_AXP192_GPIO34_SIGNAL, 4))
|
|
elif pin == self.PMU_GPIO4:
|
|
return bool(super().getRegisterBit(_AXP192_GPIO34_SIGNAL, 5))
|
|
elif pin == self.PMU_GPIO5:
|
|
return bool(super().getRegisterBit(_AXP192_GPIO5_CTL, 4))
|
|
else:
|
|
print('gpio is invalid')
|
|
return 0
|
|
|
|
def digitalWrite(self, pin: int, val: int) -> None:
|
|
if pin == self.PMU_GPIO0:
|
|
if self.gpio[pin].mode != self.OUTPUT:
|
|
self.gpio[pin].mode = self.OUTPUT
|
|
reg = super().readRegister(_AXP192_GPIO0_CTL)[0] & 0xF8
|
|
val = (reg, (reg | 0x05))[val]
|
|
print(bin(val))
|
|
super().writeRegister(_AXP192_GPIO0_CTL, val)
|
|
|
|
elif pin == self.PMU_GPIO1:
|
|
if self.gpio[pin].mode != self.OUTPUT:
|
|
self.gpio[pin].mode = self.OUTPUT
|
|
reg = super().readRegister(_AXP192_GPIO1_CTL)[0] & 0xF8
|
|
val = (reg, (reg | 0x05))[val]
|
|
super().writeRegister(_AXP192_GPIO1_CTL, val)
|
|
|
|
elif pin == self.PMU_GPIO2:
|
|
if self.gpio[pin].mode != self.OUTPUT:
|
|
self.gpio[pin].mode = self.OUTPUT
|
|
reg = super().readRegister(_AXP192_GPIO2_CTL)[0] & 0xF8
|
|
val = (reg, (reg | 0x05))[val]
|
|
super().writeRegister(_AXP192_GPIO2_CTL, val)
|
|
|
|
elif pin == self.PMU_GPIO3:
|
|
if self.gpio[pin].mode != self.OUTPUT:
|
|
self.gpio[pin].mode = self.OUTPUT
|
|
reg = super().readRegister(_AXP192_GPIO34_CTL)[0] & 0xFC
|
|
super().writeRegister(_AXP192_GPIO34_CTL, reg | 0x01)
|
|
|
|
reg = super().readRegister(_AXP192_GPIO34_SIGNAL)[0] & 0xF7
|
|
val = (reg, (reg | 0x01))[val]
|
|
super().writeRegister(_AXP192_GPIO34_SIGNAL, val)
|
|
|
|
elif pin == self.PMU_GPIO4:
|
|
if self.gpio[pin].mode != self.OUTPUT:
|
|
self.gpio[pin].mode = self.OUTPUT
|
|
reg = super().readRegister(_AXP192_GPIO34_CTL)[0] & 0xF3
|
|
super().writeRegister(_AXP192_GPIO34_CTL, reg | 0x04)
|
|
|
|
reg = super().readRegister(_AXP192_GPIO34_SIGNAL)[0] & 0xEF
|
|
val = (reg, (reg | 0x01))[val]
|
|
super().writeRegister(_AXP192_GPIO34_SIGNAL, val)
|
|
|
|
elif pin == self.PMU_GPIO5:
|
|
if self.gpio[pin].mode != self.OUTPUT:
|
|
self.gpio[pin].mode = self.OUTPUT
|
|
reg = super().readRegister(_AXP192_GPIO5_CTL)[0] & 0xBF
|
|
super().writeRegister(_AXP192_GPIO5_CTL, reg)
|
|
|
|
reg = super().readRegister(_AXP192_GPIO5_CTL)[0] & 0xDF
|
|
val = (reg, (reg | 0x01))[val]
|
|
super().writeRegister(_AXP192_GPIO5_CTL, val)
|
|
else:
|
|
print('gpio is invalid')
|
|
|
|
# ! Need FIX
|
|
def analogRead(self, pin: int) -> int:
|
|
if pin == self.PMU_GPIO0:
|
|
if self.gpio[pin].mode != self.ANALOG:
|
|
# Enable GPIO ADC Function
|
|
val = super().readRegister(_AXP192_GPIO0_CTL)[0] & 0xF8
|
|
super().writeRegister(_AXP192_GPIO0_CTL, val | 0x04)
|
|
|
|
# Enable ADC2 / GPIO0
|
|
# val = super().readRegister(_AXP192_ADC_EN2)[0] | 0x08
|
|
# super().writeRegister(_AXP192_ADC_EN2, val )
|
|
super().setRegisterBit(_AXP192_ADC_EN2, 3)
|
|
|
|
# Set adc input range 0~2.0475V
|
|
super().clrRegisterBit(_AXP192_ADC_INPUTRANGE, 0)
|
|
self.gpio[pin].mode = self.ANALOG
|
|
|
|
return super().readRegisterH8L4(_AXP192_GPIO0_VOL_ADC_H8, _AXP192_GPIO0_VOL_ADC_L4)
|
|
|
|
elif pin == self.PMU_GPIO1:
|
|
if self.gpio[pin].mode != self.ANALOG:
|
|
# Enable GPIO ADC Function
|
|
val = super().readRegister(_AXP192_GPIO1_CTL)[0] & 0xF8
|
|
super().writeRegister(_AXP192_GPIO1_CTL, val | 0x04)
|
|
|
|
# Enable ADC2 / GPIO1
|
|
# val = super().readRegister(_AXP192_ADC_EN2)[0] | 0x04
|
|
# super().writeRegister(_AXP192_ADC_EN2, val )
|
|
super().setRegisterBit(_AXP192_ADC_EN2, 2)
|
|
|
|
# Set adc input range 0~2.0475V
|
|
super().clrRegisterBit(_AXP192_ADC_INPUTRANGE, 1)
|
|
self.gpio[pin].mode = self.ANALOG
|
|
|
|
return super().readRegisterH8L4(_AXP192_GPIO1_VOL_ADC_H8, _AXP192_GPIO1_VOL_ADC_L4)
|
|
|
|
elif pin == self.PMU_GPIO2:
|
|
if self.gpio[pin].mode != self.ANALOG:
|
|
# Enable GPIO ADC Function
|
|
val = super().readRegister(_AXP192_GPIO1_CTL)[0] & 0xF8
|
|
super().writeRegister(_AXP192_GPIO1_CTL, val | 0x04)
|
|
# Enable ADC2 / GPIO1
|
|
# val = super().readRegister(_AXP192_ADC_EN2)[0] | 0x02
|
|
# super().writeRegister(_AXP192_ADC_EN2, val )
|
|
super().setRegisterBit(_AXP192_ADC_EN2, 1)
|
|
|
|
# Set adc input range 0~2.0475V
|
|
super().clrRegisterBit(_AXP192_ADC_INPUTRANGE, 2)
|
|
self.gpio[pin].mode = self.ANALOG
|
|
|
|
return super().readRegisterH8L4(_AXP192_GPIO2_VOL_ADC_H8, _AXP192_GPIO2_VOL_ADC_L4)
|
|
|
|
elif pin == self.PMU_GPIO3:
|
|
if self.gpio[pin].mode != self.ANALOG:
|
|
# Enable GPIO ADC Function
|
|
val = super().readRegister(_AXP192_GPIO1_CTL)[0] & 0xF8
|
|
super().writeRegister(_AXP192_GPIO1_CTL, val | 0x04)
|
|
|
|
# Enable ADC2 / GPIO1
|
|
super().setRegisterBit(_AXP192_ADC_EN2, 0)
|
|
|
|
# Set adc input range 0~2.0475V
|
|
super().clrRegisterBit(_AXP192_ADC_INPUTRANGE, 3)
|
|
self.gpio[pin].mode = self.ANALOG
|
|
|
|
return super().readRegisterH8L4(_AXP192_GPIO3_VOL_ADC_H8, _AXP192_GPIO3_VOL_ADC_L4)
|
|
|
|
elif pin == self.PMU_TS_PIN:
|
|
if self.gpio[pin].mode != self.ANALOG:
|
|
# Enable TS PIN ADC Function
|
|
super().setRegisterBit(_AXP192_ADC_SPEED, 2)
|
|
# val = super().readRegister(_AXP192_ADC_SPEED)[0] & 0xFB
|
|
# super().writeRegister(_AXP192_ADC_SPEED, val | 0x04)
|
|
self.gpio[pin].mode = self.ANALOG
|
|
|
|
return super().readRegisterH8L4(_AXP192_TS_IN_H8, _AXP192_TS_IN_L4)
|
|
else:
|
|
print('gpio is invalid')
|
|
|
|
return 0
|
|
|
|
# Sleep function
|
|
|
|
def enableSleep(self) -> None:
|
|
super().setRegisterBit(_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.
|
|
def setPowerKeyPressOnTime(self, opt: int) -> None:
|
|
val = super().readRegister(_AXP192_POK_SET)[0]
|
|
super().writeRegister(_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.
|
|
|
|
def getPowerKeyPressOnTime(self) -> int:
|
|
val = super().readRegister(_AXP192_POK_SET)[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.
|
|
|
|
def setPowerKeyPressOffTime(self, opt: int) -> None:
|
|
val = super().readRegister(_AXP192_POK_SET)[0]
|
|
super().writeRegister(_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.
|
|
def getPowerKeyPressOffTime(self) -> int:
|
|
val = super().readRegister(_AXP192_POK_SET)[0]
|
|
return (val & 0x03)
|
|
|
|
def setPowerKeyLongPressOnTime(self, opt: int) -> None:
|
|
val = super().readRegister(_AXP192_POK_SET)[0]
|
|
super().writeRegister(_AXP192_POK_SET, (val & 0xCF) | (opt << 4))
|
|
|
|
def enablePowerKeyLongPressPowerOff(self) -> None:
|
|
super().setRegisterBit(_AXP192_POK_SET, 3)
|
|
|
|
def disablePowerKeyLongPressPowerOff(self) -> None:
|
|
super().clrRegisterBit(_AXP192_POK_SET, 3)
|
|
|
|
# Interrupt control functions
|
|
def _setInterruptImpl(self, opts: int, enable: bool) -> None:
|
|
# log_d("%s %s - 0x%llx\n", __func__, enable ? "ENABLE": "DISABLE", opts)
|
|
if opts & 0xFF:
|
|
value = opts & 0xFF
|
|
data = super().readRegister(_AXP192_INTEN1)[0]
|
|
self.intRegister[0] = ((data & (~value)), (data | value))[enable]
|
|
super().writeRegister(_AXP192_INTEN1, self.intRegister[0])
|
|
|
|
if opts & 0xFF00:
|
|
value = opts >> 8
|
|
data = super().readRegister(_AXP192_INTEN2)[0]
|
|
self.intRegister[1] = ((data & (~value)), (data | value))[enable]
|
|
super().writeRegister(_AXP192_INTEN2, self.intRegister[1])
|
|
|
|
if opts & 0xFF0000:
|
|
value = opts >> 16
|
|
data = super().readRegister(_AXP192_INTEN3)[0]
|
|
self.intRegister[2] = ((data & (~value)), (data | value))[enable]
|
|
super().writeRegister(_AXP192_INTEN3, self.intRegister[2])
|
|
|
|
if opts & 0xFF000000:
|
|
value = opts >> 24
|
|
data = super().readRegister(_AXP192_INTEN4)[0]
|
|
self.intRegister[3] = ((data & (~value)), (data | value))[enable]
|
|
super().writeRegister(_AXP192_INTEN4, self.intRegister[3])
|
|
|
|
if opts & 0xFF00000000:
|
|
value = opts >> 32
|
|
data = super().readRegister(_AXP192_INTEN5)[0]
|
|
self.intRegister[4] = ((data & (~value)), (data | value))[enable]
|
|
super().writeRegister(_AXP192_INTEN5, self.intRegister[4])
|
|
|
|
# Signal Capture control functions
|
|
def _setSignalCaptureImpl(self, opts: int, enable: bool) -> None:
|
|
if opts & 0xFF:
|
|
value = super().readRegister(_AXP192_ADC_EN1)[0]
|
|
value = ((value & (~opts)), (value | opts))[enable]
|
|
super().writeRegister(_AXP192_ADC_EN1, value)
|
|
|
|
if opts & 0xFF00:
|
|
opts >>= 8
|
|
value = super().readRegister(_AXP192_ADC_EN2)[0]
|
|
value = ((value & (~opts)), (value | opts))[enable]
|
|
super().writeRegister(_AXP192_ADC_EN2, value)
|