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 on TMS320F28335 without interrupt is not working with FM24C04

Other Parts Discussed in Thread: TMS320F28335

Hi,

to all,

I am trying to interface with EEPROM on TMS320F28335 without interrupt,

I think i am able to write EEPROM as i get XRDY clear while Writting to the data and uo to end of data transmission

but while Read EEPROM RRDY bit of status Register is not getting clear. my EEPROM is having only 1 byte address.

up to Adress field for read I am able to complete for read.

 

Here is my code can anyone help me???

 

 

void I2CA_Init(void)

{

   // Initialize I2C

   I2caRegs.I2CSAR = 0x0050; // Slave address - EEPROM control code

 

   #if (CPU_FRQ_150MHZ)             // Default - For 150MHz SYSCLKOUT

        I2caRegs.I2CPSC.all = 14;   // Prescaler - need 7-12 Mhz on module clk (150/15 = 10MHz)

   #endif

   #if (CPU_FRQ_100MHZ)             // For 100 MHz SYSCLKOUT

    I2caRegs.I2CPSC.all = 9;    // Prescaler - need 7-12 Mhz on module clk (100/10 = 10MHz)

   #endif

 

   I2caRegs.I2CCLKL = 10; // NOTE: must be non zero

   I2caRegs.I2CCLKH = 5; // NOTE: must be non zero

   //I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY interrupts

   I2caRegs.I2CIER.all = 0; // Disable SCD & ARDY interrupts

   I2caRegs.I2CMDR.all = 0x0C20; // Take I2C out of reset

   // Stop I2C when suspended

   I2caRegs.I2CFFTX.bit.I2CFFEN = 0;// Disable FIFO mode

//   I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO

//   I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,

   return;

Uint16 I2CA_WriteData(Uint16 tx_adress, Uint16 *tx_data, Uint16 NumOfBytes)

{

char i;

    while(I2caRegs.I2CSTR.bit.BB  !=  0) ;

// I2caRegs.I2CMDR.all = 0;

    I2caRegs.I2CSAR = I2C_SLAVE_ADDR;

I2caRegs.I2CCNT = NumOfBytes+1;

I2caRegs.I2CMDR.bit.TRX = 1;

I2caRegs.I2CMDR.bit.STT = 1;

//    I2caRegs.I2CMDR.all = 0x6E20;

if(I2caRegs.I2CSTR.bit.XRDY | I2caRegs.I2CSTR.bit.ARDY)

{

I2caRegs.I2CDXR = tx_adress;

for (i=0; i<NumOfBytes; i++)

{

if(I2caRegs.I2CSTR.bit.NACK)

{

return 3;

}

if(I2caRegs.I2CSTR.bit.XRDY | I2caRegs.I2CSTR.bit.ARDY)

{

       I2caRegs.I2CDXR = *tx_data;

tx_data++;

   }

else

return 2;

}

}

else

return 1;

 

I2caRegs.I2CMDR.bit.STP = 1;

return 0;

}

 

Uint16 I2CA_ReadData(Uint16 rx_adress, Uint16 *rx_data, Uint16 NumOfBytes)

{

char i;

while(I2caRegs.I2CSTR.bit.BB  !=  0) ;

// I2caRegs.I2CMDR.all = 0;

    I2caRegs.I2CSAR = I2C_SLAVE_ADDR;

I2caRegs.I2CCNT = 1;

// I2caRegs.I2CMDR.all = 0x6E20;

// I2caRegs.I2CMDR.all = 0x2620;

I2caRegs.I2CMDR.bit.TRX = 1;

// I2caRegs.I2CMDR.bit.IRS = 1;

I2caRegs.I2CMDR.bit.STT = 1;

//while(I2caRegs.I2CSTR.bit.BB  !=  0) ;

if(I2caRegs.I2CSTR.bit.XRDY | I2caRegs.I2CSTR.bit.ARDY)

{

I2caRegs.I2CDXR = rx_adress;

if(I2caRegs.I2CSTR.bit.XRDY | I2caRegs.I2CSTR.bit.ARDY)

{

// I2caRegs.I2CMDR.all = 0;

I2caRegs.I2CSAR = I2C_SLAVE_ADDR;

I2caRegs.I2CCNT = NumOfBytes;

I2caRegs.I2CMDR.bit.STP = 1;

I2caRegs.I2CMDR.bit.TRX = 0;

//while(I2caRegs.I2CSTR.bit.BB  !=  0) ;

I2caRegs.I2CMDR.bit.IRS = 1;

// I2caRegs.I2CMDR.bit.STT = 1;

// I2caRegs.I2CMDR.all = 0x2C20; // Send restart as master receiver

for (i=0; i<NumOfBytes; i++)

{

if(I2caRegs.I2CSTR.bit.RRDY | I2caRegs.I2CSTR.bit.ARDY)

{

*rx_data = I2caRegs.I2CDRR;

rx_data++;

  }

else

return 4;

}

}

else

return 2;

}

else

return 1;

return 0;

}Regards,

Chintan

 

 

  • Chintan,

    your code snippet is a little bit confusing.  Where does you initialization function end? Is it after the first "return"?

    Next,  in your write function you use a for-loop to write a set of tx_data into the I2C. What I don't see is a wait loop to wait for the end of the first data been written into the device. If you do not use the FIFO's (as in your code snippet) and no Interrupts (btw, why not?) then you have to wait for the acknowledgement of a previous I2C-Sequence before you write a new data int txbuf.  A "return" instruction to leave the for-loop (and the function) in case of a NACK is (a) unstructured code and (b) must be dealed with by the parent function. In the latter, how do you resume the inner for-loop of your write function  So I doubt a little bit that even your write command is properly received by the EEPROM (btw, the FM24C04 it is a ferromagnetic memory , which makes a big difference to an EEPROM).

    Did you measure the I2C-Signals during the execution of your write function with a scope or logic analyzer? If not, I'd do this first to verify that the write function has been executed properly.

    Hope this helps.

    Regards

     

     

      

     

     

     

  • hi Frank,

    Thanks for Reply,

    you are right i am not able to even write a byte i have checked that thing in my write routine by removing XRDY bit and in place of that I am polling ARDY bit from status because XRDY bit have initial value is 1. 

    In my case after initialization I am checking BB bit for Bus busy detect but than also while writing data i am not able to write a EEPROM address byte so can you check my init I2C and Write EEPROM

    void I2CA_Init(void)

    {

       // Initialize I2C

       I2caRegs.I2CSAR = 0x0050; // Slave address - EEPROM control code

       #if (CPU_FRQ_150MHZ)             // Default - For 150MHz SYSCLKOUT

            I2caRegs.I2CPSC.all = 14;   // Prescaler - need 7-12 Mhz on module clk (150/15 = 10MHz)

       #endif

       #if (CPU_FRQ_100MHZ)             // For 100 MHz SYSCLKOUT

         I2caRegs.I2CPSC.all = 9;    // Prescaler - need 7-12 Mhz on module clk (100/10 = 10MHz)

       #endif

       I2caRegs.I2CCLKL = 10; // NOTE: must be non zero

       I2caRegs.I2CCLKH = 5; // NOTE: must be non zero

       //I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY interrupts

       I2caRegs.I2CIER.all = 0; // Disable SCD & ARDY interrupts

       // Stop I2C when suspended

     

       I2caRegs.I2CFFTX.bit.I2CFFEN = 0;// Disable FIFO mode

       I2caRegs.I2CMDR.all = 0x0C20; // Take I2C out of reset

       while(I2caRegs.I2CSTR.bit.BB) ;

       return;

    }

     

    Uint16 I2CA_WriteData(Uint16 tx_adress, Uint16 *tx_data, Uint16 NumOfBytes)

    {

    char i;

    while(I2caRegs.I2CSTR.bit.BB) ;

    I2caRegs.I2CMDR.all = 0;

    I2caRegs.I2CSAR = I2C_SLAVE_ADDR;

    I2caRegs.I2CCNT = NumOfBytes+1;

    I2caRegs.I2CMDR.all = 0x2E20;

    while(I2caRegs.I2CSTR.bit.NACK);

    if(I2caRegs.I2CSTR.bit.ARDY)// | I2caRegs.I2CSTR.bit.XRDY)

    {

      I2caRegs.I2CDXR = tx_adress;

      while(I2caRegs.I2CSTR.bit.NACK);

      for (i=0; i<NumOfBytes; i++)

      {

         if(I2caRegs.I2CSTR.bit.ARDY)// | I2caRegs.I2CSTR.bit.XRDY)

         {

           I2caRegs.I2CDXR = *tx_data;

           while(I2caRegs.I2CSTR.bit.NACK);

           tx_data++;

         }

         else return 2;

      }

    }

    else return 1;

    I2caRegs.I2CMDR.bit.STP = 1;

    return 0;

    }