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.

BQ27441-G1: Problem reading checksum

Part Number: BQ27441-G1
Other Parts Discussed in Thread: BQSTUDIO

I'm writing a set of c functions that can interface with the fuel gauge part and ran into some undocumented behavior I'd like some clarification on.


I followed the flow chart in figure 1 of the document SLUUAP7 (attached to this post for convenience) and captured the I2C bus transactions to verify that I was faithfully following the recommended communication pattern. I also made sure I was using the 100kHz bus data rate as recommended by the datasheet. I was able to verify that my communications were conforming to the expected behavior outlined in the figure, but had issues when comparing my expected checksum to the value retrieved by reading from the IC. Specifically, the step at the end of the block  labeled  "Steps to verify RAM update completed correctly" in the figure I've mentioned. No matter what values I was using the returned byte from the part was always 0x00, and so when comparing my expected new checksum against the reported checksum the comparison would fail. Per the recommended design flow this would configure a retry of the whole update, trapping the code in an endless loop.


I couldn't understand what the issue was but eventually found that if I added a delay before I read the checksum from the part (I'm using a 1s delay after writing 0x00 to 0x3F) that I was able to read back the expected checksum and it matched what I had calculated. From what I could tell this behavior is undocumented. What minimum delay value should I be using here to ensure that the part is able to correctly report the checksum value back to my program?


Thank you,


Don

sluuap7.pdf

  • Hello Don,

    Make sure your gauge is not in seal mode.

    Also make sure the CFG Update bit is set if you want to modify any RAM values.

    Thanks!

  • FuelGaugeI2C.csvThank you Kang. Since I was following the recommended programming flow and sniffing the activity on the I2C I can confirm that I am unsealing the part and that I am checking the CFG Update bit before making any modifications to the RAM.

    If you check the flow chart in figure one of the document I've attached to the original question it may give more context since that is what I was following. I have the code working well enough now because I added the delay before reading back the checksum value, but I want to make sure I understand the nature of what is happening and that the delay I'm using wlll be enough for every case in which I interact with the part. Could you look into why specifically the delay I'm talking about is necessary? I can share source files and point out line numbers if that will help.

    I attached a .csv of the I2C communications captured by our bus analyzer. The delay that I have found to be necessary is inserted between rows 33 and 34 if you view the file in excel. You can see that I select the data class, the data offset, and then ~2ms pass before I retrieve the checksum to compare it against what I wrote a bit earlier in the exchange. Without the 2ms delay reading the checksum returns 0x00 always.

    This is the issue I am experiencing.

    Best,

    Don

  • Hello Don,

    Thanks! This makes sense. I have seen this before.

    We have bqStudio generated gm.fs files with the delays on checksum.

    There's a slight section on 9.5.4.4 that talks about why the delay is there. If you can afford the timing, try with 5 milliseconds.

    Thanks!

  • Kang,

    I think I see what you're talking about. Are you referring to the data sheet section titled "I2C Clock Stretching"? If so I read right past it initially. Doesn't clock stretching imply that the slave device (the fuel gauge in this case) will hold the clock line low while it catches up and that the master device shouldn't need to manually insert delays since the clock stretching would arbitrate these delays on the bus as necessary?

    If I'm looking at the wrong section I apologize. Could you specify which document you're referring to if I am looking at the wrong one? If the master device (my processor) is responsible for adding delays because the device is NOT stretching the clock when it needs time, where else should I anticipate this being an issue?

    Thank you,

    Don

  • Hello Don,

    Yes, I meant clock stretching.

    You may want to check your host source code on how it handles clock stretching.

    The gauge will commit the write when you write the checksum or the address 0x60 in block data access mode.

    During this time, if you try to immediately compare the expected checksum to address 0x60, the gauge will not respond with the correct checksum.

    You may want to get a scope waveform on writing the last byte, writing to 0x60, and then reading and comparing to address 0x60 with and without the delay.

    This particular gauge may just be returning zeroes during the period when the host tries to read the checksum before it is ready.

    Thanks!

  • Thanks for the support Kang. I was developing my code to run on arduino Uno before porting it over to our target processor. I was using Wire.h to handle the I2C part of the code. I'll look into whether it is supporting clock stretching or not.

    Best,

    Don

  • Hello Don,

    You may just want to measure it with a scope. It is difficult to trace MCU level i2c issues. You could try to add a re-try until success and increment the delay to see if it will ever get to a point where the gauge finishes the computation and move to the next block write.

  • Thanks Kang. In my particular case since the issue is with an mcu+library combo that isn't our ultimate target I probably won't invest a lot of time in tracking it down for the arduino, especially since there is a known workaround. I'm curious though, does TI have a comprehensive document of times where clock-stretching may be activated?

  • Hello Don,

    Due to the complex nature of the gauge IC running FW, it is hard to know just when the device is "busy" doing some operation. The DS tries to list out these operations, but the gauge will clock stretch if it is servicing a different thread that needs to be in a critical path and a communication interrupt comes in.

  • That makes sense and is the answer I expected. I'll make sure we support clock stretching when we migrate to the next processor. Thanks for the help on this Kang. I hope you have a good day.

    Best,

    Don

  • Thanks Don, let us know if you need more help!