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.

I2C repeated start issue after receive

Other Parts Discussed in Thread: BQ27510

Dear All,

We have use the I2C for the fuel Guage IC of TI part no. BQ27510DRTZ,

Since the problem not occurred during the stellaris ware Controller but after the same code is being transformed to the TIVA C series Controller the same code is not being working properly,

After so much of my inspection, we came across the conclusion the I2C bus is not being working properly especially when the Write transfer is being done after the Read command.

Our code of action is as follows.

unsigned int BM_Checksum()
{
	unsigned int Checksum = 0, i;

	while(ROM_I2CMasterBusy(I2C2_BASE));
	ROM_I2CMasterSlaveAddrSet(I2C2_BASE, BATTERY_FUELGUAGE_ADDRESS, false);

	ROM_I2CMasterDataPut(I2C2_BASE,0x40);
	ROM_I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_START);

	ROM_I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
	while(ROM_I2CMasterBusy(I2C2_BASE));

	ROM_I2CMasterSlaveAddrSet(I2C2_BASE, BATTERY_FUELGUAGE_ADDRESS, true);
	ROM_I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);

	delay_mSec(1);

	for(i = 0; i< 32; i++)
	{
		check_sum_m[i] = ROM_I2CMasterDataGet(I2C2_BASE);
		Checksum += check_sum_m[i];
		ROM_I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
		while(ROM_I2CMasterBusy(I2C2_BASE));
	}
	ROM_I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
	while(ROM_I2CMasterBusy(I2C2_BASE));

	Checksum = Checksum & 0xFF;
	Checksum = 0xFF - Checksum;
	delay_mSec(1);

	return (unsigned int)Checksum;
}

So after find the Checksum of the fuel guage the Checksum is being calculated correctly by above sample of code but after that when we want to write the
Checksum to the address of fuel guage 0x60 in order to put it on the fuel guage IC.

Here is the code of action for the write of the checksum to the IC at address 0x60.
void BM_Write_Byte(unsigned char Command, unsigned char data)
{
	while(ROM_I2CMasterBusy(I2C2_BASE));
	ROM_I2CMasterSlaveAddrSet(I2C2_BASE, BATTERY_FUELGUAGE_ADDRESS, false);

	ROM_I2CMasterDataPut(I2C2_BASE, Command);
	ROM_I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_START);
	while(ROM_I2CMasterBusy(I2C2_BASE));

	ROM_I2CMasterDataPut(I2C2_BASE, data);
	ROM_I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
	while(ROM_I2CMasterBusy(I2C2_BASE));
}

Is this code of sample is correct???



  • Hello Smit,

    "After so much of my inspection, we came across the conclusion the I2C bus is not being working properly especially when the Write transfer is being done after the Read command."

    I do not get the issue. At one point you mention a Repeated Start issue as the forum post header and the you mention a write after read issue.

    Did you check the Application Note on I2C in TM4C documentation on www.ti.com?

    Regards
    Amit
  • Dear Amit,
    Is my above is good for to read Checksum of Battery gauge IC ?
  • It doesn't look like you're using "Repeated Start" here, which is good because I've found that BQ27510 doesn't support it very well.

    I'm not familiar with TivaWare so don't know if this is correct, but the various send and receive parts of your code are different. The write in BM_Write_Byte looks like this:

    ROM_I2CMasterDataPut // Set first byte
    I2C_MASTER_CMD_BURST_SEND_START // Start, then send first byte
    ROM_I2CMasterDataPut // Set second byte
    I2C_MASTER_CMD_BURST_SEND_FINISH // Send second byte, then finish

    Based on the TivaWare documentation I think that's correct. The command send in BM_Checksum looks like this:

    ROM_I2CMasterDataPut // Set first byte
    I2C_MASTER_CMD_BURST_SEND_START // Start, then send first byte
    I2C_MASTER_CMD_BURST_SEND_FINISH // Send second byte, then finish?

    I'm not sure but maybe that should just use I2C_MASTER_CMD_SINGLE_SEND instead of both I2C_MASTER_CMD_BURST_SEND_START and I2C_MASTER_CMD_BURST_SEND_FINISH.

    The receive part of BM_Checksum follows this pattern:

    I2C_MASTER_CMD_BURST_RECEIVE_START // Receive first byte
    ROM_I2CMasterDataGet // Read first byte
    I2C_MASTER_CMD_BURST_RECEIVE_CONT // Receive second byte
    [...]
    ROM_I2CMasterDataGet // Read 32nd byte
    I2C_MASTER_CMD_BURST_RECEIVE_CONT // Receive 33rd byte?
    I2C_MASTER_CMD_BURST_RECEIVE_FINISH // Receive 34th byte, then finish?

    I think there might be two extra I2C_MASTER_CMD_BURST_RECEIVE_CONT commands there because the I2C_MASTER_CMD_BURST_RECEIVE_START and I2C_MASTER_CMD_BURST_RECEIVE_FINISH also receive a byte each. That might put the I2C peripheral or the BQ27510 in a bad state that stops the write from working.

  • Thanks Robert ,
    i have seen in CRO that after receiving of the 32nd byte the write statement doesn't actually work so i have to put dummy byte to reset the I2C bus from being in correct state for Sending the Write Command.

    Is this method correct?
  • Hello Smit,

    Have you read the application note on I2C (I guess not) which shows how each of the main commands work?

    To have a repeated start, the FINISH command need not be there.

    ROM_I2CMasterDataPut(I2C2_BASE,0x40);
    ROM_I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    while(ROM_I2CMasterBusy(I2C2_BASE));

    ROM_I2CMasterSlaveAddrSet(I2C2_BASE, BATTERY_FUELGUAGE_ADDRESS, true);
    ROM_I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);


    Regards
    Amit
  • Hi Smit,

    I'm not sure. Can you post the code showing where you added the dummy byte?