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.

TMS320F28052F: I2C slave

Part Number: TMS320F28052F

Hi all,

i'm having an issue to make a TMS320f28052f work as an i2C slave.

When i'm doing a i2C write operation, the slave receive well (ACK on SDA and data is transmitted on the SDA line)

But when a i2C read operation is carried on, the slave do an ACK on SDA but never send the actual data. But I2C_TX_ISRC interrupt is triggered on the slave.

Trace of i2C read operation on device address 5 :  

The init function is : 

        i2cHandle->I2CMDR.bit.IRS = 0;

        // Initialize I2C
	i2cHandle->I2COAR = i2C_own_adress;
	i2cHandle->I2CSAR = 0x0000;

        // i2c clock speed 100000 hz
	i2cHandle->I2CPSC.all = 6;		// Prescaler - need 7-12 Mhz on module clk
	i2cHandle->I2CCLKL = 10;		// NOTE: must be non zero
	i2cHandle->I2CCLKH = 5;			// NOTE: must be non zero
	i2cHandle->I2CIER.all = 0x00;		// Enable __interrupts
	i2cHandle->I2CIER.bit.RRDY = 1;
	i2cHandle->I2CIER.bit.AAS = 1;
	i2cHandle->I2CIER.bit.XRDY = 1;
	i2cHandle->I2CIER.bit.ARDY = 1;
	i2cHandle->I2CIER.bit.NACK = 1;
	i2cHandle->I2CIER.bit.SCD = 1;
	i2cHandle->I2CEMDR.bit.BCM = 0;
	i2cHandle->I2CMDR.all = 0x0020;

In the ISR, i have the following code :

if(i2cObj->I2CISRC.all & I2C_TX_ISRC == I2C_TX_ISRC)
{
  // Setup number of bytes to send
  i2cObj->I2CCNT = 1;

  // Setup data to send
  i2cObj->I2CDXR = data;
}

Found a similar post at (https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/426586#pi316717=1

Can anyone give me hints ?

Thanks

  • I might have solved my problem by doing so in the ISR :

     uint16_t source = (uint16_t)halHandle->i2cAHandle->I2CISRC.all;
    
    	if(source == 5)
    	{
     	        // Setup number of bytes to send
    		halHandle->i2cAHandle->I2CCNT = 1;
    
    		// Setup data to send
    		halHandle->i2cAHandle->I2CDXR = 0x0054;
    	}

    In my case, the I2C_TX_ISRC triggered the Interruption but it seems that I2C_AAS_ISRC was then set in halHandle->i2cAHandle->I2CISRC.all

    now i have the correct behavior :

    Can someone explained me how is that possible ?

  • First off, you don't need to set I2CCNT. The slave has no control over how much data is transferred.

    Your code has a bug:

    if (i2cObj->I2CISRC.all & I2C_TX_ISRC == I2C_TX_ISRC)

    C's order of operations puts == ahead of &. (& and && have the same precedence.) You need to put parentheses around a bitwise AND operation. Also, that bit mask will match the AAS interrupt as well as the TX interrupt. You can just compare the INTCODE field with the TX value directly. The correct code looks like this:

    if (i2cObj->I2CISRC.bit.INTCODE == I2C_TX_ISRC)

  • Thanks;

    Now working like a charm.