This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

bq27621-g1 design capacity change and initialization

Other Parts Discussed in Thread: BQ27621-G1

I've tried almost everything to change the design capacity of the fuel gauge bq27621-g1, but it does not work. The reference for my c code is based on the technical reference datasheet and the shown pseudo code. Does someone can give me a hint in my code, where the problem could be?

Thank you for helping:

My code:

//unsealed
fuel_write_reg(REG_CTRL_REG1, 0x00);
fuel_write_reg(REG_CTRL_REG2, 0x80);
fuel_write_reg(REG_CTRL_REG1, 0x00);
fuel_write_reg(REG_CTRL_REG2, 0x80);

/* Enter Config Update Mode (Can take up to a second) */

uint8_t tries = 2000;
for (tries ; tries > 0 && !(fuel_read_reg(0x06) & 0x10); tries--) {
fuel_write_reg_buf(0x00, {0x13,0x00});
msleep(100);
}

if((fuel_read_reg(0x06) & 0x10)){
log_msg(LOG_ERROR, __cfunc__, "set config Succeed - OK");
}else{
log_msg(LOG_ERROR, __cfunc__, "set config FAILED");
}

/*Enter block mode */

fuel_write_reg(0x61, 0x00);

fuel_write_reg(0x3E, 0x52);

fuel_write_reg(0x3F, 0x00);

/*read out checksum old*/

uint8_t old_csum = fuel_read_reg(0x60);

/*read old design capacity */

uint8_t old_design_cap_MSB = fuel_read_reg(0x43);
uint8_t old_design_cap_LSB = fuel_read_reg(0x44);

/*write new design capacity 1250mAh -> 0x4E2 */


uint8_t new_design_cap_MSB = 0x04;
uint8_t new_design_cap_LSB = 0xE2;
fuel_write_reg(0x43,new_design_cap_MSB);
fuel_write_reg(0x44,new_design_cap_LSB);

/*compute new block checksum */
uint8_t temp = (255-old_csum-old_design_cap_MSB-old_design_cap_LSB)%256;

uint8_t new_csum = 255-(temp+new_design_cap_MSB+new_design_cap_LSB)%256;

/* Soft Reset */
uint8_t tx_buf_2[] = {0x42,0x00};
fuel_write_reg_buf(REG_CTRL_REG1, tx_buf_2);

/* confirm config mode is exited*/
if((fuel_read_reg(0x06) & 0x10)){
log_msg(LOG_ERROR, __cfunc__, "set config Succeed");
}else{
log_msg(LOG_ERROR, __cfunc__, "set config FAILED --OK");
}

