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.

BQ76942: Communication/Reset Issue

Part Number: BQ76942

Tool/software:

If the MCU and the I2C pullups are powered on before the BQ, everything works just fine.
But in our current design, normally the BQ is woken first and the voltage domain that powers the MCU and I2C pullups is only supplied with a ~20ms delay, in the meantime the bus lines don't have pullups.
Apparently this causes the I2C interface of the BQ to lock up because it will never again ACK any command but I can see that REG1V8 and REG1(3V3) are online so the BQ must be active.
Is this theory plausible and if so, what are the exact conditions for that to happen?

For the next PCB revision we intend to change how the pullups are supplied but for the current revision we still need to get it working somehow.
My idea of a workaround was to reset the BQ as soon as the MCU boots by setting the RST_SHUT pin for 10ms.
That does resolve the I2C issue but creates a new problem, the accumulated charge is then reset to some garbage value.
So I try to send it a RESET_PASSQ subcommand as well but that is without effect unless I insert a 300ms delay between RST_SHUT going low again an the subcommand being sent.
What is going on here, why is this delay needed and where is it documented?

Also:
Why does the OTP_WR_CHECK subcommand take up to 200ms to execute?
If I send the device a RESET subcommand, I need to wait 20ms before the next command is accepted, why is this not documented?
If I try to read from 0x0084, it never seems to complete, 0x3e and 0x3f always returning 0xff, why is that?
And why is a "CRC" appended to every byte? That defies the logic of a CRC, why not implement it properly and get rid of the checksum at 0x60 instead?

So far, implementing the driver for that IC has been a complete frustration..

BR

  • Hello Nicolai,

    Apparently this causes the I2C interface of the BQ to lock up because it will never again ACK any command

    What do you mean by the device will lock up? Is the AFE holding the SCL low? Have you tried sending 8+1 clock pulses? This previous forum post may be able to assist you: How to Inform an I2C Target to Release the Bus.

    So I try to send it a RESET_PASSQ subcommand as well but that is without effect unless I insert a 300ms delay between RST_SHUT going low again an the subcommand being sent.
    What is going on here, why is this delay needed and where is it documented?

    A full reset signal can take up to ~500ms, whereas a partial reset can take up to ~200-300ms. This is not documented at the moment.

    Why does the OTP_WR_CHECK subcommand take up to 200ms to execute?

    The timing of subcommands can vary depending on system operation at the time. I have seen users wait 10ms to 100ms just to be safe in giving the AFE enough time to process the command and update its register with the correct values. 

    , 0x3e and 0x3f always returning 0xff, why is that?

    Usually 0xFF means the subcommand has not completed operation yet. This can usually occur when you’re reading the data too quickly especially after writing to it. Try adding a 2 ms wait time/delay in between measurements. Section 2 Subcommands from the BQ769x2 Software Development Guide and/or Section 3.1 Direct Commands and Subcommands can provide more information regarding it.

    And why is a "CRC" appended to every byte?

    CRC is optional for our device as some users do not want CRC. Section 9.1 Serial Communications Overview from the Technical Reference Manual gives more information regarding the part’s different communication type settings.

    Best Regards,
    Alexis


  • Thank you for your response!

    What do you mean by the device will lock up? Is the AFE holding the SCL low? Have you tried sending 8+1 clock pulses? This previous forum post may be able to assist you: How to Inform an I2C Target to Release the Bus.

    The device does not respond to any commands at all, it does not respond with an ACK after the MCU sends its address. I tried sending clock pulses, 9 or even more, without any effect.

    The timing of subcommands can vary depending on system operation at the time. I have seen users wait 10ms to 100ms just to be safe in giving the AFE enough time to process the command and update its register with the correct values. 

    Is there no way to check if a write-subcommand has completed execution?

    Usually 0xFF means the subcommand has not completed operation yet. This can usually occur when you’re reading the data too quickly especially after writing to it. Try adding a 2 ms wait time/delay in between measurements.

    Since some commands needed more time than documented, the simple approach with a constant delay of 2ms did not work reliable enough for me, so I implemented the method of checking 0x3e and 0x3f before reading the remaining data. But the subcommand 0x0084 only ever returns 0xff for at least 1s, longer wait times are unacceptable for my application because of a watchdog. The TRM does not mention that a delay in the read-0x3e-0x3f-loop is needed?

    CRC is optional for our device as some users do not want CRC.

    I know the "CRC" is optional but it is not very useful. The purpose of a CRC is to detect corruption in a block of data with a single hash-like checksum. The way it is implemented here, a CRC byte is sent for every data byte, doubling the necessary bandwidth on the bus, which is no more useful than sending every byte twice. And it could instead have been accomplished with a single, properly implemented CRC byte.

    Best Regards
    Nico

  • Hello Nico,

    The device does not respond to any commands at all, it does not respond with an ACK after the MCU sends its address. I tried sending clock pulses, 9 or even more, without any effect.

    This What is the I2C Device Address of the BQ769x2 Family FAQ may help potentially.

    Is there no way to check if a write-subcommand has completed execution?

    The wait time is the simplest approach. Another approach for subcommands is described in Section 3.1 Direct Commands and Subcommands of the technical reference manual which checks if the subcommand has completed operation or not. You could keep reading 0x3E/0x3F until it returns what originally written or incorporate a retry scheme. 

    This Software Development Guide may also be useful to refer too.

    But the subcommand 0x0084 only ever returns 0xff for at least 1s

    Writing to the subcommand 0x0084 CB_SET_LVL() shouldn't require a delay as there isn't any data to fetch. The timing/delay should only be needed when reading to fetch data.

    Are you following the subcommand with a write to 0x60/0x61 with the checksum/length as well as doing this when in CONFIG_UPDATE mode? Section 3 Reading and Writing RAM Registers from the Software Development Guide explains this a bit more. 

    The purpose of a CRC is to detect corruption in a block of data with a single hash-like checksum

    With certain commands you can do a block read, instead of reading each individual byte. Because the voltage measurement commands are in ascending order, you can use the direct command to read starting from Cell 1 voltage (0x14) and read 32 bytes from there to read all 16 Cell Voltages if you wanted to have only those values.

    Another example/method to potentially read all the cell voltage measurements with less commands are with the block subcommands that section in the TRM briefly talks about. The sections after Section 4.4 give more detail regarding it.

    Best Regards,
    Alexis