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.

CC3220SF-LAUNCHXL: Interface 24C02 I2C EEPROM with CC3220SF using ti drivers

Part Number: CC3220SF-LAUNCHXL
Other Parts Discussed in Thread: TMP116

Hi,

I am stuck witn a very simple problem using the CC3220SF-LAUNCHXL LP and 24C02 EEPROM over the I2C line. My job is to write a byte of data at internal memory 0x00 of the I2C EEPROM  and then read it back and display over the UART log. I went through the TMP116 temp sensor example given in the resource explorer and modified the code in the i2ctmp.c . I am facintg problems on the restart condition generation that is needed to set the internal address of the EEPROM (I2C) using a dummy write.

I am using the ti/drivers/I2C.h and I am using I2C_transfer() function to send and read data from the EEPROM. But the write operation and read operations are unsuccessful. The code is given below, any help is appreciated:

/*
 *  ======== i2ctmp116.c ========
 */
#include <stdint.h>
#include <stddef.h>
#include <unistd.h>

/* Driver Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/I2C.h>
#include <ti/display/Display.h>

/* Driver configuration */
#include "ti_drivers_config.h"

#define TASKSTACKSIZE       640

/*
 *  ======== TMP Registers ========
 */

#define _24C64_REG          0x00; // for C64, max reg val is 0b0001111111111111 = 0x1fff
#define _24C64_ADDR         0x50;   // appending 0 before the 7 bit address

static Display_Handle display;

/*
 *  ======== mainThread ========
 */
