MBA180 sensor SPI (four wire connection) with interrupt demo. Fifty samples are read, stored in a array and presented.

Dependencies:   mbed

main.cpp

Committer:
GerritPathuis
Date:
2010-12-18
Revision:
0:8ce1608bb6f8

File content as of revision 0:8ce1608bb6f8:

#include "mbed.h"
#define BMA180_ID       0x00
#define VERSION         0x01
#define ACCXLSB         0x02
#define ACCXMSB         0x03
#define ACCYLSB         0x04
#define ACCYMSB         0x05
#define ACCZLSB         0x06
#define ACCZMSB         0x07
#define CTRL_REG0       0x0D
#define DIS_I2C         0x27    // bit 0 must be 1 for SPI
#define CTRL_REG3       0x21    // bit 1= new_data_int
#define RESET           0x10    // soft reset

/*-------------Hardware connections-------------
By Gerrit Pathuis (gpa@quicknet.nl)
MBA180 breakour board (sparkfun) is used
VIO----- mbed Vout (3.3 Volt)
SDI----- mbed mosi (p5)
SDO----- mbed miso (p6)
SCK----- mbed sck  (p7)
CS------ mbed (p8)          // chip select
INT----- mbed (p9)          // MBA give a interrupt when ready
GND----- mbed GND (0 Volt)
VDO----- mbed Vout (3.3 Volt)
there are no additional external components used
//----------------------------------------------*/

SPI spi(p5,p6,p7); //mosi, miso, sclk
DigitalOut cs(p8);
InterruptIn event(p9);

Serial pc(USBTX, USBRX); // tx, rx
void init_SPI_BMA180(void);
void soft_reset(void);
void trigger(void);
void new_data(void);
void write_bits(char u);
void write_reg(uint8_t address, char data);
char read_reg(uint8_t address);
void disable_int(void);

struct sample {                 // reserve spave for 1000 samples
    signed short x;
    signed short y;
    signed short z;
    signed short t;
} vib[1000+1];

int sample_cnt;

int main() {
    int pp;
    float xx, yy, zz;

    init_SPI_BMA180();          // init the sensor
    sample_cnt =0;              // start the counter
    pc.printf("Start lurking  ");
    while (sample_cnt <50) {
        event.rise(&trigger);
    }
    disable_int();              // switch the BMA180 off
    pc.printf("\n\r\nPresent the data\n\r");
    for (pp=0; pp<50; pp +=1)  {
        // 2^14 = 16384
        // Range is +/1 2.0 G versnelling
        xx = vib[pp].x/16384.0*4.0;
        yy = vib[pp].y/16384.0*4.0;
        zz = vib[pp].z/16384.0*4.0;
        pc.printf("Sample %2d, Acc X= %0.4f, Y= %0.4f, Z= %0.4f \n\r", pp, xx, yy, zz);
    }
}

void init_SPI_BMA180(void) {
    char readVersion, readID;
    char byte;
    // Setup the spi for 8 bit data, high steady state clock,
    // second edge capture, with a 10MHz clock rate

    spi.frequency(10000000);        // 10 mHz page 59 of the BMA180 datasheet
    spi.format(8,3);                // Not conform !!! page 58 of the BMA180 datasheet)
    wait_ms(100);
    readID = read_reg(BMA180_ID);
    readVersion = read_reg(VERSION);
    pc.printf("\n\r");
    if (readID == 3) {
        pc.printf("Connected to BMA180\n\r");
        pc.printf("BMA180 Version %d\n\r", readVersion);
    } else
        pc.printf("Sorry not connected to BMA180 !!!\n\r", readID);

    soft_reset();   // to copy EEprom into volatile area

    //---------------------------
    byte = read_reg(CTRL_REG0);             // Unlock image writing
    byte |= 0x10;                           // Set bit 4
    write_reg(CTRL_REG0,byte);              // Have to set ee_w to
    //------------------------
    byte= read_reg(DIS_I2C);                // read
    byte |= 0x01;                           // set bit0 to 1, SPI only
    write_reg(DIS_I2C, byte);               // Set spi, disable i2c, page 31
    //-------------------------
    byte = read_reg(CTRL_REG3);
    byte |= 0x02;                           // set bit 1 enable interrupt
    byte |= 0x40;                           // set bit 6 slope mode
    byte |= 0x80;                           // set bit 6 slope alert
    write_reg(CTRL_REG3,byte);              //
    pc.printf("Enable interrupt bis is set ");
    //------------------------------
    byte = read_reg(CTRL_REG0);             // Lock image writing
    byte &= 0xEF;                           // REset  bit 4
    write_reg(CTRL_REG0,byte);              // Have to set ee_w to
    //-------------------------------------------------------------------------------------
    pc.printf("\n\rBMA init done    \n\r");
}

