Electronic – BMA180 accelerometer. How does it manage to share pins between I2C and SPI

i2cspi

BMA180 accelerometer can be either SPI slave or I2C slave. The pins for both buses are shared.

SPI mode                    I2C mode
---------------------------------------------------
SDI  input                  SDA  bidirectional (!)
SDO  output                 ADDR address bit, input
SCLK input                  SCL  input
CSB  chip select, input     I2C  mode select, input

According to the datasheet (see chapter 8), the selection between buses is done through the CSB pin. When CSB is low, the device is an SPI slave. When CSB is high, the device is an I2C slave.

Here's a failure mode, which I'm concerned about. Suppose, BMA180 is on the SPI bus. There is also another device on the same bus with it’s own chip select. Suppose, SPI bus master is communicating to that other device. CSB for BMA180 is high, so it’s I2C should be enables. BMA180 sees clock edges on SCL (SPI's SCLK) and bits on SDA (SPI's MOSI) flying by. What if some of these bits look to BMA180 like a start of a valid I2C read transaction, and BMA180 starts to output data and clobbers the existing SPI transaction? How would the design of BMA180 prevent that?

This is a matter of curiosity. I haven’t experimented with these issues yet. I will be using BMA180 on SPI.

Any suggestion, insight or reference is really appreciated!

Update. Found something in the datasheet (see 7.7.11). It recommends disabling I2C by setting the dis_i2c bit, if communicating with BMA180 via SPI.

When SPI interface is used, it's highly recommended to set dis_i2c to
1 to avoid malfunction.

BMA180 has built-in EEPROM. Register contents can be stored in the EEPROM and automatically loaded on power-up sequence. So, it's possible to make BMA180 ignore I2C completely and always.

Update. L3GD20 gyro is another IC, which shares pins between I2C and SPI in a a similar way. It doesn't seem to have a bit setting for disabling the I2C mode. So, it would require an OR gate like ADXL345, which @markrages brought up.

Heads up! Bosch stopped shipping BMA180 (official letter here).

Best Answer

I've seen exactly the behavior you're afraid of on an ADXL345, which uses the same I2C/SPI selection scheme. I had another SPI device that used different clock polarity and it happened to emulate an I2C start code, the ADXL345 tried to talk out of turn as I2C. Bad news.

I carefully rewrote the SPI as bit bang instead of using the peripheral, making sure to not change the MOSI line while the clock was high. (This is the I2C start condition.) That seemed to solve things.

If I was starting from scratch, I would try to use I2C bus instead or a dedicated SPI port for the ADXL345.

Apparently I wan't the only one to encounter this. This paragraph appeared in a later revision of the ADXL345 datasheet:

enter image description here