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

Fork of bq27210 by Kevin Braun

bq27220.cpp

Committer:
loopsva
Date:
2017-07-31
Revision:
3:1b12fa9dc673
Parent:
2:d52fb7ef7429

File content as of revision 3:1b12fa9dc673:

#include    "mbed.h"
#include    "rtos.h"
#include    "bq27220.h"

extern RawSerial pc;

#define i2c_Buf dataSTR.i2c_Bufx


BQ27220::BQ27220(PinName p_sda, PinName p_scl) :
    _i2c(p_sda, p_scl)
{
    _i2c.frequency(100000);
}

BQ27220::BQ27220(PinName p_sda, PinName p_scl, int freq) :
    _i2c(p_sda, p_scl)
{
    _i2c.frequency(freq);
}

void BQ27220::default_init(BQ27220_TypeDef& dataSTR)
{
    dataSTR.shunt_res = BQ_SHUNT_RESISTOR;
}

int BQ27220::new_battery_init(BQ27220_TypeDef& dataSTR)
{   
    return(0);
}

uint16_t BQ27220::get_sub_cmmd(BQ27220_TypeDef& dataSTR, uint16_t cmmd)
{   
    i2c_Buf[0] = BQ_CNTL;
    i2c_Buf[2] = cmmd >> 8;
    i2c_Buf[1] = cmmd & 255;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
    Thread::wait(5); // needs large delay here
    //pc.printf("sub-a: %02x %02x %02x %02x \r\n", i2c_Buf[0], i2c_Buf[1], i2c_Buf[2], i2c_Buf[3]);
    int i = 0;
    for(i = 0; i < 100; i++) {
        wait_us(66);
        _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
        _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 4, false);
        //pc.printf("sub-b: %02x %02x %02x %02x \r\n", i2c_Buf[0], i2c_Buf[1], i2c_Buf[2], i2c_Buf[3]);
        if((i2c_Buf[0]== 0xa5) && (i2c_Buf[1] == 0xff)) break;
    }
    wait_us(66);
    if(i > 98) pc.printf("sub-b: ERROR \r\n");
    return (i2c_Buf[0] << 8) | i2c_Buf[1];
}

uint16_t BQ27220::get_sub_cmmd_s(BQ27220_TypeDef& dataSTR, uint16_t cmmd) 
{   
    i2c_Buf[0] = BQ_CNTL;
    i2c_Buf[2] = cmmd >> 8;
    i2c_Buf[1] = cmmd & 255;
    //pc.printf("sub-a: %02x %02x %02x \r\n", i2c_Buf[0], i2c_Buf[1], i2c_Buf[2]);
    _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
    wait_us(1066);
    i2c_Buf[0] = BQ_MACDATA;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 2, false);
    wait_us(66);
    //pc.printf("sub-b: %04x \r\n", (i2c_Buf[0] << 8) | i2c_Buf[1]);
    return (i2c_Buf[0] << 8) | i2c_Buf[1];
}

uint16_t BQ27220::get_reg_2B(BQ27220_TypeDef& dataSTR, uint8_t reg)
{   
    i2c_Buf[0] = reg;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 2, false);
    //pc.printf("sub-b: %02x %02x %02x %02x \r\n", i2c_Buf[0], i2c_Buf[1], i2c_Buf[2], i2c_Buf[3]);
    wait_us(66);
    //Thread::wait(2);
    return (i2c_Buf[1] << 8) | i2c_Buf[0];
}

void BQ27220::enter_cfg_update(BQ27220_TypeDef& dataSTR)
{   
    i2c_Buf[0] = BQ_CNTL;
    i2c_Buf[1] = 0x90;
    i2c_Buf[2] = 0x00;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
    wait_us(66);
    Thread::wait(1500);
}

void BQ27220::exitCfgUpdateExit(BQ27220_TypeDef& dataSTR)
{
    i2c_Buf[0] = BQ_CNTL;
    i2c_Buf[1] = BQ_EXIT_CFG_UPDATE & 255;
    i2c_Buf[2] = BQ_EXIT_CFG_UPDATE >> 8;
    pc.printf("exitCfg_cmmd: ->  ");
    for(int i = 0; i < 3; i++) pc.printf("%02x ",i2c_Buf[i]);
    pc.printf("\r\n");
    _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
    wait_us(66);
    Thread::wait(5);
}

