#![warn(rust_2018_idioms)]
#![no_std]
use embedded_hal::i2c;
const AXP192_ADDRESS: u8 = 0x34;
pub struct Axp192<I2C> {
i2c: I2C,
}
pub enum GpioMode0 {
NmosOpenDrainOutput = 0b000,
UniversalInput = 0b001,
LowNoiseLdo = 0b010,
Keep = 0b011,
AdcEnter = 0b100,
LowOutput = 0b101,
Floating = 0b110,
}
pub enum GpioMode12 {
NmosOpenDrainOutput = 0b000,
UniversalInput = 0b001,
PWMOutput = 0b010,
Keep = 0b011,
AdcEnter = 0b100,
LowOutput = 0b101,
Floating = 0b110,
}
pub enum GpioMode34 {
ExternalChargeControl = 0b00,
NmosOpenDrainOutput = 0b01,
UniversalInput = 0b10,
AdcEnter = 0b11,
}
pub enum BootTime {
Boot128ms = 0b00,
Boot512ms = 0b01,
Boot1s = 0b10,
Boot2s = 0b11,
}
pub enum LongPress {
Lp1000ms = 0b00,
Lp1500ms = 0b01,
Lp2000ms = 0b10,
Lp2500ms = 0b11,
}
pub enum PowerOkDelay {
Delay32ms = 0b0,
Delay64ms = 0b1,
}
pub enum ShutdownDuration {
Sd4s = 0b00,
Sd6s = 0b01,
Sd8s = 0b10,
Sd10s = 0b11,
}
impl<I2C, E> Axp192<I2C>
where
I2C: i2c::I2c<Error = E>,
{
pub fn new(i2c: I2C) -> Self {
Self { i2c }
}
fn get(&mut self, reg_addr: u8, buff: &mut [u8]) -> Result<(), E> {
self.i2c.write_read(AXP192_ADDRESS, &[reg_addr], buff)
}
fn get_8(&mut self, reg_addr: u8) -> Result<u8, E> {
let mut buff = [0u8];
self.get(reg_addr, &mut buff)?;
Ok(buff[0])
}
fn get_12(&mut self, reg_addr: u8) -> Result<u16, E> {
let mut buff = [0; 2];
self.get(reg_addr, &mut buff)?;
Ok(((buff[0] as u16) << 4) + (buff[1] as u16))
}
fn get_13(&mut self, reg_addr: u8) -> Result<u16, E> {
let mut buff = [0; 2];
self.get(reg_addr, &mut buff)?;
Ok(((buff[0] as u16) << 5) + (buff[1] as u16))
}
fn get_flag(&mut self, reg_addr: u8, flag: u8) -> Result<bool, E> {
Ok(self.get_8(reg_addr)? & flag != 0)
}
fn set_8(&mut self, addr: u8, v: u8) -> Result<(), E> {
self.i2c.write(AXP192_ADDRESS, &[addr, v])
}
fn set_flag(&mut self, addr: u8, bit: u8, state: bool) -> Result<(), E> {
let mut v = self.get_8(addr)?;
if state {
v |= bit;
} else {
v &= !bit;
}
self.set_8(addr, v)
}
fn voltage_value(value: u16, min: u16, max: u16, step: u16) -> u8 {
let value = value.clamp(min, max);
((value - min) / step) as u8
}
pub fn get_power_status(&mut self) -> Result<u8, E> {
self.get_8(0x00)
}
pub fn get_charging(&mut self) -> Result<bool, E> {
self.get_flag(0x00, 0b0000_0100)
}
pub fn get_vbus_usable(&mut self) -> Result<bool, E> {
self.get_flag(0x00, 0b0001_0000)
}
pub fn get_vbus_present(&mut self) -> Result<bool, E> {
self.get_flag(0x00, 0b0010_0000)
}
pub fn get_acin_usable(&mut self) -> Result<bool, E> {
self.get_flag(0x00, 0b0100_0000)
}
pub fn get_acin_present(&mut self) -> Result<bool, E> {
self.get_flag(0x00, 0b1000_0000)
}
pub fn get_exten_on(&mut self) -> Result<bool, E> {
self.get_flag(0x10, 0b0000_0100)
}
pub fn set_exten_on(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x10, 0b0000_0100, state)
}
pub fn get_dcdc1_on(&mut self) -> Result<bool, E> {
self.get_flag(0x12, 0b0000_0001)
}
pub fn set_dcdc1_on(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x12, 0b0000_0001, state)
}
pub fn get_dcdc3_on(&mut self) -> Result<bool, E> {
self.get_flag(0x12, 0b0000_0010)
}
pub fn set_dcdc3_on(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x12, 0b0000_0010, state)
}
pub fn get_ldo2_on(&mut self) -> Result<bool, E> {
self.get_flag(0x12, 0b0000_0100)
}
pub fn set_ldo2_on(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x12, 0b0000_0100, state)
}
pub fn get_ldo3_on(&mut self) -> Result<bool, E> {
self.get_flag(0x12, 0b0000_1000)
}
pub fn set_ldo3_on(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x12, 0b0000_1000, state)
}
pub fn get_dcdc2_on(&mut self) -> Result<bool, E> {
self.get_flag(0x12, 0b0001_0000)
}
pub fn set_dcdc2_on(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x12, 0b0001_0000, state)
}
pub fn set_dcdc1_voltage(&mut self, voltage: u16) -> Result<(), E> {
let v = Self::voltage_value(voltage, 700, 3500, 25) & 0x7f;
self.set_8(0x26, v)
}
pub fn set_dcdc3_voltage(&mut self, voltage: u16) -> Result<(), E> {
let v = Self::voltage_value(voltage, 700, 3500, 25) & 0x7f;
self.set_8(0x27, v)
}
pub fn set_ldo3_voltage(&mut self, voltage: u16) -> Result<(), E> {
let v = Self::voltage_value(voltage, 1800, 3300, 100) & 0x0f;
let existing = self.get_8(0x28)?;
self.set_8(0x28, (existing & 0xf0) | v)
}
pub fn set_ldo2_voltage(&mut self, voltage: u16) -> Result<(), E> {
let v = Self::voltage_value(voltage, 1800, 3300, 100) & 0x0f;
let existing = self.get_8(0x28)?;
self.set_8(0x28, (existing & 0x0f) | (v << 4))
}
pub fn set_ipsout_always(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x30, 0b1000_0000, state)
}
pub fn set_key_mode(
&mut self,
shutdown_duration: ShutdownDuration,
powerok_delay: PowerOkDelay,
automatic_shutdown: bool,
longpress_duration: LongPress,
boot_time: BootTime,
) -> Result<(), E> {
let v = (shutdown_duration as u8)
| ((powerok_delay as u8) << 2)
| ((automatic_shutdown as u8) << 3)
| ((longpress_duration as u8) << 4)
| ((boot_time as u8) << 6);
self.set_8(0x36, v)
}
pub fn get_acin_voltage(&mut self) -> Result<f32, E> {
let v = self.get_12(0x56)?;
Ok(v as f32 * 0.0017)
}
pub fn get_acin_current(&mut self) -> Result<f32, E> {
let v = self.get_12(0x58)?;
Ok(v as f32 * 0.000625)
}
pub fn get_vbus_voltage(&mut self) -> Result<f32, E> {
let v = self.get_12(0x5a)?;
Ok(v as f32 * 0.0017)
}
pub fn get_vbus_current(&mut self) -> Result<f32, E> {
let v = self.get_12(0x5c)?;
Ok(v as f32 * 0.000375)
}
pub fn get_internal_temperature(&mut self) -> Result<f32, E> {
let v = self.get_12(0x5e)?;
Ok((v as f32 * 0.1) - 144.7)
}
pub fn get_battery_voltage(&mut self) -> Result<f32, E> {
let v = self.get_12(0x78)?;
Ok(v as f32 * 0.0011)
}
pub fn get_battery_charge_current(&mut self) -> Result<f32, E> {
let v = self.get_13(0x7a)?;
Ok(v as f32 * 0.0005)
}
pub fn get_battery_discharge_current(&mut self) -> Result<f32, E> {
let v = self.get_13(0x7c)?;
Ok(v as f32 * 0.0005)
}
pub fn set_ts_adc_enable(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x82, 0b0000_0001, state)
}
pub fn set_aps_voltage_adc_enable(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x82, 0b0000_0010, state)
}
pub fn set_vbus_current_adc_enable(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x82, 0b0000_0100, state)
}
pub fn set_vbus_voltage_adc_enable(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x82, 0b0000_1000, state)
}
pub fn set_acin_current_adc_enable(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x82, 0b0001_0000, state)
}
pub fn set_acin_voltage_adc_enable(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x82, 0b0010_0000, state)
}
pub fn set_battery_current_adc_enable(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x82, 0b0100_0000, state)
}
pub fn set_battery_voltage_adc_enable(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x82, 0b1000_0000, state)
}
pub fn set_gpio0_mode(&mut self, mode: GpioMode0) -> Result<(), E> {
self.set_8(0x90, mode as u8)
}
pub fn set_gpio0_ldo_voltage(&mut self, voltage: u16) -> Result<(), E> {
let v = Self::voltage_value(voltage, 1800, 3300, 100) << 4;
self.set_8(0x91, v)
}
pub fn set_gpio1_mode(&mut self, mode: GpioMode12) -> Result<(), E> {
self.set_8(0x92, mode as u8)
}
pub fn set_gpio2_mode(&mut self, mode: GpioMode12) -> Result<(), E> {
self.set_8(0x93, mode as u8)
}
pub fn set_gpio0_output(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x94, 0b0000_0001, state)
}
pub fn set_gpio1_output(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x94, 0b0000_0010, state)
}
pub fn set_gpio2_output(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x94, 0b0000_0100, state)
}
pub fn set_gpio3_mode(&mut self, mode: GpioMode34) -> Result<(), E> {
let existing = self.get_8(0x95)?;
self.set_8(0x95, (existing & 0b1111_1100) | 0x80 | (mode as u8))
}
pub fn set_gpio4_mode(&mut self, mode: GpioMode34) -> Result<(), E> {
let existing = self.get_8(0x95)?;
self.set_8(0x95, (existing & 0b1111_0011) | 0x80 | ((mode as u8) << 2))
}
pub fn set_gpio3_output(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x96, 0b0000_0001, state)
}
pub fn set_gpio4_output(&mut self, state: bool) -> Result<(), E> {
self.set_flag(0x96, 0b0000_0010, state)
}
}