Thanks for the reply!
I’m using an Arduino Uno R3. I’ve distilled down the code so that it just starts up SPI and dumps registers to Serial out. If I have the XBee connected to power and GND, I get all zeros (no SPI comm). If I disconnect VCC from the XBee and hit reset on the arduino, the registers dump perfectly.
I am an SPI noob - it’s quite possible there’s just some timing thing I should be setting up in SPI that I’m not doing and that’s what’s making it stop working, especially because two separate SPI devices exhibit the same behavior (the BMA180 accelerometer and an MPL115A1 barometer). I have not toyed with adding in delay()s here and there because I’d like to understand what’s going on before I start altering the timing in random ways.
Also, the 10uF cap I have is an electrolytic. I ordered some ceramics to try that match the data sheet (8.2pf, 1uf, 10uf) but they’re not here yet. Although for decoupling I kinda figured a cap is a cap, more or less, but I could easily be quite mistaken.
Any ideas? Thanks in advance!!!
// BMA SPI Tests
// BMA180 Pins:
// INT is UNO Pin 2
// CS is UNO Pin 7
// MOSI is UNO Pin 11
// MISO is UNO Pin 12
// SCK is UNO Pin 13
// BMA180 SPI Parameters:
// 1. Bit Order: MSB first, so setBitOrder(MSBFIRST).
// 2. Polarity: polarity = 1, phase = 0 (pp. 58), so SPI.setDataMode(SPI_MODE2)
// (see http://arduino.cc/en/Reference/SPI).
// NOTE: For some reason the default settings seem to work fine.
// Control Registers. Section 7.10, p.46.
#define BMA180_CTRL_REG0_ADDR 0x0D
#define BMA180_CTRL_REG0_EE_W_BIT 0x10
#define BMA180_CTRL_REG3_ADDR 0x21
#define BMA180_CTRL_REG3_ADV_INT_BIT 0x04
// Offsets. MSB is <11:4>, LSB is <3:0>. You should never have to use
// or change these as these values are set in the factory. Google for
// calibration information if you're feeling really adventurous and
// have your BMA180 mounted securely in something VERY level.
#define BMA180_OFFSET_X_MSB_ADDR 0x38
#define BMA180_OFFSET_Y_MSB_ADDR 0x39
#define BMA180_OFFSET_Z_MSB_ADDR 0x3A
#define BMA180_OFFSET_LSB1_ADDR 0x35
#define BMA180_OFFSET_LSB2_ADDR 0x36
// Also contains Mode Config.
#define BMA180_TCO_Z_ADDR 0x30
#define BMA180_BW_TCS_ADDR 0x20
// BW (Bandwidth) is high-order 4 bits.
#define BMA180_BW_MASK 0xF0
#define BMA180_BW_10HZ 0x00
#define BMA180_BW_20HZ 0x10
#define BMA180_BW_40HZ 0x20
#define BMA180_BW_75HZ 0x30
#define BMA180_BW_150HZ 0x40
#define BMA180_BW_300HZ 0x50
#define BMA180_BW_600HZ 0x60
#define BMA180_BW_1200HZ 0x70
#define BMA180_BW_HIGH_PASS 0x80
#define BMA180_BW_BAND_PASS 0x90
// Chip ID. Reading this to verify connectivity and communication with
// the device is a pretty good idea.
#define BMA180_CHIP_ID_ADDR 0x00
// Acceleration and Temperature data. MSB is <13:6>, LSB is packed 8
// bits (<5:0> 0 new_data_flag).
#define BMA180_ACC_X_LSB_ADDR 0x02
#define BMA180_ACC_X_MSB_ADDR 0x03
#define BMA180_ACC_Y_LSB_ADDR 0x04
#define BMA180_ACC_Y_MSB_ADDR 0x05
#define BMA180_ACC_Z_LSB_ADDR 0x06
#define BMA180_ACC_Z_MSB_ADDR 0x07
#define BMA180_TEMP_ADDR 0x08
#define BMA180_NEW_ACCEL_DATA_BIT 0x01
// Range. Section 7.7.1, p. 27.
// Range is 3 bits, ranging from 1g to 16g. The value is stored in the
// offset_lsb1 register, in the high 3 bits of the lower nibble:
// 0x35 -> | offset_x<3:0> (lsb) | range<2:0> | smp_skip |
#define BMA180_RANGE_1G ( 0x00 << 1 )
#define BMA180_RANGE_1_5G ( 0x01 << 1 )
#define BMA180_RANGE_2G ( 0x02 << 1 )
#define BMA180_RANGE_3G ( 0x03 << 1 )
#define BMA180_RANGE_4G ( 0x04 << 1 )
#define BMA180_RANGE_8G ( 0x05 << 1 )
#define BMA180_RANGE_16G ( 0x06 << 1 )
#define BMA180_RANGE_MASK 0x0E
#include <SPI.h>
#define BMA180_INT_PIN 2
#define BMA180_CS_PIN 7
void readFromBMA180( byte startAddress, int numBytesToRead, byte* receiveBuf )
{
digitalWrite( BMA180_CS_PIN, LOW );
// Bitwise-OR in the R/W bit, bit 8. Datasheet p. 59.
// 1 = Read, 0 = Write.
SPI.transfer( startAddress | 0x80 );
for (int i = 0; i < numBytesToRead; i++ )
{
receiveBuf[ i ] = SPI.transfer( 0x00 );
}
digitalWrite( BMA180_CS_PIN, HIGH );
}
void writeTo( byte registerAddress, byte value )
{
digitalWrite( BMA180_CS_PIN, LOW );
// Bitwise-AND down the R/W bit, bit 8. Datasheet p. 59.
// 1 = Read, 0 = Write.
SPI.transfer( registerAddress & 0xEF );
SPI.transfer( value );
digitalWrite( BMA180_CS_PIN, HIGH );
}
// Some of these are reserved. We just read them all anyway.
byte BMA180RegisterCache[ 0x60 ];
void dumpRegisterCacheToSerial( )
{
for ( int i = 0x5F; i > 0x1F; i-- )
{
Serial.print( " 0x" ); Serial.print( i, HEX ); Serial.print( " | " ); // Register Address
Serial.print( BMA180RegisterCache[ i ], HEX ); Serial.print( "\t| "); // Value in Hex );
Serial.println( BMA180RegisterCache[ i ], BIN );
}
for ( int i = 0x10; i > -1; i-- )
{
Serial.print( " 0x" ); Serial.print( i, HEX ); Serial.print( " | " ); // Register Address
Serial.print( BMA180RegisterCache[ i ], HEX ); Serial.print( "\t| "); // Value in Hex );
Serial.println( BMA180RegisterCache[ i ], BIN );
}
}
void setup()
{
Serial.begin( 9600 );
// Don't seem to need these?? Odd...
// SPI.setClockDivider( SPI_CLOCK_DIV2 );
// SPI.setBitOrder(MSBFIRST);
// SPI.setDataMode(SPI_MODE0);
SPI.begin();
pinMode( BMA180_INT_PIN, INPUT );
pinMode( BMA180_CS_PIN, OUTPUT );
Serial.println( "Start..." );
byte chipID;
readFromBMA180( 0x00, 1, &chipID );
Serial.println( chipID, HEX );
// Update register cache.
readFromBMA180( 0x00, 0x60, BMA180RegisterCache );
dumpRegisterCacheToSerial( );
}
void loop()
{
}