Read data from an ADIS16355 IMU and write it to the USB port.

Dependencies:   mbed

imu-spi.cpp

Committer:
yahugh
Date:
2011-08-10
Revision:
0:c6ee363ac724

File content as of revision 0:c6ee363ac724:

//
// imu-spi.cpp
//
// copyright 2010 Hugh Shane
//
#include "mbed.h"
#include "imu-spi.h"

ImuSpi::ImuSpi(void) :
    spi(p5, p6, p7), // mosi, miso, sclk
    cs(p8), // IMU chip select
    reset(p8), // IMU reset. CAUTION! This also resets the altimeter.
    diag(p21), // diagnostic output
    imuDataReady(p11) // interrupt on IMU data-ready
{
    // Setup the spi for 16 bit data, high steady state clock,
    // second edge capture, with a 1 MHz clock rate
    spi.format(16,3);
    spi.frequency(1000000);
    
    // init the pingpong buffer
    pingpong = 0;
    
    // init the interrupt semaphore
    dataReady = false;    
    
    // interrupt on the falling edge of the IMU data-ready signal
    diag = 0;
    imuDataReady.fall(this, &ImuSpi::DataReadyISR);
    
    // init the IMU
    InitImu();

}

void  ImuSpi::reinitInterrupts(void) {
    imuDataReady.fall(this, &ImuSpi::DataReadyISR);
}

// initialize the IMU
void ImuSpi::InitImu(void) {
    // deselect the IMU
    cs = 1;
    reset = 1;
    // perform a hard reset
    reset = 0; wait(.1); reset = 1;    
    // send initialization commands
    Write(0x34, 0x04); // enable active low data ready on DIO1
    Write(0x38, 0x00); // Set the FIR filter to its widest possible bandwidth
}

// read the IMU accelerometer and gyro registers into the pingpong buffer
void ImuSpi::BurstRead(void) {
    static int16_t imuRegs[] = {0x04,0x06,0x08,0x0A,0x0C,0x0E,0x3C};
    int16_t* wp = GetBufferWritePtr();
    Read(imuRegs[0]); // set up the first register read operation
    wait(0.000024); // required to meet IMU t(datarate) spec
    
    // send register read commands & read the registers
    for (int i = 1; i <= 6; i++) {
        *wp++ = Read(imuRegs[i]);
        wait(0.000024);
    }
    *wp = Read(0); // read the last register output
}

int16_t ImuSpi::Read(char adr) {
    int16_t cmd = 0x3f00 & (adr << 8);
    int16_t response;
    cs = 0;
    response = spi.write(cmd);
    cs = 1;
    return response;
}


void ImuSpi::Write(char adr, char data) {
    int16_t cmd = 0x8000 | (adr << 8) | data;
    cs = 0;
    spi.write(cmd);
    cs = 1;
}

bool ImuSpi::IsDataReady(void) {
    if (dataReady == true) {
        dataReady = false;
        return true;
    } else {
        return false;
    }
}

void ImuSpi::DataReadyISR(void) {
diag = 1;
    TogglePingpong();
    dataReady = true;
diag = 0;
}