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.

CCS/CC3220S-LAUNCHXL: Simultaneous WiFi and I2C

Part Number: CC3220S-LAUNCHXL
Other Parts Discussed in Thread: CC3220S, CC2650

Tool/software: Code Composer Studio

Hi all,

I recently purchased a CC3220S Launchpad hoping to connect a variety of I2C sensors to a database using MQTT. I can run the MQTT code perfectly OR the I2C code perfectly, but not at the same time (the MQTT takes preference). I know that the MQTT, or at least the SimpleLink Task, requires SPI to operate correctly, but I don't understand why I can't use MQTT AND I2C: the I2C_transfer(...) function blocks, or at least never returns. This link, https://e2e.ti.com/support/wireless_connectivity/wilink_wifi_bluetooth/f/307/t/144950 , indicates that simultaneous I2C and WiFi isn't possible, and while I can possibly work my code around the limitation, it seems ridiculous that the datasheet boasts 8 or so peripherals, yet some cannot be used with the chip's main selling point, SimpleLink.

I am new to TI/RTOS coding, so I could very well be overlooking something simple, but please let me know if there is any standard implementation for running both WiFi/SimpleLink and I2C. This isn't a problem on the CC2650, only the CC3220S.

Any help is appreciated. Thank you!

Blake

  • Blake - 

    which example did you start with? 

    from a logic standpoint - without knowing the details of what you have implemented so far, I think you might want to look into what you configured for your subscription topics and subsequent publishing of that topic with its data. 

    you can see an example of this here (using button inputs instead of I2C data, however - but this will give you good foundation here to start from):  

    the Portable + Wi-Fi  and Out-Of-Box examples also show using the I2C temp sensor onboard

    also, another question i had for you is about your system operation expectation. I2C communication is at 100kHz or 400kHz....Wi-Fi is much faster than that and adheres to the 802.11 standard...i think here you might want to consider (from a high level) the Wi-Fi to be a high speed connection medium and the sensor data arriving to be sent out when it can (relative to its speed of communication and if there was any pre-processing of that data before being published ) 

    you may also want to check out (since you said you were new to RTOS environment) :dev.ti.com/.../

  • Josh,

    My main thread function is as follows:

    void mainTask(void* arg0)
    {
        mq_attr q_conf;
    
        if(I2C_Init(Board_I2C0) < 0)
        {
            WAIT_FOREVER;
        }
    
        // TODO Read configuration data from external EEPROM.
    
        if(configureSensor() > 0)
        {
            // TODO Add processing logic on retc bits.
            WAIT_FOREVER;
        }
    
        if(WiFi_Init() < 0)
        {
            WAIT_FOREVER;
        }
    
        if(WiFi_Connect(SSID, KEY) < 0)
        {
            WAIT_FOREVER;
        }
    
        q_conf.mq_maxmsg = 20;
        q_conf.mq_msgsize = sizeof(struct msgQueue);
        Q = mq_open("MSG QUEUE", O_CREAT, 0, &q_conf);
    
        // Need configurable variables to be read in from EEPROM.
        if(MQTT_Init(mqtt_handler, mqtt_delegate, "LAUNCHPAD", "192.168.1.140", 1883) < 0)
        {
            WAIT_FOREVER;
        }
    
        for(;;)
        {
            if(VCNL4200_read(i2cHandle, VCNL4200_PS_DATA))
            {
                PRINT("Bytes Read");  // Macro for easy UART_PRINT plus newline
                char out[32];
                sprintf(out, "0x%02x | 0x%02x", readBuf[0], readBuf[1]);
                PRINT(out);
            } else {
                PRINT("I2C Bus Fault.");
            }
            sleep(5);
        }

    The WiFi and MQTT functions are from the "mqtt_client_CC3220S_LAUNCHXL_tirtos_ccs" sample from the Resource Explorer and the I2C/sensor functions I2C_Init(...), configureSensor(), VCNL4200_read(...), and VCNL4200_config(...) are my I2C wrapper functions that I previously used successfully with the CC2650. If I comment out the the WiFi and MQTT functions (which all are adapted from the above Resource Explorer example), I can use my I2C. If I run the code as is, I can use the MQTT perfectly, but the code will never step past if(VCNL4200_read(i2cHandle, VCNL4200_PS_DATA)). There is no communication between MQTT and I2C yet because I cannot run I2C alongside MQTT. My I2C is configured in blocking mode running at 100 kHz. My suspicion is that both the I2C and SimpleLink implementations are interrupt-based, therefore creating some precedence conflict or race condition?

    I'll look at those examples you mentioned and see if they add any other insight. Thank you for your quick reply!

    All the best,

    Blake

  • I solved the problem, although it isn't ideal. I split the WiFi/MQTT and I2C on to two different threads spawned from the main function:

    void mainTask(void* arg0)
    {
        if(I2C_Init(Board_I2C0) < 0)
        {
            WAIT_FOREVER;
        }
    
        // TODO Read configuration data from external EEPROM.
    
        if(configureSensor() > 0)
        {
            // TODO Add processing logic on retc bits.
            WAIT_FOREVER;
        }
    
        for(;;)
        {
            if(VCNL4200_read(i2cHandle, VCNL4200_PS_DATA))
            {
                PRINT("Bytes Read");
                char out[32];
                sprintf(out, "0x%02x | 0x%02x", readBuf[0], readBuf[1]);
                PRINT(out);
            } else {
                PRINT("I2C Bus Fault.");
            }
            sleep(5);
        }
    }
    
    void wifi_thread()
    {
        mq_attr q_conf;
    
        if(WiFi_Init() < 0)
        {
            WAIT_FOREVER;
        }
    
        if(WiFi_Connect(SSID, KEY) < 0)
        {
            WAIT_FOREVER;
        }
    
        q_conf.mq_maxmsg = 20;
        q_conf.mq_msgsize = sizeof(struct msgQueue);
        Q = mq_open("MSG QUEUE", O_CREAT, 0, &q_conf);
    
        // Need configurable variables to be read in from EEPROM.
        if(MQTT_Init(mqtt_handler, mqtt_delegate, "LAUNCHPAD", "192.168.1.140", 1883) < 0)
        {
            WAIT_FOREVER;
        }
    }

    I say it isn't ideal since I need to be able to read in the WiFi configuration (SSID & KEY) from external EEPROM, but I guess I can use global variables & semaphores to communicate between the threads. 

    Thanks again for your help!

    Blake