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.

I2C on CC2650 - SCL issue

Other Parts Discussed in Thread: OPT3001, CC2650, CC2650STK

I am working on TI RTOS 2.14. My application is on CC2650. I am trying to interface SHT30 using I2C driver. While the I2C driver works fine for the OPT3001 ambient light sensor. I am getting NACK from the sensor when I try to read data from SHT30 sensor. I did some debugging using logic analyzer and found out that the SCL timing is not as per the datasheet. Please find relevant screenshots below: (i tested using arduino wire library and it works, so its not a hardware issue.):

PS: i am using i2c.h and I2CCC26XX.h

The screenshot above shows the correct timing. Notice the time when SDA toggles - it coincides with the falling edge of the SCL. This is also mentioned in the SHT30 datasheet, which says that this time difference should not go over 0.9us ("valid time"):

Below is the screenshot of the I2C signal that is generated using TI RTOS I2C DRIVER. You can notice the difference from the arduino generated signal. The valid time is out of the allowed range according to the datasheet:

Could some TI RTOS expert help me out? How can I fix this timing issue? I am running the I2C code as a task in my code. The priority is highest for this. 

  • *bump*

    Has anyone faced similar issues? Am i missing out something silly? Any help will do - been stuck on this for the last 3 days.
  • Siddharth,

    Can you share your I2C driver configuration and Board files for CC2650? The I2C address defined in board.h have to be updated for the SHT30 peripheral address.  Also, the bit-rate from your logic analyzer for CC2650 is set at 100KHz which differs from your Arduino setup.  The TI-RTOS I2C driver supports two bit rate modes: 100kHz and 400kHz. Have you tried the 400kHz mode since the peripheral supports fast mode?

    Vikram

  • Hello Siddharth,

    We haven't heard from you. Is the issue resolved?

    Vikram
  • Hello Vikram,

    The problem isnt solved yet. I tried again with TI RTOS 2.16, please find attached board files and the i2c driver configuration below: 

    uint8_t rxBuffer3[6];

       uint8_t txBuffer3[] = {0x24,0x00};

       I2C_Handle      i2cHandle;

       I2C_Params      i2cParams;

       I2C_Transaction i2cTransaction;

       //I2C_Transaction readTransaction;

       /* Create I2C for usage */

       I2C_Params_init(&i2cParams);

       i2cParams.bitRate = I2C_400kHz;

       i2cParams.transferMode = I2C_MODE_BLOCKING;

       i2cParams.transferCallbackFxn = NULL;

       i2cHandle = I2C_open(CC2650_LAUNCHXL_I2C0, &i2cParams);

           if (i2cHandle == NULL) {

               System_abort("Error Initializing I2C\n");

           }

           else {

               System_printf("I2C Initialized!\nValue of handle %d \n", i2cHandle);

               System_flush();

           }

               i2cTransaction.slaveAddress = SHT30_SLAVE_ADDRESS;

               i2cTransaction.writeBuf = txBuffer3;

               i2cTransaction.writeCount = 2;

               i2cTransaction.readBuf = rxBuffer3;

               i2cTransaction.readCount = 6;

               //System_printf("pre \n");

               //System_flush();

        int i = 0;

        for(i = 0 ; i < 20 ; i++) {

        if(I2C_transfer(i2cHandle, &i2cTransaction)){

        System_printf("Success\n");

        System_flush();

        }

        else{

        System_printf("bus fault\n");

        System_flush();}

        }

           Task_sleep(1000000);

    I2C_close(i2cHandle);

    //end of code

    The output shows "bus fault". please also note that same code works for opt3001 by changing device address and tx data. 

    0552.CC2650_LAUNCHXL.h

    2553.CC2650_LAUNCHXL.c

    1805.Board.h

  • Hi

    could it be that you are misinterpreting the data sheet? SDA valid time appears to be a guarantee made by the SHT30, not a requirement (DATA OUT in the diagram). It seems to say that when the SHT30 is asked to output the next bit, it will do so after at most 900 ns. On the other hand, the SHT30 also requires a certain hold time (t_{HD;DAT}) which may very possibly be violated in your Arduino example. I like the TI signal a lot better, as it balances setup and hold time requirements by putting the SDA changes right in the middle of a SCL-low period.
  • Hi Markus,

    That does make sense. But then it confuses me even more why the SHT30 is not responding when other sensors are. And it is responding even with the arduino. I believe I have followed all the steps required to initialize, configure, and use the I2C driver. Any ideas?
  • Markus,

    As an additional input, if you look at the screenshots in the original question above - look at SCL, in the arduino code the ON/OFF period is same. But in the TI generated signal, the SCL signal is not consistent, as is visible in the screenshot. Could this be a problem?

    As background of the code - I put the I2C code in the heartbeat task of the empty (minimal example) - I remove the heartbeat code and replace with my I2C code.
  • Could any expert from TI here look into this?

    I have tried many versions of TI RTOS and CC26XXWARE. I can not locate the source of this bug. I have followed all the configuration steps in the documentation provided by TI. The most surprising part is that OPT3001 works perfectly fine with my code. I do not understand why SHT30 doesnt respond when polled from CC2650.
  • Is your hardware wiring ok? The SHT30 supports switching its address between 0x45 and 0x44 using the ADDR pin. Is that pin always connected to VDD? What about nRESET?

  • Markus,

    The hardware wiring is fine because the sensor responds when we use Arduino SHT3X library. We have used 0x45 as address by hardwiring VDD to the ADDR pin. We have connected nRESET on VDD as we do not use it - as mentioned in the datasheet. Although even if nRESET is left unconnected, the sensor responds using Arduino.

    PS: On the same board we have OPT3001 with 0x44 address. It works fine and responds reliably.
  • Did you issue any write command prior to the read that you show? When a read is issued, the SHT30 will apparently send NACK if it has no data to send. I know you say that the response is fine with the Arduino library, but maybe there is some other difference in your code?

    Also, how did you set up your logic analyzer? I am asking because to me both I2C requests look the same (read from 0x45).

  • Hi,

    I am working with CC2650 to access, by I2C, the MAXIM 30100 HeartRate chip and I had problems to use I2C with sensortag CC2650 too.  The SCL is correct but the function "I2C_transfer()"  it i s not sending all data inside the buffer. Only the first one because the I2C driver is writing a slave address 0x5C always in front my correct ID address data 0xAE. Until now I did not get to access the MAXIM CI.  The function I2C_transfer() is not increasing the buffer automatically and it is not send the slave ID address 0xAE.

    My  C code is similar to your. I think that I2C SensorTag driver is prepared to work only with onboard sensors. The 0x5C in front my data stream is blocking my access to MAXIM.

     Did you have success in your test ? 

    /********** My code ***********/

    bool transferir()

    {

      // Store new slave address

      I2C_Transaction i2cTrans;

      I2C_Handle handle;

      I2C_Params params;

      unsigned char i;

      unsigned char buffer1[9];

       buffer1[0] = 0x01;

       buffer1[1] = INTENABLEREG;

       buffer1[2] = 0xF0;

       buffer1[3] = ADDCONF;

       buffer1[4] = (MODEUSED + SP2ENABLE + TEMPENABLE);

       buffer1[5] = SP02_CONF_REG;

       buffer1[6] = (SP02REG + LEDPW_200 + SP02SR_200);

       buffer1[7] = LED_CONF_REG;

       buffer1[8] = (LEDREG + REDPA11_0MA +  IRPA11_0MA);

       I2C_Params_init(&params);

       //params.transferMode = I2C_MODE_CALLBACK;

       params.transferCallbackFxn = writeCallbackDefault;

       params.bitRate = I2C_100kHz;

       handle = I2C_open(CC2650STK_I2C0, &params);

        // Initialize master I2C transaction structure

        i2cTrans.writeCount   = 9;

        i2cTrans.writeBuf     = buffer1;

        i2cTrans.readCount    = 0;

        i2cTrans.readBuf      = rxBuffer;

        i2cTrans.slaveAddress = 0xAE;

    ************* it is a test ******************

    *********** the for() is not necessary if  I2C_transfer() to increase the buffer by itself ********************

           for( i = 0; i < 9; i++)

           {

         // Do I2C transfer (in callback mode)

         if(!I2C_transfer(handle, &i2cTrans))

         {

         PIN_setOutputValue(led1PinHandle, Board_DP2, 1); //Erro

         //return false;

         }else

         PIN_setOutputValue(led1PinHandle, Board_DP3, 1); //Correto

           }

           //System_printf("I2C Initialized!\nValue of handle %d \n", handle);

       I2C_close(handle);

     return true;

    }

  • Hi Carlos,

    This is an old thread. Please start a new thread with your question. Also, provide us with the device name and the software versions that you are using.

    Thanks,
    Vikram