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 master doesn't generate STP condition (TMS320F28335)

Guru 20045 points
Other Parts Discussed in Thread: TMS320F28335

Hello,

I have a TMS320F28335 conencted to a 24C64 eeprom.  If I try to transmit more than 32 bytes, the I2C master doesn't generate a stop condition (neither on the bus nor as an interrupt).

All the bytes are being transmitted including the two byte address - I can see them on the bus and my debug code shows them being put in the transmit register.  I consecutively ordered the data bytes sent (i.e. 0,1,2,3,4,5...0x1F) and I set the page number to 0, so I would get 0 0 0 1 2 3 4 5 6 7....0x1F on the bus, which is a total of 34 bytes sent.  The I2C Count register shows 0x22, which is equal to 34. 

My debug code and when I stop the program shows the I2C register as shown below.

Does anyone have any idea why the stop condition would not be generated for more than 32 bytes of data?

Stephen

I2C Registers

I2COAR: 0x0000   // I2C is a master,so its own slave address doesn't matter

I2CIER: 0x0026    //  ARDY,NACK and SCD standard interrupts are enabled

I2CSTR: 0x1010   // Bus is busy of course since stop condition wasn't generated and XRDY is set, but doesn't matter since I am using the FIFO

I2CCLKL: 0x002D //NA

I2CCLKL: 0x002D //NA

I2CCNT: 0x0022   // set to 34 bytes as it should be

I2CDRR: 0x0046  // NA

I2CSAR: 0x0050   // EEPROM address

I2CDXR: 0x001F  // NA

I2CMDR: 0x4E20  // FREE=1 (NA), STP=1 (should generate stop when 34 bytes transmitted), MST=1, TRX=1 (transmitter), IRS =1 (I2C module is enabled.)

I2CISRC: 0x0000   // No interrupts happened

I2CPSC: 0x000E    // Prescale register (NA)

I2CFFTX: 0x6080  // I2CFFEN =1 (FIFO mode enabled),TXFFRST = 1 (enable transmit FIFO), TXFFINT = 1 (Transmit fifo interrupt condition occurred)

