rudiratlos
Posts: 231
Joined: Tue May 01, 2012 8:47 am
Location: Germany (old europe)

multiple IO with i2ctransfer not working

Sun Jul 04, 2021 11:23 am

Hi,
I've tried to read multiple i2c sensors at once with i2ctransfer. I have sensors on 0x70 and 0x71 But it's not working:

Code: Select all

i2ctransfer -y -v 0 r2@0x70 r2@0x71
Error: Sending messages failed: Operation not supported

Code: Select all

i2ctransfer -y -v 0 r2@0x70 r2@0x70
Error: Sending messages failed: Operation not supported

this is working:

Code: Select all

i2ctransfer -y -v 0 r2@0x70
msg 0: addr 0x70, read, len 2, buf 0x06 0x62

i2ctransfer -y -v 0 r2@0x71
msg 0: addr 0x71, read, len 2, buf 0x06 0x77

Code: Select all

uname -a
Linux pump 5.10.17-v7l+ #1421 SMP Thu May 27 14:00:13 BST 2021 armv7l GNU/Linux
but the multiple IO should work, according to the this code:
https://fossies.org/linux/i2c-tools/tools/i2ctransfer.c

What's wrong with rpi OS?

pidd
Posts: 2972
Joined: Fri May 29, 2020 8:29 pm
Location: Wirral, UK
Contact: Website

Re: multiple IO with i2ctransfer not working

Sat Jul 17, 2021 12:29 pm

Out of curiosity, could you show the results of

Code: Select all

i2ctransfer -y -v 0 r2@0x70 r2

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 12336
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: multiple IO with i2ctransfer not working

Sat Jul 17, 2021 5:27 pm

https://github.com/raspberrypi/linux/bl ... 835.c#L450

Code: Select all

	for (i = 0; i < (num - 1); i++)
		if (msgs[i].flags & I2C_M_RD) {
			dev_warn_once(i2c_dev->dev,
				      "only one read message supported, has to be last\n");
			return -EOPNOTSUPP;
		}
So if you'd checked the kernel logs you should have found that it told you (once) why it failed.

Sorry, I have no idea why the original author of that change viewed that as necessary.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4345
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: multiple IO with i2ctransfer not working

Sun Jul 18, 2021 6:48 pm

I haven't verified this, but my suspicion is that either the I2C hardware can't handle multiple restarts, only a single transition from a write phase to a read phase (the documentation is sketchy), or the author of the driver mistakenly thought that was the case. I don't see any such restriction in the i2c-bcm2708 driver - try using the i2c-bcm2708 overlay to switch to that driver instead:

Code: Select all

dtoverlay=i2c-bcm2708
Note that I haven't tried that driver in a long time and it may have bit rotted.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 12336
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: multiple IO with i2ctransfer not working

Sun Jul 18, 2021 8:48 pm

I haven't read through the I2C spec recently enough, but I'd have thought changing the address would use a stop and new start, instead of a repeated start.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4345
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: multiple IO with i2ctransfer not working

Sun Jul 18, 2021 9:20 pm

