Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDA line held low even after a Stop issued. #34

Open
GoogleCodeExporter opened this issue Mar 25, 2015 · 2 comments
Open

SDA line held low even after a Stop issued. #34

GoogleCodeExporter opened this issue Mar 25, 2015 · 2 comments

Comments

@GoogleCodeExporter
Copy link

What steps will reproduce the problem?
Set MPSSE to Ack following each read byte.
Perform an I2C Read followed by a Stop.  The number of bytes read doesn't 
matter.

What is the expected output? What do you see instead?
Using a logic analyzer, I can see that where the stop is issued, the SCL line 
goes high but the SDA line always stays low.  The next I2C operation fails 
because a valid start condition can't be generated.

Calling SendNacks and issuing a dummy read is incorrect if you are trying to 
read from a device that has a FIFO buffer or auto-incrementing support.

What version of the product are you using? On what operating system?
LibMPSSE v1.3 along with ftdi v1.0 on OSX 10.8.5

Please provide any additional information below.
I've tried forcing the SDA line high with a variety of set_bits or PinHigh 
calls without success.  I've tried using the FlushAfterRead call as well.  I'm 
trying to talk to an Invensense MPU9150 digital motion processor.

Original issue reported on code.google.com by [email protected] on 25 Sep 2013 at 3:47

@GoogleCodeExporter
Copy link
Author

After several days of hacking, testing, and observation with a logic analyzer, 
I've come up with a fix.

Background:
The Invensense MPU-9150 supports burst reads.  From their documentation:

"To read the internal MPU-9150 registers, the master sends a start condition, 
followed by the I2C address and
a write bit, and then the register address that is going to be read. Upon 
receiving the ACK signal from the
MPU-9150, the master transmits a start signal followed by the slave address and 
read bit. As a result, the
MPU-9150 sends an ACK signal and the data. The communication ends with a not 
acknowledge (NACK)
signal and a stop bit from master. The NACK condition is defined such that the 
SDA line remains high at the
9th clock cycle."

However, the LibMPSSE Read function leaves the SDA line in the last ACK state 
seen or as specified with SendAck or SendNack.  In order to bring the SDA line 
high for a proper Stop condition to be present on the pins, what we really need 
is to have the last byte read send a NACK but all previous bytes send an ACK.

The Fix:
In support.c, we modify line 185 as follows:

// Old way
buf[i++] = mpsse->tack;

// New way
if ( j == num_blocks-1 )
   buf[i++] = 0xFF;
else 
   buf[i++] = mpsse->tack;

This causes the last byte sent to put a NACK on the line.  Now perhaps in 
future versions this should be an option.  E.g Send the inverted acknowledge 
state.  It would probably depend on the device.

Original comment by [email protected] on 27 Sep 2013 at 4:19

  • Added labels: ****
  • Removed labels: ****

@GoogleCodeExporter
Copy link
Author

If you are just doing a single-byte read sequence, the following should work:

i2c.SendNacks()
i2c.Start()
data = i2c.Read(1)
i2c.Stop()

For multiple bytes where you want ACKs on all but the last byte, this should 
work:

i2c.SendAcks()           # Always send ACKs
i2c.Start()
data = i2c.Read(3)     # Read the first three bytes
i2c.SendNacks()         # From here on out, send NACKs
data += i2c.Read(1)  # Read the last byte
i2c.Stop()

Is this not the case? Regardless, your solution is probably more convenient as 
sending a NACK on the last byte read is a fairly common operation.

Original comment by [email protected] on 1 Oct 2013 at 7:11

  • Added labels: ****
  • Removed labels: ****

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant