Maxim Integrated / MAX17055_EZconfig

Dependents:   Low_Power_Long_Distance_IR_Vision_Robot MAX17055_EZconfig MAX17055_EZconfig_Sample Low_Power_Long_Distance_IR_Vision_Robot

Fork of max17055 by Maxim Integrated

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers max17055.cpp Source File

max17055.cpp

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