lauri_pirttiaho
Posts: 2
Joined: Tue Aug 26, 2014 10:31 am

Re: i2c repeated start transactions

Tue Aug 26, 2014 11:07 am

To correct some points in the previous discussion, there are devices that absolutely need repeated start to function correctly. Examples of such are early EEPROM memories, which hang internally if one writes an address and then generates a stop condition. Only way to reset such device is to power-cycle it.

The BCM2835 ARM Peripherals document claims that the BSC (the I2C controller in BMC2835) is I2C 2.1 compliant so it must support repeated start. And indeed, it does. However, the documentation of that feature is quite minimal, limited to the one example of how the 10-bit addressing can be achieved with BSC. The procedure in section 3.3 (pages 36-37) describing reading of 10-bit-addressed slave is an example of the more general one.

In brief, the procedure is that a write is started and then a read is queued before the write is completed. When a read is available to teh decice's state machine when the write ends, BSC does not generate stop condition but a repeated start, re-addressing, and read.

That functionality has been implemented in theRPi device driver (i2c-bcm2708.c). The catch here is that the feature, called as "combined" transaction, is disabled by deafault and has to be enabled to work.

So, once one has the i2c driver installed (insmod i2c-dev.ko, insmod i2c-bcm2708.ko), and made available (chmod 666 /dev/i2c-*), then one needs to turn on the combined transactions (chmod 666 /sys/module/i2c_bcm2708/parameters/combined, echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined).

Now one can read even those old, repeated-start-picky EEPROMs like XR24C02 like

Code: Select all

...
  struct i2c_msg rdwr_msgs[2] = {
    {  // Start address
      .addr = 0x50,
      .flags = 0, // write
      .len = 1,
      .buf = &reg_address
    },
    { // Read buffer
      .addr = 0x50,
      .flags = I2C_M_RD, // read
      .len = 16,
      .buf = buffer
    }
  };

  struct i2c_rdwr_ioctl_data rdwr_data = {
    .msgs = rdwr_msgs,
    .nmsgs = 2
  };

  file = open( "/dev/i2c-1", O_RDWR );
...

  result = ioctl( file, I2C_RDWR, &rdwr_data );

  if ( result < 0 ) {
    printf( "rdwr ioctl error: %d\n", errno );
    perror( "reason" );
  } else {
    printf( "rdwr ioctl OK\n" );
    for ( i = 0; i < 16; ++i ) {
      printf( "%c", buffer[i] );
    }
    printf( "\n" );
  }
...
-- Lauri

MBA1959
Posts: 1
Joined: Sat Nov 01, 2014 7:57 pm

Re: i2c repeated start transactions

Sat Nov 01, 2014 7:59 pm

Thanks, this is also working for a MPL3115 device

Carl-Cipher
Posts: 2
Joined: Wed Aug 26, 2015 7:13 pm

Re: i2c repeated start transactions

Wed Aug 26, 2015 7:14 pm

Using:
Raspberry Pi 2 Model B
Python 2.7
python-smbus
i2c-tools

I was having problems with a device that required combined (repeated start) mode operation to work. After flailing around for a couple of days (getting smarter about I2C, Python, R-Pi and Linux), I found the information on this site:
http://ciaduck.blogspot.com/
Lastly, the MPL3115A2 requires a proper repeated start command in it's I2C communication. Raspberry Pi doesn't do this out of the box, but there is a kernel module that can be enabled to make it perform repeated start correctly. Run the following commands to enable repeated start on the Pi:

sudo su -
echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined
exit

More details about the repeated start problem can be found here:
http://www.raspberrypi.org/forums/viewt ... 0&start=25

After setting the contents of the file from “N” to “Y”, my device started working, with the scope showing that the Stop command was no longer being issued in the middle of the read_word_data(addr, cmd) instruction.

jdb
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1661
Joined: Thu Jul 11, 2013 2:37 pm

Re: i2c repeated start transactions

Wed Aug 26, 2015 8:28 pm

Carl-Cipher wrote:Using:
Raspberry Pi 2 Model B
Python 2.7
python-smbus
i2c-tools

I was having problems with a device that required combined (repeated start) mode operation to work. After flailing around for a couple of days (getting smarter about I2C, Python, R-Pi and Linux), I found the information on this site:
http://ciaduck.blogspot.com/
Lastly, the MPL3115A2 requires a proper repeated start command in it's I2C communication. Raspberry Pi doesn't do this out of the box, but there is a kernel module that can be enabled to make it perform repeated start correctly. Run the following commands to enable repeated start on the Pi:

