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:
5:a18a189588dc
Parent:
4:a4d6ae2182c2
Child:
6:5ced10109ebf
--- a/max17055.cpp	Wed Sep 27 17:10:18 2017 +0000
+++ b/max17055.cpp	Mon Oct 02 21:59:00 2017 +0000
@@ -7,7 +7,7 @@
 *
 * Started: 11SEP17
 *
-* Updated: 
+* Updated:
 *
 * @brief Source file for MAX31855 class
 *
@@ -47,27 +47,64 @@
 #include "mbed.h"
 #include "max17055.h"
 
-struct max17055_priv {
-    struct i2c_client       *client;
-    struct device           *dev;
-    struct regmap           *regmap;
-    struct power_supply     battery;
-    struct max17055_platform_data   *pdata;
-    struct work_struct      init_worker;
-    struct attribute_group  *attr_grp;
-};
+#define DRV_NAME "max17055"
+
+/* CONFIG register bits */
+#define MAX17055_CONFIG_ALRT_EN         (1 << 2)
+#define MAX17055_CONFIG2_LDMDL          (1 << 5)
+
+/* STATUS register bits */
+#define MAX17055_STATUS_BST             (1 << 3)
+#define MAX17055_STATUS_POR             (1 << 1)
+
+/* MODELCFG register bits */
+#define MAX17055_MODELCFG_REFRESH       (1 << 15)
+
+/* TALRTTH register bits */
+#define MIN_TEMP_ALERT                  0
+#define MAX_TEMP_ALERT                  8
+
+/* FSTAT register bits */
+#define MAX17055_FSTAT_DNR              (1)
+
+/* STATUS interrupt status bits */
+#define MAX17055_STATUS_ALRT_CLR_MASK   (0x88BB)
+#define MAX17055_STATUS_SOC_MAX_ALRT    (1 << 14)
+#define MAX17055_STATUS_TEMP_MAX_ALRT   (1 << 13)
+#define MAX17055_STATUS_VOLT_MAX_ALRT   (1 << 12)
+#define MAX17055_STATUS_SOC_MIN_ALRT    (1 << 10)
+#define MAX17055_STATUS_TEMP_MIN_ALRT   (1 << 9)
+#define MAX17055_STATUS_VOLT_MIN_ALRT   (1 << 8)
+#define MAX17055_STATUS_CURR_MAX_ALRT   (1 << 6)
+#define MAX17055_STATUS_CURR_MIN_ALRT   (1 << 2)
+
+#define MAX17055_VMAX_TOLERANCE     50 /* 50 mV */
 
 
-MAX17055::MAX17055(I2C &i2c): 
-m_i2cBus(i2c)
+//struct battery_priv {
+//        struct power_supply battery;
+//    };
+
+
+MAX17055::MAX17055(I2C &i2c):
+    m_i2cBus(i2c)
 {
-  //empty block
+    //empty block
 }
 
 MAX17055::~MAX17055()
 {
     //empty block
 }
+
+
+
+
+
+
+
+
+
 ///////////////////////////////////////////////////////////////////////////////
 
 /**
@@ -84,15 +121,15 @@
 int MAX17055::writeReg(Registers_e reg_addr, uint16_t reg_data)
 {
 
-    
+
     uint8_t dataLSB;
     uint8_t dataMSB;
-    
+
     dataLSB = reg_data & 0x00FF;
-    dataMSB = (reg_data >> 8) & 0x00FF; 
-    
+    dataMSB = (reg_data >> 8) & 0x00FF;
+
     char add_plus_data[3] = {reg_addr, dataLSB, dataMSB};
-    
+
     if ( m_i2cBus.write(I2C_W_ADRS, add_plus_data, 3, false) == 0)
         return 1;
     else
@@ -120,20 +157,18 @@
     char local_data[1];
     local_data[0] = reg_addr;
     char read_data[2];
- 
+
     result = m_i2cBus.write(I2C_W_ADRS, local_data, 1);
-    if(result == 0) 
-    {
+    if(result == 0) {
         result = m_i2cBus.read(I2C_R_ADRS, read_data , 2, false);
-        if (result == 0)
-        {
+        if (result == 0) {
             value = ( ((read_data[1] & 0x00FF) << 8) + (read_data[0]));
             result = 1;
-        } 
+        }
     }
-    
+
     return result;
-  
+
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -143,40 +178,40 @@
 *               This function wites and verifies if the writing process was successful
 *
 * \param[in]    reg_addr     - register address
-* \param[out]   reg_data     - the variable that contains the data to write 
+* \param[out]   reg_data     - the variable that contains the data to write
 *                                to the register address
 *
 * \retval       1 on success
 */
 
 
