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.

TMS320f2808 I2C problem

Other Parts Discussed in Thread: SPRC191, TMS320F2808

Hi,

 

I'm having some problems with the I2C protocol on the tms320f2808. In fact i only want to write 4 bytes to a slave µC. I have been using the example   of sprc191, however the bit I2caRegs.I2CSTR.bit.BB  never goes to 0.

The init routine is like that:

void InitI2C(void)
{
   //I2caRegs.I2CMDR.all = 0x0000;
    // Initialize I2C
   I2caRegs.I2CSAR = 0x0002;        // Slave address - EEPROM control code
   I2caRegs.I2CPSC.all = 9;            // Prescaler - need 7-12 Mhz on module clk
   I2caRegs.I2CCLKL = 10;            // NOTE: must be non zero
   I2caRegs.I2CCLKH = 5;            // NOTE: must be non zero
   I2caRegs.I2CIER.all = 0x24;    //0x24    // Enable SCD & ARDY interrupts

   I2caRegs.I2CMDR.all = 0x0020;    // Take I2C out of reset
                                                               // Stop I2C when suspended
   I2caRegs.I2CMDR.bit.IRS = 1;
   I2caRegs.I2CFFTX.all =0x6000;    // Enable FIFO mode and TXFIFO
  // I2caRegs.I2CFFRX.all = 0x2040;    // Enable RXFIFO, clear RXFFINT,
   I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1;
   bufCheck[0]=251;
   bufCheck[1]=3;
   bufCheck[2]=0;
   bufCheck[3]=234;
}

And the write routine:

int Escribir_I2C(Uint16 Dir_I2C,unsigned char *buf,  Uint16 len)
{
 Uint16 i;
  while (I2caRegs.I2CMDR.bit.STP == 1); // Wait for Stop condition bit to be zero.
  while (I2caRegs.I2CSTR.bit.BB == 1);  // Wait for Bus Busy to be zero.

  // I2caRegs.I2CMDR.all = 0x0000;
   // Setup slave address
   I2caRegs.I2CSAR = Dir_I2C;
   // Setup number of bytes to send
   // MsgBuffer + Address
   I2caRegs.I2CCNT = len;
 
   for (i=0; i<4; i++)
   {
      I2caRegs.I2CDXR = buf[i];
     
   }
    
   I2caRegs.I2CMDR.all = 0x6E20;
   // Send start as master transmitter
 
   return 0;
}

If somebody have any ideas i will be gratefull. thx.

  • Hi, i have the same problem .

    Eduardo, did you find a solution?

    Thank you.

  • Hi,

    The cause of my problems with I2C was incorrect comm. timings with slave device. I'm using i2c eeprom (AT24c1024).

    When i write a byte i should account for 'write cycle time'. The time when eeprom is not ready for communication.

    So, pay attention to the slave device specifications.

     

  • Hello,

     

    how you account this "write cycle time"? you whait until your eeprom is ready or you use interrupts?

    what is your SCL frequency?

     

    thanks

  • According to at24c1024 datasheet, the eeprom chip pins are disabled during write cycle. Consequntly, there will be no ACK in that mode. 

    See AT24 datasheet paragraph which is named "write operations" (ACKNOWLEDGE POLLING).

    But i still have a problem with SCL, after second  write it becomes LOW and remains in that state.

    I can't understand why SCL remains low. AT24C1024 doesn't have clock stretching...

    I'll write more results a bit later.

     

    SCL=200KHz

  • I see by oscillograph that there is no ACK from AT24 at second write which is started just after first with no delay. It's OK, cause eeprom is busy. 

    But after no ACK SCL remains LOW. Is it ok?  

    I don't use interrupts. I'm planning to do write (fill FIFO, write 0x6e20 into I2CMDR) and than do polling while EEPROM will do ACK. This is a one write cycle.

    As i said i start TX by writing 0x6E20 into I2CMDR reg (TMS should generate STOP condition). 

    It seems to me that TMS doesn't set stop condition if no ACK from slave. Am i write? If this is ture, what should I do to reset SCL?

    Thank you

     

     

  • It seems to me that TMS doesn't set stop condition if no ACK from slave. Am i write? Yes if the dsp don't see an ACK, the interrupt falg NOACK is activated, and the stop bit is cleared and the dsp stop writing to the slave.

     

     

    If this is ture, what should I do to reset SCL?  u have to enabled the NOACK interruption or see the flag bit of NOACK  each time you write. If this bit becomes 1 u have to perform a reset of the I2C module. (desactivate and activate)...


    But the problem is, why the eeprom don't send to you the ACK?, that is the problem... it is not normal that the eeprom is always busy to respond to the I2C...

  • Eeprom doesn't send ACK only when it is busy (during write cycle). E.g. first byte write done according to specs ( with acknoledge for every byte ).

    At this moment i have a pair of functions

        i2c_write( unsigned long mem_offset, unsigned int byte ) ;

        i2c_wait();

     

    This code seems work ok:

     ....

    while(1) {

        i2c_write(0, 0xAA );

        DELAY_US( 10000 /*max write cycle time */ ); 

    // i2c_wait(); // the problem is how to make this function correctly

    }

     

    But i prefer 'wait' functions that poll some bit instead of dumb delay.

     

  • Eduardo Rondon said:

     u have to perform a reset of the I2C module. (desactivate and activate)...

    Is it according to TI docs? Looks like trick. I think that absence of ACK is not  smth. extraordinary, that need module reset.

    Imho, 'No ACK' situation should be handled like that. I send data, look at NACK bit. If that bit set i know that this is an error or slave is busy, Then i send STOP.

    Then try again several times. If attempts number exceeds some limit, this is an error.

    Is there any instructions how to handle this sistuation in TI docs? I can't find anything in I2C ref. guide.