void BQ27220::exitCfgUpdateReInit(BQ27220_TypeDef& dataSTR)
{
    i2c_Buf[0] = BQ_CNTL;
    i2c_Buf[1] = BQ_EXIT_CFG_UPDATE_REINIT & 255;
    i2c_Buf[2] = BQ_EXIT_CFG_UPDATE_REINIT >> 8;
    pc.printf("exitInit_cmmd: ->  ");
    for(int i = 0; i < 3; i++) pc.printf("%02x ",i2c_Buf[i]);
    pc.printf("\r\n");
    _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
    wait_us(66);
    Thread::wait(5);
}


void BQ27220::reset(BQ27220_TypeDef& dataSTR)
{
    i2c_Buf[0] = BQ_CNTL;
    i2c_Buf[1] = BQ_RESET & 255;
    i2c_Buf[2] = BQ_RESET >> 8;
    pc.printf("reset_cmmd: ->  ");
    for(int i = 0; i < 3; i++) pc.printf("%02x ",i2c_Buf[i]);
    pc.printf("\r\n");
    _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
    wait_us(66);
    Thread::wait(5);
}
    
void BQ27220::useProfile_1(BQ27220_TypeDef& dataSTR)
{   
    i2c_Buf[0] = BQ_CNTL;
    i2c_Buf[1] = BQ_SET_PROFILE_1 >> 8;
    i2c_Buf[2] = BQ_SET_PROFILE_1 & 255;;
    pc.printf("Profile_1_cmmd: ->  ");
    for(int i = 0; i < 3; i++) pc.printf("%02x ",i2c_Buf[i]);
    pc.printf("\r\n");
    _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
    wait_us(66);
    Thread::wait(200);
}

uint16_t BQ27220::get_cs_len(BQ27220_TypeDef& dataSTR, bool pf)
{   
    i2c_Buf[0] = BQ_MACDATASUM;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 1, false);
    wait_us(66);
    //Thread::wait(5);
    uint16_t csl = i2c_Buf[0];
    
    i2c_Buf[0] = BQ_MACDATALEN;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 1, false);
    wait_us(66);
    //Thread::wait(5);
    csl = (csl << 8) | i2c_Buf[0];
    if(pf) pc.printf("get_cs: %02x\r\n", csl >> 8);
    if(pf) pc.printf("get_ln: %02x\r\n", csl & 255);
    return(csl);
}

uint8_t BQ27220::calc_checksum_rx(BQ27220_TypeDef& dataSTR, int length)
{
    uint8_t cs = 0;
    //pc.printf("c_csum_rx_len: %02x -> ", length);
    i2c_Buf[0] = BQ_SUB;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 34, false);
    wait_us(66);
    Thread::wait(5);
    for(int i = 0; i < length + 2; i++) {
        cs += i2c_Buf[i];
        //pc.printf("b: %02x cs: %02x  ", i2c_Buf[i], cs);
    }
    cs = 255 - cs;
    //pc.printf("cs_rx:%02x \r\n", cs);
    return (cs);
}

uint8_t BQ27220::calc_checksum_tx(BQ27220_TypeDef& dataSTR, int length)
{
    uint8_t cs = 0;
    pc.printf("cs_tx_len: %02x ->    ", length);
    for(int i = 0; i < length + 2; i++) {
        cs += i2c_Buf[i + 1];
        //pc.printf("i2c: %02x cs: %02x   ", i2c_Buf[i + 1], cs);
        pc.printf("%02x ", i2c_Buf[i + 1]);
    }
    cs = 255 - cs;
    pc.printf("\r\ncs_tx: %02x\r\n", cs);
    return (cs);
}

