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.

BQ78350: SMBus proplem

Part Number: BQ78350
Other Parts Discussed in Thread: BQSTUDIO

 Hello;

I'm having problems communicating with the fuel gauge...the problem is as follows:

First, I can send the reset command with no apparent complaint - it properly ACK's the I2C transaction.

BUT, when trying to do a block read from the DF, I first send the command and address, but the 350 does not ACK the last byte. Then, if I ignore this and send the repeated start to do the read anyway, the 350 returns the LSB of the address, but then all zeros ??????????

I'm "guessing" this is a result of the NACK error, but I don't know.

Any help would be appreciated...

    Here's what's happening

Block[0]    =    BQ78350_MANUFACT_BLK_ACCESS; <-- = 0x44

Block[1]    =    (uint8_t)0xCC;

Block[2]    =    (uint8_t)0x44;

   

OK    =    HAL_I2C_Master_Seq_Transmit_DMA(pI2cHandle,
                                                  BQ78350_ADDRESS,
                                                  Block,
                                                  3,
                                                  I2C_FIRST_FRAME);

  ....I get a NACK error here????

but I ignore it and send the repeated start to read...
   
    if (Dir == READ)
    {
         OK    =    HAL_I2C_Master_Seq_Receive_DMA(pI2cHandle,
                                               BQ78350_ADDRESS,
                                               pBuf,
                                               numBytes,
                                               I2C_LAST_FRAME);


And this is what's returned?: Buf[0xCC, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,...]

  • Hi Jeffrey,

    I gave this a quick try using BQStudio and the EVM and I am able to read this location okay. Here is the screen shot below from BQStudio. I will send you the scope shots by email, though they are a little hard to read due to resolution.

  • Hi Jeffrey,

    I am closing this thread since we've figured this out through email. I think you are correct that the documentation should be more clear and I will enhance this in the next revision of the TRM. As you pointed out, the TRM needs correcting in this section, since it says that the first bytes returned are the address bytes, but  the device returns a byte count first (SMBus spec), followed by the DF address and data.

    Linking the older thread with a decent logic analyzer image example: https://e2e.ti.com/support/power-management/f/196/t/656336

    And your updated code:

        Block.Cmd        =    BQ78350_MANUFACT_BLK_ACCESS;
        Block.ByteCount    =    (uint8_t)2;
        Block.Addr        =    addr;   
       
    /*
    *    First, write command, byte count, and address.
    */   
        OK    =    HAL_I2C_Mem_Write_DMA(pI2cHandle,
                                        BQ78350_ADDRESS,
                                        Block.Cmd,
                                        I2C_MEMADD_SIZE_8BIT,
                                        (uint8_t *)&Block.ByteCount,
                                        (uint8_t)3); 
       
        while (HAL_I2C_GetState(pI2cHandle) != HAL_I2C_STATE_READY)
         {
        }
    /*
    *    Next, use the sequential API to send the address and write the command, and then
    *    send a restart if a read the register.
    */   

        OK    =    HAL_I2C_Master_Seq_Transmit_DMA(pI2cHandle,
                                                BQ78350_ADDRESS,
                                                (uint8_t *)&Block.Cmd,
                                                1,
                                                I2C_FIRST_FRAME);   
       
        while (HAL_I2C_GetState(pI2cHandle) != HAL_I2C_STATE_READY)
         {
        }

    /*
    *    Finally, use the sequential read API to the register.
    */
        if (Dir == READ)
        {
            OK    =    HAL_I2C_Master_Seq_Receive_DMA(pI2cHandle,
                                                BQ78350_ADDRESS,
                                                pBuf,
                                                numBytes,
                                                I2C_LAST_FRAME);   
        }
        else
        {
            OK    =    HAL_I2C_Master_Seq_Transmit_DMA(pI2cHandle,
                                                      BQ78350_ADDRESS,
                                                      pBuf,
                                                      numBytes,
                                                    I2C_LAST_FRAME);   
        }                                                             
    /*
    *    The complete flag is set in the callback
    */
        WaitForI2C();
    /*
    *    Release access semaphore
    */

        OSPostSem(I2C_AccessSemaphore);

    Best regards,

    Matt