sudo su -
echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined
exit

More details about the repeated start problem can be found here:
http://www.raspberrypi.org/forums/viewt ... 0&start=25

After setting the contents of the file from “N” to “Y”, my device started working, with the scope showing that the Stop command was no longer being issued in the middle of the read_word_data(addr, cmd) instruction.
The repeated start functionality was grudgingly added as it seems there are a large proportion of i2c devices that implement a common i2c transaction of the type Address(W)-write_register_pointer(ack)-repeated_start-address(R)-read_register_data(ack)-Stop. It's possible to make the hardware do a repeated start, but only if you write to its data FIFO when the last byte is being shifted out. This suppresses the Stop signal and instead forces a repeated Start.

The driver does this by busy-wait polling. This is bad for a number of reasons, but partially alleviated due to the fact that the transition necessary between write/read phases is only a couple of i2c bytes, i.e. 200uS.
Rockets are loud.
https://astro-pi.org

Carl-Cipher
Posts: 2
Joined: Wed Aug 26, 2015 7:13 pm

Re: i2c repeated start transactions

Thu Aug 27, 2015 5:37 pm

OK, so the combined mode is a hack on the existing system. I thought all was going well with the combined mode addressing (combined file set to "Y"), but I began to notice timeouts (Error 110: connection timed out) when taking more than single set of 4 measurements on my VEML6040 RGBW opto-sensor. I would typically see an error after 10 to 100 measurements in a burst of data collection.
With the combined file set to "N" (disabled), I got bad results from my reads (reads of all 4 registers returning the same value), but there were never any timeout errors (thousands of cycles). Do you have any suggestions that I might explore that would allow me to properly read my opto-sensor, and also avoid the timeouts that the combined mode hack seems to provoke?

thanks,
Carl

User avatar
joan
Posts: 12705
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: i2c repeated start transactions

Thu Aug 27, 2015 6:04 pm

Carl-Cipher wrote:OK, so the combined mode is a hack on the existing system. I thought all was going well with the combined mode addressing (combined file set to "Y"), but I began to notice timeouts (Error 110: connection timed out) when taking more than single set of 4 measurements on my VEML6040 RGBW opto-sensor. I would typically see an error after 10 to 100 measurements in a burst of data collection.
With the combined file set to "N" (disabled), I got bad results from my reads (reads of all 4 registers returning the same value), but there were never any timeout errors (thousands of cycles). Do you have any suggestions that I might explore that would allow me to properly read my opto-sensor, and also avoid the timeouts that the combined mode hack seems to provoke?

thanks,
Carl
Have you considered bit banging? I noticed problems with trying to use devices which didn't need repeated starts after those that did (setting then clearing the combined flag).

hairball
Posts: 1
Joined: Thu Dec 03, 2015 3:46 pm

Re: i2c repeated start transactions

Thu Dec 03, 2015 4:57 pm

Thanks for the info. The repeated-start is working for me in a lightly-loaded RPi2 with the combined option - for communication with a MLX90614 IR sensor:
Sr.jpg
Sr.jpg (57.3 KiB) Viewed 7018 times
As mentioned above, the BCM2835 ARM Peripherals document does describe the method for getting a repeated-start -- which is to set up the second part of the transaction while the first is still clocking out of the I2C block. That's rather nasty as it requires software timing (polling) to work.

e.g. from the data sheet:
3. ... Set I2CC.READ = 0 and I2CC.ST = 1, this will start a write transfer.
4. Poll the I2CS.TA bit, waiting for the transfer has started.
5. Write the number of data bytes to read to the I2CDLEN register.
6. Set I2CC.READ = 1 and I2CC.ST = 1, this will send the repeat start bit, new slave address and R/W bit (which is ‘1’) initiating the read.
The i2c driver (linux/drivers/i2c/busses/i2c-bcm2708.c) implements this software polling scheme for repeated-starts, but it seems to me that there is a hazard in the code -- there is a critical timing region between the first start (write ST=1) and the second (write ST=1 again).

If an interrupt is received in the critical region, the kernel module code will stop running, and the I2C block could finish clocking out the first part of the transaction (slave address + command) before the second part is set up -- so the I2C block will presumably send a stop rather than a repeated start.