/* sealing device */
uint8_t tx_buf_sealing[] = {0x20,0x00};
fuel_write_reg_buf(0x00, tx_buf_sealing);

  • Hello Sandro,

    I couldn't find in your code where you wrote the new block checksum to the gauge after computing it. This should be done between /*compute new block checksum*/ and the Soft Reset.

    If the correct checksum is not written to the gauge, this may affect data memory parameter updating.

    Hope this helps, thanks!
  • Hi Fernando

    Yes, this was one issue, i forget it in my code. but after this, it still doesn't work. I have now a buggy version which some times works. The main problem is the timing. I put some delays into my code and now it works.

    /* Enter block mode */
    fuel_write_reg(0x61, 0x00); //0x61 command 0x00
    msleep(100);
    fuel_write_reg(0x3E, 0x52); //0x3e 0x40 dec muss 0x52 sein um subclass 82 zu sein.
    msleep(100);
    fuel_write_reg(0x3F, 0x00); //0x3F offset ist 3 und somit muss 0x00 eingestellt werden.

    msleep(100); /* Shouldn't be needed, doesn't work without it. */

    But for example, yesterday it worked and today not, so i think it is not the best solution.

  • Hi All


    As already described, i had some issue with the initialisation of the fuel gauge. The following shows now the sometimes working code for changing the design capacity. But my question is, is this initialisation time sensitive, because it was necessary to implement some delays at specific code parts. And now, this code works just sometime, meaning... after testing the same code after some hours, the fuel gauge initialisation does not work anymore.



    Thank you for your help.


    Here is my code:

    //unsealed
    fuel_write_reg(REG_CTRL_REG1, 0x00);
    fuel_write_reg(REG_CTRL_REG2, 0x80);
    fuel_write_reg(REG_CTRL_REG1, 0x00);
    fuel_write_reg(REG_CTRL_REG2, 0x80);

    //msleep(100);

    // Enter Config Update Mode (Can take up to a second) //
    if((fuel_read_reg(REG_FLAGS) & 0x10)){
    log_msg(LOG_ERROR, __cfunc__, "set config -- FALSE");
    }else{
    log_msg(LOG_ERROR, __cfunc__, "set config -- OK");
    }

    uint16_t tries = 2000;
    uint8_t tx_buf[] = {0x13,0x00};
    fuel_write_reg_buf(REG_CTRL_REG1, tx_buf);

    for (tries = 2000 ; (tries > 0 ) && !(fuel_read_reg(REG_FLAGS) & FLAGS_CFGUPD); tries--) {
    fuel_write_reg_buf(REG_CTRL_REG1, tx_buf);
    msleep(10);
    }

    if((fuel_read_reg(REG_FLAGS) & 0x10)){
    log_msg(LOG_ERROR, __cfunc__, "set config Succeed - OK");
    }else{
    log_msg(LOG_ERROR, __cfunc__, "set config FAILED");
    }


    // Enter block mode //
    fuel_write_reg(0x61, 0x00); //0x61 command 0x00
    msleep(100);
    fuel_write_reg(0x3E, 0x52); //0x3e 0x40 dec muss 0x52 sein um subclass 82 zu sein.
    msleep(100);
    fuel_write_reg(0x3F, 0x00); //0x3F offset ist 3 und somit muss 0x00 eingestellt werden.

    msleep(100);// Shouldn't be needed, doesn't work without it. //

    //read out checksum old//
    uint8_t old_csum = fuel_read_reg(0x60);


    uint8_t old_design_cap_MSB = fuel_read_reg(0x43);
    uint8_t old_design_cap_LSB = fuel_read_reg(0x44);


    //write new design capacity 1250mAh -> 0x4E2 //
    uint8_t new_design_cap_MSB = 0x04; //0x04
    uint8_t new_design_cap_LSB = 0xE2; //0xE2
    fuel_write_reg(0x43,new_design_cap_MSB);
    fuel_write_reg(0x44,new_design_cap_LSB);

    //compute new block checksum //
    uint8_t temp = (255 - old_csum - old_design_cap_MSB - old_design_cap_LSB)%256;
    uint8_t new_csum = 255 - ((temp + new_design_cap_MSB + new_design_cap_LSB)%256);

    //write new csum//
    fuel_write_reg(0x60,new_csum);
    msleep(100);

    // Soft Reset //
    uint8_t tx_buf_2[] = {0x42,0x00};
    fuel_write_reg_buf(REG_CTRL_REG1, tx_buf_2);
    msleep(100);
    // confirm config mode is exited//
    if((fuel_read_reg(0x06) & 0x10)){
    log_msg(LOG_ERROR, __cfunc__, "set config -- FALSE");
    }else{
    log_msg(LOG_ERROR, __cfunc__, "set config -- OK");
    }

    // sealing device //
    uint8_t tx_buf_sealing[] = {0x20,0x00};
    fuel_write_reg_buf(0x00, tx_buf_sealing);
  • Hello Sandro,

    What host are you using to communicate with the gauge? Does it allow clock stretching?

    What is the I2C operating frequency you are using? If it's 400kHz, I recommend reviewing section 8.5.3.3 that details the waiting time required for proper I2C operation.

    Thank you.
  • hi fernando

    we re using the stm32f429 from stmicroelectronics. About the clock streching i'm not sure. the i2c operating frequency is 400khz.

    i saw the waiting time requirements and i think with the additional waiting times implemented that should be fine.