7 years, 12 months ago.

[SOLVED] I2C STOP condition between read request and data

Development kit: LP4088 QuickStart board + Experiment Base Board

Hi everyone,

I'm trying to establish a very simple communication with an I2C device. I2C frequency is 400 kHz.

        i2c.start();
        i2c.write(0xEF);
        i2c.read(1);
        i2c.read(1);
        i2c.read(1);
        i2c.stop();

The 7 bit slave address is 0x77, so 0xEF would be the read request.

The 3 bytes I need to receive are 0x00, 0x01, 0x00 from the slave.

However for some reason, I get a stop condition immediately after the read request (see below).

/media/uploads/flirflashlight/ivrh4jw.png

I have tried i2c.read(0xEF, &data, 3) but it gives me errors so I have chosen to use the simpler commands above.

Basically, I need to be seeing:

ST-ADDRESS-R-ACK DATA-ACK DATA-ACK DATA-ACK SP

I'm seeing

ST-ADDRESS-R-ACK-SP [trash data]

Any help is appreciated, thanks!

EDIT on 20160425 19:07 PST: Block read command gives this output. Important to note that EN (connected to an EN pin on slave) is connected to a +3.3V supply on the dev board, so it is strange that it is being pulled low. Slave pulls SYS_ERR down when it detects an error.

/media/uploads/flirflashlight/index.png

EDIT on 20160502 13:30 PST: Turns out my problem was the level shifter I was using. Slave is 1.8V and master is 3.3V. The level shifter did not play well with the strong pull-ups on the dev board and slave. Component choice mistake on our part. Everything is working correctly now with block transfers.

I am now using a PCA9306 ( https://www.sparkfun.com/products/11955 ) , specifically designed for I2C.

2 Answers

7 years, 12 months ago.

The slave responds with ack to the address so it receives and recognizes that correctly. However, the ack does not stay at low level long enough and is raised while SCL is still high. That leads the slave (and analyser) detecting a stop and ignoring the following read datatransfers (you get 0xFF because the bus is floating high). This seems like a problem in the slave. Which device is it? Also note that the bytewise I2C operations are not implemented/working correctly on all platforms due to i2c engine hardware issues. What does the traffic look like for the block transfer that you tested.

Thanks for the input, Wim. The device is one whose documentation I'm not allowed to release and which has no software examples or support from the manufacturer yet aside from a data brief that shows its expected operation. I've edited the original post (please see EDIT on 20160425 19:07 PST) with the output for a block read i2c.read(0xEF, &dataptr, 3);

The slave doesn't seem to like it, as the error signal trips out and the read request to the address doesn't ever appear on the analyser. A bit more info- the slave is on a board that we designed ourselves, so there is definitely a chance that hardware is an issue...

posted by Flir Flashlight 26 Apr 2016

The EN input (!) pin pulling down supply must be wrong. Check the wiring to make sure the right pins are connected. Check the power and pin level with an analog (memory)scope. In case power does get pulled down it would result in a device reset due to shorted/disconnected power and then all I2C traffic would also fail. Same could happen when EN pin gets disabled.

The SDA/SCL should be high level at the start of the transactions since they are pulled up. You see that for the byte operations, but not for the block operations. Is this happening right after power on or init? What levels do you get when there are no transactions. Try to capture the very first transactions after a reset. I have seen slaves and masters misbehave after errors and pulling down pins or not responding. The first incorrect transaction needs to be found and fixed.

What happens to the EN and ERR pins when you use the byte operations.

Some slave devices (eg camera chips, CCI) claim to be ''I2C like'' but actually dont behave correctly (eg the Ack being too short) and could confuse an I2C hardware engine on the master. The only option may then be I2C bit banging to ignore all slave errors. Did you try and check the I2C operations on any of the slave devices present on the LP4088 Experiment Board (eg the temp sensor LM75).

posted by Wim Huiskamp 26 Apr 2016

I'd second your bit-banging suggestion. Since the I/O calls wait for completion anyway there's likely to be little or no performance loss.

I'd add that with software bit-bang it should be possible to force SDA low for the second half of the ACK bit to actively prevent the false stop which may be important as it may not be enough to simply ignore it.

posted by Oliver Broad 27 Apr 2016
7 years, 12 months ago.

You might try adding low value capacitors on SCL, SDA. 33-100pF I'd guess. The peripheral might be picking up ringing and registering an extra clock edge that doesn't show on your analyser.

Incidentally I'm not certain but I understand that the master is meant to not acknowledge the very last read operation prior to the stop, to ensure the slave releases the bus prior to the "stop" being sent. Otherwise contention could prevent the stop condition being registered.

Correct, Master is not supposed to ack very last read operation. However, in the above case (ie byte operations) things have gone wrong even before that on the first ack from the slave. Looks to me that the slave is releasing the ack SDA line right after the rising edge of the master SCL. It should instead have waited until the falling edge of SCL. This behaviour (rising SDA while SCL is high) is interpreted as a Stop condition be the I2C hardware and by the analyser.

posted by Wim Huiskamp 28 Apr 2016

I was more thinking about capacitance. I seem to recall old schematics from the 1990s tended to load SCL, SDA with a small cap unless it was a direct connection to an EEPROM right next to the micro.

I wonder if somehow a runt-pulse gets onto SDA at the rising edge of SCL causing the slave interface to reset. The half-ACK might be the symptom not the cause and simply adding capacitance at the slave device might be enough to suppress it and restore expected behavior. It probably won't but it is a cheap fix if it does.

posted by Oliver Broad 29 Apr 2016

Thank you for your input, Oliver and Wim. Turns out my problem was the level shifter I was using. Slave is 1.8V and master is 3.3V. The level shifter did not play well with the strong pull-ups on the dev board and slave. Component choice mistake on our part. Everything is working correctly now with block transfers.

I am now using a PCA9306 ( https://www.sparkfun.com/products/11955 ) , specifically designed for I2C.

posted by Flir Flashlight 02 May 2016

I guess the EN pin behavior should have been the clue, it was showing up low when it shouldn't. It hadn't occured to me that a level translation was needed.

Which level translator had you been using before, was it the TXB0108 by any chance?

Also while level translation is the safe option is there any indication whether SCL, SDA might be voltage-tolerant? Sometimes it is under device "Maximum Ratings"

posted by Oliver Broad 03 May 2016