When execution returns to the kernel module after missing the window, S.DONE will be set, and the code will exit the polling loop. Then it will go ahead and send the second part of the transaction -- but you won't get a repeated-start.

An interrupt will hit that region eventually, and in a heavily loaded system it would happen sooner rather than later.

Code: Select all

	bcm2708_wr(bi, BSC_DIV, cdiv);
	bcm2708_wr(bi, BSC_A, bi->msg->addr);
	bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
	if (combined)
	{
		/* Do the next two messages meet combined transaction criteria?
		   - Current message is a write, next message is a read
		   - Both messages to same slave address
		   - Write message can fit inside FIFO (16 bytes or less) */
		if ( (bi->nmsgs > 1) &&
			!(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) &&
			 (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) {
			/* Fill FIFO with entire write message (16 byte FIFO) */
			while (bi->pos < bi->msg->len) {
				bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);
			}
			/* Start write transfer (no interrupts, don't clear FIFO) */
--> critical region start
			bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST);

			/* poll for transfer start bit (should only take 1-20 polls) */
			do {
				s = bcm2708_rd(bi, BSC_S);
			} while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE)) && --wait_loops >= 0);

			/* did we time out or some error occured? */
			if (wait_loops < 0 || (s & (BSC_S_ERR | BSC_S_CLKT))) {
				return -1;
			}

			/* Send next read message before the write transfer finishes. */
			bi->nmsgs--;
			bi->msg++;
			bi->pos = 0;
			bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
			c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_INTR | BSC_C_ST | BSC_C_READ;
		}
	}
	bcm2708_wr(bi, BSC_C, c);
--> critical region end
So, I think the i2c driver should have a separate interrupts-disabled path to handle repeated-starts. This would protect the region between the first and second start (write ST, poll for TA==1, write DLEN, write ST) - and guarantee that it hits the window.

In the example above (100KHz clock) -- the code has 200us to set up the second part of the transaction, but presumably the polling time (irq disabled) would be much shorter if the I2C block is ready.

The driver code already has a timeout which would limit on the width of the interrupt-disabled region, but there may be other checks to see that the I2C block is ready to start before disabling interrupts.

justnice
Posts: 2
Joined: Fri Mar 25, 2016 3:05 pm

Re: i2c repeated start transactions

Fri Mar 25, 2016 3:37 pm

Hi,

After setting the /sys/module/i2c_bcm2708/parameters/combined to "Y" everything works fine for those device that required the repeated start. However I am facing another issue is that after the Raspberry Pi reboot the /sys/module/i2c_bcm2708/parameters/combined is auto restore to "N" again. Any suggestion to prevent the setting reset back?

phoenix127
Posts: 5
Joined: Wed Apr 24, 2013 9:08 pm

Re: i2c repeated start transactions

Tue Mar 29, 2016 10:16 pm

Just add the command to the end of the /etc/rc.local (above the line that says "exit 0"). This script runs every time the machine boots.

Make sure that the command is correct by re-running /etc/rc.local before you reboot, since this file can also prevent the machine booting properly if your additions are bad !

nic_ferro
Posts: 5
Joined: Mon May 30, 2016 8:14 am

Re: i2c repeated start transactions

Tue Jun 14, 2016 1:13 pm

Hi,
I have the same problem. I tried to enable the combined mode but the problem hasn't been corrected. Sometimes it works properly and sometimes doesn't.
Could I know which library you are using (c or python)?
Could you post the code to use the combined mode?
Thanks

User avatar
audio-badger
Posts: 15
Joined: Wed Jun 15, 2016 9:44 am

Re: i2c repeated start transactions

Fri Jul 29, 2016 2:05 pm

However I am facing another issue is that after the Raspberry Pi reboot the /sys/module/i2c_bcm2708/parameters/combined is auto restore to "N" again. Any suggestion to prevent the setting reset back?
ensure /etc/modprobe.d/i2c.conf (rather than /etc/modules ) has the following line:

Code: Select all

options i2c-bcm2708 combined=1
Seem to do the trick for me on Jessie 4.4.13v7 - repeated starts always enabled after boot.

User avatar
Gavinmc42
Posts: 1339
Joined: Wed Aug 28, 2013 3:31 am

Re: i2c repeated start transactions

