Advertisements

Raspberry Pi I2C Bus Timing vs. BNO055 Clock Stretching

An Adafruit BNO055 connected to a Raspberry Pi 3 I2C bus, despite knowing it won’t work:

I2C 100kHz - BNO055 SCL 1 mA-div - B7 Rd error

I2C 100kHz – BNO055 SCL 1 mA-div – B7 Rd error

The I2C bus ticks along at 100 kHz (nominal) = 62.5 kHz (actual), as described a while ago.

The three digital traces along the bottom are D0 = SCL, D1 = SDA, and D2 = trigger raised when the Python program detects an error.

The upper trace shows the SCL current (1 mA/div) between the Pi and the BNO055, as described yesterday, with the latter stretching the clock whenever the current goes negative.

The fourth burst is the BNO055 sending the chip’s temperature in response to a simple request:


temp_c = bno.read_temp()

A closer look at the last transaction:

I2C 100kHz - BNO055 SCL 1 mA-div - B7 Rd error - SCL glitch

I2C 100kHz – BNO055 SCL 1 mA-div – B7 Rd error – SCL glitch

I commend to your attention a useful tutorial on I2C bus protocols / transactions / signalling.

Over on the left, the BNO055 has SCL held low (-2 mA) during the ACK phase of the previous byte. The first upward SCL edge marks the ACK, with the BNO055 holding SDA low during the edge until the Pi drops SCL.

The BNO releases SDA when SCL goes low again, whereupon SDA goes high, exactly as it should.

Now, things gets ugly.

The -1 mA current on SCL shows both the Pi (+1 mA) and the BNO (-2 mA) are pulling SCL low.  The BNO is clock-stretching after the ACK, which the Pi can’t handle.

The Pi seems to think the rising edge of SCL occurs when it stops pulling SCL down, at the point where the SCL current goes from -1 mA to -2 mA, halfway though the high SDA pulse. It reads SDA at that point and receives an incorrect binary 1 bit from SDA, because the BNO hasn’t yet seen a rising SCL edge.

The SCL rising edge occurs when the BNO055 releases SCL and produces the SCL sliver.

Here’s a very close look at the sliver:

I2C 100kHz - BNO055 SCL 1 mA-div - B7 Rd error - Pi SCL mistiming

I2C 100kHz – BNO055 SCL 1 mA-div – B7 Rd error – Pi SCL mistiming

The two vertical cursors bracketing the sliver mark the 16 µs SCL timing produced by the Pi’s SCL clock, which is not the 10 µs you’d expect at 100 kHz.

The right cursor sits on the next rising edge, so the left cursor marks where SCL should rise: exactly where the Pi releases its hold on SCL and expects it to pop up.

That error happens about 6% of the time, producing a chip temperature 128 °C higher than reality. The other 94% of the reads either work correctly or, perhaps, encounter a bogus SDA state coincidentally delivering a binary zero that looks good.

Here’s a sample of a “good” read:

I2C 100kHz - BNO055 SCL 1 mA-div - B7 Rd OK - long SCL high

I2C 100kHz – BNO055 SCL 1 mA-div – B7 Rd OK – long SCL high

The stop bit is now off to the right, so the last rising SCL edge is the ACK. Counting leftward eight edges from the ACK, the left cursor marks where the SCL edge should be for bit B7. Instead it occurs instantly after the BNO releases its hold on SCL, shown by the transition from -2 mA to 0 mA. I don’t know the setup and hold times for the Pi’s I2C port, but 250-ish ns seem aggressive; I think the data transitions should happen close to the down-going SCL edges.

Running the I2C bus at 200 kHz seems to work fine, but it still has the same aggressive SDA-to-SCL setup time. Here’s a close look at the same situation as in the previous photo, with SCL set for 200 kHz:

I2C 200kHz - BNO055 SCL 1 mA-div - Rd OK - 250 ns SDA-SCL setup

I2C 200kHz – BNO055 SCL 1 mA-div – Rd OK – 250 ns SDA-SCL setup

This being a read, the BNO sets SDA to whatever it should be, then releases its clock-stretching hold on SCL about 200 ns later. The Pi raises SCL shortly thereafter and it apparently Just Works. Maybe it’s Good Enough to be consistent, but I’d like to run more tests before trusting it.

Anyhow, that’s how the Pi’s I2C hardware doesn’t handle a chip using clock stretching.

Advertisements

  1. Streaming Radio Player: I2C Display | The Smell of Molten Projects in the Morning

Spam comments vanish. Comment moderation may cause a delay.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s