2024-02-16 08:32 AM
I am attempting to connect the satel-vl53l8a to the Nordic Semiconductor nRF5340 using the I2C protocol, but I am not receiving any acknowledgment (ACK). I have followed the wiring diagrams provided in this document: AN5945. Additionally, I have captured the output of my logic analyzer for reference.
Solved! Go to Solution.
2024-02-29 07:29 AM
Something is clearly wrong - You cannot get large negative distances. And the status byte is always between 0 and 20 (plus 255).
Step one - meticulously check all the status returns on every call.
But all the problems I've seen with this chip are I2C problems.
There are two types: 1 is a byte-swap or word-swap. Your data is transmitted, so it looks right, but the sensor gets the wrong meaning.
The other issue is the long WrMulti. Some MCUs cannot handle those long writes at initialization.
As you are getting a result - even a bad one, it looks like you are past the long write issue.
So I'm going to guess you have a word swap issue.
Take that bit of code above and try this.
Use 4 WrByte calls to write 4 consecutive bytes starting at location 100. Then read it back with 2 WrWord() calls, and 1 WrDWord. You should get the data you wrote - in the correct order.
And if you wanted to be complete you, could do a 4-byte WrMulti, and read it back 3 other ways.
-john
2024-02-16 09:55 AM
The sensor is pretty complicated, but the I2C is not. It needs power, ground, and an I2C. And you need to lift the LPn pin. I'm betting it the LPn pin. Essentially, this pin enables the I2C. That app note tells you to connect the pin, but does not provide much in the way of protocol. It assumes you are using the ST provided software.
When you get the ACK, try this bit of code:
/* --------------------------------------------------
* --- This function can be used to test VL53L5CX I2C
* --------------------------------------------------
*/
uint8_t vl53l5cx_test_i2c(VL53L5CX_Configuration *p_dev){
uint8_t status = VL53L5CX_STATUS_OK;
printf("Starting VL53L5CX I2C test...\n");
/* To check the I2C RdByte/WrByte function :
* Inside the function “vl53l5cx_is_alive()”, it will call I2C RdByte/WrByte to
* read device and verion ID. which can help you to verify the I2C RdByte/WrByte
* functions at same time.
*/
uint8_t device_id, revision_id;
status |= WrByte(&(p_dev->platform), 0x7fff, 0x00);
status |= RdByte(&(p_dev->platform), 0, &device_id);
status |= RdByte(&(p_dev->platform), 1, &revision_id);
status |= WrByte(&(p_dev->platform), 0x7fff, 0x02);
if(status)
{
printf("Error Rd/Wr byte: status %u\n", status);
return status;
}
/* To check the I2C RdMulti/WrMulti function:
* Below is example codes which can help you vefify the I2C RdMulti/WrMulti
* function.
*/
uint8_t Data_write[4]={0x5A,0xA5,0xAA,0x55};
uint8_t Data_read[4]={0,0,0,0};
uint8_t Data_default[4]={0,0,0,0};
status |= RdMulti(&(p_dev->platform), 0x100, Data_default, 4);
if(status)
{
printf("Error RdMulti: status %u\n", status);
return status;
}
printf("Read default value and save it at begging\n");
printf("Data_default (0x%x)\n", Data_default[0]);
printf("Data_default (0x%x)\n", Data_default[1]);
printf("Data_default (0x%x)\n", Data_default[2]);
printf("Data_default (0x%x)\n", Data_default[3]);
status |= WrMulti(&(Dev.platform), 0x100, Data_write, 4);
if(status)
{
printf("Error WrMulti: status %u\n", status);
return status;
}
printf("Writing values 0x5A 0xA5 0xAA 0x55\n");
status |= RdMulti(&(p_dev->platform), 0x100, Data_read, 4);
if(status)
{
printf("Error RdMulti: status %u\n", status);
return status;
}
printf("Reading:\n");
printf("Data_read (0x%x)\n", Data_read[0]);
printf("Data_read (0x%x)\n", Data_read[1]);
printf("Data_read (0x%x)\n", Data_read[2]);
printf("Data_read (0x%x)\n", Data_read[3]);
status |= WrMulti(&(Dev.platform), 0x100, Data_default, 4);
printf("Write back default value\n");
if(status)
{
printf("Error WrMulti: status %u\n", status);
return status;
}
status |= RdMulti(&(Dev.platform), 0x100, Data_default, 4);
if(status)
{
printf("Error RdMulti: status %u\n", status);
return status;
}
printf("Read value again to make sure default value was correct loaded\n");
printf("Data_default (0x%x)\n", Data_default[0]);
printf("Data_default (0x%x)\n", Data_default[1]);
printf("Data_default (0x%x)\n", Data_default[2]);
printf("Data_default (0x%x)\n", Data_default[3]);
printf("I2C test done - everything works fine.\n");
return status;
}
2024-02-16 11:39 AM
Thank you very much for responding promptly. I've produced a video to illustrate my problem: YouTube link.
Essentially, I've ensured that all the pins are correctly configured, yet I'm still unable to receive an ACK from the sensor. I'm uncertain about what mistake I might be making.
2024-02-19 12:43 AM
Ok, so I got the i2c working. I was interpreting the 8-bit address as a 7-bit address. Hence the confusion. And now i am facing another issue. It is with the code provided where it says to mandatory update the firmware by calling the int function. When that function is called it fails. Do we need to update the firmware or use that function?
I am currently testing your above code to see if the Read/Write i2c functions work. Thank you.
2024-02-19 07:34 AM
there are a few common issues with I2C.
1) the STM32 can do a very long I2C write. Most other MCUs cannot. So I'm guessing the init fails because your MCU writes smaller chunks. Some max out at 255 bytes, others at 127 or 128.
re-write the Init with a 'chunk' size.
There is another thread on this topic.
Re: VL53L5CX driver vl53l5cx_init() fails - Page 5 - STMicroelectronics Community
Next issue is byte swap. Or word swap. Thing wont work out until you figure out if your machines endian matches with the STM32.
That other thread has come code that can help.
- john
2024-02-20 09:22 AM
Dear John,
I appreciate your prompt response. I have once again created a video illustrating my ongoing struggle https://youtube.com/live/NKhth-AvypM. There are a few points I am certain about:
I have two inquiries:
Thank you for your ongoing assistance.
2024-02-21 07:59 AM
Hello John,
I've managed to get the VL53L8CX ULD ready (Version: VL53L8CX_1.2.1) operational, at least it progresses beyond the initialization phase. I'm currently attempting to execute Example 1 - Ranging basis. However, the output appears to not make too much sense.
During the 1st iteration: VL53L8CX ULD ready (Version: VL53L8CX_1.2.1)
Status is : 0
Print data no : 0
Zone : 0, Status : 41, Distance : -3369 mm
Zone : 1, Status : 187, Distance : 4839 mm
Zone : 2, Status : 218, Distance : -4285 mm
Zone : 3, Status : 30, Distance : 2845 mm
Zone : 4, Status : 181, Distance : 1439 mm
Zone : 5, Status : 10, Distance : -1048 mm
Zone : 6, Status : 226, Distance : -7736 mm
Zone : 7, Status : 11, Distance : 6499 mm
Zone : 8, Status : 119, Distance : 5283 mm
Zone : 9, Status : 187, Distance : -2201 mm
Zone : 10, Status : 160, Distance : 1291 mm
Zone : 11, Status : 12, Distance : 5704 mm
Zone : 12, Status : 184, Distance : -4217 mm
Zone : 13, Status : 170, Distance : -6485 mm
Zone : 14, Status : 1, Distance : 5729 mm
Zone : 15, Status : 214, Distance : 3365 mm
By the 10th iteration, all values are zero:
Status is : 0
Print data no : 9
Zone : 0, Status : 41, Distance : 0 mm
Zone : 1, Status : 187, Distance : 0 mm
Zone : 2, Status : 218, Distance : 0 mm
Zone : 3, Status : 30, Distance : 0 mm
Zone : 4, Status : 181, Distance : 0 mm
Zone : 5, Status : 10, Distance : 0 mm
Zone : 6, Status : 226, Distance : 0 mm
Zone : 7, Status : 11, Distance : 0 mm
Zone : 8, Status : 119, Distance : 0 mm
Zone : 9, Status : 187, Distance : 0 mm
Zone : 10, Status : 160, Distance : 0 mm
Zone : 11, Status : 12, Distance : 0 mm
Zone : 12, Status : 184, Distance : 0 mm
Zone : 13, Status : 170, Distance : 0 mm
Zone : 14, Status : 1, Distance : 0 mm
Zone : 15, Status : 214, Distance : 0 mm
I'm perplexed by this output. Could you assist me in deciphering its meaning? Additionally, do you know if there's a datasheet available for this sensor that provides explanations for each of the register values and their functions?
2024-02-28 09:26 PM
Hello John,
I hope you're well. I'm reaching out regarding the issues I've outlined above, and I'm hoping you might be able to assist me. I've been facing this challenge for some time now. While the firmware successfully updates, it encounters difficulties retrieving ranging information. Specifically, the code anticipates receiving 532 bytes from the sensor, but my logic analyzer indicates that only 21 bytes are being sent. How should I proceed to troubleshoot this problem and make progress? Any insights you can provide would be greatly appreciated.
2024-02-29 07:29 AM
Something is clearly wrong - You cannot get large negative distances. And the status byte is always between 0 and 20 (plus 255).
Step one - meticulously check all the status returns on every call.
But all the problems I've seen with this chip are I2C problems.
There are two types: 1 is a byte-swap or word-swap. Your data is transmitted, so it looks right, but the sensor gets the wrong meaning.
The other issue is the long WrMulti. Some MCUs cannot handle those long writes at initialization.
As you are getting a result - even a bad one, it looks like you are past the long write issue.
So I'm going to guess you have a word swap issue.
Take that bit of code above and try this.
Use 4 WrByte calls to write 4 consecutive bytes starting at location 100. Then read it back with 2 WrWord() calls, and 1 WrDWord. You should get the data you wrote - in the correct order.
And if you wanted to be complete you, could do a 4-byte WrMulti, and read it back 3 other ways.
-john