Skip to main content
DBonh.1
Associate III
July 12, 2022
Question

VL53L5 init stalls at get offset NVM data

  • July 12, 2022
  • 14 replies
  • 4214 views

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!

This topic has been closed for replies.

14 replies

John E KVAM
ST Employee
July 12, 2022

i've got an idea that I want you to check.

The number one issue with I2C and non-ST MCUs is that the STM32 can do a very large multi-byte I2C write. Most other MCUs are limited to reasonable numbers, like 32, 128 or 256.

Unfortunately our driver takes full advantage of the STM32, and the WrMulti does not show how to divide up that function into chunks.

The sizeof(VL53L5CX_GET_NVM_CMD) is 40.

I'm guessing your max I2C write is 32.

So the write never completes.

Could you check it please?

re-write WrMulti() to do the write in chunks of 32. (just repeated writes but you have to update the address accordingly.

  • john

DBonh.1
DBonh.1Author
Associate III
July 12, 2022
Thanks, John for the fast response.
Below I pasted a screenshot from the Total Phase I2C analyzer. The analyzer shows all 42 bytes. It also shows the much bigger packets containing the sensor's firmware as transferring okay.
There's something else very strange. After several of the I2C commands from the host, your ULD calls a polling function that waits for a good response from the sensor. In two cases, the sensor responds okay after exactly 25 polling queries from the host. When I add short delays in the polling function, the sensor continues to respond after 25 queries, regardless of how long it takes. This doesn't feel right.
The polling function is also called after the NVM command, and it responds with an error after exactly 16 polling queries, regardless of how slowly I run the poll.
I just now downloaded your v1.3.4 ULD. I was previously using v1.0.4. I'm seeing some minor diffs. I'll let you know after I get 1.3.4 fully incorporated into my Atmel code (I would have designed with an STM processor but Atmels were more readily available from the distributors).
[image: image.png]
John E KVAM
ST Employee
July 12, 2022

the 66 is what you get when the sensor is not actually running. It's a catch-all error. Only the interface logic is going. So you are really going to have to dig into the manual and find out if the AT supports the long i2C access.

(or you can just shorten it up as a test.)

DBonh.1
DBonh.1Author
Associate III
July 12, 2022

Both an oscilloscope and the protocol analyzer show that the Atmel is sending packets of 32770 bytes, and that the sensor is ACKing all of those bytes. Although Atmel's I2C driver stalls after 22,000 bytes - I opened a case with Atmel for that issue. Until they fix that I'm using a bit-banged I2C driver that can do long packets.

Knowing that the 66 means that the sensor is not running the firmware - that's helpful. I might be able to attack this by attaching the I2C protocol analyzer to one of your eval boards and watch it initialize a sensor. Does your eval board do pretty much the same init routine as your ULD?

John E KVAM
ST Employee
July 12, 2022

The Eval kit does exactly what we are asking you do to. It would be a very good way to debug.

And don't just think the write limitation is equal to the read limitation. One can read up to 5K in some situations, although 2500 is more common.

  • john
DBonh.1
DBonh.1Author
Associate III
July 12, 2022

Great. Although I won't have a complete eval kit until Monday because I loaned out my Nucleo-F401 boards, got more on order. I do have a Nucleo-H7 board along with some LV53L5C boards sitting here. Do you have a Nucleo-H7 driver for your sensor board? Or is it easier for me to wait for more F401s on Monday?

John E KVAM
ST Employee
July 12, 2022

Way easier to wait. The Graphical User Interface software was really only built on the F401RE, and although it could be rebuilt, it would take long than a few days of test time.

Sorry about that.

  • john
DBonh.1
DBonh.1Author
Associate III
July 12, 2022

No prob, we can stall this case till Monday. Talk to ya then. Thanks! -Doug

DBonh.1
DBonh.1Author
Associate III
July 13, 2022

I got itchy to pursue this so I overnighted a Nucleo board from Mouser. Here's first glimpse of my Atmel side-by-side with STM Eval Board. The Eval board's init function shows additional write statements before each read. This might reflect a problem with how I structure my read statements, not sure yet. I will continue investigating this lead. No need for you to dig in yet until I investigate. But if you know something off hand it might help. I should know more by tomorrow. Thanks! -Doug 406.830.0373.

AlexCloned
Senior
July 15, 2022

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

AlexCloned
Senior
July 15, 2022

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
DBonh.1Author
Associate III
July 15, 2022

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?

AlexCloned
Senior
July 15, 2022

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.

AlexCloned
Senior
July 15, 2022

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.