2025-06-03 2:31 PM
The most viewed and commented post on the Imaging page had to do with an Init failure on the multizone part.
These parts have large I2C writes at the beginning, which is downloading the Firmware (on the L5 and L7) and downloading patch updates on the L8.
The solution was:
uint8_t WrMulti(VL53L8CX_Platform *p_platform, uint16_t RegisterAddress, uint8_t *p_values, uint32_t size) {
uint8_t status = HAL_OK; // Initialize status as HAL_OK
uint32_t remaining_size = size; // Calculate remaining size to write
uint16_t current_address = RegisterAddress; // Initialize current address
// 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;
// Perform write operation for current chunk
status = HAL_I2C_Mem_Write(&hi2c2, addr, current_address, I2C_MEMADD_SIZE_16BIT, p_values, current_chunk_size, 100);
// Check for error
if (status != HAL_OK) {
APP_LOG(TS_ON, 3, "[WrMulti] error. status %d, regADDR %d, size %d, remaining_size %d\n", status, current_address, size, remaining_size);
return status; // Return error 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;
HAL_Delay(10);
}
return status; // Return status (HAL_OK if all writes were successful)
}
Notice how he used the HAL command to write 16-bit addr and had to manually recalculate the current address before each loop.
chunk_size was defined as:
#define chunk_size (1<<8)
The same has to be done for RdMulti. as it tries to read 420 bytes at once at some point.
Do not try to read the registers after downloading firmware, to check if they match with the firmware, you just downloaded it. It will make init fail. And of course he used the default firmware download code.
Solved! Go to Solution.
2025-08-25 2:06 AM
Hello @John E KVAM,
Thanks for sharing this case and the solution you found.
To make this post more visible and easier to find by others who may face the same issue, I mark my reply as the solution.
Regards,
Maxime
@John E KVAM wrote:
The most viewed and commented post on the Imaging page had to do with an Init failure on the multizone part.
These parts have large I2C writes at the beginning, which is downloading the Firmware (on the L5 and L7) and downloading patch updates on the L8.
The solution was:
uint8_t WrMulti(VL53L8CX_Platform *p_platform, uint16_t RegisterAddress, uint8_t *p_values, uint32_t size) { uint8_t status = HAL_OK; // Initialize status as HAL_OK uint32_t remaining_size = size; // Calculate remaining size to write uint16_t current_address = RegisterAddress; // Initialize current address // 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; // Perform write operation for current chunk status = HAL_I2C_Mem_Write(&hi2c2, addr, current_address, I2C_MEMADD_SIZE_16BIT, p_values, current_chunk_size, 100); // Check for error if (status != HAL_OK) { APP_LOG(TS_ON, 3, "[WrMulti] error. status %d, regADDR %d, size %d, remaining_size %d\n", status, current_address, size, remaining_size); return status; // Return error 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; HAL_Delay(10); } return status; // Return status (HAL_OK if all writes were successful) }Notice how he used the HAL command to write 16-bit addr and had to manually recalculate the current address before each loop.
chunk_size was defined as:
#define chunk_size (1<<8)
The same has to be done for RdMulti. as it tries to read 420 bytes at once at some point.
Do not try to read the registers after downloading firmware, to check if they match with the firmware, you just downloaded it. It will make init fail. And of course he used the default firmware download code.
2025-08-25 2:06 AM
Hello @John E KVAM,
Thanks for sharing this case and the solution you found.
To make this post more visible and easier to find by others who may face the same issue, I mark my reply as the solution.
Regards,
Maxime
@John E KVAM wrote:
The most viewed and commented post on the Imaging page had to do with an Init failure on the multizone part.
These parts have large I2C writes at the beginning, which is downloading the Firmware (on the L5 and L7) and downloading patch updates on the L8.
The solution was:
uint8_t WrMulti(VL53L8CX_Platform *p_platform, uint16_t RegisterAddress, uint8_t *p_values, uint32_t size) { uint8_t status = HAL_OK; // Initialize status as HAL_OK uint32_t remaining_size = size; // Calculate remaining size to write uint16_t current_address = RegisterAddress; // Initialize current address // 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; // Perform write operation for current chunk status = HAL_I2C_Mem_Write(&hi2c2, addr, current_address, I2C_MEMADD_SIZE_16BIT, p_values, current_chunk_size, 100); // Check for error if (status != HAL_OK) { APP_LOG(TS_ON, 3, "[WrMulti] error. status %d, regADDR %d, size %d, remaining_size %d\n", status, current_address, size, remaining_size); return status; // Return error 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; HAL_Delay(10); } return status; // Return status (HAL_OK if all writes were successful) }Notice how he used the HAL command to write 16-bit addr and had to manually recalculate the current address before each loop.
chunk_size was defined as:
#define chunk_size (1<<8)
The same has to be done for RdMulti. as it tries to read 420 bytes at once at some point.
Do not try to read the registers after downloading firmware, to check if they match with the firmware, you just downloaded it. It will make init fail. And of course he used the default firmware download code.
2025-10-15 2:34 AM - edited 2025-10-15 2:36 AM
The STM32 HAL I2C library will not send more than 255 bytes in one go, even when using DMA. I found this out trying to use the firmware api to bring up the VL53L5CXV which is mounted on the B-U585 IOT board.
My solution was to implement a SW block transfer method that limits the number of bytes sent in one transfer to 255. The method keeps track of reading and writing addresses so it circumvents this hardware limitation. Too bad this powerful microcontroller (STM32U585) has an I2C perif that has this limitation. I guess that is the price for staying compatible with older STM32 variants.
It would be nice to be able to use SPI to do the transferring of 86 KBytes of firmware for this ranging sensor, since SPI has no 255 bytes limitation.
My last remark deals with the platform
void VL53L5CX_SwapBuffer
function.
The example stated is okay, but why not use the Cortex-M byte in word reverse (REV) function? Below is my (C++) implementation:
UInt32 CortexMProcessor::REV(const UInt32 value)
{
UInt32 result=0u;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
I can then do this (also C++ but easily adaptable to C):
for (auto i = 0u; i < size; i = i + 4)
{
auto *buffer32Value= reinterpret_cast<UInt32 *>(&buffer[i]);
const auto iw = *buffer32Value;
const auto resValue = CortexMProcessor::REV(iw);
*buffer32Value = resValue;
}
No messy manual swapping and calling memcpy anymore, much more compact and faster.