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: TMS320F28379D, TMS320F28379D LaunchPad I2C not working

Part Number: TMS320F28379D

Tool/software: Code Composer Studio

Hello everyone;

I am using TMS320F28379D LaunchPad.  I need to implement I2C with this microcontroller. But no example works. In the forum, I tried every sample I researched a lot. I can't read I2C.

//
// Included Files
//
#include "F28x_Project.h"
Uint16 ErrorCounter;
//
// Defines
//
#define I2C_SLAVE_ADDRESS     0x44

Uint16 ReceiveData[5];
//
// Function Prototypes
//
void I2CA_Init(void);
void I2C_Read(Uint16 Slave_address, Uint16 Start_address,Uint16 No_of_databytes, Uint16 Read_Array[]);

//
// Main
//
void main(void)
{
//
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xD_SysCtrl.c file.
//
    InitSysCtrl();

//
// Step 2. Initialize GPIO:
// This example function is found in the F2837xD_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//
    InitGpio();

//
// For this example, only init the pins for the SCI-A port.
// These functions are found in the F2837xD_Gpio.c file.
//
    GPIO_SetupPinMux(104, GPIO_MUX_CPU1, 1);
    GPIO_SetupPinMux(105, GPIO_MUX_CPU1, 1);

//
// Step 3. Clear all __interrupts and initialize PIE vector table:
// Disable CPU __interrupts
//
    DINT;

//
// Initialize PIE control registers to their default state.
// The default state is all PIE __interrupts disabled and flags
// are cleared.
// This function is found in the F2837xD_PieCtrl.c file.
//
    InitPieCtrl();

//
// 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 F2837xD_DefaultIsr.c.
// This function is found in F2837xD_PieVect.c.
//
    InitPieVectTable();

//
// 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

    EDIS;
    // This is needed to disable write to EALLOW protected registers

//
// Step 4. Initialize the Device Peripherals:
//
    I2CA_Init();


//
// Enable CPU INT8 which is connected to PIE group 8
//
    IER |= M_INT8;
    EINT;

    while(1)
    {
         I2C_Read(EEPROM_24LC256_ADDRESS, 0x38,2,(Uint16*)&ReceiveData);
         DELAY_US(100);
         I2C_Read(EEPROM_24LC256_ADDRESS, 0xD7,2,(Uint16*)&ReceiveData);
         DELAY_US(100);
    }
}

//
// I2CA_Init - Initialize I2CA settings
//
void I2CA_Init(void)
{
       I2caRegs.I2CSAR.all = 0x44;     // Slave address - EEPROM control code
       I2caRegs.I2CPSC.all = 6;          // Prescaler - need 7-12 Mhz on module clk
       I2caRegs.I2CCLKL = 140;            // Prescalers set for 100kHz bit rate
       I2caRegs.I2CCLKH = 140;             //At a 100khz I2C clock
       I2caRegs.I2CIER.all = 0x00;       // DESAable SCD & ARDY __interrupts
       I2caRegs.I2CMDR.all = 0x0020;     // Take I2C out of reset
       I2caRegs.I2CFFTX.all = 0x6000;    // Enable FIFO mode and TXFIFO
       I2caRegs.I2CFFRX.all = 0x2040;    // Enable RXFIFO, clear RXFFINT,

    return;
}

void I2C_Read(Uint16 Slave_address, Uint16 Start_address,Uint16 No_of_databytes, Uint16 Read_Array[])
{
    Uint16 i = 0;
    I2caRegs.I2CSAR.all = Slave_address;
    I2caRegs.I2CCNT = No_of_databytes; // When operating in non repeat mode, this value will determine how many bytes to receive/send.
    Uint16 *Temp_Pointer;
    //Temp_Pointer = Read_Array;

    while (I2caRegs.I2CMDR.bit.STP != 0); // Detect a stop bit

    I2caRegs.I2CMDR.bit.TRX = 1; // Start bit, write mode, Higher 16 address bits, Master, Non Repeat mode.


    if (Slave_address == I2C_SLAVE_ADDRESS)
    {
        I2caRegs.I2CDXR.all = (Start_address) >> 8;
    }

    I2caRegs.I2CMDR.all = 0x26A0;

    while (I2caRegs.I2CSTR.bit.ARDY != 1);

    if (I2caRegs.I2CSTR.bit.ARDY == 1)
    {
        I2caRegs.I2CDXR.all = Start_address; // (Lower 16) address bits
    }

    while (I2caRegs.I2CSTR.bit.ARDY != 1);

// Put a stop bit. Because we need to change to non repeat mode.
    I2caRegs.I2CMDR.bit.STP = 1;

    while (I2caRegs.I2CMDR.bit.STP != 0); // Detect a stop bit
    I2caRegs.I2CMDR.all = 0x2C20;
    while (i < No_of_databytes)
    {
        //while (I2caRegs.I2CSTR.bit.RRDY != 1);
        while(I2caRegs.I2CFFRX.bit.RXFFINT != 1);
        Temp_Pointer[i] = I2caRegs.I2CDRR.all;
        i++;
    }
}

In addition, #define __LAUNCHXL_F28379D is defined in the library F2837xD_StsCtrl.c.  Nothing I've tried has worked. As soon as possible, I will review and share the SDA and CLK outputs with an oscilloscope.

  • Can you give me more details about in what way is it not working? Is the code getting stuck somewhere? Seeing what is happening on SDA and CLK will be helpful.

    One thing I'm noticing right now is that you're setting I2CCNT to No_of_databytes and then sending two bytes of address before requesting a stop condition. The stop condition won't actually be sent until I2CCNT is counted down to 0 though, so if No_of_databytes > 2, it's not going to send a stop condition when you expect it to. You should instead set I2CCNT to 2, send the address, and then set it to No_of_databytes when you are ready to receive the message.

    Whitney