Sat Aug 13, 2016 7:49 am

I have used two ways to work around this.

1st method is to read a block of registers from the slave into a buffer array, then grab the data from the array, does not always work, so I put repeats in until it does get data. This is ok if the data is in the first 64 registers and you don't need it in a hurry.

2nd method is to use a 8 pin PSoC CY8C24123A as a slave to the Pi and master to the device.
This works much better and is faster.

The PSoC 1 series are really good as i2c gadgets for Pi's, the 24123 is easy to use in a 8pin dip.
The 28xxx give you 4 x 14bit SD ADCs and as many software i2c's as you need.
Need an ADC, reprogram a 24123, need to measure an analog pressure sensor, need RPM.
One 24123 can do all three at the same time.

Used your last RTC, PSoC can emulate it, need a i2c to gpio expander, no problem, i2c to servo easy.
I'm dancing on Rainbows.
Raspberries are not Apples or Oranges

lec
Posts: 2
Joined: Wed Nov 09, 2016 2:01 pm

Re: i2c repeated start transactions

Fri Nov 11, 2016 5:18 pm

Sorry but, did we have a regression? I see from this post viewtopic.php?p=855345#p855345 the repeated start behavior clearly working well, yet when I followed the instructions in this post: viewtopic.php?p=807804#p807804, and when this did not work, then made the setting permanent as suggested by this post: viewtopic.php?p=1016727#p1016727. I am still seeing the top panel in this image. I include a trace (bottom panel in the trace) taken from a non-RPI device which is correctly implementing the repeat start transaction ( and consequently properly reading the data). I am driving this via the python via the SMBus module.
repStart.png
repStart.png (52.2 KiB) Viewed 4128 times
Here is my code:

Code: Select all

#!/usr/bin/python

from smbus import SMBus
import os
import time
smb=SMBus(1);
slaveaddr=0x40;
if __name__ == '__main__':
    print "Result: "
    addr = 0xfc00
    
    for i in range(0,18):
        a1=addr/256
        a0=addr%256
        smb.write_i2c_block_data(slaveaddr,a1,[a0])
        val = smb.read_byte(slaveaddr)
        time.sleep(.2)
	print "byte " + str(hex(0xfc00 + i)) + " is... " + str(val)
        time.sleep(.5)
        addr += 1

My OS particulars are these:
cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"
NAME="Raspbian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"


Any help anyone can lend is greatly appreciated.

User avatar
joan
Posts: 12705
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: i2c repeated start transactions

Sat Nov 12, 2016 6:48 pm

I never found the Linux driver to be consistent when using the combined flag. Some transactions started working, some transactions stopped working. I remember looking at the driver code but it didn't make a great deal of sense at the time.

jdb
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1661
Joined: Thu Jul 11, 2013 2:37 pm

Re: i2c repeated start transactions

Mon Nov 14, 2016 12:05 pm

There's a patch set for the upstream driver that may be of interest...

http://lists.infradead.org/pipermail/li ... 04487.html

It appears that a workaround for generating repeated starts had been divined.
Rockets are loud.
https://astro-pi.org

notro
Posts: 681
Joined: Tue Oct 16, 2012 6:21 pm
Location: Drammen, Norway

Re: i2c repeated start transactions

Mon Nov 14, 2016 4:57 pm

The patchset has just been applied to rpi-4.8.y: https://github.com/raspberrypi/linux/pull/1716
Hopefully it will survive testing so we can use i2c-bcm2835 as default when we move to the next stable Linux version.

I have only tested 3 devices, from commit message:
I have run thousands of transfers to a DS1307 (rtc), MMA8451 (accel) and AT24C32 (eeprom) in parallel without problems.

It is possible to apply the patches on rpi-4.4.y and create an overlay to choose i2c-bcm2835, but I haven't got the time to do this.

lec
Posts: 2
Joined: Wed Nov 09, 2016 2:01 pm

Re: i2c repeated start transactions

Wed Nov 16, 2016 3:55 pm

jdb wrote:There's a patch set for the upstream driver that may be of interest...

http://lists.infradead.org/pipermail/li ... 04487.html

It appears that a workaround for generating repeated starts had been divined.
OK please forgive my ignorance, I am still searching for my divining rod.

