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.

BQ27532 I2C Can someone explain how on earth the commands work please (from a very experienced embedded engineer)

Other Parts Discussed in Thread: BQ28Z610

Folks,

I am struggling to understand what on earth the BQ27532 datasheet is on about when it comes to explaining how to interface over I2C. The datasheet is just terrible when it comes to explaining the commands. I cannot even begin to understand what it's on about! I have twenty-five years' experience of writing embedded code and interfacing to I2C, SPI, UART, Ethernet etc etc etc, but have no clue whatsoever as to what TI are going on about with this chip.

So...

...it says you have Command Codes and lists them as things like 0x01 and 0x02 for Control(), 0x0C and 0x0D for Nominal Available capacity etc.

With that in mind, if you want to read back Nominal Available capacity do you send two one-byte write commands to address 0x55, the first with CMD byte as 0x0C and the second as 0x0D? If so, what about the data bytes in those two I2C transactions? And then how do you read it back? It is two quick reads?

What about when writing? If you want to write to the At Rate register? Do you send two one-byte write commands to 0x02 and then 0x03 with the most significant data byte being one write and the low in the other? If so, what comes first? High byte or low byte? If that's not how you do it, what is the method?

Then we come to the utterly unfathomable Control() which is command code 0x00 and 0x01, then  has control data. Does that mean you write single commands of 0x00 and then 0x01 this time with the command data being what is sent as the data byte in the two write commands? So if you wanted to get, say, the device type back would be doing the following?

Write Sequence 1: ADDR CMD DATA 0x55 0x00 0x00

Write Sequence 2: ADDR CMD DATA 0x55 0x01 0x01

Then two quick reads ie: ADDR DATA ADDR DATA 0x55 0xYY 0x55 0xZZ where the device type returned would be made into a 16-bit in 0xYYZZ = 0x0532 in this case? That's assuming, of course, it would send back the MSB first!

I think what would be really helpful is a couple of examples of how to interface with it. I don't need code, it's more something along the lines of:

1. Do 1-byte Write with what ADDR CMD and DATA should be

2. Do another 1-byte write with what ADDR CMD and DATA should be

(I'm fairly use ADDR will always be 0x55)

3. Do a read  in whichever way that read should be done. Two one-bytes, incremental with whatever the CMD should be

etc

Please note I'm using ADDR, CMD and DATA as they appear in section 8.5.4.1 of the SLUSBU6 datasheet and 8.1 of the SLUUB04 technical reference. I realise that the data becomes 0xAA or 0xAB depending on whether it's a read or write. I know I2C. :)

Also, it goes on about instructing the fuel gauge to return things like device type (when doing Control() command and then requesting DEVICE_TYPE)  to addresses 0x00 and 0x01. What are these addresses?! How do I access these addresses?!


If someone could just give me one or two read and write examples in that sort of format I might be able to understand what's going on.


Many thanks. :)

  • Hello Robert,

    Thanks for bringing this up to our attention.

    Just to clarify, are you using 7-bit address or 8-bit address for I2C?

    0x55 becomes 0xAA.

    I will work on getting a sequence on how to read and write via I2C commands for you.

    Thanks
  • Hi, thanks for that. I am indeed aware of the 0x55 to 0xAA thing as I stated in my original post :)

    Rob
  • Hi, sorry to mither, but did you get anywhere with this? Or does anyone else just have a few lines of pseudo code they could post to get me started? Someone out there must have used this device? Many thanks!
  • I dont know if this answers your question, but I wrote some code that works for a BQ-24261 host-controlled charger. It can be controlled using I2C and has similar sounding registers as yours, that is what has prompted me write here. 

    https://github.com/chintanp/i2c-charger . The code is well-commented and should explain itself to you. 

    TI should definitely host some example codes for their devices, which was also told to me by my forum moderator, but was never done, that is kinds frustrating. 

  • Bumping this again. Is there really no-one who has done this?!

  • Hi and thanks for the reply. Your code doesn't really help me I'm afraid.

    Even down to the most basic things I just can't tie in your code to the data sheet:

    You have:

    init_reg[0] = 0x00;
    init_reg[1] = 0x04;

    Then you seem to send those two bytes to the device and read back 100 bytes. I can't even see in the data sheet where sending 0 and 4 to the device enables you to read back 100 register bytes. I#m clrarly missing something VERY fundamental and no matter how many times I read the datasheet I'm just not getting it.

    I simply want to know some pseudo code to read its ID and *maybe* I'll be able to piece everything together then!

    Thanks again for trying to help.
  • OK, sussed it. Found another thread which showed you how to do it in very basic steps with a different device and then tried similar methods with mine.

    So, here's thing thing: the datasheet is just nonsense. Don't even bother trying to make sense of it, you never will.

    First MASSIVE mistake in the datasheet:

    All the command bytes are NOT, repeat NOT things like 0x00 AND 0x01. They are 0x00 **OR** 0x01. To get that wrong shows THE most basic lack of understanding of logic.

    Next we come to these subcommand things. I still cannot fathom why someone thought this description was a good one. Just think of them as three byte commands. So, if you want a control command you send a three byte command:

    Byte 0 (always 0x00) Byte 1 Byte 2

    Byte 1 and 2 are the bytes in table 2.1 of the datasheet, BUT, you have to send them out big

    Next, you have to note that the data is sent in reverse pigging order. So, if you want to send a device type request,. you don't send 0x00 0x00 0x01. oh no, it's 0x00 0x01 0x00. Nowhere in the datasheet can I see it mention little endian data.

    So, to read the device ID:

    0x55(w) 0x00 0x01 0x00

    0x55(w) 0x00 0x55(r) 0x32 0x05

    Which gives a reply of 0x532. You know it makes sense.

    Well done TI, you have made a datasheet even worse than some of ST's. That takes some doing. All you silicon manufacturers need to go and study Atmel and see how they do it, then copy them.
  • Hello, in the BQ28Z610 Tech ref is stated "address is 0x55, then 0xAA to read and 0xAB to write"
    the I2C std cmd are 0x55(w) -> 0xAA while 0x55(r) -> 0xAB, exactly the contrary of the Texas Literature.
    Is is the literature wrong or do I have to rewrite all std I2C routine libraries?
  • 0x55(w) -> 0xAA while 0x55(r) -> 0xAB is correct.
    thanks
    Onyx
  • Robert,

    Just can not agree you more.

    the datasheet is so terrible.

    I spend a lot of time try to follow the step of datasheet, but the result is always wrong.

    Fortunately I have found your reply,or I still trap in the strange datasheet now.

    thank you so much.

    (I follow what you say,and it is successful at my first try. TI's datasheet is XXX)

  • sorry for your trouble. We now have an app note that discusses communication with our gauges.
    www.ti.com/.../slua801
    thanks
    Onyx