Monday, 18 July 2016

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


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).



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


No comments:

Post a Comment

arduino - Can I use TI's cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...