-int MAX17055::write_and_verify_reg (MAX17055::Registers_e reg_addr, uint16_t reg_data)
-{   
+int MAX17055::write_and_verify_reg(Registers_e reg_addr, uint16_t reg_data)
+{
     int retries = 8;
     int ret;
     int statusRead;
     int statusWrite;
     uint16_t read_data;
-    
+
     do {
         statusWrite = writeReg(reg_addr, reg_data);
         if (statusWrite != 1)
             ret = -1;
         wait_ms(3);
-        statusRead = readReg(reg_addr, read_data); 
+        statusRead = readReg(reg_addr, read_data);
         if  (statusRead != 1)
             ret = -2;
-        if (read_data != reg_data){
+        if (read_data != reg_data) {
             ret = -3;
             retries--;
         }
-    }while (retries && read_data != reg_data);
-    
-    if (ret<0)
-    {
+    } while (retries && read_data != reg_data);
+
+    if (ret<0) {
         return ret;
-    } else
+    } else {
         return 1;
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -186,42 +221,119 @@
 * \par          Details
 *               This function intitializes the MAX17055
 *
-* \retval       1 on success 
+* \retval       1 on success
 *               0 if device is not present
 *              -1 if errors exist
 */
-    
-    
-int MAX17055::init()
+
+
+int MAX17055::init(struct max17055_platform_data *pri)
 {
-    int status;
-    uint16_t read_data, hibcfg_value;
-    
+    //*batt_con = batt_info;
+    int status, ret;
+    uint16_t read_data, hibcfg_value,dpacc, reg;
+
+
     status = readReg(MAX17055_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);
 
     if (!(read_data & MAX17055_STATUS_POR ) )
-        return -1;  //POR is not set. Skip Initialization. 
+        return -1;  //POR is not set. Skip Initialization.
 
     /* Step 1: Check if FStat.DNR == 0 */
     // Do not continue until FSTAT.DNR == 0
-    
-    while(readReg(MAX17055_FSTAT_REG, read_data)&1)
-    {
+
+    while(readReg(MAX17055_FSTAT_REG, read_data)&1) {
         wait_ms(10);//10 ms wait empty loop
     }
-    
-     /* Force exit from hibernate */
-     hibcfg_value = forcedExitHyberMode();
-    
+
+    /* Force exit from hibernate */
+    hibcfg_value = forcedExitHyberMode();
+
+
+    /* Step 2: Initialize configuration */
+    switch (1) {
+        case MODEL_LOADING_OPTION1:
+            /* Step 2.1: Option 1 EZ Config */
+            writeReg(MAX17055_DESIGNCAP_REG, designcap);
+            writeReg(MAX17055_DQACC_REG, pri.designcap >> 5);
+            writeReg(MAX17055_ICHGTERM_REG, pri.ichgterm);
+            writeReg(MAX17055_VEMPTY_REG, pri.vempty);
+
+            if (pri.vcharge > 4275) { //Need to know what this 4275 is
+                dpacc = (pri.designcap >> 5) * 0xC800 / pri.designcap;
+                writeReg(MAX17055_DPACC_REG, dpacc);
+                writeReg(MAX17055_MODELCFG_REG, 0x8400); //Why 0x8400
+            } else {
+                dpacc = (pri.designcap >> 5) * 0xAC6A / pri.designcap;
+                writeReg(MAX17055_DPACC_REG, dpacc);
+                writeReg(MAX17055_MODELCFG_REG, 0x8000);
+            }
+
+            /* Poll ModelCFG.ModelRefresh bit for clear */
+            ret = max17055_poll_flag_clear(MAX17055_MODELCFG_REG, MAX17055_MODELCFG_REFRESH, 500);
+            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);
+
+    /* Optional step - alert threshold initialization */
+    //max17055_set_alert_thresholds(priv);
+
+    /* Clear Status.POR */
+    readReg(MAX17055_STATUS_REG, reg);
+    write_and_verify_reg(MAX17055_STATUS_REG, (reg & ~MAX17055_STATUS_POR));
+
     return 1;
-}  
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+* \brief        Poll Flag clear
+* \par          Details
+*               This function clears status flags for the MAX17055
+*
+* \param[in]    reg_addr - register address
+* \param[in]    mask - register address
+* \param[in]    timeout - register data
+*
+* \retval       1 on success
+*              -1 on Failure
+*/
+
+int max17055_poll_flag_clear(Registers_e reg_addr, int mask, int timeout)
+{
+    uint16_t data;
+    int ret;
+
+    do {
+        wait(50);
+        ret = readReg(red_addr, data);
+        if(ret < 0)
+            return ret;
+
+        if(!(data & mask))
+            return 1;
+
+        timeout -= 50;
+    } while(timeout > 0);
+
+    return -1;
+}
+
+
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -232,20 +344,20 @@
 *               of the MAX17055
 *
 * \param[in]    reg_addr     - register address
-* \param[out]   reg_data     - the variable that contains the data to write 
+* \param[out]   reg_data     - the variable that contains the data to write
 *                                to the register address
-* \retval       1 on success 
-*   
+* \retval       1 on success
+*
 *              -1 if errors exist
 */
-    
-    
+
+
 int MAX17055::get_temperature(int *temp)
 {
-    
+
     int ret;
     uint16_t data;
-    
+
     ret = readReg(MAX17055_TEMP_REG, data);
     if (ret < 0)
         return ret;
@@ -260,7 +372,7 @@
     *temp >>= 8;
 
     return 1;
-}  
+}
 
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -268,141 +380,30 @@
 /**
 * \brief        Forced Exit Hibernate Mode Function for MAX17055
 * \par          Details
-*               This function executes a force exit from hibernate mode. 
+*               This function executes a force exit from hibernate mode.
 *
 * \retval       returns HibCFG original value before forced Exit Hybernate mode
 *
 */
-    
-    
+
+
 uint16_t MAX17055::forcedExitHyberMode()
 {
     uint16_t hibcfg;
-    
-/* Force exit from hibernate */
+
+    /* Force exit from hibernate */
 
     //STEP 0: Store original HibCFG value
     readReg(MAX17055_HIBCFG_REG, hibcfg);
 
     //STEP 1: Write to Soft-Wakeup Commannd Register
     writeReg(MAX17055_VFSOC0_QH0_LOCK_REG, 0x90); //Soft-Wakeup from hybernate
-    
+
     //STEP 2: Write to Hibernate Configuration register
     writeReg(MAX17055_HIBCFG_REG, 0x0); //disable hibernate mode
-    
+
     //STEP 3:Write to Soft-Wakeup Commannd Register
     writeReg(MAX17055_VFSOC0_QH0_LOCK_REG, 0x0); //Clear All commnads
-    
+
     return hibcfg;
-} 
-  
-//step_1:
-//        // Wait until MAX17055 complete setup operations (Data is Ready)
-//        while(readReg(F_STAT) & 0x0001) delay(10);
-//        /***************************************************************/
-//        // Setting up or initializing charging configurations down here , EZ CONFIG because no .INI file
-//        // FIXX:: DOUBLE CHECK THE INITIALIZATION VALUES
-//        // init values is claculated based on the register lsb's default value page 1 software implementation UG
-//        /* Capacity is in mAH and 1 bit is 0.5mAH)*/
-//        temp = battery->capacity*2;
-//        writeReg(DESIGN_CAP, temp);
-//        writeReg(DQ_A_CC, temp/32);
-//        /* Current measurement, assuming current input in mA */
-//        temp = battery->currentTerm*1000/1.5625;
-//        writeReg(ICHG_TERM, temp);
-//        /* FIXX: DOUBLE CHECK Vempty register (v empty | v recovery), I am assuming that
-//        VE resolution is 10mV and VR resolution is 40mV (programmer's guide)*/
-//        temp =((battery->voltageMin/10) << 7 | (battery->voltageNom)/40);
-//        writeReg(V_EMPTY ,temp);
-//
-//        data = readReg(HIB_CFG); // Store original HIB_CFG inside
-//        writeReg((Registers_e)0x60, 0x90); // Exit hibernate mode step 1
-//        writeReg(CONFIG_2, 0x0); // Exit hibernate mode step 2
-//        writeReg((Registers_e)0x60, 0x0); // Exit hibernate mode step 3
-//
-//        temp = battery->capacity*2;
-//        if (battery->voltageMax > 4.275) {
-//            writeReg(DP_A_CC, (temp/32)*51200/temp); // Write dPAcc
-//            writeReg(MODEL_CFG, 0x8400);    // Write ModelCFG
-//        } else {
-//            writeReg(DP_A_CC, (temp/32)*44138/temp);
-//            writeReg(MODEL_CFG, 0x8000);
-//        }
-//        // Poll ModelCFG.refresh (highest bit), proceed to next step when ModelCFG.Refresh = 0.
-//        while(readReg(MODEL_CFG) & 0x8000) delay(10);
-//        writeReg(HIB_CFG, data);    // Restore the original HibCFG value
-//        /***************************************************************/
-//    }
-//    /***************************************************************/
-//    // FIXX: DOUBLE CHECK, STEP 4 IN PROGRAMMER'S GUIDE
-//    data = readReg(STATUS); // read status register
-//
-//    if (write_and_verify_reg(STATUS, data & 0xFFFD) != E_NO_ERROR) {
-//        return -1;
-//    }
-//    // Check whether there is saved history parameters
-//    temp = saved_param->rcomp0;
-//    temp &= saved_param ->temp_co;
-//    temp &= saved_param->full_cap_rep;
-//    temp &= saved_param->cycles;
-//    temp &= saved_param->full_cap_nom;
-//    // If there is no history setup the battery
-//    if (temp == 0) {
-//        // Check for MAX17055 reset
-//        StatusPOR = readReg(STATUS) & 0x0002;
-//        if (StatusPOR == 1) goto step_1;
-//    }
-//step_4P3:
-//    // Read the reported capacity(mAH) and SOC (percentage)
-//    RepCap = readReg(REP_CAP);
-//    RepSOC = readReg(REP_SOC);
-//
-//    // Read the TTE (in 5.625s)
-//    TTE_val = ((float)(readReg(TTE))) * 5.625;
-//
-//    // Save learned parameters
-//    saved_param->rcomp0 = readReg(R_COMP_0);
-//    saved_param->temp_co = readReg(TEMP_CO);
-//    saved_param->full_cap_rep = readReg(FULL_CAP_REP);
-//    saved_param->cycles = readReg(CYCLES);
-//    saved_param->full_cap_nom = readReg(FULL_CAP_NOM);
-//
-//    // Restoring Capacity Parameters
-//    if (write_and_verify_reg(R_COMP_0, saved_param->rcomp0) != E_NO_ERROR) {
-//        return -1;
-//    }
-//    if (write_and_verify_reg(TEMP_CO, saved_param->temp_co) != E_NO_ERROR) {
-//        return -1;
-//    }
-//    if (write_and_verify_reg(FULL_CAP_REP, saved_param->full_cap_rep) != E_NO_ERROR) {
-//        return -1;
-//    }
-//
-//    delay(350);
-//    // Restore FullCap
-//    temp = readReg(FULL_CAP_NOM); // Read full_cap_nom
-//    data = (readReg(MIX_SOC)*temp)/25600; // MIXCAP
-//    if (write_and_verify_reg(MIX_CAP, data) != E_NO_ERROR) {
-//        return -1;
-//    }
-//    if (write_and_verify_reg(FULL_CAP_REP, temp) != E_NO_ERROR) {
-//        return -1;
-//    }
-//    data = saved_param->full_cap_nom/16; // This act as dQacc
-//    if (write_and_verify_reg(DP_A_CC, 0x0C80) != E_NO_ERROR) {
-//        return -1;
-//    }
-//    if (write_and_verify_reg(DQ_A_CC, temp) != E_NO_ERROR) {
-//        return -1;
-//    }
-//
-//    delay(350);
-//    // Restore Cycles Register
-//    if (write_and_verify_reg(CYCLES, saved_param->cycles) != E_NO_ERROR) {
-//        return -1;
-//    }
-//
-//return E_NO_ERROR;
-//
-//
-//saved_fuel_gauge_params_t default_param = {0,0,0,0,0};
\ No newline at end of file
+}