TI BQ27220 I2C based, battery State of Charge and Coulomb Counter

Fork of bq27210 by Kevin Braun

Revision:
1:ab433d7c3e30
Parent:
0:96d5698a376f
--- a/bq27210.cpp	Tue Jun 13 16:21:47 2017 +0000
+++ b/bq27210.cpp	Mon Jun 19 22:28:50 2017 +0000
@@ -1,12 +1,76 @@
 #include    "mbed.h"
 #include    "bq27210.h"
 #define i2c_Buf dataSTR.i2c_Bufx
-
-BQ27210::BQ27210 (PinName p_sda, PinName p_scl) :
+/*
+BQ27210::BQ27210(PinName p_sda, PinName p_scl) :
     _i2c(p_sda, p_scl)
 {
     _i2c.frequency(100000);
 }
+*/
+
+BQ27210::BQ27210(PinName p_sda, PinName p_scl, PinName p_pgrm) :
+    _i2c(p_sda, p_scl),
+    _pgm(p_pgrm, 0)
+{
+    _i2c.frequency(100000);
+}
+
+void BQ27210::default_init(BQ27210_TypeDef& dataSTR)
+{
+    dataSTR.shunt_res = BQ_SHUNT_RESISTOR;
+    dataSTR.cmmd_key = BQ_COMMAND_0xA9;
+    
+    //write AR register
+    i2c_Buf[0] = BQ_AR_HI;
+    i2c_Buf[1] = BQ_AR_VALUE >> 8;
+    _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false);
+    i2c_Buf[0] = BQ_AR_LO;
+    i2c_Buf[1] = BQ_AR_VALUE & 255;
+    _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false);
+}
+
+int BQ27210::new_battery_init(BQ27210_TypeDef& dataSTR)
+{   
+    //get the MODE register
+    i2c_Buf[0] = BQ_MODE;
+    _i2c.write((int)BQ27210_ADDR, i2c_Buf, 1, true);
+    _i2c.read((int)BQ27210_ADDR +1, i2c_Buf, 1, false);
+    char modeR = i2c_Buf[0];
+    //write DONE bit to MODE reg
+    i2c_Buf[0] = BQ_MODE;
+    i2c_Buf[1] = modeR | BQ_BIT_DONE;
+    _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false);
+    //write command
+    i2c_Buf[0] = BQ_CRTL;
+    i2c_Buf[1] = BQ_COMMAND_0xA9;
+    _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false);
+    int i = 0;
+    for(i = 0; i < 500; i++) {
+        //Thread::wait(1);
+        wait_ms(1);
+        i2c_Buf[0] = BQ_CRTL;
+        _i2c.write((int)BQ27210_ADDR, i2c_Buf, 1, true);
+        _i2c.read((int)BQ27210_ADDR +1, i2c_Buf, 1, false);
+        if(!(i2c_Buf[0])) break;
+    }
+    if(i > 498) return(i); // 40 fails, 50 passes
+    
+    //get the MODE register
+    i2c_Buf[0] = BQ_MODE;
+    _i2c.write((int)BQ27210_ADDR, i2c_Buf, 1, true);
+    _i2c.read((int)BQ27210_ADDR +1, i2c_Buf, 1, false);
+    modeR = i2c_Buf[0];
+    //write PRST bit to MODE reg
+    i2c_Buf[0] = BQ_MODE;
+    i2c_Buf[1] = modeR | BQ_BIT_PRST;
+    _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false);
+    //write command
+    i2c_Buf[0] = BQ_CRTL;
+    i2c_Buf[1] = BQ_COMMAND_0xA9;
+    _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false);
+    return(0);
+}
 
 int BQ27210::read_registers(BQ27210_TypeDef& dataSTR)
 {
@@ -40,7 +104,6 @@
     dataSTR.cyclReg = (i2c_Buf[BQ_CYCL_HI] << 8) | i2c_Buf[BQ_CYCL_LO];
     dataSTR.cyctReg = (i2c_Buf[BQ_CYCT_HI] << 8) | i2c_Buf[BQ_CYCT_LO];
     dataSTR.csocReg = i2c_Buf[BQ_CSOC];
-    dataSTR.shunt_res = BQ_SHUNT_RESISTOR;
     return(0);
 }
 
@@ -65,5 +128,55 @@
     dataSTR.gafDedvReg = i2c_Buf[7];
     dataSTR.dcompReg = i2c_Buf[8];
     dataSTR.tcompReg = i2c_Buf[9];
+    return(20);
+}
+
+int BQ27210::write_eep_registers(BQ27210_TypeDef& dataSTR)
+{
+    //first get old data and enable writing to EEPROM
+    int result = read_eep_registers(dataSTR);
+    if(result) return(21);
+    i2c_Buf[0] = BQ_EE_EN;
+    i2c_Buf[1] = BQ_EE_WRITE_EN;
+    result = _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false);
+    if(result) return(22);
+    
+    //setup and write new values to EEPROM
+    i2c_Buf[1] = BQ_ILMD;
+    //i2c_Buf[2] = dataSTR.ilmdReg;
+    //i2c_Buf[3] = dataSTR.sedvfReg;
+    //i2c_Buf[4] = dataSTR.sedv1Reg;
+    i2c_Buf[5] = dataSTR.islcEdvtReg;
+    i2c_Buf[6] = dataSTR.dmfsdReg;
+    i2c_Buf[7] = dataSTR.taperReg;
+    i2c_Buf[8] = dataSTR.pkcfgReg;
+    i2c_Buf[9] = dataSTR.gafDedvReg;
+    i2c_Buf[10] = dataSTR.dcompReg;
+    i2c_Buf[11] = dataSTR.tcompReg;
+    
+    i2c_Buf[2] = BQ_NEW_ILMD;
+    i2c_Buf[3] = BQ_NEW_SEDVF;
+    i2c_Buf[4] = BQ_NEW_SEDV1;
+    result = _i2c.write((int)BQ27210_ADDR, i2c_Buf+1, 10, false);
+    if(result) return(23);
+    
+    //now program each register
+    int i = 0;
+    for(i = BQ_ILMD; i <= BQ_TCOMP; i++) {
+        i2c_Buf[0] = i2c_Buf[i + 1];
+        result = _i2c.write((int)BQ27210_ADDR, i2c_Buf, 1, true);
+        _i2c.read((int)BQ27210_ADDR +1, i2c_Buf, 1, false);
+        _pgm = 1;
+        //Thread::wait(50);
+        wait_ms(50);
+        _pgm = 0;
+        if(result) break;
+    }
+    
+    //finally, disable writing of EEPROM
+    i2c_Buf[0] = BQ_EE_EN;
+    i2c_Buf[1] = 0;
+    _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false);
+    if(result) return(i);
     return(0);
-}
\ No newline at end of file
+}