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/CC2640: Sensor controller studio + I2C + time of flight sensor VL6180x

Part Number: CC2640
Other Parts Discussed in Thread: ENERGIA, CC3200, SYSBIOS

Tool/software: Code Composer Studio

Hi,

I am trying to interface I2C time of flight sensor to CC2640. But I am not getting the proper data.

I have interface this sensor with CC3200 with pololu energia library. But I can't interface that with CC2640.

I have connected I2C to SDA to IOID_0 and  SCL to IOID_1. Below is the code for it, if someone has solution for this please guide me.

/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/System.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Task.h>

/* TI-RTOS Header files */
#include <ti/drivers/PIN.h>
#include <ti/drivers/I2C.h>
#include <ti/drivers/UART.h>

/* Example/Board Header files */
#include "Board.h"

#define TASKSTACKSIZE       1024
#define TMP007_OBJ_TEMP     0x0003  /* Object Temp Result Register */

#define BoostEn IOID_9
/* Global memory storage for a PIN_Config table */
static PIN_State ledPinState;

/*
 * Application LED pin configuration table:
 *   - All LEDs board LEDs are off.
 */
PIN_Config ledPinTable[] = {
    Board_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    Board_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    BoostEn | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    PIN_TERMINATE
};
PIN_Handle ledPinHandle;
Task_Struct task0Struct;
Char task0Stack[TASKSTACKSIZE];


UART_Handle uart;
UART_Params uartParams;
//const char echoPrompt[] = "\fEchoing characters:\r\n";


uint8_t Read (uint8_t Reg[1]);
int Write (int16_t Reg[1],int16_t data[1]);

//uint8_t       txBuffer[2];
int16_t txBuffer[2];
uint8_t         rxBuffer[2];
I2C_Handle      i2c;
I2C_Params      i2cParams;
I2C_Transaction i2cTransaction;

#define DeviceAddr 0x29

int done=0;
// RANGE_SCALER values for 1x, 2x, 3x scaling - see STSW-IMG003 core/src/vl6180x_api.c (ScalerLookUP[])
static uint16_t const ScalerValues[] = {0, 253, 127, 84};

uint8_t address;
uint8_t scaling;
uint8_t ptp_offset;
uint16_t io_timeout;
int did_timeout;

