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.

BQ27421-G1: Gauge is not accepting new calculated checksum issued over I2C bus

Part Number: BQ27421-G1
Other Parts Discussed in Thread: EV2400, BQSTUDIO

Good afternoon,

I am using BQ27421-G1A battery gauge in our project. It was a time to do some power consumption tests and I realised using the battery gauge data will be the easiest way to do so due to equipment limitations.
Hence, I have started tailoring battery gauge to the needs we are having. I have determined all 4 necessary parameters to adjust - Design Capacity(120mAh), Design Energy(444mWh), Terminate Voltage(3200mV) and Taper Rate (500). I have got these number from battery datasheet and applied formulas provided from TI in "Quickstart Guide for bq27421-G1" (page 3-4)

Battery gauge currently in use comes UNSEALED (0x00 register bit 5 is unset), so all data updates can be done straight away.

So, I successfully managed to access registers to read Design Capacity (registers 0x4A, 0x4B), Design Energy (registers 0x4C, 0x4D), Terminate Voltage (registers 0x50, 0x51) and Taper Rate (registers 0x5B, 0x5C) which were set to default values. Hence, registers are written with values determined above. After writing new values, values are read again to confirm that battery gauge received the right values.

Now, to finalise writing procedure and make gauge save new data in NVM storage, a correct checksum has to be calculated and issued. So, I calculate checksum as per method described in "Technical Reference" for a battery gauge (page 16)

To get a step by step disassembled view of all the values received, please refer to attached TXT file.

OLD_Csum = 0xAC

OLD_DesCap_MSB = 0x5
OLD_DesCap_LSB = 0x3C

OLD_DesEn_MSB = 0x13
OLD_DesEn_LSB = 0x60

OLD_TerVol_MSB = 0xC
OLD_TerVol_LSB = 0x80

OLD_TapRat_MSB = 0x00
OLD_TapRat_LSB = 0x64


NEW_DesCap_MSB = 0x00
NEW_DesCap_LSB = 0x78

NEW_DesEn_MSB = 0x1
NEW_DesEn_LSB = 0xBC

NEW_TerVol_MSB = 0xC
NEW_TerVol_LSB = 0x80

NEW_TapRat_MSB = 0x1
NEW_TapRat_LSB = 0xF4



temp = mod(0xFF - 0xAC - 0x5 - 0x3C - 0x13 - 0x60 - 0xC - 0x80 - 0x00 - 0x64, 0x100) = mod(0x-151, 0x100) = 0xAF


NEW_Csum = 0xFF - mod(0xAF + 0x78 + 0x1 + 0xBC + 0xC + 0x80 + 0x1 + 0xF4, 0x100) = 0xFF - mod(0x365, 0x100) = 0xFF - 0x65 = 0x9A

Values calculated by hand and using software match. However, when I am trying to write values to a register, it doesnt accept it - I2C issues the value but battery gauge doesnt respond to received value. Moreover, if I am going to issue SOFTRESET command (0x0042) it seems like it is not coming back to normal mode from CFGUPDATEMODE (Flag for the mode is still set).

So, I am stuck here, not being able to write new calculated checksum even though it looks like a good checksum, calculated as per datasheets. Am I missing some kind of delay after issuing I2C command? I am not using any delay routines when issuing writing commands over I2C to write Design Capacity, Design Energy etc. since when i read them back over I2C bus, they already coming back to me updated. However, is it the case with chechksum? Or there should be some kind of a delay routine to allow gauge to recalculate checksum in the background so it has something to compare with when I actually write checksum over I2C?

  • Hello Dmitrij,

    The best way to test the communication of the gauge is to sniff the I2C lines while you communicate with the EV2400 and EVM. Then you can use that as a reference for your own application.

    Are you writing one parameter at a time or are you writing all of them and doing the checksum for all at once? I would try doing it one parameter at a time and see if it helps.

    Sincerely,

    Wyatt Keller

  • Thanks for a prompt reply.

    I am currently using new I2C call to read/write each register.

    Logic flow is as follows (device is UNSEALED):

    1. Issue I2C command to put gauge into CFGUPDATEMODE
    2. Access appropriate memory blocks (some more I2C writes not described here)
    3. Read current checksum register via I2C call. Store value locally.
    4. Read Design Capacity register via I2C call. Store value locally
    5. Read Design Energy register via I2C call. Store value locally.
    6. Read Terminate Voltage register via I2C call. Store value locally.
    7. Read Taper Rate register via I2C call. Store value locally.
    8. Calculate temporal checksum of the values stored locally
    9. Write new Design Capacity value, stored locally, via I2C call.
    10. Write new Design Energy value, stored locally, via I2C call.
    11. Write new Terminate Voltage value, stored locally, via I2C call.
    12. Write new Taper Rate value, stored locally, via I2C call.
    13. Finish calculating new checksum using new values.
    14. Write new checksum value via I2C call
    15. Issue SOFTRESET command over I2C bus.

    Steps in red are failing.

    As per design, i do at least 5 reads over I2C bus and at least 5 writes over I2C bus. There are some commands issued over I2C while I am setting up data blocks to read. But I assume I set up the memory blocks to read correctly since when I am reading old values (step 3 - 7) I am getting default values of the gauge which correlate to the ones outlined in the datasheet.

    As far as I see, if I am trying to read the checksum register (same register as in step 3) after all the writes, I am getting old checksum (same checksum as in step 3) back, not the updated one...

    I am using a custom platform and dont currently possess an evaluation board of the gauge.

    I am now confused - maybe there is an issue of the custom platform I am using? All the other I2C commands are coming through, but I2C write call for checksum is not... 

    The other question is - are there any delays needed between steps 14 and 15? My assumption is if checksum takes time to confirm it is the right one (I assume gauge does the check of a checksum for me), maybe I am issuing SOFTRESET command too early which corrupts gauge's flow?

    Moreover, seems like SOFTRESET doesnt work either since if I am to poll flags register again after all the writes (after step 15), gauge is still in CFGUPDATEMODE....

  • Hello Dimitrij,

    This apps note may help you: https://www.ti.com/lit/an/slua801/slua801.pdf?ts=1593193163862&ref_url=https%253A%252F%252Fwww.google.com%252F

    You will need to add a delay between when you write a checksum and when you read it. Try adding a delay between steps 14 and 15, no delay could prevent the gauge from calculating the right values for the checksum.

    Have you tried writing one parameter at a time then calculating the checksum and writing it? If you could use the EV2400 and bqStudio you could verify the correct checksum procedure with your board.

    Sincerely,

    Wyatt Keller

  • Thank you for a response.

    I have tried writing one parameter at a time and it worked up to a point.
    I had a look into a platform that we are currently using, and seems like it was I2C driver issue - it was failing after issuing some I2C commands.
    So, we have fixed the I2C driver and now it works flawlessly!

    Thank you for an idea - it definitely helped understanding where the issue was!