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 communication with TMS320F28xx

Other Parts Discussed in Thread: CONTROLSUITE

Hi everyone, I am trying to establish communication wbetween my uC and MCP4017 (Potentiometer). My first attempt is to send "Read" request to the chip and to get a response. I have put some breakpoints inside my interrupt function to determine whether the chip is sending any response or not, be know if my request structure is correct. Here some lines code,


// I2C initialization
void I2CA_Init(void)
{
   // Initialize I2C
   //0101111(1) last 1 represents part of the slave address but also a Read command        
   I2caRegs.I2CSAR = 0x005F;        // Slave address
    
   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;        // 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;
}



// Initialization of Input/Output ports
void init_gpio(void)
{

// GPIO-32 - PIN FUNCTION = I2C SDA
    GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;// Enable pull-up for GPIO32 (SDAA)
    GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3;  // Asynch input GPIO32 (SDAA)
   GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1;//0;    // 0=GPIO,  1=I2C-SDA,  2=SYNCI,  3=ADCSOCA
   //GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1;        // 1=OUTput,  0=INput

// GPIO-33 - PIN FUNCTION = I2C SCL
GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;       // Enable pull-up for GPIO33 (SCLA)
 GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;  // Asynch input GPIO33 (SCLA)
   GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1;//0;    // 0=GPIO,  1=I2C-SCL,  2=SYNCO,  3=ADCSOCB
   //GpioCtrlRegs.GPBDIR.bit.GPIO33 = 1;        // 1=OUTput,  0=INput
   
}


//deactivate ADC intrrupt for test, activate I2C interrupt  
   I2c_interrupt_init()
{
    // Disable CPU interrupts
               DINT;
   
        // Disable CPU interrupts and clear all CPU interrupt flags:
           IER = 0x0000;
           IFR = 0x0000;
        
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        // This will populate the entire table, even if the interrupt
        // is not used in this example.  This is useful for debug purposes.
        // The shell ISR routines are found in DSP280x_DefaultIsr.c.
        // This function is found in DSP280x_PieVect.c.
        //   InitPieVectTable();
        
        
        // Enable the PIE Vector Table
        PieCtrlRegs.PIECTRL.bit.ENPIE = 1;    
        
        // Interrupts that are used in this example are re-mapped to
        // ISR functions found within this file.
           EALLOW;    // This is needed to write to EALLOW protected registers
           PieVectTable.I2CINT1A = &i2c_int1a_isr;
           EDIS;   // This is needed to disable write to EALLOW protected registers
    
        
        // Enable I2C interrupt 1 in the PIE: Group 8 interrupt 1
           PieCtrlRegs.PIEIER8.bit.INTx1 = 1;
        
        // Enable CPU INT8 which is connected to PIE group 8
           IER |= M_INT8;
           EINT;
}

//Start of the endless loop
for(;;)
{
    if(i2c_sent == 0)
           I2C_communication();
}

void I2C_communication()
{

    i2c_sent = 1;
        // Send slave address with 1 as last bit for Read command
        // 0101111(1) == 0x5F

        I2caRegs.I2CSAR = I2C_READ_SLAVE_ADDRESS;
}

interrupt void i2c_int1a_isr(void)     // I2C-A
{
   Uint16 IntSource;//, i;

   // Read interrupt source
   IntSource = I2caRegs.I2CISRC.all;

   // Interrupt source = stop condition detected
   if(IntSource == I2C_SCD_ISRC)
   {
      // If completed message was writing data, reset msg to inactive state
      if (CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_WRITE_BUSY)
      {
         CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_INACTIVE;
      }
   }
else if(IntSource == I2C_ARDY_ISRC)
   {
           // NACK a no-acknowledge bit was sent during the acknowledge
           // cycle on the I2C-bus.
      if(I2caRegs.I2CSTR.bit.NACK == 1)
      {
          // STP has been set by the device to generate a STOP condition
          // when the internal data counter of the I2C module counts down to 0
         I2caRegs.I2CMDR.bit.STP = 1;
         // (1) NACK bit received. The hardware detects that a no-acknowledge
         // (NACK) bit has been received. Note: While the I2C module performs
         // a general call transfer, NACK is 1, even if one or more slaves
         // send acknowledgment.
         I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
      }
      else if(CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY)
      {
         CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_RESTART;
      }
   }  // end of register access ready

   else
   {
      // Generate some error due to invalid interrupt source
      asm("   ESTOP0");
   }

    i2c_sent = 0;
    
   // Enable future I2C (PIE Group 8) interrupts
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
}

Thanks in advance

  • Hi,

    Maybe you have this somewhere else in your code but when you write to I2CSAR did you set the I2CCNT register for "number of bytes you expect to read", I2CMDR to set the device to "Master Recevier, set START and STOP bits"?

    There should be an I2C example in the device_support folder in controlSUITE for the MCU that you are using. It might be helpful to take a look at it.