3

I've looked at all the info that I could find on I2C repeated starts, and I tested a simple example that uses ioctl calls with the standard two message structure required to cause a repeated start:

  struct i2c_msg rdwr_msg[] =
  {
    {  // Start address
      .addr = 0x52,
      .flags = 0, // write
      .len = 1,
      .buf = &command
    },
    { // Read buffer
      .addr = 0x52,
      .flags = I2C_M_RD, // read
      .len = 1,
      .buf = read_buffer
    }
  };
...
  rdwr_data.msgs = rdwr_msg;
  rdwr_data.nmsgs = 2;
  command = 0x00;
  read_buffer[0] = 0xEE;  // Preset to see if it is overwritten by read

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

I can see that the I2C signals are different when the combined parameter is set to enable repeated starts. There is sort of a repeated start, but the data is off by one bit. The repeated start is circled in red in the two following screenshots. The address sent after the restart is 0x52. The first one is from the PI2 and the second one is from a USB I2C interface. Only the second one correctly accesses the device. So the question remains, has anyone successfully used repeated starts on the PI2?

Bad repeated restart to addr 0x52 from PI2 Good repeated restart to addr 0x52 from a USB I2C interface

Ghanima
  • 15,855
  • 15
  • 61
  • 119
crj11
  • 493
  • 4
  • 9

1 Answers1

2

Some people have reported success using the module combined parameter to trigger repeated starts. I have done so myself but I have not found it to be reliable.

In my tests eventually a I2C segment will fail and from then on I2C transactions will go wrong. To recover the situation I stop using the combined flag (see i2cz for details).

paul /ram $ pigs i2cz 0 2 4 0x53 7 1 0x32 6 6 3 0
6 185 255 48 0 240 254
paul /ram $ pigs i2cz 0 2 4 0x53 7 1 0x32 6 6 3 0
6 186 255 49 0 240 254
paul /ram $ pigs i2cz 0 2 4 0x53 7 1 0x32 6 6 3 0
6 185 255 49 0 240 254
paul /ram $ pigs i2cz 0 2 4 0x53 7 1 0x32 6 6 3 0
6 185 255 48 0 239 254
paul /ram $ pigs i2cz 0 2 4 0x53 7 1 0x32 6 6 3 0
ERROR: an I2C transaction segment failed
-106
paul /ram $ pigs i2cz 0 2 4 0x53 7 1 0x32 6 6 3 0
6 50 185 255 49 0 239
paul /ram $ pigs i2cz 0 2 4 0x53 7 1 0x32 6 6 3 0
6 50 0 0 229 0 0
paul /ram $ pigs i2cz 0 2 4 0x53 7 1 0x32 6 6 3 0
6 50 229 0 0 0 0
paul /ram $ pigs i2cz 0 3 4 0x53 7 1 0x32 6 6 3 0 # combined flag off (3)
6 186 255 47 0 239 254
paul /ram $ pigs i2cz 0 3 4 0x53 7 1 0x32 6 6 3 0
6 185 255 49 0 240 254
paul /ram $ pigs i2cz 0 3 4 0x53 7 1 0x32 6 6 3 0
6 186 255 48 0 238 254

The above shows reading an ADXL345 with and without the combined flag.

pigs i2cz 0 2 4 0x53 7 1 0x32 6 6 3 0

This is a multiple segment transaction on handle 0 (pigs i2cz 0).

2 - sets the combined flag 
4 0x53 - sets the I2C address (ADXL345) 
7 1 0x32 - writes 1 byte (0x32) 
6 6 - reads six bytes 
3 - clears the combined flag 
0 - end command

In contrast if I bit bang I2C I can use repeated starts without problem.

The following is the same as above but using bit bang (see bi2cz for details).

paul /ram $ pigs bi2co 2 3 50000 # open 2/3 for I2C bit bang at 50kbps
paul /ram $ pigs bi2cz 2 4 0x53 2 7 1 0x32 2 6 6 3 3 0
6 185 255 49 0 239 254
paul /ram $ pigs bi2cz 2 4 0x53 2 7 1 0x32 2 6 6 3 3 0
6 186 255 48 0 241 254
paul /ram $ pigs bi2cz 2 4 0x53 2 7 1 0x32 2 6 6 3 3 0
6 185 255 49 0 240 254
paul /ram $ pigs bi2cz 2 4 0x53 2 7 1 0x32 2 6 6 3 3 0
6 186 255 49 0 239 254

The 2 command is now a start condition. The 3 command is a stop condition.

joan
  • 71,024
  • 5
  • 73
  • 106
  • Thanks for the incredibly fast and useful answer! I downloaded your library and now have the bit bang version working. I didn't bother trying the combined flag version. Your library is a life saver! The only minor suggestion I would make is to add an option for hex display of the read data for the pigs command line utility. – crj11 May 20 '15 at 15:15
  • @crj11 I've had a play and added -a (ascii) and -x (hex) flags to pigs. As long as I don't uncover any problems I'll add that functionality to the next release. – joan May 21 '15 at 07:52