// register addresses
   enum regAddr
   {
     IDENTIFICATION__MODEL_ID              = 0x000,
     IDENTIFICATION__MODEL_REV_MAJOR       = 0x001,
     IDENTIFICATION__MODEL_REV_MINOR       = 0x002,
     IDENTIFICATION__MODULE_REV_MAJOR      = 0x003,
     IDENTIFICATION__MODULE_REV_MINOR      = 0x004,
     IDENTIFICATION__DATE_HI               = 0x006,
     IDENTIFICATION__DATE_LO               = 0x007,
     IDENTIFICATION__TIME                  = 0x008, // 16-bit

     SYSTEM__MODE_GPIO0                    = 0x010,
     SYSTEM__MODE_GPIO1                    = 0x011,
     SYSTEM__HISTORY_CTRL                  = 0x012,
     SYSTEM__INTERRUPT_CONFIG_GPIO         = 0x014,
     SYSTEM__INTERRUPT_CLEAR               = 0x015,
     SYSTEM__FRESH_OUT_OF_RESET            = 0x016,
     SYSTEM__GROUPED_PARAMETER_HOLD        = 0x017,

     SYSRANGE__START                       = 0x018,
     SYSRANGE__THRESH_HIGH                 = 0x019,
     SYSRANGE__THRESH_LOW                  = 0x01A,
     SYSRANGE__INTERMEASUREMENT_PERIOD     = 0x01B,
     SYSRANGE__MAX_CONVERGENCE_TIME        = 0x01C,
     SYSRANGE__CROSSTALK_COMPENSATION_RATE = 0x01E, // 16-bit
     SYSRANGE__CROSSTALK_VALID_HEIGHT      = 0x021,
     SYSRANGE__EARLY_CONVERGENCE_ESTIMATE  = 0x022, // 16-bit
     SYSRANGE__PART_TO_PART_RANGE_OFFSET   = 0x024,
     SYSRANGE__RANGE_IGNORE_VALID_HEIGHT   = 0x025,
     SYSRANGE__RANGE_IGNORE_THRESHOLD      = 0x026, // 16-bit
     SYSRANGE__MAX_AMBIENT_LEVEL_MULT      = 0x02C,
     SYSRANGE__RANGE_CHECK_ENABLES         = 0x02D,
     SYSRANGE__VHV_RECALIBRATE             = 0x02E,
     SYSRANGE__VHV_REPEAT_RATE             = 0x031,

     SYSALS__START                         = 0x038,
     SYSALS__THRESH_HIGH                   = 0x03A,
     SYSALS__THRESH_LOW                    = 0x03C,
     SYSALS__INTERMEASUREMENT_PERIOD       = 0x03E,
     SYSALS__ANALOGUE_GAIN                 = 0x03F,
     SYSALS__INTEGRATION_PERIOD            = 0x040,

     RESULT__RANGE_STATUS                  = 0x04D,
     RESULT__ALS_STATUS                    = 0x04E,
     RESULT__INTERRUPT_STATUS_GPIO         = 0x04F,
     RESULT__ALS_VAL                       = 0x050, // 16-bit
     RESULT__HISTORY_BUFFER_0              = 0x052, // 16-bit
     RESULT__HISTORY_BUFFER_1              = 0x054, // 16-bit
     RESULT__HISTORY_BUFFER_2              = 0x056, // 16-bit
     RESULT__HISTORY_BUFFER_3              = 0x058, // 16-bit
     RESULT__HISTORY_BUFFER_4              = 0x05A, // 16-bit
     RESULT__HISTORY_BUFFER_5              = 0x05C, // 16-bit
     RESULT__HISTORY_BUFFER_6              = 0x05E, // 16-bit
     RESULT__HISTORY_BUFFER_7              = 0x060, // 16-bit
     RESULT__RANGE_VAL                     = 0x062,
     RESULT__RANGE_RAW                     = 0x064,
     RESULT__RANGE_RETURN_RATE             = 0x066, // 16-bit
     RESULT__RANGE_REFERENCE_RATE          = 0x068, // 16-bit
     RESULT__RANGE_RETURN_SIGNAL_COUNT     = 0x06C, // 32-bit
     RESULT__RANGE_REFERENCE_SIGNAL_COUNT  = 0x070, // 32-bit
     RESULT__RANGE_RETURN_AMB_COUNT        = 0x074, // 32-bit
     RESULT__RANGE_REFERENCE_AMB_COUNT     = 0x078, // 32-bit
     RESULT__RANGE_RETURN_CONV_TIME        = 0x07C, // 32-bit
     RESULT__RANGE_REFERENCE_CONV_TIME     = 0x080, // 32-bit

     RANGE_SCALER                          = 0x096, // 16-bit - see STSW-IMG003 core/inc/vl6180x_def.h

     READOUT__AVERAGING_SAMPLE_PERIOD      = 0x10A,
     FIRMWARE__BOOTUP                      = 0x119,
     FIRMWARE__RESULT_SCALER               = 0x120,
     I2C_SLAVE__DEVICE_ADDRESS             = 0x212,
     INTERLEAVED_MODE__ENABLE              = 0x2A3,
   };
/*
 *  ======== echoFxn ========
 *  Task for this function is created statically. See the project's .cfg file.
 */
