This is a library for the MAX17055 Li+ Battery Fuel Gauge.

Fork of max17055 by Central Applications - Mbed Code repo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers max17055.cpp Source File

max17055.cpp

Go to the documentation of this file.
00001 /******************************************************************//**
00002 * @file max17055.cpp
00003 *
00004 * @author Felipe Neira - Maxim Integrated - TTS
00005 *
00006 * @version 1.5
00007 *
00008 * Started: 13DEC17
00009 *
00010 * Updated: 16APR18.
00011 * Remove unnecessary code.  
00012 * Check spelling
00013 * Error check
00014 *
00015 *
00016 /*******************************************************************************
00017 * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
00018 *
00019 * Permission is hereby granted, free of charge, to any person obtaining a
00020 * copy of this software and associated documentation files (the "Software"),
00021 * to deal in the Software without restriction, including without limitation
00022 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00023 * and/or sell copies of the Software, and to permit persons to whom the
00024 * Software is furnished to do so, subject to the following conditions:
00025 *
00026 * The above copyright notice and this permission notice shall be included
00027 * in all copies or substantial portions of the Software.
00028 *
00029 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00030 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00031 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00032 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00033 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00034 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00035 * OTHER DEALINGS IN THE SOFTWARE.
00036 *
00037 * Except as contained in this notice, the name of Maxim Integrated
00038 * Products, Inc. shall not be used except as stated in the Maxim Integrated
00039 * Products, Inc. Branding Policy.
00040 *
00041 * The mere transfer of this software does not imply any licenses
00042 * of trade secrets, proprietary technology, copyrights, patents,
00043 * trademarks, maskwork rights, or any other form of intellectual
00044 * property whatsoever. Maxim Integrated Products, Inc. retains all
00045 * ownership rights.
00046 *******************************************************************************
00047 */
00048 
00049 #include "mbed.h"
00050 #include "max17055.h "
00051 
00052 /* POR Mask */
00053 #define MAX17055_POR_MASK               (0xFFFD)
00054 
00055 /* MODELCFG register bits */
00056 #define MAX17055_MODELCFG_REFRESH       (1 << 15)
00057 
00058 
00059 /* FSTAT register bits */
00060 #define MAX17055_FSTAT_DNR              (1)
00061 
00062 /* LIBRARY FUNCTION SUCCESS*/
00063 #define F_SUCCESS_0  0
00064 
00065 /* LIBRARY FUNCTION ERROR CODES */  
00066 #define F_ERROR_1 -1    //-1 if I2C read/write errors exist         
00067 #define F_ERROR_2 -2    //-2 if device is not present
00068 #define F_ERROR_3 -3    //-3 if function error
00069 #define F_ERROR_4 -4    //-4 if other error
00070 #define F_ERROR_5 -5    //-5 if POR not detected
00071 
00072 
00073 
00074 /**
00075  * @brief       max17055 Constructor
00076  * @details     max17055 Constructor with battery and i2c as parameters
00077  */
00078 MAX17055::MAX17055(I2C &i2c):
00079     m_i2cBus(i2c)
00080 {
00081     //empty block
00082 }
00083 
00084 /**
00085  * @brief       Fuel Gauge Destructor
00086  */
00087 MAX17055::~MAX17055()
00088 {
00089     //empty block
00090 }
00091 
00092 /**
00093  * @brief      Writes a register.
00094  *
00095  * @param[in]  reg_addr  The register address
00096  * @param[in]  reg_data  The register data
00097  *
00098  * @retval     0 on success
00099  * @retval     non-0 for errors
00100  */
00101 int MAX17055::writeReg(Registers_e reg_addr, uint16_t reg_data)
00102 {
00103 
00104     uint16_t mask = 0x00FF;
00105     uint8_t dataLSB;
00106     uint8_t dataMSB;
00107 
00108     dataLSB = reg_data & mask;
00109     dataMSB = (reg_data >> 8) & mask;
00110 
00111     char addr_plus_data[3] = {reg_addr, dataLSB, dataMSB};
00112 
00113     if ( m_i2cBus.write(I2C_W_ADRS, addr_plus_data, 3, false) == F_SUCCESS_0)
00114         return F_SUCCESS_0;
00115     else
00116         return F_ERROR_1;
00117 }
00118 
00119 /**
00120  * @brief      Reads from MAX17055 register.
00121  *
00122  * @param[in]  reg_addr  The register address
00123  * @param      value     The value
00124  *
00125  * @retval     0 on success
00126  * @retval     non-0 for errors
00127  */
00128 int32_t MAX17055::readReg(Registers_e reg_addr, uint16_t &value)
00129 {
00130     int32_t result;
00131     uint16_t mask = 0x00FF;
00132     char local_data[1];
00133     local_data[0] = reg_addr;
00134     char read_data[2];
00135 
00136     result = m_i2cBus.write(I2C_W_ADRS, local_data, 1);
00137     if(result == F_SUCCESS_0) {
00138         result = m_i2cBus.read(I2C_R_ADRS, read_data , 2, false);
00139         if (result == F_SUCCESS_0) {
00140             value = ( ((read_data[1] & mask) << 8) + (read_data[0]));
00141             result = F_SUCCESS_0;
00142         }
00143     }
00144     return result;
00145 }
00146 
00147 /**
00148  * @brief        Write and Verify a MAX17055 register
00149  * @par          Details
00150  *               This function writes and verifies if the writing process was successful
00151  *               
00152  * @param[in]    reg_addr     - register address
00153  * @param[out]   reg_data     - the variable that contains the data to write
00154  *                               to the register address
00155  *
00156  * @retval       0 on success
00157  * @retval       non-0 for errors
00158  */
00159 int MAX17055::write_and_verify_reg(Registers_e reg_addr, uint16_t reg_data)
00160 {
00161     int retries = 8;
00162     int ret;
00163     int statusRead;
00164     int statusWrite;
00165     uint16_t read_data;
00166 
00167     do {
00168         statusWrite = writeReg(reg_addr, reg_data);
00169         if (statusWrite != F_SUCCESS_0)
00170             ret = -6;
00171         wait_ms(3);
00172         statusRead = readReg(reg_addr, read_data);
00173         if  (statusRead != F_SUCCESS_0)
00174             ret = -7;
00175         if (read_data != reg_data) {
00176             ret = -8;
00177             retries--;
00178         }
00179     } while (retries && read_data != reg_data);
00180 
00181     if (ret!=F_SUCCESS_0)
00182         return ret;
00183     else
00184         return F_SUCCESS_0;
00185 }
00186 
00187 /**
00188  * @brief       Initialization Function for MAX17055.
00189  * @par         Details
00190  *              This function initializes the MAX17055 for the implementation of the EZconfig model.\n
00191  *              The library needs to be customized for the implementation of customize model.\n  
00192  *              
00193  * @retval      0 on success 
00194  * @retval      non-0 for errors
00195  */
00196 int MAX17055::init(platform_data des_data)
00197 {
00198 
00199     int status, ret;
00200     int time_out = 10;
00201     uint16_t hibcfg_value,read_data;
00202 
00203 
00204     status = readReg(VERSION_REG , read_data);
00205     if (status != F_SUCCESS_0)
00206         return status;
00207 
00208     ///STEP 0. Check for POR (Skip load model if POR bit is cleared)
00209 
00210     if (check_POR_func() == F_ERROR_5)
00211         return F_ERROR_5;  //POR not detected. Skip Initialization.
00212     //This is not an error. 
00213 
00214     ///STEP 1. Check if FStat.DNR == 0 (Do not continue until FSTAT.DNR == 0)
00215     ret = poll_flag_clear(FSTAT_REG , MAX17055_FSTAT_DNR, time_out);
00216     if (ret < F_SUCCESS_0) {
00217         return ret;
00218     }
00219 
00220     ///STEP 1.2. Force exit from hibernate
00221     hibcfg_value = forcedExitHiberMode();
00222 
00223     //printf("step 1 check \r\n");
00224 
00225     ///STEP 2. Initialize configuration
00226     switch (1) {
00227         case MODEL_LOADING_OPTION1:
00228             ///STEP 2.1. Load EZ Config
00229             EZconfig_init(des_data);
00230 
00231             ///STEP 2.2. Poll ModelCFG.ModelRefresh bit for clear
00232             ret = poll_flag_clear(MODELCFG_REG , MAX17055_MODELCFG_REFRESH, time_out);
00233             if(ret < F_SUCCESS_0) {
00234                 return ret;
00235             }
00236 
00237             break; 
00238     }
00239     ///STEP3. Restore original HibCfg
00240     writeReg(HIBCFG_REG , hibcfg_value);
00241 
00242     /* Clear Status.POR */
00243     ret = clear_POR_bit();
00244     if (ret < F_SUCCESS_0)
00245         return ret; //See errors   
00246     return F_SUCCESS_0;
00247 }
00248 
00249 /**
00250  * @brief      Check POR function
00251  * @par Details
00252  *     This function check is there was a power on reset event for the
00253  *     MAX17055
00254  *
00255  * @retval    0 on success (POR detected)
00256  * @retval    non-0 for errors (POR not detected)
00257  * 
00258  */
00259 int MAX17055::check_POR_func()
00260 {
00261     uint16_t read_data;
00262     
00263     readReg(STATUS_REG , read_data);
00264 
00265     if (!(read_data & MAX17055_STATUS_POR ) )
00266         return F_ERROR_5;  //POR not detected.
00267     else 
00268         return F_SUCCESS_0;
00269 }
00270 
00271 /**
00272  * @brief        clear POR bit function
00273  * @par          Details
00274  *               This function clear the indicating bit for POR - MAX17055
00275  *
00276  * @retval       0 for Success
00277  * @retval      non-0 for errors
00278  */
00279 int MAX17055::clear_POR_bit()
00280 {
00281     int status, ret;
00282     uint16_t read_data, hibcfg_value, reg;
00283 
00284 
00285     status = readReg(STATUS_REG , read_data);
00286     if (status != F_SUCCESS_0)
00287         return F_ERROR_2;  //Device is not present in the i2c Bus
00288     status = write_and_verify_reg(STATUS_REG , (read_data & MAX17055_POR_MASK));
00289     if (status != F_SUCCESS_0)
00290         return F_ERROR_1; //read or write error
00291     else 
00292         return F_SUCCESS_0;
00293 }
00294 
00295 /**
00296  * @brief      Poll Flag clear Function. 
00297  * @par Details
00298  *     This function clears status flags for the MAX17055
00299  *
00300  * @param[in]  reg_addr  - register address
00301  * @param[in]  mask      - register address
00302  * @param[in]  timeout   - register data
00303  *
00304  * @retval     0 on success 
00305  * @retval    non-0 negative for errors
00306  */
00307 int MAX17055::poll_flag_clear (Registers_e reg_addr, int mask, int timeout)
00308 {
00309     uint16_t data;
00310     int ret;
00311 
00312     do {
00313         wait_ms(1);
00314         ret = readReg(reg_addr, data);
00315         if(ret < F_SUCCESS_0)
00316             return F_ERROR_1;
00317 
00318         if(!(data & mask))
00319             return F_SUCCESS_0;
00320 
00321         timeout -= 1;
00322     } while(timeout > 0);
00323 
00324     return F_ERROR_4;
00325 }
00326 
00327 /**
00328  * @brief        Get Temperature Function from the MAX17055 TEMP register.
00329  * @par          Details
00330  *               This function sends a request to access the TEMP register
00331  *               of the MAX17055, which reflects the temperature measured for the fuel gauge. 
00332  *               The temperature values will reflect the Config Register (0x1D) selections for Tsel bit (D15).
00333  *               For this library the setting are for die temperature.
00334  *               The MAX32620FTHR thermistor bias pin is not connected. The biasing of the thermistor is
00335  *               done by the MAX77650. See MAX77650 library for how to enable the thermistor biasing.  
00336  *
00337  *   
00338  * @retval      temp - Temperature value from TEMP register in &deg;C
00339  * @retval      non-0 negative values check for errors
00340  */
00341 int MAX17055::get_temperature()
00342 {
00343 
00344     int ret;
00345     uint16_t temp;
00346 
00347     ret = readReg(TEMP_REG , temp);
00348     if (ret < F_SUCCESS_0)
00349         return ret;
00350 
00351     /* The value is signed. */
00352     if (temp & 0x8000)
00353         temp |= 0xFFFF0000;
00354 
00355     /* The value is converted into centigrade scale */
00356     /* Units of LSB = 1 / 256 degree Celsius */
00357     temp >>= 8;
00358 
00359     return temp;
00360 }
00361 
00362 /**
00363  * @brief        Forced Exit Hibernate Mode Function for MAX17055
00364  * @par          Details
00365  *               This function executes a force exit from hibernate mode.
00366  *
00367  * @retval       HibCFG original value before forced Exit Hibernate mode *
00368  */
00369 uint16_t MAX17055::forcedExitHiberMode()
00370 {
00371     uint16_t hibcfg;
00372 
00373     /* Force exit from hibernate */
00374     //STEP 0: Store original HibCFG value
00375     readReg(HIBCFG_REG , hibcfg);
00376 
00377     //STEP 1: Write to Soft-Wakeup Command Register
00378     writeReg(VFSOC0_QH0_LOCK_REG , 0x90); //Soft-Wakeup from hibernate
00379 
00380     //STEP 2: Write to Hibernate Configuration register
00381     writeReg(HIBCFG_REG , 0x0); //disable hibernate mode
00382 
00383     //STEP 3:Write to Soft-Wakeup Command Register
00384     writeReg(VFSOC0_QH0_LOCK_REG , 0x0); //Clear All commands
00385 
00386     return hibcfg;
00387 }
00388 
00389 /**
00390  * @brief        EZ Config Initialization function
00391  * @par          Details
00392  *               This function implements the steps for the EZ config m5 FuelGauge
00393  * @param[in]    des_data - Plataform_data struct with information about the design.
00394  * @retval       0 on success
00395  * @retval       non-zero for errors
00396  */
00397 uint16_t MAX17055::EZconfig_init(platform_data des_data)
00398 {
00399     ///STEP 2.1.1 EZ config values suggested by manufacturer.
00400     const int charger_th = 4275;
00401     const int chg_V_high = 51200; // scaling factor high voltage charger
00402     const int chg_V_low = 44138;
00403     const int param_EZ_FG1 = 0x8400; // Sets config bit for the charge voltage for the m5
00404     const int param_EZ_FG2 = 0x8000;
00405     uint16_t dpacc, ret;
00406 
00407     ///STEP 2.1.2 Store the EZ Config values into the appropriate registers. 
00408     ret = writeReg(DESIGNCAP_REG , des_data.designcap );
00409     ret = writeReg(DQACC_REG , des_data.designcap  >> 5);  //DesignCap divide by 32
00410     ret = writeReg(ICHGTERM_REG , des_data.ichgterm );
00411     ret = writeReg(VEMPTY_REG , des_data.vempty );
00412 
00413     if (des_data.vcharge  > charger_th) {
00414         dpacc = (des_data.designcap  >> 5) * chg_V_high / des_data.designcap ;
00415         ret = writeReg(DPACC_REG , dpacc);
00416         ret = writeReg(MODELCFG_REG , param_EZ_FG1); // 
00417     } else {
00418         dpacc = (des_data.designcap  >> 5) * chg_V_low / des_data.designcap ;
00419         ret = writeReg(DPACC_REG , dpacc);
00420         ret = writeReg(MODELCFG_REG , param_EZ_FG2);
00421     }
00422     return ret;
00423 }
00424 
00425 /**
00426  * @brief        Get reported State Of Charge(SOC) Function from MAX17055 Fuel Gauge.
00427  * @par          Details
00428  *               This function sends a request to access the RepSOC register
00429  *               of the MAX17055. RepSOC is the reported state-of-charge percentage output of the fuel gauge. 
00430  *
00431  * @retval      soc_data - Reported SOC data from the RepSOC register in % value.
00432  * @retval      non-0 negative values check for errors 
00433  */
00434 int MAX17055::get_SOC()
00435 {
00436 
00437     int ret;
00438     uint16_t soc_data;
00439 
00440     ret = readReg(REPSOC_REG , soc_data);
00441     if (ret < F_SUCCESS_0)
00442         return ret;
00443 
00444     soc_data = soc_data >> 8; /* RepSOC LSB: 1/256 % */
00445 
00446     return soc_data;
00447 }
00448 
00449 /**
00450  * @brief       Get at rate Average State Of Charge(SOC) Function from MAX17055 Fuel Gauge.
00451  * @par          Details
00452  *               This function sends a request to access the atAvSOC register of the MAX17055.
00453  *               The AvSOC registers hold the calculated available capacity and percentage of the
00454  *               battery based on all inputs from the ModelGauge m5 algorithm including empty 
00455  *               compensation. These registers provide unfiltered results. Jumps in the reported 
00456  *               values can be caused by abrupt changes in load current or temperature.
00457  *
00458  * @retval       atAvSOC_data - Average SOC data from the atAVSOC register in % value. 
00459  * @retval       non-0 negative values check for errors      
00460  */
00461 int MAX17055::get_atAvSOC()
00462 {
00463     int ret;
00464     uint16_t atAvSOC_data;
00465 
00466     ret = readReg(AVSOC_REG , atAvSOC_data);
00467     if (ret < F_SUCCESS_0)
00468         return ret; //Check errors if data is not correct
00469 
00470     atAvSOC_data = atAvSOC_data >> 8; /* avSOC LSB: 1/256 % */
00471 
00472     return atAvSOC_data;
00473 }
00474 
00475 /**
00476  * @brief        Get mix State Of Charge(SOC) Function for MAX17055 Fuel Gauge.
00477  * @par          Details
00478  *               This function sends a request to access mixSOC register
00479  *               of the MAX17055. The MixSOC registers holds the calculated
00480  *               remaining capacity and percentage of the cell before any empty compensation
00481  *               adjustments are performed.
00482  * 
00483  * @retval       mixSOC_data - Mixed SOC register values from the mixSOC register in % value. 
00484  * @retval       non-0 for errors
00485  */
00486 int MAX17055::get_mixSOC()
00487 {
00488     int ret;
00489     uint16_t mixSOC_data;
00490 
00491     ret = readReg(MIXSOC_REG , mixSOC_data);
00492     if (ret < F_SUCCESS_0)
00493         return ret;
00494 
00495     mixSOC_data = mixSOC_data >> 8; /* RepSOC LSB: 1/256 % */
00496 
00497     return mixSOC_data;
00498 }
00499 
00500 /**
00501  * @brief       Get the Time to Empty(TTE) Function form MAX17055 Fuel Gauge.
00502  * @par         Details
00503  *              This function sends a request to access the TTE register
00504  *              of the MAX17055
00505  *              The TTE register holds the estimated time to empty for the 
00506  *              application under present temperature and load conditions. The TTE value is 
00507  *              determined by relating AvCap with AvgCurrent. The corresponding AvgCurrent 
00508  *              filtering gives a delay in TTE, but provides more stable results.
00509  *
00510  * @retval      tte_data - Time to Empty data from the TTE register in seconds.
00511  * @retval      non-0 negative values check for errors
00512  */
00513 float MAX17055::get_TTE()
00514 {
00515 
00516     int ret;
00517     uint16_t tte_data;
00518     float f_tte_data;
00519 
00520     ret = readReg(TTE_REG , tte_data);
00521     if (ret < F_SUCCESS_0)
00522         return ret;
00523     else
00524         f_tte_data = ((float)tte_data * 5.625); /* TTE LSB: 5.625 sec */
00525 
00526     return f_tte_data;
00527 }
00528 
00529 /**
00530  * @brief       Get the at Time to Empty(atTTE) value Function for MAX17055 Fuel Gauge.
00531  * @par         Details
00532  *              This function sends a request to access the internal register
00533  *              of the MAX17055
00534  *
00535  * @retval      atTTE_data - Time to Empty data from the atTTE register in seconds. 
00536  * @retval      non-0 negative values check for errors
00537  */
00538 float MAX17055::get_atTTE()
00539 {
00540 
00541     int ret;
00542     uint16_t atTTE_data;
00543     float f_atTTE_data;
00544 
00545     ret = readReg(ATTTE_REG , atTTE_data);
00546     if (ret < F_SUCCESS_0)
00547         return ret; //Check for errors
00548     else
00549         f_atTTE_data = ((float)atTTE_data * 5.625); /* TTE LSB: 5.625 sec */
00550 
00551     return  f_atTTE_data;
00552 }
00553 
00554 /**
00555  * @brief      Get the Time to Full(TTE) values Function for MAX17055 Fuel Gauge.
00556  * @par        Details
00557  *             This function sends a request to access the internal register of the MAX17055
00558  *             The TTF register holds the estimated time to full for the application
00559  *             under present conditions. The TTF value is determined by learning the
00560  *             constant current and constant voltage portions of the charge cycle based
00561  *             on experience of prior charge cycles. Time to full is then estimate 
00562  *             by comparing present charge current to the charge termination current. 
00563  *             Operation of the TTF register assumes all charge profiles are consistent in the application.
00564  *
00565  * @retval     ttf_data - Time to Full data from the TTF register in seconds. 
00566  * @retval     non-0 negative values check for errors
00567  */
00568 float MAX17055::get_TTF()
00569 {
00570 
00571     int ret;
00572     uint16_t ttf_data;
00573     float f_ttf_data;
00574 
00575     ret = readReg(TTF_REG , ttf_data);
00576     if (ret < F_SUCCESS_0)
00577         return ret;
00578     else
00579         f_ttf_data = ((float)ttf_data * 5.625); /* TTE LSB: 5.625 sec */
00580 
00581     return  f_ttf_data;
00582 }
00583 
00584 /**
00585  * @brief       Get voltage of the cell Function for MAX17055 Fuel Gauge.
00586  * @par         Details
00587  *              This function sends a request to access the VCell Register
00588  *              of the MAX17055 to read the measured voltage from the cell. 
00589  *              
00590  * @retval      vcell_data  - vcell data from the VCELL_REG register in uVolts.
00591  * @retval      non-0 negative values check for errors
00592  */
00593 int MAX17055::get_Vcell()
00594 {
00595 
00596     int ret;
00597     uint16_t vcell_data;
00598 
00599     ret = readReg(VCELL_REG , vcell_data);
00600     if (ret < F_SUCCESS_0)
00601         return ret;
00602     else
00603         ret = lsb_to_uvolts(vcell_data);
00604     return ret;
00605 }
00606 
00607 /**
00608  * @brief       Get current Function for MAX17055 Fuel Gauge.
00609  * @par         Details
00610  *              This function sends a request to access the CURRENT register
00611  *              of the MAX17055 to read the current readings. 
00612  *
00613  * @param[in]   des_data - Plataform_data struct with information about the design.
00614  * 
00615  * @retval      curr_data  - current data from the CURRENT register in uAmps. 
00616  * @retval      non-0 negative values check for errors.
00617  */
00618 int MAX17055::get_Current( platform_data des_data )
00619 {
00620 
00621     int ret,design_rsense;
00622     uint16_t curr_data;
00623 
00624     ret = readReg(CURRENT_REG , curr_data);
00625     if (ret < F_SUCCESS_0)
00626         return ret;
00627     else
00628     design_rsense = des_data.rsense;
00629     ret = raw_current_to_uamps((uint32_t)curr_data, design_rsense);
00630     return ret;
00631 }
00632 
00633 /**
00634  * @brief       Get average current Function for MAX17055 Fuel Gauge.
00635  * @par         Details
00636  *              This function sends a request to access the aveCURRENT register
00637  *              of the MAX17055 to read the average current readings. 
00638  *
00639  * @param[in]   des_data - Plataform_data struct with information about the design.
00640  * 
00641  * @retval      aveCurr_data - current data from the AVGCURRENT register in uAmps. 
00642  * @retval      non-0 negative values check for errors.
00643  */
00644 int MAX17055::get_AvgCurrent( platform_data des_data )
00645 {
00646     int ret, design_rsense;
00647     uint16_t data;
00648     uint32_t aveCurr_data;
00649 
00650     ret = readReg(AVGCURRENT_REG , data);
00651     if (ret < F_SUCCESS_0)
00652         return ret;
00653     else
00654     aveCurr_data = data;
00655     design_rsense = des_data.rsense;
00656     aveCurr_data = raw_current_to_uamps(aveCurr_data, design_rsense);
00657     return aveCurr_data;
00658 }
00659 
00660 /**
00661  * @brief        lsb_to_uvolts Conversion Function 
00662  * @par          Details
00663  *               This function takes the lsb value of the register and convert it
00664  *               to uvolts
00665  *
00666  * @param[in]   lsb - value of register lsb
00667  * @retval      conv_2_uvolts - value converted lsb to uvolts        
00668  */
00669 int MAX17055:: lsb_to_uvolts(uint16_t lsb)
00670 {
00671     int conv_2_uvolts;
00672     conv_2_uvolts = (lsb * 625) / 8; /* 78.125uV per bit */
00673     return conv_2_uvolts;
00674 }
00675 
00676 /**
00677  * @brief        raw_current_to_uamp Conversion Function 
00678  * @par          Details
00679  *               This function takes the raw current value of the register and 
00680  *               converts it to uamps
00681  *
00682  * @param[in]   curr - raw current value of register 
00683  * @retval      res  - converted raw current to uamps (Signed 2's complement)         
00684  */
00685 int MAX17055::raw_current_to_uamps(uint32_t curr, int rsense_value)
00686 {
00687     int res = curr;
00688     /* Negative */
00689     if (res & 0x8000) {
00690         res |= 0xFFFF0000;
00691     } else {
00692         res *= 1562500 /(rsense_value * 1000); //Change to interact with the rsense implemented in the design
00693     }
00694     return res;
00695 }
00696 
00697 /**
00698  * @brief        Save Learned Parameters Function for battery Fuel Gauge model.  
00699  * @par          Details
00700  *               It is recommended to save the learned capacity parameters every
00701  *               time bit 2 of the Cycles register toggles
00702  *               (so that it is saved every 64% change in the battery) 
00703  *               so that if power is lost the values can easily be restored.
00704  *
00705  * @param[in]   FG_params Fuel Gauge Parameters based on design details. 
00706  * 
00707  * @retval      0 for success
00708  * @retval      non-0 negative for errors
00709  */
00710 int MAX17055::save_Params(saved_FG_params_t FG_params)
00711 {
00712     int ret, value;
00713     uint16_t data[5];
00714     ///STEP 1. Checks if the cycel register bit 2 has changed.
00715     ret = readReg(CYCLES_REG , data[3]);
00716     if (ret < F_SUCCESS_0)
00717         return ret;
00718     else {
00719         value = data[3];
00720     }
00721 
00722     ///STEP 2. Save the capacity parameters for the specific battery.
00723     ret = readReg(RCOMP0_REG , data[0]);
00724     if (ret < F_SUCCESS_0)
00725         return ret;
00726     else
00727         FG_params.rcomp0 = data[0];
00728 
00729     ret = readReg(TEMPCO_REG , data[1]);
00730     if (ret < F_SUCCESS_0)
00731         return ret;
00732     else
00733         FG_params.temp_co = data[1];
00734 
00735     ret = readReg(FULLCAPREP_REG , data[2]);
00736     if (ret < F_SUCCESS_0)
00737         return ret;
00738     else
00739         FG_params.full_cap_rep = data[2];
00740 
00741     FG_params.cycles = data[3];
00742 
00743     ret = readReg(FULLCAPNOM_REG , data[4]);
00744     if (ret < F_SUCCESS_0)
00745         return ret;
00746     else
00747         FG_params.full_cap_nom = data[4];
00748     return ret;
00749 }
00750 
00751 /**
00752  * @brief        Restore Parameters Function for battery Fuel Gauge model.
00753  * @par          Details
00754  *               If power is lost, then the capacity information 
00755  *               can be easily restored with this function. 
00756  *
00757  * @param[in]   FG_params Struct for Fuel Gauge Parameters 
00758  * @retval      0 for success
00759  * @retval      non-0 negative for errors
00760  */
00761 int MAX17055::restore_Params(saved_FG_params_t FG_params)
00762 {
00763     int ret;
00764     uint16_t temp_data, fullcapnom_data, mixCap_calc, dQacc_calc;
00765     uint16_t dPacc_value = 0x0C80;//Set it to 200%
00766 
00767     ///STEP 1. Restoring capacity parameters 
00768     write_and_verify_reg(RCOMP0_REG , FG_params.rcomp0);
00769     write_and_verify_reg(TEMPCO_REG , FG_params.temp_co);
00770     write_and_verify_reg(FULLCAPNOM_REG , FG_params.full_cap_nom);
00771     
00772     wait_ms(350);//check the type of wait
00773     
00774     ///STEP 2. Restore FullCap
00775     ret = readReg(FULLCAPNOM_REG , fullcapnom_data);
00776     if (ret < F_SUCCESS_0)
00777         return ret;
00778 
00779     ret = readReg(MIXSOC_REG , temp_data); //check if Error in software guide register incorrect
00780     if (ret < F_SUCCESS_0)
00781         return ret;
00782     
00783     mixCap_calc = (temp_data*fullcapnom_data)/25600;
00784 
00785     write_and_verify_reg(MIXCAP_REG , mixCap_calc);
00786     write_and_verify_reg(FULLCAPREP_REG , FG_params.full_cap_rep);
00787     
00788     ///STEP 3. Write DQACC to 200% of Capacity and DPACC to 200%
00789     dQacc_calc = (FG_params.full_cap_nom/ 16) ;
00790 
00791     write_and_verify_reg(DPACC_REG , dPacc_value);
00792     write_and_verify_reg(DQACC_REG , dQacc_calc);
00793 
00794     wait_ms(350);
00795 
00796     ///STEP 4. Restore Cycles register
00797     ret = write_and_verify_reg(CYCLES_REG , FG_params.cycles);
00798     if (ret < F_SUCCESS_0)
00799         return ret;
00800     return ret;
00801 }
00802 
00803 /**
00804  * @brief        Function to Save Average Current to At Rate register.
00805  * @par          Details
00806  *               For User friendliness display of atTTE, atAvSOC, atAvCAP
00807  *               write the average current to At Rate registers every 10sec 
00808  *               when the battery is in use.
00809  *               NOTE: do not use this function when the Battery is charging. 
00810  *
00811  * @retval      0 for success
00812  * @retval      non-0 negative for errors
00813  */
00814 int MAX17055::avCurr_2_atRate()
00815 {
00816     int ret;
00817     uint16_t avCurr_data;
00818 
00819     ret = readReg(AVGCURRENT_REG , avCurr_data);
00820     if (ret < F_SUCCESS_0){
00821         return ret = -3;
00822     }      
00823 
00824     //Write avCurrent to atRate Register
00825     ret = writeReg(ATRATE_REG , avCurr_data);
00826     if (ret < F_SUCCESS_0){
00827         return ret;
00828     }
00829     return F_SUCCESS_0;
00830 }