ADXL362 Deep FIFO Buffer

main.cpp

Committer:
tkreyche
Date:
2013-10-15
Revision:
0:73eaa4d98d25

File content as of revision 0:73eaa4d98d25:

#include "mbed.h"

// ACC Registers
#define ID0 0x00
#define STATUS 0x0b
#define FIFO_EL 0x0c
#define FIFO_EH 0x0d
#define RESET 0x1f
#define FIFO_CTL 0x28
#define FIFO_SAM 0x29
#define INTMAP1 0x2a
#define INTMAP2 0x2b
#define FILTER_CTL 0x2c
#define POWER_CTL 0x2d

#define WR_SPI 0x0a
#define RD_SPI 0x0b
#define RD_FIFO 0x0d
#define DOWN 0
#define UP 1

#define SAMPLE_SET 128

// function definitions
void drSub();
uint8_t ACC_ReadReg( uint8_t reg );
void ACC_WriteReg( uint8_t reg, uint8_t reg );
uint32_t drFlag;
void ACC_GetXYZ12( int16_t *x, int16_t *y, int16_t *z);
void ACC_GetXYZ8( int8_t *x, int8_t *y, int8_t *z);
void ACC_GetFIFO(uint8_t *x, uint32_t samples);
int16_t convertFIFOdata(uint8_t h, uint8_t l);

// mbed hardware config
SPI spi(p11, p12, p13); // mosi, miso, sclk
DigitalOut cs(p14);
InterruptIn dr(p15);
Serial pc(USBTX, USBRX); // tx, rx


int main()
{
    // local variables
    uint8_t reg;

    int8_t x8 = 0;
    int8_t y8 = 0;
    int8_t z8 = 0;

    int16_t x12 = 0;
    int16_t y12 = 0;
    int16_t z12 = 0;

    //uint8_t fl;
    //uint8_t fh;
    //uint32_t fb;

    uint8_t xyz[1020];  // 6 bytes per 3x sample set
    for (uint32_t i = 0; i < 1020; i++) xyz[i] = 0;

     // mbed serial port config
    pc.baud(115200);

    // mbed spi config
    // spi 8 bits, mode 0, 1 MHz for adxl362
    spi.format(8,0);
    // 5 MHz, max for acc - works fine
    spi.frequency(5000000);

    // mbed interrupt config
    drFlag = 0;
    dr.mode(PullDown);
    dr.rise(&drSub);
    __disable_irq();

    // reset the adxl362
    wait_ms(100);
    ACC_WriteReg(RESET, 0x52);
    wait_ms(100);

    /*
    // read adxl362 registers
    printf("\r\n");
    // read id register
    reg = ACC_ReadReg(ID0);
    pc.printf("ID0 = 0x%X\r\n", reg);
    reg = ACC_ReadReg(FILTER_CTL);
    pc.printf("FILTER_CTL = 0x%X\r\n", reg);
    */

    // set FIFO
    ACC_WriteReg(FIFO_CTL,0x0A);  // stream mode, AH bit
    //ACC_WriteReg(FIFO_CTL,0x02);  // stream mode, no AH bit
    reg = ACC_ReadReg(FIFO_CTL);
    pc.printf("FIFO_CTL = 0x%X\r\n", reg);

    //ACC_WriteReg(FIFO_SAM,0xFF);   // fifo depth
    ACC_WriteReg(FIFO_SAM,SAMPLE_SET * 3);   // fifo depth
    reg = ACC_ReadReg(FIFO_SAM);
    pc.printf("FIFO_SAM = 0x%X\r\n", reg);

    // set adxl362 to 4g range, 25Hz
    //ACC_WriteReg(FILTER_CTL,0x51);
    // 2g, 25Hz
    ACC_WriteReg(FILTER_CTL,0x11);
    reg = ACC_ReadReg(FILTER_CTL);
    printf("FILTER_CTL = 0x%X\r\n", reg);

    // map adxl362 interrupts
    //ACC_WriteReg(INTMAP1,0x01); //data ready
    ACC_WriteReg(INTMAP1,0x04); //watermark
    reg = ACC_ReadReg(INTMAP1);
    pc.printf("INTMAP1 = 0x%X\r\n", reg);

    // set adxl362 to measurement mode, ultralow noise
    ACC_WriteReg(POWER_CTL,0x22);
    reg = ACC_ReadReg(POWER_CTL);
    pc.printf("POWER_CTL = 0x%X\r\n", reg);


    // start continuous processing adxl362 data
    __enable_irq();

    uint64_t j = 0;

    while(1) {

        if(drFlag == 1) {


            //fl = ACC_ReadReg(FIFO_EL);
            //fh = ACC_ReadReg(FIFO_EH);
            //fb =  (fh << 8) | fl;
            //pc.printf("\r\n%04X\r\n", fb);

            ACC_GetFIFO(&xyz[0],SAMPLE_SET);

            pc.printf("--%u------------------------------------------------------------\r\n", j);

            for (uint32_t i = 0; i < SAMPLE_SET * 6; i+=6) {

                // useful use for testing
                /*
                uint8_t xAddr = (xyz[i+1] & 0xC0) >> 6;
                uint8_t yAddr = (xyz[i+3] & 0xC0) >> 6;
                uint8_t zAddr = (xyz[i+5] & 0xC0) >> 6;
                pc.printf("%u %02x %02x %02x\r\n", j, xAddr, yAddr, zAddr);
                */

                int16_t x = convertFIFOdata(xyz[i+1], xyz[i]);
                int16_t y = convertFIFOdata(xyz[i+3], xyz[i+2]);
                int16_t z = convertFIFOdata(xyz[i+5], xyz[i+4]);

                pc.printf("%+05d %+05d %+05d\r\n",x,y,z);
                j++;
                drFlag = 0;
            }
        }

        if(drFlag == 8) {
            ACC_GetXYZ8(&x8, &y8, &z8);
            pc.printf("%+04d %+04d %+04d\r\n", x8,y8,z8);
            drFlag = 0;
        }

        else if(drFlag == 12) {
            ACC_GetXYZ12(&x12, &y12, &z12);
            pc.printf ("%+05d %+05d %+05d\r\n",x12, y12, z12);
            //pc.printf("%04X, %04X, %04X\r\n", x12, y12, z12);
            drFlag = 0;
        }

    }
}

