cancel
Showing results for 
Search instead for 
Did you mean: 

VL53L8CX will not initialize correctly on big-endian machine

John E KVAM
ST Employee

If your VL53L8CX gets past the 'is_alive' function but you cannot get it to run, it might be because you are running on a big-endian machine, and the ST code you downloaded assumes a little-endian machine.

Try swapping your vl53l8cx_is_alive function with this one.

It reads 4 bytes by bytes, by words and by longwords. 

You will get a warning about the implicit definition of printf, so add

 

 

#include <stdio.h>

 

 

if you are careful about getting warnings.

 

 

 

uint8_t vl53l8cx_is_alive(
		VL53L8CX_Configuration		*p_dev,
		uint8_t				*p_is_alive)
{
	uint8_t status = VL53L8CX_STATUS_OK;
	uint8_t device_id, revision_id, byte2, byte3;
	uint16_t chip_id, word2;
	uint32_t long_id;

	status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x00);
	status |= VL53L8CX_RdByte(&(p_dev->platform), 0, &device_id);
	status |= VL53L8CX_RdByte(&(p_dev->platform), 1, &revision_id);
	status |= VL53L8CX_RdByte(&(p_dev->platform), 2, &byte2);
	status |= VL53L8CX_RdByte(&(p_dev->platform), 3, &byte3);
	status |= VL53L8CX_RdMulti(&(p_dev->platform), 0, (uint8_t *)&chip_id,2);
	status |= VL53L8CX_RdMulti(&(p_dev->platform), 2, (uint8_t *)&word2,2);
	status |= VL53L8CX_RdMulti(&(p_dev->platform), 0, (uint8_t *)&long_id,4);
	status |= VL53L8CX_WrByte(&(p_dev->platform), 0x7fff, 0x02);

	printf("by bytes\n %02x,%02x,%02x,%02x\n", device_id, revision_id, byte2,byte3);
	printf("by words\n %04x,%04x\n",chip_id, word2);
	printf("by longword\n %08lx\n",long_id);
	if((device_id == (uint8_t)0xF0) && (revision_id == (uint8_t)0x0C))
	{
		*p_is_alive = 1;
	}
	else
	{
		*p_is_alive = 0;
	}

	return status;
}

 

 

 If it all works correctly, you should get:

 

 

by bytes
 f0,0c,62,01
by words
 0cf0,0162
by longword
 01620cf0

 

 

The device ID is F0 and the Revision ID is 0C. 

The other two bytes don't matter, except they are constants and if the order matches, you are good.

But what if you do not get these results?

If you are on a big-endian, 32-bit machine, have a look at the function SwapBuffer.

 

 

void VL53L8CX_SwapBuffer(
		uint8_t 		*buffer,
		uint16_t 	 	 size)
{
	uint32_t i, tmp;

	/* Example of possible implementation using <string.h> */
	for(i = 0; i < size; i = i + 4)
	{
		tmp = (
		  buffer[i]<<24)
		|(buffer[i+1]<<16)
		|(buffer[i+2]<<8)
		|(buffer[i+3]);

		memcpy(&(buffer[i]), &tmp, 4);
	}
}

 

 

This function is called before every WrMulti, and after every RdMulti. 

The I2C protocol, is big-endian, and the STM32 that we wrote the code for is Little-endian. 

If you have a big-endian machine, simply have SwapBuffer return without doing anything and try running again. 

Should work.

- 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.
0 REPLIES 0