MAX77658 Ultra-Low Power PMIC Mbed Driver

MAX77658.cpp

Committer:
Okan Sahin
Date:
21 months ago
Revision:
2:70a11f46a913
Parent:
1:40ef1dc30cb7

File content as of revision 2:70a11f46a913:

/*******************************************************************************
 * 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;

	interrupt_handler_list = new handler[INT_CHG_END] {};
	
    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;

	if (interrupt_handler_list)
        delete [] interrupt_handler_list;
}

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 *)&reg, 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 *)&reg, 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 = {0};

	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 = {0};

    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 = {0};
	reg_intm_glbl0_t reg_intm_glbl0 = {0};
	reg_intm_glbl1_t reg_intm_glbl1 = {0};
 
	//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));
}

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 = {0};
	reg_intm_glbl0_t reg_intm_glbl0 = {0};
	reg_intm_glbl1_t reg_intm_glbl1 = {0};
 
	//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 = {0};
	
	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 = {0};

    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 = {0};
	reg_cnfg_gpio1_t reg_cnfg_gpio1 = {0};
	reg_cnfg_gpio2_t reg_cnfg_gpio2 = {0};
	
	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 = {0};
	reg_cnfg_gpio1_t reg_cnfg_gpio1 = {0};
	reg_cnfg_gpio2_t reg_cnfg_gpio2 = {0};
	
	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 = {0};
	
	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 = {0};

    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 = {0};

    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 = {0};

    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 = {0};

    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 = {0};

    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 = {0};

	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 = {0};

    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 = {0};

	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 = {0};

    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 = {0};

	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 = {0};

    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 = {0};

	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 = {0};

    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 = {0};
	
	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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};

	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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};

	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 = {0};

    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 = {0};

	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 = {0};

    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 = {0};

	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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};

    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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};
	
	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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};
	
	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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};
	
	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 = {0};

    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 = {0};

    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 = {0};

    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 = {0};
	
	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 = {0};

    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 = {0};
	reg_cnfg_sbb1_a_t reg_cnfg_sbb1_a = {0};
	reg_cnfg_sbb2_a_t reg_cnfg_sbb2_a = {0};
	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 = {0};
    reg_cnfg_sbb1_a_t reg_cnfg_sbb1_a = {0};
    reg_cnfg_sbb2_a_t reg_cnfg_sbb2_a = {0};

	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 = {0};
	reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b = {0};
	reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b = {0};
	
	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 = {0};
	reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b = {0};
	reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b = {0};

	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 = {0};
	reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b = {0};
	reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b = {0};
	
	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 = {0};
	reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b = {0};
	reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b = {0};

	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 = {0};
	reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b = {0};
	reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b = {0};
	
	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 = {0};
	reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b = {0};
	reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b = {0};

	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 = {0};
	reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b = {0};
	reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b = {0};
	
	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 = {0};
	reg_cnfg_sbb1_b_t reg_cnfg_sbb1_b = {0};
	reg_cnfg_sbb2_b_t reg_cnfg_sbb2_b = {0};

	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 = {0};
	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 = {0};

	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 = {0};
	reg_cnfg_ldo1_a_t reg_cnfg_ldo1_a = {0};
	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 = {0};
	reg_cnfg_ldo1_a_t reg_cnfg_ldo1_a = {0};
	
	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 = {0};
	reg_cnfg_ldo1_a_t reg_cnfg_ldo1_a = {0};
	
	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 = {0};
	reg_cnfg_ldo1_a_t reg_cnfg_ldo1_a = {0};

	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 = {0};
	reg_cnfg_ldo1_b_t reg_cnfg_ldo1_b = {0};
	
	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 = {0};
	reg_cnfg_ldo1_b_t reg_cnfg_ldo1_b = {0};

	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 = {0};
	reg_cnfg_ldo1_b_t reg_cnfg_ldo1_b = {0};
	
	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 = {0};
	reg_cnfg_ldo1_b_t reg_cnfg_ldo1_b = {0};

	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 = {0};
	reg_cnfg_ldo1_b_t reg_cnfg_ldo1_b = {0};
	
	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 = {0};
	reg_cnfg_ldo1_b_t reg_cnfg_ldo1_b = {0};

	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 = {0};
	
	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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};
	
	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 = {0};

    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 = {0};
	
	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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};

    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 = {0};

    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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};
	
	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 = {0};

    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 = {0};

	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};	
	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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};
	
	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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};
	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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	// 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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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 = {0};
	
	//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 = {0};

    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, &reg);
    if (ret != MAX77658_NO_ERROR) return ret;

    //Disable Masks in INTM_GLBL0
    ret = write_register(INTM_GLBL0, &reg);
    if (ret != MAX77658_NO_ERROR) return ret;

    //Disable Masks in INT_M_CHG
    ret = write_register(INT_M_CHG, &reg);
    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 = 0, inten = 0, not_inten = 0, mask = 0;

    while (true) {

        ThisThread::flags_wait_any(POST_INTR_WORK_SIGNAL_ID);

        // Check Interrupt Flags in INT_GLBL0
        ret = read_register(INT_GLBL0, &reg);
        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, &reg);
		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, &reg);
		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);
}