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.

CC2652RB: How to realize I2C slave from empty example

Part Number: CC2652RB


Hi ti:

I am working in simplelink_cc13x2_26x2_sdk_4_30_00_54 with LP_CC2652RB.

I want to realize a I2C slave project, but there is no example in SDK. So I try to do it by dreverlib.

Following is my parts of code, that I call init_i2c() in empty's mainThread().

#include <i2c.h>
#include <ti/drivers/Power.h>
#include <ti/drivers/power/PowerCC26XX.h>
#include <ti/drivers/PIN.h>
#include <ti/drivers/pin/PINCC26XX.h>

#define I2C0_SCL0          IOID_4
#define I2C0_SDA0          IOID_5

void init_i2c(void)
{
    //PRCMPowerDomainOn(PRCM_DOMAIN_PERIPH);
    
    Power_setDependency(PowerCC26XX_PERIPH_I2C0);
    
    //PRCMLoadSet();
    //PRCMPeripheralRunEnable(PRCM_PERIPH_I2C0); // Enable I2C module
    //PRCMPeripheralRunEnable(PRCM_PERIPH_GPIO);
    //PRCMLoadSet();

    I2CSlaveInit(I2C0_BASE, 0x53);
    I2CIntRegister(I2C0_BASE, i2c_callback);
    I2CSlaveIntEnable(I2C0_BASE, I2C_SLAVE_INT_START | I2C_SLAVE_INT_STOP | I2C_SLAVE_INT_DATA);
}

void i2c_callback(void)
{
    uint32_t val;
    uint32_t status = I2CSlaveIntStatus(I2C0_BASE, true);
    I2CSlaveIntClear(I2C0_BASE, status);

    if(status & I2C_SLAVE_INT_DATA)
    {
        status = I2CSlaveStatus(I2C0_BASE);

        if(status & I2C_SLAVE_ACT_RREQ)
        {
            val = I2CSlaveDataGet(I2C0_BASE);
            GPIO_toggle(CONFIG_GPIO_LED_0);
        }
    }
}

However, when I run i2copt3001 example to test the I2C slave project. the red_led dose NOT blink(implicit I2C get some data), but the green_led work normal(implicit mainThread() work well).

So I'm here for asking your help:

1. How to realize a I2C slave by CC2652RB, is there some documents can be referred?

2. In my above code, there is some commented lines like PRCMxxx(), I can't find define of them, where are them?

3. Actually from my code, I am NOT maping the GPIO to I2C since I do not know how to do it. Could you show me how to map the specific GPIO for SCL and SDA function?

