cancel
Showing results for 
Search instead for 
Did you mean: 

VL53L5CX with Zephyr on NRF Board

osugiw
Associate

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:

  • Failed on the vl53l5cx_init, because after the firmware is successfully flashed the  _vl53l5cx_poll_for_answer always gets the wrong value as attached image

osugiw_0-1752315908809.png

 

osugiw_0-1752140817597.png

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 = &reg_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,

 

@Anne BIGOT @John E KVAM 

2 REPLIES 2
John_Kvam
Associate II

@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

If this or any post solves your issue, please mark them as "Accept as Solution". It really helps the next guy.
And if you notice anything wrong do not hesitate to "Report Inappropriate Content".
I am a recently retired ST Employee. My former username was John E KVAM.

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.

osugiw_0-1752577107274.png

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.