I2c EmbeddedLinuxMultimediaRefrence -> ApalisIMX8QM -> Ixora

I’m Having issue connecting a VL53L5CX sensor over i2c to the Apalis IMX8QM on the Ixora carrier board.

root@apalis-imx8-14903975:~# uname -a
Linux apalis-imx8-14903975 5.15.129-6.4.0+git.67c3153d20ff #1 SMP PREEMPT Wed Sep 27 12:30:36 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux

I’m using Pins 5/6 for connecting the sensor, however the address appears wrong when using i2cdetect.
The address should be 0x52, however it appears at 29 in i2c detect.

Heres the following steps I used to check the issue:

root@apalis-imx8-14903975:~# ls -l /dev/apalis-i2c*
lrwxrwxrwx 1 root root 5 Jan 24 16:30 /dev/apalis-i2c-on-module -> i2c-3
lrwxrwxrwx 1 root root 5 Jan 24 16:30 /dev/apalis-i2c1 -> i2c-4
lrwxrwxrwx 1 root root 5 Jan 24 16:30 /dev/apalis-i2c3 -> i2c-5



Plugged In:
root@apalis-imx8-14903975:~# i2cdetect 4
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-4.
I will probe address range 0x08-0x77.
Continue? [Y/n] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- 29 -- -- -- -- -- -- 
30: 30 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --    


Unplugged:
root@apalis-imx8-14903975:~# i2cdetect 4
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-4.
I will probe address range 0x08-0x77.
Continue? [Y/n] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: 30 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

I know the i2c address is set to 0x52 as I’m using it on other devices using this address.
Any steps to rectify the issue would be very helpful, as I’m building out an application using this sensor.
Thank you
William

Hello @DHWill , welcome to the community :slight_smile:
According to this page:
https://learn.sparkfun.com/tutorials/qwiic-tof-imager---vl53l5cx-hookup-guide/hardware-overview
the value 0x29 corresponds to the 7-bit unshifted address. That will be 0x52 when writing and 0x53 for reading.
From your output , i2cdetect seems to display the 7-bit address of the device.

Best regards,
Josep

** apologies for the mistaken paste there **

Thank you very much! I’m trying to adapt a driver.

For clarity, do you know when using open in C should I be referencing the symlink?


open("/dev/apalis-i2c1", O_RDONLY);
//or 
open("/dev/i2c-4", O_RDONLY);

Also do you know if any permissions are required for i2c access on the IMX8QM Multimedia Reference Image?
I’m struggling getting the manufacturer provided driver to work on the Ixora.

Thank you very much for your prompt reply,

William

Hello @DHWill

I think that both should work.

if you are able to run i2cdetect there shouldn’t be any permission issues.

What specific issues are you experiencing? Could you please describe them in detail?

Best regards,
Josep

I’m using the “User” methos of the driver available here:
https://www.st.com/en/embedded-software/stsw-img025.html

The driver appears to throw an error around here:

	/* 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);

	status |= RdMulti(&(p_dev->platform), VL53L5CX_UI_CMD_START, p_dev->temp_buffer, VL53L5CX_NVM_DATA_SIZE); //ErrorHere

	(void)memcpy(p_dev->offset_data, p_dev->temp_buffer, VL53L5CX_OFFSET_BUFFER_SIZE);

	status |= _vl53l5cx_send_offset_data(p_dev, VL53L5CX_RESOLUTION_4X4);

It is a call to this function:

int32_t write_read_multi(
		int fd,
		uint16_t i2c_address,
		uint16_t reg_address,
		uint8_t *pdata,
		uint32_t count,
		int write_not_read)
{

#ifdef STMVL53L5CX_KERNEL
	struct comms_struct cs;

	cs.len = count;
	cs.reg_address = reg_address;
	cs.buf = pdata;
	cs.write_not_read = write_not_read;

	if (ioctl(fd, ST_TOF_IOCTL_TRANSFER, &cs) < 0)
		return VL53L5CX_COMMS_ERROR;
#else

	struct i2c_rdwr_ioctl_data packets;
	struct i2c_msg messages[2];

	uint32_t data_size = 0;
	uint32_t position = 0;

	if (write_not_read) {
		do {
			data_size = (count - position) > (VL53L5CX_COMMS_CHUNK_SIZE-2) ? (VL53L5CX_COMMS_CHUNK_SIZE-2) : (count - position);

			memcpy(&i2c_buffer[2], &pdata[position], data_size);

			i2c_buffer[0] = (reg_address + position) >> 8;
			i2c_buffer[1] = (reg_address + position) & 0xFF;

			messages[0].addr = i2c_address >> 1;
			messages[0].flags = 0; //I2C_M_WR;
			messages[0].len = data_size + 2;
			messages[0].buf = i2c_buffer;

			packets.msgs = messages;
			packets.nmsgs = 1;

			if (ioctl(fd, I2C_RDWR, &packets) < 0)
				return VL53L5CX_COMMS_ERROR;
			position +=  data_size;

		} while (position < count);
	}

	else {
		do {
			data_size = (count - position) > VL53L5CX_COMMS_CHUNK_SIZE ? VL53L5CX_COMMS_CHUNK_SIZE : (count - position);

			i2c_buffer[0] = (reg_address + position) >> 8;
			i2c_buffer[1] = (reg_address + position) & 0xFF;

			messages[0].addr = i2c_address >> 1;
			messages[0].flags = 0; //I2C_M_WR;
			messages[0].len = 2;
			messages[0].buf = i2c_buffer;

			messages[1].addr = i2c_address >> 1;
			messages[1].flags = I2C_M_RD;
			messages[1].len = data_size;
			messages[1].buf = pdata + position;

			packets.msgs = messages;
			packets.nmsgs = 2;

			int ret = ioctl(fd, I2C_RDWR, &packets);
			if (ret < 0){		//throws error here
				return VL53L5CX_COMMS_ERROR;
			}
//			if (ioctl(fd, I2C_RDWR, &packets) < 0)
//				return VL53L5CX_COMMS_ERROR;

			position += data_size;

		} while (position < count);
	}
#endif
	return 0;
}

with :
ioctl(fd, I2C_RDWR, &packets)

Throwing a -1

The rest of the i2c communications appear to work OK.

The size of the read is below:
VL53L5CX_NVM_DATA_SIZE:
#define VL53L5CX_NVM_DATA_SIZE ((uint16_t)492U)

Could it be an i2C speed issue? I believe the sensor to run on baudrate 400KHz

I’ve posted about this here:

Thank you,

Hello @DHWill ,
Since this driver seems to be maintained by ST, I thinks it’s better to wait for their answer in their community.

Best regards,
Josep

Hi Josep,

Thank you for your help so far, prompt replies!
As this driver appears to work on a ‘Teensy’ MCU, I believe the Linux version should also work, but it could potentially be down to i2c speeds?

Do you know if there is a way to change the baudrate of the IMX8QM i2c driver for the ixora board?

Thank you,

Hello @DHWill ,
The recommended way to change the I2C speed is by modifying the device tree using an overlay:

Here you can learn more about device trees and overlays:
https://developer.toradex.com/software/linux-resources/device-tree/

Best regards,
Josep