2024-01-05 06:04 AM
Hi ! I'm using the VL53L4CD sensor's example with the Nucleo-L432KC.
A first problem I solved was that the VL53L4CD didn't have the adress 0x52 as in the documentation, but 0x29 (this problem has already mentioned in a topic).
My current problem is that the following code return a good status but a wrong id :
'''
'''
It gives back the address 0.
It should be the basic code, but it doesn't work.
Have you got a solution ?
Thank you !
Clément Poisson.
Solved! Go to Solution.
2024-01-08 07:03 AM
I'm stuck setting up for CES, and I cannot verify it, but I think I see something.
The VL53 sensors (unlike other I2C devices) use a 16 bit address to decide which location to read.
uint8_t VL53L4CD_WrDWord(Dev_t dev, uint16_t RegisterAdress, uint32_t value)
That uint16_t is not kidding. They really want that.
But later you have the line:
status = HAL_I2C_Mem_Write(I2C, dev, (uint8_t)RegisterAdress,1, (uint8_t*)towrite, 4, I2CTIMEOUT);
This sends only half the register address. I think changing the 1 to a 2 should do it.
Fix it in all locations.
- john
2024-01-05 09:16 AM
The first thing to know about the I2C bus is that it has a funny addressing scheme.
There is a base address, and to make the write address, one shifts the base to the left one bit.
The LSB is now the Write/Read bit.
So 0x29 turns into 0x52 as a write address and 0x53 as a read address.
So when it comes to I2C 0x29 is 0x52.
(And i know, it's a mess. )
I'm going to guess that you don't get a good ID because your chip is not on, and your I2C read command is timing out.
Unfortunately that "if ( status || ( sensor_id != 0xEBAA ))" does not distinguish between an I2C timeout and no data.
i've included a bit of verification code.
But do check that the Xshut line is high and that you have power.
- john
2024-01-08 05:49 AM
Thank you so much for your answer, I now understand about the 7bits I2C adress and finally find the 0x52 et 0x53.
I used your I2C verification function, but it still doesn't give a good result :
expected = ebaa10ff,
read_bytes = 0, 29, 0, 0
read words = 0, 56a2
read dword = 0
Even regarding the bit to bit, I don't see any correspondances or logic between theses results.
Here is my platform file for the read/write functions :
/*
Copyright (c) 2021, STMicroelectronics - All Rights Reserved
This file : part of VL53L4CD Ultra Lite Driver and : 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 : strictly prohibited unless
specifically authorized in writing by STMicroelectronics.
*******************************************************************************
Alternatively, VL53L4CD 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:
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"
uint8_t VL53L4CD_RdDWord(Dev_t dev, uint16_t RegisterAdress, uint32_t *value)
{
uint8_t status = 255;
uint8_t temp[4];
status = HAL_I2C_Mem_Read(I2C, dev, (uint8_t)RegisterAdress,1, temp, 4, I2CTIMEOUT);
*value = (((uint32_t)temp[0])<<24) | (((uint32_t)temp[1])<<16) | (((uint32_t)temp[2])<<8) | (temp[3]);
checkI2CError(status);
return status;
}
uint8_t VL53L4CD_RdWord(Dev_t dev, uint16_t RegisterAdress, uint16_t *value)
{
uint8_t status = 255;
uint8_t temp[4];
status = HAL_I2C_Mem_Read(I2C, dev, (uint8_t)RegisterAdress,1, temp, 2, I2CTIMEOUT);
*value = (((uint16_t)temp[0])<<8) | (temp[1]);
checkI2CError(status);
return status;
}
uint8_t VL53L4CD_RdByte(Dev_t dev, uint16_t RegisterAdress, uint8_t *value)
{
uint8_t status = 255;
status = HAL_I2C_Mem_Read(I2C, dev, (uint8_t)RegisterAdress,1, value, 1, I2CTIMEOUT);
checkI2CError(status);
return status;
}
uint8_t VL53L4CD_WrByte(Dev_t dev, uint16_t RegisterAdress, uint8_t value)
{
uint8_t status = 255;
status = HAL_I2C_Mem_Write(I2C, dev, (uint8_t)RegisterAdress,1, &value, 1, I2CTIMEOUT);
checkI2CError(status);
return status;
}
uint8_t VL53L4CD_WrWord(Dev_t dev, uint16_t RegisterAdress, uint16_t value)
{
uint8_t status = 255;
uint8_t towrite[2];
towrite[0]=(uint8_t)(value>>8 & 0xFF); //MSB
towrite[1]=(uint8_t)(value & 0xFF); //LSB
status = HAL_I2C_Mem_Write(I2C, dev, (uint8_t)RegisterAdress,1, (uint8_t*)towrite, 2, I2CTIMEOUT);
checkI2CError(status);
return status;
}
uint8_t VL53L4CD_WrDWord(Dev_t dev, uint16_t RegisterAdress, uint32_t value)
{
uint8_t status = 255;
uint8_t towrite[4];
towrite[0]=(uint8_t)(value>>24 & 0xFF); //MSB
towrite[1]=(uint8_t)(value>>16 & 0xFF);
towrite[2]=(uint8_t)(value>>8 & 0xFF);
towrite[3]=(uint8_t)(value & 0xFF); //LSB
status = HAL_I2C_Mem_Write(I2C, dev, (uint8_t)RegisterAdress,1, (uint8_t*)towrite, 4, I2CTIMEOUT);
checkI2CError(status);
return status;
}
uint8_t WaitMs(Dev_t dev, uint32_t TimeMs)
{
uint8_t status = 255;
HAL_Delay(TimeMs);
return status;
}
void checkI2CError(uint8_t status)
{
if (status != HAL_OK) {
printf("I2C error: ");
I2C_HandleTypeDef *hi2c; // Assume hi2c is initialized and points to your I2C handle
if (hi2c->ErrorCode & HAL_I2C_ERROR_BERR) {
printf("Bus error\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_ARLO) {
printf("Arbitration lost error\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_AF) {
printf("Acknowledge failure\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_OVR) {
printf("Overrun error\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_DMA) {
printf("DMA transfer error\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_TIMEOUT) {
printf("Timeout error\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_SIZE) {
printf("Size mismatch\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_NONE) {
printf("No error\n");
}
}
}
Do you have a solution ? Or do you see an error in the platform ?
Thank you again for your time !
Clement Poisson.
2024-01-08 05:51 AM
I just precise that the message "I2C test failed" isn't printed*
2024-01-08 07:03 AM
I'm stuck setting up for CES, and I cannot verify it, but I think I see something.
The VL53 sensors (unlike other I2C devices) use a 16 bit address to decide which location to read.
uint8_t VL53L4CD_WrDWord(Dev_t dev, uint16_t RegisterAdress, uint32_t value)
That uint16_t is not kidding. They really want that.
But later you have the line:
status = HAL_I2C_Mem_Write(I2C, dev, (uint8_t)RegisterAdress,1, (uint8_t*)towrite, 4, I2CTIMEOUT);
This sends only half the register address. I think changing the 1 to a 2 should do it.
Fix it in all locations.
- john
2024-01-09 12:01 AM
Oh yes of curse ! Thank you so much for your help !
I am just giving my corrected platform to help who would want it.
/*
Copyright (c) 2021, STMicroelectronics - All Rights Reserved
This file : part of VL53L4CD Ultra Lite Driver and : 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 : strictly prohibited unless
specifically authorized in writing by STMicroelectronics.
*******************************************************************************
Alternatively, VL53L4CD 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:
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"
uint8_t VL53L4CD_RdDWord(Dev_t dev, uint16_t RegisterAdress, uint32_t *value)
{
uint8_t status = 255;
uint8_t temp[4];
status = HAL_I2C_Mem_Read(I2C, dev, RegisterAdress,2, temp, 4, I2CTIMEOUT);
*value = (((uint32_t)temp[0])<<24) | (((uint32_t)temp[1])<<16) | (((uint32_t)temp[2])<<8) | (temp[3]);
checkI2CError(status);
return status;
}
uint8_t VL53L4CD_RdWord(Dev_t dev, uint16_t RegisterAdress, uint16_t *value)
{
uint8_t status = 255;
uint8_t temp[2];
status = HAL_I2C_Mem_Read(I2C, dev, RegisterAdress,2, &temp, 2, I2CTIMEOUT);
*value = (((uint16_t)temp[0])<<8) | (temp[1]);
checkI2CError(status);
return status;
}
uint8_t VL53L4CD_RdByte(Dev_t dev, uint16_t RegisterAdress, uint8_t *value)
{
uint8_t status = 255;
status = HAL_I2C_Mem_Read(I2C, dev, RegisterAdress,2, value, 1, I2CTIMEOUT);
checkI2CError(status);
return status;
}
uint8_t VL53L4CD_WrByte(Dev_t dev, uint16_t RegisterAdress, uint8_t value)
{
uint8_t status = 255;
status = HAL_I2C_Mem_Write(I2C, dev, RegisterAdress,2, &value, 1, I2CTIMEOUT);
checkI2CError(status);
return status;
}
uint8_t VL53L4CD_WrWord(Dev_t dev, uint16_t RegisterAdress, uint16_t value)
{
uint8_t status = 255;
uint8_t towrite[2];
towrite[0]=(uint8_t)(value>>8 & 0xFF);
towrite[1]=(uint8_t)(value & 0xFF);
status = HAL_I2C_Mem_Write(I2C, dev, RegisterAdress,2, (uint8_t*)towrite, 2, I2CTIMEOUT);
checkI2CError(status);
return status;
}
uint8_t VL53L4CD_WrDWord(Dev_t dev, uint16_t RegisterAdress, uint32_t value)
{
uint8_t status = 255;
uint8_t towrite[4];
towrite[0]=(uint8_t)(value>>24 & 0xFF);
towrite[1]=(uint8_t)(value>>16 & 0xFF);
towrite[2]=(uint8_t)(value>>8 & 0xFF);
towrite[3]=(uint8_t)(value & 0xFF);
status = HAL_I2C_Mem_Write(I2C, dev, RegisterAdress,2, (uint8_t*)towrite, 4, I2CTIMEOUT);
checkI2CError(status);
return status;
}
uint8_t WaitMs(Dev_t dev, uint32_t TimeMs)
{
uint8_t status = 255;
HAL_Delay(TimeMs);
return status;
}
void checkI2CError(uint8_t status)
{
if (status != HAL_OK) {
printf("I2C error: ");
I2C_HandleTypeDef *hi2c; // Assume hi2c is initialized and points to your I2C handle
if (hi2c->ErrorCode & HAL_I2C_ERROR_BERR) {
printf("Bus error\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_ARLO) {
printf("Arbitration lost error\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_AF) {
printf("Acknowledge failure\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_OVR) {
printf("Overrun error\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_DMA) {
printf("DMA transfer error\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_TIMEOUT) {
printf("Timeout error\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_SIZE) {
printf("Size mismatch\n");
}
if (hi2c->ErrorCode & HAL_I2C_ERROR_NONE) {
printf("No error\n");
}
}
}