2021-08-11 02:47 AM
The Ultra Light Driver (STSW-IMG023) init function vl53l5cx_init() fails in this section :
/* Get offset NVM data and store them into the offset buffer */
status |= WrMulti(&(p_dev->platform), 0x2fd8,
(uint8_t*)VL53L5CX_GET_NVM_CMD, sizeof(VL53L5CX_GET_NVM_CMD));
status |= _vl53l5cx_poll_for_answer(p_dev, 4, 0,
VL53L5CX_UI_CMD_STATUS, 0xff, 2);
The sensor does not answer with '2' as expected by _vl53l5cx_poll_for_answer. (The senosr answers '0')
This results in a failed initialization.
How can this be fixed?
2021-08-18 10:58 AM
Update:
I have fixed the bug (RdMulti was casting length to a byte, truncating one of the reads).
This now works fine running demos 1 and 2 in the Arduino IDE (after renaming the ULD c and platform files cpp).
Here's my platform.cpp:
/*******************************************************************************
* Copyright (c) 2020, STMicroelectronics - All Rights Reserved
*
* This file is part of the VL53L5CX Ultra Lite Driver and is dual licensed,
* either 'STMicroelectronics Proprietary license'
* or 'BSD 3-clause "New" or "Revised" License' , at your option.
*
********************************************************************************
*
* 'STMicroelectronics Proprietary license'
*
********************************************************************************
*
* License terms: STMicroelectronics Proprietary in accordance with licensing
* terms at www.st.com/sla0081
*
* STMicroelectronics confidential
* Reproduction and Communication of this document is strictly prohibited unless
* specifically authorized in writing by STMicroelectronics.
*
*
********************************************************************************
*
* Alternatively, the VL53L5CX Ultra Lite Driver may be distributed under the
* terms of 'BSD 3-clause "New" or "Revised" License', in which case the
* following provisions apply instead of the ones mentioned above :
*
********************************************************************************
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*******************************************************************************/
#include "platform.h"
//#define DEBUG_MODE 1
uint8_t RdByte(
VL53L5CX_Platform *p_platform,
uint16_t RegisterAdress,
uint8_t *p_value)
{
return RdMulti(p_platform, RegisterAdress, p_value, 1);;
}
uint8_t WrByte(
VL53L5CX_Platform *p_platform,
uint16_t RegisterAdress,
uint8_t value)
{
return WrMulti(p_platform, RegisterAdress, &value, 1);
}
uint8_t WrMulti(
VL53L5CX_Platform *p_platform,
uint16_t RegisterAdress,
uint8_t *p_values,
uint32_t size)
{
#ifdef DEBUG_MODE
Serial.print("Beginning transmission to ");
Serial.print(((p_platform->address) >> 1) & 0x7F, HEX);
Serial.print("; Writing "); Serial.print(size); Serial.print(" bytes to register 0x");
Serial.println(RegisterAdress, HEX);
#endif
Wire.beginTransmission(((uint8_t)(((p_platform->address) >> 1) & 0x7F)));
uint8_t buffer[2] {RegisterAdress >> 8, RegisterAdress & 0xFF };
Wire.write(buffer, 2);
for (uint32_t i = 0 ; i < size ; i++) {
if(Wire.write(p_values[i])==0) { // buffer is full so this byte didn't write, flush buffer and restart sending at new offset
Wire.endTransmission(false); // writes out the current tx buffer, but hold the connection open since we're about to use it again
Wire.beginTransmission(((uint8_t)(((p_platform->address) >> 1) & 0x7F))); // restart sending data
buffer[0] = (RegisterAdress+i) >> 8;
buffer[1] = (RegisterAdress+i) & 0xFF;
Wire.write(buffer, 2);
if (Wire.write(p_values[i])==0) {
#ifdef DEBUG_MODE
Serial.println("Re-sending value after buffer flushed failed again");
#endif
}
}
}
uint8_t code = Wire.endTransmission(true);
#ifdef DEBUG_MODE
if (code) {
Serial.print("Write Status: ");
Serial.println(code);
}
#endif
return code;
}
uint8_t RdMulti(
VL53L5CX_Platform *p_platform,
uint16_t RegisterAdress,
uint8_t *p_values,
uint32_t size)
{
// based on https://github.com/stm32duino/VL53L1 i2c write function
int status = 0;
//Loop until the port is transmitted correctly
do {
Wire.beginTransmission(((uint8_t)(((p_platform->address) >> 1) & 0x7F)));
#ifdef DEBUG_MODE
Serial.print("Beginning transmission to ");
Serial.print(((p_platform->address) >> 1) & 0x7F, HEX);
Serial.print("; Reading "); Serial.print(size); Serial.print(" bytes from register 0x");
Serial.println(RegisterAdress, HEX);
#endif
const uint8_t buffer[2] {RegisterAdress >> 8, RegisterAdress & 0xFF };
Wire.write(buffer, 2);
status = Wire.endTransmission(false);
//Fix for some STM32 boards
//Reinitialize th i2c bus with the default parameters
#ifdef ARDUINO_ARCH_STM32
if (status) {
Wire.end();
Wire.begin();
}
#endif
//End of fix
} while (status != 0);
Wire.requestFrom(((uint8_t)(((p_platform->address) >> 1) & 0x7F)), size);
int i = 0;
while (Wire.available()) {
p_values[i] = Wire.read();
i++;
}
#ifdef DEBUG_MODE
Serial.print("Read "); Serial.print(i); Serial.print("/"); Serial.println(size);
for (i=0; i<size;i++) { Serial.print(" 0x"); Serial.print(p_values[i], HEX); }
Serial.println("");
#endif
return i!=size;
}
uint8_t Reset_Sensor(
VL53L5CX_Platform *p_platform)
{
uint8_t status = 0;
/* (Optional) Need to be implemented by customer. This function returns 0 if OK */
/* Set pin LPN to LOW */
/* Set pin AVDD to LOW */
/* Set pin VDDIO to LOW */
digitalWrite(8, LOW);
WaitMs(p_platform, 100);
/* Set pin LPN of to HIGH */
/* Set pin AVDD of to HIGH */
/* Set pin VDDIO of to HIGH */
digitalWrite(8, HIGH);
WaitMs(p_platform, 100);
return status;
}
void 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);
}
}
uint8_t WaitMs(
VL53L5CX_Platform *p_platform,
uint32_t TimeMs)
{
delay(TimeMs);
return 0;
}
2021-08-18 11:27 AM
So I looked at the three firmware writes to see if they are corrupted and they appear to be shifted to the right by two bytes. The first two bytes for each of the the three writes are zeros and then it matches the firmware - for a while - too big to look at all. I do not know a way to output my analyzer to a readable file to compare against the buffer file. Using Pulseview and an ten dollar analyzer but I am seeing what the code is sending and it is correct aside from the firmware leading zeros. I will keep at this and if I make any progress then I will post it.
2021-08-18 12:31 PM
After a lot of scrolling through logic probe data comparing it to what I was seeing I found and fixed the problem in my platform.cpp. It now appears to work fully. I've updated my comment above to contain the fixed version. The current version still requires that the Wire.h read buffer is increased from 256 to 512 though, since it doesn't handle read buffer overflows.
2021-08-18 01:03 PM
I'm not sure how notifications work here but I've posted a fully working platform.cpp for samd21 elsewhere in this thread.
2021-08-18 01:26 PM
Thanks for the Wire buffer lesson! This solved it for me.
2021-08-18 01:55 PM
For next time pulseview does let you dump hex or binary i2c data: https://www.sigrok.org/blog/even-more-pulseview-features-you-might-have-missed
That's what I used to debug the same issue. It doesn't separate the data into packets or anything so I had to reformat the data as a single line and search for the starting bytes I wanted in the i2c read or write hex dumps.
2021-08-20 09:29 AM
Thanks to SBonn2 this now works in the Arduino IDE, see here.
2021-08-28 07:18 AM
Hello,
I am facing the same problem with the Init() Function. Yet a bit earlier because the register 0x06 always gives me a 9 and not 1 as planned... Changing the VL53L5 does not make any difference. The documentation is not very helpful on this one... Have you faced the same issue in the past?
I am using the platform.c of the VL53L1 (for Zephyr).
Thanks for the help
2021-11-09 02:40 AM
Hi all,
if you are still interested, I found the reason why the Arduino VL53L5 library did not work with STM32duino Core. Basically, the WrMulti of 0x8000 bytes done to load the firmware in the sensor is too huge for that core and so the firmware is not loaded correctly. In order to fix it, I implemented a new version of the WrMulti, splitting the big written into small chunks. You can find here my Pull Request to fix this issue.
I hope it will be useful for everyone.
Best Regards,
Carlo
2022-01-07 05:30 AM
I was also struggling with some issues, a specific one that is not yet mentioned in this thread: it seemed important to use 400kHz I2C speed i.o. 100 kHz! (using NRF9160 microcontroller)