void soft_reset(void) {
    // Write a soft reset
    // to copy EEprom into volatile area, see mid page 22
    write_reg(RESET, 0xB6);             // page 48
    wait_ms(10);                        // wait 10 ms, see page 49
    pc.printf("Soft reset, EEPROM copied    \n\r");
}

//-----------------READ OUT the X-Y-Z values---------------
void trigger(void) {
    char x_lsb, x_msb;
    char y_lsb, y_msb;
    char z_lsb, z_msb;
    signed short ax, ay, az;

    //------------X----------------
    x_lsb = read_reg(ACCXLSB);
    x_msb = read_reg(ACCXMSB);
    ax = (x_msb << 8) |  x_lsb ;   // combineer msb en lsb
    ax = ax >> 2;                  // Get rid of two non-value bits in LSB
    //------------Y----------------
    y_lsb = read_reg(ACCYLSB);
    y_msb = read_reg(ACCYMSB);
    ay = (y_msb << 8) | y_lsb;     // combineer msb en lsb
    ay = ay >> 2;                  // Get rid of two non-value bits in LSB
    //------------Z----------------
    z_lsb = read_reg(ACCZLSB);
    z_msb = read_reg(ACCZMSB);
    az = (z_msb << 8) |  z_lsb;    //  combineer msb en lsb
    az = az >> 2;                  // Get rid of two non-value bits in LSB

    //----------shift into the array---------------------
    vib[sample_cnt].x= ax;
    vib[sample_cnt].y= ay;
    vib[sample_cnt].z= az;
    //---------counter------------
    sample_cnt += 1;
}

void write_reg(uint8_t address, char data) {
    address &= 0x7F;                        //Force a write (bit 7=0)
    cs=0;                                   //Select SPI device
    wait_us(2);
    spi.write(address);                     //Send register location
    wait_us(2);
    spi.write(data);                        //Send value to record into register
    wait_us(2);
    cs=1;
    wait_us(2);
}

char read_reg(uint8_t address) {
    char byte;
    address |= 0x80;                        //Force a read (bit 7=1)
    cs=0;
    wait_us(2);                             //Select SPI device
    spi.write(address);                     //Send register location
    wait_us(2);
    byte=spi.write(0xFF);                   //Get the data
    wait_us(2);
    cs=1;
    wait_us(2);
    return byte;
}

void disable_int(void) {
    char byte;
    byte = read_reg(CTRL_REG0);             // Unlock image writing
    byte |= 0x10;                           // Set bit 4
    write_reg(CTRL_REG0,byte);              // Have to set ee_w to
    //-------------------------
    byte = read_reg(CTRL_REG3);
    byte &= 0xFD;                           // REset bit 1 enable interrupt
    write_reg(CTRL_REG3,byte);              //
    pc.printf("\n\rDisable interrupt bis is set ");
    //------------------------------
    byte = read_reg(CTRL_REG0);             // Lock image writing
    byte &= 0xEF;                           // REset  bit 4
    write_reg(CTRL_REG0,byte);              // Have to set ee_w to
    pc.printf("\n\rMBA180 in now switched off ");
}