I found the patch, applied it and built as per the instructions found in: https://www.raspberrypi.org/documentati ... uilding.md. I was confused, I was not seeing bcm2835 being built at all. From reading:https://github.com/notro/rpi-firmware/w ... 8vsBCM2835
I understand that the bcm2708 is the standard RPI kernel, and bcm2835 is in the upstream vanilla kernel.

After the generating the .config file from bcm2709_defconfig, I changed it to include the bcm2835 kernel module by adding CONFIG_I2C_BCM2835=m. When I did, I could see that module was being created.

This is the modinfo data for the respective modules:

Code: Select all

pi@raspberrypi:~/linux/Documentation$ modinfo i2c_bcm2708
filename:       /lib/modules/4.9.0-rc4-v7+/kernel/drivers/i2c/busses/i2c-bcm2708.ko
alias:          platform:bcm2708_i2c
license:        GPL v2
author:         Chris Boot <bootc@bootc.net>
description:    BSC controller driver for Broadcom BCM2708
srcversion:     0C1F4F8690E98B7CEAABAE5
alias:          of:N*T*Cbrcm,bcm2708-i2cC*
alias:          of:N*T*Cbrcm,bcm2708-i2c
depends:        
intree:         Y
vermagic:       4.9.0-rc4-v7+ SMP mod_unload modversions ARMv7 p2v8 
parm:           baudrate:The I2C baudrate (uint)
parm:           combined:Use combined transactions (bool)
pi@raspberrypi:~/linux/Documentation$ 
pi@raspberrypi:~/linux/Documentation$ modinfo i2c_bcm2835
filename:       /lib/modules/4.9.0-rc4-v7+/kernel/drivers/i2c/busses/i2c-bcm2835.ko
alias:          platform:i2c-bcm2835
license:        GPL v2
description:    BCM2835 I2C bus adapter
author:         Stephen Warren <swarren@wwwdotorg.org>
srcversion:     FA636ABF449B23300297875
alias:          of:N*T*Cbrcm,bcm2835-i2cC*
alias:          of:N*T*Cbrcm,bcm2835-i2c
depends:        
intree:         Y
vermagic:       4.9.0-rc4-v7+ SMP mod_unload modversions ARMv7 p2v8 
pi@raspberrypi:~/linux/Documentation$ modinfo i2c_dev
filename:       /lib/modules/4.9.0-rc4-v7+/kernel/drivers/i2c/i2c-dev.ko
license:        GPL
description:    I2C /dev entries driver
author:         Frodo Looijaard <frodol@dds.nl> and Simon G. Vogl <simon@tk.uni-linz.ac.at>
srcversion:     AD14BB701F4700C67162A62
depends:        
intree:         Y
vermagic:       4.9.0-rc4-v7+ SMP mod_unload modversions ARMv7 p2v8 
But, I am still missing something since the i2c-bcm2835 does not appear to be a direct replacement for i2c-bcm2708.
As it, the kernel still defaults to the using the 2708 variant which has the same behavior as before.
Where did I go wrong?
As before, any ray of light in the vastness of my ignorance is much appreciated.

notro
Posts: 681
Joined: Tue Oct 16, 2012 6:21 pm
Location: Drammen, Norway

Re: i2c repeated start transactions

Wed Nov 16, 2016 7:32 pm

In arch/arm/boot/dts/bcm2708_common.dtsi change 3 occurences of:
compatible = "brcm,bcm2708-i2c"; -> compatible = "brcm,bcm2835-i2c";

Or make an overlay like this but change the compatible property: https://github.com/raspberrypi/linux/bl ... verlay.dts

bum
Posts: 1
Joined: Fri Jan 06, 2017 7:49 pm

Re: i2c repeated start transactions

Fri Jan 06, 2017 7:52 pm

lec did this fix work for you or not? I'm trying to do a multi-write then stop to control my motor controller board outputs.... If I can do this I can start/stop motors simultaneously. would be nice...

notro
Posts: 681
Joined: Tue Oct 16, 2012 6:21 pm
Location: Drammen, Norway

Re: i2c repeated start transactions

Tue Jan 10, 2017 11:59 pm

rpi linux 4.9 uses i2c-bcm2835 with these patches.
Available here: viewtopic.php?f=29&t=167934

grhhm
Posts: 5
Joined: Sat Jan 21, 2017 8:41 am

Re: i2c repeated start transactions

Tue Jan 24, 2017 7:59 am

