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/LAUNCHXL-F280049C: LAUNCHXL-F280049C I2C problem

Part Number: LAUNCHXL-F280049C

Tool/software: Code Composer Studio

Dear Sir

I have a problem with the I2C in the LAUNCHXL-F280049C board.

I simply want write to I2C a data. I configure the board in several way, adapting code for other microcontroller.

My problem is that: after write, in SDA and SCL pin (GPIO35, GPIO37) I don't see anything. Both the pin keep always high (I use external pull up resistor).

In the following code, the program stops in "I2CA_Wait();" at "while (I2caRegs.I2CMDR.bit.STP == 1);" instruction.

Any suggestion?

Regards

Piero

// Included Files
#include "F28x_Project.h"
#include "stdio.h"

//--------------------------------------------
// Defines
//--------------------------------------------

// Error Messages
#define I2C_ERROR               0xFFFF
#define I2C_ARB_LOST_ERROR      0x0001
#define I2C_NACK_ERROR          0x0002
#define I2C_BUS_BUSY_ERROR      0x1000
#define I2C_STP_NOT_READY_ERROR 0x5555
#define I2C_NO_FLAGS            0xAAAA
#define I2C_SUCCESS             0x0000

// Clear Status Flags
#define I2C_CLR_AL_BIT          0x0001
#define I2C_CLR_NACK_BIT        0x0002
#define I2C_CLR_ARDY_BIT        0x0004
#define I2C_CLR_RRDY_BIT        0x0008
#define I2C_CLR_SCD_BIT         0x0020

// Interrupt Source Messages
#define I2C_NO_ISRC             0x0000
#define I2C_ARB_ISRC            0x0001
#define I2C_NACK_ISRC           0x0002
#define I2C_ARDY_ISRC           0x0003
#define I2C_RX_ISRC             0x0004
#define I2C_TX_ISRC             0x0005
#define I2C_SCD_ISRC            0x0006
#define I2C_AAS_ISRC            0x0007

// Prototype statements for functions found within this file.
void I2CA_Init(void);
void I2CA_Write(int);
void I2CA_Read(int);
void I2CA_Wait(void);

interrupt void i2c_int1a_isr(void);

struct FLAGREG_BITS
{
    volatile unsigned int Rsvd:16;      //bits 0-14
};
union FLAG_REG
{
    volatile unsigned int all;
    struct FLAGREG_BITS   bit;
}Flags;


Uint16 Register;
Uint16 Reg[6];
Uint16 ReadReg[6] = {0,0,0,0,0,0};

Uint16 InData[3];
Uint16 OutData[3];
Uint16 I2cIndex;

#define I2C_SLAVE_ADDR        0x2c

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


// Step 2. Initalize GPIO:
// This example function is found in the DSP280x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();
// Setup only the GP I/O only for I2C functionality
    //InitI2CGpio();
    EALLOW;
    // Enable internal pull-up for the selected pins
    // Pull-ups can be enabled or disabled disabled by the user.
    GpioCtrlRegs.GPBPUD.bit.GPIO35 = 1; // Disable pull-up for GPIO35 (I2CA_SDA)
    GpioCtrlRegs.GPBPUD.bit.GPIO37 = 1; // Disable pull-up for GPIO37 (I2CA_SCL)
    // Set qualification for selected pins to asynch only
    // This will select asynch (no qualification) for the selected pins.
    GpioCtrlRegs.GPBQSEL1.bit.GPIO35 = 3; // Asynch input GPIO35 (I2CA_SDA)
    GpioCtrlRegs.GPBQSEL1.bit.GPIO37 = 3; // Asynch input GPIO37 (I2CA_SCL)
    // Configure SCI pins using GPIO regs
    // This specifies which of the possible GPIO pins will be I2C functional pins.
    GpioCtrlRegs.GPBMUX1.bit.GPIO35 = 3; // Configure GPIO35 for I2CA_SDA operation
    GpioCtrlRegs.GPBMUX1.bit.GPIO37 = 3; // Configure GPIO37 for I2CA_SCL operation
    EDIS;

// 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 DSP280x_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 DSP280x_DefaultIsr.c.
// This function is found in DSP280x_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
    //PieVectTable.I2CA_FIFO_INT = &i2c_int1a_isr;
    PieVectTable.I2CA_INT = &i2c_int1a_isr;
    EDIS;   // This is needed to disable write to EALLOW protected registers

    I2cIndex = 0;

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

// Step 5, Master I2C register initialization
//
    Reg[0] = 0x0055;
    Reg[1] = 0x01AA;
    Reg[2] = 0x0234;
    Reg[3] = 0x0321;
    Reg[4] = 0x0468;
    Reg[5] = 0x0531;