////////////////////////////////////////////////////////////////////////////////////
// convert fifo sample to unsigned int
////////////////////////////////////////////////////////////////////////////////////
int16_t convertFIFOdata(uint8_t hiByte, uint8_t loByte)
{
    /*
    //mask off type bits
    uint16_t x = ((h & 0x3F) << 8);
    // combine low byte
    x = x | l;
    // get sign bits, copy into B15, B14, combine
    x = ((x & 0x3000) << 2) | x;
    int16_t y = x;
    return (y);
    */
    //mask off id bits, combine low byte
    int16_t x = ((hiByte & 0x3F) << 8) | loByte;
    // get sign bits, copy into B15, B14, combine
    x = ((x & 0x3000) << 2) | x;
    return(x);
}


////////////////////////////////////////////////////////////////////////////////////
// read FIFO
////////////////////////////////////////////////////////////////////////////////////

void ACC_GetFIFO(uint8_t *x, uint32_t samples)
{
    cs = DOWN;
    spi.write(RD_FIFO);
    for(int i = 0; i < samples * 6; i++) {
        *x = spi.write(0x00);
        x++;
    }

    cs = UP;
}

////////////////////////////////////////////////////////////////////////////////////
// read 8-bit x,y,z data
////////////////////////////////////////////////////////////////////////////////////

void ACC_GetXYZ8(int8_t* x, int8_t* y, int8_t* z)
{

    cs = DOWN;
    spi.write(RD_SPI);
    spi.write(0x08);

    *x = spi.write(0x00);
    *y = spi.write(0x00);
    *z = spi.write(0x00);

    cs = UP;
}

////////////////////////////////////////////////////////////////////////////////////
// read 12-bit x,y,z data
////////////////////////////////////////////////////////////////////////////////////

void ACC_GetXYZ12(int16_t* x, int16_t* y, int16_t* z)
{
    int16_t xyzVal[6] = {0, 0, 0, 0, 0, 0};

    cs = DOWN;
    spi.write(RD_SPI);
    spi.write(0x0E);

    for (uint32_t i = 0; i < 6; i++) {
        xyzVal[i] = spi.write(0x00);
    }

    *x = (xyzVal[1] << 8) + xyzVal[0];
    *y = (xyzVal[3] << 8) + xyzVal[2];
    *z = (xyzVal[5] << 8) + xyzVal[4];

    cs = UP;
}

////////////////////////////////////////////////////////////////////////////////////
// read ACC 8-bit registers
////////////////////////////////////////////////////////////////////////////////////

uint8_t ACC_ReadReg( uint8_t reg )
{
    cs = DOWN;
    spi.write(RD_SPI);
    spi.write(reg);
    uint8_t val = spi.write(0x00);
    cs = UP;
    return (val);
}

////////////////////////////////////////////////////////////////////////////////////
// write ACC 8-bit register
////////////////////////////////////////////////////////////////////////////////////

void ACC_WriteReg( uint8_t reg, uint8_t cmd )
{
    cs = DOWN;
    spi.write(WR_SPI);
    spi.write(reg);
    spi.write(cmd);
    cs = UP;
}

////////////////////////////////////////////////////////////////////////////////////
// Handle data ready interrupt
// just sets data ready flag
////////////////////////////////////////////////////////////////////////////////////

void drSub()
{
    drFlag = 1;
    //drFlag = 8;
    //drFlag = 12;
}