@lauri_pirttiaho, Thank you so much for precise problem description and unique solution. After week of intensive search and tries to resolve a problem of getting data from MLX90614 sensor I found your solution. This helps.

Slightly modified:

Code: Select all

sudo chmod 666 /dev/i2c-*
sudo chmod 666 /sys/module/i2c_bcm2708/parameters/combined
sudo echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined
To validate the "combined file content before and after such config:

Code: Select all

sudo cat /sys/module/i2c_bcm2708/parameters/combined

User avatar
JoanTheSpark
Posts: 31
Joined: Sun Feb 21, 2016 5:36 am

Re: i2c repeated start transactions

Fri Apr 21, 2017 5:10 am

Sorry to wake a sleeping thread, but I was wondering how I could take advantage of the 'repeated start' when I use python to control the i2c bus?
My horizon ends where I'm calling on the io module/wrapper/library when it comes to this.

Is there any method to do a write/read without the STOP via the io module in python?

Thanks.

rchackman
Posts: 4
Joined: Sun Jun 04, 2017 3:11 pm

Re: i2c repeated start transactions

Sun Jun 04, 2017 3:49 pm

@notro says:
by notro » Tue Jan 10, 2017 11:59 pm
rpi linux 4.9 uses i2c-bcm2835 with these patches.

Code: Select all

uname -a
tells me I'm running linux 4.9.24+ on my pi zero, but repeat starts aren't being generated by the python (2.7) smbus module.

I've done

Code: Select all

sudo apt-get update
sudo apt-get dist-upgrade
to ensure all up to date.

I've tried following the instructions in this thread wrt enabling combined mode but I get "permission denied" when I try to create the combined file in /sys/module/i2c_bcm2835/parameters/, even when using sudo:

Code: Select all

sudo chmod 666 /sys/module/i2c_bcm2835/parameters/
sudo nano /sys/module/i2c_bcm2835/parameters/combined
I am very-much a linux novice so it's possible I'm doing something wrong wrt creating the combined file.

I tried replacing the smbus and RPi.GPIO modules with the excellent pigpio to gain access to its alternative h/w and bit-banged I2C library but what I assume are comms delays to/from the pigpiod daemon are too slow for my application.

It seems I need those h/w restarts via smbus. Any help deeply appreciated. My project has ground to a halt.

User avatar
joan
Posts: 12705
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: i2c repeated start transactions

Sun Jun 04, 2017 4:05 pm

The combined file is only used by the i2c_bcm2708 module. The current (updated) i2c_bcm2835 module does not use or understand the combined file, It is meant (I believe) to automatically send repeated starts as needed (I don't know how).

rchackman
Posts: 4
Joined: Sun Jun 04, 2017 3:11 pm

Re: i2c repeated start transactions

Sun Jun 04, 2017 5:16 pm

@joan thanks for swift reply... and pigpio really is excellent, just not fast enough for my project (sadly). Have you considered creating a version directly callable from python rather than via the daemon (or am I being stupid)?.

Thanks to your confident assertion that repeat starts _are_ supported, I now realise I have been misinterpreting the symptoms.

Looking _very_ closely at the attached scope trace of an aborted combined WRITE-READ transaction reveals what's going on...

SCL - Green
SDA - Lt blue
Ignore red and dk blue traces.

1. The RPi is _trying_ to issue a restart (SDA floats high and is then sunk low between 2nd and 3rd bytes (REG 0xFC and ADDRESS(R) 0xC3 respectively). The problem is, the slave device is holding off the clock whilst servicing the REG byte. When the RPi sinks SDA low, the slave is still holding SCL low and the restart condition isn't met (SDA going low whilst SCL is _high_).

2. You can just see a tiny step in the green trace where presumably the RPi is attempting to float SCL high mid-way between SDA floating high and then being driven low again. Judging from SCL slew rate elsewhere, were the slave not holding off the clock, SCL would be high before SDA sinks low and the restart condition would be satisfied.

It seems the real problem is that the RPi is not honouring the slave's clock stretch.

And, sure enough, now I know the _real_ cause of the problem, a quick google reveals all: [url]viewtopic.php?p=146272[/url]

Thanks once again.
Attachments
i2cdebug.png
i2cdebug.png (23.88 KiB) Viewed 1190 times

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

Who is online

Users browsing this forum: No registered users and 9 guests