I2CFFRX: 0x202D // RXFFRST=1 (Rx FIFO enabled),RXFFIENA =1 (Rx FIFO interrupt enabled),  RXFFIL4-0 = 13 (interrupts after 13 bytes rx)

  • Hello,

    I have attached a modified version of the  Example_2833xI2C_eeprom example project  (located in the tidcs/c28/DSP2833x/v131/DSP2833x_examples_ccsv4 folder).

    This project has the same issues.  A stop is not generated if greater than 32 total bytes are transmitted (I2C_NUMBYTES > 30).

    Stephen

     

    1185.i2c_eeprom.zip

     

  • Hello,

    Just checking if anyone from TI is looking into this one - just so it doesn't get lost in the stack of papers:)

    Also, I previously attached a CCS5.3 project having the same issue.  The project is a modified version of a control suite example.

    Thanks,

    Stephen

  • Hi Stephen,

    I ran your code and observed the stream with an I2C monitor

    The image may not be very clear but ill describe what I got

    First off, in your code I2C_NUMBYTES is set to 30, the stream that is shown in the red box is the result of this

    I was able to transmit 32 characters and then recieve data from the slave, Master transmits upto 1D

    00 00 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D

    Now, I changed I2C_NUMBYTES to 32, but as you said the STP does not get generated.When I looked at the transmission stream(blue box) I get:

    00 00 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F

    0E and 0F are missing from this transmission, that is why the STP isn't being generated its still waiting to tx 2 more bytes. You might want to take a look at your TX interrupt routine again and make sure it isn't skipping over any of the data bytes

  • Hello Vishal,

    Thanks alot.  I think I got mislead by my debug data that was showing the data being written.

    However, an issue still exist.  The Tx FIFO is shown to be completely full when the second transmit interrupt occurs and that is what I believe is causing the two missing data.

    When the second (last) transmit interrupt occurs, the last two bytes are shifted into the FIFO and the two front bytes in the FIFO are shifted out (disappear).

    Why would the interrupt occur when the FIFO is full.  I checked all the registers and I couldn't find out why it would be happening.

    I attached the program with additional debug code.

    Stephen

    // TI File $Revision: /main/2 $
    // Checkin $Date: July 30, 2009   18:45:12 $
    //###########################################################################
    //
    // FILE:    Example_2833xI2c_eeprom.c
    //
    // TITLE:   DSP2833x I2C EEPROM Example
    //
    // ASSUMPTIONS:
    //
    //    This program requires the DSP2833x header files.
    //
    //    This program requires an external I2C EEPROM connected to
    //    the I2C bus at address 0x50.
    //
    //    As supplied, this project is configured for "boot to SARAM"
    //    operation.  The 2833x Boot Mode table is shown below.
    //    For information on configuring the boot mode of an eZdsp,
    //    please refer to the documentation included with the eZdsp,
    //
    //       $Boot_Table:
    //
    //         GPIO87   GPIO86     GPIO85   GPIO84
    //          XA15     XA14       XA13     XA12
    //           PU       PU         PU       PU
    //        ==========================================
    //            1        1          1        1    Jump to Flash
    //            1        1          1        0    SCI-A boot
    //            1        1          0        1    SPI-A boot
    //            1        1          0        0    I2C-A boot
    //            1        0          1        1    eCAN-A boot
    //            1        0          1        0    McBSP-A boot
    //            1        0          0        1    Jump to XINTF x16
    //            1        0          0        0    Jump to XINTF x32
    //            0        1          1        1    Jump to OTP
    //            0        1          1        0    Parallel GPIO I/O boot
    //            0        1          0        1    Parallel XINTF boot
    //            0        1          0        0    Jump to SARAM	    <- "boot to SARAM"
    //            0        0          1        1    Branch to check boot mode
    //            0        0          1        0    Boot to flash, bypass ADC cal
    //            0        0          0        1    Boot to SARAM, bypass ADC cal
    //            0        0          0        0    Boot to SCI-A, bypass ADC cal
    //                                              Boot_Table_End$
    //
    // DESCRIPTION:
    //
    //    This program will write 1-14 words to EEPROM and read them back.
    //    The data written and the EEPROM address written to are contained
    //    in the message structure, I2cMsgOut1. The data read back will be
    //    contained in the message structure I2cMsgIn1.
    //
    //    This program will work with the on-board I2C EEPROM supplied on
    //    the F2833x eZdsp.
    //
    //
    //###########################################################################
    // Original Author: D.F.
    //
    // $TI Release: DSP2833x/DSP2823x C/C++ Header Files V1.31 $
    // $Release Date: August 4, 2009 $
    //###########################################################################
    
    
    
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    #define DEBUG_DATA_ARRAY_SIZE 100
    #define DEBUG_INFO_ARRAY_SIZE 10
    
    Uint16 abc[DEBUG_DATA_ARRAY_SIZE];
    Uint16 abcIndex =0;
    Uint16 abcNumOfDataInFIFO[DEBUG_INFO_ARRAY_SIZE];
    Uint16 abcWhereAmI[DEBUG_INFO_ARRAY_SIZE];
    Uint16 abcFIFOtxIntLevel[DEBUG_INFO_ARRAY_SIZE];
    Uint16 abcIndex2 = 0;
    // Note: I2C Macros used in this example can be found in the
    // DSP2833x_I2C_defines.h file
    
    // Prototype statements for functions found within this file.
    void   I2CA_Init(void);
    Uint16 I2CA_WriteData(struct I2CMSG *msg);
    Uint16 I2CA_ReadData(struct I2CMSG *msg);
    interrupt void i2c_int1a_isr(void);
    interrupt void i2c_int2a_isr(void);
    void pass(void);
    void fail(void);
    
    #define I2C_SLAVE_ADDR        0x50
    #define I2C_NUMBYTES          32
    #define I2C_EEPROM_HIGH_ADDR  0x00
    #define I2C_EEPROM_LOW_ADDR   0x00
    
    // Global variables
    // Two bytes will be used for the outgoing address,
    // thus only setup 14 bytes maximum
    struct I2CMSG I2cMsgOut1={I2C_MSGSTAT_SEND_WITHSTOP,
                              I2C_SLAVE_ADDR,
                              I2C_NUMBYTES,
                              I2C_EEPROM_HIGH_ADDR,
                              I2C_EEPROM_LOW_ADDR,
                              0x00,                   // Msg Byte 1
                              0x01,                   // Msg Byte 2
                              0x02,                   // Msg Byte 3
                              0x03,                   // Msg Byte 4
                              0x04,                   // Msg Byte 5
                              0x05,                   // Msg Byte 6
                              0x06,                   // Msg Byte 7
                              0x07,                   // Msg Byte 8
                              0x08,                   // Msg Byte 9
                              0x09,                   // Msg Byte 10
                              0x0a,                   // Msg Byte 11
                              0x0b,                   // Msg Byte 12
                              0x0c,                   // Msg Byte 13
                              0x0d,
                              0x0e,
                              0x0f,
                              0x10,                   // Msg Byte 13
                              0x11,
                              0x12,
                              0x13,
                              0x14,
                              0x15,                   // Msg Byte 9
                              0x16,                   // Msg Byte 10
                              0x17,                   // Msg Byte 11
                              0x18,                   // Msg Byte 12
                              0x19,                   // Msg Byte 13
                              0x1a,
                              0x1b,
                              0x1c,
                              0x1d,                   // Msg Byte 13
                              0x1e,
                              0x1f };                  // Msg Byte 14
    
    Uint16 numberOfDataLeftToWrite;
    Uint16 CurrentMsgBufferDataIndex = 0;
    
    struct I2CMSG I2cMsgIn1={ I2C_MSGSTAT_SEND_NOSTOP,
                              I2C_SLAVE_ADDR,
                              I2C_NUMBYTES,
                              I2C_EEPROM_HIGH_ADDR,
                              I2C_EEPROM_LOW_ADDR};
    
    struct I2CMSG *CurrentMsgPtr;				// Used in interrupts
    Uint16 PassCount;
    Uint16 FailCount;
    
    void main(void)
    {
       Uint16 Error;
       Uint16 i;
    
       CurrentMsgPtr = &I2cMsgOut1;
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2833x_SysCtrl.c file.
       InitSysCtrl();
    
    
    // Step 2. Initalize GPIO:
    // This example function is found in the DSP2833x_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();
    
    // 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 DSP2833x_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 DSP2833x_DefaultIsr.c.
    // This function is found in DSP2833x_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.I2CINT1A = &i2c_int1a_isr;
       PieVectTable.I2CINT2A = &i2c_int2a_isr;
       EDIS;   // This is needed to disable write to EALLOW protected registers
    
       for (i=0;i<DEBUG_INFO_ARRAY_SIZE;i++)
       {
    
          abcNumOfDataInFIFO[i] = 0;
          abcWhereAmI[i] = 0;
          abcFIFOtxIntLevel[i] = 0;
       }
    
    
    
       for (i=0;i<DEBUG_DATA_ARRAY_SIZE;i++)
       {
          abc[i] = 0;
       }
    
    // Step 5. User specific code
    
       // Clear Counters
       PassCount = 0;
       FailCount = 0;
    
       // Clear incoming message buffer
       for (i = 0; i < I2C_MAX_BUFFER_SIZE; i++)
       {
           I2cMsgIn1.MsgBuffer[i] = 0x0000;
       }
    
       // Step 4. Initialize all the Device Peripherals:
       // This function is found in DSP2833x_InitPeripherals.c
       // InitPeripherals(); // Not required for this example
       I2CA_Init();
       EINT;
    
       // Application loop
       for(;;)
       {
          //////////////////////////////////
          // Write data to EEPROM section //
          //////////////////////////////////
    
          // Check the outgoing message to see if it should be sent.
          // In this example it is initialized to send with a stop bit.
          if(I2cMsgOut1.MsgStatus == I2C_MSGSTAT_SEND_WITHSTOP)
          {
             Error = I2CA_WriteData(&I2cMsgOut1);
             // If communication is correctly initiated, set msg status to busy
             // and update CurrentMsgPtr for the interrupt service routine.
             // Otherwise, do nothing and try again next loop. Once message is
             // initiated, the I2C interrupts will handle the rest. Search for
             // ICINTR1A_ISR in the i2c_eeprom_isr.c file.
             if (Error == I2C_SUCCESS)
             {
                CurrentMsgPtr = &I2cMsgOut1;
                I2cMsgOut1.MsgStatus = I2C_MSGSTAT_WRITE_BUSY;
             }
          }  // end of write section
    
          ///////////////////////////////////
          // Read data from EEPROM section //
          ///////////////////////////////////
    
          // Check outgoing message status. Bypass read section if status is
          // not inactive.
          if (I2cMsgOut1.MsgStatus == I2C_MSGSTAT_INACTIVE)
          {
             // Check incoming message status.
             if(I2cMsgIn1.MsgStatus == I2C_MSGSTAT_SEND_NOSTOP)
             {
                // EEPROM address setup portion
                while(I2CA_ReadData(&I2cMsgIn1) != I2C_SUCCESS)
                {
                   // Maybe setup an attempt counter to break an infinite while
                   // loop. The EEPROM will send back a NACK while it is performing
                   // a write operation. Even though the write communique is
                   // complete at this point, the EEPROM could still be busy
                   // programming the data. Therefore, multiple attempts are
                   // necessary.
                }
                // Update current message pointer and message status
                CurrentMsgPtr = &I2cMsgIn1;
                I2cMsgIn1.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY;
             }
    
             // Once message has progressed past setting up the internal address
             // of the EEPROM, send a restart to read the data bytes from the
             // EEPROM. Complete the communique with a stop bit. MsgStatus is
             // updated in the interrupt service routine.
             else if(I2cMsgIn1.MsgStatus == I2C_MSGSTAT_RESTART)
             {
                // Read data portion
                while(I2CA_ReadData(&I2cMsgIn1) != I2C_SUCCESS)
                {
                   // Maybe setup an attempt counter to break an infinite while
                   // loop.
                }
                // Update current message pointer and message status
                CurrentMsgPtr = &I2cMsgIn1;
                I2cMsgIn1.MsgStatus = I2C_MSGSTAT_READ_BUSY;
             }
          }  // end of read section
    
       }   // end of for(;;)
    }   // end of main
    
    void I2CA_Init(void)
    {
       EALLOW;
       GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1;        // 0=GPIO  1=SDAA      2=EPWMSYNCI  3=ADCSOCAO
       GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1;        // 0=GPIO  1=SCLA      2=EPWMSYNCO  3=ADCSOCBO
    
       /* Enable the I2C Peripheral clock */
       SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1;
    
       /* Assign the correct Interrupt Service Routine
        * function pointers to the PIE vector Table */
       PieVectTable.I2CINT1A = &i2c_int1a_isr;
       PieVectTable.I2CINT2A = &i2c_int2a_isr;
       EDIS;
    
       // I2C Module Clock = SysClockOut/(I2C_IPC+1)
       I2caRegs.I2CPSC.all = 14;
    
       I2caRegs.I2CCLKL = 45;  // I2C Clock Low Time
       I2caRegs.I2CCLKH = 45;  // I2C Clock High Time
    
       I2caRegs.I2CIER.all = 0x00;          //first, clear the Interrupt Enable Register
       I2caRegs.I2CIER.bit.ARDY = 1;        //Register access ready interrupt
       I2caRegs.I2CIER.bit.SCD = 1;         //Stop condition detection
       I2caRegs.I2CIER.bit.NACK = 1;        // Detect NAK from slave-receiver
       I2caRegs.I2CIER.bit.ARBL =  1;
    
       I2caRegs.I2CFFTX.all = 0x00;         // first, clear the FIFO Tx register
                                            // and then
                                            // set the individual bits.
       I2caRegs.I2CFFTX.bit.I2CFFEN = 1;    // Enable FIFO Mode
       I2caRegs.I2CFFTX.bit.TXFFRST = 1;    // Enable Transmit FIFO Mode (16 byte Tx fifo)
       I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1; // Clear the TXFFINT flag.
    
       I2caRegs.I2CFFTX.all = 0x00;         // first, clear the FIFO Rx register
                                            // and then
                                            // set the individual bits.
       I2caRegs.I2CFFTX.bit.I2CFFEN = 1;    // Enable FIFO Mode
       I2caRegs.I2CFFTX.bit.TXFFRST = 1;    // Enable Transmit FIFO (16 byte Tx fifo)
       I2caRegs.I2CFFTX.bit.TXFFIL = 0;     // interrupt when Tx FIFO is empty.
       I2caRegs.I2CFFTX.bit.TXFFIENA = 0;   // Disable Tx FIFO interrupt until
                                            // Ready to transmit.
    
       I2caRegs.I2CFFRX.all = 0x00;
       I2caRegs.I2CFFRX.bit.RXFFRST = 1;    // Enable Rx FIFO (16 byte Rx fifo)
       I2caRegs.I2CFFRX.bit.RXFFIL= 13;     // Generate Rx Interrupt when Rx FIFO
                                                                // level is = I2C_RX_INTERRUPT_LEVEL.
       I2caRegs.I2CFFRX.bit.RXFFIENA = 1;   // Enable Rx FIFO interrupt.
    
       I2caRegs.I2CMDR.all = 0x0000;        // first, clear the Mode Register
       I2caRegs.I2CMDR.bit.RM = 0;           // Repeat Mode
       I2caRegs.I2CMDR.bit.TRX = 1;         // The module is a Transmitter
       I2caRegs.I2CMDR.bit.MST = 1;         // Master Mode.
       I2caRegs.I2CMDR.bit.IRS = 1;         // Bring the I2C out of reset.
       I2caRegs.I2CMDR.bit.FREE = 0;
       //I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1;
       I2caRegs.I2CFFTX.all |= 0x6000;      // Enable FIFO mode and TXFIFO
       I2caRegs.I2CFFRX.all |= 0x2040;      // Enable RXFIFO, clear RXFFINT,
    
    
       /* Enable the I2C1A PIE */
       PieCtrlRegs.PIEIER8.bit.INTx1=1;
       PieCtrlRegs.PIEIER8.bit.INTx2=1;
    
       IER |=M_INT8;    // Enable INT8
    
       return;
    }
    
    Uint16 I2CA_WriteData(struct I2CMSG *msg)
    {
       Uint16 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.
       if (I2caRegs.I2CMDR.bit.STP == 1)
       {
          return I2C_STP_NOT_READY_ERROR;
       }
    
       // Setup slave address
       I2caRegs.I2CSAR = msg->SlaveAddress;
    
       // Check if bus busy
       if (I2caRegs.I2CSTR.bit.BB == 1)
       {
          return I2C_BUS_BUSY_ERROR;
       }
    
       // Setup number of bytes to send
       // MsgBuffer + Address
       I2caRegs.I2CCNT = msg->NumOfBytes+2;
    
       numberOfDataLeftToWrite = msg->NumOfBytes+2 - 16;
    
    
       // Write first 16 bytes to FIFO - isr will do the rest.\
    
    
       // Setup data to send
       I2caRegs.I2CDXR = msg->MemoryHighAddr;
       I2caRegs.I2CDXR = msg->MemoryLowAddr;
    
       for (i=0; i<14;i++)
       {
          I2caRegs.I2CDXR = *(msg->MsgBuffer+i);
          abc[abcIndex++] = *(msg->MsgBuffer+i);
       }
    
       I2caRegs.I2CFFTX.bit.TXFFIENA = 1;
       I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1;
    
       CurrentMsgBufferDataIndex = i;
    
       // Send start as master transmitter
       I2caRegs.I2CMDR.all = 0x6E20;
    
       return I2C_SUCCESS;
    }
    
    
    Uint16 I2CA_ReadData(struct I2CMSG *msg)
    {
       // 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.
       if (I2caRegs.I2CMDR.bit.STP == 1)
       {
          return I2C_STP_NOT_READY_ERROR;
       }
    
       I2caRegs.I2CSAR = msg->SlaveAddress;
    
       if(msg->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP)
       {
          // Check if bus busy
          if (I2caRegs.I2CSTR.bit.BB == 1)
          {
             return I2C_BUS_BUSY_ERROR;
          }
          I2caRegs.I2CCNT = 2;
          I2caRegs.I2CDXR = msg->MemoryHighAddr;
          I2caRegs.I2CDXR = msg->MemoryLowAddr;
          I2caRegs.I2CMDR.all = 0x2620;			// Send data to setup EEPROM address
       }
       else if(msg->MsgStatus == I2C_MSGSTAT_RESTART)
       {
          I2caRegs.I2CCNT = msg->NumOfBytes;	// Setup how many bytes to expect
          I2caRegs.I2CMDR.all = 0x2C20;			// Send restart as master receiver
       }
    
       return I2C_SUCCESS;
    }
    
    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 a message receives a NACK during the address setup portion of the
             // EEPROM read, the code further below included in the register access ready
             // interrupt source code will generate a stop condition. After the stop
             // condition is received (here), set the message status to try again.
             // User may want to limit the number of retries before generating an error.
             if(CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY)
             {
                CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_SEND_NOSTOP;
             }
             // If completed message was reading EEPROM data, reset msg to inactive state
             // and read data from FIFO.
             else if (CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_READ_BUSY)
             {
                CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_INACTIVE;
                for(i=0; i < I2C_NUMBYTES; i++)
                {
                  CurrentMsgPtr->MsgBuffer[i] = I2caRegs.I2CDRR;
                }
             {
             // Check recieved data
             for(i=0; i < I2C_NUMBYTES; i++)
             {
                if(I2cMsgIn1.MsgBuffer[i] == I2cMsgOut1.MsgBuffer[i])
                {
                    PassCount++;
                }
                else
                {
                    FailCount++;
                }
             }
             if(PassCount == I2C_NUMBYTES)
             {
                pass();
             }
             else
             {
                fail();
             }
    
    
          }
    
        }
          }
       }  // end of stop condition detected
    
       // Interrupt source = Register Access Ready
       // This interrupt is used to determine when the EEPROM address setup portion of the
       // read data communication is complete. Since no stop bit is commanded, this flag
       // tells us when the message has been sent instead of the SCD flag. If a NACK is
       // received, clear the NACK bit and command a stop. Otherwise, move on to the read
       // data portion of the communication.
       else if(IntSource == I2C_ARDY_ISRC)
       {
          if(I2caRegs.I2CSTR.bit.NACK == 1)
          {
             I2caRegs.I2CMDR.bit.STP = 1;
             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 soe error due to invalid interrupt source
          asm("   ESTOP0");
       }
    
       // Enable future I2C (PIE Group 8) interrupts
       PieCtrlRegs.PIEACK.all |= PIEACK_GROUP8;
    }
    Uint32 fifoNotZero = 0;
    
    interrupt void i2c_int2a_isr(void)
    {
       Uint16 i;
       Uint16 txFifoInterruptOccurred;
       Uint16 rxFifoInterruptOccurred;
       Uint16 xxx1 = 0;
       Uint16 xxx2 = 0;
    
       if (1 == abcIndex2)
       {
          abcIndex2 = 1;
       }
    
       txFifoInterruptOccurred = I2caRegs.I2CFFTX.bit.TXFFINT;
    
       rxFifoInterruptOccurred = I2caRegs.I2CFFRX.bit.RXFFINT;
    
       I2caRegs.I2CFFRX.bit.RXFFINTCLR = 1;
    
    
       if (txFifoInterruptOccurred)
       {
          //if(I2caRegs.I2CFFTX.bit.TXFFST)
          //{
             //fifoNotZero++;
             //PieCtrlRegs.PIEACK.all |= PIEACK_GROUP8;
             //return;
          //}
    
          I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1;
    
          // If number of bytes to transmit is <= Fifo then
          // then load all those bytes into the fifo and don't
          // try to transmit any more.
          if (numberOfDataLeftToWrite <= 16)
          {
    
             I2caRegs.I2CFFTX.bit.TXFFIENA = 0;
    
             abcWhereAmI[abcIndex2] = 1;
             abcFIFOtxIntLevel[abcIndex2] = I2caRegs.I2CFFTX.bit.TXFFIL;
             abcNumOfDataInFIFO[abcIndex2++] =  I2caRegs.I2CFFTX.bit.TXFFST;
    
             xxx1 = I2caRegs.I2CFFTX.bit.TXFFST;
    
             xxx2 = I2caRegs.I2CFFTX.bit.TXFFST;
    
             // Write bytes to the FIFO
             for (i = CurrentMsgBufferDataIndex;
                   i < CurrentMsgBufferDataIndex + numberOfDataLeftToWrite; i++)
             {
                I2caRegs.I2CDXR = *(CurrentMsgPtr->MsgBuffer+i);
                abc[abcIndex++] = *(CurrentMsgPtr->MsgBuffer+i);
    
             }
    
             // Don't send any more bytes
             // after FIFO is empty.
             numberOfDataLeftToWrite = 0;
    
          }
          else
          {
             abcWhereAmI[abcIndex2] = 2;
             abcFIFOtxIntLevel[abcIndex2] = I2caRegs.I2CFFTX.bit.TXFFIL;
             abcNumOfDataInFIFO[abcIndex2++] =  I2caRegs.I2CFFTX.bit.TXFFST;
    
             // Fill the FIFO
             for (i = CurrentMsgBufferDataIndex; i < CurrentMsgBufferDataIndex + 16;
                   i++)
             {
                I2caRegs.I2CDXR = *(CurrentMsgPtr->MsgBuffer+i);
                abc[abcIndex++] = *(CurrentMsgPtr->MsgBuffer+i);
             }
    
             CurrentMsgBufferDataIndex = i;
    
             // Compute number of bytes to send after FIFO is empty
             numberOfDataLeftToWrite = numberOfDataLeftToWrite - 16;
    
          }
       }
    
       // Enable future I2C (PIE Group 8) interrupts
       PieCtrlRegs.PIEACK.all |= PIEACK_GROUP8;
    }
    
    void pass()
    {
        asm("   ESTOP0");
        for(;;);
    }
    
    void fail()
    {
        asm("   ESTOP0");
        for(;;);
    }
    
    
    //===========================================================================
    // No more.
    //===========================================================================
    

    Note: I have another post where I mentioned the i2c_int2a_isr occurring and neither the Tx or Rx interrupt was set.  I am wonder if this is somehow related (http://e2e.ti.com/support/microcontrollers/c2000/f/171/p/267195/934175.aspx#934175)

  • Just wanted to let everyone know I have already solved the problem.

    I needed to clear the Tx intflag (I2caRegs.I2CFFTX.bit.TXFFINTCLR) after (not before) filling the fifo.

    Stephen