Wire Library doesn't handle Repeated START commands in I2C slave mode [imported] #848

Closed
cmaglie opened this Issue Nov 15, 2012 · 5 comments

Projects

None yet

5 participants

@cmaglie
Member
cmaglie commented Nov 15, 2012

This is Issue 848 moved from a Google Code project.
Added by 2012-03-07T03:05:19.000Z by natew...@gmail.com.
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Defect, Priority-Medium

Original description

What steps will reproduce the problem?

1.Create a Slave I2C device (Wire.begin(0xCA >> 1)).
2.On the I2C master, send a request that contains a repeated START command
3.Verify that the Arduino does not respond to the second request

Using the BusPirate, to generate a read request the following commands are given to write to the I2C slave to specify the register to read, followed by the actual read request. Let's assume the 'Read' register is 0x00.

[OxCA 0x00 [0xCB rr]

English description of the above.

The start command [ is given, and we are writing to the device (LSB addres bit is 0, and the data we are writing is '0x00', the register we intend on reading. After writing to the register, in order to do an atomic transaction to indicate we want to read from this register, the master creates another START request [. This time, the request is a read (address LSB bit is now 1) and we are requesting two bytes.

What is the expected output? What do you see instead?

In the Arduino, the Wire.onReceive() callback is called correctly for the write, but due to addition of twi_stop() in the TW_SR_STOP case of the interrupt service routine, the master times waiting for the slave. Note, sending a STOP bit is not a valid response in the two-wire protocol per the Atmel documentation (see page 237 of the Atmel documentation in the two-wire section for case 0xA0{TW_SR_STOP}). The slave code should never be sending a STOP bit. Inferring the original intent of the author from the provided comment, if the desire was to support clock stretching, the way to do that is to NOT clear the TWINT flag until the callback completes. This is what the original code did, and the new code would do in twi_busRlease() if the two_stop() method and comment is removed.

What version of the Arduino software are you using? On what operating
system? Which Arduino board are you using?

Arduino 1.0 software on OS/X, using multiple Arduino UNO boards.

Tests were done using a BusPirate (http://dangerousprototypes.com/category/bus-pirate/) as well as a National Instruments cRIO, both running as an I2C master attempting to do atomic reads of a register address on an I2C slave. The code follows the same patterns as used in most I2C drivers, including those in LeJOS (http://www.lejos.org).

Using both, I verified the incorrect behavior with the stock 1.0 Arudino Wire library (really, the twi.c ISR), and with the two_stop() method removed, the Arduino responded correctly when requested from the two separate I2C masters.

Please provide any additional information below.

See comment from both wallclimber1 and HelenaRobotics (myself).

7392f85#libraries/Wire/utility/twi.c

@wrffrz
wrffrz commented Jan 31, 2013

This issue also exists with the arduino-1.0.3-windows release and Leonardo board. Commenting out libraries/Wire/utility/twi.c:468 twi_stop() does resolve this issue and tests well so far.

@ghost
ghost commented Jun 20, 2013

In Arduino 1.0.5, in june 2013 this problem still exist.
Commenting out that line solved only a part of my problem: http://forum.arduino.cc/index.php?topic=172296.0

@ffissore ffissore added the New label Feb 27, 2014
@cmaglie cmaglie removed the New label Feb 27, 2014
@baronep
baronep commented Jun 25, 2015

I also have struggled through this issue and would hope that it is fixed soon. I outlined by debug process here: http://forums.adafruit.com/viewtopic.php?f=49&t=75720.

@cmaglie cmaglie was assigned by ffissore Jul 1, 2015
@sandeepmistry
Member

@cmaglie this should be resolved now that #66 has been merged.

@sandeepmistry
Member

Closed via #66.

@ffissore ffissore modified the milestone: Release 1.6.6 Oct 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment