#include "sgm4151x.h"

/**
 * @param state - combine SGM4151X_HIZ_MODE_t,SGM4151X_STAT_PIN_t,SGM4151X_IINDPM_t
 *                with '|'
*/
int sgm4151x_set_reg0(sgm4151x_dev_t *dev, uint8_t state)
{
    DEV_ASSERT(dev);
    uint8_t buf[] = {REG00_ADDR, state};
    sensor_serial_if_t *driver = dev->driver;
    
    return driver->write_reg(driver, buf, 1);
}


/**
 * @param state - combine SGM4151X_PFM_MODE_t,SGM4151X_WD_RST_t,SGM4151X_OTG_CONFIG_t
 *                SGM4151X_CHG_CONFIG_t, SGM4151X_SYS_MIN_t, SGM4151X_MIN_BAT_SEL_twith '|'
*/
int sgm4151x_set_reg1(sgm4151x_dev_t *dev, uint8_t state)
{
    DEV_ASSERT(dev);
    uint8_t buf[] = {REG01_ADDR, state};
    sensor_serial_if_t *driver = dev->driver;
    
    return driver->write_reg(driver, buf, 1);
}


/**
 * Watchdog Timer Reset Control Bit. Write 1 to this bit to 
 * avoid watchdog expiry.WD_RST resets to 0 after watchdog timer
 * reset (expiry).
 * Expiry time is 40s (default), watchdog can disable through REG05
*/
int sgm4151x_watchdog_reset(sgm4151x_dev_t *dev)
{
    uint8_t buf[] = {REG01_ADDR, 0};
    sensor_serial_if_t *driver = dev->driver;
    if(driver->read_reg(driver, buf, 1) != SENSOR_ERROR)
    {
        return SENSOR_ERROR_IO;
    }
    buf[1] |= WD_RESET;
    
    return driver->write_reg(driver, buf, 1);
}


/**
 * @param state - combine SGM4151X_BOOST_LIM_t,SGM4151X_Q1_FULLON_t,FAST_CHARGE_MA_TO_REG_VALUE
 *                with '|'
*/
int sgm4151x_set_reg2(sgm4151x_dev_t *dev, uint8_t state)
{
    DEV_ASSERT(dev);
    uint8_t buf[] = {REG02_ADDR, state};
    sensor_serial_if_t *driver = dev->driver;
    
    return driver->write_reg(driver, buf, 1);
}


/**
 * @param state - combine IPRECHG_MA_TO_REG_VALUE, ITERM_MA_TO_REG_VALUE with '|'
*/
int sgm4151x_set_reg3(sgm4151x_dev_t *dev, uint8_t state)
{
    DEV_ASSERT(dev);
    uint8_t buf[] = {REG03_ADDR, state};
    sensor_serial_if_t *driver = dev->driver;
    
    return driver->write_reg(driver, buf, 1);
}


/**
 * @param state - combine VREF_MV_TO_REG_VALUE, TOPOFF_TIMER_t,
 *                SGM4151X_BAT_RECHARGE_THRE_t with '|'
*/
int sgm4151x_set_reg4(sgm4151x_dev_t *dev, uint8_t state)
{
    DEV_ASSERT(dev);
    uint8_t buf[] = {REG04_ADDR, state};
    sensor_serial_if_t *driver = dev->driver;
    
    return driver->write_reg(driver, buf, 1);
}


/**
 * @param state - combine SGM4151X_TERM_STATE_t, SGM4151X_WATCHDOG_SETTING_t,
 *                SGM4151X_CHARGE_SAFETY_TIMER_STATE_t, 
 *                SGM4151X_CHARGE_SAFETY_TIMER_SETTING_t, 
 *                SGM4151X_THERMAL_REGULATION_THRESHOLD_t,
 *                SGM4151X_JEITA_CHARGING_CURRENT_t with '|'
 * use the default value may be is better
*/
int sgm4151x_set_reg5(sgm4151x_dev_t *dev, uint8_t state)
{
    DEV_ASSERT(dev);
    uint8_t buf[] = {REG05_ADDR, state};
    sensor_serial_if_t *driver = dev->driver;
    
    return driver->write_reg(driver, buf, 1);
}


/**
 * @param state - combine SGM4151X_OVP_THRESHOLD_t, SGM4151X_BOOSTV_t,
 *                VINDPM_MV_TO_REG_VALUE with '|'
 * use the default value may be is better
*/
int sgm4151x_set_reg6(sgm4151x_dev_t *dev, uint8_t state)
{
    DEV_ASSERT(dev);
    uint8_t buf[] = {REG06_ADDR, state};
    sensor_serial_if_t *driver = dev->driver;
    
    return driver->write_reg(driver, buf, 1);
}


/**
 * @param state - combine SGM4151X_INPUT_CURRENT_LIMIT_DET_t, SGM4151X_TMR2X_STATE_t,
 *                SGM4151X_BATFET_STATE_t, SGM4151X_JEITA_VSET_t,
 *                SGM4151X_BATFET_DLY_t, SGM4151X_BATFET_RST_STATE_t, 
 *                SGM4151X_VDPM_BAT_TRACK_t with '|'
 * use the default value may be is better
*/
int sgm4151x_set_reg7(sgm4151x_dev_t *dev, uint8_t state)
{
    DEV_ASSERT(dev);
    uint8_t buf[] = {REG07_ADDR, state};
    sensor_serial_if_t *driver = dev->driver;
    
    return driver->write_reg(driver, buf, 1);
}

/**
 * after read, judjement the state use the combine of SGN4151X_VBUS_STAT_t
 * SGM4151X_CHRG_STAT_t, SGM4151X_OG_STAT_t, SGM4151X_THERM_STAT_t,
 * SGM4151X_VSYS_STAT_t with '&'
 * Notice:only read register
*/
int sgm4151x_get_status(sgm4151x_dev_t *dev, uint8_t *state)
{
    int ret = SENSOR_ERROR;
    DEV_ASSERT(dev);
    uint8_t buf[] = {REG08_ADDR, 0};
    sensor_serial_if_t *driver = dev->driver;

    ret = driver->read_reg(driver, buf, 1);
    *state = buf[1];

    return ret;
}


/**
 * after read, judjement the state use the combine of SGM4151_WATCHDOG_FAULT_STATUS_t
 * SGM4151_BOOST_FAULT_STATUS_t, SGM4151_CHRG_FAULT_STATUS_t, SGM4151_BAT_FAULT_STATUS_t,
 * SGM4151_NTC_FAULT_STATUS_t with '&'
 * Notice:only read register
*/
int sgm4151x_get_fault(sgm4151x_dev_t *dev, uint8_t *fault)
{
    int ret = SENSOR_ERROR;
    DEV_ASSERT(dev);
    uint8_t buf[] = {REG09_ADDR, 0};
    sensor_serial_if_t *driver = dev->driver;

    ret = driver->read_reg(driver, buf, 1);
    *fault = buf[1];

    return ret;
}


/**
 * combine of SGM4151X_VINDPM_INT_MASK_t, SGM4151X_IINDPM_INT_MASK_t with '|'
*/
int sgm4151x_set_reg10(sgm4151x_dev_t *dev, uint8_t state)
{
    DEV_ASSERT(dev);
    uint8_t buf[] = {REG10_ADDR, state};
    sensor_serial_if_t *driver = dev->driver;

    return driver->write_reg(driver, buf, 1);
}


/**
 * after read, judjement the state use the combine of SGM4151X_SOURCE_DETECTED_t
 * SGM4151X_VINDPM_STAT_t, SGM4151X_IINDPM_STAT_t, SGM4151X_TOPOFF_TIMER_STATUS_t,
 * SGM4151X_ACOV_STAT_t,SGM4151X_VINDPM_INT_MASK_t, SGM4151X_IINDPM_INT_MASK_t with '&'
*/
int sgm4151x_get_reg10(sgm4151x_dev_t *dev, uint8_t *state)
{
    int ret = SENSOR_ERROR;
    DEV_ASSERT(dev);
    uint8_t buf[] = {REG10_ADDR, 0};
    sensor_serial_if_t *driver = dev->driver;

    ret = driver->read_reg(driver, buf, 1);
    *state = buf[1];

    return ret;
}


int sgm4151x_reset(sgm4151x_dev_t *dev)
{
    DEV_ASSERT(dev);
    uint8_t buf[] = {REG11_ADDR, RESET_ALL};
    sensor_serial_if_t *driver = dev->driver;

    return driver->write_reg(driver, buf, 1);
}


bool sgm4151x_check_part_number(sgm4151x_dev_t *dev)
{
    DEV_ASSERT(dev);
    
    uint8_t buf[] = {REG11_ADDR, 0};
    uint8_t part_num = 0;
    sensor_serial_if_t *driver = dev->driver;
    
    driver->dev_addr = SGM4151X_7BIT_ADDR;
    driver->read_reg(driver, buf, 1);
    
    part_num = ((buf[1] & DEVICE_PART_ID_MASK) >> DEVICE_PART_ID_POS);
    
    
    return (part_num == DEVICE_PART_ID)? true: false;
}

int sgm4151x_device_init(sgm4151x_dev_t *dev)
{
    int ret = SENSOR_SUCCESS;

    if(!sgm4151x_check_part_number(dev))
    {
        return SENSOR_ERROR_CHECK_ID;
    }
    ret |= sgm4151x_set_reg0(dev, HIZ_MODE_DISABLE|STAT_PIN_ENABLE | dev->iindpm);
    ret |= sgm4151x_set_reg1(dev, PFM_ENABLE | WD_NORMAL | OTG_ENABLE | CHARGE_ENABLE | dev->sys_min_vol);
    ret |= sgm4151x_set_reg2(dev, BOOST_MODE_CURRENT_LIM_0_5A | dev->fast_charge_current);
    ret |= sgm4151x_set_reg3(dev, dev->iprechg | dev->iterm);
    ret |= sgm4151x_set_reg4(dev, dev->vreg | TOPOFF_TIMER_DISABLED | BELOW_VRECHG_100MV);

    return ret;
}

