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.

LAUNCHXL-F280025C: EEPROM AT24Cxx breakout board interface with F280025C

Part Number: LAUNCHXL-F280025C
Other Parts Discussed in Thread: C2000WARE

Hi community, 

I'm working on EEPROM 1 byte write and read using I2C polling method inspired by "i2c_ex2_eeprom" and "i2c_ex4_eeprom_polling" examples of C2000Ware SDK

I tried to run examples of both codes I could not write to or read from the AT24XX breakup board.

So I tried with the below code without bus_scan() with the existing library i2cLib_FIFO_polling in the  i2c_ex4_eeprom_polling example 

can you help me with the flow to configure write and read from the EEPROM

as per my information acquired from the SDK following functions are called in the order please check an update if necessary 

To i2c master function call flow:

I2C_setDataCount();

I2C_setConfig();

I2C_setAddressMode();

I2C_setTargetAddress();

I2C_putData();

I2C_sendStartCondition();

// wait for Tx/Rx data

I2C_sendStopCondition();

Here I attached the code made as simple as possible after this also I'm not able to write or read data from the EEPROM 

#include "driverlib.h"
#include "device.h"
#include "i2cLib_FIFO_polling.h"

//
// Defines
//
#define EEPROM_ADDR 0x50

//
// Globals
//
struct I2CHandle EEPROM;

uint16_t TX_MsgBuffer[MAX_BUFFER_SIZE];
uint16_t RX_MsgBuffer[MAX_BUFFER_SIZE];
uint32_t ControlAddr;
uint16_t status;

void I2C_GPIO_init(void)
{
    // I2CA pins (SDAA / SCLA)
    GPIO_setDirectionMode(DEVICE_GPIO_PIN_SDAA, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_SDAA, GPIO_PIN_TYPE_PULLUP);
    GPIO_setQualificationMode(DEVICE_GPIO_PIN_SDAA, GPIO_QUAL_ASYNC);

    GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCLA, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_SCLA, GPIO_PIN_TYPE_PULLUP);
    GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCLA, GPIO_QUAL_ASYNC);

    GPIO_setPinConfig(DEVICE_GPIO_CFG_SDAA);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_SCLA);
}

