Skip to main content
Visitor II
November 16, 2023
Solved

WrMulti function ULD for the vl53l5cx running in Zephyr return error on the I2C line

  • November 16, 2023
  • 3 replies
  • 2041 views

I am attempting to write the platform code for the ULD to work with Zephyr. WrByte, RdByte, and RdMulti are running correctly, but the WrMulti function is throwing two types of errors:

<err> i2c_nrfx_twim: Error on I2C line occurred for message 0

<err> i2c_nrfx_twim: Error 0x0BAE0001 occurred for message 0.

The second error appears to be an issue with NACK, but it seems strange that there is no NACK when writing a single byte (WrByte) and NACK is received when attempting to write more (WrMulti). I'm attaching the platform files in case someone could lend me a hand. Thank you in advance.

Best answer by John E KVAM

if you look into the Zephyr you will find (I'm guessing) that there is a limit to the length of I2C they can write in one go. And I'm guessing you have exceeded it.

The STM32 is one of the rare chips that can send an I2C write of 0x8000 bytes.

What you have to do is dig in there and break up your I2C writeMulti into chunks suitable to your processor. 

On this forum is the code that someone posted but I cannot find the one I was looking for, but one guy implemented it like this:

uint8_t WrMultiLarge(VL53L5CX_Platform *p_platform,
 uint16_t RegisterAdress,
 uint8_t *p_values,
 uint32_t size) {
 // Solution based on https://forum.arduino.cc/t/stream-large-array-to-i2c-slave/659405/4
 
 // uses raw I2C writes, rather than use the txbuffer
 PERIPH_WIRE.startTransmissionWIRE(((p_platform->address) >> 1) & 0x7F, WIRE_WRITE_FLAG);
 
 // Send address of register
 PERIPH_WIRE.sendDataMasterWIRE((byte)(RegisterAdress >> 8));
 PERIPH_WIRE.sendDataMasterWIRE((byte)(RegisterAdress & 0xFF));
 
 // send one byte at a time from the array to the I2C device
 for (unsigned int i = 0; i < size; i++) {
 if (!PERIPH_WIRE.sendDataMasterWIRE((byte) p_values[i])){ 
 Serial.println("Write error at index "); Serial.println(i); 
 }
 }
 
 // stop sending the data
 PERIPH_WIRE.prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
 
 return 0; // No error checking :(
}
 
uint8_t WrMulti(
		VL53L5CX_Platform *p_platform,
		uint16_t RegisterAdress,
		uint8_t *p_values,
		uint32_t size)
{
 // The arduino Wire TX buffer size found in your arduino core's Wire.h
 // For samd21 this is 256, but for other cores it varies widely
 if (size>=256) { 
 return WrMultiLarge(p_platform, RegisterAdress, p_values, size);
 }
 
 Wire.beginTransmission(((uint8_t)(((p_platform->address) >> 1) & 0x7F)));
 
 const 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){ Serial.print("Write error at offset "); Serial.println(i); }
 }
 
 uint8_t code = Wire.endTransmission(true);
 return code;
}

 

3 replies

John E KVAM
John E KVAMBest answer
ST Employee
November 16, 2023

if you look into the Zephyr you will find (I'm guessing) that there is a limit to the length of I2C they can write in one go. And I'm guessing you have exceeded it.

The STM32 is one of the rare chips that can send an I2C write of 0x8000 bytes.

What you have to do is dig in there and break up your I2C writeMulti into chunks suitable to your processor. 

On this forum is the code that someone posted but I cannot find the one I was looking for, but one guy implemented it like this:

uint8_t WrMultiLarge(VL53L5CX_Platform *p_platform,
 uint16_t RegisterAdress,
 uint8_t *p_values,
 uint32_t size) {
 // Solution based on https://forum.arduino.cc/t/stream-large-array-to-i2c-slave/659405/4
 
 // uses raw I2C writes, rather than use the txbuffer
 PERIPH_WIRE.startTransmissionWIRE(((p_platform->address) >> 1) & 0x7F, WIRE_WRITE_FLAG);
 
 // Send address of register
 PERIPH_WIRE.sendDataMasterWIRE((byte)(RegisterAdress >> 8));
 PERIPH_WIRE.sendDataMasterWIRE((byte)(RegisterAdress & 0xFF));
 
 // send one byte at a time from the array to the I2C device
 for (unsigned int i = 0; i < size; i++) {
 if (!PERIPH_WIRE.sendDataMasterWIRE((byte) p_values[i])){ 
 Serial.println("Write error at index "); Serial.println(i); 
 }
 }
 
 // stop sending the data
 PERIPH_WIRE.prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
 
 return 0; // No error checking :(
}
 
uint8_t WrMulti(
		VL53L5CX_Platform *p_platform,
		uint16_t RegisterAdress,
		uint8_t *p_values,
		uint32_t size)
{
 // The arduino Wire TX buffer size found in your arduino core's Wire.h
 // For samd21 this is 256, but for other cores it varies widely
 if (size>=256) { 
 return WrMultiLarge(p_platform, RegisterAdress, p_values, size);
 }
 
 Wire.beginTransmission(((uint8_t)(((p_platform->address) >> 1) & 0x7F)));
 
 const 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){ Serial.print("Write error at offset "); Serial.println(i); }
 }
 
 uint8_t code = Wire.endTransmission(true);
 return code;
}

 

Visitor II
September 29, 2025

I am having trouble in uploading firmware please see if there is some error i am using DevaSys board and every time getting init failed i am attaching the logs also 

Zhiyuan.Han
Technical Moderator
September 30, 2025

Hi

From your log seems IC read write successfully with short data length, like vl53l5cx_is_alive() you have tried to read the device information, and the I2C works well.

The issue happens when you are trying to write big size date to device inside vl53l5cx_is_alive(), which used to download the FW to the device, take below line for example, the data's is 0x8000 bytes long, so my suggestion is to check if your platform supporting such big size data writing.  if not supported by your platform., you can try to split the big size into two 0x4000 .

status |= VL53L8CX_WrMulti(&(p_dev->platform),0,

(uint8_t*)&VL53L8CX_FIRMWARE[0],0x8000);

 

Br

Zhiyaun.Han

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Visitor II
September 30, 2025

tanmaygoyal_26_1-1759220538994.png

below is when i split the firmware into small chunk 16 bytes i am able to write 

tanmaygoyal_26_0-1759220501717.png

Please check if these two are correct to write the firmware

 

and also my connection 

gnd->gnd

avdd,iovdd,lpn->3v3(high)

scl->scl

sda->sda

i2c_rst->0(gnd)