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

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

Revision:
7:479a36909ced
Parent:
6:5ced10109ebf
Child:
8:ca8765c30ed2
--- a/max17055.cpp	Thu Oct 05 02:37:59 2017 +0000
+++ b/max17055.cpp	Tue Oct 10 00:06:40 2017 +0000
@@ -112,16 +112,16 @@
 int MAX17055::writeReg(Registers_e reg_addr, uint16_t reg_data)
 {
 
-
+    uint16_t mask = 0x00FF;
     uint8_t dataLSB;
     uint8_t dataMSB;
 
-    dataLSB = reg_data & 0x00FF;
-    dataMSB = (reg_data >> 8) & 0x00FF;
+    dataLSB = reg_data & mask;
+    dataMSB = (reg_data >> 8) & mask;
 
-    char add_plus_data[3] = {reg_addr, dataLSB, dataMSB};
+    char addr_plus_data[3] = {reg_addr, dataLSB, dataMSB};
 
-    if ( m_i2cBus.write(I2C_W_ADRS, add_plus_data, 3, false) == 0)
+    if ( m_i2cBus.write(I2C_W_ADRS, addr_plus_data, 3, false) == 0)
         return 1;
     else
         return 0;
@@ -143,8 +143,7 @@
 int32_t MAX17055::readReg(Registers_e reg_addr, uint16_t &value)
 {
     int32_t result;
-    //int16_t value2;
-    //int16_t twoBytes;
+    uint16_t mask = 0x00FF;
     char local_data[1];
     local_data[0] = reg_addr;
     char read_data[2];
@@ -153,7 +152,7 @@
     if(result == 0) {
         result = m_i2cBus.read(I2C_R_ADRS, read_data , 2, false);
         if (result == 0) {
-            value = ( ((read_data[1] & 0x00FF) << 8) + (read_data[0]));
+            value = ( ((read_data[1] & mask) << 8) + (read_data[0]));
             result = 1;
         }
     }
@@ -200,7 +199,7 @@
 
     if (ret<0)
         return ret;
-     else 
+    else
         return 1;
 }
 
@@ -217,21 +216,21 @@
 */
 
 
-int MAX17055::init(max17055_platform_data des_data)
+int MAX17055::init(platform_data des_data)
 {
 
     int status, ret;
-    uint16_t read_data, hibcfg_value, dpacc, reg;
+    uint16_t read_data, hibcfg_value, reg;
 
 
-    status = readReg(MAX17055_VERSION_REG, read_data);
+    status = readReg(VERSION_REG, read_data);
     if (status == 0)
         return status;  //Device is not present in the i2c Bus
 
     /* Step 0: Check for POR */
     /* Skip load model if POR bit is cleared */
 
-    readReg(MAX17055_STATUS_REG, read_data);
+    readReg(STATUS_REG, read_data);
 
     if (!(read_data & MAX17055_STATUS_POR ) )
         return -1;  //POR is not set. Skip Initialization.
@@ -239,57 +238,46 @@
     /* Step 1: Check if FStat.DNR == 0 */
     // Do not continue until FSTAT.DNR == 0
     printf("step 0 check \r\n");
-    
+
     int time_out = 500;
-    ret = max17055_poll_flag_clear (MAX17055_FSTAT_REG, MAX17055_FSTAT_DNR, time_out);
-    if (ret < 0){
+    ret = poll_flag_clear(FSTAT_REG, MAX17055_FSTAT_DNR, time_out);
+    if (ret < 0) {
         printf("Unsuccessful init: Data Not Ready!\n");
         return ret;
     }
 
     /* Force exit from hibernate */
     hibcfg_value = forcedExitHyberMode();
-    
+
     printf("step 1 check \r\n");
 
     /* Step 2: Initialize configuration */
     switch (1) {
         case MODEL_LOADING_OPTION1:
             /* Step 2.1: Option 1 EZ Config */
-            writeReg(MAX17055_DESIGNCAP_REG, des_data.designcap);
-            writeReg(MAX17055_DQACC_REG, des_data.designcap >> 5);
-            writeReg(MAX17055_ICHGTERM_REG, des_data.ichgterm);
-            writeReg(MAX17055_VEMPTY_REG, des_data.vempty);
-
-            if (design_data.vcharge > 4275) { //Need to know what this 4275 is
-                dpacc = (des_data.designcap >> 5) * 0xC800 / des_data.designcap;
-                writeReg(MAX17055_DPACC_REG, dpacc);
-                writeReg(MAX17055_MODELCFG_REG, 0x8400); //Why 0x8400
-            } else {
-                dpacc = (des_data.designcap >> 5) * 0xAC6A / des_data.designcap;
-                writeReg(MAX17055_DPACC_REG, dpacc);
-                writeReg(MAX17055_MODELCFG_REG, 0x8000);
-            }
+            EZconfig_init(des_data);
 
             /* Poll ModelCFG.ModelRefresh bit for clear */
-            ret = max17055_poll_flag_clear(MAX17055_MODELCFG_REG, MAX17055_MODELCFG_REFRESH, 500);
+            int time_out = 500; //msec
+            ret = poll_flag_clear(MODELCFG_REG, MAX17055_MODELCFG_REFRESH, time_out);
             if(ret < 0) {
                 //dev_err(priv->dev, "Option1 model refresh not completed!\n");
                 return ret;
             }
+
             break;
     }
     /* Restore original HibCfg */
-    writeReg(MAX17055_HIBCFG_REG, hibcfg_value);
+    writeReg(HIBCFG_REG, hibcfg_value);
     printf("Last section check \r\n");
 
 
     /* Optional step - alert threshold initialization */
-    //max17055_set_alert_thresholds(priv);
+    //set_alert_thresholds(priv);
 
     /* Clear Status.POR */
-    readReg(MAX17055_STATUS_REG, reg);
-    write_and_verify_reg(MAX17055_STATUS_REG, (reg & ~MAX17055_STATUS_POR));
+    readReg(STATUS_REG, reg);
+    write_and_verify_reg(STATUS_REG, (reg & ~MAX17055_STATUS_POR));
 
     return 1;
 }
@@ -310,13 +298,13 @@
 *              -1 on Failure
 */
 
-int MAX17055::max17055_poll_flag_clear (Registers_e reg_addr, int mask, int timeout)
+int MAX17055::poll_flag_clear (Registers_e reg_addr, int mask, int timeout)
 {
     uint16_t data;
     int ret;
 
     do {
-        wait(50);
+        wait_ms(10);
         ret = readReg(reg_addr, data);
         if(ret < 0)
             return ret;
@@ -324,7 +312,7 @@
         if(!(data & mask))
             return 1;
 
-        timeout -= 50;
+        timeout -= 10;
     } while(timeout > 0);
 
     return -1;
@@ -340,35 +328,31 @@
 *               This function sends a request to access the internal
 *               of the MAX17055
 *
-* \param[in]    reg_addr     - register address
-* \param[out]   reg_data     - the variable that contains the data to write
-*                                to the register address
-* \retval       1 on success
 *
+* \retval      temperature value
 *              -1 if errors exist
 */
 
 
-int MAX17055::get_temperature(int *temp)
+int MAX17055::get_temperature()
 {
 
     int ret;
     uint16_t data;
 
-    ret = readReg(MAX17055_TEMP_REG, data);
+    ret = readReg(TEMP_REG, data);
     if (ret < 0)
         return ret;
 
-    *temp = data;
     /* The value is signed. */
-    if (*temp & 0x8000)
-        *temp |= 0xFFFF0000;
+    if (data & 0x8000)
+        data |= 0xFFFF0000;
 
     /* The value is converted into centigrade scale */
     /* Units of LSB = 1 / 256 degree Celsius */
-    *temp >>= 8;
+    data >>= 8;
 
-    return 1;
+    return data ;
 }
 
 
@@ -389,18 +373,265 @@
     uint16_t hibcfg;
 
     /* Force exit from hibernate */
-
     //STEP 0: Store original HibCFG value
-    readReg(MAX17055_HIBCFG_REG, hibcfg);
+    readReg(HIBCFG_REG, hibcfg);
 
     //STEP 1: Write to Soft-Wakeup Commannd Register
-    writeReg(MAX17055_VFSOC0_QH0_LOCK_REG, 0x90); //Soft-Wakeup from hybernate
+    writeReg(VFSOC0_QH0_LOCK_REG, 0x90); //Soft-Wakeup from hybernate
 
     //STEP 2: Write to Hibernate Configuration register
-    writeReg(MAX17055_HIBCFG_REG, 0x0); //disable hibernate mode
+    writeReg(HIBCFG_REG, 0x0); //disable hibernate mode
 
     //STEP 3:Write to Soft-Wakeup Commannd Register
-    writeReg(MAX17055_VFSOC0_QH0_LOCK_REG, 0x0); //Clear All commnads
+    writeReg(VFSOC0_QH0_LOCK_REG, 0x0); //Clear All commnads
 
     return hibcfg;
 }
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+* \brief        EZ COnfing Init function
+* \par          Details
+*               This function implements the steps for the EZ confing m5 FuelGauge
+*
+* \retval       returns TBD
+*
+*/
+
+
+uint16_t MAX17055::EZconfig_init(platform_data des_data)
+{
+    const int charger_th = 4275;
+    const int chg_V_high = 51200;
+    const int chg_V_low = 44138;
+    const int param_EZ_FG1 = 0x8400;
+    const int param_EZ_FG2 = 0x8000;
+    int ret;
+    uint16_t dpacc;
+
+
+    /* Step 2.1: Option 1 EZ Config */
+    writeReg(DESIGNCAP_REG, des_data.designcap);
+    writeReg(DQACC_REG, des_data.designcap >> 5);
+    writeReg(ICHGTERM_REG, des_data.ichgterm);
+    writeReg(VEMPTY_REG, des_data.vempty);
+
+    if (des_data.vcharge > charger_th) {
+        dpacc = (des_data.designcap >> 5) * chg_V_high / des_data.designcap;
+        writeReg(DPACC_REG, dpacc);
+        writeReg(MODELCFG_REG, param_EZ_FG1); //Why 0x8400
+    } else {
+        dpacc = (des_data.designcap >> 5) * chg_V_low / des_data.designcap;
+        writeReg(DPACC_REG, dpacc);
+        writeReg(MODELCFG_REG, param_EZ_FG2);
+    }
+
+
+    return ret;
+
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+* \brief        Get State Of Charge(SOC) Function for MAX17055
+* \par          Details
+*               This function sends a request to access the internal
+*               of the MAX17055
+*
+* \param[in]    reg_addr     - register address
+* \param[out]   reg_data     - SOC data from the REPSOC_REG register
+* \retval       1 on success
+*
+*              -1 if errors exist
+*/
+
+
+int MAX17055::get_SOC()
+{
+
+    int ret;
+    uint16_t data;
+
+    ret = readReg(REPSOC_REG, data);
+    if (ret < 0)
+        return ret;
+
+    data = data >> 8; /* RepSOC LSB: 1/256 % */
+
+    return data;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+* \brief        Get the remaining Time to Empty(TTE) Function for MAX17055
+* \par          Details
+*               This function sends a request to access the internal register
+*               of the MAX17055
+*
+* \retval      tte_data  - Time to Empty data from the TTE_REG register
+*
+*              -1 if errors exist
+*/
+
+int MAX17055::get_TTE()
+{
+
+    int ret;
+    uint16_t data;
+
+    ret = readReg(TTE_REG, data);
+    if (ret < 0)
+        return ret;
+    else
+        data = (data * 45) >> 3; /* TTE LSB: 5.625 sec */
+
+    return data;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+/**
+* \brief        Get voltage of the cell Function for MAX17055
+* \par          Details
+*               This function sends a request to access the internal register
+*               of the MAX17055 to read the voltage of the cell
+*
+* \retval      vcell_data  - vcell data from the VCELL_REG register
+*
+*              -1 if errors exist
+*/
+
+
+int MAX17055::get_Vcell()
+{
+
+    int ret;
+    uint16_t vcell_data;
+
+    ret = readReg(VCELL_REG, vcell_data);
+    if (ret < 0)
+        return ret;
+    else
+        //printf("Vcell Reg= %d \r\n",vcell_data);
+        ret = lsb_to_uvolts(vcell_data);
+    //printf("Vcell Conv= %d \r\n",ret);
+    return ret;
+
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+/**
+* \brief        Get current Function for MAX17055
+* \par          Details
+*               This function sends a request to access the internal register
+*               of the MAX17055 to read the current register.
+*
+* \retval      curr_data  - vcell data from the VCELL_REG register
+*
+*              -1 if errors exist
+*/
+
+
+int MAX17055::get_Current( platform_data des_data )
+{
+
+    int ret,design_rsense;
+    uint16_t data;
+
+    ret = readReg(CURRENT_REG, data);
+    if (ret < 0)
+        return ret;
+    else
+    design_rsense = des_data.rsense;
+    ret = raw_current_to_uamps((uint32_t)data, design_rsense);
+    return ret;
+
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+/**
+* \brief        Get Average Current Function for MAX17055
+* \par          Details
+*               This function sends a request to access the internal register
+*               of the MAX17055 to read the average current register.
+*
+* \retval      curr_data  - vcell data from the AVGCURRENT_REG register
+*
+*              -1 if errors exist
+*/
+
+
+int MAX17055::get_AvgCurrent( platform_data des_data )
+{
+
+    int ret, design_rsense;
+    uint16_t data;
+    uint32_t aveCurr_data;
+
+    ret = readReg(AVGCURRENT_REG, data);
+    if (ret < 0)
+        return ret;
+    else
+    aveCurr_data = data;
+    design_rsense = des_data.rsense;
+    aveCurr_data = raw_current_to_uamps(aveCurr_data, design_rsense);
+    return aveCurr_data;
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+* \brief        lsb_to_uvolts Converssion Function
+* \par          Details
+*               This function takes the lsb value of the register and convert it
+*               to uvolts
+*
+* \param[in]   lsb     - value of register lsb
+* \retval      lsb  - converted lsb to uvolts
+*
+*/
+
+int MAX17055:: lsb_to_uvolts(uint16_t lsb)
+{
+    int store;
+    store = (lsb * 625) / 8; /* 78.125uV per bit */
+    return store;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+* \brief        raw_current_to_uamp Converssion Function
+* \par          Details
+*               This function takes the raw current value of the register and
+*               converts it to uamps
+*
+* \param[in]   curr - raw current value of register
+* \retval      res  - converted raw current to uamps - Signed 2's complement
+*
+*/
+
+int MAX17055::raw_current_to_uamps(uint32_t curr, int rsense_value)
+{
+    int res = curr;
+    /* Negative */
+    if (res & 0x8000) {
+        res |= 0xFFFF0000;
+    } else {
+        res *= 1562500 /(rsense_value * 1000); //Change to interact with the rsense of customer
+    }
+    return res;
+}
\ No newline at end of file