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/TMS320F28379D: I2C don't transmite data in master mode (XRDY never is one)

Part Number: TMS320F28379D
Other Parts Discussed in Thread: LAUNCHXL-F28379D, TMP006, C2000WARE

Tool/software: Code Composer Studio

Hi dear Texas Instrument community

I have a problem to work with the LAUNCHXL-F28379D and the sensor TMP006, I tried to write a register but I only can put the adres in I2CSAR and the value of the pointer in I2CDXR (pointer or the register in TMP) that is the first data that i need transmit. I am using the temperature sensor(TMP006)  that I have in a  BOOSTERPACK MKII, I enable alll interruptions to check if I have a problem with the interruption, and I put a ESTOP0; in the code of the interruption but never I have a interruption. This is my code and thanks for your answers.

#include "F28x_Project.h"

/* Defines*/
#define TMP006_ADDR           0b1000000
#define TMP006_Vobj           0x00
#define TMP006_Tamb           0x01
#define TMP006_Conf           0x02
#define TMP006_Conf_Val       0b0111000010000000

/*Message struct*/
struct TMP006_msg16WT{
    Uint16 SlaveAddress;    //slave direction
    Uint16 Pointer;         //Number of bits
    Uint16 Msg;             //Message to send
};

struct TMP006_msg16WT conf_TMP006 = { TMP006_ADDR,          //
                                      TMP006_Conf,          //message for configure the function of the sensor
                                      TMP006_Conf_Val};     //
/*Variables*/
Uint16 RES;

/*Prototype functions*/
void   I2CB_Init(void);                             //Prototype function for init I2CB
void   TMP006_W_R(struct TMP006_msg16WT *msg);      //Prototype function for write register in objective (MASTER-TRANSMITER)
Uint16 TMP006_R_R(Uint16 ADDR, Uint16 Pointer);     //Prototype function for read register in objective (1.MASTER-TRANSMITER y 2.MASTER-RECIVER)
__interrupt void i2c_int1b_isr(void);               //Prototype function for interruption I2CB (ONLY A ESTO0; FOR BE SURE THAT A INTERRUP)


/**
 * main.c
 */
int main(void)
{
    InitSysCtrl();                                  //Init system
    InitGpio();                                     //Init GPIO

    EALLOW;                                         //This is needed to write to EALLOW protected registers
    DINT;                                           //Clear all __interrupts
    InitPieCtrl();                                  //Initialize PIE control registers (interrupts disabled and flags are cleared)
    IER = 0x0000;                                   //Disable CPU __interrupts
    IFR = 0x0000;                                   //clear all CPU __interrupt flags
    InitPieVectTable();                             //Initialize the PIE vector table
    PieVectTable.I2CB_INT = &i2c_int1b_isr;         //mapped I2CB_INT to direction of i2c_intb_isr
    IER |= M_INT8;                                  //Enable interruptions of the group 8 of the pie interrupt vectors
    EINT;                                           //Enable all interruptions
    PieCtrlRegs.PIEIER8.bit.INTx3 = 1;              //Enable interruption 3 of the group 8 that is I2CB interruption
    EDIS;                                           // This is needed to disable write to EALLOW protected registers



    I2CB_Init();                                    //Execute function for init I2CB
    DELAY_US(100);
    DELAY_US(100);
    TMP006_W_R(&conf_TMP006);                       //Execute function for WRITE A REGISTER in MASTER-TRANSMITER

    while(1){
        RES=TMP006_R_R(TMP006_ADDR, TMP006_Tamb);   //Execute function for READ A REGISTER in MASTER-RECIVER
    }

	//return 0;
}

//
//function for init I2CB
//
void   I2CB_Init(void){
    EALLOW;
    /*Configuracion de los pines*/
    GpioCtrlRegs.GPBQSEL1.bit.GPIO40 = 3;   // Asynch input GPIO40 (SDAB)
    GpioCtrlRegs.GPBQSEL1.bit.GPIO41 = 3;   // Asynch input GPIO41 (SCLB)
    GpioCtrlRegs.GPBPUD.bit.GPIO40 = 0;     // Enable pull-up for GPIO40 (SDAB)
    GpioCtrlRegs.GPBPUD.bit.GPIO41 = 0;     // Enable pull-up for GPIO41 (SCLB)
    GpioCtrlRegs.GPBMUX1.bit.GPIO40 = 1;    // Configure GPIO40 for SDAB
    GpioCtrlRegs.GPBMUX1.bit.GPIO41 = 1;    // Configure GPIO41 for SCLB

    /*Configure the clock of the I2CB*/
    I2cbRegs.I2CPSC.all = 16;
    I2cbRegs.I2CCLKL = 10;
    I2cbRegs.I2CCLKH = 5;

    I2cbRegs.I2CIER.all = 0x7F;             //Enable all interruptions

    I2cbRegs.I2CMDR.bit.IRS = 1;            //start I2CB module

    EDIS;
}

