I2C repeated start with TC387

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
ntimm
Level 1
Level 1
First like received 10 sign-ins 5 sign-ins

Hi,

 

i'm trying to communiacte with a PMBus device via I2C. For that I need to generate a repeated Start between the address write and consecutive read. I'm using a TC387 with ILLD 1.14 and the following code:

 

IfxI2c_I2c_Config config;
	IfxI2c_I2c_initConfig(&config, &MODULE_I2C0);

	const IfxI2c_Pins pins = { &IfxI2c0_SCL_P15_4_INOUT,
				   &IfxI2c0_SDA_P15_5_INOUT,
				   IfxPort_PadDriver_cmosAutomotiveSpeed1 };

	config.pins = &pins;
	config.baudrate = 400000;
	IfxI2c_I2c_initModule(&t->i2c, &config);
	IfxI2c_I2c_deviceConfig i2cDeviceConfig;
	IfxI2c_I2c_initDeviceConfig(
		&i2cDeviceConfig,
		&t->i2c); /* Device config for Bus of i2c handle */

	i2cDeviceConfig.deviceAddress = addr;
	i2cDeviceConfig.enableRepeatedStart=TRUE;
	IfxI2c_I2c_initDevice(&t->i2cDev, &i2cDeviceConfig);

if (IfxI2c_I2c_write(&t->i2cDev, data, 1) != IfxI2c_I2c_Status_ok) {		
		return FALSE;
	}
if (IfxI2c_I2c_read(&t->i2cDev, data, 1) != IfxI2c_I2c_Status_ok) {
		return FALSE;
	}

For non-PMBus devices this code works fine with enableRepeatedStart set to FALSE. When its set to TRUE the the program doesn't return from IfxI2c_I2c_write. It hangs in an endless loop at 

 if (!i2cDevice->enableRepeatedStart)
    {
        IfxI2c_releaseBus(i2c);
    }
    else
    {
        //wait until bus is free
        while (IfxI2c_getProtocolInterruptSourceStatus(i2c, IfxI2c_ProtocolInterruptSource_transmissionEnd) == FALSE)
        {}

        IfxI2c_clearProtocolInterruptSource(i2c, IfxI2c_ProtocolInterruptSource_transmissionEnd);
    }

waiting for the transmission end interrupt.

 

After the write the SDA line stays high while SCL stays low

ntimm_0-1674484859676.png

Any ideas?

 

Kind regards

0 Likes
8 Replies
Nambi
Moderator
Moderator
Moderator
500 replies posted 50 likes received 5 likes given

Hi,

Can you try initiating the subsequent write after the repeated start condition?

Best Regards.

0 Likes
ntimm
Level 1
Level 1
First like received 10 sign-ins 5 sign-ins

Hi,

IfxI2c_I2c_write doesn't return from the first write. It waits forever for the Transmission End Signal at

//wait until bus is free
        while (IfxI2c_getProtocolInterruptSourceStatus(i2c, IfxI2c_ProtocolInterruptSource_transmissionEnd) == FALSE)
        {}

When I forcefully skip this with the help of a debugger, I get a "Bus busy" error at the next write.

 

Kind regards

0 Likes
Mayur_Gaikwad
Level 1
Level 1
5 sign-ins First like given First question asked

Hi, 

I am also facing same problem for TC397. 

Please let me know if you got any solution. 

Thanks

 

0 Likes
MoD
Employee
Employee
50 likes received 500 replies posted 100 solutions authored

The problem here is the code:

    if (!i2cDevice->enableRepeatedStart)
    {
        IfxI2c_releaseBus(i2c);
    }
    else
    {
        //wait until bus is free
        while (IfxI2c_getProtocolInterruptSourceStatus(i2c, IfxI2c_ProtocolInterruptSource_transmissionEnd) == FALSE)
        {}

        IfxI2c_clearProtocolInterruptSource(i2c, IfxI2c_ProtocolInterruptSource_transmissionEnd);
    }

I don't know why the sw should wait here for TX_END. From my point of view it is wrong because the the TX_END flag is reset shortly before and there is no trigger which result in a new TX_END. 

Change the code to:

    if (!i2cDevice->enableRepeatedStart)
    {
        IfxI2c_releaseBus(i2c);
    }
    else
    {
    }

and test again.

ntimm
Level 1
Level 1
First like received 10 sign-ins 5 sign-ins

Hi,

unfortunately this doesn't fix the issue for me.

When I delete the 2 lines the subsequent call of IfxI2c_I2c_read fails with a "bus busy" error and he CLK line is held low.

 

// bus free?
    if (IfxI2c_busIsFree(i2c) == FALSE)
    {
        status                    = IfxI2c_I2c_Status_busNotFree;
        i2cDevice->i2c->busStatus = IfxI2c_getBusStatus(i2c);
        i2cDevice->i2c->status    = status;
        return status;
    }

 

This code returns with i2cDevice->i2c->busStatus == IfxI2c_BusStatus_busyMaster.

 

Anything I might need to do between the write and read?

 

Kind regards

 

MoD
Employee
Employee
50 likes received 500 replies posted 100 solutions authored

The problem is that the code is not really prepared to be use with repeated start as you can see where you hang. When you are in repeated start then the status of read and write must be IfxI2c_BusStatus_busyMaster but the function ask for bus free which is only correct when there is no repeated start. You should change the read/write function also that when it is in repeated start then the state should be free (for first call) or IfxI2c_BusStatus_busyMaster in subsequent calls.

0 Likes
Anand2603
Level 1
Level 1
5 sign-ins First reply posted First question asked

Hi

  I am also working on the SMBus, if you know how to make the Bus Ideal from software side during  very first Read Call ? Because as mentioned in User Manual the
clock SCL stays low as long as no further communication is requested after Repeated Start, so to bring the Bus Ideal, the SCL should be set to High as per my understanding. So is there any way from software side to bring the  SCL in to HIGH state to bring BUS in IDEAL state.

 

0 Likes
lock attach
Attachments are accessible only for community members.
VG
Level 1
Level 1
5 sign-ins First reply posted First like given

Hi,

Attached patch helps me.

Usage:
/* Write data to device */
IfxI2c_I2c_restart(&g_i2cDev);
while(IfxI2c_I2c_write(&g_i2cDev, &rxBuffer[0], 3) == IfxI2c_I2c_Status_nak);
/* Read the reg address */
while(IfxI2c_I2c_read(&g_i2c, &data[0], 2) == IfxI2c_I2c_Status_nak);

0 Likes