void *mainThread(void *arg0)
{
    uint16_t        sample;
    uint16_t        temperature;
    uint8_t         txBuffer[3];
    uint8_t         rxBuffer[10];
    I2C_Handle      i2c;
    I2C_Params      i2cParams;
    I2C_Transaction i2cTransaction;

    /* Call driver init functions */
    Display_init();
    GPIO_init();
    I2C_init();

    /* Configure the LED and if applicable, the TMP116_EN pin */
    GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
#ifdef CONFIG_GPIO_TMP116_EN
    GPIO_setConfig(CONFIG_GPIO_TMP116_EN, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);
    /* 1.5 ms reset time for the TMP116 */
    sleep(1);
#endif

    /* Open the HOST display for output */
    display = Display_open(Display_Type_UART, NULL);
    if (display == NULL) {
        while (1);
    }

    /* Turn on user LED */
    GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    Display_printf(display, 0, 0, "Starting the i2c24C64 example\n");

    /* Create I2C for usage */
    I2C_Params_init(&i2cParams);
    i2cParams.bitRate = I2C_100kHz;
    i2c = I2C_open(CONFIG_I2C_TMP, &i2cParams);
    if (i2c == NULL) {
        Display_printf(display, 0, 0, "Error Initializing I2C\n");
        while (1);
    }
    else {
        Display_printf(display, 0, 0, "I2C Initialized!\n");
    }

    /* Common I2C transaction setup */
    i2cTransaction.writeBuf   = txBuffer;
    i2cTransaction.writeCount = 2;
    i2cTransaction.readBuf    = rxBuffer;
    i2cTransaction.readCount  = 0;

    Display_printf(display, 0, 0, "Writing the address 0x00 of EEPROM with data 0x32");
    txBuffer[0] = 0x00;
    txBuffer[1] = '2';
    i2cTransaction.slaveAddress = _24C64_ADDR;
    if (!I2C_transfer(i2c, &i2cTransaction))
    {
        Display_printf(display, 0, 0, "Error. No 24C64 Slave EEPROM found! NACK error");
    }
    Display_printf(display, 0, 0, "Write successful");


    /* Sleep for 1 second */
    sleep(1);



    /*
     * Reading Address set and read data
     */
    i2cTransaction.writeBuf   = txBuffer;
    i2cTransaction.writeCount = 2;
    i2cTransaction.readBuf    = rxBuffer;
    i2cTransaction.readCount  = 10;

    Display_printf(display, 0, 0, "Setting the address of EEPROM = 0x50");
    txBuffer[0] = 0x00;
    txBuffer[1] = 0xA1; // Read I2C chip address of the eeprom

    i2cTransaction.slaveAddress = _24C64_ADDR;
    if (I2C_transfer(i2c, &i2cTransaction))
    {
        Display_printf(display, 0, 0, " 24C02 Slave EEPROM found!");

        for (sample = 0; sample < 10; ++sample)
        {
            temperature = rxBuffer[sample];
             Display_printf(display, 0, 0, "value for read[%d]: %d -- \r", sample, temperature);
        }

    }



    I2C_close(i2c);
    Display_printf(display, 0, 0, "I2C closed!");

    return (NULL);
}

  • Hello,

    Just to make sure the I2C lines are completely isolated from other components, have you removed the I2C jumpers that connect to the temperature sensor?

    Also, I did a quick search on the EEPROM you're using. I see this is a 5V device whereas our GPIOs can be driven up to 3.3V max. Are you using a logic level shifter to interface to the EEPROM?

    Your code at a glimpse looks good assuming you set the correct slave address.

    Jesu

  • Hi Jesu,

    Thanks for your reply. yes I have opened the jumbers on board to the temp sensor and the Acc sensor and connected them to the EEPROM. 

    Yes this eeprom is a 5V eeprom, but it does work on the 3V3 level quite smoothly. I have been using this chip for almost 15 years on 3V3 line now and it has no complaints.

    Yes. The slave address I have used looks good. This is because the datasheet of the eeprom says the slave addr. is 1010 A2 A1 A0 (where Ax are the hard wired address lines that are now connected to ground). So in my case the address will be 1010000 and appending a 0 gives me 01010000 = 0x50. And for read operations it is directly sent as a data which I have put as 10100001 (the last bit is the R/W' = 1 for read case) = 0xA1.

    I just wanted to know that the I2C TI drivers for TI RTOS 2.2 has some special function for repeated start use cases or is it that it has to be sent just as a new I2C transaction data stream separately ?

    Thanks again for your help !

  • Hi,

    I seemed to have found a solution to this now. I have tested a write to 5 consecutive writes to adjacent memory locations from 0x10 to 0x14 with values 0x01, 0x02, 0x03, 0x04 and 0x05. That is a sequential write. Then I am reading from the same memory locations alongwith more adjacent memory locations upto 0x19. As the output shows, the outputs read from memory locations 0x10 to 0x14 are those that were written. But the values in the remaing memory areas from 0x15 to 0x19 are unwritten values 0xff existing inside a fresh eeprom. The code and the output are given below:

    /*
     * Copyright (c) 2018-2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * 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.
     */
    
    /*
     *  ======== i2ctmp116.c ========
     */
    #include <stdint.h>
    #include <stddef.h>
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/I2C.h>
    #include <ti/display/Display.h>
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    #define TASKSTACKSIZE       640
    
    /*
     *  ======== 24C02 Registers ========
     */
    
    #define _24C64_REG          0x10; // for C64, max reg val is 0b0001111111111111 = 0x1fff
    #define _24C64_ADDR         0x50;   // appending 0 before the 7 bit address
    
    static Display_Handle display;
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        uint16_t        sample;
        uint16_t        temperature;
        uint8_t         txBuffer[10];
        uint8_t         rxBuffer[10];
        I2C_Handle      i2c;
        I2C_Params      i2cParams;
        I2C_Transaction i2cTransaction;
    
        /* Call driver init functions */
        Display_init();
        GPIO_init();
        I2C_init();
    
        /* Configure the LED and if applicable, the TMP116_EN pin */
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    #ifdef CONFIG_GPIO_TMP116_EN
        GPIO_setConfig(CONFIG_GPIO_TMP116_EN, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);
        /* 1.5 ms reset time for the TMP116 */
        sleep(1);
    #endif
    
        /* Open the HOST display for output */
        display = Display_open(Display_Type_UART, NULL);
        if (display == NULL) {
            while (1);
        }
    
        /* Turn on user LED */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
        Display_printf(display, 0, 0, "Starting the i2c24C64 example\n");
    
        /* Create I2C for usage */
        I2C_Params_init(&i2cParams);
        i2cParams.bitRate = I2C_100kHz;
        i2c = I2C_open(CONFIG_I2C_TMP, &i2cParams);
        if (i2c == NULL) {
            Display_printf(display, 0, 0, "Error Initializing I2C\n");
            while (1);
        }
        else {
            Display_printf(display, 0, 0, "I2C Initialized!\n");
        }
    
        /* Common I2C transaction setup */
        i2cTransaction.writeBuf   = txBuffer;
        i2cTransaction.writeCount = 6;
        i2cTransaction.readBuf    = rxBuffer;
        i2cTransaction.readCount  = 0;
    
        Display_printf(display, 0, 0, "Writing the address 0x0000 of EEPROM = 0x32");
        txBuffer[0] = _24C64_REG;
        txBuffer[1] = 0x01;
        txBuffer[2] = 0x02;
        txBuffer[3] = 0x03;
        txBuffer[4] = 0x04;
        txBuffer[5] = 0x05;
        i2cTransaction.slaveAddress = _24C64_ADDR;
        if (!I2C_transfer(i2c, &i2cTransaction))
        {
            Display_printf(display, 0, 0, "Error. No 24C64 Slave EEPROM found! NACK error");
        }
        Display_printf(display, 0, 0, "Write successful");
    
    
        /* Sleep for 1 second */
        sleep(1);
    
    
    
        /*
         * Reading Address set and read data
         */
        Display_printf(display, 0, 0, "Read part... \r");
    
        i2cTransaction.writeBuf   = txBuffer;
        i2cTransaction.writeCount = 1;
        i2cTransaction.readBuf    = rxBuffer;
        i2cTransaction.readCount  = 0;
        txBuffer[0] = _24C64_REG;
        i2cTransaction.slaveAddress = _24C64_ADDR;
        if (!I2C_transfer(i2c, &i2cTransaction))
        {
            Display_printf(display, 0, 0, "Error...");
        }
    
    
    
        i2cTransaction.writeBuf   = txBuffer;
        i2cTransaction.writeCount = 1;
        i2cTransaction.readBuf    = rxBuffer;
        i2cTransaction.readCount  = 10;
    
    
       //
        txBuffer[1] = 0xA1;
    
        i2cTransaction.slaveAddress = _24C64_ADDR;
        if (I2C_transfer(i2c, &i2cTransaction))
        {
            Display_printf(display, 0, 0, " 24C02 Slave EEPROM found!");
    
            for (sample = 0; sample < 10; ++sample)
            {
                temperature = rxBuffer[sample];
                 Display_printf(display, 0, 0, "value for read[%d]: %x H \r", sample, temperature);
            }
    
        }
    
    
    
        I2C_close(i2c);
        Display_printf(display, 0, 0, "I2C closed!");
    
        return (NULL);
    }
    

    And here is the output from the UART console:

    Starting the i2c24C64 example<\n><\r>
    <\r>
    <\n><\r>
    I2C Initialized!<\n><\r>
    <\r>
    <\n><\r>
    Writing the address 0x0000 of EEPROM = 0x32<\r>
    <\n><\r>
    Write successful<\r>
    <\n><\r>
    Read part... <\r>
    <\r>
    <\n><\r>
    24C02 Slave EEPROM found!<\r>
    <\n><\r>
    value for read[0]: 1 H <\r>
    <\r>
    <\n><\r>
    value for read[1]: 2 H <\r>
    <\r>
    <\n><\r>
    value for read[2]: 3 H <\r>
    <\r>
    <\n><\r>
    value for read[3]: 4 H <\r>
    <\r>
    <\n><\r>
    value for read[4]: 5 H <\r>
    <\r>
    <\n><\r>
    value for read[5]: ff H <\r>
    <\r>
    <\n><\r>
    value for read[6]: ff H <\r>
    <\r>
    <\n><\r>
    value for read[7]: ff H <\r>
    <\r>
    <\n><\r>
    value for read[8]: ff H <\r>
    <\r>
    <\n><\r>
    value for read[9]: ff H <\r>
    <\r>
    <\n><\r>
    I2C closed!<\r>
    <\n><\r>