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.

CCS/TMS320F28377S: I2C was not working

Part Number: TMS320F28377S

Tool/software: Code Composer Studio

Dear Sir,

I am trying to use I2C on tms320f28377s, GPIO91 and GPIO92 (I2C A). But this is not working. This is my code. There is no clock or output on this pin.So please help me to find out what is wrong.

/*   Initialisation , i take this  form example code given  in control suit */

void I2CA_Init(void)
{
GpioCtrlRegs.GPCMUX2.bit.GPIO91=6;
GpioCtrlRegs.GPCMUX2.bit.GPIO92=6;

//GPIO_SetupPinMux(91, GPIO_MUX_CPU2,6);
//GPIO_SetupPinMux(92, GPIO_MUX_CPU2,6);

I2caRegs.I2CSAR.all = 0x00A0; // Slave address - EEPROM in write mode

I2caRegs.I2CPSC.all = 6; // 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; // Enable SCD & ARDY __interrupts

I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
// Stop I2C when suspended

I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,

return;
}

void I2CA_WriteData(void)
{
unsigned char i;

//
// Wait until the STP bit is cleared from any previous master communication.
// Clearing of this bit by the module is delayed until after the SCD bit is
// set. If this bit is not checked prior to initiating a new message, the
// I2C could get confused.
//

check1:

if(I2caRegs.I2CMDR.bit.STP == 1)
{
goto check1;
// return I2C_STP_NOT_READY_ERROR;
}

//
// Setup slave address
//
I2caRegs.I2CSAR.all = 0XA0;    //eeprom address.   

//
// Check if bus busy
//

if(I2caRegs.I2CSTR.bit.BB == 1)
{
//return I2C_BUS_BUSY_ERROR;
goto check1;
}

//
// Setup number of bytes to send
// MsgBuffer + Address
//
I2caRegs.I2CCNT = 2;

//
// Setup data to send
//
// I2caRegs.I2CDXR.all = 0X00;
I2caRegs.I2CDXR.all = 0XAA;

//
// Send start as master transmitter
//
I2caRegs.I2CMDR.all = 0x6E20;

return ;
}

  • Hello,
    I am writing to let you know that a C2000 team member has been assigned to this post and should be answering shortly.

    Regards
    Baskaran
  • You need to have EALLOW before mux configuration.

    EALLOW;
    GpioCtrlRegs.GPCMUX2.bit.GPIO91=6;
    GpioCtrlRegs.GPCMUX2.bit.GPIO92=6;
    EDIS;

    Vivek Singh
  • Thanks,

    Now at least I am able to generate some data. But I want to write my own lib. I want to write address and data separately on I2C bus and there are two separate register for writing data and address. So i write following functions and they are not working properly. So please can you tell how to write general function of read,write ,stop, start and ack. I have to interface eeprom, RTC, ADC on I2C . I wrote following function

    /****************************************Write Address**************************************************************************/

    void write_address(unsigned char address)
    {
    if(I2caRegs.I2CMDR.bit.STP == 1) //wait for i2c bus to end any prrevious communication
    {
    us(500);
    }

    I2caRegs.I2CCNT =1; //no of byte to send on i2c address+data
    I2caRegs.I2CSAR.all = address; // Slave address - EEPROM in write mode

    if(I2caRegs.I2CSTR.bit.BB == 1); //wait for to bus free
    {
    us(500);
    }

    I2caRegs.I2CMDR.all = 0x6E20;

    return;
    }

    /*************************************Write Data**************************************************************************/

    void write_data(unsigned char data)
    {
    if(I2caRegs.I2CMDR.bit.STP == 1) //wait for i2c bus to end any prrevious communication
    {
    us(500);
    }
    I2caRegs.I2CCNT =1;
    I2caRegs.I2CDXR.all =data; //write data is to be put

    if(I2caRegs.I2CSTR.bit.BB == 1); //wait for to bus free
    {
    us(500);
    }

    I2caRegs.I2CMDR.all = 0x6E20;

    return;
    }

    /******************************************Start Condition*************************************************************************/


    void start_condition(void)
    {
    I2caRegs.I2CMDR.bit.STT=1; //send start condition

    if(I2caRegs.I2CSTR.bit.BB == 1); //wait for to bus free
    {
    ms(10);
    }

    return;
    }

    /******************************************Stop Condition*************************************************************************/

    void stop_condition(void)
    {
    I2caRegs.I2CMDR.bit.STP=1; //send stop condition

    if(I2caRegs.I2CSTR.bit.BB == 1); //wait for to bus free
    {
    ms(10);
    }

    return;
    }

    /***********************************************Nack Condition ***************************************************************/

    void nack_condition(void)
    {
    I2caRegs.I2CMDR.bit.NACKMOD=1; //Send nack bit

    if(I2caRegs.I2CSTR.bit.BB == 1); //wait for to bus free
    {
    ms(10);
    }
    }

    /*************************************************************************************************************************/
  • Good. We'll have our I2C expert look into your query.
  • Can you explain in a bit more detail what you mean by "not working properly"? In what way are they failing?

    I don't think our hardware supports sending the address separately using the SAR register, but I did find this forum post where someone used FDF and sent the address as if it were a data byte. Will that fit your requirement?

    e2e.ti.com/.../1720695

    Whitney
  • Just I want to know what are register to send stop,start, NACK, Address and data. SO I can develop my own lib. Above code are not working properly .
  • This is the program calling above function. And I want to run this using I2C peripheral.

    void EEPROM_WriteByte(unsigned char eeprom_Address, unsigned char eeprom_Data, unsigned char Page_Number)
    {
    I2C_Start(); // Start i2c communication
    write_address(EEPROM_ID|(Page_Number<<1)); // connect to AT2404 by sending its ID on I2c Bus
    write_data(eeprom_Address); // Select the Specified EEPROM address of AT2404
    write_data(eeprom_Data); // Write the data at specified address
    I2C_Stop(); // Stop i2c communication after Writing the data
    ms(5); // Write operation takes max 5ms, refer At2404 datasheet
    }

    unsigned char EEPROM_ReadByte(unsigned char eeprom_Address,unsigned char Page_Number)
    {
    unsigned char eeprom_Data;

    I2C_Start(); // Start i2c communication
    write_address(EEPROM_ID|(Page_Number<<1)); // connect to AT2404(write) by sending its ID on I2c Bus
    write_data(eeprom_Address); // Select the Specified EEPROM address of AT2404
    I2C_Start(); // Start i2c communication
    write_address(0xA1|(Page_Number<<1)); // connect to AT2404(read) by sending its ID on I2c Bus
    eeprom_Data = I2C_Read(); // Read the data from specified address
    I2C_NoAck();
    I2C_Stop(); // Stop i2c communication after Reading the data
    us(10);
    return eeprom_Data; // Return the Read data

    }
  • Have you checked out our i2c_eeprom example project?

    I suspect what's happening in EEPROM_WriteByte() is that your EEPROM isn't expecting the STOP condition until after both the word address and the data have been sent, but your write_data() function is asserting the STOP condition after only one byte (which in your case is the word address).

    Please read up on the conditions that cause a stop condition to be set in the I2C chapter of the TRM.

    http://www.ti.com/litv/pdf/spruhx5d

    Whitney

  • Sir ,

    I already read the given link and example and I take the reference of both of them to write above function. And I think when we load I2C control register "I2caRegs.I2CMDR.all = 0x6E20" then start and stop condition are automatically generated??

    I want to know what is function of "I2caRegs.I2CCNT" register. I load 1 if only address is send, I s this is correct?

    I2caRegs.I2CCNT =1; //no of byte to send on i2c address

    If I want to send address + data then I2caRegs.I2CCNT =2 is correct ??

    One more think when I am interfacing with eeprom then I have to first send EEPROM addrress+Page_Num, this is not problem but when I sending memory location then which register is used ??

    Only due to this I write two function for writing address and other for writing data. This is correct???

    When I reading data form eeprom then I face same problem. Please tell what is sequence to read data form eeprom or any other devise.

    Thankyou
  • If I understand your EEPROM correctly, I believe you will want to set I2CCNT to 2. The slave address that you put in I2CSAR will be sent when you set the STT bit and does not count toward the I2CCNT value. The memory address and data are the 2 bytes that effect the count. Once those two bytes are sent, the stop condition will automatically be generated and the hardware will clear the I2CMDR.STP bit to let you know that it has been sent.

    Whitney