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.

Trouble with simple I2C MasterTx between two C2000 boards

Hello,

I am trying to set up an I2C communication between two F28069M Dev boards. The plan is to later expand the bus to include 5 slaves and one master, each one a F28069M.

For now, I am starting with what (i think) should be a simple Master Transmit mode without interupts. I've spent the past week trying to get it working but now I am stuck.
I am currently using CCS's built in debug probe and a Logic Analyser to probe the bus.

As you can see in the screencap below, the master initiates a transmit to the slave (0x003) however the slave never acknowledges the transfer and the SCL line is then pulled low indefinitely.

I also think it might be possible there is a problem on the slave's end if it is not replying back. I have also attached a stripped down version of the code I am running.

#define Master
#define slave
#define Master_Adr 0x0002
#deifne Slave_Adr 0x0003;

int main(void)
{
InitSysCtrl();
InitGpio();
I2cInit();

#ifdef Master
while (1) //loop to send data over. data sent over will increment by one after each successful transmision
{
if(I2cMstTx(sdata,Slave_Adr))
{
GpioDataRegs.GPBDAT.bit.GPIO34 ^= 1; //toggle LED on each transfer
sdata++;
}
DELAY_US(100000); // Wait a bit to make the numbers change at a human speed
}
#endif

#ifdef Slave
I2caRegs.I2CMDR.all = 0x0020;
while(1) //poll the data comming in and show. toggle LED state on every increment
{
rdata = I2cReceive();
GpioDataRegs.GPBDAT.bit.GPIO39 = rdata%2;
DELAY_US(2000);
}
#endif
}//end main

void I2cInit(void)
{
I2caRegs.I2CMDR.bit.IRS = 0;

#ifdef Master
I2caRegs.I2COAR = Master_Adr;
#else Slave
I2caRegs.I2COAR = Slave_Adr;

I2caRegs.I2CPSC.all = 8;
I2caRegs.I2CCLKL = 10;
I2caRegs.I2CCLKH = 5;
I2caRegs.I2CFFTX.bit.I2CFFEN = 0;
I2caRegs.I2CIER.all = 0x0000;
}//end I2cInit

char I2cMstTx(char message, char I2CAddress)
{
if (I2caRegs.I2CSTR.bit.BB == 1||I2caRegs.I2CMDR.bit.STP == 1) // check busy bit and stop condition
{
return 0;// return false if the I2C module is still occupied with the last transmission
}

I2caRegs.I2CSAR = (Uint16)I2CAddress;//set receiving slave address
I2caRegs.I2CDXR = (Uint16)*message;// Data to be sent
I2caRegs.I2CCNT = sizeof(*message)+1; // Transmit count (1 = 1 word)

I2caRegs.I2CMDR.all = 0x2E20; //set MDR
return 1;
} // end of I2cMstTx()

Any help would be greatly appreciated; every example seems to do it a little differently.
Regards,

John

  • John,

    The I2C clock is held low when the slave doesn't have room to receive the data. There are a couple things that might be wrong:

    1. Your delay before reading could be too long. Instead of waiting for 2000 us, try waiting for I2CSTR.RRDY to go high.

    2. Your comments suggest you're trying to send one byte when you write to I2CCNT, but sizeof(char) + 1 is 3, not 1.

    Without seeing your receive code, it's hard to say more.

  • Hey Adam,

    Thanks for the reply. I tried all the things that you suggested; I removed the delays and put in a while wait as well as fixed the issue with the data counter being too large.

    It seems to have made a slight improvement. The SCL line is no longer locked low when I run, however I am still receiving NACK's every transfer attempt. I have included a screencap of the current state of the transfer, but really it appears to be the same thing but repeated.

    You mentioned not having the receive code; here its, everything that runs on the slave board:

    int rdata = 0;

    int main(void)
    {
    InitSysCtrl();
    InitGpio();
    I2cInit();

    while(1)
    {
    while (!I2caRegs.I2CSTR.bit.RRDY);
    rdata = I2caRegs.I2CDRR;
    }//end whileLoop
    }//end main

    void I2cInit(void)
    {
    I2caRegs.I2CMDR.bit.IRS = 0;
    I2caRegs.I2COAR = Slave_Adr;
    I2caRegs.I2CPSC.all = 8; /
    I2caRegs.I2CCLKL = 10;
    I2caRegs.I2CCLKH = 5;
    I2caRegs.I2CFFTX.bit.I2CFFEN = 0;
    I2caRegs.I2CIER.all = 0x0000;
    I2caRegs.I2CMDR.all = 0b0000000000100000;
    }//end I2cInit

    I feel like something is missing here, but i don't know what.

    Thank you once again,

    John

  • Nvm Adam,
    The real issue was with my defines. I tried to do something fancy and assumed it would work. The problem was with the slave, it wasnt actualy being initialised as a slave.

    Thank you for all your help

    John