Void taskFxn(UArg arg0, UArg arg1)
{

    /* Create I2C for usage */
    I2C_Params_init(&i2cParams);
    i2cParams.bitRate = I2C_400kHz;
    i2c = I2C_open(Board_I2C_TMP, &i2cParams);
    if (i2c == NULL) {
       // System_abort("Error Initializing I2C\n");
        UART_write(uart, "\n\rError Initializing I2C", sizeof("\n\rError Initializing I2C"));
    }
    else {
        //System_printf("I2C Initialized!\n");
        UART_write(uart, "\n\rI2C Initialized!", sizeof("\n\rI2C Initialized!"));
    }

    ptp_offset = Read(SYSRANGE__PART_TO_PART_RANGE_OFFSET);

    if(Read(SYSTEM__FRESH_OUT_OF_RESET)==0x1){
    UART_write(uart, "\n\rDevice reseted", sizeof("\n\rDevice reseted"));
    Write(0x207, 0x01);
    Write(0x208, 0x01);
    Write(0x096, 0x00);
    Write(0x097, 0xFD); // RANGE_SCALER = 253
    Write(0x0E3, 0x00);
    Write(0x0E4, 0x04);
    Write(0x0E5, 0x02);
    Write(0x0E6, 0x01);
    Write(0x0E7, 0x03);
    Write(0x0F5, 0x02);
    Write(0x0D9, 0x05);
    Write(0x0DB, 0xCE);
    Write(0x0DC, 0x03);
    Write(0x0DD, 0xF8);
    Write(0x09F, 0x00);
    Write(0x0A3, 0x3C);
    Write(0x0B7, 0x00);
    Write(0x0BB, 0x3C);
    Write(0x0B2, 0x09);
    Write(0x0CA, 0x09);
    Write(0x198, 0x01);
    Write(0x1B0, 0x17);
    Write(0x1AD, 0x00);
    Write(0x0FF, 0x05);
    Write(0x100, 0x05);
    Write(0x199, 0x05);
    Write(0x1A6, 0x1B);
    Write(0x1AC, 0x3E);
    Write(0x1A7, 0x1F);
    Write(0x030, 0x00);

    Write(SYSTEM__FRESH_OUT_OF_RESET, 0);
    }
    else{
    UART_write(uart, "\n\rDevice already initialized", sizeof("\n\rDevice already initialized"));

    uint16_t s = Read(RANGE_SCALER);

    if      (s == ScalerValues[3]) { scaling = 3; }
    else if (s == ScalerValues[2]) { scaling = 2; }
    else                           { scaling = 1; }
    ptp_offset *= scaling;

    }

    // readout__averaging_sample_period = 48
    Write(READOUT__AVERAGING_SAMPLE_PERIOD, 0x30);

    // sysals__analogue_gain_light = 6 (ALS gain = 1 nominal, actually 1.01 according to Table 14 in datasheet)
    Write(SYSALS__ANALOGUE_GAIN, 0x46);

    // sysrange__vhv_repeat_rate = 255 (auto Very High Voltage temperature recalibration after every 255 range measurements)
    Write(SYSRANGE__VHV_REPEAT_RATE, 0xFF);

    // sysals__integration_period = 99 (100 ms)
    // AN4545 incorrectly recommends writing to register 0x040; 0x63 should go in the lower byte, which is register 0x041.
    Write(SYSALS__INTEGRATION_PERIOD, 0x0063);

    // sysrange__vhv_recalibrate = 1 (manually trigger a VHV recalibration)
    Write(SYSRANGE__VHV_RECALIBRATE, 0x01);


    // "Optional: Public registers"

    // sysrange__intermeasurement_period = 9 (100 ms)
    Write(SYSRANGE__INTERMEASUREMENT_PERIOD, 0x09);

    // sysals__intermeasurement_period = 49 (500 ms)
    Write(SYSALS__INTERMEASUREMENT_PERIOD, 0x31);

    // als_int_mode = 4 (ALS new sample ready interrupt); range_int_mode = 4 (range new sample ready interrupt)
    Write(SYSTEM__INTERRUPT_CONFIG_GPIO, 0x24);


    // Reset other settings to power-on defaults

    // sysrange__max_convergence_time = 49 (49 ms)
    Write(SYSRANGE__MAX_CONVERGENCE_TIME, 0x31);

    // disable interleaved mode
    Write(INTERLEAVED_MODE__ENABLE, 0);

    uint8_t const DefaultCrosstalkValidHeight = 20; // default value of SYSRANGE__CROSSTALK_VALID_HEIGHT

    scaling = 1;
    Write(RANGE_SCALER, ScalerValues[scaling]);

    // apply scaling on part-to-part offset
    Write(SYSRANGE__PART_TO_PART_RANGE_OFFSET, ptp_offset / scaling);

    // apply scaling on CrossTalkValidHeight
    Write(SYSRANGE__CROSSTALK_VALID_HEIGHT, DefaultCrosstalkValidHeight / scaling);

    // This function does not apply scaling to RANGE_IGNORE_VALID_HEIGHT.

    // enable early convergence estimate only at 1x scaling
    uint8_t rce = Read(SYSRANGE__RANGE_CHECK_ENABLES);
    Write(SYSRANGE__RANGE_CHECK_ENABLES, (rce & 0xFE) | (scaling == 1));

    Write(SYSRANGE__MAX_CONVERGENCE_TIME, 30);
    Write(SYSALS__INTEGRATION_PERIOD, 50);
    io_timeout = 500;//Set timeout as 500


    Write(SYSRANGE__START, 0x01);//stop continuous
    Write(SYSALS__START, 0x01);
    Write(INTERLEAVED_MODE__ENABLE, 0);

    Task_sleep(1000000 / Clock_tickPeriod);


    Write(INTERLEAVED_MODE__ENABLE, 1);//startInterleavedContinuous
    Write(SYSALS__INTERMEASUREMENT_PERIOD, 9);
    Write(SYSALS__START, 0x03);

    char Range[3]={'0','0','0'};
    //memset(Range,'\0',3);

    while(1){
        UART_write(uart, "\n\rWait for Interrupt", sizeof("\n\rWait for Interrupt"));
        while ((Read(RESULT__INTERRUPT_STATUS_GPIO) & 0x04) == 0);

          uint8_t range = Read(RESULT__RANGE_VAL);
          Write(SYSTEM__INTERRUPT_CLEAR, 0x01);

          Range[2]=(char)(range/100)+'0';
          Range[1]=(char)((range/10)%10)+'0';
          Range[0]=(char)(range%10)+'0';
          UART_write(uart, "\n\rThe range is ", sizeof("\n\rThe range is "));
          UART_write(uart, Range, sizeof(Range));

       // Task_sleep(500000 / Clock_tickPeriod);
    }

    //System_flush();
    //Task_sleep(1000000 / Clock_tickPeriod);

    //I2C_close(i2c);
}

