-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
679 additions
and
19 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,254 @@ | ||
from __future__ import division | ||
import logging | ||
import time | ||
import math | ||
import numpy as np | ||
from ecomet_i2c_sensors.axp209 import axp209_constant | ||
from ctypes import c_uint8, BigEndianStructure, Union | ||
|
||
reg_list = { 'POWER_OPERATING_MODE_REG' : axp209_constant.POWER_OPERATING_MODE_REG, 'POWER_INPUT_STATUS_REG' : axp209_constant.POWER_INPUT_STATUS_REG, | ||
'BATTERY_GAUGE_REG' : axp209_constant.BATTERY_GAUGE_REG, | ||
'INTERNAL_TEMPERATURE_REG' : axp209_constant.INTERNAL_TEMPERATURE_REG, 'BATTERY_VOLTAGE_REG' : axp209_constant.BATTERY_VOLTAGE_REG, | ||
'BATTERY_CHARGE_CURRENT_REG' : axp209_constant.BATTERY_CHARGE_CURRENT_REG, | ||
'BATTERY_DISCHARGE_CURRENT_REG' : axp209_constant.BATTERY_DISCHARGE_CURRENT_REG, 'BATTERY_VOLTAGE_REG' : axp209_constant.BATTERY_VOLTAGE_REG, | ||
'VBUS_IPSOUT_CHANNEL_MANAGEMENT_REG' : axp209_constant.VBUS_IPSOUT_CHANNEL_MANAGEMENT_REG, | ||
'ADC_ENABLE1_REG' : axp209_constant.ADC_ENABLE1_REG, 'ADC_ENABLE2_REG' : axp209_constant.ADC_ENABLE2_REG | ||
} | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
class AXP209(object): | ||
'''axp209() Power Management Controller''' | ||
|
||
def __init__(self, address=axp209_constant.AXP209_ADDRESS, busnum=None, i2c=None, **kwargs) : | ||
'''Initialize the axp209.''' | ||
# Setup I2C interface for the device. | ||
if i2c is None: | ||
import ecomet_i2c_sensors.i2c as I2C | ||
i2c = I2C | ||
self._logger = logging.getLogger(__name__) | ||
self._device = i2c.get_i2c_device(address, busnum=busnum, i2c_interface='smbus2', **kwargs) | ||
#i2c_interface parameter choise smbus2 lib insted of Adafruit PureIO | ||
|
||
# force ADC enable for battery voltage and current | ||
self.adc_enable1 = 0xc3 | ||
|
||
def __enter__(self): | ||
return self | ||
|
||
def __exit__(self, exc_type, exc_val, exc_tb): | ||
if self.autocleanup: | ||
self.close() | ||
|
||
def close(self): | ||
self._device.close() | ||
|
||
@property | ||
def gpio2_output(self): | ||
pass | ||
|
||
@gpio2_output.setter | ||
def gpio2_output(self, val): | ||
flags = GPIO012_FEATURE_SET_FLAGS() | ||
if bool(val): | ||
flags.gpio_function = 0b111 | ||
else: | ||
flags.gpio_function = 0b000 | ||
self.write_register('ADC_ENABLE1_REG', flags.asbyte) | ||
|
||
@property | ||
def adc_enable1(self): | ||
flags = axp209_constant.ADC_ENABLE1_FLAGS() | ||
(flags.asbyte,ret) = self.read_register('ADC_ENABLE1_REG') | ||
return flags | ||
|
||
@adc_enable1.setter | ||
def adc_enable1(self, flags): | ||
if hasattr(flags, "asbyte"): | ||
flags = flags.asbyte | ||
self.write_register('ADC_ENABLE1_REG', flags) | ||
|
||
@property | ||
def adc_enable2(self): | ||
flags = axp209_constant.ADC_ENABLE2_FLAGS() | ||
(flags.asbyte,ret) = self.read_register('ADC_ENABLE2_REG') | ||
return flags | ||
|
||
@adc_enable2.setter | ||
def adc_enable2(self, flags): | ||
if hasattr(flags, "asbyte"): | ||
flags = flags.asbyte | ||
self.write_register('ADC_ENABLE2_REG', flags) | ||
|
||
@property | ||
def vbus_current_limit(self): | ||
""" Returns the current vbus current limit setting """ | ||
limits = { #00:900 mA; 01:500 mA; 10:100 mA; 11: not limit | ||
0: "900 mA", | ||
1: "500 mA", | ||
2: "100 mA", | ||
3: "not limited", | ||
} | ||
(current_data,ret) = self.read_register('VBUS_IPSOUT_CHANNEL_MANAGEMENT_REG') | ||
current_limit = current_data & 0x03 | ||
return limits.get(current_limit, "invalid setting") | ||
|
||
@vbus_current_limit.setter | ||
def vbus_current_limit(self, val): | ||
flags = axp209_constant.VBUS_CURRENT_LIMIT_CONTROL() | ||
limits = { #00:900 mA; 01:500 mA; 10:100 mA; 11: not limit | ||
0: "900 mA", | ||
1: "500 mA", | ||
2: "100 mA", | ||
3: "no limit", | ||
} | ||
for setting, limit in limits.items(): | ||
if limit == val : | ||
(flags.asbyte,ret) = self.read_register('VBUS_IPSOUT_CHANNEL_MANAGEMENT_REG') | ||
flags.vbus_current_limit = setting | ||
self.write_register('VBUS_IPSOUT_CHANNEL_MANAGEMENT_REG', flags.asbyte) | ||
|
||
@property | ||
def power_input_status(self): | ||
flags = axp209_constant.POWER_INPUT_STATUS_FLAGS() | ||
(flags.asbyte,ret) = self.read_register('POWER_INPUT_STATUS_REG') | ||
return flags | ||
|
||
@property | ||
def battery_current_direction(self): | ||
return bool(self.power_input_status.battery_current_direction) | ||
|
||
@property | ||
def power_operating_mode(self): | ||
flags = axp209_constant.POWER_OPERATING_STATUS_FLAGS() | ||
(flags.asbyte,ret) = self.read_register('POWER_OPERATING_MODE_REG') | ||
return flags | ||
|
||
# ADC_ENABLE1 REGISTER status | ||
@property | ||
def battery_current_adc_enable(self): | ||
return bool(self.adc_enable1.battery_current_adc_enable) | ||
|
||
@property | ||
def acin_voltage_adc_enable(self): | ||
return bool(self.adc_enable1.acin_voltage_adc_enable) | ||
|
||
@property | ||
def acin_current_adc_enable(self): | ||
return bool(self.adc_enable1.acin_current_adc_enable) | ||
|
||
@property | ||
def vbus_voltage_adc_enable(self): | ||
return bool(self.adc_enable1.vbus_voltage_adc_enable) | ||
|
||
@property | ||
def vbus_current_adc_enable(self): | ||
return bool(self.adc_enable1.vbus_current_adc_enable) | ||
|
||
@property | ||
def aps_voltage_adc_enable(self): | ||
return bool(self.adc_enable1.aps_voltage_adc_enable) | ||
|
||
@property | ||
def ts_pin_adc_function_enable(self): | ||
return bool(self.adc_enable1.ts_pin_adc_function_enable) | ||
|
||
# TBD_ENABLE2_REGISTER status | ||
@property | ||
def apx209_internal_temperature_monitoring_adc_enable(self): | ||
return bool(self.adc_enable2.apx209_internal_temperature_monitoring_adc_enable) | ||
|
||
@property | ||
def gpio0_adc_function_enable(self): | ||
return bool(self.adc_enable2.gpio0_adc_function_enable) | ||
|
||
@property | ||
def gpio1_adc_function_enable(self): | ||
return bool(self.adc_enable2.gpio1_adc_function_enable) | ||
# | ||
@property | ||
def battery_exists(self): | ||
return bool(self.power_operating_mode.battery_exists) | ||
|
||
@property | ||
def battery_charging(self): | ||
return bool(self.power_operating_mode.battery_charging) | ||
|
||
@property | ||
def battery_voltage(self): | ||
""" Returns voltage in mV """ | ||
(voltage_bin,ret) = self.read_register('BATTERY_VOLTAGE_REG') | ||
return voltage_bin * 1.1 | ||
|
||
@property | ||
def battery_charge_current(self): | ||
""" Returns current in mA """ | ||
(charge_bin,ret) = self.read_register('BATTERY_CHARGE_CURRENT_REG') | ||
# (12 bits) | ||
# 0 mV -> 000h, 0.5 mA/bit FFFh -> 1800 mA | ||
return charge_bin * 0.5 | ||
|
||
@property | ||
def battery_discharge_current(self): | ||
""" Returns current in mA """ | ||
(discharge_bin,ret) = self.read_register('BATTERY_DISCHARGE_CURRENT_REG') | ||
# 13bits | ||
# 0 mV -> 000h, 0.5 mA/bit 1FFFh -> 1800 mA | ||
return discharge_bin * 0.5 | ||
|
||
@property | ||
def internal_temperature(self): | ||
""" Returns temperature in celsius C """ | ||
(temp,ret) = self.read_register('INTERNAL_TEMPERATURE_REG') | ||
# MSB is 8 bits, LSB is lower 4 bits | ||
# -144.7c -> 000h, 0.1c/bit FFFh -> 264.8c | ||
return temp*0.1-144.7 | ||
|
||
@property | ||
def battery_gauge(self): | ||
(gauge_bin,ret) = self.read_register('BATTERY_GAUGE_REG') | ||
gauge = gauge_bin & 0x7f | ||
if gauge > 100: | ||
return -1 | ||
return gauge | ||
|
||
def read_register(self, register) : | ||
reg_status = -9999 | ||
ret = 0 | ||
if register in ['INTERNAL_TEMPERATURE_REG','BATTERY_VOLTAGE_REG','BATTERY_CHARGE_CURRENT_REG'] : | ||
try : | ||
# 12 bit | ||
reg_status_bita = self._device.readList(reg_list[register],2) | ||
reg_status_hex_high = reg_status_bita[0] | ||
reg_status_hex_low = reg_status_bita[1] | ||
reg_status = reg_status_hex_high << 4 | reg_status_hex_low & 0x0f | ||
except : | ||
ret = ret + 1 | ||
elif register in ['BATTERY_DISCHARGE_CURRENT_REG'] : | ||
try : | ||
# 13 bit | ||
reg_status_bita = self._device.readList(reg_list[register],2) | ||
reg_status_hex_high = reg_status_bita[0] | ||
reg_status_hex_low = reg_status_bita[1] | ||
reg_status = reg_status_hex_high << 5 | reg_status_hex_low & 0x1f | ||
except : | ||
ret = ret + 1 | ||
elif register in ['POWER_OPERATING_MODE_REG','POWER_INPUT_STATUS_REG','BATTERY_GAUGE_REG','BATTERY_GAUGE_REG','VBUS_IPSOUT_CHANNEL_MANAGEMENT_REG', | ||
'ADC_ENABLE1_REG','ADC_ENABLE2_REG'] : | ||
try : | ||
reg_status = self._device.readU8(reg_list[register]) | ||
except : | ||
ret = ret + 1 | ||
return(reg_status,ret) | ||
|
||
def write_register(self, register,data) : | ||
ret = 0 | ||
#print ( register ) | ||
if register in ['VBUS_IPSOUT_CHANNEL_MANAGEMENT_REG','ADC_ENABLE1_REG','ADC_ENABLE2_REG'] : | ||
self._device.write8(reg_list[register],data) | ||
try : | ||
self._device.write8(reg_list[register],data) | ||
except : | ||
ret = ret + 1 | ||
return (ret) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
from ctypes import c_uint8, BigEndianStructure, Union | ||
|
||
# Address: | ||
AXP209_ADDRESS = 0x34 # 8 bit version | ||
|
||
# from CHIP battery.sh script | ||
POWER_INPUT_STATUS_REG = 0x00 | ||
POWER_OPERATING_MODE_REG = 0x01 | ||
CHARGE_CONTROL_REG = 0x33 | ||
CHARGE_CONTROL2_REG = 0x34 | ||
ADC_ENABLE1_REG = 0x82 | ||
ADC_ENABLE2_REG = 0x83 | ||
INTERNAL_TEMPERATURE_REG = 0x5e | ||
BATTERY_VOLTAGE_REG = 0x78 | ||
BATTERY_CHARGE_CURRENT_REG = 0x7a | ||
BATTERY_DISCHARGE_CURRENT_REG = 0x7c | ||
GPIO0_FEATURE_SET_REG = 0x90 | ||
GPIO1_FEATURE_SET_REG = 0x92 | ||
GPIO2_FEATURE_SET_REG = 0x93 | ||
BATTERY_GAUGE_REG = 0xb9 | ||
VBUS_IPSOUT_CHANNEL_MANAGEMENT_REG = 0X30 | ||
|
||
# POWER_OPERATING_MODE_REG Bits: | ||
class POWER_OPERATING_STATUS_FLAGS(Union): | ||
class _b(BigEndianStructure): | ||
_fields_ = [ | ||
("over-temperature", c_uint8, 1), # instruct AXP209 Is it overheated? 0:Not too warm ; 1:Overtemperature | ||
("battery_charging", c_uint8, 1), # Charging instructions | ||
# 0:Not charging or charging completed ; 1:Charging | ||
("battery_exists", c_uint8, 1), # Battery presence status indication | ||
# 0:No battery connected to AXP209; 1:The battery is connected to AXP209 | ||
("_reserved_", c_uint8, 1), | ||
("battery_active", c_uint8, 1), # Indicates whether the battery has entered activation mode | ||
# 0:Not entering battery activation mode ; 1:Entered battery activation mode | ||
("reached_desired_charge_current", c_uint8, 1), # Indicates whether the charging current is less than the expected current | ||
# 0:The actual charging current is equal to the expected current ; 1:The actual charging current is less than the expected current | ||
("_reserved_", c_uint8, 2), | ||
] | ||
|
||
_fields_ = [("_b", _b), | ||
("asbyte", c_uint8)] | ||
|
||
_anonymous_ = ("_b",) | ||
|
||
class POWER_INPUT_STATUS_FLAGS(Union): | ||
class _b(BigEndianStructure): | ||
_fields_ = [ | ||
("acin_present", c_uint8, 1), | ||
("acin_available", c_uint8, 1), | ||
("vbus_present", c_uint8, 1), | ||
("vbus_available", c_uint8, 1), | ||
("vbus_direction", c_uint8, 1), | ||
("battery_current_direction", c_uint8, 1), # 1: charging, 0: discharging | ||
("acin_vbus_shorted", c_uint8, 1), | ||
("start_source", c_uint8, 1) | ||
] | ||
|
||
_fields_ = [("_b", _b), | ||
("asbyte", c_uint8)] | ||
|
||
_anonymous_ = ("_b",) | ||
|
||
|
||
class POWER_OPERATING_STATUS_FLAGS(Union): | ||
class _b(BigEndianStructure): | ||
_fields_ = [ | ||
("over-temperature", c_uint8, 1), | ||
("battery_charging", c_uint8, 1), # 1: charging, 0: not charging or charging done | ||
("battery_exists", c_uint8, 1), # 1: battery is connected, 0: not connected | ||
("_reserved_", c_uint8, 1), | ||
("battery_active", c_uint8, 1), | ||
("reached_desired_charge_current", c_uint8, 1), | ||
("_reserved_", c_uint8, 2), | ||
] | ||
|
||
_fields_ = [("_b", _b), | ||
("asbyte", c_uint8)] | ||
|
||
_anonymous_ = ("_b",) | ||
|
||
|
||
class GPIO012_FEATURE_SET_FLAGS(Union): | ||
class _b(BigEndianStructure): | ||
_fields_ = [ | ||
("gpio_rising_edge_interupt", c_uint8, 1), | ||
("gpio_falling_edge_interupt", c_uint8, 1), | ||
("_reserved_", c_uint8, 3), | ||
("gpio_function", c_uint8, 3), | ||
] | ||
|
||
_fields_ = [("_b", _b), | ||
("asbyte", c_uint8)] | ||
|
||
_anonymous_ = ("_b",) | ||
|
||
|
||
class VBUS_CURRENT_LIMIT_CONTROL(Union): | ||
class _b(BigEndianStructure): | ||
_fields_ = [ | ||
("vbus_available", c_uint8, 1), | ||
("hold_pressure_limiting", c_uint8, 1), | ||
("hold_set_up", c_uint8, 3), | ||
("_reserved_", c_uint8, 1), | ||
("vbus_current_limit", c_uint8, 2), | ||
] | ||
|
||
_fields_ = [("_b", _b), | ||
("asbyte", c_uint8)] | ||
|
||
_anonymous_ = ("_b",) | ||
|
||
class ADC_ENABLE1_FLAGS(Union): | ||
class _b(BigEndianStructure): | ||
_fields_ = [ | ||
("battery_voltage_adc_enable", c_uint8, 1), | ||
("battery_current_adc_enable", c_uint8, 1), | ||
("acin_voltage_adc_enable", c_uint8, 1), | ||
("acin_current_adc_enable", c_uint8, 1), | ||
("vbus_voltage_adc_enable", c_uint8, 1), | ||
("vbus_current_adc_enable", c_uint8, 1), | ||
("aps_voltage_adc_enable", c_uint8, 1), | ||
("ts_pin_adc_function_enable", c_uint8, 1), | ||
] | ||
|
||
_fields_ = [("_b", _b), | ||
("asbyte", c_uint8)] | ||
|
||
_anonymous_ = ("_b",) | ||
|
||
class ADC_ENABLE2_FLAGS(Union): | ||
class _b(BigEndianStructure): | ||
_fields_ = [ | ||
("apx209_internal_temperature_monitoring_adc_enable", c_uint8, 1), | ||
("_reserved_", c_uint8, 3), | ||
("gpio0_adc_function_enable", c_uint8, 1), | ||
("gpio1_adc_function_enable", c_uint8, 1), | ||
("_reserved_", c_uint8, 2), | ||
] | ||
|
||
_fields_ = [("_b", _b), | ||
("asbyte", c_uint8)] | ||
|
||
_anonymous_ = ("_b",) |
Oops, something went wrong.