// Enable interrupts required for this example
// 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;

   // Application loop
    while(1){
        I2caRegs.I2CSAR.all = I2C_SLAVE_ADDR;// Set up address written to.
        
        I2CA_Write(0);                   // Transfer Register 0 contents to slave.
        I2CA_Wait();                     // Wait for I2C bus to clear
        
        /*I2CA_Write(1);
        I2CA_Wait();                     // Wait for I2C bus to clear   
        I2CA_Write(2);
        I2CA_Wait();                     // Wait for I2C bus to clear    
        I2CA_Write(3);
        I2CA_Wait();                     // Wait for I2C bus to clear     
        I2CA_Write(4);
        I2CA_Wait();                     // Wait for I2C bus to clear 
        I2CA_Write(5);
        I2CA_Wait();                     // Wait for I2C bus to clear
        
          ///////////////////////////////////
          // Read data from slave section  //
          ///////////////////////////////////
        //
        //  This needs to be changed to (1) Send out the Register as a write,
        //   followed by (2) Receiving the response.
        //
        I2CA_Read(0);
        I2CA_Wait();
        ReadReg[0] = (InData[0]<<8) + InData[1];       
        I2CA_Read(1);
        I2CA_Wait();
        ReadReg[1] = (InData[0]<<8) + InData[1];
        I2CA_Read(2);
        I2CA_Wait();
        ReadReg[2] = (InData[0]<<8) + InData[1];       
        I2CA_Read(3);
        I2CA_Wait();
        ReadReg[3] = (InData[0]<<8) + InData[1];   
        I2CA_Read(4);
        I2CA_Wait();
        ReadReg[4] = (InData[0]<<8) + InData[1];  
        I2CA_Read(5);
        I2CA_Wait();
        ReadReg[5] = (InData[0]<<8) + InData[1];*/

    }
}   // end of main


void I2CA_Init(void)
{
   // Initialize I2C
    I2caRegs.I2CSAR.all = I2C_SLAVE_ADDR;//0x002C;       // Slave Address.
    I2caRegs.I2COAR.all = 0x002D;       //  address as Master.
    I2caRegs.I2CPSC.all = 9;        // Prescaler - need 7-12 Mhz on module clk
    I2caRegs.I2CCLKL = 45;          // NOTE: must be non zero
    I2caRegs.I2CCLKH = 45;           // NOTE: must be non zero
    I2caRegs.I2CIER.all = 0x2C;     // Enable SCD & ARDY interrupts

    I2caRegs.I2CMDR.bit.IRS = 1;    // 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_Write(Register)
{
    int Byte0;
    int Byte1;

    Byte0 = Reg[Register]&0x0FF;    // Get low byte of selected register.
    Byte1 = Reg[Register]>>8;       // Get high byte of selected register.

// Slave Address info gets passed with Start Condition
//    I2caRegs.I2CFFTX.all = 0x6000;    // Enable FIFO mode and TXFIFO
    I2caRegs.I2CCNT = 3;            // 3 Additional Bytes being tranferred.
    I2caRegs.I2CDXR.all = Register;     // Send Register to be updated.
    I2caRegs.I2CDXR.all = Byte1;        // Next is high byte of register.
    I2caRegs.I2CDXR.all = Byte0;        // Next is low byte of register.

    I2caRegs.I2CMDR.all = 0x6E20;   // Set up the control register:
                                    // bit 14 FREE = 1
                                    // bit 13 STT = 1  (Start condition)

                                    // bit 11 STP = 1  (Stop condition after
                                    //                transfer of bytes.)
                                    // bit 10 MST = 1  Master
                                    // bit  9 TRX = 1  Transmit

                                    // bit  5 IRS = 1 to Reset I2C bus.
}

void I2CA_Read(Register)
{
    I2cIndex = 0;                   // Reset value for ISR.
// Slave Address info gets passed with Start Condition
    I2caRegs.I2CCNT = 1;            // 1 Additional Byte being tranferred.
    I2caRegs.I2CDXR.all = Register;     // Send Register to be updated.
    I2caRegs.I2CMDR.all = 0x6620;   // Set up the control register:
                                    // bit 14 FREE = 1
                                    // bit 13 STT = 1  (Start condition)

                                    // bit 11 STP = 0  (Stop condition after
                                    //                transfer of bytes.)
                                    // bit 10 MST = 1  Master
                                    // bit  9 TRX = 1  Transmit

                                    // bit  5 IRS = 1 to Reset I2C bus.

    DELAY_US(50);                   // Delay 50 usec

    I2caRegs.I2CCNT = 2;            // Set up receive of 2 bytes.
    I2caRegs.I2CMDR.all = 0x6C20;   // Send "repeated" Start with Read (TRX off)
                                    // and Stop.
//    while (I2caRegs.I2CMDR.bit.STP == 1); // Wait for Stop condition bit to be zero.

//  while (I2caRegs.I2CSTR.bit.BB == 1);  // Wait for Bus Busy to be zero.

}

void I2CA_Wait(void)
{
   // 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.

    while (I2caRegs.I2CMDR.bit.STP == 1); // Wait for Stop condition bit to be zero.

    while (I2caRegs.I2CSTR.bit.BB == 1);  // Wait for Bus Busy to be zero.

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

   // Read interrupt source
    IntSource = I2caRegs.I2CISRC.bit.INTCODE & 0x7;

    switch(IntSource)
    {
        case I2C_NO_ISRC:   // =0
            break;

        case I2C_ARB_ISRC:  // =1
            break;

        case I2C_NACK_ISRC: // =2
            break;

        case I2C_ARDY_ISRC: // =3
            break;

        case I2C_RX_ISRC:   // =4
            InData[I2cIndex++] = I2caRegs.I2CDRR.all;
            break;

        case I2C_TX_ISRC:   // =5
            break;

        case I2C_SCD_ISRC:  // =6
            break;

        case I2C_AAS_ISRC:  // =7
            break;

        default:
            asm("   ESTOP0"); // Halt on invalid number.
    }

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

  • You may want to write a 0 to the GPBGMUX1 fields just to be sure, but otherwise the GPIO configuration for 35 and 37 looks okay. I'm not seeing any issues with your I2C configuration either.

    So no activity on either pin at any point in the write and wait functions? What do you see in the I2CSTR register? What about the I2CFFTX.TXFFST field?

    Whitney