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.

RTOS/CC1310: i2c connect to/ control vl53l0x

Part Number: CC1310

Tool/software: TI-RTOS

I hava a custom board as follow:

I have 2 i2c devices on this board (not sure if this causes the problem), a vl53l0x TOF sensor and a SHT21 temperature and humidity sensor, both with the same sda and scl, hooked up on dio27 and dio28 respectively.

I could make the SHT21 work, i could get the temperature, humidity readings fine, no problem.

However, i couldnt get the vl53l0x TOF sensor to work, I2C_transfer() would return false.

The following is my code snippet:

void *pirThread(void *arg0){
    /* Call driver init functions */
    I2C_init();
    /* Create I2C for usage */
    I2C_Params_init(&i2cParams);
    i2cParams.bitRate = I2C_400kHz;
    i2cParams.transferMode = I2C_MODE_BLOCKING;
    i2c = I2C_open(Board_I2C_TMP, &i2cParams);
    if (i2c == NULL) {
        //Error Initializing I2C
        while (1);
    }

    i2cTransaction.slaveAddress = 0x52; 	//TOF device address

    txBuffer[0] = 0x80;		// index ?
    txBuffer[1] = 0x01;		// data  ?
    i2cTransaction.writeBuf = txBuffer;
    i2cTransaction.writeCount = 2; 			//number of bytes to send
    i2cTransaction.readBuf = rxBuffer; 		//memory location to save read data
    i2cTransaction.readCount = 2; 			//num of bytes to save

	// not working: return false
	if(I2C_transfer(i2c, &i2cTransaction)){
		printf("write success\n");
        res = rxBuffer[0];
	}
	
	
	// the following works as expected:
	i2cTransaction.slaveAddress = 040; 		//SHT21 device address
	txBuffer[0] = SHT21_TEMP_CMD; 			//E3
    i2cTransaction.writeBuf = txBuffer;
    i2cTransaction.writeCount = 1; 			//number of bytes to send
    i2cTransaction.readBuf = rxBuffer; 		//memory location to save read data
    i2cTransaction.readCount = 2; 			//num of bytes to save
    float tempC;
	
    while(1){
        if(I2C_transfer(i2c, &i2cTransaction)){
            tempC = calTemp((rxBuffer[0] << 8) | rxBuffer[1]);
			printf("TempC : %f\n", tempC);
		}
    }

    /* Deinitialized I2C */
    I2C_close(i2c);
}

