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.

MSPM0G3507: VL53L0X(TOF) Driver for TI

Part Number: MSPM0G3507

Tool/software:

Hello,

I am trying to connect the VL53L0X Time-of-Flight (ToF) sensor to the MSPM0G3507 LaunchPad using I2C. The sensor is connected as follows:

  • VCC3.3V

  • GNDGND

  • SCLPB2

  • SDAPB3

  • GPIO1Not connected

  • XSHUT3.3V

I am using the I2C driver example from:
  C:\ti\mspm0_sdk_2_04_00_06\examples\rtos\LP_MSPM0G3507\drivers\i2c_tmp

Modifications Made:

  • Changed the I2C slave address to match the VL53L0X sensor.

  • The example supports two sensors, but I commented out the code for the second sensor.

    I need to determine which memory address to read from the VL53L0X sensor to retrieve distance measurements correctly.

    I have attached my full code below. Could you help me identify the correct memory address to read for distance data?

    /*
     *  ======== i2ctmp.c ========
     */
    #include <stddef.h>
    #include <stdint.h>
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/display/DisplayUart.h>
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/I2C.h>
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    /* Temperature result registers */
    #define TMP11X_RESULT_REG 0xc0
    
    /* I2C target addresses */
    #define TMP11X_BASSENSORS_ADDR 0x29
    //#define TMP116_LAUNCHPAD_ADDR 0x49
    
    /* Number of supported sensor iterations */
    #define TMP_COUNT 1
    uint8_t gBuffer[CONFIG_UART_BUFFER_LENGTH] = {0};
    
    /*
     * Data structure containing currently supported I2C TMP sensors.
     * Sensors are ordered by descending preference.
     */
    static const struct {
        uint8_t address;
        uint8_t resultReg;
        char *id;
    } sensors[TMP_COUNT] = {{TMP11X_BASSENSORS_ADDR, TMP11X_RESULT_REG, "11X"}};
       // {TMP116_LAUNCHPAD_ADDR, TMP11X_RESULT_REG, "116"}};
    
    static uint8_t targetAddress;
    static Display_Handle display;
    
    static void i2cErrorHandler(
        I2C_Transaction *transaction, Display_Handle display);
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        uint16_t sample;
        int16_t temperature;
        uint8_t txBuffer[1];
        uint8_t rxBuffer[2];
        int8_t i;
        I2C_Handle i2c;
        I2C_Params i2cParams;
        I2C_Transaction i2cTransaction;
    
        /* Call driver init functions */
        Display_init();
        GPIO_init();
        I2C_init();
    
        /* Configure the LED and if applicable, the TMP_EN pin */
        GPIO_setConfig(CONFIG_GPIO_LED_0,
            GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH | CONFIG_GPIO_LED_0_IOMUX);
    #ifdef CONFIG_GPIO_TMP_EN
        GPIO_setConfig(CONFIG_GPIO_TMP_EN,
            GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH | CONFIG_GPIO_TMP_EN_IOMUX);
        /* Allow the sensor to power on */
        sleep(1);
    #endif
    
        /* Open the UART display for output */
        display = Display_open(Display_Type_UART, NULL);
        if (display == NULL) {
            while (1) {
            }
        }
        
        /* Turn on user LED to indicate successful initialization */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_LED_ON);
        Display_printf(display, 0, 0, "Starting the i2ctmp example\n");
    
        /* Create I2C for usage */
        I2C_Params_init(&i2cParams);
        i2cParams.bitRate = I2C_100kHz;
        i2c               = I2C_open(CONFIG_I2C_TMP, &i2cParams);
        if (i2c == NULL) {
            Display_printf(display, 0, 0, "Error Initializing I2C\n");
            while (1) {
            }
        } else {
            Display_printf(display, 0, 0, "I2C Initialized!\n");
        }
    
        /* Common I2C transaction setup */
        i2cTransaction.writeBuf   = txBuffer;
        i2cTransaction.writeCount = 1;
        i2cTransaction.readBuf    = rxBuffer;
        i2cTransaction.readCount  = 0;
    
        /*
         * Determine which I2C sensors are present by querying known I2C
         * target addresses.
         */
        for (i = TMP_COUNT - 1; i >= 0; i--) {
            i2cTransaction.targetAddress = sensors[i].address;
            txBuffer[0]                  = sensors[i].resultReg;
    
            if (I2C_transfer(i2c, &i2cTransaction)) {
                targetAddress = sensors[i].address;
                Display_printf(display, 0, 0,
                    "Detected TMP%s sensor with target"
                    " address 0x%x",
                    sensors[i].id, sensors[i].address);
            } else {
                i2cErrorHandler(&i2cTransaction, display);
            }
        }
    
        /* If we never assigned a target address */
        if (targetAddress == 0) {
            Display_printf(display, 0, 0, "Failed to detect a sensor!");
            I2C_close(i2c);
            while (1) {
            }
        }
    
        Display_printf(display, 0, 0, "\nUsing last known sensor for samples.");
        i2cTransaction.targetAddress = targetAddress;
    
        /* Take 20 samples and print them out onto the console */
        for (sample = 0; sample < 20; sample++) {
            i2cTransaction.readCount = 2;
            if (I2C_transfer(i2c, &i2cTransaction)) {
                /*
                 * Extract degrees C from the received data;
                 * see TMP sensor datasheet
                 */
                temperature = (rxBuffer[0] << 8) | (rxBuffer[1]);
               // temperature *= 0.0078125;
    
                Display_printf(
                    display, 0, 0, "Sample %u: %d C", sample, temperature);
            } else {
                i2cErrorHandler(&i2cTransaction, display);
            }
    
            /* Sleep for 1 second */
            sleep(1);
        }
        Display_printf(display, 0, 0, "I2C closed!");
        I2C_close(i2c);
        return (NULL);
    }
    
    /*
     *  ======== i2cErrorHandler ========
     */
    static void i2cErrorHandler(
        I2C_Transaction *transaction, Display_Handle display)
    {
        switch (transaction->status) {
            case I2C_STATUS_TIMEOUT:
                Display_printf(display, 0, 0, "I2C transaction timed out!");
                break;
            case I2C_STATUS_CLOCK_TIMEOUT:
                Display_printf(display, 0, 0, "I2C serial clock line timed out!");
                break;
            case I2C_STATUS_ADDR_NACK:
                Display_printf(display, 0, 0,
                    "I2C target address 0x%x not"
                    " acknowledged!",
                    transaction->targetAddress);
                break;
            case I2C_STATUS_DATA_NACK:
                Display_printf(display, 0, 0, "I2C data byte not acknowledged!");
                break;
            case I2C_STATUS_ARB_LOST:
                Display_printf(
                    display, 0, 0, "I2C arbitration to another controller!");
                break;
            case I2C_STATUS_INCOMPLETE:
                Display_printf(
                    display, 0, 0, "I2C transaction returned before completion!");
                break;
            case I2C_STATUS_BUS_BUSY:
                Display_printf(display, 0, 0, "I2C bus is already in use!");
                break;
            case I2C_STATUS_CANCEL:
                Display_printf(display, 0, 0, "I2C transaction cancelled!");
                break;
            case I2C_STATUS_INVALID_TRANS:
                Display_printf(display, 0, 0, "I2C transaction invalid!");
                break;
            case I2C_STATUS_ERROR:
                Display_printf(display, 0, 0, "I2C generic error!");
                break;
            default:
                Display_printf(display, 0, 0, "I2C undefined error case!");
                break;
        }
    }
    

  • i find out the issue, attaching a full code, if any one need go through it

    #include <stddef.h>
    #include <stdint.h>
    #include <unistd.h>
    #include <ti/display/DisplayUart.h>
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/I2C.h>
    #include "ti_drivers_config.h"
    
    // VL53L0X I2C address
    #define VL53L0X_ADDR 0x29
    
    // Register addresses
    #define VL53L0X_REG_SYSRANGE_START      0x00
    #define VL53L0X_REG_RESULT_RANGE_STATUS 0x14
    #define VL53L0X_REG_RESULT_RANGE_MM     0x1E  // Distance register
    
    static Display_Handle display;
    static I2C_Handle i2c;
    
    void initVL53L0X() {
        uint8_t txBuffer[2];
        uint8_t rxBuffer[1];
        I2C_Transaction i2cTransaction;
    
        // Check if sensor is detected
        txBuffer[0] = 0xC0;  // Model ID register
        i2cTransaction.writeBuf = txBuffer;
        i2cTransaction.writeCount = 1;
        i2cTransaction.readBuf = rxBuffer;
        i2cTransaction.readCount = 1;
        i2cTransaction.targetAddress = VL53L0X_ADDR;
    
        if (I2C_transfer(i2c, &i2cTransaction)) {
            if (rxBuffer[0] == 0xEE) {
                Display_printf(display, 0, 0, "VL53L0X detected!");
            } else {
                Display_printf(display, 0, 0, "Unexpected Model ID: 0x%x", rxBuffer[0]);
            }
        } else {
            Display_printf(display, 0, 0, "I2C Transfer failed");
        }
    
        // Set XSHUT HIGH (enable sensor if needed)
     //   GPIO_write(CONFIG_GPIO_TMP_EN, 1);
        usleep(5000);  // Wait 5ms for power-up
    
        // Start single measurement mode
        txBuffer[0] = VL53L0X_REG_SYSRANGE_START;
        txBuffer[1] = 0x01;  // Single-shot mode
        i2cTransaction.writeBuf = txBuffer;
        i2cTransaction.writeCount = 2;
        i2cTransaction.readCount = 0;
        if (!I2C_transfer(i2c, &i2cTransaction)) {
            Display_printf(display, 0, 0, "Failed to start measurement");
        }
    }
    void startMeasurement() {
        uint8_t txBuffer[2];
        I2C_Transaction i2cTransaction;
    
        txBuffer[0] = VL53L0X_REG_SYSRANGE_START;
        txBuffer[1] = 0x01;  // Start a new measurement
        i2cTransaction.writeBuf = txBuffer;
        i2cTransaction.writeCount = 2;
        i2cTransaction.readBuf = NULL;
        i2cTransaction.readCount = 0;
        i2cTransaction.targetAddress = VL53L0X_ADDR;
    
        I2C_transfer(i2c, &i2cTransaction);
    }
    
    uint16_t readDistance() {
        uint8_t txBuffer[1];
        uint8_t rxBuffer[2];
        I2C_Transaction i2cTransaction;
        uint16_t distance;
        int timeout = 200;
    
        // Start a new measurement before reading
        startMeasurement();
    
        // Wait for measurement completion
        do {
            txBuffer[0] = VL53L0X_REG_RESULT_RANGE_STATUS;
            i2cTransaction.writeBuf = txBuffer;
            i2cTransaction.writeCount = 1;
            i2cTransaction.readBuf = rxBuffer;
            i2cTransaction.readCount = 1;
            i2cTransaction.targetAddress = VL53L0X_ADDR;
    
            if (!I2C_transfer(i2c, &i2cTransaction)) {
                Display_printf(display, 0, 0, "Error reading status");
                return 0xFFFF;
            }
    
            usleep(10000);
        } while ((rxBuffer[0] & 0x01) == 0 && --timeout > 0);
    
        if (timeout == 0) {
            Display_printf(display, 0, 0, "Timeout waiting for measurement");
            return 0xFFFF;
        }
    
        // Read distance
        txBuffer[0] = VL53L0X_REG_RESULT_RANGE_MM;
        i2cTransaction.writeBuf = txBuffer;
        i2cTransaction.writeCount = 1;
        i2cTransaction.readBuf = rxBuffer;
        i2cTransaction.readCount = 2;
    
        if (!I2C_transfer(i2c, &i2cTransaction)) {
            Display_printf(display, 0, 0, "Error reading distance");
            return 0xFFFF;
        }
    
        distance = (rxBuffer[0] << 8) | rxBuffer[1];
        return distance;
    }
    
    
    #if 0
    uint16_t readDistance() {
        uint8_t txBuffer[1];
        uint8_t rxBuffer[2];
        I2C_Transaction i2cTransaction;
        uint16_t distance;
        int timeout = 200;  // Increase timeout to avoid infinite loop
    
        // Wait for measurement completion
        do {
            txBuffer[0] = VL53L0X_REG_RESULT_RANGE_STATUS;
            i2cTransaction.writeBuf = txBuffer;
            i2cTransaction.writeCount = 1;
            i2cTransaction.readBuf = rxBuffer;
            i2cTransaction.readCount = 1;
            i2cTransaction.targetAddress = VL53L0X_ADDR;
    
            if (!I2C_transfer(i2c, &i2cTransaction)) {
                Display_printf(display, 0, 0, "Error reading status");
                return 0xFFFF;
            }
    
            usleep(10000);  // 10ms delay
        } while ((rxBuffer[0] & 0x01) == 0 && --timeout > 0);
    
        if (timeout == 0) {
            Display_printf(display, 0, 0, "Timeout waiting for measurement");
            return 0xFFFF;
        }
    
        // Read distance value (16-bit)
        txBuffer[0] = VL53L0X_REG_RESULT_RANGE_MM;
        i2cTransaction.writeBuf = txBuffer;
        i2cTransaction.writeCount = 1;
        i2cTransaction.readBuf = rxBuffer;
        i2cTransaction.readCount = 2;
    
        if (!I2C_transfer(i2c, &i2cTransaction)) {
            Display_printf(display, 0, 0, "Error reading distance");
            return 0xFFFF;
        }
    
        // Convert to mm
        distance = (rxBuffer[0] << 8) | rxBuffer[1];
        return distance;
    }
    #endif
    void *mainThread(void *arg0) {
        I2C_Params i2cParams;
    
        Display_init();
        GPIO_init();
        I2C_init();
    
        display = Display_open(Display_Type_UART, NULL);
        if (display == NULL) {
            while (1);
        }
    
        I2C_Params_init(&i2cParams);
        i2cParams.bitRate = I2C_100kHz;
        i2c = I2C_open(CONFIG_I2C_TMP, &i2cParams);
        if (i2c == NULL) {
            Display_printf(display, 0, 0, "Error Initializing I2C\n");
            while (1);
        }
    
        initVL53L0X();
    
        while (1) {
            uint16_t distance = readDistance();
            if (distance != 0xFFFF) {
                Display_printf(display, 0, 0, "Distance: %d mm", distance);
            }
            sleep(1);
        }
    }
    

    Thanks && Regards

    Amara Rakesh