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.

TMS320F28379S: F2837xS Peripheral Driver Library - I2C Module Example needed

Part Number: TMS320F28379S
Other Parts Discussed in Thread: C2000WARE

C2000 champs, please find message from my customer below and provide an example close to the specification he needs.

I am working with F28377S microcontroller,

 

I have some questions about i2c Module, because I can´t configure it properly (Configuration for send data to display).

 

I need:

  • Microcontroller must be the Master device.
  • Microcontroller must be send data /Start – data (With slave address) – Stop/ bytes to slave device.
  • i2c data must be send when the function is call (Without interruptions).

 

In the examples that is provide with c2000 or Control suite this case is not contemplated (Examples with interruptions).

 

In my example the microcontroller only send the slave address to i2c bus (without data), I don’t know why.

 

I tried with many i2c configurations but the result is the same.

 

 

  • Raul,

    One more idea I can give is, you can look at the I2C Boot code in the device boot ROM sources provided for your device. They are available in C200ware at below location. Look for I2C_Boot.c, the I2C boot in ROM implements I2C Master mode and reads the application hex file from EEPROM and doesn't use interrupts. Also refer to the device boot ROM chapter of TRM if you want to further understand the I2C Boot.

    C:\ti\c2000\C2000Ware_1_00_02_00\libraries\boot_rom\f2837xs\revB\rom_sources\F2837x_bootROM\cpu01-bootROM\source

    The I2C Boot is EEPROM read only and doesn't provide a Write to EEPROM. For this you will have to adapt the example 9C:\ti\c2000\C2000Ware_1_00_02_00\device_support\f2837xs\examples\cpu1\i2c_eeprom) yourself.

    Alternatively, You can start with the I2C EEPROM provided example in C200Ware (C:\ti\c2000\C2000Ware_1_00_02_00\device_support\f2837xs\examples\cpu1\i2c_eeprom), try to get it working with the interrupts enabled using the example as it is.

    If you don't want to use interrupts , you can still start with the example but instead of enabling the interrupts at PIE level, you can poll for the PIE flags and gradually modify the code to poll the interrupt status bit in the I2C module.

    Hope this helps.

    Best regards
    Santosh Ahturu
  • Hi Santosh Athuru,

    I modified the EEPROM example, but the i2c output is wrong (Only Slave adress).

    i2c output:

    [0xA0-][0xA0-][0xA0-][0xA0-][0xA0-][0xA0-][0xA0-][0xA0-][0xA0-][0xA0-][0xA0-]

    [ = Start

    ] = Stop

    - = NACK

    i2c_ex2_eeprom.c  is attached.

    Can you help me?

    I only need send information to i2c bus.

    //#############################################################################
    //
    // FILE:   i2c_ex2_eeprom.c
    //
    // TITLE:  I2C EEPROM
    //
    //! \addtogroup driver_example_list
    //! <h1>I2C EEPROM</h1>
    //!
    //! 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, i2cMsgOut. The data read back will be contained in the message
    //! structure i2cMsgIn.
    //!
    //! \b External \b Connections \n
    //!  - Connect external I2C EEPROM at address 0x50
    //!  - Connect GPIO32/SDAA to external EEPROM SDA (serial data) pin
    //!  - Connect GPIO33/SCLA to external EEPROM SCL (serial clock) pin
    //!
    //! \b Watch \b Variables \n
    //!  - \b i2cMsgOut - Message containing data to write to EEPROM
    //!  - \b i2cMsgIn - Message containing data read from EEPROM
    //!
    //
    //#############################################################################
    // $TI Release: F2837xS Support Library v3.02.00.00 $
    // $Release Date: Sat Sep 16 15:30:24 CDT 2017 $
    // $Copyright:
    // Copyright (C) 2014-2017 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //#############################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    
    //
    // Defines
    //
    #define SLAVE_ADDRESS               0x50
    #define EEPROM_HIGH_ADDR            0x00
    #define EEPROM_LOW_ADDR             0x30
    #define NUM_BYTES                   8
    #define MAX_BUFFER_SIZE             14      // Max is currently 14 because of
                                                // 2 address bytes and the 16-byte 
                                                // FIFO
    
    //
    // I2C message states for I2CMsg struct
    //
    #define MSG_STATUS_INACTIVE         0x0000 // Message not in use, do not send
    #define MSG_STATUS_SEND_WITHSTOP    0x0010 // Send message with stop bit
    #define MSG_STATUS_WRITE_BUSY       0x0011 // Message sent, wait for stop
    #define MSG_STATUS_SEND_NOSTOP      0x0020 // Send message without stop bit
    #define MSG_STATUS_SEND_NOSTOP_BUSY 0x0021 // Message sent, wait for ARDY
    #define MSG_STATUS_RESTART          0x0022 // Ready to become master-receiver
    #define MSG_STATUS_READ_BUSY        0x0023 // Wait for stop before reading data
    
    //
    // Error messages for read and write functions
    //
    #define ERROR_BUS_BUSY              0x1000
    #define ERROR_STOP_NOT_READY        0x5555
    #define SUCCESS                     0x0000
    
    //
    // Typedefs
    //
    struct I2CMsg 
    {
        uint16_t msgStatus;                  // Word stating what state msg is in.
                                             // See MSG_STATUS_* defines above.
        uint16_t slaveAddr;                  // Slave address tied to the message.
        uint16_t numBytes;                   // Number of valid bytes in message.
        uint16_t memoryHighAddr;             // EEPROM address of data associated
                                             // with message (high byte).
        uint16_t memoryLowAddr;              // EEPROM address of data associated
                                             // with message (low byte).
        uint16_t msgBuffer[MAX_BUFFER_SIZE]; // Array holding message data.
    };
    
    //
    // Globals
    //
    struct I2CMsg i2cMsgOut = {MSG_STATUS_SEND_WITHSTOP,
                               SLAVE_ADDRESS,
                               NUM_BYTES,
                               EEPROM_HIGH_ADDR,
                               EEPROM_LOW_ADDR,
                               0x01,                // Message bytes
                               0x23,
                               0x45,
                               0x67,
                               0x89,
                               0xAB,
                               0xCD,
                               0xEF};
    struct I2CMsg i2cMsgIn  = {MSG_STATUS_SEND_NOSTOP,
                               SLAVE_ADDRESS,
                               NUM_BYTES,
                               EEPROM_HIGH_ADDR,
                               EEPROM_LOW_ADDR};
    
    struct I2CMsg *currentMsgPtr;                   // Used in interrupt
    
    uint16_t passCount = 0;
    uint16_t failCount = 0;
    
    //
    // Function Prototypes
    //
    void initI2C(void);
    uint16_t readData(struct I2CMsg *msg);
    uint16_t writeData(struct I2CMsg *msg);
    
    void fail(void);
    void pass(void);
    
    __interrupt void i2cAISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        uint16_t error;
        uint16_t i;
    
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pullups.
        //
        Device_initGPIO();
    
        //
        // Initialize GPIOs 32 and 33 for use as SDA A and SCL A respectively
        //
        GPIO_setPinConfig(GPIO_42_SDAA);
        GPIO_setPadConfig(42, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(42, GPIO_QUAL_ASYNC);
    
        GPIO_setPinConfig(GPIO_43_SCLA);
        GPIO_setPadConfig(43, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(43, GPIO_QUAL_ASYNC);
    
        //
        // Initialize PIE and clear PIE registers. Disable CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Interrupts that are used in this example are re-mapped to ISR functions
        // found within this file.
        //
        Interrupt_register(INT_I2CA, &i2cAISR);
    
        //
        // Set I2C use, initializing it for FIFO mode
        //
        initI2C();
    
        //
        // Clear incoming message buffer
        //
        for (i = 0; i < MAX_BUFFER_SIZE; i++)
        {
            i2cMsgIn.msgBuffer[i] = 0x0000;
        }
    
        //
        // Set message pointer used in interrupt to point to outgoing message
        //
        currentMsgPtr = &i2cMsgOut;
    
        //
        // Enable interrupts required for this example
        //
        Interrupt_enable(INT_I2CA);
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // Loop indefinitely
        //
        while(1)
        {
            //
            // **** 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(i2cMsgOut.msgStatus == MSG_STATUS_SEND_WITHSTOP)
            //{
                //
                // Send the data to the EEPROM
                //
                error = writeData(&i2cMsgOut);
    
                //
                // 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. See the
                // function i2cAISR().
                //
                if(error == SUCCESS)
                {
                    currentMsgPtr = &i2cMsgOut;
                    i2cMsgOut.msgStatus = MSG_STATUS_WRITE_BUSY;
                }
            //}
    
            /*
    
            //
            // **** Read data from EEPROM section ****
            //
            // Check outgoing message status. Bypass read section if status is
            // not inactive.
            //
            if (i2cMsgOut.msgStatus == MSG_STATUS_INACTIVE)
            {
                //
                // Check incoming message status
                //
                if(i2cMsgIn.msgStatus == MSG_STATUS_SEND_NOSTOP)
                {
                    //
                    // Send EEPROM address setup
                    //
                    while(readData(&i2cMsgIn) != 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
                        // 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 = &i2cMsgIn;
                    i2cMsgIn.msgStatus = MSG_STATUS_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(i2cMsgIn.msgStatus == MSG_STATUS_RESTART)
                {
                    //
                    // Read data portion
                    //
                    while(readData(&i2cMsgIn) != SUCCESS)
                    {
                        //
                        // Maybe setup an attempt counter to break an infinite
                        // while loop.
                        //
                    }
    
                    //
                    // Update current message pointer and message status
                    //
                    currentMsgPtr = &i2cMsgIn;
                    i2cMsgIn.msgStatus = MSG_STATUS_READ_BUSY;
                }
            }*/
        }
    }
    
    //
    // initI2C - Function to configure I2C A in FIFO mode.
    //
    void
    initI2C()
    {
        //
        // Must put I2C into reset before configuring it
        //
        I2C_disableModule(I2CA_BASE);
    
        //
        // I2C configuration. Use a 50kHz I2CCLK with a 33% duty cycle.
        //
        I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 50000, I2C_DUTYCYCLE_33);
        I2C_setBitCount(I2CA_BASE, I2C_BITCOUNT_8);
        I2C_setSlaveAddress(I2CA_BASE, SLAVE_ADDRESS);
        I2C_setEmulationMode(I2CA_BASE, I2C_EMULATION_FREE_RUN);
    
        //
        // Enable stop condition and register-access-ready interrupts
        //
        I2C_enableInterrupt(I2CA_BASE, I2C_INT_STOP_CONDITION |
                            I2C_INT_REG_ACCESS_RDY);
    
        //
        // FIFO configuration
        //
        I2C_enableFIFO(I2CA_BASE);
        I2C_clearInterruptStatus(I2CA_BASE, I2C_INT_RXFF | I2C_INT_TXFF);
    
        //
        // Configuration complete. Enable the module.
        //
        I2C_enableModule(I2CA_BASE);
    }
    
    //
    // writeData - Function to send the data that is to be written to the EEPROM
    //
    uint16_t
    writeData(struct I2CMsg *msg)
    {
        uint16_t 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(I2C_getStopConditionStatus(I2CA_BASE))
        {
            return(ERROR_STOP_NOT_READY);
        }
    
        //
        // Setup slave address
        //
        I2C_setSlaveAddress(I2CA_BASE, SLAVE_ADDRESS);
    
        //
        // Check if bus busy
        //
        if(I2C_isBusBusy(I2CA_BASE))
        {
            return(ERROR_BUS_BUSY);
        }
    
        //
        // Setup number of bytes to send msgBuffer and address
        //
        I2C_setDataCount(I2CA_BASE, (msg->numBytes + 2));
    
        //
        // Setup data to send
        //
        I2C_putData(I2CA_BASE, msg->memoryHighAddr);
        I2C_putData(I2CA_BASE, msg->memoryLowAddr);
    
        for (i = 0; i < msg->numBytes; i++)
        {
            I2C_putData(I2CA_BASE, msg->msgBuffer[i]);
        }
    
        //
        // Send start as master transmitter
        //
        I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
        I2C_sendStartCondition(I2CA_BASE);
        I2C_sendStopCondition(I2CA_BASE);
    
        return(SUCCESS);
    }
    
    /*
    
    //
    // readData - Function to prepare for the data that is to be read from the EEPROM
    //
    uint16_t
    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(I2C_getStopConditionStatus(I2CA_BASE))
        {
            return(ERROR_STOP_NOT_READY);
        }
    
        //
        // Setup slave address
        //
        I2C_setSlaveAddress(I2CA_BASE, SLAVE_ADDRESS);
    
        //
        // If we are in the the address setup phase, send the address without a
        // stop condition.
        //
        if(msg->msgStatus == MSG_STATUS_SEND_NOSTOP)
        {
            //
            // Check if bus busy
            //
            if(I2C_isBusBusy(I2CA_BASE))
            {
                return(ERROR_BUS_BUSY);
            }
    
            //
            // Send data to setup EEPROM address
            //
            I2C_setDataCount(I2CA_BASE, 2);
            I2C_putData(I2CA_BASE, msg->memoryHighAddr);
            I2C_putData(I2CA_BASE, msg->memoryLowAddr);
            I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
            I2C_sendStartCondition(I2CA_BASE);
        }
        else if(msg->msgStatus == MSG_STATUS_RESTART)
        {
            //
            // Address setup phase has completed. Now setup how many bytes expected
            // and send restart as master-receiver.
            //
            I2C_setDataCount(I2CA_BASE, (msg->numBytes));
            I2C_setConfig(I2CA_BASE, I2C_MASTER_RECEIVE_MODE);
            I2C_sendStartCondition(I2CA_BASE);
            I2C_sendStopCondition(I2CA_BASE);
        }
    
        return(SUCCESS);
    }*/
    
    
    
    //
    // i2cAISR - I2C A ISR (non-FIFO)
    //
    __interrupt void
    i2cAISR(void)
    {
        I2C_InterruptSource intSource;
        uint16_t i;
    
        //
        // Read interrupt source
        //
        intSource = I2C_getInterruptSource(I2CA_BASE);
    
        //
        // Interrupt source = stop condition detected
        //
        if(intSource == I2C_INTSRC_STOP_CONDITION)
        {
            //
            // If completed message was writing data, reset msg to inactive state
            //
            if(currentMsgPtr->msgStatus == MSG_STATUS_WRITE_BUSY)
            {
                currentMsgPtr->msgStatus = MSG_STATUS_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 == MSG_STATUS_SEND_NOSTOP_BUSY)
                {
                    currentMsgPtr->msgStatus = MSG_STATUS_SEND_NOSTOP;
                }
                //
                // If completed message was reading EEPROM data, reset message to
                // inactive state and read data from FIFO.
                //
                else if(currentMsgPtr->msgStatus == MSG_STATUS_READ_BUSY)
                {
                    currentMsgPtr->msgStatus = MSG_STATUS_INACTIVE;
                    for(i=0; i < NUM_BYTES; i++)
                    {
                        currentMsgPtr->msgBuffer[i] = I2C_getData(I2CA_BASE);
                    }
    
                    //
                    // Check received data
                    //
                    for(i=0; i < NUM_BYTES; i++)
                    {
                        if(i2cMsgIn.msgBuffer[i] == i2cMsgOut.msgBuffer[i])
                        {
                            passCount++;
                        }
                        else
                        {
                            failCount++;
                        }
                    }
    
                    if(passCount == NUM_BYTES)
                    {
                        pass();
                    }
                    else
                    {
                        fail();
                    }
                }
            }
        }
        //
        // 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.
        //
        else if(intSource == I2C_INTSRC_REG_ACCESS_RDY)
        {
            //
            // If a NACK is received, clear the NACK bit and command a stop.
            // Otherwise, move on to the read data portion of the communication.
            //
            if((I2C_getStatus(I2CA_BASE) & I2C_STS_NO_ACK) != 0)
            {
                I2C_sendStopCondition(I2CA_BASE);
                I2C_clearStatus(I2CA_BASE, I2C_STS_NO_ACK);
            }
            else if(currentMsgPtr->msgStatus == MSG_STATUS_SEND_NOSTOP_BUSY)
            {
                currentMsgPtr->msgStatus = MSG_STATUS_RESTART;
            }
        }
        else
        {
            //
            // Generate some error from invalid interrupt source
            //
            asm("   ESTOP0");
        }
    
        //
        // Issue ACK to enable future group 8 interrupts
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
    }
    
    //
    // pass - Function to be called if data written matches data read
    //
    void
    pass(void)
    {
        asm("   ESTOP0");
        for(;;);
    }
    
    //
    // fail - Function to be called if data written does NOT match data read
    //
    void fail(void)
    {
        asm("   ESTOP0");
        for(;;);
    }
    
    //
    // End of File
    //
    
    

  • Debug attached: 

    Regards, 

  • Raul,
    were you able to get any reads accomplished? Also check if there is any write protection enabled on I2C slave Pins, before trying writes.
    were you able to use the example as is, without any modification and see the data that you indent to see on the I2C line?

    While we cannot review user code line by line, from your snapshot and your message, what you are saying is the data from message buffer is not translating to the line. Did you verify the I2C_putData functionality? are you seeing the message buffer data getting translated to I2C Data transmit register? It looks like that of I2C_putData is not working as you intend it to, check all of the msg structure initialization as well, but I would start debugging it from that I2C_putData function.

    Also I don't see the I2C_putData function in TI example, defnitely check that function.

    Hope this helps.

    Best regards
    Santosh Athuru

  • Athuru,

    I not need read data, only send.
    Yes, when the example is running, the result is the same (Without data).
    No, only problem is this, the data is not send to i2c buffer (Only slave adress).
    In the TI example is used the same function (I2C_putData) - and the example is not working properly.

    I2C_putData:
    static void I2C_putData ( uint32_t base, uint16_t data ) [inline], [static]
    "Transmits a byte from the I2C".
    "This function places the supplied data into I2C Data Transmit Register".

    Do you have any example of something that are sure that is working properly? (With initialization config and function to send i2c data).

    Regards,
  • Finally i can write i2c bus!!

    Thanks for all!

    Regards,

    Franco Pagani
  • Franco,
    thanks for the update. Can you let us know what fixed the issue and what was the issue?

    Best Regards
    Santosh Athuru
  • Yes, there were some problems, and now i have another problem, may be you can help me.

    Issues:
    1 - When the ACK in the first byte (Address ) is not received, the sw not sent data.
    2 - The sequence to send i2c data in the example is not the adequate to my project.

    New issue:
    The i2c, when the string to send is less than 16 bytes is working properly, but, when the data is major than 16 bytes, the microcontroller not send all bytes to i2c bus. Only send 16 bytes + Adress byte (17 in total).

    My example code (Issue string > 16 bytes):

    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    //
    // Defines
    //
    #define SLAVE_ADDRESS 0x00

    //
    // Globals
    //
    uint16_t sData[40]; // Send data buffer
    uint16_t rDataPoint = 0; // To keep track of where we are in the data stream to check received data
    uint16_t i;
    //
    // Function Prototypes
    //
    void initI2C(void);

    //
    // Main
    //
    void main(void)

    {

    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Disable pin locks and enable internal pullups.
    //
    Device_initGPIO();
    //
    // Initialize GPIOs 42 and 43 for use as SDA A and SCL A respectively
    //
    GPIO_setPinConfig(GPIO_42_SDAA);
    GPIO_setPadConfig(42, GPIO_PIN_TYPE_PULLUP);
    GPIO_setQualificationMode(42, GPIO_QUAL_ASYNC);

    GPIO_setPinConfig(GPIO_43_SCLA);
    GPIO_setPadConfig(43, GPIO_PIN_TYPE_PULLUP);
    GPIO_setQualificationMode(43, GPIO_QUAL_ASYNC);
    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();


    //
    // Set I2C use, initializing it for FIFO mode
    //
    initI2C();

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    //
    // Loop forever.
    //
    while(1)
    {

    I2C_disableModule(I2CA_BASE);
    I2C_clearInterruptStatus(I2CA_BASE, I2C_INT_RXFF | I2C_INT_TXFF);
    I2C_enableModule(I2CA_BASE);

    sData[0]= 0x01;
    sData[1]= 0x02;
    sData[2]= 0x03;
    sData[3]= 0x04;
    sData[4]= 0x05;
    sData[5]= 0x06;
    sData[6]= 0x07;
    sData[7]= 0x08;
    sData[8]= 0xB1;
    sData[9]= 0xB2;
    sData[10]= 0xB3;
    sData[11]= 0xB4;
    sData[12]= 0xB5;
    sData[13]= 0xB6;
    sData[14]= 0xB7;
    sData[15]= 0xB8;
    sData[16]= 0xC1;
    sData[17]= 0xC2;
    sData[18]= 0xC3;
    sData[19]= 0xC4;
    sData[20]= 0xC5;
    sData[21]= 0xC6;
    sData[22]= 0xC7;
    sData[23]= 0xC8;



    I2C_setSlaveAddress(I2CA_BASE, SLAVE_ADDRESS);
    I2C_setDataCount(I2CA_BASE,24);

    for (i = 0; i <24; i++)
    {
    I2C_putData(I2CA_BASE, sData[i]);
    }

    //
    // Send start as master transmitter
    //

    I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
    I2C_sendStopCondition(I2CA_BASE);
    I2C_sendStartCondition(I2CA_BASE);

    DEVICE_DELAY_US(100000);


    }


    }

    //
    // Function to configure I2C A in FIFO mode.
    //
    void initI2C()
    {

    //
    // Must put I2C into reset before configuring it
    //
    I2C_disableModule(I2CA_BASE);

    //
    // I2C configuration. Use a 50kHz I2CCLK with a 33% duty cycle.
    //
    I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 50000, I2C_DUTYCYCLE_33);
    I2C_setBitCount(I2CA_BASE, I2C_BITCOUNT_8);
    I2C_setSlaveAddress(I2CA_BASE, SLAVE_ADDRESS);
    I2C_setEmulationMode(I2CA_BASE, I2C_EMULATION_FREE_RUN);

    //
    // Enable stop condition and register-access-ready interrupts
    //
    I2C_enableInterrupt(I2CA_BASE, I2C_INT_STOP_CONDITION |
    I2C_INT_REG_ACCESS_RDY);

    //
    // FIFO configuration
    //
    I2C_enableFIFO(I2CA_BASE);
    I2C_clearInterruptStatus(I2CA_BASE, I2C_INT_RXFF | I2C_INT_TXFF);

    //
    // Configuration complete. Enable the module.
    //
    I2C_enableModule(I2CA_BASE);

    }


    //
    // End of File
    //


    i2c Output:

    [0x00+0xB1+0xB2+0xB3+0xB4+0xB5+0xB6+0xB7+0xB8+0xC1+0xC2+0xC3+0xC4+0xC5+0xC6+0xC7+0xC8+
  • Franco,

    FRANCO PAGANI said:
    Issues:
    1 - When the ACK in the first byte (Address ) is not received, the sw not sent data.
    2 - The sequence to send i2c data in the example is not the adequate to my project.

    yes on the above the data should be framed as needed or spec'd by the slave device. If salve deivce doesn't understand the data being received then communication will break. It is good progress,  thanks for the update.

    FRANCO PAGANI said:
    New issue:
    The i2c, when the string to send is less than 16 bytes is working properly, but, when the data is major than 16 bytes, the microcontroller not send all bytes to i2c bus. Only send 16 bytes + Adress byte (17 in total).

    On the new issue, see if you can use the Repeat Mode. If your requirement is to keep sending data bytes until SW issues a STOP or new START repeat mode is what you are looking for. Refer to  section 20.3.3 and Table 20-2, 20-3 in TRM for different modes you can use depending on your need.

    Hope this helps.

    Best Regards

    Santosh Athuru

  • Hi Athuru, if i use Repeat mode Stop is sended but only 16 data bytes (last 16).

    data to i2c:

    sData[0]= 0x01;
    sData[1]= 0x02;
    sData[2]= 0x03;
    sData[3]= 0x04;
    sData[4]= 0x05;
    sData[5]= 0x06;
    sData[6]= 0x07;
    sData[7]= 0x08;
    sData[8]= 0xB1;
    sData[9]= 0xB2;
    sData[10]= 0xB3;
    sData[11]= 0xB4;
    sData[12]= 0xB5;
    sData[13]= 0xB6;
    sData[14]= 0xB7;
    sData[15]= 0xB8;
    sData[16]= 0xC1;
    sData[17]= 0xC2;
    sData[18]= 0xC3;
    sData[19]= 0xC4;
    sData[20]= 0xC5;
    sData[21]= 0xC6;
    sData[22]= 0xC7;
    sData[23]= 0xC8;

    i2c output:

    [0x00+0xB1+0xB2+0xB3+0xB4+0xB5+0xB6+0xB7+0xB8+0xC1+0xC2+0xC3+0xC4+0xC5+0xC6+0xC7+0xC8+]

    sequence to send:

    I2C_disableModule(I2CA_BASE);
    //I2C_clearInterruptStatus(I2CA_BASE, I2C_INT_RXFF | I2C_INT_TXFF);
    I2C_enableModule(I2CA_BASE);

    I2C_setSlaveAddress(I2CA_BASE, SLAVE_ADDRESS);
    I2C_setDataCount(I2CA_BASE,24);

    for (i = 0; i <24; i++)
    {
    I2C_putData(I2CA_BASE, sData[i]);
    }

    //
    // Send start as master transmitter
    //

    I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE | I2C_REPEAT_MODE);
    I2C_sendStopCondition(I2CA_BASE);
    I2C_sendStartCondition(I2CA_BASE);

    DEVICE_DELAY_US(100000);

    -----------------------------------------------------------


    Any idea?

    Regards,
  • Franco,
    I haven;t tried this, but try disabling FIFO mode and see if you can write back to back data to the I2C DXR directly in a loop. You can use the ARDY bit to see when you can put the next byte.

    You should be able to use FIFO as well, but once you write 16 bytes (FIFO Length) you should look for ARDY bit to see if FIFO is ready for more data.

    I see that in your while(1) loop you are re-initializing I2C and at the end of 24 bytes loop you are sending a STOP and START. Are you trying to see if all 24 bytes come out before the STOP?

    Also you should enable the transmit and Repeat mode before you put the data in the Data register (or FIFO).

    Best Regards
    Santosh Athuru
  • No, i am only need send all bytes >>> START - ALL BYTES (24 or more) - STOP.

    Yes, FIFO length is 16 bytes.

    How i can implement this options in my code?
  • Which is the correct sequence and i2c configuration to send : START - ALL BYTES (one by one - Number bytes > 16) - STOP ?

    Regards,

    Franco P.
  • Done!!

    I2C_clearStatus is needed.

    Sequence:

    uint16_t i;


    initI2C();


    I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE | I2C_REPEAT_MODE);
    I2C_sendStartCondition(I2CA_BASE);

    for (i = 0; i <num_bytes; i++)
    {
    I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE | I2C_REPEAT_MODE);
    I2C_putData(I2CA_BASE, getdata[i]);
    I2C_clearStatus (I2CA_BASE,I2C_STS_RX_DATA_RDY);
    DEVICE_DELAY_US(10000);
    }

    //
    // Send start as master transmitter
    //

    I2C_sendStopCondition(I2CA_BASE);

    DEVICE_DELAY_US(100000);


    Thanks,

    Regards,

    Franco Pagani
  • Franco,
    thanks for confirming and posting the solution. Let me know if we can close the post.

    Best regards
    Santosh Athuru
  • Yes, you can close the post.

    Thanks for all,

    Regards,