2023-03-07 05:52 PM
Hi all,
For the last several days I have been battling this API for the VL53L5CX and finally reached the point where the initialisation passes every time. I proceed to set some of the configuration parameters (mostly resetting to the default values suggested in the application note). These functions also return status = 0.
Then I start a ranging session. The problem is that checking the status/error output shows me that the function is failing with a 255 error. Further investigation with a debugger has yielded that the final if() check in the function sets the status too 255. This means that the data_read_size check has failed. see screenshot below for reference.
I should note that, every single function and I2C transaction passes with no error. In other words, status = 0, the whole time, until this if statement. It is the physical value of the variables that does not match. Has anyone else had this error? or can offer some suggestions as to what is happening and how to fix it?
Thanks
2023-03-09 04:12 PM
check the value of status prior to the final check. My thought is that they are all failing, but at the last line you set it to 255 masking all the other failures.
I like status += function() better than status |= but there are advantages to both.
print out thd two values that don't match - and should.
There might be an answer there.
2023-03-09 04:17 PM
hi John,
I am using a debugger to individually step through each line and monitor the status. it remains zero until it enters the if statement. there it gets set to 255. With the debugger i can see the variables as they get edited. the value of "tmp" is read out as 0 from the temp_buffer its pulled from. Inspecting the I2c communications with a logic analyser also shows that the sensor is sending back "0'.
The question remains, how does every other read/write pass with no errors, and yet this check fails
2023-03-10 08:30 AM
The status of the last read is OK and you read 0 bytes? That does not seem right. But I can guess...
The STM can read and write 32k bytes in one go. But it's one of the few MCUs that can do that.
All other MCUs have a limitation of 512, 256 and one is limited to 16 bytes.
That read is requesting some 6K bytes.
And I'm going to guess your MCU can't to that in one go.
You can edit Platform.c and uncomment some of the result data. (Starting at line 114 or so.) That will reduce the length of your return buffer.
Or you can break the I2C request into smaller chunks.
2023-03-12 03:31 PM
I have implemented the I2C as a custom bit banging. I'm not storing the values in a temporary "i2c buffer" as most MCUs do when running the transactions. I.E. When writing the ULD library uses a pointer to where the data is. I simply increment that pointer and de-reference to send the value. When reading, this time the ULD seems to use the "temp_buffer" variable to store most reads. again the RdByte/Multi functions are passed a pointer to this buffer. I simply increment it for each byte read from the sensror.
I have also reduced the size of the data down to 64 Bytes. By uncommenting most of the disable macros. At this stage I've also changed the RdMulti and WrMulti functions. Writing will send 64 byte blocks. Reading will read 1 byte at a time. I still get the same behaviour.
2023-11-02 12:38 PM
Hello,
I have a verry similar problem on a vl53l8cx. Have you found a solution?
Thanks
2023-11-14 06:21 AM
hello
Did you try John's sugestion regarding IC2 chunks ?
I mean :
The STM can read and write 32k bytes in one go. But it's one of the few MCUs that can do that.
All other MCUs have a limitation of 512, 256 and one is limited to 16 bytes.
That read is requesting some 6K bytes.
And I'm going to guess your MCU can't to that in one go.
You can edit Platform.c and uncomment some of the result data. (Starting at line 114 or so.) That will reduce the length of your return buffer.
Or you can break the I2C request into smaller chunks.
Anne
2024-03-19 08:50 AM
I am having similar issues to the original poster. It seems that I am able to init the vl53l5cx but when I try reading any data (not just ranging), even the resolution, it returns 0 for the data but also returns 0 for status...very confusing.
Here is my swap buffer code:
void VL53L5CX::SwapBuffer(uint8_t *buffer, uint16_t size)
{
uint32_t i, tmp;
//TODO: Swap buffer gets 0 for resolution and range ui content
/* 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]);
// PX4_INFO("Swapped: %lu", tmp);
memcpy(&(buffer[i]), &tmp, 4);
}
Also here is my RdMulti
uint8_t VL53L5CX::RdMulti(VL53L5CX_Platform *p_platform, uint16_t RegisterAddress,
uint8_t *p_values, uint32_t size)
{
int8_t ret;
uint8_t mread_local[2];
/* Write the register address of the sensor*/
mread_local[0] = (RegisterAddress >> 8) & 0xff;
mread_local[1] = RegisterAddress & 0xff;
ret = transfer(&mread_local[0], sizeof(mread_local), nullptr, 0);
if (ret != PX4_OK) {
perf_count(_comms_errors);
return ret;
}
ret = transfer(nullptr, 0, p_values, size);
if (ret != PX4_OK) {
perf_count(_comms_errors);
return ret;
}
return PX4_OK;
}
It appears that when I specifically try to read the data buffer for resolution, the swap buffer has a bunch of zeros. When I compare the tmp with p_dev->data_read_size I always fail this check, again due to swapbuffer only getting 0's from the device.
2024-03-19 09:37 AM
If you are not getting any answers back - everything zero - then I'm going to guess you did not get the processor started.
During the initialization phase you need to download some 80K of data. With the last byte, the ranging engine will start.
Could you have a look at the code in:
Solved: How do I verify I have my I2C configured correctly... - STMicroelectronics Community
And add that to the top of your program.
Hopefully it will verify your I2C interface.
- john
2024-03-19 10:13 AM
Thanks John! So the strange thing is the return status is fine, but there is no data being received.
I am able to pass all the poll for answers at firmware update. Now I did have to chunk out the firmware update into blocks <=1024 bytes, and this may be the issue. I am running on an nxp s32k344:
/* Download FW into VL53L5 */
status |= WrByte(&(p_dev->platform), 0x7fff, 0x09);
// WaitMs(&(p_dev->platform), 1);
uint32_t fw_addr = 0x0;
// Transfer initial 32k bytes
for (uint8_t i = 0; i < 32; ++i) {
status |= WrMulti(&(p_dev->platform), 0, (uint8_t *)&VL53L5CX_FIRMWARE[fw_addr], 0x400);
// WaitMs(&(p_dev->platform), 5);
fw_addr += 0x400;
}
status |= WrByte(&(p_dev->platform), 0x7fff, 0x0a);
// Transfer next 32k bytes
for (uint8_t i = 0; i < 32; ++i) {
status |= WrMulti(&(p_dev->platform), 0, (uint8_t *)&VL53L5CX_FIRMWARE[fw_addr], 0x400);
// WaitMs(&(p_dev->platform), 5);
fw_addr += 0x400;
}
status |= WrByte(&(p_dev->platform), 0x7fff, 0x0b);
for (uint8_t i = 0; i < 20; ++i) {
status |= WrMulti(&(p_dev->platform), 0, (uint8_t *)&VL53L5CX_FIRMWARE[fw_addr], 0x400);
// WaitMs(&(p_dev->platform), 5);
fw_addr += 0x400;
}
// WaitMs(&(p_dev->platform), 10);
PX4_INFO("last transfer: %lu", fw_addr);