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.

BQ27510-G3: I2C sequency for subcommand write

Part Number: BQ27510-G3
Other Parts Discussed in Thread: BQ27510

I read SLUUA97, SLUSAT1A and SLUA467B and was able to find only the sequence for reading subcommands. It does work. However, if I want to, let's say, put BQ27510 into SLEEP or HIBERNATE state, I need to perform a subcommand write. How can I do that?

I tried to mimick the sequence for subcommand reading and do this - START, I2C_ADDR, CONTROL_CMD, SUBCOMMAND_LOW, SUBCOMMAND_HIGH, STOP and than do incremental write of the new value to the CONTROL_CMD - START, I2C_ADDR, CONTROL_CMD, VALUE_LOW, VALUE_HIGH, STOP.

I don't get any unexpected NACKs from BQ27510 but I'm not sure that I actually wrote something, since CONTROL_AND_STATUS is always read as 0x00.

It is also not clear what value should I write to the SET_SLEEP or SET_HIBERNATE to activate it. 1? Or any positive value?

Please, tell me, what is a correct sequence to write something to a subcommand and how do I check that it is actually written?

  • I think the easiest way for you to do that is to snoop the bus or scopr the i2c line. Control Status will always return the response to any command if received.
  • What do you mean - snoop the bus? What exactly should I see there?

    Can you please provide the correct sequence of I2C states for subcommand write?

  • My answer above was to help you check if your commands are actually being sent on the i2c line.

    For the subcommand,

    Example using DEVICE_TYPE subcommand:
    • To device address 0xAA, starting at command 0x00, write two bytes of data: 0x01 and 0x00.
    • Then read the response using an incremental read. To device address 0xAB, starting at command
    0x00, read two bytes.
  • >My answer above was to help you check if your commands are actually being sent on the i2c line.

    I'm pretty sure that my commands are actually sent since reading works, I can read FW_VERSION or DEVICE_TYPE. 

    >For the subcommand,

    >Example using DEVICE_TYPE subcommand:
    >• To device address 0xAA, starting at command 0x00, write two bytes of data: 0x01 and 0x00.
    >• Then read the response using an incremental read. To device address 0xAB, starting at command
    >0x00, read two bytes.

    That's a subcommand read (I wrote that I was able to find examples of subcommand read in the first post), I need a sequence for subcommand write. For instance, write to SET_HIBERNATE.

  • Write works the same way. Instead of sending the command 0x01 0x00, you will instead send 0x11 0x00 in little endian format. Then a read of the registers will show you that the hibernate bit has been set.
  • Thank you! Okay, so reading and writing is basically the same, that's weird.

    I did as you suggested and got mixed results. On one hand, in BQ Studio I can see that HIBERNATE bit was successfully set. On the other - after my code in the MCU sends SET_HIBERNATE subcommand - all reads of the CONTROL_STATUS command give me 0x0000.

    If I stop MCU (without resetting the board) and connect to bq27519 with BQ Studio I can properly see CONTROL_STATUS value there and it's not zero.

    I then close BQ Studio, resume my code execution and CONTROL_STATUS reads are non-zero again.

    All other commands are read without problem.

    If I try to SET_HIBERNATE from BQ Studio - there is no such effect. So BQ Studio and my code are different in some way but I can't figure out what is the difference; logic analyzer shows me the same sequence of I2c events.

    Any ideas?
  • Yeah, that's an IO register. So, if you stop scanning it or stop sending it 0x0000, it will reflect the status of whatever the command that was last sent to the gauge.

    I can't comment on your code. If the commands are the same, the response should also be the same.
  • So is there a way to make reading 0x00 reflect CONTROL_STATUS and not the status of the last subcommand?
  • Send 0x00 to 0x00 again and read. That gives you control status.
  • Yes, that worked. Thank you!