MAX77658 Ultra-Low Power PMIC Mbed Driver
Diff: MAX77658.cpp
- Revision:
- 0:00d2a8670533
- Child:
- 1:40ef1dc30cb7
diff -r 000000000000 -r 00d2a8670533 MAX77658.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MAX77658.cpp Thu Jun 30 12:15:15 2022 +0300 @@ -0,0 +1,4057 @@ +/******************************************************************************* + * Copyright(C) Analog Devices Inc., All Rights Reserved. + * + * 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 MAXIM INTEGRATED 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. + * + * Except as contained in this notice, the name of Analog Devices Inc. + * shall not be used except as stated in the Analog Devices Inc. + * Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Analog Devices Inc.retains all ownership rights. + ******************************************************************************* + */ + +#include <Thread.h> +#include "MAX77658.h" +#include <math.h> + +#define POST_INTR_WORK_SIGNAL_ID 0x1 +#define TO_UINT8 0xFF +#define TO_UINT16 0xFFFF + +MAX77658::MAX77658(I2C *i2c, PinName IRQPin) +{ + if (i2c == NULL) + return; + + i2c_handler = i2c; + + if (IRQPin != NC) { + irq_disable_all(); + post_intr_work_thread = new Thread(); + post_intr_work_thread->start(Callback<void()>(this, &MAX77658::post_interrupt_work)); + + this->irq_pin = new InterruptIn(IRQPin); + this->irq_pin->fall(Callback<void()>(this, &MAX77658::interrupt_handler)); + this->irq_pin->enable_irq(); + } else { + this->irq_pin = NULL; + } +} + +MAX77658::~MAX77658() +{ + if (post_intr_work_thread) + delete post_intr_work_thread; + + if (irq_pin) + delete irq_pin; +} + +int MAX77658::read_register(uint8_t reg, uint8_t *value) +{ + int rtn_val; + + if (value == NULL) + return MAX77658_VALUE_NULL; + + rtn_val = i2c_handler->write(MAX77658_I2C_ADDRESS_PMIC_1, (const char *)®, 1, true); + if (rtn_val != 0) + return MAX77658_WRITE_DATA_FAILED; + + rtn_val = i2c_handler->read(MAX77658_I2C_ADDRESS_PMIC_1, (char *) value, 1, false); + if (rtn_val < 0) + return MAX77658_READ_DATA_FAILED; + + return MAX77658_NO_ERROR; +} + +int MAX77658::write_register(uint8_t reg, const uint8_t *value) +{ + int rtn_val; + unsigned char local_data[2]; + + if (value == NULL) + return MAX77658_VALUE_NULL; + + local_data[0] = reg; + + memcpy(&local_data[1], value, 1); + + rtn_val = i2c_handler->write(MAX77658_I2C_ADDRESS_PMIC_1, (const char *)local_data, sizeof(local_data)); + if (rtn_val != MAX77658_NO_ERROR) + return MAX77658_WRITE_DATA_FAILED; + + return MAX77658_NO_ERROR; +} + +int MAX77658::read_fg_register(uint8_t reg, uint8_t *value) +{ + int rtn_val; + + if (value == NULL) + return MAX77658_VALUE_NULL; + + rtn_val = i2c_handler->write(MAX77658_I2C_ADDRESS_FG, (const char *)®, 1, true); + if (rtn_val != 0) + return MAX77658_WRITE_DATA_FAILED; + + rtn_val = i2c_handler->read(MAX77658_I2C_ADDRESS_FG, (char *) value, 2, false); + if (rtn_val < 0) + return MAX77658_READ_DATA_FAILED; + + return MAX77658_NO_ERROR; +} + +int MAX77658::write_fg_register(uint8_t reg, const uint8_t *value) +{ + int rtn_val; + unsigned char local_data[3]; + + if (value == NULL) + return MAX77658_VALUE_NULL; + + local_data[0] = reg; + + memcpy(&local_data[1], value, 2); + + rtn_val = i2c_handler->write(MAX77658_I2C_ADDRESS_FG, (const char *)local_data, sizeof(local_data)); + if (rtn_val != MAX77658_NO_ERROR) + return MAX77658_WRITE_DATA_FAILED; + + return MAX77658_NO_ERROR; +} + +#define SET_BIT_FIELD(address, reg_name, bit_field_name, value) \ + int ret_val; \ + ret_val = read_register(address, (uint8_t *)&(reg_name)); \ + if (ret_val) { \ + return ret_val; \ + } \ + bit_field_name = value; \ + ret_val = write_register(address, (uint8_t *)&(reg_name)); \ + if (ret_val) { \ + return ret_val; \ + } + + + +#define SET_FG_BIT_FIELD(address, reg_name, bit_field_name, value) \ + int ret_val_fg; \ + ret_val_fg = read_fg_register(address, (uint8_t *)&(reg_name)); \ + if (ret_val_fg) { \ + return ret_val_fg; \ + } \ + bit_field_name = value; \ + ret_val_fg = write_fg_register(address, (uint8_t *)&(reg_name)); \ + if (ret_val_fg) { \ + return ret_val_fg; \ + } + +int MAX77658::get_ercflag(reg_bit_ercflag_t bit_field, uint8_t *flag) +{ + int ret; + reg_ercflag_t reg_ercflag; + + ret = read_register(ERCFLAG, (uint8_t *)&(reg_ercflag)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case ERCFLAG_TOVLD: + *flag = (uint8_t)reg_ercflag.bits.tovld; + break; + case ERCFLAG_SYSOVLO: + *flag = (uint8_t)reg_ercflag.bits.sysovlo; + break; + case ERCFLAG_SYSUVLO: + *flag = (uint8_t)reg_ercflag.bits.sysuvlo; + break; + case ERCFLAG_MRST_F: + *flag = (uint8_t)reg_ercflag.bits.mrst_f; + break; + case ERCFLAG_SFT_OFF_F: + *flag = (uint8_t)reg_ercflag.bits.sft_off_f; + break; + case ERCFLAG_SFT_CRST_F: + *flag = (uint8_t)reg_ercflag.bits.sft_crst_f; + break; + case ERCFLAG_WDT_OFF: + *flag = (uint8_t)reg_ercflag.bits.wdt_off; + break; + case ERCFLAG_WDT_RST: + *flag = (uint8_t)reg_ercflag.bits.wdt_rst; + break; + default: + ret = MAX77658_INVALID_DATA; + break; + } + + return ret; +} + +int MAX77658::get_stat_glbl(reg_bit_stat_glbl_t bit_field, uint8_t *status) +{ + int ret; + reg_stat_glbl_t reg_stat_glbl; + + ret = read_register(STAT_GLBL, (uint8_t *)&(reg_stat_glbl)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case STAT_GLBL_STAT_IRQ: + *status = (uint8_t)reg_stat_glbl.bits.stat_irq; + break; + case STAT_GLBL_STAT_EN: + *status = (uint8_t)reg_stat_glbl.bits.stat_en; + break; + case STAT_GLBL_TJAL1_S: + *status = (uint8_t)reg_stat_glbl.bits.tjal1_s; + break; + case STAT_GLBL_TJAL2_S: + *status = (uint8_t)reg_stat_glbl.bits.tjal2_s; + break; + case STAT_GLBL_DOD1_S: + *status = (uint8_t)reg_stat_glbl.bits.dod1_s; + break; + case STAT_GLBL_DOD0_S: + *status = (uint8_t)reg_stat_glbl.bits.dod0_s; + break; + case STAT_GLBL_BOK: + *status = (uint8_t)reg_stat_glbl.bits.bok; + break; + case STAT_GLBL_DIDM: + *status = (uint8_t)reg_stat_glbl.bits.didm; + break; + default: + ret = MAX77658_INVALID_DATA; + break; + } + + return ret; +} + +int MAX77658::set_interrupt_mask(reg_bit_int_mask_t bit_field, uint8_t maskBit) +{ + int ret; + uint8_t reg_addr; + reg_int_m_chg_t reg_int_m_chg; + reg_intm_glbl0_t reg_intm_glbl0; + reg_intm_glbl1_t reg_intm_glbl1; + + //INT_M_CHG (0x07), INTM_GLBL0 (0x08) and INTM_GLBL1 (0x09) + reg_addr = (uint8_t)floor((static_cast<uint8_t>(bit_field)) / 8) + 0x07; + + if (reg_addr == INT_M_CHG) + ret = read_register(INT_M_CHG, (uint8_t *)&(reg_int_m_chg)); + else if (reg_addr == INTM_GLBL0) + ret = read_register(INTM_GLBL0, (uint8_t *)&(reg_intm_glbl0)); + else if (reg_addr == INTM_GLBL1) + ret = read_register(INTM_GLBL1, (uint8_t *)&(reg_intm_glbl1)); + else + return MAX77658_INVALID_DATA; + + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case INT_M_CHG_THM_M: + reg_int_m_chg.bits.thm_m = maskBit; + break; + case INT_M_CHG_CHG_M: + reg_int_m_chg.bits.chg_m = maskBit; + break; + case INT_M_CHG_CHGIN_M: + reg_int_m_chg.bits.chgin_m = maskBit; + break; + case INT_M_CHG_TJ_REG_M: + reg_int_m_chg.bits.tj_reg_m = maskBit; + break; + case INT_M_CHG_CHGIN_CTRL_M: + reg_int_m_chg.bits.chgin_ctrl_m = maskBit; + break; + case INT_M_CHG_SYS_CTRL_M: + reg_int_m_chg.bits.sys_ctrl_m = maskBit; + break; + case INT_M_CHG_SYS_CNFG_M: + reg_int_m_chg.bits.sys_cnfg_m = maskBit; + break; + case INT_M_CHG_DIS_AICL: + reg_int_m_chg.bits.dis_aicl = maskBit; + break; + case INTM_GLBL0_GPI0_FM: + reg_intm_glbl0.bits.gpi0_fm = maskBit; + break; + case INTM_GLBL0_GPI0_RM: + reg_intm_glbl0.bits.gpi0_rm = maskBit; + break; + case INTM_GLBL0_nEN_FM: + reg_intm_glbl0.bits.nen_fm = maskBit; + break; + case INTM_GLBL0_nEN_RM: + reg_intm_glbl0.bits.nen_rm = maskBit; + break; + case INTM_GLBL0_TJAL1_RM: + reg_intm_glbl0.bits.tjal1_rm = maskBit; + break; + case INTM_GLBL0_TJAL2_RM: + reg_intm_glbl0.bits.tjal2_rm = maskBit; + break; + case INTM_GLBL0_DOD1_RM: + reg_intm_glbl0.bits.dod1_rm = maskBit; + break; + case INTM_GLBL0_DOD0_RM: + reg_intm_glbl0.bits.dod0_rm = maskBit; + break; + case INTM_GLBL1_GPI1_FM: + reg_intm_glbl1.bits.gpi1_fm = maskBit; + break; + case INTM_GLBL1_GPI1_RM: + reg_intm_glbl1.bits.gpi1_rm = maskBit; + break; + case INTM_GLBL1_SBB0_FM: + reg_intm_glbl1.bits.sbb0_fm = maskBit; + break; + case INTM_GLBL1_SBB1_FM: + reg_intm_glbl1.bits.sbb1_fm = maskBit; + break; + case INTM_GLBL1_SBB2_FM: + reg_intm_glbl1.bits.sbb2_fm = maskBit; + break; + case INTM_GLBL1_LDO0_M: + reg_intm_glbl1.bits.ldo0_m = maskBit; + break; + case INTM_GLBL1_LDO1_M: + reg_intm_glbl1.bits.ldo1_m = maskBit; + break; + case INTM_GLBL1_RSVD: + reg_intm_glbl1.bits.rsvd = maskBit; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + if (reg_addr == INT_M_CHG) + return write_register(INT_M_CHG, (uint8_t *)&(reg_int_m_chg)); + else if (reg_addr == INTM_GLBL0) + return write_register(INTM_GLBL0, (uint8_t *)&(reg_intm_glbl0)); + else if (reg_addr == INTM_GLBL1) + return write_register(INTM_GLBL1, (uint8_t *)&(reg_intm_glbl1)); + else + return MAX77658_INVALID_DATA; +} + +int MAX77658::get_interrupt_mask(reg_bit_int_mask_t bit_field, uint8_t *maskBit) +{ + int ret; + uint8_t reg_addr; + reg_int_m_chg_t reg_int_m_chg; + reg_intm_glbl0_t reg_intm_glbl0; + reg_intm_glbl1_t reg_intm_glbl1; + + //INT_M_CHG (0x07), INTM_GLBL0 (0x08) and INTM_GLBL1 (0x09) + reg_addr = (uint8_t)floor((static_cast<uint8_t>(bit_field)) / 8) + 0x07; + + if (reg_addr == INT_M_CHG) + ret = read_register(INT_M_CHG, (uint8_t *)&(reg_int_m_chg)); + else if (reg_addr == INTM_GLBL0) + ret = read_register(INTM_GLBL0, (uint8_t *)&(reg_intm_glbl0)); + else if (reg_addr == INTM_GLBL1) + ret = read_register(INTM_GLBL1, (uint8_t *)&(reg_intm_glbl1)); + else + return MAX77658_INVALID_DATA; + + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case INT_M_CHG_THM_M: + *maskBit = (uint8_t)reg_int_m_chg.bits.thm_m; + break; + case INT_M_CHG_CHG_M: + *maskBit = (uint8_t)reg_int_m_chg.bits.chg_m; + break; + case INT_M_CHG_CHGIN_M: + *maskBit = (uint8_t)reg_int_m_chg.bits.chgin_m; + break; + case INT_M_CHG_TJ_REG_M: + *maskBit = (uint8_t)reg_int_m_chg.bits.tj_reg_m; + break; + case INT_M_CHG_CHGIN_CTRL_M: + *maskBit = (uint8_t)reg_int_m_chg.bits.chgin_ctrl_m; + break; + case INT_M_CHG_SYS_CTRL_M: + *maskBit = (uint8_t)reg_int_m_chg.bits.sys_ctrl_m; + break; + case INT_M_CHG_SYS_CNFG_M: + *maskBit = (uint8_t)reg_int_m_chg.bits.sys_cnfg_m; + break; + case INT_M_CHG_DIS_AICL: + *maskBit = (uint8_t)reg_int_m_chg.bits.dis_aicl; + break; + case INTM_GLBL0_GPI0_FM: + *maskBit = (uint8_t)reg_intm_glbl0.bits.gpi0_fm; + break; + case INTM_GLBL0_GPI0_RM: + *maskBit = (uint8_t)reg_intm_glbl0.bits.gpi0_rm; + break; + case INTM_GLBL0_nEN_FM: + *maskBit = (uint8_t)reg_intm_glbl0.bits.nen_fm; + break; + case INTM_GLBL0_nEN_RM: + *maskBit = (uint8_t)reg_intm_glbl0.bits.nen_rm; + break; + case INTM_GLBL0_TJAL1_RM: + *maskBit = (uint8_t)reg_intm_glbl0.bits.tjal1_rm; + break; + case INTM_GLBL0_TJAL2_RM: + *maskBit = (uint8_t)reg_intm_glbl0.bits.tjal2_rm; + break; + case INTM_GLBL0_DOD1_RM: + *maskBit = (uint8_t)reg_intm_glbl0.bits.dod1_rm; + break; + case INTM_GLBL0_DOD0_RM: + *maskBit = (uint8_t)reg_intm_glbl0.bits.dod0_rm; + break; + case INTM_GLBL1_GPI1_FM: + *maskBit = (uint8_t)reg_intm_glbl1.bits.gpi1_fm; + break; + case INTM_GLBL1_GPI1_RM: + *maskBit = (uint8_t)reg_intm_glbl1.bits.gpi1_rm; + break; + case INTM_GLBL1_SBB0_FM: + *maskBit = (uint8_t)reg_intm_glbl1.bits.sbb0_fm; + break; + case INTM_GLBL1_SBB1_FM: + *maskBit = (uint8_t)reg_intm_glbl1.bits.sbb1_fm; + break; + case INTM_GLBL1_SBB2_FM: + *maskBit = (uint8_t)reg_intm_glbl1.bits.sbb2_fm; + break; + case INTM_GLBL1_LDO0_M: + *maskBit = (uint8_t)reg_intm_glbl1.bits.ldo0_m; + break; + case INTM_GLBL1_LDO1_M: + *maskBit = (uint8_t)reg_intm_glbl1.bits.ldo1_m; + break; + case INTM_GLBL1_RSVD: + *maskBit = (uint8_t)reg_intm_glbl1.bits.rsvd; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_cnfg_glbl(reg_bit_cnfg_glbl_t bit_field, uint8_t config) +{ + int ret; + reg_cnfg_glbl_t reg_cnfg_glbl; + + ret = read_register(CNFG_GLBL, (uint8_t *)&(reg_cnfg_glbl)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_GLBL_SFT_CTRL: + reg_cnfg_glbl.bits.sft_ctrl = config; + break; + case CNFG_GLBL_DBEN_nEN: + reg_cnfg_glbl.bits.dben_nen = config; + break; + case CNFG_GLBL_nEN_MODE: + reg_cnfg_glbl.bits.nen_mode = config; + break; + case CNFG_GLBL_SBIA_LPM: + reg_cnfg_glbl.bits.sbia_lpm = config; + break; + case CNFG_GLBL_T_MRST: + reg_cnfg_glbl.bits.t_mrst = config; + break; + case CNFG_GLBL_PU_DIS: + reg_cnfg_glbl.bits.pu_dis = config; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_register(CNFG_GLBL, (uint8_t *)&(reg_cnfg_glbl)); +} + +int MAX77658::get_cnfg_glbl(reg_bit_cnfg_glbl_t bit_field, uint8_t *config) +{ + int ret; + reg_cnfg_glbl_t reg_cnfg_glbl; + + ret = read_register(CNFG_GLBL, (uint8_t *)&(reg_cnfg_glbl)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_GLBL_SFT_CTRL: + *config = (uint8_t)reg_cnfg_glbl.bits.sft_ctrl; + break; + case CNFG_GLBL_DBEN_nEN: + *config = (uint8_t)reg_cnfg_glbl.bits.dben_nen; + break; + case CNFG_GLBL_nEN_MODE: + *config = (uint8_t)reg_cnfg_glbl.bits.nen_mode; + break; + case CNFG_GLBL_SBIA_LPM: + *config = (uint8_t)reg_cnfg_glbl.bits.sbia_lpm; + break; + case CNFG_GLBL_T_MRST: + *config = (uint8_t)reg_cnfg_glbl.bits.t_mrst; + break; + case CNFG_GLBL_PU_DIS: + *config = (uint8_t)reg_cnfg_glbl.bits.pu_dis; + break; + default: + ret = MAX77658_INVALID_DATA; + break; + } + + return ret; +} + +int MAX77658::set_cnfg_gpio(reg_bit_cnfg_gpio_t bit_field, uint8_t channel, uint8_t config) +{ + int ret; + reg_cnfg_gpio0_t reg_cnfg_gpio0; + reg_cnfg_gpio1_t reg_cnfg_gpio1; + reg_cnfg_gpio2_t reg_cnfg_gpio2; + + if (channel == 0) + { + ret = read_register(CNFG_GPIO0, (uint8_t *)&(reg_cnfg_gpio0)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_GPIO_DIR: + reg_cnfg_gpio0.bits.gpo_dir = config; + break; + case CNFG_GPIO_DI: + reg_cnfg_gpio0.bits.gpo_di = config; + break; + case CNFG_GPIO_DRV: + reg_cnfg_gpio0.bits.gpo_drv = config; + break; + case CNFG_GPIO_DO: + reg_cnfg_gpio0.bits.gpo_do = config; + break; + case CNFG_GPIO_DBEN_GPI: + reg_cnfg_gpio0.bits.dben_gpi = config; + break; + case CNFG_GPIO_ALT_GPIO: + reg_cnfg_gpio0.bits.alt_gpio = config; + break; + case CNFG_GPIO_RSVD: + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_register(CNFG_GPIO0, (uint8_t *)&(reg_cnfg_gpio0)); + } + else if (channel == 1) + { + ret = read_register(CNFG_GPIO1, (uint8_t *)&(reg_cnfg_gpio1)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_GPIO_DIR: + reg_cnfg_gpio1.bits.gpo_dir = config; + break; + case CNFG_GPIO_DI: + reg_cnfg_gpio1.bits.gpo_di = config; + break; + case CNFG_GPIO_DRV: + reg_cnfg_gpio1.bits.gpo_drv = config; + break; + case CNFG_GPIO_DO: + reg_cnfg_gpio1.bits.gpo_do = config; + break; + case CNFG_GPIO_DBEN_GPI: + reg_cnfg_gpio1.bits.dben_gpi = config; + break; + case CNFG_GPIO_ALT_GPIO: + reg_cnfg_gpio1.bits.alt_gpio = config; + break; + case CNFG_GPIO_RSVD: + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_register(CNFG_GPIO1, (uint8_t *)&(reg_cnfg_gpio1)); + } + else if (channel == 2) + { + ret = read_register(CNFG_GPIO2, (uint8_t *)&(reg_cnfg_gpio2)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_GPIO_DIR: + reg_cnfg_gpio2.bits.gpo_dir = config; + break; + case CNFG_GPIO_DI: + reg_cnfg_gpio2.bits.gpo_di = config; + break; + case CNFG_GPIO_DRV: + reg_cnfg_gpio2.bits.gpo_drv = config; + break; + case CNFG_GPIO_DO: + reg_cnfg_gpio2.bits.gpo_do = config; + break; + case CNFG_GPIO_DBEN_GPI: + reg_cnfg_gpio2.bits.dben_gpi = config; + break; + case CNFG_GPIO_ALT_GPIO: + reg_cnfg_gpio2.bits.alt_gpio = config; + break; + case CNFG_GPIO_RSVD: + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_register(CNFG_GPIO2, (uint8_t *)&(reg_cnfg_gpio2)); + } + else { + return MAX77658_INVALID_DATA; + } +} + +int MAX77658::get_cnfg_gpio(reg_bit_cnfg_gpio_t bit_field, uint8_t channel, uint8_t *config) +{ + int ret; + reg_cnfg_gpio0_t reg_cnfg_gpio0; + reg_cnfg_gpio1_t reg_cnfg_gpio1; + reg_cnfg_gpio2_t reg_cnfg_gpio2; + + if (channel == 0) + { + ret = read_register(CNFG_GPIO0, (uint8_t *)&(reg_cnfg_gpio0)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_GPIO_DIR: + *config = (uint8_t)reg_cnfg_gpio0.bits.gpo_dir; + break; + case CNFG_GPIO_DI: + *config = (uint8_t)reg_cnfg_gpio0.bits.gpo_di; + break; + case CNFG_GPIO_DRV: + *config = (uint8_t)reg_cnfg_gpio0.bits.gpo_drv; + break; + case CNFG_GPIO_DO: + *config = (uint8_t)reg_cnfg_gpio0.bits.gpo_do; + break; + case CNFG_GPIO_DBEN_GPI: + *config = (uint8_t)reg_cnfg_gpio0.bits.dben_gpi; + break; + case CNFG_GPIO_ALT_GPIO: + *config = (uint8_t)reg_cnfg_gpio0.bits.alt_gpio; + break; + case CNFG_GPIO_RSVD: + default: + return MAX77658_INVALID_DATA; + break; + } + } + else if (channel == 1) + { + ret = read_register(CNFG_GPIO1, (uint8_t *)&(reg_cnfg_gpio1)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_GPIO_DIR: + *config = (uint8_t)reg_cnfg_gpio1.bits.gpo_dir; + break; + case CNFG_GPIO_DI: + *config = (uint8_t)reg_cnfg_gpio1.bits.gpo_di; + break; + case CNFG_GPIO_DRV: + *config = (uint8_t)reg_cnfg_gpio1.bits.gpo_drv; + break; + case CNFG_GPIO_DO: + *config = (uint8_t)reg_cnfg_gpio1.bits.gpo_do; + break; + case CNFG_GPIO_DBEN_GPI: + *config = (uint8_t)reg_cnfg_gpio1.bits.dben_gpi; + break; + case CNFG_GPIO_ALT_GPIO: + *config = (uint8_t)reg_cnfg_gpio1.bits.alt_gpio; + break; + case CNFG_GPIO_RSVD: + default: + return MAX77658_INVALID_DATA; + break; + } + } + else if (channel == 2) + { + ret = read_register(CNFG_GPIO2, (uint8_t *)&(reg_cnfg_gpio2)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_GPIO_DIR: + *config = (uint8_t)reg_cnfg_gpio2.bits.gpo_dir; + break; + case CNFG_GPIO_DI: + *config = (uint8_t)reg_cnfg_gpio2.bits.gpo_di; + break; + case CNFG_GPIO_DRV: + *config = (uint8_t)reg_cnfg_gpio2.bits.gpo_drv; + break; + case CNFG_GPIO_DO: + *config = (uint8_t)reg_cnfg_gpio2.bits.gpo_do; + break; + case CNFG_GPIO_DBEN_GPI: + *config = (uint8_t)reg_cnfg_gpio2.bits.dben_gpi; + break; + case CNFG_GPIO_ALT_GPIO: + *config = (uint8_t)reg_cnfg_gpio2.bits.alt_gpio; + break; + case CNFG_GPIO_RSVD: + default: + return MAX77658_INVALID_DATA; + break; + } + } + else { + return MAX77658_INVALID_DATA; + } + + return ret; +} + +int MAX77658::get_cid(void) { + char rbuf[1]; + int ret; + + ret = read_register(CID, (uint8_t *)&(rbuf)); + if (ret != MAX77658_NO_ERROR) return ret; + + return *rbuf; +} + +int MAX77658::set_cnfg_wdt(reg_bit_cnfg_wdt_t bit_field, uint8_t config) +{ + int ret; + reg_cnfg_wdt_t reg_cnfg_wdt; + + ret = read_register(CNFG_WDT, (uint8_t *)&(reg_cnfg_wdt)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_WDT_WDT_LOCK: + reg_cnfg_wdt.bits.wdt_lock = config; + break; + case CNFG_WDT_WDT_EN: + reg_cnfg_wdt.bits.wdt_en = config; + break; + case CNFG_WDT_WDT_CLR: + reg_cnfg_wdt.bits.wdt_clr = config; + break; + case CNFG_WDT_WDT_MODE: + reg_cnfg_wdt.bits.wdt_mode = config; + break; + case CNFG_WDT_WDT_PER: + reg_cnfg_wdt.bits.wdt_per = config; + break; + case CNFG_WDT_RSVD: + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_register(CNFG_WDT, (uint8_t *)&(reg_cnfg_wdt)); +} + +int MAX77658::get_cnfg_wdt(reg_bit_cnfg_wdt_t bit_field, uint8_t *config) +{ + int ret; + reg_cnfg_wdt_t reg_cnfg_wdt; + + ret = read_register(CNFG_WDT, (uint8_t *)&(reg_cnfg_wdt)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_WDT_WDT_LOCK: + *config = (uint8_t)reg_cnfg_wdt.bits.wdt_lock; + break; + case CNFG_WDT_WDT_EN: + *config = (uint8_t)reg_cnfg_wdt.bits.wdt_en; + break; + case CNFG_WDT_WDT_CLR: + *config = (uint8_t)reg_cnfg_wdt.bits.wdt_clr; + break; + case CNFG_WDT_WDT_MODE: + *config = (uint8_t)reg_cnfg_wdt.bits.wdt_mode; + break; + case CNFG_WDT_WDT_PER: + *config = (uint8_t)reg_cnfg_wdt.bits.wdt_per; + break; + case CNFG_WDT_RSVD: + default: + return MAX77658_INVALID_DATA; + break; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_stat_chg_a(reg_bit_stat_chg_a_t bit_field, uint8_t *status) +{ + int ret; + reg_stat_chg_a_t reg_stat_chg_a; + + ret = read_register(STAT_CHG_A, (uint8_t *)&(reg_stat_chg_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case STAT_CHG_A_THM_DTLS: + *status = (uint8_t)reg_stat_chg_a.bits.thm_dtls; + break; + case STAT_CHG_A_TJ_REG_STAT: + *status = (uint8_t)reg_stat_chg_a.bits.tj_reg_stat; + break; + case STAT_CHG_A_VSYS_MIN_STAT: + *status = (uint8_t)reg_stat_chg_a.bits.vsys_min_stat; + break; + case STAT_CHG_A_ICHGIN_LIM_STAT: + *status = (uint8_t)reg_stat_chg_a.bits.ichgin_lim_stat; + break; + case STAT_CHG_A_VCHGIN_MIN_STAT: + *status = (uint8_t)reg_stat_chg_a.bits.vchgin_min_stat; + break; + case STAT_CHG_A_RSVD: + default: + return MAX77658_INVALID_DATA; + break; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_thm_dtls(decode_thm_dtls_t *thm_dtls) +{ + int ret; + reg_stat_chg_a_t reg_stat_chg_a; + + ret = read_register(STAT_CHG_A, (uint8_t *)&(reg_stat_chg_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + *thm_dtls = (decode_thm_dtls_t)reg_stat_chg_a.bits.thm_dtls; + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_stat_chg_b(reg_bit_stat_chg_b_t bit_field, uint8_t *status) +{ + int ret; + reg_stat_chg_b_t reg_stat_chg_b; + + ret = read_register(STAT_CHG_B, (uint8_t *)&(reg_stat_chg_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case STAT_CHG_B_TIME_SUS: + *status = (uint8_t)reg_stat_chg_b.bits.time_sus; + break; + case STAT_CHG_B_CHG: + *status = (uint8_t)reg_stat_chg_b.bits.chg; + break; + case STAT_CHG_B_CHGIN_DTLS: + *status = (uint8_t)reg_stat_chg_b.bits.chgin_dtls; + break; + case STAT_CHG_B_CHG_DTLS: + *status = (uint8_t)reg_stat_chg_b.bits.chg_dtls; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_chg_dtls(decode_chg_dtls_t *chg_dtls) +{ + int ret; + reg_stat_chg_b_t reg_stat_chg_b; + + ret = read_register(STAT_CHG_B, (uint8_t *)&(reg_stat_chg_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *chg_dtls = (decode_chg_dtls_t)reg_stat_chg_b.bits.chg_dtls; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_thm_hot(int tempDegC) +{ + uint8_t value; + reg_cnfg_chg_a_t reg_cnfg_chg_a; + + if (tempDegC < 45) tempDegC = 45; + else if (tempDegC > 60) tempDegC = 60; + + value = (tempDegC - 45) / 5; + + SET_BIT_FIELD(CNFG_CHG_A, reg_cnfg_chg_a, reg_cnfg_chg_a.bits.thm_hot, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_thm_hot(int *tempDegC) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_a_t reg_cnfg_chg_a; + + ret = read_register(CNFG_CHG_A, (uint8_t *)&(reg_cnfg_chg_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_a.bits.thm_hot; + if (bit_value <= 3) + *tempDegC = (bit_value * 5) + 45; + else + return MAX77658_INVALID_DATA; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_thm_warm(int tempDegC) +{ + uint8_t value; + reg_cnfg_chg_a_t reg_cnfg_chg_a; + + if (tempDegC < 35) tempDegC = 35; + else if (tempDegC > 50) tempDegC = 50; + + value = (tempDegC - 35) / 5; + + SET_BIT_FIELD(CNFG_CHG_A, reg_cnfg_chg_a, reg_cnfg_chg_a.bits.thm_warm, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_thm_warm(int *tempDegC) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_a_t reg_cnfg_chg_a; + + ret = read_register(CNFG_CHG_A, (uint8_t *)&(reg_cnfg_chg_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_a.bits.thm_warm; + if (bit_value <= 3) + *tempDegC = (bit_value * 5) + 35; + else + return MAX77658_INVALID_DATA; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_thm_cool(int tempDegC) +{ + uint8_t value; + reg_cnfg_chg_a_t reg_cnfg_chg_a; + + if (tempDegC < 0) tempDegC = 0; + else if (tempDegC > 15) tempDegC = 15; + + value = tempDegC / 5; + + SET_BIT_FIELD(CNFG_CHG_A, reg_cnfg_chg_a, reg_cnfg_chg_a.bits.thm_cool, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_thm_cool(int *tempDegC) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_a_t reg_cnfg_chg_a; + + ret = read_register(CNFG_CHG_A, (uint8_t *)&(reg_cnfg_chg_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_a.bits.thm_cool; + if (bit_value <= 3) + *tempDegC = bit_value * 5; + else + return MAX77658_INVALID_DATA; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_thm_cold(int tempDegC) +{ + uint8_t value; + reg_cnfg_chg_a_t reg_cnfg_chg_a; + + if (tempDegC < -10) tempDegC = -10; + else if (tempDegC > 5) tempDegC = 5; + + value = (tempDegC + 10) / 5; + + SET_BIT_FIELD(CNFG_CHG_A, reg_cnfg_chg_a, reg_cnfg_chg_a.bits.thm_cold, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_thm_cold(int *tempDegC) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_a_t reg_cnfg_chg_a; + + ret = read_register(CNFG_CHG_A, (uint8_t *)&(reg_cnfg_chg_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_a.bits.thm_cold; + if (bit_value <= 3) + *tempDegC = (bit_value * 5) - 10; + else + return MAX77658_INVALID_DATA; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_cnfg_chg_b(reg_bit_cnfg_chg_b_t bit_field, uint8_t config) +{ + int ret; + reg_cnfg_chg_b_t reg_cnfg_chg_b; + + ret = read_register(CNFG_CHG_B, (uint8_t *)&(reg_cnfg_chg_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_CHG_B_CHG_EN: + reg_cnfg_chg_b.bits.chg_en = config; + break; + case CNFG_CHG_B_I_PQ: + reg_cnfg_chg_b.bits.i_pq = config; + break; + case CNFG_CHG_B_ICHGIN_LIM: + reg_cnfg_chg_b.bits.ichgin_lim = config; + break; + case CNFG_CHG_B_VCHGIN_MIN: + reg_cnfg_chg_b.bits.vchgin_min = config; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_register(CNFG_CHG_B, (uint8_t *)&(reg_cnfg_chg_b)); +} + +int MAX77658::get_cnfg_chg_b(reg_bit_cnfg_chg_b_t bit_field, uint8_t *config) +{ + int ret; + reg_cnfg_chg_b_t reg_cnfg_chg_b; + + ret = read_register(CNFG_CHG_B, (uint8_t *)&(reg_cnfg_chg_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_CHG_B_CHG_EN: + *config = (uint8_t)reg_cnfg_chg_b.bits.chg_en; + break; + case CNFG_CHG_B_I_PQ: + *config = (uint8_t)reg_cnfg_chg_b.bits.i_pq; + break; + case CNFG_CHG_B_ICHGIN_LIM: + *config = (uint8_t)reg_cnfg_chg_b.bits.ichgin_lim; + break; + case CNFG_CHG_B_VCHGIN_MIN: + *config = (uint8_t)reg_cnfg_chg_b.bits.vchgin_min; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_vchgin_min(float voltV) +{ + uint8_t value; + reg_cnfg_chg_b_t reg_cnfg_chg_b; + float voltmV = voltV * 1000; + + if (voltmV < 4000) voltmV = 4000; + else if (voltmV > 4700) voltmV = 4700; + + value = (voltmV - 4000) / 100; + + SET_BIT_FIELD(CNFG_CHG_B, reg_cnfg_chg_b, reg_cnfg_chg_b.bits.vchgin_min, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_vchgin_min(float *voltV) +{ + int ret; + uint8_t value; + reg_cnfg_chg_b_t reg_cnfg_chg_b; + + ret = read_register(CNFG_CHG_B, (uint8_t *)&(reg_cnfg_chg_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + value = (uint8_t)reg_cnfg_chg_b.bits.vchgin_min; + *voltV = (float)(value * 0.1f) + 4.0f; + return MAX77658_NO_ERROR; +} + +int MAX77658::set_ichgin_lim(int currentmA) +{ + uint8_t value; + reg_cnfg_chg_b_t reg_cnfg_chg_b; + + if (currentmA < 95) currentmA = 95; + else if (currentmA > 475) currentmA = 475; + + value = (currentmA - 95) / 95; + + SET_BIT_FIELD(CNFG_CHG_B, reg_cnfg_chg_b, reg_cnfg_chg_b.bits.ichgin_lim, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_ichgin_lim(int *currentmA) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_b_t reg_cnfg_chg_b; + + ret = read_register(CNFG_CHG_B, (uint8_t *)&(reg_cnfg_chg_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_b.bits.ichgin_lim; + *currentmA = (bit_value * 95) + 95; + return MAX77658_NO_ERROR; +} + +int MAX77658::set_chg_pq(float voltV) +{ + uint8_t value; + reg_cnfg_chg_c_t reg_cnfg_chg_c; + float voltmV = voltV * 1000; + + if (voltmV < 2300) voltmV = 2300; + else if (voltmV > 3000) voltmV = 3000; + + value = (voltmV - 2300) / 100; + + SET_BIT_FIELD(CNFG_CHG_C, reg_cnfg_chg_c, reg_cnfg_chg_c.bits.chg_pq, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_chg_pq(float *voltV) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_c_t reg_cnfg_chg_c; + + ret = read_register(CNFG_CHG_C, (uint8_t *)&(reg_cnfg_chg_c)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_c.bits.chg_pq; + *voltV = (bit_value * 0.1f) + 2.3f; + return MAX77658_NO_ERROR; +} + +int MAX77658::set_i_term(float percent) +{ + uint8_t value; + reg_cnfg_chg_c_t reg_cnfg_chg_c; + + if (percent < 7.5f) value = 0; + else if ((percent >= 7.5f) && (percent < 10)) value = 1; + else if ((percent >= 10) && (percent < 15)) value = 2; + else if (percent >= 15) value = 3; + + SET_BIT_FIELD(CNFG_CHG_C, reg_cnfg_chg_c, reg_cnfg_chg_c.bits.i_term, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_i_term(float *percent) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_c_t reg_cnfg_chg_c; + + ret = read_register(CNFG_CHG_C, (uint8_t *)&(reg_cnfg_chg_c)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_c.bits.i_term; + + if (bit_value == 0) *percent = 5.0f; + else if (bit_value == 1) *percent = 7.5f; + else if (bit_value == 2) *percent = 10.0f; + else if (bit_value == 3) *percent = 15.0f; + else return MAX77658_INVALID_DATA; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_t_topoff(uint8_t minute) +{ + uint8_t value; + reg_cnfg_chg_c_t reg_cnfg_chg_c; + + if (minute > 35) minute = 35; + + value = (uint8_t)(minute / 5); + + SET_BIT_FIELD(CNFG_CHG_C, reg_cnfg_chg_c, reg_cnfg_chg_c.bits.t_topoff, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_t_topoff(uint8_t *minute) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_c_t reg_cnfg_chg_c; + + ret = read_register(CNFG_CHG_C, (uint8_t *)&(reg_cnfg_chg_c)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_c.bits.t_topoff; + *minute = (bit_value * 5); + return MAX77658_NO_ERROR; +} + +int MAX77658::set_tj_reg(uint8_t tempDegC) +{ + uint8_t value; + reg_cnfg_chg_d_t reg_cnfg_chg_d; + + if (tempDegC < 60) tempDegC = 60; + else if (tempDegC > 100) tempDegC = 100; + + value = (tempDegC - 60) / 10; + + SET_BIT_FIELD(CNFG_CHG_D, reg_cnfg_chg_d, reg_cnfg_chg_d.bits.tj_reg, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_tj_reg(uint8_t *tempDegC) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_d_t reg_cnfg_chg_d; + + ret = read_register(CNFG_CHG_D, (uint8_t *)&(reg_cnfg_chg_d)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_d.bits.tj_reg; + *tempDegC = (bit_value * 10) + 60; + return MAX77658_NO_ERROR; +} + +int MAX77658::set_vsys_reg(float voltV) +{ + uint8_t value; + reg_cnfg_chg_d_t reg_cnfg_chg_d; + float voltmV = voltV * 1000; + + if (voltmV < 3300) voltmV = 3300; + else if (voltmV > 4800) voltmV = 4800; + + value = (voltmV - 3300) / 50; + + SET_BIT_FIELD(CNFG_CHG_D, reg_cnfg_chg_d, reg_cnfg_chg_d.bits.vsys_reg, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_vsys_reg(float *voltV) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_d_t reg_cnfg_chg_d; + + ret = read_register(CNFG_CHG_D, (uint8_t *)&(reg_cnfg_chg_d)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_d.bits.vsys_reg; + *voltV = (bit_value * 0.05f) + 3.3f; + return MAX77658_NO_ERROR; +} + +int MAX77658::set_chg_cc(float currentmA) +{ + uint8_t value; + reg_cnfg_chg_e_t reg_cnfg_chg_e; + float currentuA = currentmA * 1000; + + if (currentuA < 7500) currentuA = 7500; + if (currentuA > 300000) currentuA = 300000; + + value = (currentuA - 7500) / 7500; + + SET_BIT_FIELD(CNFG_CHG_E, reg_cnfg_chg_e, reg_cnfg_chg_e.bits.chg_cc, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_chg_cc(float *currentmA) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_e_t reg_cnfg_chg_e; + + ret = read_register(CNFG_CHG_E, (uint8_t *)&(reg_cnfg_chg_e)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_e.bits.chg_cc; + if (bit_value >= 39) bit_value = 39; //0x27 to 0x3F = 300.0mA + + *currentmA = (bit_value * 7.5f) + 7.5f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_t_fast_chg(decode_t_fast_chg_t t_fast_chg) +{ + reg_cnfg_chg_e_t reg_cnfg_chg_e; + + SET_BIT_FIELD(CNFG_CHG_E, reg_cnfg_chg_e, reg_cnfg_chg_e.bits.t_fast_chg, t_fast_chg); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_t_fast_chg(decode_t_fast_chg_t *t_fast_chg) +{ + int ret; + reg_cnfg_chg_e_t reg_cnfg_chg_e; + + ret = read_register(CNFG_CHG_E, (uint8_t *)&(reg_cnfg_chg_e)); + if (ret != MAX77658_NO_ERROR) return ret; + + *t_fast_chg = (decode_t_fast_chg_t)reg_cnfg_chg_e.bits.t_fast_chg; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_chg_cc_jeita(float currentmA) +{ + uint8_t value; + reg_cnfg_chg_f_t reg_cnfg_chg_f; + float currentuA = currentmA * 1000; + + if (currentuA < 7500) currentuA = 7500; + else if (currentuA > 300000) currentuA = 300000; + + value = round(currentuA - 7500) / 7500; + + SET_BIT_FIELD(CNFG_CHG_F, reg_cnfg_chg_f, reg_cnfg_chg_f.bits.chg_cc_jeita, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_chg_cc_jeita(float *currentmA) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_f_t reg_cnfg_chg_f; + + ret = read_register(CNFG_CHG_F, (uint8_t *)&(reg_cnfg_chg_f)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_f.bits.chg_cc_jeita; + if (bit_value >= 39) bit_value = 39; //0x27 to 0x3F = 300.0mA + + *currentmA = (bit_value * 7.5f) + 7.5f; + return MAX77658_NO_ERROR; +} + +int MAX77658::set_cnfg_chg_g(reg_bit_cnfg_chg_g_t bit_field, uint8_t config) +{ + int ret; + reg_cnfg_chg_g_t reg_cnfg_chg_g; + + ret = read_register(CNFG_CHG_G, (uint8_t *)&(reg_cnfg_chg_g)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_CHG_G_FUS_M: + reg_cnfg_chg_g.bits.fus_m = config; + break; + case CNFG_CHG_G_USBS: + reg_cnfg_chg_g.bits.usbs = config; + break; + case CNFG_CHG_G_CHG_CV: + reg_cnfg_chg_g.bits.chg_cv = config; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_register(CNFG_CHG_G, (uint8_t *)&(reg_cnfg_chg_g)); +} + +int MAX77658::get_cnfg_chg_g(reg_bit_cnfg_chg_g_t bit_field, uint8_t *config) +{ + int ret; + reg_cnfg_chg_g_t reg_cnfg_chg_g; + + ret = read_register(CNFG_CHG_G, (uint8_t *)&(reg_cnfg_chg_g)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_CHG_G_FUS_M: + *config = (uint8_t)reg_cnfg_chg_g.bits.fus_m; + break; + case CNFG_CHG_G_USBS: + *config = (uint8_t)reg_cnfg_chg_g.bits.usbs; + break; + case CNFG_CHG_G_CHG_CV: + *config = (uint8_t)reg_cnfg_chg_g.bits.chg_cv; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_chg_cv(float voltV) +{ + uint8_t value; + reg_cnfg_chg_g_t reg_cnfg_chg_g; + float voltmV = voltV * 1000; + + if (voltmV < 3600) voltmV = 3600; + else if (voltmV > 4600) voltmV = 4600; + + value = (voltmV - 3600) / 25; + + SET_BIT_FIELD(CNFG_CHG_G, reg_cnfg_chg_g, reg_cnfg_chg_g.bits.chg_cv, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_chg_cv(float *voltV) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_g_t reg_cnfg_chg_g; + + ret = read_register(CNFG_CHG_G, (uint8_t *)&(reg_cnfg_chg_g)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_g.bits.chg_cv; + *voltV = (bit_value * 0.025f) + 3.6f; + return MAX77658_NO_ERROR; +} + +int MAX77658::set_cnfg_chg_h(reg_bit_cnfg_chg_h_t bit_field, uint8_t config) +{ + int ret; + reg_cnfg_chg_h_t reg_cnfg_chg_h; + + ret = read_register(CNFG_CHG_H, (uint8_t *)&(reg_cnfg_chg_h)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_CHG_H_CHR_TH_DIS: + reg_cnfg_chg_h.bits.chr_th_dis = config; + break; + case CNFG_CHG_H_SYS_BAT_PRT: + reg_cnfg_chg_h.bits.sys_bat_prt = config; + break; + case CNFG_CHG_H_CHG_CV_JEITA: + reg_cnfg_chg_h.bits.chg_cv_jeita = config; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_register(CNFG_CHG_H, (uint8_t *)&(reg_cnfg_chg_h)); +} + +int MAX77658::get_cnfg_chg_h(reg_bit_cnfg_chg_h_t bit_field, uint8_t *config) +{ + int ret; + reg_cnfg_chg_h_t reg_cnfg_chg_h; + + ret = read_register(CNFG_CHG_H, (uint8_t *)&(reg_cnfg_chg_h)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_CHG_H_CHR_TH_DIS: + *config = (uint8_t)reg_cnfg_chg_h.bits.chr_th_dis; + break; + case CNFG_CHG_H_SYS_BAT_PRT: + *config = (uint8_t)reg_cnfg_chg_h.bits.sys_bat_prt; + break; + case CNFG_CHG_H_CHG_CV_JEITA: + *config = (uint8_t)reg_cnfg_chg_h.bits.chg_cv_jeita; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_chg_cv_jeita(float voltV) +{ + uint8_t value; + reg_cnfg_chg_h_t reg_cnfg_chg_h; + float voltmV = voltV * 1000; + + if (voltmV < 3600) voltmV = 3600; + else if (voltmV > 4600) voltmV = 4600; + + value = round(voltmV - 3600) / 25; + + SET_BIT_FIELD(CNFG_CHG_H, reg_cnfg_chg_h, reg_cnfg_chg_h.bits.chg_cv_jeita, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_chg_cv_jeita(float *voltV) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_h_t reg_cnfg_chg_h; + + ret = read_register(CNFG_CHG_H, (uint8_t *)&(reg_cnfg_chg_h)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_chg_h.bits.chg_cv_jeita; + *voltV = (bit_value * 0.025f) + 3.6f; + return MAX77658_NO_ERROR; +} + +int MAX77658::set_imon_dischg_scale(float currentmA) +{ + uint8_t value; + reg_cnfg_chg_i_t reg_cnfg_chg_i; + + if (currentmA < 40.5f) value = 0; + else if ((currentmA >= 40.5f) && (currentmA < 72.3f)) value = 1; + else if ((currentmA >= 72.3f) && (currentmA < 103.4f)) value = 2; + else if ((currentmA >= 103.4f) && (currentmA < 134.1f)) value = 3; + else if ((currentmA >= 134.1f) && (currentmA < 164.1f)) value = 4; + else if ((currentmA >= 164.1f) && (currentmA < 193.7f)) value = 5; + else if ((currentmA >= 193.7f) && (currentmA < 222.7f)) value = 6; + else if ((currentmA >= 222.7f) && (currentmA < 251.2f)) value = 7; + else if ((currentmA >= 251.2f) && (currentmA < 279.3f)) value = 8; + else if ((currentmA >= 279.3f) && (currentmA < 300.0f)) value = 9; + else if (currentmA >= 300.0f) value = 10; + + SET_BIT_FIELD(CNFG_CHG_I, reg_cnfg_chg_i, reg_cnfg_chg_i.bits.imon_dischg_scale, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_imon_dischg_scale(float *currentmA) +{ + int ret; + uint8_t bit_value; + reg_cnfg_chg_i_t reg_cnfg_chg_i; + + ret = read_register(CNFG_CHG_I, (uint8_t *)&(reg_cnfg_chg_i)); + if (ret != MAX77658_NO_ERROR) { + return ret; + } + + bit_value = (uint8_t)reg_cnfg_chg_i.bits.imon_dischg_scale; + + if (bit_value == 0) *currentmA = 8.2f; + else if (bit_value == 1) *currentmA = 40.5f; + else if (bit_value == 2) *currentmA = 72.3f; + else if (bit_value == 3) *currentmA = 103.4f; + else if (bit_value == 4) *currentmA = 134.1f; + else if (bit_value == 5) *currentmA = 164.1f; + else if (bit_value == 6) *currentmA = 193.7f; + else if (bit_value == 7) *currentmA = 222.7f; + else if (bit_value == 8) *currentmA = 251.2f; + else if (bit_value == 9) *currentmA = 279.3f; + else *currentmA = 300.0f; //0xA to 0xF = 300.0mA + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_mux_sel(decode_mux_sel_t selection) +{ + reg_cnfg_chg_i_t reg_cnfg_chg_i; + + SET_BIT_FIELD(CNFG_CHG_I, reg_cnfg_chg_i, reg_cnfg_chg_i.bits.mux_sel, selection); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_mux_sel(decode_mux_sel_t *selection) +{ + int ret; + reg_cnfg_chg_i_t reg_cnfg_chg_i; + + ret = read_register(CNFG_CHG_I, (uint8_t *)&(reg_cnfg_chg_i)); + if (ret != MAX77658_NO_ERROR) return ret; + + *selection = (decode_mux_sel_t)reg_cnfg_chg_i.bits.mux_sel; + return MAX77658_NO_ERROR; +} + +int MAX77658::set_cnfg_sbb_top(reg_bit_cnfg_sbb_top_t bit_field, uint8_t config) +{ + int ret; + reg_cnfg_sbb_top_t reg_cnfg_sbb_top; + + ret = read_register(CNFG_SBB_TOP, (uint8_t *)&(reg_cnfg_sbb_top)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_SBB_TOP_DRV_SBB: + reg_cnfg_sbb_top.bits.drv_sbb = config; + break; + case CNFG_SBB_TOP_DIS_LPM: + reg_cnfg_sbb_top.bits.dis_lpm = config; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_register(CNFG_SBB_TOP, (uint8_t *)&(reg_cnfg_sbb_top)); +} + +int MAX77658::get_cnfg_sbb_top(reg_bit_cnfg_sbb_top_t bit_field, uint8_t *config) +{ + int ret; + reg_cnfg_sbb_top_t reg_cnfg_sbb_top; + + ret = read_register(CNFG_SBB_TOP, (uint8_t *)&(reg_cnfg_sbb_top)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case CNFG_SBB_TOP_DRV_SBB: + *config = (uint8_t)reg_cnfg_sbb_top.bits.drv_sbb; + break; + case CNFG_SBB_TOP_DIS_LPM: + *config = (uint8_t)reg_cnfg_sbb_top.bits.dis_lpm; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_tv_sbb_a(uint8_t channel, float voltV) +{ + uint8_t value; + reg_cnfg_sbb0_a_t reg_cnfg_sbb0_a; + reg_cnfg_sbb1_a_t reg_cnfg_sbb1_a; + reg_cnfg_sbb2_a_t reg_cnfg_sbb2_a; + float voltmV = voltV * 1000; + + if (voltmV < 500) voltmV = 500; + else if (voltmV > 5500) voltmV = 5500; + + value = (voltmV - 500) / 25; + + if (channel == 0) { + SET_BIT_FIELD(CNFG_SBB0_A, reg_cnfg_sbb0_a, reg_cnfg_sbb0_a.bits.tv_sbb0, value); + } + else if (channel == 1) { + SET_BIT_FIELD(CNFG_SBB1_A, reg_cnfg_sbb1_a, reg_cnfg_sbb1_a.bits.tv_sbb1, value); + } + else if (channel == 2) { + SET_BIT_FIELD(CNFG_SBB2_A, reg_cnfg_sbb2_a, reg_cnfg_sbb2_a.bits.tv_sbb2, value); + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_tv_sbb_a(uint8_t channel, float *voltV) +{ + int ret; + uint8_t bit_value; + reg_cnfg_sbb0_a_t reg_cnfg_sbb0_a; + reg_cnfg_sbb1_a_t reg_cnfg_sbb1_a; + reg_cnfg_sbb2_a_t reg_cnfg_sbb2_a; + + if (channel == 0) { + ret = read_register(CNFG_SBB0_A, (uint8_t *)&(reg_cnfg_sbb0_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_sbb0_a.bits.tv_sbb0; + } + else if (channel == 1) { + ret = read_register(CNFG_SBB1_A, (uint8_t *)&(reg_cnfg_sbb1_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_sbb1_a.bits.tv_sbb1; + } + else if (channel == 2) { + ret = read_register(CNFG_SBB2_A, (uint8_t *)&(reg_cnfg_sbb2_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_sbb2_a.bits.tv_sbb2; + } + else return MAX77658_INVALID_DATA; + + if (bit_value > 200) bit_value = 200; + *voltV = (bit_value * 0.025f) + 0.5f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_op_mode(uint8_t channel, decode_op_mode_t mode) +{ + reg_cnfg_sbb0_b_t reg_cnfg_sbb0_b; + reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b; + reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b; + + if (channel == 0) { + SET_BIT_FIELD(CNFG_SBB0_B, reg_cnfg_sbb0_b, reg_cnfg_sbb0_b.bits.op_mode0, mode); + } + else if (channel == 1) { + SET_BIT_FIELD(CNFG_SBB1_B, reg_cnfg_sbb1_b, reg_cnfg_sbb1_b.bits.op_mode1, mode); + } + else if (channel == 2) { + SET_BIT_FIELD(CNFG_SBB2_B, reg_cnfg_sbb2_b, reg_cnfg_sbb2_b.bits.op_mode2, mode); + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_op_mode(uint8_t channel, decode_op_mode_t *mode) +{ + int ret; + reg_cnfg_sbb0_b_t reg_cnfg_sbb0_b; + reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b; + reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b; + + if (channel == 0) { + ret = read_register(CNFG_SBB0_B, (uint8_t *)&(reg_cnfg_sbb0_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *mode = (decode_op_mode_t)reg_cnfg_sbb0_b.bits.op_mode0; + } + else if (channel == 1) { + ret = read_register(CNFG_SBB1_B, (uint8_t *)&(reg_cnfg_sbb1_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *mode = (decode_op_mode_t)reg_cnfg_sbb1_b.bits.op_mode1; + } + else if (channel == 2) { + ret = read_register(CNFG_SBB2_B, (uint8_t *)&(reg_cnfg_sbb2_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *mode = (decode_op_mode_t)reg_cnfg_sbb2_b.bits.op_mode2; + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_ip_sbb(uint8_t channel, decode_ip_sbb_t ip_sbb) +{ + reg_cnfg_sbb0_b_t reg_cnfg_sbb0_b; + reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b; + reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b; + + if (channel == 0) { + SET_BIT_FIELD(CNFG_SBB0_B, reg_cnfg_sbb0_b, reg_cnfg_sbb0_b.bits.ip_sbb0, ip_sbb); + } + else if (channel == 1) { + SET_BIT_FIELD(CNFG_SBB1_B, reg_cnfg_sbb1_b, reg_cnfg_sbb1_b.bits.ip_sbb1, ip_sbb); + } + else if (channel == 2) { + SET_BIT_FIELD(CNFG_SBB2_B, reg_cnfg_sbb2_b, reg_cnfg_sbb2_b.bits.ip_sbb2, ip_sbb); + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_ip_sbb(uint8_t channel, decode_ip_sbb_t *ip_sbb) +{ + int ret; + reg_cnfg_sbb0_b_t reg_cnfg_sbb0_b; + reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b; + reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b; + + if (channel == 0) { + ret = read_register(CNFG_SBB0_B, (uint8_t *)&(reg_cnfg_sbb0_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *ip_sbb = (decode_ip_sbb_t)reg_cnfg_sbb0_b.bits.ip_sbb0; + } + else if (channel == 1) { + ret = read_register(CNFG_SBB1_B, (uint8_t *)&(reg_cnfg_sbb1_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *ip_sbb = (decode_ip_sbb_t)reg_cnfg_sbb1_b.bits.ip_sbb1; + } + else if (channel == 2) { + ret = read_register(CNFG_SBB2_B, (uint8_t *)&(reg_cnfg_sbb2_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *ip_sbb = (decode_ip_sbb_t)reg_cnfg_sbb2_b.bits.ip_sbb2; + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_ade_sbb(uint8_t channel, decode_ade_sbb_t ade_sbb) +{ + reg_cnfg_sbb0_b_t reg_cnfg_sbb0_b; + reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b; + reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b; + + if (channel == 0) { + SET_BIT_FIELD(CNFG_SBB0_B, reg_cnfg_sbb0_b, reg_cnfg_sbb0_b.bits.ade_sbb0, ade_sbb); + } + else if (channel == 1) { + SET_BIT_FIELD(CNFG_SBB1_B, reg_cnfg_sbb1_b, reg_cnfg_sbb1_b.bits.ade_sbb1, ade_sbb); + } + else if (channel == 2) { + SET_BIT_FIELD(CNFG_SBB2_B, reg_cnfg_sbb2_b, reg_cnfg_sbb2_b.bits.ade_sbb2, ade_sbb); + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_ade_sbb(uint8_t channel, decode_ade_sbb_t *ade_sbb) +{ + int ret; + reg_cnfg_sbb0_b_t reg_cnfg_sbb0_b; + reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b; + reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b; + + if (channel == 0) { + ret = read_register(CNFG_SBB0_B, (uint8_t *)&(reg_cnfg_sbb0_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *ade_sbb = (decode_ade_sbb_t)reg_cnfg_sbb0_b.bits.ade_sbb0; + } + else if (channel == 1) { + ret = read_register(CNFG_SBB1_B, (uint8_t *)&(reg_cnfg_sbb1_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *ade_sbb = (decode_ade_sbb_t)reg_cnfg_sbb1_b.bits.ade_sbb1; + } + else if (channel == 2) { + ret = read_register(CNFG_SBB2_B, (uint8_t *)&(reg_cnfg_sbb2_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *ade_sbb = (decode_ade_sbb_t)reg_cnfg_sbb2_b.bits.ade_sbb2; + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_en_sbb(uint8_t channel, decode_en_sbb_t en_sbb) +{ + reg_cnfg_sbb0_b_t reg_cnfg_sbb0_b; + reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b; + reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b; + + if (channel == 0) { + SET_BIT_FIELD(CNFG_SBB0_B, reg_cnfg_sbb0_b, reg_cnfg_sbb0_b.bits.en_sbb0, en_sbb); + } + else if (channel == 1) { + SET_BIT_FIELD(CNFG_SBB1_B, reg_cnfg_sbb1_b, reg_cnfg_sbb1_b.bits.en_sbb1, en_sbb); + } + else if (channel == 2) { + SET_BIT_FIELD(CNFG_SBB2_B, reg_cnfg_sbb2_b, reg_cnfg_sbb2_b.bits.en_sbb2, en_sbb); + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_en_sbb(uint8_t channel, decode_en_sbb_t *en_sbb) +{ + int ret; + reg_cnfg_sbb0_b_t reg_cnfg_sbb0_b; + reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b; + reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b; + + if (channel == 0) { + ret = read_register(CNFG_SBB0_B, (uint8_t *)&(reg_cnfg_sbb0_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *en_sbb = (decode_en_sbb_t)reg_cnfg_sbb0_b.bits.en_sbb0; + } + else if (channel == 1) { + ret = read_register(CNFG_SBB1_B, (uint8_t *)&(reg_cnfg_sbb1_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *en_sbb = (decode_en_sbb_t)reg_cnfg_sbb1_b.bits.en_sbb1; + } + else if (channel == 2) { + ret = read_register(CNFG_SBB2_B, (uint8_t *)&(reg_cnfg_sbb2_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *en_sbb = (decode_en_sbb_t)reg_cnfg_sbb2_b.bits.en_sbb2; + } + else return MAX77658_INVALID_DATA; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_tv_sbb_dvs(float voltV) +{ + uint8_t value; + reg_cnfg_dvs_sbb0_a_t reg_cnfg_dvs_sbb0_a; + float voltmV = voltV * 1000; + + if (voltmV < 500) voltmV = 500; + else if (voltmV > 5500) voltmV = 5500; + + value = (voltmV - 500) / 25; + + SET_BIT_FIELD(CNFG_DVS_SBB0_A, reg_cnfg_dvs_sbb0_a, reg_cnfg_dvs_sbb0_a.bits.tv_sbb0_dvs, value); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_tv_sbb_dvs(float *voltV) +{ + int ret; + uint8_t bit_value; + reg_cnfg_dvs_sbb0_a_t reg_cnfg_dvs_sbb0_a; + + ret = read_register(CNFG_DVS_SBB0_A, (uint8_t *)&(reg_cnfg_dvs_sbb0_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_dvs_sbb0_a.bits.tv_sbb0_dvs; + + if (bit_value > 200) bit_value = 200; + + *voltV = (bit_value * 0.025f) + 0.5f; + return MAX77658_NO_ERROR; +} + +int MAX77658::set_tv_ldo_volt_a(uint8_t channel, float voltV) +{ + int ret; + uint8_t value; + reg_cnfg_ldo0_a_t reg_cnfg_ldo0_a; + reg_cnfg_ldo1_a_t reg_cnfg_ldo1_a; + float voltmV = voltV * 1000; + + if (channel == 0) { + ret = read_register(CNFG_LDO0_A, (uint8_t *)&(reg_cnfg_ldo0_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + if ((uint8_t)reg_cnfg_ldo0_a.bits.tv_ldo0_7 == 0) { //No Offset + if (voltmV < 500) voltmV = 500; + else if (voltmV > 3675) voltmV = 3675; + + value = (voltmV - 500) / 25; + } + else { //1.325V Offset + if (voltmV < 1825) voltmV = 1825; + else if (voltmV > 5000) voltmV = 5000; + + value = (voltmV - 1825) / 25; + } + + SET_BIT_FIELD(CNFG_LDO0_A, reg_cnfg_ldo0_a, reg_cnfg_ldo0_a.bits.tv_ldo0_6_0, value); + } + else { + ret = read_register(CNFG_LDO1_A, (uint8_t *)&(reg_cnfg_ldo1_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + if ((uint8_t)reg_cnfg_ldo1_a.bits.tv_ldo1_7 == 0) { //No Offset + if (voltmV < 500) voltmV = 500; + else if (voltmV > 3675) voltmV = 3675; + + value = (voltmV - 500) / 25; + } + else { //1.325V Offset + if (voltmV < 1825) voltmV = 1825; + else if (voltmV > 5000) voltmV = 5000; + + value = (voltmV - 1825) / 25; + } + + SET_BIT_FIELD(CNFG_LDO1_A, reg_cnfg_ldo1_a, reg_cnfg_ldo1_a.bits.tv_ldo1_6_0, value); + } + return MAX77658_NO_ERROR; +} + +int MAX77658::get_tv_ldo_volt_a(uint8_t channel, float *voltV) +{ + int ret; + uint8_t bit_value; + reg_cnfg_ldo0_a_t reg_cnfg_ldo0_a; + reg_cnfg_ldo1_a_t reg_cnfg_ldo1_a; + + if (channel == 0){ + ret = read_register(CNFG_LDO0_A, (uint8_t *)&(reg_cnfg_ldo0_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_ldo0_a.bits.tv_ldo0_6_0; + if ((uint8_t)reg_cnfg_ldo0_a.bits.tv_ldo0_7 == 0) //No Offset + *voltV = (bit_value * 0.025f) + 0.5f; + else //1.325V Offset + *voltV = (bit_value * 0.025f) + 1.825f; + } + else { + ret = read_register(CNFG_LDO1_A, (uint8_t *)&(reg_cnfg_ldo1_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + bit_value = (uint8_t)reg_cnfg_ldo1_a.bits.tv_ldo1_6_0; + if ((uint8_t)reg_cnfg_ldo1_a.bits.tv_ldo1_7 == 0) //No Offset + *voltV = (bit_value * 0.025f) + 0.5f; + else //1.325V Offset + *voltV = (bit_value * 0.025f) + 1.825f; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_tv_ldo_offset_a(uint8_t channel, decode_tv_ldo_offset_a_t offset) +{ + reg_cnfg_ldo0_a_t reg_cnfg_ldo0_a; + reg_cnfg_ldo1_a_t reg_cnfg_ldo1_a; + + if (channel == 0) { + SET_BIT_FIELD(CNFG_LDO0_A, reg_cnfg_ldo0_a, reg_cnfg_ldo0_a.bits.tv_ldo0_7, offset); + } + else if (channel == 1) { + SET_BIT_FIELD(CNFG_LDO1_A, reg_cnfg_ldo1_a, reg_cnfg_ldo1_a.bits.tv_ldo1_7, offset); + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_tv_ldo_offset_a(uint8_t channel, decode_tv_ldo_offset_a_t *offset) +{ + int ret; + reg_cnfg_ldo0_a_t reg_cnfg_ldo0_a; + reg_cnfg_ldo1_a_t reg_cnfg_ldo1_a; + + if (channel == 0) { + ret = read_register(CNFG_LDO0_A, (uint8_t *)&(reg_cnfg_ldo0_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + *offset = (decode_tv_ldo_offset_a_t)reg_cnfg_ldo0_a.bits.tv_ldo0_7; + } + else if (channel == 1) { + ret = read_register(CNFG_LDO1_A, (uint8_t *)&(reg_cnfg_ldo1_a)); + if (ret != MAX77658_NO_ERROR) return ret; + + *offset = (decode_tv_ldo_offset_a_t)reg_cnfg_ldo1_a.bits.tv_ldo1_7; + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_en_ldo(uint8_t channel, decode_en_ldo_t en_ldo) +{ + reg_cnfg_ldo0_b_t reg_cnfg_ldo0_b; + reg_cnfg_ldo1_b_t reg_cnfg_ldo1_b; + + if (channel == 0) { + SET_BIT_FIELD(CNFG_LDO0_B, reg_cnfg_ldo0_b, reg_cnfg_ldo0_b.bits.en_ldo0, en_ldo); + } + else if (channel == 1) { + SET_BIT_FIELD(CNFG_LDO1_B, reg_cnfg_ldo1_b, reg_cnfg_ldo1_b.bits.en_ldo1, en_ldo); + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_en_ldo(uint8_t channel, decode_en_ldo_t *en_ldo) +{ + int ret; + reg_cnfg_ldo0_b_t reg_cnfg_ldo0_b; + reg_cnfg_ldo1_b_t reg_cnfg_ldo1_b; + + if (channel == 0) { + ret = read_register(CNFG_LDO0_B, (uint8_t *)&(reg_cnfg_ldo0_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *en_ldo = (decode_en_ldo_t)reg_cnfg_ldo0_b.bits.en_ldo0; + } + else if (channel == 1) { + ret = read_register(CNFG_LDO1_B, (uint8_t *)&(reg_cnfg_ldo1_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *en_ldo = (decode_en_ldo_t)reg_cnfg_ldo1_b.bits.en_ldo1; + } + else return MAX77658_INVALID_DATA; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_ade_ldo(uint8_t channel, decode_ade_ldo_t ade_ldo) +{ + reg_cnfg_ldo0_b_t reg_cnfg_ldo0_b; + reg_cnfg_ldo1_b_t reg_cnfg_ldo1_b; + + if (channel == 0) { + SET_BIT_FIELD(CNFG_LDO0_B, reg_cnfg_ldo0_b, reg_cnfg_ldo0_b.bits.ade_ldo0, ade_ldo); + } + else if (channel == 1) { + SET_BIT_FIELD(CNFG_LDO1_B, reg_cnfg_ldo1_b, reg_cnfg_ldo1_b.bits.ade_ldo1, ade_ldo); + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_ade_ldo(uint8_t channel, decode_ade_ldo_t *ade_ldo) +{ + int ret; + reg_cnfg_ldo0_b_t reg_cnfg_ldo0_b; + reg_cnfg_ldo1_b_t reg_cnfg_ldo1_b; + + if (channel == 0) { + ret = read_register(CNFG_LDO0_B, (uint8_t *)&(reg_cnfg_ldo0_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *ade_ldo = (decode_ade_ldo_t)reg_cnfg_ldo0_b.bits.ade_ldo0; + } + else if (channel == 1) { + ret = read_register(CNFG_LDO1_B, (uint8_t *)&(reg_cnfg_ldo1_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *ade_ldo = (decode_ade_ldo_t)reg_cnfg_ldo1_b.bits.ade_ldo1; + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_ldo_md(uint8_t channel, decode_ldo_md_t mode) +{ + reg_cnfg_ldo0_b_t reg_cnfg_ldo0_b; + reg_cnfg_ldo1_b_t reg_cnfg_ldo1_b; + + if (channel == 0) { + SET_BIT_FIELD(CNFG_LDO0_B, reg_cnfg_ldo0_b, reg_cnfg_ldo0_b.bits.ldo0_md, mode); + } + else if (channel == 1) { + SET_BIT_FIELD(CNFG_LDO1_B, reg_cnfg_ldo1_b, reg_cnfg_ldo1_b.bits.ldo1_md, mode); + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_ldo_md(uint8_t channel, decode_ldo_md_t *mode) +{ + int ret; + reg_cnfg_ldo0_b_t reg_cnfg_ldo0_b; + reg_cnfg_ldo1_b_t reg_cnfg_ldo1_b; + + if (channel == 0) { + ret = read_register(CNFG_LDO0_B, (uint8_t *)&(reg_cnfg_ldo0_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *mode = (decode_ldo_md_t)reg_cnfg_ldo0_b.bits.ldo0_md; + } + else if (channel == 1) { + ret = read_register(CNFG_LDO1_B, (uint8_t *)&(reg_cnfg_ldo1_b)); + if (ret != MAX77658_NO_ERROR) return ret; + + *mode = (decode_ldo_md_t)reg_cnfg_ldo1_b.bits.ldo1_md; + } + else { + return MAX77658_INVALID_DATA; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_status(reg_bit_status_t bit_field, uint8_t status) +{ + int ret; + reg_status_t reg_status; + + ret = read_fg_register(Status, (uint8_t *)&(reg_status)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case Status_Imn: + reg_status.bits.imn = status; + break; + case Status_POR: + reg_status.bits.por = status; + break; + case Status_SPR_2: + reg_status.bits.spr_2 = status; + break; + case Status_Bst: + reg_status.bits.bst = status; + break; + case Status_Isysmx: + reg_status.bits.isysmx = status; + break; + case Status_SPR_5: + reg_status.bits.spr_5 = status; + break; + case Status_ThmHot: + reg_status.bits.thmhot = status; + break; + case Status_dSOCi: + reg_status.bits.dsoci = status; + break; + case Status_Vmn: + reg_status.bits.vmn = status; + break; + case Status_Tmn: + reg_status.bits.tmn = status; + break; + case Status_Smn: + reg_status.bits.smn = status; + break; + case Status_Bi: + reg_status.bits.bi = status; + break; + case Status_Vmx: + reg_status.bits.vmx = status; + break; + case Status_Tmx: + reg_status.bits.tmx = status; + break; + case Status_Smx: + reg_status.bits.smx = status; + break; + case Status_Br: + reg_status.bits.br = status; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_fg_register(Status, (uint8_t *)&(reg_status)); +} + +int MAX77658::get_fg_status(reg_bit_status_t bit_field, uint8_t *status) +{ + int ret; + reg_status_t reg_status; + + ret = read_fg_register(Status, (uint8_t *)&(reg_status)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case Status_Imn: + *status = (uint8_t)reg_status.bits.imn; + break; + case Status_POR: + *status = (uint8_t)reg_status.bits.por; + break; + case Status_SPR_2: + *status = (uint8_t)reg_status.bits.spr_2; + break; + case Status_Bst: + *status = (uint8_t)reg_status.bits.bst; + break; + case Status_Isysmx: + *status = (uint8_t)reg_status.bits.isysmx; + break; + case Status_SPR_5: + *status = (uint8_t)reg_status.bits.spr_5; + break; + case Status_ThmHot: + *status = (uint8_t)reg_status.bits.thmhot; + break; + case Status_dSOCi: + *status = (uint8_t)reg_status.bits.dsoci; + break; + case Status_Vmn: + *status = (uint8_t)reg_status.bits.vmn; + break; + case Status_Tmn: + *status = (uint8_t)reg_status.bits.tmn; + break; + case Status_Smn: + *status = (uint8_t)reg_status.bits.smn; + break; + case Status_Bi: + *status = (uint8_t)reg_status.bits.bi; + break; + case Status_Vmx: + *status = (uint8_t)reg_status.bits.vmx; + break; + case Status_Tmx: + *status = (uint8_t)reg_status.bits.tmx; + break; + case Status_Smx: + *status = (uint8_t)reg_status.bits.smx; + break; + case Status_Br: + *status = (uint8_t)reg_status.bits.br; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_valrt_th(reg_bit_valrt_th_t bit_field, float voltV) +{ + int ret; + uint8_t voltRaw; + reg_valrt_th_t reg_valrt_th; + float voltmV = voltV * 1000; + + ret = read_fg_register(VAlrtTh, (uint8_t *)&(reg_valrt_th)); + if (ret != MAX77658_NO_ERROR) return ret; + + //20mV resolution + voltRaw = (int)(voltmV / 20) & TO_UINT8; + + switch (bit_field) + { + case VAlrtTh_MinVoltageAlrt: + reg_valrt_th.bits.min_voltage_alrt = voltRaw; + break; + case VAlrtTh_MaxVoltageAlrt: + reg_valrt_th.bits.max_voltage_alrt = voltRaw; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_fg_register(VAlrtTh, (uint8_t *)&(reg_valrt_th)); +} + +int MAX77658::get_fg_valrt_th(reg_bit_valrt_th_t bit_field, float *voltV) +{ + int ret; + int8_t voltSigned; + reg_valrt_th_t reg_valrt_th; + + ret = read_fg_register(VAlrtTh, (uint8_t *)&(reg_valrt_th)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case VAlrtTh_MinVoltageAlrt: + voltSigned = (int8_t)reg_valrt_th.bits.min_voltage_alrt; + break; + case VAlrtTh_MaxVoltageAlrt: + voltSigned = (int8_t)reg_valrt_th.bits.max_voltage_alrt; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + //20mV resolution + *voltV = (float)((voltSigned * 20.0f) / 1000.0f); + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_talrt_th(reg_bit_talrt_th_t bit_field, int tempDegC) +{ + int ret; + uint8_t tempRaw; + reg_talrt_th_t reg_talrt_th; + + ret = read_fg_register(TAlrtTh, (uint8_t *)&(reg_talrt_th)); + if (ret != MAX77658_NO_ERROR) return ret; + + //1°C resolution + tempRaw = tempDegC & TO_UINT8; + + switch (bit_field) + { + case TAlrtTh_MinTempAlrt: + if(tempRaw < 128) tempRaw = 128; + reg_talrt_th.bits.min_temp_alrt = tempRaw; + break; + case TAlrtTh_MaxTempAlrt: + if(tempRaw > 127) tempRaw = 127; + reg_talrt_th.bits.max_temp_alrt = tempRaw; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_fg_register(TAlrtTh, (uint8_t *)&(reg_talrt_th)); +} + +int MAX77658::get_fg_talrt_th(reg_bit_talrt_th_t bit_field, int *tempDegC) +{ + int ret, tempSigned; + reg_talrt_th_t reg_talrt_th; + + ret = read_fg_register(TAlrtTh, (uint8_t *)&(reg_talrt_th)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case TAlrtTh_MinTempAlrt: + tempSigned = (int)reg_talrt_th.bits.min_temp_alrt; + if(tempSigned < -128) tempSigned = -128; + break; + case TAlrtTh_MaxTempAlrt: + tempSigned = (int)reg_talrt_th.bits.max_temp_alrt; + if(tempSigned > 127) tempSigned = 127; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + //1°C resolution + *tempDegC = (int)tempSigned & 0xFF; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_salrt_th(reg_bit_salrt_th_t bit_field, uint8_t soc) +{ + int ret; + uint8_t capRaw; + reg_salrt_th_t reg_salrt_th; + + ret = read_fg_register(SAlrtTh, (uint8_t *)&(reg_salrt_th)); + if (ret != MAX77658_NO_ERROR) return ret; + + //%1 resolution + capRaw = (uint8_t)(soc); + + switch (bit_field) + { + case SAlrtTh_MinSocAlrt: + reg_salrt_th.bits.min_soc_alrt = capRaw; + break; + case SAlrtTh_MaxSocAlrt: + reg_salrt_th.bits.max_soc_alrt = capRaw; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_fg_register(SAlrtTh, (uint8_t *)&(reg_salrt_th)); +} + +int MAX77658::get_fg_salrt_th(reg_bit_salrt_th_t bit_field, uint8_t *soc) +{ + int ret; + uint8_t capRaw; + reg_salrt_th_t reg_salrt_th; + + ret = read_fg_register(SAlrtTh, (uint8_t *)&(reg_salrt_th)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case SAlrtTh_MinSocAlrt: + capRaw = (uint8_t)reg_salrt_th.bits.min_soc_alrt; + break; + case SAlrtTh_MaxSocAlrt: + capRaw = (uint8_t)reg_salrt_th.bits.max_soc_alrt; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + //%1 resolution + *soc = (uint8_t)(capRaw); + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_full_soc_thr(float soc_thr) +{ + int capRaw; + reg_full_soc_thr_t reg_full_soc_thr; + + //LSB unit is 1/256%. + capRaw = (int)round(soc_thr * 256); + + SET_FG_BIT_FIELD(FullSocThr, reg_full_soc_thr, reg_full_soc_thr.bits.full_soc_thr, capRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_full_soc_thr(float *soc_thr) +{ + int ret, capRaw; + reg_full_soc_thr_t reg_full_soc_thr; + + ret = read_fg_register(FullSocThr, (uint8_t *)&(reg_full_soc_thr)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB unit is 1/256%. + capRaw = (int)reg_full_soc_thr.bits.full_soc_thr; + *soc_thr = (float)(capRaw / 256.0f); + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_design_cap(float capacitymAh) +{ + int capRaw; + reg_design_cap_t reg_design_cap; + + //Min is 0.0mAh and Max is 6553.5mAh. + if (capacitymAh < 0) capacitymAh = 0; + else if (capacitymAh > 6553.5f) capacitymAh = 6553.5; + + //LSB unit is 0.1mAh. + capRaw = (int)(capacitymAh * 10); + + SET_FG_BIT_FIELD(DesignCap, reg_design_cap, reg_design_cap.bits.design_cap, capRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_design_cap(float *capacitymAh) +{ + int ret, capRaw; + reg_design_cap_t reg_design_cap; + + ret = read_fg_register(DesignCap, (uint8_t *)&(reg_design_cap)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB unit is 0.1mAh. Min is 0.0mAh and Max is 6553.5mAh. + capRaw = (int)reg_design_cap.bits.design_cap; + *capacitymAh = (float)(capRaw * 0.1f); + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_config(reg_bit_config_t bit_field, uint8_t config) +{ + int ret; + reg_config_t reg_config; + + ret = read_fg_register(Config, (uint8_t *)&(reg_config)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case Config_Ber: + reg_config.bits.ber = config; + break; + case Config_Bei: + reg_config.bits.bei = config; + break; + case Config_Aen: + reg_config.bits.aen = config; + break; + case Config_FTHRM: + reg_config.bits.fthrm = config; + break; + case Config_ETHRM: + reg_config.bits.ethrm = config; + break; + case Config_SPR_5: + reg_config.bits.spr_5 = config; + break; + case Config_I2CSH: + reg_config.bits.i2csh = config; + break; + case Config_SHDN: + reg_config.bits.shdn = config; + break; + case Config_Tex: + reg_config.bits.tex = config; + break; + case Config_Ten: + reg_config.bits.ten = config; + break; + case Config_AINSH: + reg_config.bits.ainsh = config; + break; + case Config_SPR_11: + reg_config.bits.spr_11 = config; + break; + case Config_Vs: + reg_config.bits.vs = config; + break; + case Config_Ts: + reg_config.bits.ts = config; + break; + case Config_Ss: + reg_config.bits.ss = config; + break; + case Config_SPR_15: + reg_config.bits.spr_15 = config; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_fg_register(Config, (uint8_t *)&(reg_config)); +} + +int MAX77658::get_fg_config(reg_bit_config_t bit_field, uint8_t *config) +{ + int ret; + reg_config_t reg_config; + + ret = read_fg_register(Config, (uint8_t *)&(reg_config)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case Config_Ber: + *config = (uint8_t)reg_config.bits.ber; + break; + case Config_Bei: + *config = (uint8_t)reg_config.bits.bei; + break; + case Config_Aen: + *config = (uint8_t)reg_config.bits.aen; + break; + case Config_FTHRM: + *config = (uint8_t)reg_config.bits.fthrm; + break; + case Config_ETHRM: + *config = (uint8_t)reg_config.bits.ethrm; + break; + case Config_SPR_5: + *config = (uint8_t)reg_config.bits.spr_5; + break; + case Config_I2CSH: + *config = (uint8_t)reg_config.bits.i2csh; + break; + case Config_SHDN: + *config = (uint8_t)reg_config.bits.shdn; + break; + case Config_Tex: + *config = (uint8_t)reg_config.bits.tex; + break; + case Config_Ten: + *config = (uint8_t)reg_config.bits.ten; + break; + case Config_AINSH: + *config = (uint8_t)reg_config.bits.ainsh; + break; + case Config_SPR_11: + *config = (uint8_t)reg_config.bits.spr_11; + break; + case Config_Vs: + *config = (uint8_t)reg_config.bits.vs; + break; + case Config_Ts: + *config = (uint8_t)reg_config.bits.ts; + break; + case Config_Ss: + *config = (uint8_t)reg_config.bits.ss; + break; + case Config_SPR_15: + *config = (uint8_t)reg_config.bits.spr_15; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_ichg_term(float currentA) +{ + uint16_t currentRaw; + reg_ichg_term_t reg_ichg_term; + + //Register scale range of ± 5.12 A + if (currentA < -5.12f) currentA = -5.12f; + else if (currentA > 5.12f) currentA = 5.12f; + + //LSB value of 156.25μA + currentRaw = (int)round(currentA * 1000000 / 156.25f) & TO_UINT16; + + SET_FG_BIT_FIELD(IChgTerm, reg_ichg_term, reg_ichg_term.bits.ichg_term, currentRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_ichg_term(float *currentA) +{ + int ret; + int16_t currentSigned; + reg_ichg_term_t reg_ichg_term; + + ret = read_fg_register(IChgTerm, (uint8_t *)&(reg_ichg_term)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB value of 156.25μA + currentSigned = (int16_t)reg_ichg_term.bits.ichg_term; + *currentA = (float)(((int)currentSigned) * 156.25f / 1000000); + + //Register scale range of ± 5.12 A + if (*currentA < -5.12f) *currentA = -5.12f; + else if (*currentA > 5.12f) *currentA = 5.12f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_dev_name(uint16_t *value) +{ + int ret; + reg_dev_name_t reg_dev_name; + + ret = read_fg_register(DevName, (uint8_t *)&(reg_dev_name)); + if (ret != MAX77658_NO_ERROR) return ret; + + *value = (uint16_t)(reg_dev_name.bits.dev_name); + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_nempty(uint8_t nempty) +{ + reg_filter_cfg_t reg_filter_cfg; + + SET_FG_BIT_FIELD(FilterCfg, reg_filter_cfg, reg_filter_cfg.bits.nempty, nempty); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_nempty(uint8_t *nempty) +{ + int ret; + reg_filter_cfg_t reg_filter_cfg; + + ret = read_fg_register(FilterCfg, (uint8_t *)&(reg_filter_cfg)); + if (ret != MAX77658_NO_ERROR) return ret; + + *nempty = (uint8_t)reg_filter_cfg.bits.nempty; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_nmix(float second) +{ + int nmixRaw; + reg_filter_cfg_t reg_filter_cfg; + + //Mixing Period = 175.8ms × 2^(5+NMIX) + nmixRaw = (int)round((log2(second * 1000.0f / 175.8f)) - 5.0f); + + SET_FG_BIT_FIELD(FilterCfg, reg_filter_cfg, reg_filter_cfg.bits.nmix, nmixRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_nmix(float *second) +{ + int ret, nmixRaw; + reg_filter_cfg_t reg_filter_cfg; + + ret = read_fg_register(FilterCfg, (uint8_t *)&(reg_filter_cfg)); + if (ret != MAX77658_NO_ERROR) return ret; + + //Mixing Period = 175.8ms × 2^(5+NMIX) + nmixRaw = (int)reg_filter_cfg.bits.nmix; + *second = (float)(175.8f * pow(2, (5 + nmixRaw)) / 1000.0f); + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_navgcell(float second) +{ + int navgcellRaw; + reg_filter_cfg_t reg_filter_cfg; + + //AverageVCELL time constant = 175.8ms × 2^(6+NAVGVCELL) + navgcellRaw = (int)round((log2(second * 1000.0f / 175.8f)) - 6.0f); + + SET_FG_BIT_FIELD(FilterCfg, reg_filter_cfg, reg_filter_cfg.bits.navgcell, navgcellRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_navgcell(float *second) +{ + int ret, navgcellRaw; + reg_filter_cfg_t reg_filter_cfg; + + ret = read_fg_register(FilterCfg, (uint8_t *)&(reg_filter_cfg)); + if (ret != MAX77658_NO_ERROR) return ret; + + //AverageVCELL time constant = 175.8ms × 2^(6+NAVGVCELL) + navgcellRaw = (int)reg_filter_cfg.bits.navgcell; + *second = (float)(175.8f * pow(2, (6 + navgcellRaw)) / 1000.0f); + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_ncurr(float second) +{ + int ncurrRaw; + reg_filter_cfg_t reg_filter_cfg; + + //AverageVCELL time constant = 175.8ms × 2^(2+NCURR) + ncurrRaw = (int)round((log2(second * 1000.0f / 175.8f)) - 2.0f); + + SET_FG_BIT_FIELD(FilterCfg, reg_filter_cfg, reg_filter_cfg.bits.navgcell, ncurrRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_ncurr(float *second) +{ + int ret, ncurrRaw; + reg_filter_cfg_t reg_filter_cfg; + + ret = read_fg_register(FilterCfg, (uint8_t *)&(reg_filter_cfg)); + if (ret != MAX77658_NO_ERROR) return ret; + + //AverageVCELL time constant = 175.8ms × 2^(2+NCURR) + ncurrRaw = (int)reg_filter_cfg.bits.ncurr; + *second = (float)(175.8f * pow(2, (2 + ncurrRaw)) / 1000.0f); + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_iavg_empty(float currentA) +{ + uint16_t currentRaw; + reg_iavg_empty_t reg_iavg_empty; + + //Register scale range of ± 5.12 A + if (currentA < -5.12f) currentA = -5.12f; + else if (currentA > 5.12f) currentA = 5.12f; + + //LSB value of 156.25μA + currentRaw = (int)round(currentA * 1000000 / 156.25f) & TO_UINT16; + + SET_FG_BIT_FIELD(IAvgEmpty, reg_iavg_empty, reg_iavg_empty.bits.rsvd, currentRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_iavg_empty(float *currentA) +{ + int ret; + int16_t currentSigned; + reg_iavg_empty_t reg_iavg_empty; + + ret = read_fg_register(IAvgEmpty, (uint8_t *)&(reg_iavg_empty)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB value of 156.25μA + currentSigned = (int16_t)reg_iavg_empty.bits.rsvd; + *currentA = (float)(((int)currentSigned) * 156.25f / 1000000); + + //Register scale range of ± 5.12 A + if (*currentA < -5.12f) *currentA = -5.12f; + else if (*currentA > 5.12f) *currentA = 5.12f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_v_empty(float voltV) +{ + int voltRaw; + reg_v_empty_t reg_v_empty; + float voltmV = voltV * 1000; + + //A 10mV resolution gives a 0 to 5.11V range. + if (voltmV < 0) voltmV = 0; + else if (voltmV > 5110) voltmV = 5110; + + voltRaw = (int)(voltmV / 10); + + SET_FG_BIT_FIELD(VEmpty, reg_v_empty, reg_v_empty.bits.v_empty, voltRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_v_empty(float *voltV) +{ + int ret, voltRaw; + reg_v_empty_t reg_v_empty; + + ret = read_fg_register(VEmpty, (uint8_t *)&(reg_v_empty)); + if (ret != MAX77658_NO_ERROR) return ret; + + //A 10mV resolution gives a 0 to 5.11V range. + voltRaw = (int)reg_v_empty.bits.v_empty; + *voltV = ((float)voltRaw * 10.0f) / 1000.0f; + + if (*voltV < 0) *voltV = 0; + else if (*voltV > 5.11f) *voltV = 5.11f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_v_recover(float voltV) +{ + int voltRaw; + reg_v_empty_t reg_v_empty; + float voltmV = voltV * 1000; + + //A 40mV resolution gives a 0 to 5.08V range. + if (voltmV < 0) voltmV = 0; + else if (voltmV > 5080) voltmV = 5080; + + voltRaw = (int)(voltmV / 40); + + SET_FG_BIT_FIELD(VEmpty, reg_v_empty, reg_v_empty.bits.v_recover, voltRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_v_recover(float *voltV) +{ + int ret, voltRaw; + reg_v_empty_t reg_v_empty; + + ret = read_fg_register(VEmpty, (uint8_t *)&(reg_v_empty)); + if (ret != MAX77658_NO_ERROR) return ret; + + //A 40mV resolution gives a 0 to 5.08V range. + voltRaw = (int)reg_v_empty.bits.v_recover; + *voltV = ((float)voltRaw * 40.0f) / 1000.0f; + + + if (*voltV < 0) *voltV = 0; + else if (*voltV > 5.08f) *voltV = 5.08f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_config2(reg_bit_config2_t bit_field, uint8_t config) +{ + int ret; + reg_config2_t reg_config2; + + ret = read_fg_register(Config2, (uint8_t *)&(reg_config2)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case Config2_ISysNCurr: + reg_config2.bits.isys_ncurr = config; + break; + case Config2_OCVQen: + reg_config2.bits.qcvqen = config; + break; + case Config2_LdMdl: + reg_config2.bits.ldmdl = config; + break; + case Config2_TAlrtEn: + reg_config2.bits.tairt_en = config; + break; + case Config2_dSOCen: + reg_config2.bits.dsocen = config; + break; + case Config2_ThmHotAlrtEn: + reg_config2.bits.thm_hotairt_en = config; + break; + case Config2_ThmHotEn: + reg_config2.bits.thmhot_en = config; + break; + case Config2_FCThmHot: + reg_config2.bits.fc_thmhot = config; + break; + case Config2_SPR: + reg_config2.bits.spr = config; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_fg_register(Config2, (uint8_t *)&(reg_config2)); +} + +int MAX77658::get_fg_config2(reg_bit_config2_t bit_field, uint8_t *config) +{ + int ret; + reg_config2_t reg_config2; + + ret = read_fg_register(Config2, (uint8_t *)&(reg_config2)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case Config2_ISysNCurr: + *config = (uint8_t)reg_config2.bits.isys_ncurr; + break; + case Config2_OCVQen: + *config = (uint8_t)reg_config2.bits.qcvqen; + break; + case Config2_LdMdl: + *config = (uint8_t)reg_config2.bits.ldmdl; + break; + case Config2_TAlrtEn: + *config = (uint8_t)reg_config2.bits.tairt_en; + break; + case Config2_dSOCen: + *config = (uint8_t)reg_config2.bits.dsocen; + break; + case Config2_ThmHotAlrtEn: + *config = (uint8_t)reg_config2.bits.thm_hotairt_en; + break; + case Config2_ThmHotEn: + *config = (uint8_t)reg_config2.bits.thmhot_en; + break; + case Config2_FCThmHot: + *config = (uint8_t)reg_config2.bits.fc_thmhot; + break; + case Config2_SPR: + *config = (uint8_t)reg_config2.bits.spr; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_isys_ncurr(float second) +{ + int secondRaw; + reg_config2_t reg_config2; + + //AvgISys time constant = 45s x 2^(ISysNCurr-7) + secondRaw = (int)round(log2(second * 1000 / 45000) + 7); + + SET_FG_BIT_FIELD(Config2, reg_config2, reg_config2.bits.isys_ncurr, secondRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_isys_ncurr(float *second) +{ + int ret, secondRaw; + reg_config2_t reg_config2; + + ret = read_fg_register(Config2, (uint8_t *)&(reg_config2)); + if (ret != MAX77658_NO_ERROR) return ret; + + //AvgISys time constant = 45s x 2^(ISysNCurr-7) + secondRaw = (int)reg_config2.bits.isys_ncurr; + *second = (float)(45.0f * pow(2, secondRaw - 7)); + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_temp(float tempDegC) +{ + uint16_t tempRaw; + reg_temp_t reg_temp; + + //Min value is -128.0°C and Max value is 127.996°C. + if (tempDegC < -128) tempDegC = -128; + else if (tempDegC > 127.996f) tempDegC = 127.996f; + + //LSB is 1/256°C = 0.0039˚C. + tempRaw = (int)round(tempDegC * 256) & TO_UINT16; + + SET_FG_BIT_FIELD(Temp, reg_temp, reg_temp.bits.temp, tempRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_temp(float *tempDegC) +{ + int ret; + int16_t tempSigned; + reg_temp_t reg_temp; + + ret = read_fg_register(Temp, (uint8_t *)&(reg_temp)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB is 1/256°C = 0.0039˚C. + tempSigned = (int16_t)reg_temp.bits.temp; + *tempDegC = (float)(tempSigned / 256.0f); + + //Min value is -128.0°C and Max value is 127.996°C. + if (*tempDegC < -128) *tempDegC = -128; + else if (*tempDegC > 127.996f) *tempDegC = 127.996f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_vcell(float voltV) +{ + uint16_t voltRaw; + reg_vcell_t reg_vcell; + float voltmV = voltV * 1000; + + //Register scale range between 0V and 5.11992V. //LSB value of 1.25mV/16 + if (voltmV < 0) voltmV = 0; + else if (voltmV > 5119.92f) voltmV = 5119.92f; + + voltRaw = (int)round(voltmV / 1.25 * 16) & TO_UINT16; + + SET_FG_BIT_FIELD(Vcell, reg_vcell, reg_vcell.bits.vcell, voltRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_vcell(float *voltV) +{ + int ret, voltRaw; + reg_vcell_t reg_vcell; + + ret = read_fg_register(Vcell, (uint8_t *)&(reg_vcell)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB value of 1.25mV/16 + voltRaw = (int)reg_vcell.bits.vcell; + *voltV = (float)(voltRaw * 1.25f / 16 / 1000); + + if (*voltV < 0) *voltV = 0; + else if (*voltV > 5.11992f) *voltV = 5.11992f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_current(float currentA) +{ + uint16_t currentRaw; + reg_current_t reg_current; + float currentmA = currentA * 1000; + + if (currentmA < -1024) currentmA = -1024; + else if (currentmA > 1024) currentmA = 1024; + + //The current register has a LSB value of 31.25uA, a register scale of 1.024A + currentRaw = (int)round(currentmA * 1000 / 31.25f) & TO_UINT16; + + SET_FG_BIT_FIELD(Current, reg_current, reg_current.bits.current, currentRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_current(float *currentA) +{ + int ret; + int16_t currentSigned; + reg_current_t reg_current; + + ret = read_fg_register(Current, (uint8_t *)&(reg_current)); + if (ret != MAX77658_NO_ERROR) return ret; + + //The current register has a LSB value of 31.25uA, a register scale of 1.024A + currentSigned = (int16_t)(reg_current.bits.current); + *currentA = (float)(currentSigned * 31.25f / 1000000); + + if (*currentA < -1.024f) *currentA = -1.024f; + else if (*currentA > 1.024f) *currentA = 1.024f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_avg_current(float currentA) +{ + uint16_t currentRaw; + reg_avg_current_t reg_avg_current; + float currentmA = currentA * 1000; + + if (currentmA < -1024) currentmA = -1024; + else if (currentmA > 1024) currentmA = 1024; + + //The current register has a LSB value of 31.25uA, a register scale of 1.024A + currentRaw = (int)round(currentmA * 1000 / 31.25f) & TO_UINT16; + + SET_FG_BIT_FIELD(AvgCurrent, reg_avg_current, reg_avg_current.bits.avg_current, currentRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_avg_current(float *currentA) +{ + int ret; + int16_t currentSigned; + reg_avg_current_t reg_avg_current; + + ret = read_fg_register(AvgCurrent, (uint8_t *)&(reg_avg_current)); + if (ret != MAX77658_NO_ERROR) return ret; + + //The current register has a LSB value of 31.25uA, a register scale of 1.024A + currentSigned = (int16_t)(reg_avg_current.bits.avg_current); + *currentA = (float)(currentSigned * 31.25f / 1000000); + + if (*currentA < -1.024f) *currentA = -1.024f; + else if (*currentA > 1.024f) *currentA = 1.024f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_avgta(float tempDegC) +{ + uint16_t tempRaw; + reg_avg_ta_t reg_avg_ta; + + //Min value is -128.0°C and Max value is 127.996°C. + if (tempDegC < -128) tempDegC = -128; + else if (tempDegC > 127.996f) tempDegC = 127.996f; + + //LSB is 1/256°C = 0.0039˚C. + tempRaw = (int)round(tempDegC * 256) & TO_UINT16; + + SET_FG_BIT_FIELD(AvgTA, reg_avg_ta, reg_avg_ta.bits.avg_ta, tempRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_avgta(float *tempDegC) +{ + int ret; + int16_t tempSigned; + reg_avg_ta_t reg_avg_ta; + + ret = read_fg_register(AvgTA, (uint8_t *)&(reg_avg_ta)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB is 1/256°C = 0.0039˚C. + tempSigned = (int16_t)reg_avg_ta.bits.avg_ta; + *tempDegC = (float)(tempSigned / 256.0f); + + //Min value is -128.0°C and Max value is 127.996°C. + if (*tempDegC < -128) *tempDegC = -128; + else if (*tempDegC > 127.996f) *tempDegC = 127.996f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_avgvcell(float voltV) +{ + uint16_t voltRaw; + reg_avg_vcell_t reg_avg_vcell; + float voltmV = voltV * 1000; + + //Register scale range between 0V and 5.11992V. //LSB value of 1.25mV/16 + if (voltmV < 0) voltmV = 0; + else if (voltmV > 5119.92f) voltmV = 5119.92f; + + voltRaw = (int)round(voltmV / 1.25 * 16) & TO_UINT16; + + SET_FG_BIT_FIELD(AvgVCell, reg_avg_vcell, reg_avg_vcell.bits.avg_vcell, voltRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_avgvcell(float *voltV) +{ + int ret, voltRaw; + reg_avg_vcell_t reg_avg_vcell; + + ret = read_fg_register(AvgVCell, (uint8_t *)&(reg_avg_vcell)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB value of 1.25mV/16 + voltRaw = (int)reg_avg_vcell.bits.avg_vcell; + *voltV = (float)(voltRaw * 1.25f / 16 / 1000); + + //Min value is 0.0V and Max value is 5.11992V. + if (*voltV < 0) *voltV = 0; + else if (*voltV > 5.11992f) *voltV = 5.11992f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_max_min_temp(reg_bit_max_min_temp_t bit_field, int tempDegC) +{ + int ret; + uint8_t tempRaw; + reg_max_min_temp_t reg_max_min_temp; + + ret = read_fg_register(MaxMinTemp, (uint8_t *)&(reg_max_min_temp)); + if (ret != MAX77658_NO_ERROR) return ret; + + tempRaw = tempDegC & TO_UINT8; + + //1°C resolution + switch (bit_field) + { + case MaxMinTemp_MinTemperature: + reg_max_min_temp.bits.min_temp = tempRaw; + break; + case MaxMinTemp_MaxTemperature: + reg_max_min_temp.bits.max_temp = tempRaw; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_fg_register(MaxMinTemp, (uint8_t *)&(reg_max_min_temp)); +} + +int MAX77658::get_fg_max_min_temp(reg_bit_max_min_temp_t bit_field, int *tempDegC) +{ + int ret; + int8_t tempSigned; + reg_max_min_temp_t reg_max_min_temp; + + ret = read_fg_register(MaxMinTemp, (uint8_t *)&(reg_max_min_temp)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case MaxMinTemp_MinTemperature: + tempSigned = (int8_t)reg_max_min_temp.bits.min_temp; + break; + case MaxMinTemp_MaxTemperature: + tempSigned = (int8_t)reg_max_min_temp.bits.max_temp; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + //1°C resolution + *tempDegC = (int)tempSigned; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_max_min_volt(reg_bit_max_min_volt_t bit_field, float voltV) +{ + int ret; + uint8_t voltRaw; + reg_max_min_volt_t reg_max_min_volt; + float voltmV = voltV * 1000; + + ret = read_fg_register(MaxMinVolt, (uint8_t *)&(reg_max_min_volt)); + if (ret != MAX77658_NO_ERROR) return ret; + + //20mV resolution + voltRaw = (int)(voltmV / 20) & TO_UINT8; + + switch (bit_field) + { + case MaxMinVolt_MinVoltage: + reg_max_min_volt.bits.min_volt = voltRaw; + break; + case MaxMinVolt_MaxVoltage: + reg_max_min_volt.bits.max_volt = voltRaw; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_fg_register(MaxMinVolt, (uint8_t *)&(reg_max_min_volt)); +} + +int MAX77658::get_fg_max_min_volt(reg_bit_max_min_volt_t bit_field, float *voltV) +{ + int ret; + int8_t voltSigned; + reg_max_min_volt_t reg_max_min_volt; + + ret = read_fg_register(MaxMinVolt, (uint8_t *)&(reg_max_min_volt)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case MaxMinVolt_MinVoltage: + voltSigned = (int8_t)reg_max_min_volt.bits.min_volt; + break; + case MaxMinVolt_MaxVoltage: + voltSigned = (int8_t)reg_max_min_volt.bits.max_volt; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + //20mV resolution + *voltV = (float)((voltSigned * 20.0f) / 1000.0f); + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_max_min_curr(reg_bit_max_min_curr_t bit_field, float currentA) +{ + int ret; + uint8_t currentRaw; + reg_max_min_curr_t reg_max_min_curr; + float currentmA = currentA * 1000; + + ret = read_fg_register(MaxMinCurr, (uint8_t *)&(reg_max_min_curr)); + if (ret != MAX77658_NO_ERROR) return ret; + + //8mA resolution. + currentRaw = (int)round(currentmA / 8) & TO_UINT8; + + switch (bit_field) + { + case MaxMinCurr_MaxDisCurrent: + reg_max_min_curr.bits.min_charge_curr = currentRaw; + break; + case MaxMinCurr_MaxChargeCurrent: + reg_max_min_curr.bits.max_charge_curr = currentRaw; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + return write_fg_register(MaxMinCurr, (uint8_t *)&(reg_max_min_curr)); +} + +int MAX77658::get_fg_max_min_curr(reg_bit_max_min_curr_t bit_field, float *currentA) +{ + int ret; + int8_t currentSigned; + reg_max_min_curr_t reg_max_min_curr; + + ret = read_fg_register(MaxMinCurr, (uint8_t *)&(reg_max_min_curr)); + if (ret != MAX77658_NO_ERROR) return ret; + + switch (bit_field) + { + case MaxMinCurr_MaxDisCurrent: + currentSigned = (int8_t)reg_max_min_curr.bits.min_charge_curr; + break; + case MaxMinCurr_MaxChargeCurrent: + currentSigned = (int8_t)reg_max_min_curr.bits.max_charge_curr; + break; + default: + return MAX77658_INVALID_DATA; + break; + } + + //8mA resolution + *currentA = (float)(currentSigned * 8.0f / 1000.0f); + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_ain0(float percent) +{ + int percentRaw; + reg_ain0_t reg_ain0; + + //LSB of 0.0122% + percentRaw = (int)round(percent / 0.0122f); + + SET_FG_BIT_FIELD(AIN0, reg_ain0, reg_ain0.bits.ain0, percentRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_ain0(float *percent) +{ + int ret, percentRaw; + reg_ain0_t reg_ain0; + + ret = read_fg_register(AIN0, (uint8_t *)&(reg_ain0)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB of 0.0122% + percentRaw = (int)reg_ain0.bits.ain0; + *percent = (float)(percentRaw * 0.0122f); + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_timer(float second) +{ + int secondRaw; + reg_timer_t reg_timer; + + //full-scale range of 0 to 3.2 hours= 11520 sec + if (second < 0) second = 0; + else if (second > 11520.0f) second = 11520.0f; + + //LSB is 175.8ms + secondRaw = (int)round(second * 1000 / 175.8f); + + SET_FG_BIT_FIELD(Timer, reg_timer, reg_timer.bits.timer, secondRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_timer(float *second) +{ + int ret, secondRaw; + reg_timer_t reg_timer; + + ret = read_fg_register(Timer, (uint8_t *)&(reg_timer)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB is 175.8ms + secondRaw = (int)reg_timer.bits.timer; + *second = (float)((float)secondRaw * 175.8f / 1000); + + //full-scale range of 0 to 3.2 hours + if (*second < 0) *second = 0; + else if (*second > 11520.0f) *second = 11520.0f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_shdnctr(float second) +{ + int secondRaw; + reg_shdn_timer_t reg_shdn_timer; + + //The counter LSB is 1.4s + secondRaw = (int)round(second / 1.4f); + + SET_FG_BIT_FIELD(ShdnTimer, reg_shdn_timer, reg_shdn_timer.bits.shdnctr, secondRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_shdnctr(float *second) +{ + int ret, secondRaw; + reg_shdn_timer_t reg_shdn_timer; + + ret = read_fg_register(ShdnTimer, (uint8_t *)&(reg_shdn_timer)); + if (ret != MAX77658_NO_ERROR) return ret; + + //Period = 175.8ms × 2^(8+THR) + secondRaw = (int)reg_shdn_timer.bits.shdnctr; + *second = (float)(secondRaw * 1.4f); + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_shdn_thr(float second) +{ + int secondRaw; + reg_shdn_timer_t reg_shdn_timer; + + //minimum of 45s to a maximum of 1.6h=5760sec + if (second < 45) second = 45; + else if (second > 5760.0f) second = 5760.0f; + + //Period = 175.8ms × 2^(8+THR) + secondRaw = (int)round(log2(second * 1000 / 175.8f) - 8); + + SET_FG_BIT_FIELD(ShdnTimer, reg_shdn_timer, reg_shdn_timer.bits.shdn_thr, secondRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_shdn_thr(float *second) +{ + int ret, secondRaw; + reg_shdn_timer_t reg_shdn_timer; + + ret = read_fg_register(ShdnTimer, (uint8_t *)&(reg_shdn_timer)); + if (ret != MAX77658_NO_ERROR) return ret; + + //Period = 175.8ms × 2^(8+THR) + secondRaw = (int)reg_shdn_timer.bits.shdn_thr; + *second = (float)(175.8f / 1000 * pow(2, secondRaw + 8)); + + //minimum of 45s to a maximum of 1.6h + if (*second < 45) *second = 45; + else if (*second > 5760.0f) *second = 5760.0f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_timerh(float hour) +{ + int hourRaw; + reg_timerh_t reg_timerh; + + // Full-scale range up to 23.94 years = 209853.5577138 hr + if (hour > 209853.5577138f) hour = (209853.5577138f); + + //A 3.2-hour LSB + hourRaw = (int)round(hour / 3.2f); + + SET_FG_BIT_FIELD(TimerH, reg_timerh, reg_timerh.bits.timerh, hourRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_timerh(float *hour) +{ + int ret, hourRaw; + reg_timerh_t reg_timerh; + + ret = read_fg_register(TimerH, (uint8_t *)&(reg_timerh)); + if (ret != MAX77658_NO_ERROR) return ret; + + //A 3.2-hour LSB + hourRaw = (int)reg_timerh.bits.timerh; + *hour = (float)(hourRaw * 3.2f); + + // Full-scale range up to 23.94 years = 209853.5577138 hr + if (*hour > 209853.5577138f) *hour = 209853.5577138f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_rep_cap(float repCapmAh) +{ + int repCapRaw; + reg_rep_cap_t reg_rep_cap; + + //Min value is 0.0mAh and Max value is 6553.5mAh + if (repCapmAh < 0) repCapmAh = 0; + else if (repCapmAh > 6553.5f) repCapmAh = 6553.5f; + + //LSB is 0.1mAh. + repCapRaw = (int)round(repCapmAh / 0.1f); + + SET_FG_BIT_FIELD(RepCap, reg_rep_cap, reg_rep_cap.bits.rep_cap, repCapRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_rep_cap(float *repCapmAh) +{ + int ret, repCapRaw; + reg_rep_cap_t reg_rep_cap; + + ret = read_fg_register(RepCap, (uint8_t *)&(reg_rep_cap)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB is 0.1mAh. + repCapRaw = (int)reg_rep_cap.bits.rep_cap; + *repCapmAh = (float)(repCapRaw * 0.1f); + + //Min value is 0.0mAh and Max value is 6553.5mAh + if (*repCapmAh < 0) *repCapmAh = 0; + else if (*repCapmAh > 6553.5f) *repCapmAh = 6553.5f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_rep_soc(float percent) +{ + int percentRaw; + reg_rep_soc_t reg_rep_soc; + + //Min value is 0.0% and Max value is 255.9961% + if (percent < 0) percent = 0; + else if (percent > 255.9961f) percent = 255.9961f; + + //LSB is 1/256% + percentRaw = (int)round(percent * 256); + + SET_FG_BIT_FIELD(RepSOC, reg_rep_soc, reg_rep_soc.bits.rep_soc, percentRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_rep_soc(float *percent) +{ + int ret, percentRaw; + reg_rep_soc_t reg_rep_soc; + + ret = read_fg_register(RepSOC, (uint8_t *)&(reg_rep_soc)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB is 1/256% + percentRaw = (int)reg_rep_soc.bits.rep_soc; + *percent = (float)((float)percentRaw / 256.0f); + + //Min value is 0.0% and Max value is 255.9961% + if (*percent < 0) *percent = 0; + else if (*percent > 255.9961f) *percent = 255.9961f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_av_soc(float percent) +{ + int percentRaw; + reg_av_soc_t reg_av_soc; + + //Min value is 0.0% and Max value is 255.9961% + if (percent < 0) percent = 0; + else if (percent > 255.9961f) percent = 255.9961f; + + //LSB is 1/256% + percentRaw = (int)round(percent * 256); + + SET_FG_BIT_FIELD(AvSOC, reg_av_soc, reg_av_soc.bits.av_soc, percentRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_av_soc(float *percent) +{ + int ret, percentRaw; + reg_av_soc_t reg_av_soc; + + ret = read_fg_register(AvSOC, (uint8_t *)&(reg_av_soc)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB is 1/256% + percentRaw = (int)reg_av_soc.bits.av_soc; + *percent = (float)(percentRaw / 256.0f); + + //Min value is 0.0% and Max value is 255.9961% + if (*percent < 0) *percent = 0; + else if (*percent > 255.9961f) *percent = 255.9961f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_full_cap_reg(float repCapmAh) +{ + int repCapRaw; + reg_full_cap_rep_t reg_full_cap_rep; + + //Min value is 0.0mAh and Max value is 6553.5mAh + if (repCapmAh < 0) repCapmAh = 0; + else if (repCapmAh > 6553.5f) repCapmAh = 6553.5f; + + //LSB is 0.1mAh. + repCapRaw = (int)round(repCapmAh / 0.1f); + + SET_FG_BIT_FIELD(FullCapRep, reg_full_cap_rep, reg_full_cap_rep.bits.full_cap_rep, repCapRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_full_cap_reg(float *repCapmAh) +{ + int ret, repCapRaw; + reg_full_cap_rep_t reg_full_cap_rep; + + ret = read_fg_register(FullCapRep, (uint8_t *)&(reg_full_cap_rep)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB is 0.1mAh. + repCapRaw = (int)reg_full_cap_rep.bits.full_cap_rep; + *repCapmAh = (float)(repCapRaw * 0.1f); + + //Min value is 0.0mAh and Max value is 6553.5mAh + if (*repCapmAh < 0) *repCapmAh = 0; + else if (*repCapmAh > 6553.5f) *repCapmAh = 6553.5f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_tte(float minute) +{ + int minuteRaw; + reg_tte_t reg_tte; + + //Min value is 0.0s and Max value is 102.3984h = 6143.904min. + //LSB is 5.625s. + minuteRaw = (int)round((float)minute * 60 / 5.625f); + + SET_FG_BIT_FIELD(TTE, reg_tte, reg_tte.bits.tte, minuteRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_tte(float *minute) +{ + int ret, minuteRaw; + reg_tte_t reg_tte; + + ret = read_fg_register(TTE, (uint8_t *)&(reg_tte)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB is 5.625s. + minuteRaw = (int)reg_tte.bits.tte; + *minute = (float)((float)minuteRaw * 5.625f / 60); + + //Min value is 0.0s and Max value is 102.3984h = = 6143.904 min.min. + if (*minute < 0) *minute = 0; + else if (*minute > 6143.904f) *minute = 6143.904f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_rcell(float resOhm) +{ + int resistanceRaw; + reg_rcell_t reg_rcell; + + //Min value is 0.0Ohm and Max value is 15.99976Ohm. + if (resOhm < 0) resOhm = 0; + else if (resOhm > 15.99976f) resOhm = 15.99976f; + + //LSB is 1/4096Ohm + resistanceRaw = (int)round(resOhm * 4096); + + SET_FG_BIT_FIELD(RCell, reg_rcell, reg_rcell.bits.rcell, resistanceRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_rcell(float *resOhm) +{ + int ret, resistanceRaw; + reg_rcell_t reg_rcell; + + ret = read_fg_register(RCell, (uint8_t *)&(reg_rcell)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB is 1/4096Ohm + resistanceRaw = (int)reg_rcell.bits.rcell; + *resOhm = (float)(resistanceRaw / 4096.0f); + + //Min value is 0.0Ohm and Max value is 15.99976Ohm. + if (*resOhm < 0) *resOhm = 0; + else if (*resOhm > 15.99976f) *resOhm = 15.99976f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_cycles(uint16_t percent) +{ + reg_cycles_t reg_cycles; + + //The LSB indicates 1%. + SET_FG_BIT_FIELD(Cycles, reg_cycles, reg_cycles.bits.cycles, percent); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_cycles(uint16_t *percent) +{ + int ret; + reg_cycles_t reg_cycles; + + ret = read_fg_register(Cycles, (uint8_t *)&(reg_cycles)); + if (ret != MAX77658_NO_ERROR) return ret; + + //The LSB indicates 1%. + *percent = (uint16_t)(reg_cycles.bits.cycles); + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_av_cap(float avCapmAh) +{ + int avCapRaw; + reg_av_cap_t reg_av_cap; + + //LSB is 0.1mAh. Min value is 0.0mAh and Max value is 6553.5mAh. + if (avCapmAh < 0) avCapmAh = 0; + else if (avCapmAh > 6553.5f) avCapmAh = 6553.5f; + + avCapRaw = (int)round(avCapmAh / 0.5f); + + SET_FG_BIT_FIELD(AvCap, reg_av_cap, reg_av_cap.bits.av_cap, avCapRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_av_cap(float *avCapmAh) +{ + int ret, avCapRaw; + reg_av_cap_t reg_av_cap; + + ret = read_fg_register(AvCap, (uint8_t *)&(reg_av_cap)); + if (ret != MAX77658_NO_ERROR) return ret; + + //LSB is 0.1mAh. Min value is 0.0mAh and Max value is 6553.5mAh. + avCapRaw = (int)reg_av_cap.bits.av_cap; + *avCapmAh = (float)((float)avCapRaw * 0.1f); + + if (*avCapmAh < 0) *avCapmAh = 0; + else if (*avCapmAh > 6553.5f) *avCapmAh = 6553.5f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::set_fg_ttf(float minute) +{ + int minuteRaw; + reg_ttf_t reg_ttf; + + //Min value is 0.0s and Max value is 102.3984h = = 6143.904 min.min. + if (minute < 0) minute = 0; + else if (minute > 6143.904f) minute = 6143.904f; + + //LSB is 5.625s. + minuteRaw = (int)round((float)minute * 60 / 5.625f); + + SET_FG_BIT_FIELD(TTF, reg_ttf, reg_ttf.bits.ttf, minuteRaw); + return MAX77658_NO_ERROR; +} + +int MAX77658::get_fg_ttf(float *minute) +{ + int ret, minuteRaw; + reg_ttf_t reg_ttf; + + ret = read_fg_register(TTF, (uint8_t *)&(reg_ttf)); + if (ret != MAX77658_NO_ERROR) return ret; + + minuteRaw = (int)reg_ttf.bits.ttf; + *minute = (float)((float)minuteRaw * 5.625f / 60); + + //Min value is 0.0s and Max value is 102.3984h = = 6143.904 min.min. + if (*minute < 0) *minute = 0; + else if (*minute > 6143.904f) *minute = 6143.904f; + + return MAX77658_NO_ERROR; +} + +int MAX77658::irq_disable_all() +{ + int ret; + uint8_t reg = 0; + uint8_t status = 0; + + //Disable Masks in INTM_GLBL1 + ret = write_register(INTM_GLBL1, ®); + if (ret != MAX77658_NO_ERROR) return ret; + + //Disable Masks in INTM_GLBL0 + ret = write_register(INTM_GLBL0, ®); + if (ret != MAX77658_NO_ERROR) return ret; + + //Disable Masks in INT_M_CHG + ret = write_register(INT_M_CHG, ®); + if (ret != MAX77658_NO_ERROR) return ret; + + // Clear Interrupt Flags in INT_GLBL1 + ret = read_register(INT_GLBL1, &status); + if (ret != MAX77658_NO_ERROR) return ret; + + // Clear Interrupt Flags in INT_GLBL0 + ret = read_register(INT_GLBL0, &status); + if (ret != MAX77658_NO_ERROR) return ret; + + // Clear Interrupt Flags in INT_CHG + ret = read_register(INT_CHG, &status); + if (ret != MAX77658_NO_ERROR) return ret; + + return MAX77658_NO_ERROR; +} + +void MAX77658::set_interrupt_handler(reg_bit_int_glbl_t id, interrupt_handler_function func, void *cb) +{ + interrupt_handler_list[id].func = func; + interrupt_handler_list[id].cb = cb; +} + +void MAX77658::post_interrupt_work() +{ + int ret; + uint8_t reg, inten, not_inten, mask; + + while (true) { + + ThisThread::flags_wait_any(POST_INTR_WORK_SIGNAL_ID); + + // Check Interrupt Flags in INT_GLBL0 + ret = read_register(INT_GLBL0, ®); + if (ret != MAX77658_NO_ERROR) return; + + ret = read_register(INTM_GLBL0, &inten); + if (ret != MAX77658_NO_ERROR) return; + + not_inten = ~inten; // 0 means unmasked. + + for (int i = 0; i < INT_GLBL1_GPI1_F; i++) { + mask = (1 << i); + if ((reg & mask) && (not_inten & mask)) { + if (interrupt_handler_list[i].func != NULL) { + interrupt_handler_list[i] + .func(interrupt_handler_list[i].cb); + } + } + } + + // Check Interrupt Flags in INT_GLBL1 + ret = read_register(INT_GLBL1, ®); + if (ret != MAX77658_NO_ERROR) return; + + ret = read_register(INTM_GLBL1, &inten); + if (ret != MAX77658_NO_ERROR) return; + + not_inten = ~inten; // 0 means unmasked. + + for (int i = INT_GLBL1_GPI1_F; i < INT_CHG_THM_I; i++) { + mask = (1 << (i - INT_GLBL1_GPI1_F)); + if ((reg & mask) && (not_inten & mask)) { + if (interrupt_handler_list[i].func != NULL) { + interrupt_handler_list[i] + .func(interrupt_handler_list[i].cb); + } + } + } + + // Check Interrupt Flags in INT_CHG + ret = read_register(INT_CHG, ®); + if (ret != MAX77658_NO_ERROR) return; + + ret = read_register(INT_M_CHG, &inten); + if (ret != MAX77658_NO_ERROR) return; + + not_inten = ~inten; // 0 means unmasked. + + for (int i = INT_CHG_THM_I; i < INT_CHG_END; i++) { + mask = (1 << (i - INT_CHG_THM_I)); + if ((reg & mask) && (not_inten & mask)) { + if (interrupt_handler_list[i].func != NULL) { + interrupt_handler_list[i] + .func(interrupt_handler_list[i].cb); + } + } + } + } +} + +void MAX77658::interrupt_handler() +{ + post_intr_work_thread->flags_set(POST_INTR_WORK_SIGNAL_ID); +} +