uint8_t Read(uint8_t Reg[1]){

    uint8_t RxBuffer[2];
    char recData[3]={'0','0','0'};
    /* Point to the T ambient register and read its 2 bytes */
    //txBuffer[0] = 0x0016;//TMP007_OBJ_TEMP;
    i2cTransaction.slaveAddress = DeviceAddr;//0x29;//0x052;//Board_TMP007_ADDR;
    i2cTransaction.writeBuf = Reg;
    i2cTransaction.writeCount = 1;
    i2cTransaction.readBuf = RxBuffer;
    i2cTransaction.readCount = 1;

    while(1){
        if (I2C_transfer(i2c, &i2cTransaction)) {
            recData[2]=(char)(RxBuffer[0]/100)+'0';
            recData[1]=(char)((RxBuffer[0]/10)%10)+'0';
            recData[0]=(char)(RxBuffer[0]%10)+'0';
            UART_write(uart, "\n\rRecv data is ", sizeof("\n\rRecv data is "));
            UART_write(uart, recData, sizeof(recData));break;

        }
        else {
           // System_printf("I2C Bus fault\n");
            UART_write(uart, "\n\rNo data from I2C", sizeof("\n\rNo data from I2C"));break;
        }
        }
 return RxBuffer[0];

}

int Write (int16_t Reg[1],int16_t data[1]){

    txBuffer[0] = Reg[0];
    txBuffer[1] = data[0];
    i2cTransaction.slaveAddress = DeviceAddr;//0x052;//Board_TMP007_ADDR;
    i2cTransaction.writeBuf = txBuffer;
    i2cTransaction.writeCount = 1;
    i2cTransaction.readBuf = rxBuffer;
    i2cTransaction.readCount = 1;

    while(1){
    if (I2C_transfer(i2c, &i2cTransaction)){
        UART_write(uart, "\n\rRecv Ack", sizeof("\n\rRecv Ack"));return 0;
      }
      else {
          UART_write(uart, "\n\rNo data from I2C", sizeof("\n\rNo data from I2C"));return -1;
      }
    }
}

/*
 *  ======== main ========
 */
int main(void)
{

    Task_Params taskParams;

    /* Call board init functions */
   // Board_initGeneral();
    Power_init();
    PIN_init(ledPinTable);
    Board_initI2C();
    Board_initUART();

    /* Create a UART with data processing off. */
    UART_Params_init(&uartParams);
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudRate = 115200;
    uart = UART_open(Board_UART0, &uartParams);

    if (uart == NULL) {
        System_abort("Error opening the UART");
    }

    /* Construct tmp007 Task thread */
    Task_Params_init(&taskParams);
    taskParams.stackSize = TASKSTACKSIZE;
    taskParams.stack = &task0Stack;
    Task_construct(&task0Struct, (Task_FuncPtr)taskFxn, &taskParams, NULL);

    /* Open LED pins */
    ledPinHandle = PIN_open(&ledPinState, ledPinTable);
    if(!ledPinHandle) {
        System_abort("Error initializing board LED pins\n");
    }

    PIN_setOutputValue(ledPinHandle, BoostEn, BoostEn);
    PIN_setOutputValue(ledPinHandle, Board_LED1, 0);
   //  PIN_setOutputValue(ledPinHandle, Board_LED2, 0);

    /* Start BIOS */
    BIOS_start();

    return (0);
}