uint32_t BQ27220::get_data_32(BQ27220_TypeDef& dataSTR, uint16_t sub_cmmd, int length)
{   
    i2c_Buf[0] = BQ_SUB;
    i2c_Buf[2] = sub_cmmd >> 8;
    i2c_Buf[1] = sub_cmmd & 255;
    dataSTR.subReg = sub_cmmd;
    //pc.printf("dat-32a: %02x %02x %02x \r\n", i2c_Buf[0], i2c_Buf[1], i2c_Buf[2]);
    _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
    wait_us(3066);
    //Thread::wait(3); //needs to be at least 2
    
    dataSTR.checksum = calc_checksum_rx(dataSTR, length);
    
    uint16_t cslen = get_cs_len(dataSTR, false);
    dataSTR.macSumReg = cslen >> 8;
    dataSTR.macLenReg = cslen & 255;
    
    i2c_Buf[0] = BQ_MACDATA;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    _i2c.read(BQ27220_ADDR + 1, i2c_Buf, length, false);
    wait_us(5066);
    //Thread::wait(5); //seems to work down to 1
    for(int i = 0; i < length; i++) {
        dataSTR.macData[i] = dataSTR.i2c_Bufx[i];
        pc.printf("%02x,", dataSTR.macData[i]);
    }
    pc.printf("\r\n");
    //pc.printf(" mdl: %02x,  mdcs: %02x,  ccs: %02x\r\n", dataSTR.macLenReg, dataSTR.macSumReg, dataSTR.checksum);
    return ((uint32_t)dataSTR.subReg); 
}

//#define BQ_SHORT          1

void BQ27220::change_ram_1_2_4(BQ27220_TypeDef& dataSTR, uint16_t sub_cmmd, uint32_t value, int qty, bool pre)
{   
    if(pre) {
#ifndef BQ_SHORT
        pc.printf("ram124_a: %04x ->         ", sub_cmmd);
        get_data_32(dataSTR, sub_cmmd, 32);
#endif  
    
        if(qty == 1) {
            dataSTR.macData[0] = value & 255;
#ifdef BQ_SHORT
            dataSTR.macData[1] = 0;
            dataSTR.macData[2] = 0;
            dataSTR.macData[3] = 0;
#endif
        } else
        if(qty == 2) {
            dataSTR.macData[0] = (value >> 8) & 255;
            dataSTR.macData[1] = value & 255;
#ifdef BQ_SHORT
            dataSTR.macData[2] = 0;
            dataSTR.macData[3] = 0;
#endif
        } else
        if(qty == 4) {
            dataSTR.macData[0] = (value >> 24) & 255;
            dataSTR.macData[1] = (value >> 16) & 255;
            dataSTR.macData[2] = (value >> 8) & 255;
            dataSTR.macData[3] = value & 255;
        } else {
            pc.printf("ram124_q_error\r\n");
            return;
        }
    }
    
    i2c_Buf[0] = BQ_SUB;
    i2c_Buf[1] = sub_cmmd >> 8;
    i2c_Buf[2] = sub_cmmd & 255;
    if(pre) {
        i2c_Buf[3] = dataSTR.macData[0];
        i2c_Buf[4] = dataSTR.macData[1];
        i2c_Buf[5] = dataSTR.macData[2];
        i2c_Buf[6] = dataSTR.macData[3];
    }
    pc.printf("ram124_cmmd: ->  ");
    int i = 0;
#ifdef BQ_SHORT
    for(i = 0; i < qty + 3; i++) pc.printf("%02x ",i2c_Buf[i]);
    pc.printf("\r\n");
    uint8_t x = calc_checksum_tx(dataSTR, qty);
    _i2c.write(BQ27220_ADDR, i2c_Buf, qty + 3, false);
#else
    for(i = 0; i < 32; i++) i2c_Buf[i + 3] = dataSTR.macData[i];
    for(i = 0; i < 35; i++) pc.printf("%02x ",i2c_Buf[i]);
    pc.printf("\r\n");
    uint8_t x = calc_checksum_tx(dataSTR, 32);
    _i2c.write(BQ27220_ADDR, i2c_Buf, 35, false);
#endif
    wait_us(66);
    //Thread::wait(5);
    
    i2c_Buf[0] = BQ_MACDATASUM;
    i2c_Buf[1] = x;
#ifndef BQ_SHORT
    i2c_Buf[1] -= 0x20; //why is this???? !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    if((sub_cmmd >= 0x91e0) && (sub_cmmd < BQ_CONFIG_TAPER_CURR)) i2c_Buf[1]--;
#endif
    pc.printf("ram124_cs:   ->  ");
    for(i = 0; i < 2; i++) pc.printf("%02x ",i2c_Buf[i]);
    pc.printf("\r\n");
    _i2c.write(BQ27220_ADDR, i2c_Buf, 2, false);
    wait_us(66);
    //Thread::wait(5);
    
    i2c_Buf[0] = BQ_MACDATALEN;
#ifdef BQ_SHORT
    i2c_Buf[1] = qty + 4;
#else
    i2c_Buf[1] = 36;
#endif
    pc.printf("ram124_len:  ->  ");
    for(i = 0; i < 2; i++) pc.printf("%02x ",i2c_Buf[i]);
    pc.printf("\r\n");
    _i2c.write(BQ27220_ADDR, i2c_Buf, 2, false);
    wait_us(5066);
    //Thread::wait(200);
    
    get_cs_len(dataSTR, true);
    //pc.printf("\r\n");
    
#ifndef BQ_SHORT
    pc.printf("ram124_x: %04x ->         ", sub_cmmd);
    get_data_32(dataSTR, sub_cmmd, 32);
    pc.printf("\r\n");
#endif
}