//
//function for write register in objective (MASTER-TRANSMITER)
//
void   TMP006_W_R(struct TMP006_msg16WT *msg){
    Uint16  MSB,LSB,tmp;

    LSB = msg->Msg & 0b0000000011111111;

    tmp = msg->Msg & 0b1111111100000000;
    tmp = tmp >> 8;
    MSB = tmp;

    I2cbRegs.I2CSAR.all = msg->SlaveAddress;            //Put the direction of the SLAVE in the I2CSAR
    I2cbRegs.I2CDXR.all = msg->Pointer;                 //put in the I2CDXR the pointer value (first data to transmit)
    I2cbRegs.I2CCNT = 3;                                //3 messages = 1 for pointer + 2 data

    while(I2cbRegs.I2CMDR.bit.STP == 1){}               //be sure that STP = 0
    while(I2cbRegs.I2CMDR.bit.STT == 1){}               //be sure that STT = 0
    while(I2cbRegs.I2CSTR.bit.BB == 1){}                //I2CB is't busy

    //Configure data transmit
    I2cbRegs.I2CMDR.all= 0x4620;                        //0100 0110 0010 0000   1->FREE, MST, TRX, IRS

    I2cbRegs.I2CMDR.bit.STT = 0x1;                      // Send START condition
    I2cbRegs.I2CMDR.bit.STP = 0x1;                      // STOP condition will be generated when I2CCNT is zero

    /****in this point the XRDY never is 1 to be sure that I can write a new message in I2CDXR***/
    while(!I2cbRegs.I2CSTR.bit.XRDY){}                  //wait to XRDY to put the second message
    /********************************************************************************************/

    I2cbRegs.I2CDXR.all = MSB;                          //Put the second message
    while(!I2cbRegs.I2CSTR.bit.XRDY){}                  //wait to XRDY to put the third message
    I2cbRegs.I2CDXR.all = LSB;                          //Put the third message
    while(!I2cbRegs.I2CSTR.bit.BB){}                    //Wait to finish the
}
//
//function for read register in objective (1.MASTER-TRANSMITER y 2.MASTER-RECIVER)
//
Uint16 TMP006_R_R(Uint16 ADDR, Uint16 Pointer){
    Uint16 MSB,LSB;

    I2cbRegs.I2CSAR.all = ADDR;                         //Put the direction of the SLAVE in the I2CSAR
    I2cbRegs.I2CDXR.all = Pointer;                      //put in the I2CDXR the pointer value (first data to transmit)
    I2cbRegs.I2CCNT = 3;                                //3 messages = 1 for pointer(trnasmit) + 2 data(recive)
    while(I2cbRegs.I2CSTR.bit.BB == 1);                 //I2CB is't busy


    //Configure data transmit
    I2cbRegs.I2CMDR.all= 0x6E20;                        //0110 1110 0010 0000   1->FREE, STT, MST, TRX, IRS, STP

    while(I2cbRegs.I2CSTR.bit.XRDY==0);

    //Configure data recive
    I2cbRegs.I2CMDR.all= 0x6420;                        //0110 0100 0010 0000   1->FREE, STT, MST, IRS || 0->STP, TRX

    while(I2cbRegs.I2CSTR.bit.RRDY==0);
    MSB=I2cbRegs.I2CDRR.all;
    while(I2cbRegs.I2CSTR.bit.RRDY==0);
    LSB=I2cbRegs.I2CDRR.all;
    MSB=MSB << 8;
    MSB=MSB&LSB;
    return MSB;
}
//
//function for interruption I2CB (ONLY A ESTO0; FOR BE SURE THAT A INTERRUP)
//
__interrupt void i2c_int1b_isr(void){
    ESTOP0;
}

  • Hi,

    Thanks for the code snippet. 

    Are you doing this based on some existing example of C2000Ware? 

    Where does the code get stuck at when you try to run this code?

    Regards,

    Sudharsanan

  • Hi

    First thanks for your quick answer, I don't use the C2000Ware example, because the C2000Ware use a FIFO buffer, and my code don't use a buffer (I try to change the value of the register I2CDXR manualy). I based my code in the answer that resolve the thread in this link

     https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/773846

    Mi code is stuck in the line 116 

    while(!I2cbRegs.I2CSTR.bit.XRDY){}

    I try  to chek that the value in the I2CDXR register is passed to the shift register to send data I2CXSR, and I try to do it cheking the state of the variable XRDY in the register I2CSTR.

    Maybe is a problem in the configurations of the pins, I don't know

  • Hi Yedison,

    Sorry for the wait.

    can you probe the bus to see if the slave address gets transmitted OK? Are there pull-up resistors on the I2C lines? If so it may be good to disable the internal pull-up on the GPIOs, setting below to 1:

        GpioCtrlRegs.GPBPUD.bit.GPIO40 = 0;     // Enable pull-up for GPIO40 (SDAB)
        GpioCtrlRegs.GPBPUD.bit.GPIO41 = 0;     // Enable pull-up for GPIO41 (SCLB)
    

    Maybe try filling the I2CDXR register after line 116 like below:

        I2cbRegs.I2CMDR.bit.STT = 0x1;                      // Send START condition
        I2cbRegs.I2CMDR.bit.STP = 0x1;                      // STOP condition will be generated when I2CCNT is zero
        /****in this point the XRDY never is 1 to be sure that I can write a new message in I2CDXR***/
        while(!I2cbRegs.I2CSTR.bit.XRDY){}                  //wait to XRDY to put the second message
        /********************************************************************************************/
    I2cbRegs.I2CDXR.all = msg->Pointer;                 //put in the I2CDXR the pointer value (first data to
    while(!I2cbRegs.I2CSTR.bit.XRDY){}                  //wait to XRDY to put the second message
        I2cbRegs.I2CDXR.all = MSB;                          //Put the second message
        while(!I2cbRegs.I2CSTR.bit.XRDY){}                  //wait to XRDY to put the third message
        I2cbRegs.I2CDXR.all = LSB;                          //Put the third message
        while(!I2cbRegs.I2CSTR.bit.BB){}                    //Wait to finish the

    Best,

    Kevin