Thanks

  • Hi Jan,

    From a quick look at your "Write" function, you seem to always only write a single byte to the device over I2C while passing two bytes in the txBuffer:

    i2cTransaction.writeCount = 1;

    Is this intended or do you actually also want to transfer the data?
  • Hi M-W,

    I want to write two bytes, I changed writeCount to 2 still I am not getting proper data from sensor.

    Thanks
  • Hi Jan,

    Could you define proper data? If you do a simple test of reading out for example the "device ID" (I assume there is a special device ID register), are you able to do this properly?
  • Hi M-W,

    Yes, I can able to read the register "SYSTEM__FRESH_OUT_OF_RESET", which address is 0x016 and it reads value as 0x1 as expected.

    Thanks

    JanSom
  • Hi Jan,

    Could you define what "proper data" is in this case? As you can read out the reset value, I expect the communication is OK. Are you reading out the right number of bytes -> are a read always only 1 byte and address always 1 byte (hardcoded in Read)?

    If this is correct, how do you verify the correctness of the data? Is it based on your conversion of the data that is printed to UART or the raw value before conversion?
  • Hi M-W,

    In my last posted code, there are many bugs. I fixed those, now I can able to communicate with sensor.

    But still, I am not able to get the distance value from it.

    I have posted the code below.


    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    #include "stdio.h"

    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Task.h>

    /* TI-RTOS Header files */
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/I2C.h>
    #include <ti/drivers/UART.h>

    /* Example/Board Header files */
    #include "Board.h"

    /******************************************************************************************************************/

    #define TASKSTACKSIZE 1024
    #define BoostEn IOID_9
    /* Global memory storage for a PIN_Config table */
    static PIN_State ledPinState;

    /*
    * Application LED pin configuration table:
    * - All LEDs board LEDs are off.
    */
    PIN_Config ledPinTable[] = {
    Board_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    Board_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    BoostEn | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    PIN_TERMINATE
    };
    PIN_Handle ledPinHandle;

    Task_Struct task0Struct;
    Char task0Stack[TASKSTACKSIZE];

    UART_Handle uart;
    UART_Params uartParams;


    // register addresses
    enum regAddr
    {
    IDENTIFICATION__MODEL_ID = 0x000,
    IDENTIFICATION__MODEL_REV_MAJOR = 0x001,
    IDENTIFICATION__MODEL_REV_MINOR = 0x002,
    IDENTIFICATION__MODULE_REV_MAJOR = 0x003,
    IDENTIFICATION__MODULE_REV_MINOR = 0x004,
    IDENTIFICATION__DATE_HI = 0x006,
    IDENTIFICATION__DATE_LO = 0x007,
    IDENTIFICATION__TIME = 0x008, // 16-bit

    SYSTEM__MODE_GPIO0 = 0x010,
    SYSTEM__MODE_GPIO1 = 0x011,
    SYSTEM__HISTORY_CTRL = 0x012,
    SYSTEM__INTERRUPT_CONFIG_GPIO = 0x014,
    SYSTEM__INTERRUPT_CLEAR = 0x015,
    SYSTEM__FRESH_OUT_OF_RESET = 0x016,
    SYSTEM__GROUPED_PARAMETER_HOLD = 0x017,

    SYSRANGE__START = 0x018,
    SYSRANGE__THRESH_HIGH = 0x019,
    SYSRANGE__THRESH_LOW = 0x01A,
    SYSRANGE__INTERMEASUREMENT_PERIOD = 0x01B,
    SYSRANGE__MAX_CONVERGENCE_TIME = 0x01C,
    SYSRANGE__CROSSTALK_COMPENSATION_RATE = 0x01E, // 16-bit
    SYSRANGE__CROSSTALK_VALID_HEIGHT = 0x021,
    SYSRANGE__EARLY_CONVERGENCE_ESTIMATE = 0x022, // 16-bit
    SYSRANGE__PART_TO_PART_RANGE_OFFSET = 0x024,
    SYSRANGE__RANGE_IGNORE_VALID_HEIGHT = 0x025,
    SYSRANGE__RANGE_IGNORE_THRESHOLD = 0x026, // 16-bit
    SYSRANGE__MAX_AMBIENT_LEVEL_MULT = 0x02C,
    SYSRANGE__RANGE_CHECK_ENABLES = 0x02D,
    SYSRANGE__VHV_RECALIBRATE = 0x02E,
    SYSRANGE__VHV_REPEAT_RATE = 0x031,

    SYSALS__START = 0x038,
    SYSALS__THRESH_HIGH = 0x03A,
    SYSALS__THRESH_LOW = 0x03C,
    SYSALS__INTERMEASUREMENT_PERIOD = 0x03E,
    SYSALS__ANALOGUE_GAIN = 0x03F,
    SYSALS__INTEGRATION_PERIOD = 0x040,

    RESULT__RANGE_STATUS = 0x04D,
    RESULT__ALS_STATUS = 0x04E,
    RESULT__INTERRUPT_STATUS_GPIO = 0x04F,
    RESULT__ALS_VAL = 0x050, // 16-bit
    RESULT__HISTORY_BUFFER_0 = 0x052, // 16-bit
    RESULT__HISTORY_BUFFER_1 = 0x054, // 16-bit
    RESULT__HISTORY_BUFFER_2 = 0x056, // 16-bit
    RESULT__HISTORY_BUFFER_3 = 0x058, // 16-bit
    RESULT__HISTORY_BUFFER_4 = 0x05A, // 16-bit
    RESULT__HISTORY_BUFFER_5 = 0x05C, // 16-bit
    RESULT__HISTORY_BUFFER_6 = 0x05E, // 16-bit
    RESULT__HISTORY_BUFFER_7 = 0x060, // 16-bit
    RESULT__RANGE_VAL = 0x062,
    RESULT__RANGE_RAW = 0x064,
    RESULT__RANGE_RETURN_RATE = 0x066, // 16-bit
    RESULT__RANGE_REFERENCE_RATE = 0x068, // 16-bit
    RESULT__RANGE_RETURN_SIGNAL_COUNT = 0x06C, // 32-bit
    RESULT__RANGE_REFERENCE_SIGNAL_COUNT = 0x070, // 32-bit
    RESULT__RANGE_RETURN_AMB_COUNT = 0x074, // 32-bit
    RESULT__RANGE_REFERENCE_AMB_COUNT = 0x078, // 32-bit
    RESULT__RANGE_RETURN_CONV_TIME = 0x07C, // 32-bit
    RESULT__RANGE_REFERENCE_CONV_TIME = 0x080, // 32-bit

    RANGE_SCALER = 0x096, // 16-bit - see STSW-IMG003 core/inc/vl6180x_def.h

    READOUT__AVERAGING_SAMPLE_PERIOD = 0x10A,
    FIRMWARE__BOOTUP = 0x119,
    FIRMWARE__RESULT_SCALER = 0x120,
    I2C_SLAVE__DEVICE_ADDRESS = 0x212,
    INTERLEAVED_MODE__ENABLE = 0x2A3,
    };
    /******************************************************************************************************************/

    uint8_t readReg(uint8_t Reg);
    uint16_t readReg16Bit(uint16_t Reg);
    int hextoChar(char *output,unsigned char n[]);
    int hex16BittoChar(char *output,unsigned short n[]);
    void writeReg(uint16_t Reg, uint16_t value);

    /******************************************************************************************************************/

    //uint8_t txBuffer[2];
    int16_t txBuffer[2];
    uint8_t rxBuffer[2];
    I2C_Handle i2c;
    I2C_Params i2cParams;
    I2C_Transaction i2cTransaction;

    #define DeviceAddr 0x29

    int done=0;
    // RANGE_SCALER values for 1x, 2x, 3x scaling - see STSW-IMG003 core/src/vl6180x_api.c (ScalerLookUP[])
    static uint16_t const ScalerValues[] = {0, 253, 127, 84};

    uint8_t address;
    uint8_t scaling;
    uint8_t ptp_offset;
    uint16_t io_timeout;
    int did_timeout;

    uint8_t RxBuffer[1];

    /******************************************************************************************************************/

    void writeReg(uint16_t Reg, uint16_t value){
    uint8_t TxBuffer[4];

    TxBuffer[0]=(Reg>>8) & 0xff;
    TxBuffer[1]=Reg & 0xff;
    TxBuffer[2]=(value>>8) & 0xff;
    TxBuffer[3]=value & 0xff;

    i2cTransaction.slaveAddress = 0x29;
    i2cTransaction.writeBuf = TxBuffer;
    i2cTransaction.writeCount = 4;
    i2cTransaction.readBuf = RxBuffer;
    i2cTransaction.readCount = 0;
    I2C_transfer(i2c, &i2cTransaction);

    if (!I2C_transfer(i2c, &i2cTransaction)) {UART_write(uart, "\n\rNo data from I2C", sizeof("\n\rNo data from I2C"));}

    }
    uint8_t readReg(uint8_t Reg){
    uint8_t tx[2];

    tx[0]=(Reg>>8) & 0xff;
    tx[1]=Reg & 0xff;

    i2cTransaction.slaveAddress = 0x29;//read
    i2cTransaction.writeBuf = tx;
    i2cTransaction.writeCount = 2;
    i2cTransaction.readBuf = RxBuffer;
    i2cTransaction.readCount = 0;
    I2C_transfer(i2c, &i2cTransaction);

    i2cTransaction.slaveAddress = 0x29;
    i2cTransaction.writeBuf = tx;
    i2cTransaction.writeCount = 0;
    i2cTransaction.readBuf = RxBuffer;
    i2cTransaction.readCount = 1;

    if (!I2C_transfer(i2c, &i2cTransaction)) {UART_write(uart, "\n\rNo data from I2C", sizeof("\n\rNo data from I2C"));}
    return RxBuffer[0];
    }

    uint16_t readReg16Bit(uint16_t Reg){
    uint8_t tx[2];

    tx[0]=(Reg>>8) & 0xff;
    tx[1]=Reg & 0xff;

    i2cTransaction.slaveAddress = 0x29;//read
    i2cTransaction.writeBuf = tx;
    i2cTransaction.writeCount = 2;
    i2cTransaction.readBuf = RxBuffer;
    i2cTransaction.readCount = 0;
    I2C_transfer(i2c, &i2cTransaction);

    i2cTransaction.slaveAddress = 0x29;
    i2cTransaction.writeBuf = tx;
    i2cTransaction.writeCount = 0;
    i2cTransaction.readBuf = RxBuffer;
    i2cTransaction.readCount = 1;

    if (!I2C_transfer(i2c, &i2cTransaction)) {UART_write(uart, "\n\rNo data from I2C", sizeof("\n\rNo data from I2C"));}
    return ( (RxBuffer[0]<<8) | RxBuffer[0] );
    }

    int hextoChar(char *output,unsigned char n[])
    {
    return sprintf(output, "%.4x", n[0]);
    }
    int hex16BittoChar(char *output,unsigned short n[])
    {
    return sprintf(output, "%.4x", n[0]);
    }
    /*
    * ======== echoFxn ========
    * Task for this function is created statically. See the project's .cfg file.
    */
    Void taskFxn(UArg arg0, UArg arg1)
    {

    /* Create I2C for usage */
    I2C_Params_init(&i2cParams);
    i2cParams.bitRate = I2C_400kHz;
    i2c = I2C_open(Board_I2C_TMP, &i2cParams);
    if (i2c == NULL) {
    // System_abort("Error Initializing I2C\n");
    UART_write(uart, "\n\rError Initializing I2C", sizeof("\n\rError Initializing I2C"));
    }
    else {
    //System_printf("I2C Initialized!\n");
    UART_write(uart, "\n\rI2C Initialized!", sizeof("\n\rI2C Initialized!"));
    }

    uint8_t Buf_uint8_t[1]; char Buf_char[4];
    Buf_uint8_t[0] = readReg16Bit(0x212);//Device slave address register

    hextoChar(Buf_char,Buf_uint8_t);

    UART_write(uart, "\n\rThe Device address is ", sizeof("\n\rThe Device address is "));UART_write(uart, Buf_char, sizeof(Buf_char));

    ptp_offset = readReg(SYSRANGE__PART_TO_PART_RANGE_OFFSET);

    if(readReg(SYSTEM__FRESH_OUT_OF_RESET)==0x01){
    UART_write(uart, "\n\rSYSTEM IS FRESH_OUT_OF_RESET", sizeof("\n\rSYSTEM IS FRESH_OUT_OF_RESET"));
    writeReg(SYSTEM__FRESH_OUT_OF_RESET, 0);
    }
    else{
    UART_write(uart, "\n\rDevice already initialized", sizeof("\n\rDevice already initialized"));
    }

    // readout__averaging_sample_period = 48
    writeReg(READOUT__AVERAGING_SAMPLE_PERIOD, 0x30);

    // sysals__analogue_gain_light = 6 (ALS gain = 1 nominal, actually 1.01 according to Table 14 in datasheet)
    writeReg(SYSALS__ANALOGUE_GAIN, 0x46);
    //Default ALS gain itself is 6,so commenting the above code line

    // sysrange__vhv_repeat_rate = 255 (auto Very High Voltage temperature recalibration after every 255 range measurements)
    writeReg(SYSRANGE__VHV_REPEAT_RATE, 0xFF);

    // sysals__integration_period = 99 (100 ms)
    // AN4545 incorrectly recommends writing to register 0x040; 0x63 should go in the lower byte, which is register 0x041.
    writeReg(SYSALS__INTEGRATION_PERIOD, 0x0063);

    // sysrange__vhv_recalibrate = 1 (manually trigger a VHV recalibration)
    writeReg(SYSRANGE__VHV_RECALIBRATE, 0x01);


    // "Optional: Public registers"

    // sysrange__intermeasurement_period = 9 (100 ms)
    writeReg(SYSRANGE__INTERMEASUREMENT_PERIOD, 0x09);

    // sysals__intermeasurement_period = 49 (500 ms)
    writeReg(SYSALS__INTERMEASUREMENT_PERIOD, 0x31);

    // als_int_mode = 4 (ALS new sample ready interrupt); range_int_mode = 4 (range new sample ready interrupt)
    writeReg(SYSTEM__INTERRUPT_CONFIG_GPIO, 0x24);


    // Reset other settings to power-on defaults

    // sysrange__max_convergence_time = 49 (49 ms)
    writeReg(SYSRANGE__MAX_CONVERGENCE_TIME, 0x31);

    // disable interleaved mode
    writeReg(INTERLEAVED_MODE__ENABLE, 0);

    uint8_t const DefaultCrosstalkValidHeight = 20; // default value of SYSRANGE__CROSSTALK_VALID_HEIGHT

    //scaling = 1;
    // writeReg(RANGE_SCALER, ScalerValues[scaling]);

    // apply scaling on part-to-part offset
    writeReg(SYSRANGE__PART_TO_PART_RANGE_OFFSET, ptp_offset);

    // apply scaling on CrossTalkValidHeight
    writeReg(SYSRANGE__CROSSTALK_VALID_HEIGHT, DefaultCrosstalkValidHeight);

    // This function does not apply scaling to RANGE_IGNORE_VALID_HEIGHT.

    // enable early convergence estimate only at 1x scaling
    uint8_t rce = readReg(SYSRANGE__RANGE_CHECK_ENABLES);
    writeReg(SYSRANGE__RANGE_CHECK_ENABLES, (rce & 0xFE) | (scaling == 1));

    writeReg(SYSRANGE__MAX_CONVERGENCE_TIME, 30);
    writeReg(SYSALS__INTEGRATION_PERIOD, 50);
    io_timeout = 500;//Set timeout as 500


    //writeReg(SYSRANGE__START, 0x01);//stop continuous
    // writeReg(SYSALS__START, 0x01);
    //writeReg(INTERLEAVED_MODE__ENABLE, 0);

    // Task_sleep(1000000 / Clock_tickPeriod);


    // writeReg(INTERLEAVED_MODE__ENABLE, 1);//startInterleavedContinuous
    // writeReg(SYSALS__INTERMEASUREMENT_PERIOD, 10);
    //writeReg(SYSALS__START, 0x03);

    writeReg(SYSRANGE__INTERMEASUREMENT_PERIOD, 9);
    writeReg(SYSRANGE__START, 0x03);

    UART_write(uart, "\n\rSensor setup done!!", sizeof("\n\rSensor setup done!!"));

    while(1){
    UART_write(uart, "\n\rWait for Interrupt", sizeof("\n\rWait for Interrupt"));
    while ((readReg(RESULT__INTERRUPT_STATUS_GPIO) & 0x04) == 0){Task_sleep(100000 / Clock_tickPeriod);}

    Buf_uint8_t[0] = readReg(RESULT__RANGE_VAL);
    writeReg(SYSTEM__INTERRUPT_CLEAR, 0x01);

    hextoChar(Buf_char,Buf_uint8_t);
    UART_write(uart, "\n\rThe range is ", sizeof("\n\rThe range is "));UART_write(uart, Buf_char, sizeof(Buf_char));

    Task_sleep(500000 / Clock_tickPeriod);
    }

    //System_flush();
    //Task_sleep(1000000 / Clock_tickPeriod);

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

    /*
    * ======== main ========
    */
    int main(void)
    {

    Task_Params taskParams;

    /* Call board init functions */
    // Board_initGeneral();
    Power_init();
    PIN_init(ledPinTable);
    Board_initI2C();
    Board_initUART();

    /* Create a UART with data processing off. */
    UART_Params_init(&uartParams);
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudRate = 115200;
    uart = UART_open(Board_UART0, &uartParams);

    if (uart == NULL) {
    System_abort("Error opening the UART");
    }

    /* Construct tmp007 Task thread */
    Task_Params_init(&taskParams);
    taskParams.stackSize = TASKSTACKSIZE;
    taskParams.stack = &task0Stack;
    Task_construct(&task0Struct, (Task_FuncPtr)taskFxn, &taskParams, NULL);

    /* Open LED pins */
    ledPinHandle = PIN_open(&ledPinState, ledPinTable);
    if(!ledPinHandle) {
    System_abort("Error initializing board LED pins\n");
    }

    PIN_setOutputValue(ledPinHandle, BoostEn, BoostEn);
    PIN_setOutputValue(ledPinHandle, Board_LED1, 0);
    // PIN_setOutputValue(ledPinHandle, Board_LED2, 0);

    /* Start BIOS */
    BIOS_start();

    return (0);
    }



    Thanks & regards,

    JanSom
  • Hi Jan,

    As you can communicate with the device I suspect it is simply a logic error in the code somewhere. I would suggest you connect a logic analyzer and scope the I2C transaction to check that it corresponds to what you expect.

    Regarding the sensor itself, I'm not able to help you with it as I have no experience at all using this sensor.
  • Hi M-W,

    Sure, I will try with analyzer.

    Thanks for your support.

    Regards,

    JanSom