Any help is appreciated.

  • I would suggest you to use protocol analyzer or scope to check if there is correct signal on SCL/SDA pins when your application calls I2C_transfer.

  • - Since you are able to get the I2C interface working towards a different sensor this is not a issue related to our chip or driver.

    - Check that you use he recommended pull-ups on the lines

    - As YiKai suggested, you have to monitor the lines connected to the sensor and compare them with the sensor datasheet. 

  • Hi there, thanks for your prompt reply.

    I would like to know if there's a way to write data to specific index (reg)? Like in the following snippet from the VL53L0X sample code:

    int32_t VL53L0X_write_multi(uint8_t address, uint8_t reg, uint8_t *pdata, int32_t count)
    {
        int32_t status = STATUS_OK;
    
        unsigned int retries = 3;
        uint8_t *pWriteData    = pdata;
        uint8_t writeDataCount = count;
        uint8_t writeReg       = reg;
        DWORD dwWaitResult;
    #ifdef VL53L0X_LOG_ENABLE
        int32_t i = 0;
        char value_as_str[VL53L0X_MAX_STRING_LENGTH_PLT];
        char *pvalue_as_str;
    #endif
    
        /* For multi writes, the serial comms dll requires multiples 4 bytes or
         * anything less than 4 bytes. So if an irregular size is required, the
         * message is broken up into two writes.
         */
        if((count > 4) && (count % 4 != 0))
        {
            writeDataCount = 4*(count/4);
            status = VL53L0X_write_multi(address, writeReg, pWriteData, writeDataCount);
    
            if(status != STATUS_OK)
            {
                SERIAL_COMMS_Get_Error_Text(debug_string);
            }
            writeReg = reg + writeDataCount;
            pWriteData += writeDataCount;
            writeDataCount = count - writeDataCount;
        }
    
    #ifdef VL53L0X_LOG_ENABLE
    
        pvalue_as_str =  value_as_str;
    
        for(i = 0 ; i < count ; i++)
        {
            sprintf(pvalue_as_str,"%02X", *(pdata+i));
    
            pvalue_as_str += 2;
        }
        trace_i2c("Write reg : 0x%04X, Val : 0x%s\n", reg, value_as_str);
    #endif
    
        if(status == STATUS_OK)
        {
            dwWaitResult = WaitForSingleObject(ghMutex, INFINITE);
            if(dwWaitResult == WAIT_OBJECT_0)
            {
                do
                {
                    status = SERIAL_COMMS_Write_UBOOT(address, 0, writeReg, pWriteData, writeDataCount);
                    // note : the field dwIndexHi is ignored. dwIndexLo will
                    // contain the entire index (bits 0..15).
                    if(status != STATUS_OK)
                    {
                        SERIAL_COMMS_Get_Error_Text(debug_string);
                    }
                } while ((status != 0) && (retries-- > 0));
                ReleaseMutex(ghMutex);
            }
    
            if(status != STATUS_OK)
            {
                SERIAL_COMMS_Get_Error_Text(debug_string);
            }
        }
    
        return status;
    }

  • I'm not sure what the APIs that is used in this code does so it doesn't help me understanding your requirement. 

    Could you describe what you need from the I2C driver in words? I assume that you have read the driver doc: http://dev.ti.com/tirex/explore/node?node=AOng5xFsavzvQ16.KytQHg__eCfARaV__LATEST 

  • I think I have to write data into specific register/ index for the TOF sensor to work, however I couldnt find any relevant function in the library that could do just that.

  • Hey there, sorry please bear with me, I am new to this I2C thing.

    So, my question would be, how do I put the value of the "Internal Register Address" (shown in image below) into a "I2C_transfer"?

    As far as I know there are only writeBuf, writeCount, readBuf, readCount, slaveAddress, arg, nextPtr in the "I2C_Transaction_" struct.

    typedef struct I2C_Transaction_ {
        void         *writeBuf;    /*!< Pointer to a buffer containing data to be
                                        written. */
        size_t        writeCount;  /*!< Number of bytes to write from the
                                        \p writeBuf. */
        void         *readBuf;     /*!< Pointer to a buffer to store data read. */
        size_t        readCount;   /*!< Number of bytes to be read from the slave */
    
        uint_least8_t slaveAddress; /*!< Address of the I2C slave peripheral. */
    
        void         *arg;         /*!< Optional application argument. This argument
                                        will be passed to the callback function
                                        specified by #I2C_Params.transferCallbackFxn
                                        when using #I2C_MODE_CALLBACK. */
        void         *nextPtr;     /*!< This value is used internally by the driver
                                        and must never be modified by the
                                        application. */
    } I2C_Transaction;

  • If you look at the example here: http://dev.ti.com/tirex/explore/node?node=AJWPglhefns2RXGXTeD9QQ__eCfARaV__LATEST this is the first byte in the txbuffer. 

  • Meaning that if I were to send 0x01 to 0x80 register I could do it like this:

        txBuffer[0] = 0x80;     
        txBuffer[1] = 0x01;     
        i2cTransaction.writeBuf = txBuffer;
        i2cTransaction.writeCount = 2;          //number of bytes to send
        i2cTransaction.readBuf = rxBuffer;      //memory location to save read data
        i2cTransaction.readCount = 0;           //num of bytes to save
    
        I2C_transfer(i2c, &i2cTransaction);

    Am I getting this right?

  • Have you tested this and monitored the I2C bus to see if you send data to the sensor in accordance to the sensor datasheet? 

  • How do I monitor the i2C bus? What do I need?

  • See the first reply in this thread.