Thanks very much for your help!

  • Hi there,

    I have try some code as following and seems work well.

    #include <i2c.h>
    #include <prcm.h>
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerCC26XX.h>
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    
    #define I2C0_SCL0          IOID_4
    #define I2C0_SDA0          IOID_5
    
    void init_i2c(void);
    void i2c_callback(void);
    
    PIN_State i2cPinState;      // Must reside in persistent memory
    
    void init_i2c(void)
    {
        PRCMPowerDomainOn(PRCM_DOMAIN_PERIPH);
    
        // Set Power dependecies & constraints
        Power_setDependency(PowerCC26XX_PERIPH_I2C0);
        Power_setDependency(PowerCC26XX_PERIPH_GPIO);
    
        // Set constraints for Standby, powerdown and idle mode
        Power_setConstraint(PowerCC26XX_SB_DISALLOW);
        Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
    
        PRCMLoadSet();
        PRCMPeripheralRunEnable(PRCM_PERIPH_I2C0); // Enable I2C module
        PRCMPeripheralRunEnable(PRCM_PERIPH_GPIO);
        PRCMLoadSet();
    
        PIN_Config i2cPinTable[] = {
            I2C0_SDA0 | PIN_INPUT_EN | PIN_PULLUP | PIN_OPENDRAIN,
            I2C0_SCL0 | PIN_INPUT_EN | PIN_PULLUP | PIN_OPENDRAIN,
            PIN_TERMINATE
        };
    
        PIN_Handle i2cPinHandle = PIN_open(&i2cPinState, i2cPinTable);
        if (    (PIN_SUCCESS == PINCC26XX_setMux(i2cPinHandle, I2C0_SCL0, IOC_PORT_MCU_I2C_MSSCL)) &&
                (PIN_SUCCESS == PINCC26XX_setMux(i2cPinHandle, I2C0_SDA0, IOC_PORT_MCU_I2C_MSSDA))      )
        {
            DBG_INFO("I2C PIN set succ.");
        } else {
            DBG_INFO("I2C PIN set failed.");
        }
    
        I2CSlaveInit(I2C0_BASE, 0x53);
    
        I2CIntRegister(I2C0_BASE, i2c_callback);
        I2CSlaveIntEnable(I2C0_BASE, I2C_SLAVE_INT_START | I2C_SLAVE_INT_STOP | I2C_SLAVE_INT_DATA);
    }
    
    void i2c_callback(void)
    {
        uint32_t val;
        uint32_t status = I2CSlaveIntStatus(I2C0_BASE, true);
        I2CSlaveIntClear(I2C0_BASE, status);
    
        if(status & I2C_SLAVE_INT_DATA)
        {
            status = I2CSlaveStatus(I2C0_BASE);
    
            if(status & I2C_SLAVE_ACT_RREQ)
            {
                val = I2CSlaveDataGet(I2C0_BASE);
                GPIO_toggle(CONFIG_GPIO_LED_0);
            }
        }
    }

    BTW, I also add include path in properties as below:

    And the PRCMxxx() is reside in simplelink_cc13x2_26x2_sdk_4_30_00_54\source\ti\devices\cc13x2_cc26x2\driverlib.

  • Hi junde,

    Thank you for providing the solution to your issue in detail!

    Regards,
    Ryan

  • Hi Ryan,

    I meet another question about I2C slave project.

    I modify above code to below:

    #include <i2c.h>
    #include <prcm.h>
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerCC26XX.h>
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    
    #define I2C0_SCL0          IOID_4
    #define I2C0_SDA0          IOID_5
    #define SLAVE_ADDR         0x11
    
    void init_i2c(void);
    void i2c_callback(void);
    
    PIN_State i2cPinState;      // Must reside in persistent memory
    volatile uint8_t i2c_read_cnt;
    volatile uint32_t i2c_read_buf[20];
    
    void *mainThread(void *arg0)
    {
        GPIO_init();
        DBG_INIT();
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(CONFIG_GPIO_LED_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_ON);
    
        DBG_INFO("/********** Program Start ***********/");
    
        init_i2c();
    
        while (1) {
            if(i2c_read_cnt != 0)
            {
                GPIO_toggle(CONFIG_GPIO_LED_1);
    
                DBG_INFO("I2C get data: [%d]", i2c_read_cnt);
    
                uint8_t i;
                for(i = 0; i < i2c_read_cnt; i++)
                {
                    DBG_INFO("test1");
    //                DBG_INFO("[%d] = 0x%08x", 0, 0);
    //                DBG_INFO("[%d] = 0x%08x", i, i2c_read_buf[i]);
                }
    
                DBG_INFO("test2");
                i2c_read_cnt = 0;
            }
        }
    }
    
    void init_i2c(void)
    {
        PRCMPowerDomainOn(PRCM_DOMAIN_PERIPH);
    
        // Set Power dependecies & constraints
        Power_setDependency(PowerCC26XX_PERIPH_I2C0);
        Power_setDependency(PowerCC26XX_PERIPH_GPIO);
    
        // Set constraints for Standby, powerdown and idle mode
        Power_setConstraint(PowerCC26XX_SB_DISALLOW);
        Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
    
        PRCMLoadSet();
        PRCMPeripheralRunEnable(PRCM_PERIPH_I2C0); // Enable I2C module
        PRCMPeripheralRunEnable(PRCM_PERIPH_GPIO);
        PRCMLoadSet();
    
        PIN_Config i2cPinTable[] = {
            I2C0_SDA0 | PIN_INPUT_EN | PIN_PULLUP | PIN_OPENDRAIN,
            I2C0_SCL0 | PIN_INPUT_EN | PIN_PULLUP | PIN_OPENDRAIN,
            PIN_TERMINATE
        };
    
        PIN_Handle i2cPinHandle = PIN_open(&i2cPinState, i2cPinTable);
        if (    (PIN_SUCCESS == PINCC26XX_setMux(i2cPinHandle, I2C0_SCL0, IOC_PORT_MCU_I2C_MSSCL)) &&
                (PIN_SUCCESS == PINCC26XX_setMux(i2cPinHandle, I2C0_SDA0, IOC_PORT_MCU_I2C_MSSDA))      )
        {
            DBG_INFO("I2C PIN set succ.");
        } else {
            DBG_INFO("I2C PIN set failed.");
        }
    
        I2CSlaveInit(I2C0_BASE, SLAVE_ADDR);
        I2CIntRegister(I2C0_BASE, i2c_callback);
        I2CSlaveIntEnable(I2C0_BASE, I2C_SLAVE_INT_START | I2C_SLAVE_INT_STOP | I2C_SLAVE_INT_DATA);
    }
    
    void i2c_callback(void)
    {
        i2c_read_cnt = 0;
        uint32_t status = I2CSlaveIntStatus(I2C0_BASE, true);
        I2CSlaveIntClear(I2C0_BASE, status);
    
        if(status & I2C_SLAVE_INT_DATA)
        {
            //status = I2CSlaveStatus(I2C0_BASE);
    
            while( I2CSlaveStatus(I2C0_BASE) & I2C_SLAVE_ACT_RREQ)
            {
                i2c_read_buf[i2c_read_cnt++] = I2CSlaveDataGet(I2C0_BASE);
                GPIO_toggle(CONFIG_GPIO_LED_0);
            }
        }
    }

    When I run i2copt3001 example to test the I2C slave, the XDS110 output as following:

    /********** Program Start ***********/
    I2C PIN set succ.
    I2C get data: [1]
    test2

    YES, there is NO test1 output... I can't understand it, could you help me?

    Thanks!

  • Hi,

    I find that i2c_read_cnt is changed by i2c_callback(), I fix the bug and post at here for your infomation: gitee.com/.../i2c-interactive.git