uint16_t BQ27220::get_16(BQ27220_TypeDef& dataSTR, uint16_t cmmd)
{   
    get_sub_cmmd_s(dataSTR, cmmd);
    i2c_Buf[0] = BQ_MACDATA;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 2, false);
    wait_us(66);
    return (i2c_Buf[0] << 8) | i2c_Buf[1]; 
}

uint8_t BQ27220::get_8(BQ27220_TypeDef& dataSTR, uint16_t cmmd)
{   
    //pc.printf("get_8: %04x\r\n", cmmd);
    get_sub_cmmd_s(dataSTR, cmmd);
    i2c_Buf[0] = BQ_MACDATA;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 1, false);
    wait_us(66);
    return i2c_Buf[0]; 
}

void BQ27220::seal(BQ27220_TypeDef& dataSTR)
{   
    i2c_Buf[0] = BQ_CNTL;
    i2c_Buf[1] = 0x30;
    i2c_Buf[2] = 0x00;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
    wait_us(66);
    wait_ms(5);
    //Thread::wait(5);
}

void BQ27220::unseal(BQ27220_TypeDef& dataSTR)
{   
    i2c_Buf[0] = BQ_CNTL;
    i2c_Buf[1] = 0x14;
    i2c_Buf[2] = 0x04;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
    wait_us(66);
    wait_ms(5);
    //Thread::wait(5);
    
    i2c_Buf[0] = BQ_CNTL;
    i2c_Buf[1] = 0x72;
    i2c_Buf[2] = 0x36;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
    wait_ms(5);
    //Thread::wait(5);
}

void BQ27220::full_access(BQ27220_TypeDef& dataSTR)
{   
    i2c_Buf[0] = BQ_CNTL;
    i2c_Buf[1] = 0xff;
    i2c_Buf[2] = 0xff;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
    wait_us(66);
    wait_ms(5);
    //Thread::wait(5);
    
    i2c_Buf[0] = BQ_CNTL;
    i2c_Buf[1] = 0xff;
    i2c_Buf[2] = 0xff;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
    wait_us(66);
    wait_ms(5);
    //Thread::wait(5);
}

uint32_t BQ27220::get_dev_id(BQ27220_TypeDef& dataSTR)
{   
    uint16_t dat = get_sub_cmmd(dataSTR, BQ_DEVICE_NUMBER);
    //pc.printf("dat-idq: %04x \r\n", dat);
    if(dat != 0xa5ff) return(dat);
    i2c_Buf[0] = BQ_SUB;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 4, false);
    uint32_t id = (i2c_Buf[0] << 24) | (i2c_Buf[1] << 16) | (i2c_Buf[2] << 8) | i2c_Buf[3];
    //pc.printf("dat-idq: %08x \r\n", id);
    wait_us(66);
    return(id) ; 
}

uint32_t BQ27220::get_fw_rev(BQ27220_TypeDef& dataSTR)
{   
    uint16_t dat = get_sub_cmmd(dataSTR, BQ_FW_VERSION);
    //pc.printf("dat-fwq: %04x \r\n", dat);
    if(dat != 0xa5ff) return(dat);
    i2c_Buf[0] = BQ_SUB;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 34, false);
    wait_us(66);
    return (i2c_Buf[0] << 24) | (i2c_Buf[1] << 16) | (i2c_Buf[2] << 8) | i2c_Buf[3]; 
}

