MAX77658 Ultra-Low Power PMIC Mbed Driver
MAX77658.cpp
- Committer:
- metin.ozkan@analog.com
- Date:
- 2022-06-30
- Revision:
- 0:00d2a8670533
- Child:
- 1:40ef1dc30cb7
File content as of revision 0:00d2a8670533:
/******************************************************************************* * 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); }