cancel
Showing results for 
Search instead for 
Did you mean: 

VL53L5 init stalls at get offset NVM data

DBonh.1
Associate III

I'm implementing the VL53L5CX ultralight driver on an ATSAM4L. The sensor responds correctly when requesting Device ID and Rev. The init function runs without errors (status = 0) through the loading of firmware and restarting the sensor's MCU. But one of the next steps in the init function is getting the offset NVM data. It writes VL53L5CX_GET_NVM_CMD without error (status is still = 0). Then it polls the sensor, and at that point it returns status = 66.

I have a Total Phase I2C protocol analyzer on it during the entire init process. It reports no errors during any of the transactions. Any ideas? This step is the first WrMulti() call where the register address is not 0 (it's 0x2fd8). So that is a possibility. But the I2C analyzer shows 0x2fd8 being correctly passed to the sensor. So I'm running out of ideas. All help or suggestions appreciated!

19 REPLIES 19

Hi Doug.

I see a detail, that does not go to the point of the issue but it may help you debugging. In your analyzer screenshot I see for STM Eval board I2C address is 2A (treated as 0x54 in ST Nucleo format). This is not the native I2C address of the sensor (it is 0x52 or 29 in the analyzer unless you have edited RANGING_SENSOR_VL53L5CX_ADDRESS constant). As I see in my Nucleo app there is a SetAddress function call (that changes addresses to each sensor). It is found way after vl53l5cx_init() exits successfully. This would mean that analyzer capture might be comparing different moments of soft initialization.

Another comment that might help, as a user of ATSAM4S I had to write my own platform to get the ST api working. I had no problem with multibyte transfer length over I2C. I am working with three VL53L5C. However at a first glance of the platform I can describe there are byte and multibyte read, write, swap buffer, and wait functions.

Proven I2C transfers are ok. I would re-check swap and wait functions. In my case I had some trouble about systick setup, in wich my WaitMs() function was based too. I think you might be almost there.

Regards

Alex

In my ULD driver I found what I think is a bug in the _vl53l5cx_poll_for_answer() function within the api. That causes that system to stall, but only when some other thing went wrong and poll is not receiving what is expected. Then this function reaches the (too long) timeout but never exits.

static uint8_t _vl53l5cx_poll_for_answer(
		VL53L5CX_Configuration	*p_dev,
		uint8_t					size,
		uint8_t					pos,
		uint16_t				address,
		uint8_t					mask,
		uint8_t					expected_value)
{
	uint8_t status = VL53L5CX_STATUS_OK;
	uint8_t timeout = 0;
 
	do {
		status |= RdMulti(&(p_dev->platform), address,
				p_dev->temp_buffer, size);
		status |= WaitMs(&(p_dev->platform), 10);
 
		if(timeout >= (uint8_t)50)	 /* 2s timeout too long. Edited to 0.5s */
		{
			status |= p_dev->temp_buffer[2];
//HERE  there is a break missing I have added:
			break;
		}else if((size >= (uint8_t)4) 
                         && (p_dev->temp_buffer[2] >= (uint8_t)0x7f))
		{
			status |= VL53L5CX_MCU_ERROR;
		}
		else
		{
			timeout++;
		}
	}while ((p_dev->temp_buffer[pos] & mask) != expected_value);
 
	return status;
}

DBonh.1
Associate III

Thanks, Alex, I should have been updating this.

The 29 / 52 discrepancy is related to 8-bit versus 7-bit format for expressing an I2C device address. This protocol analyzer displays 8-bit, STM uses 7-bit.

I had to create my own microsecond counter for the Atmel.

I eventually made it all the way through the vl32l5cx_init() function without errors after I created a discrete I2C write function for sending the register address, complete with an I2C stop bit before sending an I2C read command (STM does this differently than some other I2C implementations).

I'm currently working on the ranging loop where the host polls the sensor for data ready. My sensor is responding to vl53l5cx_check_data_ready() with an error condition (00 05 C5 81) where the "81" indicates some kind of error. Have you run into that one?

I think I hit that too, or something similar. The poll_for_answer() function has a parameter for a mask. I found that I had to change that mask byte for at least one of the calls, sorry I don't remember which one. I'm surprised others have not hit that.
AlexCloned
Senior

I am not sure sensor error codes are listed somewhere. I think not. But let me ask you did you set up a ranging profile, and send a start instruction to the sensor. Please navigate inside the ST Eval soft and reproduce the set up procedure. I am pretty sure once you configure the measuremente profile and send the start instruction to the sensor, it is just a matter of calling the check_data_ready function repeatedly until it returns VL53L5CX_STATUS_OK. I assume you are working by polling instead of waiting for the INT pin.

It is a pity you are not taking advantage of Cortex M4 native I2C peripheral. This sensor gives you lots of data (64 zones simultaneously) and data transfer speeds are critical, or they will be. Perhaps you can re-check Atmel ASF TWI functions for I2C and put them to work for you once you have stabilized the rest of your proto. You will be releived of a lot of overhead processing at the host driving the pins "manually". My admiration for your achivement, anyway.

To go further I edited two consntants in twi.c (from the ASF bundle) and took I2C and sensor to work at 1 MHz (watch out your I2C bus capacitances and signal edges).

#define LOW_LEVEL_TIME_LIMIT 960000 //tune the I2C to 1 MHz  //384000
#define I2C_FAST_MODE_SPEED  1000000 ////tune the I2C to 1 MHz //400000

Regards.

DBonh.1
Associate III

I sure wanted to use Atmel's ASF TWI driver. But on the ATSAM4L the TWI transmit stops dead and hangs after sending 22,174 bytes. We need to send 32,770 bytes of firmware. I have an open case with Microchip on that but they haven't solved it yet, so I resorted to a bit-bang.

I suspect the TWI limitation on the ATSAM4L is related to how the total amount of program flash isn't a lot bigger than that. Atmel might have assumed that no one will need to send I2C packets that big.

John E KVAM
ST Employee

I just posted some ST code (written by a collegue) that breaks long I2C transactions into smaller chunk sizes.

I posted it under:

I2C multi-byte read and write functions with i2C byte limit. (st.com)

It should help a lot. Although you will still have to adapt it to your MCU.

  • john

If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.
DBonh.1
Associate III

Thanks, John, because one of Microchips off-the-shelf I2C drivers stalls at 22,000 bytes. I've had an open case with them for weeks but they haven't solved it yet. I won't be the only one who hits this. It's only with their barely-big-enough ATSAM4L. Their bigger ATSAMs that have more memory do not have this limitation. Thanks!! -Doug

John E KVAM
ST Employee

Someone reported that bug a while back and I think it was fixed in version 1.3.1.

The current version on ST.com is 1.3.4.

But I don't blame you for running older code. There does not appear to be any way to check for a newer release except to download the code and look at the version.

That might be the bigger issue.


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.