Well, the i2ctransfer manpage (https://manpages.debian.org/unstable/i2 ... .8.en.html) says:
i2ctransfer is a program to create I2C messages and send them combined as one transfer. For read messages, the contents of the received buffers are printed to stdout, one line per read message.
Please note the difference between a transfer and a message here. A transfer may consist of multiple messages and is started with a START condition and ends with a STOP condition as described in the I2C specification. Messages within the transfer are concatenated using the REPEATED START condition which is described there as well.
And later:
The next parameter is one or multiple desc blocks. The number of blocks is limited by the Linux Kernel and defined by I2C_RDWR_IOCTL_MAX_MSGS (42 as of v4.10). desc blocks are composed like this:

{r|w}<length_of_message>[@address]
If there were restrictions on mixing reads and writes within a single transfer then I would expect it to be mentioned here, and for the I2C framework to filter it out before it reached the driver, neither of which appears to be the case.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4345
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: multiple IO with i2ctransfer not working

Mon Jul 19, 2021 10:41 am

From https://i2c.info/i2c-bus-specification:
Image
There is no suggestion that restarts must only be used for write->read switchovers.

I tried with the old i2c-bcm2708 driver and using i2ctransfer for two reads worked. However, this "transfer" was actually two transfers back to back, with a proper stop and start in-between, whereas i2c-bcm2835 issues a proper restart between a write and a read. Hacking the i2c-bcm2835 driver to remove the test results in a timeout after the first read. I think the problem is caused by the way the interrupts work/are used, but I'm not going to invest more time into fully understanding the issue.

rudiratlos
Posts: 231
Joined: Tue May 01, 2012 8:47 am
Location: Germany (old europe)

Re: multiple IO with i2ctransfer not working

Mon Jul 19, 2021 11:30 am

I have modified my /boot/config.txt and added dtoverlay=i2c-bcm2708 (with reboot).
but I have the same error:

Code: Select all

i2ctransfer -y -v 0 r2@0x70 r2@0x70
Error: Sending messages failed: Operation not supported
kernel log:

Code: Select all

Jul 19 12:20:23 [  177.461018] i2c-bcm2835 fe205000.i2c: only one read message supported, has to be last
looks like the bcm2835 is still active. How to disable this and use 2708?

rudiratlos
Posts: 231
Joined: Tue May 01, 2012 8:47 am
Location: Germany (old europe)

Re: multiple IO with i2ctransfer not working

Mon Jul 19, 2021 11:46 am

in the i2c-bcm2708.c there is not such a check, that assures that the last msg has a read flag 'I2C_M_RD'
https://github.com/raspberrypi/linux/bl ... 708.c#L260

rudiratlos
Posts: 231
Joined: Tue May 01, 2012 8:47 am
Location: Germany (old europe)

Re: multiple IO with i2ctransfer not working

Mon Jul 19, 2021 11:58 am

I've contacted the author of i2c-bcm2835.c 'Stephen Warren' directly.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4345
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: multiple IO with i2ctransfer not working

Mon Jul 19, 2021 12:19 pm

The dtoverlay line appears to have not worked. What does "sudo vcdbg log msg |& grep dt" show?

rudiratlos
Posts: 231
Joined: Tue May 01, 2012 8:47 am
Location: Germany (old europe)

Re: multiple IO with i2ctransfer not working

Mon Jul 19, 2021 12:30 pm

Code: Select all

sudo vcdbg log msg |& grep dt
005901.939: dtb_file 'bcm2711-rpi-4-b.dtb'
005908.569: brfs: File read: /mfs/sd/bcm2711-rpi-4-b.dtb
005908.586: Loading 'bcm2711-rpi-4-b.dtb' to 0x100 size 0xbfc2
005931.239: brfs: File read: /mfs/sd/overlays/overlay_map.dtb
005996.196: dterror: not a valid FDT - err -9
005996.214: dtparam: i2c_arm=on
006004.563: dtparam: spi=on
006012.403: dtparam: audio=on
006033.642: brfs: File read: /mfs/sd/overlays/vc4-fkms-v3d.dtbo
006050.765: dtparam: i2c_baudrate=400000
006058.612: dtparam: i2c_vc=on
006105.366: dtwarn: overlay 'pi3-miniuart-bt' has been renamed 'miniuart-bt'
006113.284: brfs: File read: /mfs/sd/overlays/miniuart-bt.dtbo
006185.906: brfs: File read: /mfs/sd/overlays/i2c-rtc.dtbo
006206.336: dtparam: ds3231=true
006225.879: brfs: File read: /mfs/sd/overlays/fluidicworks18.dtbo
006234.666: dtparam: green=true
006234.935: dtparam: dc_pin=9
006235.235: dtparam: reset_pin=27
006235.532: dtparam: debug=3
006235.832: dtparam: basisid=pumpid
006238.684: Unknown dtparam 'basisid' - ignored
006264.210: brfs: File read: /mfs/sd/overlays/i2c-bcm2708.dtbo

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4345
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: multiple IO with i2ctransfer not working

Mon Jul 19, 2021 2:45 pm

Oh - you're using I2C0. Try "dtoverlay=i2c0,combine=off" to see if it makes a difference, but I think the "i2c-bcm2708" overlay should be extended to also change the compatible string for I2C0.

Code: Select all

pi@raspberrypi:~$ dtoverlay -h i2c0
Name:   i2c0

Info:   Change i2c0 pin usage. Not all pin combinations are usable on all
        platforms - platforms other then Compute Modules can only use this
        to disable transaction combining.
        Do NOT use in conjunction with dtparam=i2c_vc=on. From the 5.4 kernel
        onwards the base DT includes the use of i2c_mux_pinctrl to expose two
        muxings of BSC0 - GPIOs 0&1, and whichever combination is used for the
        camera and display connectors. This overlay disables that mux and
        configures /dev/i2c0 to point at whichever set of pins is requested.
        dtparam=i2c_vc=on will try and enable the mux, so combining the two
        will cause conflicts.

Usage:  dtoverlay=i2c0,<param>=<val>

Params: pins_0_1                Use pins 0 and 1 (default)
        pins_28_29              Use pins 28 and 29
        pins_44_45              Use pins 44 and 45
        pins_46_47              Use pins 46 and 47
        combine                 Allow transactions to be combined (default
                                "yes")

rudiratlos
Posts: 231
Joined: Tue May 01, 2012 8:47 am
Location: Germany (old europe)

Re: multiple IO with i2ctransfer not working

Tue Jul 20, 2021 8:32 am

working with i2c-bcm2708:

Code: Select all

i2ctransfer -y -v 1 r2@0x70 r2@0x71 r2@0x73 r2@0x74
msg 0: addr 0x70, read, len 2, buf 0x06 0x6e
msg 1: addr 0x71, read, len 2, buf 0x06 0x75
msg 2: addr 0x73, read, len 2, buf 0x20 0x10
msg 3: addr 0x74, read, len 2, buf 0x20 0x05

Code: Select all

i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
70: 70 71 -- 73 74 -- -- --  

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4345
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: multiple IO with i2ctransfer not working

Tue Jul 20, 2021 8:56 am

Yes, for some values of "working". It may be doing what you want it to do, but it's not doing what it should because it is releasing the bus between the reads.

Why are you using i2ctransfer? Is it for speed or convenience? If the single-transfer isn't important to you then you may find it better in the long run to write your own small utility to submit multiple reads as separate transfers.

rudiratlos
Posts: 231
Joined: Tue May 01, 2012 8:47 am
Location: Germany (old europe)

Re: multiple IO with i2ctransfer not working

Tue Jul 20, 2021 9:24 am

just wrote a test, reading 4 sensors with I2C single iO (one sensor after another with single IOs) and all 4 sensors with one single I2C_xfer function. I did this in a loop with 10000 iterations each. i2c_xfer is 14% faster.

Code: Select all

I2C_bus_WrRd Time:3763ms
I2C single IO test: 0x065D
I2C single IO test: 0x0677
I2C single IO test: 0x2012
I2C single IO test: 0x2007

I2C_xfer Time:3254ms
hdl:4 msg:1/4 addr:0x70 bptr:0xBEACDEEC len:2 flags:0x0001 buf:0x8660
hdl:4 msg:2/4 addr:0x71 bptr:0xBEACDFEC len:2 flags:0x0001 buf:0x0677
hdl:4 msg:3/4 addr:0x73 bptr:0xBEACE0EC len:2 flags:0x0001 buf:0x2015
hdl:4 msg:4/4 addr:0x74 bptr:0xBEACE1EC len:2 flags:0x0001 buf:0x2005

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4345
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: multiple IO with i2ctransfer not working

Tue Jul 20, 2021 9:37 am

You have three options:
1. Submit a patch to the bcm2835 driver that allows it (if a suitable Device Tree property is present) to fall back multiple stops and starts in the way that the i2c-bcm2708 driver does.
2. Continue to use i2c-bcm2708.
3. Live with the 14% slower operation.

rudiratlos
Posts: 231
Joined: Tue May 01, 2012 8:47 am
Location: Germany (old europe)

Re: multiple IO with i2ctransfer not working

Tue Jul 20, 2021 9:46 am

Hi Phil,
I think i accept the 14% speed degradation. I've hoped to gain much more efficency with i2c_xfer.
Thank you very much for your valuable support.
SF

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4345
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: multiple IO with i2ctransfer not working

Tue Jul 20, 2021 9:56 am

I think that's a wise choice. And technically it's only ~12% slower. ;)

Return to “Interfacing (DSI, CSI, I2C, etc.)”