TI BQ27220 I2C based, battery State of Charge and Coulomb Counter
Fork of bq27210 by
bq27210.cpp@1:ab433d7c3e30, 2017-06-19 (annotated)
- Committer:
- loopsva
- Date:
- Mon Jun 19 22:28:50 2017 +0000
- Revision:
- 1:ab433d7c3e30
- Parent:
- 0:96d5698a376f
Made the same as CLI version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
loopsva | 0:96d5698a376f | 1 | #include "mbed.h" |
loopsva | 0:96d5698a376f | 2 | #include "bq27210.h" |
loopsva | 0:96d5698a376f | 3 | #define i2c_Buf dataSTR.i2c_Bufx |
loopsva | 1:ab433d7c3e30 | 4 | /* |
loopsva | 1:ab433d7c3e30 | 5 | BQ27210::BQ27210(PinName p_sda, PinName p_scl) : |
loopsva | 0:96d5698a376f | 6 | _i2c(p_sda, p_scl) |
loopsva | 0:96d5698a376f | 7 | { |
loopsva | 0:96d5698a376f | 8 | _i2c.frequency(100000); |
loopsva | 0:96d5698a376f | 9 | } |
loopsva | 1:ab433d7c3e30 | 10 | */ |
loopsva | 1:ab433d7c3e30 | 11 | |
loopsva | 1:ab433d7c3e30 | 12 | BQ27210::BQ27210(PinName p_sda, PinName p_scl, PinName p_pgrm) : |
loopsva | 1:ab433d7c3e30 | 13 | _i2c(p_sda, p_scl), |
loopsva | 1:ab433d7c3e30 | 14 | _pgm(p_pgrm, 0) |
loopsva | 1:ab433d7c3e30 | 15 | { |
loopsva | 1:ab433d7c3e30 | 16 | _i2c.frequency(100000); |
loopsva | 1:ab433d7c3e30 | 17 | } |
loopsva | 1:ab433d7c3e30 | 18 | |
loopsva | 1:ab433d7c3e30 | 19 | void BQ27210::default_init(BQ27210_TypeDef& dataSTR) |
loopsva | 1:ab433d7c3e30 | 20 | { |
loopsva | 1:ab433d7c3e30 | 21 | dataSTR.shunt_res = BQ_SHUNT_RESISTOR; |
loopsva | 1:ab433d7c3e30 | 22 | dataSTR.cmmd_key = BQ_COMMAND_0xA9; |
loopsva | 1:ab433d7c3e30 | 23 | |
loopsva | 1:ab433d7c3e30 | 24 | //write AR register |
loopsva | 1:ab433d7c3e30 | 25 | i2c_Buf[0] = BQ_AR_HI; |
loopsva | 1:ab433d7c3e30 | 26 | i2c_Buf[1] = BQ_AR_VALUE >> 8; |
loopsva | 1:ab433d7c3e30 | 27 | _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false); |
loopsva | 1:ab433d7c3e30 | 28 | i2c_Buf[0] = BQ_AR_LO; |
loopsva | 1:ab433d7c3e30 | 29 | i2c_Buf[1] = BQ_AR_VALUE & 255; |
loopsva | 1:ab433d7c3e30 | 30 | _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false); |
loopsva | 1:ab433d7c3e30 | 31 | } |
loopsva | 1:ab433d7c3e30 | 32 | |
loopsva | 1:ab433d7c3e30 | 33 | int BQ27210::new_battery_init(BQ27210_TypeDef& dataSTR) |
loopsva | 1:ab433d7c3e30 | 34 | { |
loopsva | 1:ab433d7c3e30 | 35 | //get the MODE register |
loopsva | 1:ab433d7c3e30 | 36 | i2c_Buf[0] = BQ_MODE; |
loopsva | 1:ab433d7c3e30 | 37 | _i2c.write((int)BQ27210_ADDR, i2c_Buf, 1, true); |
loopsva | 1:ab433d7c3e30 | 38 | _i2c.read((int)BQ27210_ADDR +1, i2c_Buf, 1, false); |
loopsva | 1:ab433d7c3e30 | 39 | char modeR = i2c_Buf[0]; |
loopsva | 1:ab433d7c3e30 | 40 | //write DONE bit to MODE reg |
loopsva | 1:ab433d7c3e30 | 41 | i2c_Buf[0] = BQ_MODE; |
loopsva | 1:ab433d7c3e30 | 42 | i2c_Buf[1] = modeR | BQ_BIT_DONE; |
loopsva | 1:ab433d7c3e30 | 43 | _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false); |
loopsva | 1:ab433d7c3e30 | 44 | //write command |
loopsva | 1:ab433d7c3e30 | 45 | i2c_Buf[0] = BQ_CRTL; |
loopsva | 1:ab433d7c3e30 | 46 | i2c_Buf[1] = BQ_COMMAND_0xA9; |
loopsva | 1:ab433d7c3e30 | 47 | _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false); |
loopsva | 1:ab433d7c3e30 | 48 | int i = 0; |
loopsva | 1:ab433d7c3e30 | 49 | for(i = 0; i < 500; i++) { |
loopsva | 1:ab433d7c3e30 | 50 | //Thread::wait(1); |
loopsva | 1:ab433d7c3e30 | 51 | wait_ms(1); |
loopsva | 1:ab433d7c3e30 | 52 | i2c_Buf[0] = BQ_CRTL; |
loopsva | 1:ab433d7c3e30 | 53 | _i2c.write((int)BQ27210_ADDR, i2c_Buf, 1, true); |
loopsva | 1:ab433d7c3e30 | 54 | _i2c.read((int)BQ27210_ADDR +1, i2c_Buf, 1, false); |
loopsva | 1:ab433d7c3e30 | 55 | if(!(i2c_Buf[0])) break; |
loopsva | 1:ab433d7c3e30 | 56 | } |
loopsva | 1:ab433d7c3e30 | 57 | if(i > 498) return(i); // 40 fails, 50 passes |
loopsva | 1:ab433d7c3e30 | 58 | |
loopsva | 1:ab433d7c3e30 | 59 | //get the MODE register |
loopsva | 1:ab433d7c3e30 | 60 | i2c_Buf[0] = BQ_MODE; |
loopsva | 1:ab433d7c3e30 | 61 | _i2c.write((int)BQ27210_ADDR, i2c_Buf, 1, true); |
loopsva | 1:ab433d7c3e30 | 62 | _i2c.read((int)BQ27210_ADDR +1, i2c_Buf, 1, false); |
loopsva | 1:ab433d7c3e30 | 63 | modeR = i2c_Buf[0]; |
loopsva | 1:ab433d7c3e30 | 64 | //write PRST bit to MODE reg |
loopsva | 1:ab433d7c3e30 | 65 | i2c_Buf[0] = BQ_MODE; |
loopsva | 1:ab433d7c3e30 | 66 | i2c_Buf[1] = modeR | BQ_BIT_PRST; |
loopsva | 1:ab433d7c3e30 | 67 | _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false); |
loopsva | 1:ab433d7c3e30 | 68 | //write command |
loopsva | 1:ab433d7c3e30 | 69 | i2c_Buf[0] = BQ_CRTL; |
loopsva | 1:ab433d7c3e30 | 70 | i2c_Buf[1] = BQ_COMMAND_0xA9; |
loopsva | 1:ab433d7c3e30 | 71 | _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false); |
loopsva | 1:ab433d7c3e30 | 72 | return(0); |
loopsva | 1:ab433d7c3e30 | 73 | } |
loopsva | 0:96d5698a376f | 74 | |
loopsva | 0:96d5698a376f | 75 | int BQ27210::read_registers(BQ27210_TypeDef& dataSTR) |
loopsva | 0:96d5698a376f | 76 | { |
loopsva | 0:96d5698a376f | 77 | i2c_Buf[0] = BQ_CRTL; |
loopsva | 0:96d5698a376f | 78 | int result = _i2c.write((int)BQ27210_ADDR, i2c_Buf, 1, true); |
loopsva | 0:96d5698a376f | 79 | if(result) return(result); |
loopsva | 0:96d5698a376f | 80 | _i2c.read((int)BQ27210_ADDR +1, i2c_Buf, 45, false); |
loopsva | 0:96d5698a376f | 81 | |
loopsva | 0:96d5698a376f | 82 | dataSTR.cntlReg = i2c_Buf[BQ_CRTL]; |
loopsva | 0:96d5698a376f | 83 | dataSTR.modeReg = i2c_Buf[BQ_MODE]; |
loopsva | 0:96d5698a376f | 84 | dataSTR.arReg = (i2c_Buf[BQ_AR_HI] << 8) | i2c_Buf[BQ_AR_LO]; |
loopsva | 0:96d5698a376f | 85 | dataSTR.artteReg = (i2c_Buf[BQ_ARTTE_HI] << 8) | i2c_Buf[BQ_ARTTE_LO]; |
loopsva | 0:96d5698a376f | 86 | dataSTR.tempReg = (i2c_Buf[BQ_TEMP_HI] << 8) | i2c_Buf[BQ_TEMP_LO]; |
loopsva | 0:96d5698a376f | 87 | dataSTR.voltReg = (i2c_Buf[BQ_VOLT_HI] << 8) | i2c_Buf[BQ_VOLT_LO]; |
loopsva | 0:96d5698a376f | 88 | dataSTR.flagsReg = i2c_Buf[BQ_FLAGS]; |
loopsva | 0:96d5698a376f | 89 | dataSTR.rsocReg = i2c_Buf[BQ_RSOC]; |
loopsva | 0:96d5698a376f | 90 | dataSTR.nacReg = (i2c_Buf[BQ_NAC_HI] << 8) | i2c_Buf[BQ_NAC_LO]; |
loopsva | 0:96d5698a376f | 91 | dataSTR.lmdReg = (i2c_Buf[BQ_LMD_HI] << 8) | i2c_Buf[BQ_LMD_LO]; |
loopsva | 0:96d5698a376f | 92 | dataSTR.cacReg = (i2c_Buf[BQ_CAC_HI] << 8) | i2c_Buf[BQ_CAC_LO]; |
loopsva | 0:96d5698a376f | 93 | dataSTR.fcacReg = (i2c_Buf[BQ_FCAC_HI] << 8) | i2c_Buf[BQ_FCAC_LO]; |
loopsva | 0:96d5698a376f | 94 | dataSTR.aiReg = (i2c_Buf[BQ_AI_HI] << 8) | i2c_Buf[BQ_AI_LO]; |
loopsva | 0:96d5698a376f | 95 | dataSTR.tteReg = (i2c_Buf[BQ_TTE_HI] << 8) | i2c_Buf[BQ_TTE_LO]; |
loopsva | 0:96d5698a376f | 96 | dataSTR.ttfReg = (i2c_Buf[BQ_TTF_HI] << 8) | i2c_Buf[BQ_TTF_LO]; |
loopsva | 0:96d5698a376f | 97 | dataSTR.siReg = (i2c_Buf[BQ_SI_HI] << 8) | i2c_Buf[BQ_SI_LO]; |
loopsva | 0:96d5698a376f | 98 | dataSTR.stteReg = (i2c_Buf[BQ_STTE_HI] << 8) | i2c_Buf[BQ_STTE_LO]; |
loopsva | 0:96d5698a376f | 99 | dataSTR.junk1 = (i2c_Buf[BQ_STTE_HI +2] << 8) | i2c_Buf[BQ_STTE_LO +2]; |
loopsva | 0:96d5698a376f | 100 | dataSTR.cedvReg = (i2c_Buf[BQ_CEDV_HI] << 8) | i2c_Buf[BQ_CEDV_LO]; |
loopsva | 0:96d5698a376f | 101 | dataSTR.junk2 = (i2c_Buf[BQ_CEDV_HI +2] << 8) | i2c_Buf[BQ_CEDV_LO +2]; |
loopsva | 0:96d5698a376f | 102 | dataSTR.junk3 = (i2c_Buf[BQ_CEDV_HI +4] << 8) | i2c_Buf[BQ_CEDV_LO +4]; |
loopsva | 0:96d5698a376f | 103 | dataSTR.ttecpReg = (i2c_Buf[BQ_TTECP_HI] << 8) | i2c_Buf[BQ_TTECP_LO]; |
loopsva | 0:96d5698a376f | 104 | dataSTR.cyclReg = (i2c_Buf[BQ_CYCL_HI] << 8) | i2c_Buf[BQ_CYCL_LO]; |
loopsva | 0:96d5698a376f | 105 | dataSTR.cyctReg = (i2c_Buf[BQ_CYCT_HI] << 8) | i2c_Buf[BQ_CYCT_LO]; |
loopsva | 0:96d5698a376f | 106 | dataSTR.csocReg = i2c_Buf[BQ_CSOC]; |
loopsva | 0:96d5698a376f | 107 | return(0); |
loopsva | 0:96d5698a376f | 108 | } |
loopsva | 0:96d5698a376f | 109 | |
loopsva | 0:96d5698a376f | 110 | int BQ27210::read_eep_registers(BQ27210_TypeDef& dataSTR) |
loopsva | 0:96d5698a376f | 111 | { |
loopsva | 0:96d5698a376f | 112 | i2c_Buf[0] = BQ_EE_EN; |
loopsva | 0:96d5698a376f | 113 | int result = _i2c.write((int)BQ27210_ADDR, i2c_Buf, 1, true); |
loopsva | 0:96d5698a376f | 114 | if(result) return(result); |
loopsva | 0:96d5698a376f | 115 | _i2c.read((int)BQ27210_ADDR +1, i2c_Buf, 1, false); |
loopsva | 0:96d5698a376f | 116 | dataSTR.eeEnReg = i2c_Buf[0]; |
loopsva | 0:96d5698a376f | 117 | |
loopsva | 0:96d5698a376f | 118 | i2c_Buf[0] = BQ_ILMD; |
loopsva | 0:96d5698a376f | 119 | result = _i2c.write((int)BQ27210_ADDR, i2c_Buf, 1, true); |
loopsva | 0:96d5698a376f | 120 | _i2c.read((int)BQ27210_ADDR +1, i2c_Buf, 10, false); |
loopsva | 0:96d5698a376f | 121 | dataSTR.ilmdReg = i2c_Buf[0]; |
loopsva | 0:96d5698a376f | 122 | dataSTR.sedvfReg = i2c_Buf[1]; |
loopsva | 0:96d5698a376f | 123 | dataSTR.sedv1Reg = i2c_Buf[2]; |
loopsva | 0:96d5698a376f | 124 | dataSTR.islcEdvtReg = i2c_Buf[3]; |
loopsva | 0:96d5698a376f | 125 | dataSTR.dmfsdReg = i2c_Buf[4]; |
loopsva | 0:96d5698a376f | 126 | dataSTR.taperReg = i2c_Buf[5]; |
loopsva | 0:96d5698a376f | 127 | dataSTR.pkcfgReg = i2c_Buf[6]; |
loopsva | 0:96d5698a376f | 128 | dataSTR.gafDedvReg = i2c_Buf[7]; |
loopsva | 0:96d5698a376f | 129 | dataSTR.dcompReg = i2c_Buf[8]; |
loopsva | 0:96d5698a376f | 130 | dataSTR.tcompReg = i2c_Buf[9]; |
loopsva | 1:ab433d7c3e30 | 131 | return(20); |
loopsva | 1:ab433d7c3e30 | 132 | } |
loopsva | 1:ab433d7c3e30 | 133 | |
loopsva | 1:ab433d7c3e30 | 134 | int BQ27210::write_eep_registers(BQ27210_TypeDef& dataSTR) |
loopsva | 1:ab433d7c3e30 | 135 | { |
loopsva | 1:ab433d7c3e30 | 136 | //first get old data and enable writing to EEPROM |
loopsva | 1:ab433d7c3e30 | 137 | int result = read_eep_registers(dataSTR); |
loopsva | 1:ab433d7c3e30 | 138 | if(result) return(21); |
loopsva | 1:ab433d7c3e30 | 139 | i2c_Buf[0] = BQ_EE_EN; |
loopsva | 1:ab433d7c3e30 | 140 | i2c_Buf[1] = BQ_EE_WRITE_EN; |
loopsva | 1:ab433d7c3e30 | 141 | result = _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false); |
loopsva | 1:ab433d7c3e30 | 142 | if(result) return(22); |
loopsva | 1:ab433d7c3e30 | 143 | |
loopsva | 1:ab433d7c3e30 | 144 | //setup and write new values to EEPROM |
loopsva | 1:ab433d7c3e30 | 145 | i2c_Buf[1] = BQ_ILMD; |
loopsva | 1:ab433d7c3e30 | 146 | //i2c_Buf[2] = dataSTR.ilmdReg; |
loopsva | 1:ab433d7c3e30 | 147 | //i2c_Buf[3] = dataSTR.sedvfReg; |
loopsva | 1:ab433d7c3e30 | 148 | //i2c_Buf[4] = dataSTR.sedv1Reg; |
loopsva | 1:ab433d7c3e30 | 149 | i2c_Buf[5] = dataSTR.islcEdvtReg; |
loopsva | 1:ab433d7c3e30 | 150 | i2c_Buf[6] = dataSTR.dmfsdReg; |
loopsva | 1:ab433d7c3e30 | 151 | i2c_Buf[7] = dataSTR.taperReg; |
loopsva | 1:ab433d7c3e30 | 152 | i2c_Buf[8] = dataSTR.pkcfgReg; |
loopsva | 1:ab433d7c3e30 | 153 | i2c_Buf[9] = dataSTR.gafDedvReg; |
loopsva | 1:ab433d7c3e30 | 154 | i2c_Buf[10] = dataSTR.dcompReg; |
loopsva | 1:ab433d7c3e30 | 155 | i2c_Buf[11] = dataSTR.tcompReg; |
loopsva | 1:ab433d7c3e30 | 156 | |
loopsva | 1:ab433d7c3e30 | 157 | i2c_Buf[2] = BQ_NEW_ILMD; |
loopsva | 1:ab433d7c3e30 | 158 | i2c_Buf[3] = BQ_NEW_SEDVF; |
loopsva | 1:ab433d7c3e30 | 159 | i2c_Buf[4] = BQ_NEW_SEDV1; |
loopsva | 1:ab433d7c3e30 | 160 | result = _i2c.write((int)BQ27210_ADDR, i2c_Buf+1, 10, false); |
loopsva | 1:ab433d7c3e30 | 161 | if(result) return(23); |
loopsva | 1:ab433d7c3e30 | 162 | |
loopsva | 1:ab433d7c3e30 | 163 | //now program each register |
loopsva | 1:ab433d7c3e30 | 164 | int i = 0; |
loopsva | 1:ab433d7c3e30 | 165 | for(i = BQ_ILMD; i <= BQ_TCOMP; i++) { |
loopsva | 1:ab433d7c3e30 | 166 | i2c_Buf[0] = i2c_Buf[i + 1]; |
loopsva | 1:ab433d7c3e30 | 167 | result = _i2c.write((int)BQ27210_ADDR, i2c_Buf, 1, true); |
loopsva | 1:ab433d7c3e30 | 168 | _i2c.read((int)BQ27210_ADDR +1, i2c_Buf, 1, false); |
loopsva | 1:ab433d7c3e30 | 169 | _pgm = 1; |
loopsva | 1:ab433d7c3e30 | 170 | //Thread::wait(50); |
loopsva | 1:ab433d7c3e30 | 171 | wait_ms(50); |
loopsva | 1:ab433d7c3e30 | 172 | _pgm = 0; |
loopsva | 1:ab433d7c3e30 | 173 | if(result) break; |
loopsva | 1:ab433d7c3e30 | 174 | } |
loopsva | 1:ab433d7c3e30 | 175 | |
loopsva | 1:ab433d7c3e30 | 176 | //finally, disable writing of EEPROM |
loopsva | 1:ab433d7c3e30 | 177 | i2c_Buf[0] = BQ_EE_EN; |
loopsva | 1:ab433d7c3e30 | 178 | i2c_Buf[1] = 0; |
loopsva | 1:ab433d7c3e30 | 179 | _i2c.write((int)BQ27210_ADDR, i2c_Buf, 2, false); |
loopsva | 1:ab433d7c3e30 | 180 | if(result) return(i); |
loopsva | 0:96d5698a376f | 181 | return(0); |
loopsva | 1:ab433d7c3e30 | 182 | } |