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.

TMS320F28069: How to send more than 4 bytes of data to eeprom using FIFO mode in I2C

Part Number: TMS320F28069
Other Parts Discussed in Thread: C2000WARE

Hi ,i am interfacing eeprom with tms320f28069 using I2C protocol,I am unable to send more than 4 bytes of data.

and i have to write the entire page of eeprom .

so,what can i do to send more than 4bytes of data to the eeprom using FIFO.

thank you

your faithfully 

mihir dave

  • hi,

    The I2C FIFO on this device can support only upto 4 bytes of data transfer and interrupt generation setting.  

    We do have devices with 16-byte FIFOs.

    I believe you are already looking at the example : C2000Ware\device_support\f2806x\examples\c28\i2c_eeprom

    Transfer of multiple data can be achieved by using the FIFOs .

    The default options in the code are 0. Since these bits are zero, the receive FIFO interrupt flag will be set if the receive FIFO operation is enabled and the I2C is taken out of reset. 

    I2caRegs.I2CFFTX.all 
    I2caRegs.I2CFFRX.all 

    We could increase the trigger levels in the registers and send chunks of data .

    Regards.

  • Hi,

    Currently the value's of respective registers are I2caRegs.I2CFFTX.all=0x6020 and I2caRegs.I2CFFRX.all=0x2040.


    So, for multiple data byte  transfer i have to assign I2caRegs.I2CFFTX.all=0x0000 and I2caRegs.I2CFFRX.all=0x0000 values to the following registers?.

    right?.

    Thank you

    Your Faithfully

    Mihir Dave

  • Part Number: TMS320F28069

    Hi,

    I am able to send 4 bytes of data to the EEPROM using this program which contains "HIGH ADDRESS","LOW ADDRESS","1ST DATA","SECOND DATA".

    but now i have to do page write (sending multiple bytes to the eeprom).

    so,please suggest me the modification needed in the program which i have attached below. to send multiple bytes to the EEPROM.

    Thank you.

    /*
     * i2clibrary.c
     *
     *  Created on: Jul 14, 2019
     *      Author: mihir
     */
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    // Note: I2C Macros used in this example can be found in the
    // F2806x_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);
    void pass(void);
    void fail(void);
    #define I2C_SLAVE_ADDR        0x50
    #define I2C_NUMBYTES          4
    #define I2C_EEPROM_HIGH_ADDR  0x00
    #define I2C_EEPROM_LOW_ADDR   0x81
    // 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,
                              0x05,                   // Msg Byte 1
                              0x09};                  // Msg Byte 2
    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;
    void gpioConfig(void);
    Uint16 FailCount;
    int count=0;
    int msg[10]={0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    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 F2806x_SysCtrl.c file.
       gpioConfig();
    // Step 2. Initalize GPIO:
    // This example function is found in the F2806x_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
    
    // 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 F2806x_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 F2806x_DefaultIsr.c.
    // This function is found in F2806x_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;
       EDIS;   // This is needed to disable write to EALLOW protected registers
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in F2806x_InitPeripherals.c
    // InitPeripherals(); // Not required for this example
       I2CA_Init();
    // 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;
       }
    // 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;
    
       /*I2caRegs.I2CSAR = I2C_SLAVE_ADDR;
              I2caRegs.I2CCNT = 4;
              I2caRegs.I2CDXR = 0x00;  // CAL_CFG1 Register
              I2caRegs.I2CDXR = 0x80;  //  bit OUT=1 and bit FT=1
              I2caRegs.I2CDXR = 0x01;
              I2caRegs.I2CDXR = 0x01;
    
    
    
              I2caRegs.I2CMDR.all=0x6EA0;*/
    
       // 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
             // i2c_int1a_isr in this 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)
    {
       // Initialize I2C
       I2caRegs.I2CSAR = 0x0050; // Slave address - EEPROM control code
       I2caRegs.I2CPSC.all = 6;    // 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;
    }
    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;
       // Setup data to send
       I2caRegs.I2CDXR = msg->MemoryHighAddr;
       I2caRegs.I2CDXR = msg->MemoryLowAddr;
       for (i=0; i<msg->NumOfBytes-2; i++)
    //   for (i=0; i<msg->NumOfBytes; i++)
       {
          I2caRegs.I2CDXR = *(msg->MsgBuffer+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 received data
          }
        }
          }
       }  // 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 some error due to invalid interrupt source
          asm("   ESTOP0");
       }
       // Enable future I2C (PIE Group 8) interrupts
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
    }
    
    void gpioConfig(void){
        EALLOW;
    
    
            //GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;   // Enable pull-up for GPIO32 (SDAA)
            //GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;   // Enable pull-up for GPIO33 (SCLA)
    
    
            GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3;  // Asynch input GPIO32 (SDAA)
            GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;  // Asynch input GPIO33 (SCLA)
    
    
            GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1;   // Configure GPIO32 for SDAA
            GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1;   // Configure GPIO33 for SCLA
            SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1;   // I2C
    
            EDIS;
    }
    //===========================================================================
    // No more.
    //=========================
    
    
    
    

  • hi Mihir ,

    If you are looking to not using the FIFO then I2CFFTX / I2CFFRX can be kept 0.

    On reset the I2CFFTX / I2CFFRX registers are 0.

    If you are looking to increase fifo capacity , need to modify bits 4 to 0 of these registers.

    Regards.

  • Hi,

    I have kept  I2CFFTX / I2CFFRX to "0".

    but after than I received MSG STATUS CODE "32 &33" during receiving.

    I have attached the same program below.

    Thank you

    Your Faithfully

    Mihir Dave

    /*
     * i2clibrary.c
     *
     *  Created on: Jul 14, 2019
     *      Author: mihir
     */
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    // Note: I2C Macros used in this example can be found in the
    // F2806x_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);
    void pass(void);
    void fail(void);
    #define I2C_SLAVE_ADDR        0x50
    #define I2C_NUMBYTES          4
    #define I2C_EEPROM_HIGH_ADDR  0x00
    #define I2C_EEPROM_LOW_ADDR   0x81
    // 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,
                              0x05,                   // Msg Byte 1
                              0x09};                  // Msg Byte 2
    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;
    void gpioConfig(void);
    Uint16 FailCount;
    int count=0;
    int msg[10]={0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    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 F2806x_SysCtrl.c file.
       gpioConfig();
    // Step 2. Initalize GPIO:
    // This example function is found in the F2806x_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
    
    // 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 F2806x_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 F2806x_DefaultIsr.c.
    // This function is found in F2806x_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;
       EDIS;   // This is needed to disable write to EALLOW protected registers
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in F2806x_InitPeripherals.c
    // InitPeripherals(); // Not required for this example
       I2CA_Init();
    // 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;
       }
    // 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;
    
       I2caRegs.I2CSAR = I2C_SLAVE_ADDR;
              I2caRegs.I2CCNT = 4;
              I2caRegs.I2CDXR = 0x00;  // CAL_CFG1 Register
              I2caRegs.I2CDXR = 0x80;  //  bit OUT=1 and bit FT=1
              I2caRegs.I2CDXR = 0x01;
              I2caRegs.I2CDXR = 0x01;
    
    
    
    
    
              I2caRegs.I2CMDR.all=0x6EA0;
    
       // 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
             // i2c_int1a_isr in this 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)
    {
       // Initialize I2C
       I2caRegs.I2CSAR = 0x0050; // Slave address - EEPROM control code
       I2caRegs.I2CPSC.all = 6;    // 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;
    }
    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;
       // Setup data to send
       I2caRegs.I2CDXR = msg->MemoryHighAddr;
       I2caRegs.I2CDXR = msg->MemoryLowAddr;
       for (i=0; i<msg->NumOfBytes-2; i++)
    //   for (i=0; i<msg->NumOfBytes; i++)
       {
          I2caRegs.I2CDXR = *(msg->MsgBuffer+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 received data
          }
        }
          }
       }  // 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 some error due to invalid interrupt source
          asm("   ESTOP0");
       }
       // Enable future I2C (PIE Group 8) interrupts
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
    }
    
    void gpioConfig(void){
        EALLOW;
    
    
            //GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;   // Enable pull-up for GPIO32 (SDAA)
            //GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;   // Enable pull-up for GPIO33 (SCLA)
    
    
            GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3;  // Asynch input GPIO32 (SDAA)
            GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;  // Asynch input GPIO33 (SCLA)
    
    
            GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1;   // Configure GPIO32 for SDAA
            GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1;   // Configure GPIO33 for SCLA
            SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1;   // I2C
    
            EDIS;
    }
    //===========================================================================
    // No more.
    //=========================
    
    
    
    

  • I've merged your other thread with this one since it appeared to be a duplicate.

    Are you updating the number of bytes in I2CCNT when you try to send the whole page? I see where you write msg->NumOfBytes to I2C count in your write function, but I don't see where you update this field in your message structure.

    Also, if you use the FIFO, you just need to watch the I2CFFTX.TXFFST field to make sure it isn't too full to take more data before you write to the I2CDXR. If you don't use the FIFO you have to check the I2CSTR.XRDY bit after each byte before writing to I2CDXR.

    Whitney

  • Hi,

    I am updating the number of bytes to be sent at Line.No.18.

    And after assigning more than 4 count(bytes) at Line 18 ,than also only 4 bytes of data are sent to the location,and next data more than 4 bytes are lost.

    Thank you

    Mihir Dave 

  • I see, so you're updating that line and rebuilding the application? That's fine. You still need to address what I said about updating your code to check TXFFST to make sure the FIFO isn't full before you try to add more data too it though.

    Whitney

  • Hi,

    Ok I will implement that also and update you after that.

    Thank you 

    Mihir  Dave

  • Hi,

    I monitored the status of TXFFST,it's showing 6280.

    and could you please tell me at which line of code i should checked the TXFFST status and update new data so that i can send more than four bytes of data.

    I am in a dead end.

    Thank you 

    your faithfully

    Mihir Dave

  • Hi ,

    Were you able to make progress?

    Regards.