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.

MSPM0L1306: I2C communication stuck when MSPM0L1306 with BQ76905 using Example code

Part Number: MSPM0L1306
Other Parts Discussed in Thread: BQ76905, , BQ76905EVM, SYSCONFIG, BQ40Z50, TCA9546A, ISO1541, ISO1540

Tool/software:

I have custom board using MSPM0L1306 with BQ76905 over I2C protocol and i am able to flash example code of it over I2C but that example stuck at I2C_Read Function at 

/* Wait until controller send all bytes */
while ((gI2cControllerStatus != I2C_STATUS_TX_COMPLETE) &&
(gI2cControllerStatus != I2C_STATUS_ERROR)) {
__WFE();
}

when 

/* I2C Write Example */

DirectCommands(AlarmEnable, 0x00, R); // Read AlarmEnable Configuration

Please tell me why this is happening.

  • 1) It looks as though gI2cControllerStatus is not declared "volatile". With Optimization=2 (-O2) it's possible the loop isn't seeing the variable updates (done by the ISR). Specifically:

    > enum I2cControllerStatus {

    Try instead:

    > volatile enum I2cControllerStatus {

    2) Another possibility is that you're encountering a NACK (the example code doesn't appear to handle NACK properly). Are you using the bq76905EVM?

  • Using 

    > volatile enum I2cControllerStatus { 

    instead of 

    > enum I2cControllerStatus {

    this didn't resolve my issue. It still stuck at 

    /* Wait until controller send all bytes */
    while ((gI2cControllerStatus != I2C_STATUS_TX_COMPLETE) &&
    (gI2cControllerStatus != I2C_STATUS_ERROR)) {
    __WFE();
    }  

    I am using BQ76905RGRR.

    Please guide me.

  • 1) Can you post a schematic of your board? (If you're using a commercial breakout board, a product name and/or link is probably enough.) The first thing I would look for is the pullup resistors on SDA/SCL. If they're (only) connected to REGOUT, I'm pretty sure you need to have a battery attached. (The EVM has two sets of pullups, just in case.)

    2) You appear to have the debugger available; can you see the value of "gI2cControllerStatus"?

    3) Have you changed anything in the Example code?

    4) If you have a scope or logic analyzer, this might be a good time to set it up.

    I recommend you keep the "volatile" change; even if it's not the cause of what you're seeing now, it will be eventually.

    I don't have one of these devices, so all I can do is make suggestions.

  • Hi Nitin,
    Aside from what Bruce mentions (which you should do 100%), I will recommend to check which pins are you using, and the way they are configured in Sysconfig.

    Best Regards,

    Diego Abad

  • Please find my Response below,

    1) Can you post a schematic of your board? (If you're using a commercial breakout board, a product name and/or link is probably enough.) The first thing I would look for is the pullup resistors on SDA/SCL. If they're (only) connected to REGOUT, I'm pretty sure you need to have a battery attached. (The EVM has two sets of pullups, just in case.) 

    Response: My board is custom with SDA and SCL pin of MSPM0L1306 is PA0 and PA1 respectively. 4.7K Pullup is connected to it with separate 3.3V regulator voltage and not from REGOUT. Regulators input voltage is battery voltage.

    2) You appear to have the debugger available; can you see the value of "gI2cControllerStatus"?

    Response: The Value of gI2cControllerStatus is "I2C_STATUS_TX_INPROGRESS"

    3) Have you changed anything in the Example code?

    Response: NO.

    4) If you have a scope or logic analyzer, this might be a good time to set it up.

    Response: I have checked SDA signal on Logic analyzer and found that it wait for ACK and gets Timeout error.

    The SDA and SCL pins are already configured in example code as PA0 for SDA and PA1 for SCL and my board also had same pins connections.

    regards,

    Nitin

  • Your description of the logic analyzer trace is interesting. If the master (MSPM0) is waiting for the ACK, that must mean that the slave (BQ76905) is stretching the clock. Datasheet (SLUSE97) Fig 7-4 indicates that it might stretch the clock After the ACK cycle. I wonder if that actually means that it stretches the ACK cycle itself (though I have seen a trace from the BQ40Z50 (here) that shows it stretching after the first Tx bit (mid-byte)).

    If the BQ76905 is stretching the clock for a full 2 seconds (its "long" timeout), that suggests something not-quite-right about that device -- maybe the way it's wired up on your board. Do you have the EVM? I'm curious whether you see the same symptom there.

  • Hi Nitin,
    It seems that the M0 is working as intended, and the BQ76905 is not responding. I recommend posting this question in the BMS-BGP E2E forum for further help on the BQ76905.
    Best Regards,
    Diego Abad

  • Currently I don't have EVM. In will try on it but till can you suggest anything on the same my custom board which will solve my problem?

    Regards,

    Nitin

  • At the I2C level, if the slave is holding (stretching) SCL low, the master can't do much. I2C spec (UM10204 rev7) Sec 3.1.16 suggests resetting or power-cycling the slave; I don't see a reset pin, and I think the BQ runs from the battery, so those probably aren't options. Given that the very first transaction fails, my guess is that even if you did reset it it would probably do the same thing.

    What I would do at this point is compare the EVM schematic [Ref UG (SLUUCY9) sec 5.1] with yours, and consider any differences between them.

    Can you post your logic analyzer trace [Insert->Image]? Maybe someone here will see a clue.

    As Diego points out, the Power Management people might have a better suggestion:

    https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum

  • Hello

    Thanks for Support.

    I think the issue with my board  itself. But I want your advise on it. The I2C communication executed when I have connected SDA, SCL and GND pin to Logic analyzer to check waveforms. And when GND disconnected from logic analyzer then again it stuck at 

    /* Wait until controller send all bytes */
    while ((gI2cControllerStatus != I2C_STATUS_TX_COMPLETE) &&
    (gI2cControllerStatus != I2C_STATUS_ERROR)) {
    __WFE();
    }  

    Please let me know what will be the problem.

    Regards,

    Nitin

  • I suppose that means you have a grounding problem. How is pin 11 (VSS) connected? I imagine VSS should be shared with the MCU.

    I notice that the EVM also has "pin" 21 (the exposed pad on the bottom) connected to GND, though I don't see a recommendation for that in the data sheet. 

    My EE used to suggest, in cases where the scope seemed to be altering the GND, using a 3-to-2 pin power adapter on the scope, and leaving the third pin (on the adapter)  unconnected, providing a form of isolation. At least then you can see what's actually happening on the I2C.

  • VSS is connected to GND and MCU and BQ76905 had common GND.

  • Hi Nitin,
    I would recommend looking over the following Reference design (TIDA-010268) since this should provide a good reference on how an application layout for the BQ76905 and the MSPM0L device should look like.

    Best Regards,

    Diego Abad

  • I will rework on my custom board based on reference design.

    Thanks for support

    Regards,

    Nitin

  • Hello,

    I have updated my schematic and I am still not able to execute example code. It stuck at 

    /* Wait until controller send all bytes */
    while ((gI2cControllerStatus != I2C_STATUS_TX_COMPLETE) &&
    (gI2cControllerStatus != I2C_STATUS_ERROR)) {
    __WFE();
    }  

    Also find the I2C line waveforms on logic Analyzer.

      

    Please guide me on this.

    Regards,

    Nitin 

  • I think this is progress: There's no (bus) hang, and I think this isn't the first transaction, so at least one has succeeded.

    But you're getting a NACK on the Write data for register/command 0x60, which I don't see in TRM Sec 11. As I mentioned, this example doesn't deal well with NACKs (due to gI2cControllerStatus), so I suppose the (TI) testers didn't encounter it. Can you show a stack backtrace, or at least tell us which function (from main) is being called?

    Diego: Since this is one of the SDK demos, do you know anyone who knows how this code/device is intended to work? I can help from first-principles, but I don't know much about this device beyond a skimming of the TRM.

    [Edit: datasheet->TRM]

  • Hi Bruce and Nitin,

    The original examples intends for the I2C communication to work as bellow:

    1. Controller sends data

    2. Target receives data and transmits it back

    3. Controller receives the data and toggles LED if successful

    If the device is stuck at that part of the code, then the following must be true: 1. The M0 is not completing the intended transaction since it cannot reach the TX Done interrupt. 2. The NACK is not being registered by the M0 (which is weird since there is an interrupt handler for it.) Just to verify, Nitin can you set a breakpoint inside the case DL_I2C_IIDX_CONTROLLER_NACK part of the code (either a hardware or software breakpoint.) I want to check if it's accessing that interrupt since the other explanation of why it's not working is that gI2CControllerStatus is not TX_STARTED.

    Best Regards,

    Diego Abad

  • Your trace shows an I2C address of 0x20, but the address for the BQ76905 is 0x08 (DEV_ADDR). Is there anything else on your I2C bus?

  • I'm looking at Example (demo) bq7690x_control_i2c:

    https://dev.ti.com/tirex/explore/node?node=A__AOcJ8NCFdwGlSLJgqnoWEw__MSPM0-SDK__a3PaaoK__LATEST

    The NACK mistake here is similar to that in some of the base I2C examples: A NACK is only recognized in a certain state (really one of a pair) but that state is improbable/impossible at that moment so the conditional is always false and the NACK is ignored. In the base examples this is because a FIFO interrupt happens first. This one is different since those states never (ever) happen -- there's no code that sets the state to RX/TX_STARTED.

    I don't see the purpose of (any) state checks in the first place. As I recall you don't get a TXDONE event in the case of a NACK (though the I2C unit does terminate the transfer), so the symptom is a hang, not a failure.  And even if the checks did work they wouldn't catch the case of a Data NACK (as seen here).

  • Even supposing that the BQ76905 is (somehow) responding to address 0x20: A write to the Checksum register (0x60) is consistent with a call to Subcommands(); one might guess that the NACK results from an incorrect checksum. But this is only half-a-theory since:

    1) The TRM [Ref Sec 3.1] says that the device won't (can't) validate the checksum until the Length register (0x61) is written, so this NACK is too early.

    2) There are no calls to Subcommands() in this program (as provided).

    It seems more plausible that the Analyzer trace shows a response from some other device -- one which disapproves of the value being set in its 0x60 register.

  • Hello,

    I have Kept Device address is 0x08 only. 

    I have also set gI2cControllerStatus as volatile and I am getting it as "I2C_STATUS_TX_INPROGRESS". 

    I set breakpoint at DL_I2C_IIDX_CONTROLLER_NACK and observed that it got then it goes in while loop with I2C_STATUS_TX_INPROGRESS in I2C_Read Function

    In my custom board I2C lines are connected to 3.3V pullup with 4K7 and also used Isolation IC in between MCU and BQ76905 I2C lines.

    Please tell me what is wrong. 

    Regards,

    Nitin

  • I'm pretty sure you're getting a NACK, but I'm having trouble tying that to the NACK in your Analyzer trace, since that doesn't appear to be coming from the BQ76905.

    ----------

    What isolator IC are you using? I'm trying to figure out whether it is electrical-only (ISO16xx e.g.) or an I2C multiplexer (TCA9546A, e.g.).

    ----------

    Just to make sure: I'm looking at the SDK example code "bq7690x_control_i2c" [link above]. Is that what you're using?

  • Hi Bruce,
    I agree with you. I just need it to check if the device could recognize a NACK, which it seems to do based on Nitin's comment. To get out the infinite loop, the solution I can think is adding the "|| gI2cControllerStatus == I2C_STATUS_TX_INPROGRESS" inside the NACK interrupt. However, this won't solve the communication issues, just exit the infinite while loop.

  • Hi Nitin,
    I second Bruce comments on the isolator you are using. Is there a way for you to test this out by just having the I2C communication directly to the BQ76905? Also, did you posted this question in the BMS-BGP E2E forum? Did you get any feedback from the BMS-BGP team?

    Best Regards,

    Diego Abad

  • Also: When I build this program (fresh from Import) I get a warning from the linker: "warning #10210-D: creating ".sysmem" section with default size of 0x800"; this is triggered by the use of printf().

    I'm going to suggest you avoid this warning by setting "Project->Properties->Build->Arm Linker->Basic->Heap size" to 512.

    Besides getting rid of the warning, this will also allow more memory for the stack, just in case we're seeing a stack overflow (something which can have mysterious symptoms). This may or may not be the problem, but it's one thing fewer to worry about.

  • My (counter-)suggestion would be to remove the if() entirely from the NACK case. Among other things, this program isn't handling the states properly, which makes the if() vulnerable to stale state values.

  • Hello,

    I am using isolator IC ISO1514 with both side pullup added on I2C lines.

    I am using SDK example code "bq7690x_control_i2c" in that same code stuck in while loop for TX complete ( gI2cControllerStatus == I2C_STATUS_TX_INPROGRESS).

    I didn't receive any feedback on BMS-BGP E2E forum.

    Regards,

    Nitin

  • Hi Nitin,
    I can't seem to find any parts matching that isolator, can you share the datasheet for it? Also, I would recommend follow Bruce's advice and removing the if statement from the NACK interrupt so that it just changes the gI2cControllerStatus to error whenever it happens. Finally, before you remove the if statement, can you check what is the status of the gI2cControllerStatus whenever is stuck? Is it still I2C_STATUS_TX_INPROGRESS?

    Best Regards,

    Diego Abad

  • I am using isolator IC ISO1514 

    If this was intended to say ISO1541, I'll point out that that device doesn't permit Slave-side clock-stretching [Ref datasheet (SLLSEB6F) Sec 3], so the ISO1540 would be needed instead. (The BQ76905 overtly relies on clock-stretching.)

  • Hello,

    Sorry for spell mistake. The correct Isolator IC is ISO1541.

    regards,

    Nitin

  • Hello,

    Sorry for Spell mistake. The IC is ISO1541. 

    After removing if statement, gI2cControllerStatus is still I2C_STATUS_TX_INPROGRESS.

    regards,

    Nitin

  • Hello,

    After Bypassing Isolation IC i got,

    and Debug message as below,

    Cell1 Voltage Register = -300 mV
    Cell2 Voltage Register = 2530 mV
    Cell3 Voltage Register = 1 mV
    Cell4 Voltage Register = 3258 mV
    Cell5 Voltage Register = -483 mV
    Cell6 Voltage Register = 0 mV
    Cell7 Voltage Register = 0 mV
    Stack Voltage = 8078 mV
    REG18 Voltage = 1764 mV
    VSS Voltage = 0 mV
    CC2 Current = -18 mA
    CC1 Current = -23 mA
    Internal Temperature = 34 ºC

    Test Sequence with BQ7690x Completed.

    But I have 12V Li-Ion battery with 4 Cell which is connected to BQ76905 and actual Battery voltage is 13.16V

    Please tell me why this is getting like this?

    regards,

    Nitin

  • The isolator does appear to have been the (most recent) problem.

    The Cell4 voltage (3258 mV) is being reported properly based on what the device is saying (command 0x1A -> 0x0CB0), so I'm (back to) wondering about wiring. Do you have test points on VC1-5?

    More generally: I'm now way beyond my expertise; I have to defer to the Power Management people.

    This thread reports what seems to be a similar problem -- only Cell4 is reporting correctly. There's no Solution mentioned, but the TI person (Terry) offers some things to check for:

    https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1508090/bq76905-measured-voltage-error-on-the-first-3-cells-of-the-5-cell-series/5825307

  • Hi Nitin,
    Since the MSPM0 I2C part of things seems to be fine, I recommend creating a new E2E in the BMS-BGP E2E forum.

    Best Regards,

    Diego Abad