uint32_t BQ27220::get_hw_rev(BQ27220_TypeDef& dataSTR)
{   
    uint16_t dat = get_sub_cmmd(dataSTR, BQ_HW_VERSION);
    //pc.printf("dat-fwq: %04x \r\n", dat);
    if(dat != 0xa5ff) return(dat);
    i2c_Buf[0] = BQ_SUB;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 34, false);
    wait_us(66);
    return (i2c_Buf[0] << 24) | (i2c_Buf[1] << 16) | (i2c_Buf[2] << 8) | i2c_Buf[3]; 
}

void BQ27220::set_ntc_as_sensor(BQ27220_TypeDef& dataSTR, bool ntc)
{
    uint16_t res = get_16(dataSTR, BQ_CONFIG_OP_CONFIG_A);
        pc.printf("s_ntc: %04x ", res);
        
    if(!(ntc)) {
        pc.printf(" N ");
        res &= ~BQ_BIT_OCA_TEMPS;
        res |=  BQ_BIT_OCA_BIE;

    } else {
        pc.printf(" L ");
        res &= ~BQ_BIT_OCA_BIE;
        res |=  BQ_BIT_OCA_TEMPS;
    }
    
    pc.printf("new: %04x\r\n", res);
    change_ram_1_2_4(dataSTR, BQ_CONFIG_OP_CONFIG_A - 0x20, (uint32_t)res, 2, true);
}
/*
void BQ27220::set_reg(BQ27220_TypeDef& dataSTR, uint16_t reg, uint16_t da, int byt)
{
    uint16_t res = get_16(dataSTR, reg);
    change_ram_1_2_4(dataSTR, reg, (uint32_t)da, byt, true);
}
*/
/*
uint16_t BQ27220::get_OS_reg(BQ27220_TypeDef& dataSTR)
{
    i2c_Buf[0] = BQ_OS;
    _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 2, false);
    wait_us(66);
    dataSTR.osReg = (i2c_Buf[1] << 8) | i2c_Buf[0];
    return(dataSTR.osReg);
}
*/