void I2Cinit(void)
{
    //myI2CA initialization
    I2C_disableModule(I2CA_BASE);
    I2C_initController(I2CA_BASE, DEVICE_SYSCLK_FREQ, 100000, I2C_DUTYCYCLE_50);
    I2C_setConfig(I2CA_BASE, I2C_CONTROLLER_SEND_MODE);
    I2C_setTargetAddress(I2CA_BASE, 0x50);
//    I2C_setOwnAddress(I2CA_BASE, 96); //I2CA address
    I2C_disableLoopback(I2CA_BASE);
    I2C_setBitCount(I2CA_BASE, I2C_BITCOUNT_8);
    I2C_setDataCount(I2CA_BASE, 2);
    I2C_setAddressMode(I2CA_BASE, I2C_ADDR_MODE_7BITS);
    I2C_enableFIFO(I2CA_BASE);
    I2C_clearInterruptStatus(I2CA_BASE, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
    I2C_setFIFOInterruptLevel(I2CA_BASE, I2C_FIFO_TXEMPTY, I2C_FIFO_RX2);
    I2C_enableInterrupt(I2CA_BASE, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
    I2C_setEmulationMode(I2CA_BASE, I2C_EMULATION_FREE_RUN);
    I2C_enableModule(I2CA_BASE);
}

//
// 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(;;);
}
void verifyEEPROMRead(void)
{
    uint16_t i;
    while(I2C_getStatus(I2CA_BASE) & I2C_STS_BUS_BUSY);

    for(i=0;i<EEPROM.NumOfDataBytes;i++)
    {
        if(RX_MsgBuffer[i] != TX_MsgBuffer[i])
        {
            //Transmitted data doesn't match received data
            //Fail condition. PC shouldn't reach here
            ESTOP0;
            fail();
        }
    }
}
//
// Main
//
void main()
{
    volatile int status = 0;

    uint16_t i;

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

    //
    // Disable pin locks and enable internal pullups.
    //
    Device_initGPIO();

    //
    // Initialize I2C pins
    //
    I2C_GPIO_init();

    //
    // 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();

    I2Cinit();
    EEPROM.TargetAddr      = 0x50;
    EEPROM.base           = I2CA_BASE;
    EEPROM.pControlAddr   = &ControlAddr;
    EEPROM.NumOfAddrBytes = 2;
    EEPROM.pTX_MsgBuffer  = TX_MsgBuffer;
    EEPROM.pRX_MsgBuffer  = RX_MsgBuffer;
    EEPROM.NumOfAttempts  = 5;
    EEPROM.Delay_us       = 10;
    EEPROM.WriteCycleTime_in_us = 6000;    //10ms for EEPROM this code was tested

    //Example 1: EEPROM Byte Write
    //Write 11 to EEPROM address 0x0
    ControlAddr = 0x01;
    EEPROM.NumOfDataBytes = 1;
    TX_MsgBuffer[0]       = 11;

    status = I2C_ControllerTransmitter(&EEPROM);

    //Wait for EEPROM write cycle time
    //This delay is not mandatory. User can run their application code instead.
    //It is however important to wait for EEPROM write cycle time before you initiate
    //another read / write transaction
    DEVICE_DELAY_US(EEPROM.WriteCycleTime_in_us);

    //Example 2: EEPROM Byte Read
    //Make sure 11 is written to EEPROM address 0x0
    ControlAddr = 0x01;
    EEPROM.pControlAddr   = &ControlAddr;
    EEPROM.NumOfDataBytes = 1;
    status = I2C_ControllerReceiver(&EEPROM);

    while(I2C_getStatus(EEPROM.base) & I2C_STS_BUS_BUSY);

    verifyEEPROMRead();
}

correct me if I'm wrong anywhere looking forward to solutions or hints.

In TRM

"START and STOP conditions can be generated by the I2C module when the module is configured to be a master on the I2C bus." 

Q. After which instruction we can observe CLOCK and DATA on the DSO?.

In my case not able to view SCL and SDA for any of the example programs immediately after "void I2Cinit(void)" and "I2C_sendStartCondition(base);" these functions.

Q. Give general steps for I2C debugging from both software and hardware perspective for any TI board. 

Thanks and regards,

Ajaykumar V

  • Hello,

    Please expect delays due to the holidays.

  • Hi Opus Fontillas,

    Happy holidays and I'll wait for the response.

    Q. Which flow is correct above or below one?

    I2C_setDataCount();

    I2C_setConfig();

    I2C_setAddressMode();

    I2C_setTargetAddress();

    I2C_sendStartCondition();

    I2C_putData(); (or) I2C_getData();

    // wait for Tx/Rx data

    I2C_sendStopCondition();

    Q. Is the target address automatically, configured along with the read/write bit, in the I2C_setTargetAddress() function following the invocation of I2C_sendStartCondition(base)?

    Thanks and regards

    Ajaykumar V.

  • Hi Ajaykumar,

    Since the issue is that you cannot see SCL/SDAA, I would suggest taking a look at your I2C and GPIO setup. Specifically, I see that the I2C_setOwnAddress() function has been disabled but is needed to set the own address for the module. The address that is set in this function is then compared to the target address sent by the I2C controller.

    At this point you should be able to scope out the bus accordingly. Your logic for the functions seems correct. I would just note that you have used the I2C_getStatus() inside a while loop after the EEPROM transactions in addition to using it within the verifyEEPROMRead() which could potentially have the program stuck on that line. In addition, the TX_MsgBuffer/RX_MsgBuffer are currently empty when you pass it into the pointers on line 129-130, so I would take a look at i2c_ex4_eeprom_polling example for how to use the buffers

    Aishwarya