2025-07-10 2:54 AM - edited 2025-07-12 3:27 AM
Hi everyone,
I have been struggling to work with VL53L5CX on my NRF board using Zephyr. I used the VL53L5CX_ULD_driver_2.0.1 API and changed the platform.cpp. So far, what my problem is as follows:
My code is as follows:
uint8_t VL53L5CX_WrMulti(VL53L5CX_Platform *sensor, uint16_t reg, uint8_t *p_values, uint32_t size)
{
uint8_t status = VL53L5CX_STATUS_OK;
uint16_t current_address = reg; // Initialize current address
uint32_t remaining_size = size; // Calculate remaining size to write
// Loop until all data is written
while (remaining_size > 0)
{
// Calculate the current chunk size to write
uint32_t current_chunk_size = (remaining_size > chunk_size) ? chunk_size : remaining_size;
struct i2c_msg msg[2];
uint8_t reg_buff[2] = {current_address >> 8, current_address & 0xFF};
msg[0].buf = ®_buff;
msg[0].len = 2;
msg[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
msg[1].buf = &p_values;
msg[1].len = current_chunk_size;
msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
status = i2c_transfer(sensor->i2c_dev, msg, 2, sensor->address);
if (status != VL53L5CX_STATUS_OK)
{
status = VL53L5CX_STATUS_ERROR;
LOG_ERR("Failed to write status %d", status);
}
// Update remaining size and pointer to move to the next chunk
remaining_size -= current_chunk_size;
current_address += current_chunk_size; // Increment register address for next chunk
p_values += current_chunk_size;
VL53L5CX_WaitMs(&sensor, 10);
}
return status;
}
uint8_t VL53L5CX_RdMulti(VL53L5CX_Platform *sensor, uint16_t reg, uint8_t *p_values, uint32_t size)
{
uint8_t status = VL53L5CX_STATUS_OK;
uint8_t buf[2] = {reg >> 8, reg & 0xFF};
status = i2c_write(sensor->i2c_dev, buf, 2, sensor->address);
if (status != VL53L5CX_STATUS_OK)
{
status = VL53L5CX_STATUS_ERROR;
LOG_ERR("Failed to write, status %d", status);
}
// uint16_t bytesToReadRemaining = size;
// uint16_t offset = 0;
// while (bytesToReadRemaining > 0)
// {
// uint16_t bytesToRead = (bytesToReadRemaining > chunk_size) ? chunk_size : bytesToReadRemaining;
// // for (uint16_t x = 0; x < bytesToRead; x++)
// // {
// // status = i2c_read(sensor->i2c_dev, &p_values[offset + x], (uint8_t)bytesToRead, sensor->address);
// // if (status != VL53L5CX_STATUS_OK)
// // {
// // status = VL53L5CX_STATUS_ERROR;
// // LOG_ERR("Failed to read status %d", status);
// // }
// // }
// status = i2c_read(sensor->i2c_dev, &p_values[offset], bytesToRead, sensor->address);
// if (status != VL53L5CX_STATUS_OK)
// {
// status = VL53L5CX_STATUS_ERROR;
// LOG_ERR("Failed to read status %d", status);
// }
// offset += bytesToRead;
// bytesToReadRemaining -= bytesToRead;
// }
status = i2c_read(sensor->i2c_dev, p_values, size, sensor->address);
if (status != VL53L5CX_STATUS_OK)
{
status = VL53L5CX_STATUS_ERROR;
LOG_ERR("Failed to read status %d", status);
}
return status;
}
Kindly help me if anyone has successfully used VL53L5CX on the Zephyr platform.
Thank you!
Best Regards,
2025-07-14 8:37 AM
@John E KVAM has a long last retired but old habits die hard. (I'm John_Kvam now. Same guy, but now an unpaid contributor.)
You are getting data so your I2C works, but that doesn't mean you don't have a byte swap issue. Or a word-swap issue.
The STM32 ST uses in it's demo code is a little-endian device, and the I2C interface is a big-endian device. So if you look at the code there is a lot of swapping going on.
The best way to tell if you have it the right way 'round is to write 4 bytes and read back 2 words, and then read back 1 long word. Then write one longword and read it back as 2 words and as 4 bytes.
There is some code to do this on the Forum somewhere, but I left my version of it at work.
Resolve these issues and I think you will be all set.
There is one other issue you might see. those really long I2C writes are not well handled by other MCUs. Do check to see that they have been completely written. And adjust the long writes into several shorter ones if you have an issue.
- john
2025-07-15 4:05 AM
Hi John,
Thanks for informing. I appreciate your suggestion to check the data integrity. Is this the code for testing the data endianness that you wrote is in this link
https://community.st.com/t5/imaging-sensors/vl53l5cx-driver-vl53l5cx-init-fails/m-p/640829/highlight/true#M3626 ?
I have tested using that, and as you can see from my attached image, the data was wrong. For example, first data should be 0xCE, but read as 0x9F and so on. I have checked my WriteMultipleBytes using a logic analyzer and has correct dataframe.
Indeed, the data reading is wrong, but, strangely, the API can be used for uploading the FW to the sensor. However, after being FW successfully flashed, then reset and boot up again, and when entering the NVM reading sensor, it always failed and recognised as timeout.
Do you think the problem could be FW upload failure due to MCU's incapability for transferring a large amount of FW data?
Thank you very much for your time and suggestion.