int BQ27220::read_registers(BQ27220_TypeDef& dataSTR)
{
    i2c_Buf[0] = BQ_CNTL;
    int result = _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    if(result) return(result + 0x10);
    result = _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 32, false);
    wait_us(66);
    if(result) return(result + 0x18);
    //Thread::wait(1);
    
    dataSTR.cntlReg =    (i2c_Buf[BQ_CNTL    - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_CNTL    - BQ_CNTL];
    dataSTR.arReg =      (i2c_Buf[BQ_AR      - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_AR      - BQ_CNTL];
    dataSTR.artteReg =   (i2c_Buf[BQ_ARTTE   - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_ARTTE   - BQ_CNTL];
    dataSTR.tempReg =    (i2c_Buf[BQ_TEMP    - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_TEMP    - BQ_CNTL];
    dataSTR.voltReg =    (i2c_Buf[BQ_VOLT    - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_VOLT    - BQ_CNTL];
    dataSTR.flagsReg =   (i2c_Buf[BQ_FLAGS   - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_FLAGS   - BQ_CNTL];
    dataSTR.currentReg = (i2c_Buf[BQ_CURRENT - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_CURRENT - BQ_CNTL];
    
    dataSTR.rmReg =      (i2c_Buf[BQ_RM      - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_RM      - BQ_CNTL];
    dataSTR.fccReg =     (i2c_Buf[BQ_FCC     - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_FCC     - BQ_CNTL];
    dataSTR.aiReg =      (i2c_Buf[BQ_AI      - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_AI      - BQ_CNTL];
    dataSTR.tteReg =     (i2c_Buf[BQ_TTE     - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_TTE     - BQ_CNTL];
    dataSTR.ttfReg =     (i2c_Buf[BQ_TTF     - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_TTF     - BQ_CNTL];
    dataSTR.siReg =      (i2c_Buf[BQ_SI      - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_SI      - BQ_CNTL];
    dataSTR.stteReg =    (i2c_Buf[BQ_STTE    - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_STTE    - BQ_CNTL];
    dataSTR.mliReg =     (i2c_Buf[BQ_MLI     - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_MLI     - BQ_CNTL];
    
    i2c_Buf[0] = BQ_MLTTE;
    result = _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    //if(result) return(result + 0x20);
    result =_i2c.read(BQ27220_ADDR + 1, i2c_Buf, 32, false);
    wait_us(66);
    //Thread::wait(1);
    //if(result) return(result + 0x28);
    
    dataSTR.mltteReg =   (i2c_Buf[BQ_MLTTE   -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_MLTTE   -  BQ_MLTTE];
    dataSTR.rawccReg =   (i2c_Buf[BQ_RCC     -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_RCC     -  BQ_MLTTE];
    dataSTR.apReg =      (i2c_Buf[BQ_AP      -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_AP      -  BQ_MLTTE];
    dataSTR.intTempReg = (i2c_Buf[BQ_INTTEMP -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_INTTEMP -  BQ_MLTTE];
    dataSTR.cycReg =     (i2c_Buf[BQ_CYC     -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_CYC     -  BQ_MLTTE];
    dataSTR.socReg =     (i2c_Buf[BQ_SOC     -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_SOC     -  BQ_MLTTE];
    dataSTR.sohReg =     (i2c_Buf[BQ_SOH     -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_SOH     -  BQ_MLTTE];
    
    dataSTR.cvReg =      (i2c_Buf[BQ_CV      -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_CV      -  BQ_MLTTE];
    dataSTR.ccReg =      (i2c_Buf[BQ_CC      -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_CC      -  BQ_MLTTE];
    dataSTR.btpdReg =    (i2c_Buf[BQ_BTPD    -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_BTPD    -  BQ_MLTTE];
    dataSTR.btpcReg =    (i2c_Buf[BQ_BTPC    -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_BTPC    -  BQ_MLTTE];
    dataSTR.osReg =      (i2c_Buf[BQ_OS      -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_OS      -  BQ_MLTTE];
    dataSTR.dcReg =      (i2c_Buf[BQ_DC      -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_DC      -  BQ_MLTTE];
    dataSTR.subReg =     (i2c_Buf[BQ_SUB     -  BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_SUB     -  BQ_MLTTE];
    
    i2c_Buf[0] = BQ_MACDATA;
    result = _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    //if(result) return(result + 0x30);
    result =_i2c.read(BQ27220_ADDR + 1, i2c_Buf, 32, false);
    wait_us(66);
    //Thread::wait(1);
    //if(result) return(result + 0x38);
    
    for(int i = 0; i < 32; i++) {
        dataSTR.macData[i] = i2c_Buf[i];
    }
    
    i2c_Buf[0] = BQ_MACDATASUM;
    result = _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
    //if(result) return(result + 0x40);
    result =_i2c.read(BQ27220_ADDR + 1, i2c_Buf, 32, false);
    wait_us(66);
    //Thread::wait(1);
    //if(result) return(result + 0x48);
    
    dataSTR.macSumReg = (i2c_Buf[BQ_MACDATASUM  -  BQ_MACDATASUM + 1] << 8) | i2c_Buf[BQ_MACDATASUM  -  BQ_MACDATASUM];
    dataSTR.macLenReg = (i2c_Buf[BQ_MACDATALEN  -  BQ_MACDATASUM + 1] << 8) | i2c_Buf[BQ_MACDATALEN  -  BQ_MACDATASUM];
    dataSTR.anacReg =    i2c_Buf[BQ_ANACNT      -  BQ_MACDATASUM];
    dataSTR.rawcReg =   (i2c_Buf[BQ_RAWC        -  BQ_MACDATASUM + 1] << 8) | i2c_Buf[BQ_RAWC        -  BQ_MACDATASUM];
    dataSTR.rawvReg =   (i2c_Buf[BQ_RAWV        -  BQ_MACDATASUM + 1] << 8) | i2c_Buf[BQ_RAWV        -  BQ_MACDATASUM];
    dataSTR.rawtReg =   (i2c_Buf[BQ_RAWT        -  BQ_MACDATASUM + 1] << 8) | i2c_Buf[BQ_RAWT        -  BQ_MACDATASUM];
   
    return(0);
}