acc_dev

Dependencies:   mbed

main.cpp

Committer:
p07gbar
Date:
2010-04-13
Revision:
0:3033fd7e75a4

File content as of revision 0:3033fd7e75a4:

#include "mbed.h"
#include "SDFileSystem.h"

SDFileSystem sd(p5, p6, p7, p8, "sd");

//WWWWROTE is an interrupt driven AD345 logger - 16/3/2010 Tim Owen
//This works OK for up to 1Mbyte files to flash -
// misses at 1600, ? at 800s/s probably OK at 400s/s  ?????
//This version writes on a read by read basis, no buffering internally
//It stores in MBED flash, records by interrupt- it logs write times
// usually its just OK at 1600 ss but the occasional write is too long.
// needs a more reliable data store!!!!!!!!
//class definitions etc
//defines
#define MAXFILESIZE 60               // secs
#define BUFSIZE     16                   // size of 2 ram flipflop buffers
#define CHANS       3                   // number of stored data values
#define READSIZE   16                   // reads 16 x 3 int data values
#define SS3200     0x0F                 // AD345 at 3200 s/s &c
#define SS1600     0x0E
#define SS800      0x0D
#define SS400      0x0C
#define SS200      0x0B
#define SPFIFO     0x51                 // 17 samples - interrupt is dodgy if its 16 ???? curious
#define SPRATE     SS400                 // see above  
#define SPINTE     0x02                 //watermark
#define SPINTM     0x00                 // true low
#define SPDATA     0x2B                 // 16g
#define SPPWRR     0x08                 // pwr ready   - run
#define SPPWRS     0x00                 // pwr Standby - stop

Serial pc(USBTX, USBRX);                // tx, rx
DigitalOut led(LED1);                 // useful indicator of progress
SPI spi(p11, p12, p13);                 // mosi, miso, sclk
DigitalOut cs(p22);                     //SPI chip select true lo
InterruptIn watermark(p21);             // goes lo when fifo has >21 values
FILE *fp;
Timer t;                               // output write file - bin


//function prototypes
int secondise(int in);
int AD345_init(int rate);               // sets up accelerometer, rate = 100 x2 ...3200 s/s
int AD345_check(void);                  // checks values in essential registers
int AD345_standby(void);                // sets to standby mode to save power
void AD345_watermark_service(void);     //services Watermark interrupt
int show_bin_file(char* filename);      //reads binary file to screen
int write_file(void*, int );
int secs =0, mins = 0;
// global variables
int buf[BUFSIZE*CHANS];
int buf_write_count;                       // number of ints in buffer to write.
int buf_index=0;     // buf index points to next free space.
int buf_file=0, elapse =0;           // is a file open?
int rate,data_size=0,service_count=0;               //
int file_size =0,write_count=0;                     // running total of writes
int times[400],tindex=0,dumps[400];
int bytes_written=0;
int SampsCollected = 0;
int samptime = 0;int samptimeS = 0;
//buffer - there are 2 buffers of BUFSIZE ints each, buf_insw sets which buffer to use for input
// and buf_outsw sets buffer to read.  buf_in_indx and ..._out_indx are buf pointers

int secondise(int in)
{
   float S = in/1000;
   int real = 0;
   while(real < S - 1)
   {
    real = real + 1;
   }
    return real;
}

int AD345_init(int rate) {
    //rate not used yet
    // Setup the spi for
    // 8 bit data, high steady state clock,
    // second edge capture, with a 1000KHz clock rate
    //watermark trigger via INT1 pin going lo on 21 datavalues
    spi.format(8,3);
    spi.frequency(1000000);
    cs = 0;
    pc.printf(".");  // this doesn't work - only when its copied below
    spi.write(0x38); // write FIFO
    spi.write(SPFIFO); // (mode FIFO-watermark )
    cs = 1;
    pc.printf(".");
    cs = 0;
    spi.write(0x2C); // write RATE
    spi.write(SPRATE); // (? Hz)
    cs = 1;
    pc.printf(".");
    cs = 0;
    spi.write(0x2E); // write INT_ENABLE
    spi.write(SPINTE); // (watermark)
    cs = 1;
    pc.printf(".");
    cs = 0;
    spi.write(0x2F); // write INT_MAP
    spi.write(SPINTM); // (to INT1
    cs = 1;
    pc.printf(".");
    cs =  0;
    spi.write(0x31); // write DATA
    spi.write(SPDATA); // (16g)
    cs = 1;
    cs = 0;
    pc.printf(".");
    spi.write(0x38); // write FIFO
    spi.write(SPFIFO); // (mode FIFO-watermark)
    cs = 1;
    pc.printf(".");
    cs = 0;
    spi.write(0x2D); // write PWRCTL
    spi.write(SPPWRR); // (ON)
    cs = 1;
    return(1);
}

int AD345_standby(void) {// sets AD345 into standby mode at the end of the run;
    int pwrc;

    pc.printf(".");
    cs = 0;
    spi.write(0x2D); // write PWRCTL
    spi.write(0x00); // (Standby)
    cs = 1;
    pc.printf(".");
    cs = 0;
    spi.write(0x2D); // write PWRCTL
    spi.write(0x00); // (Standby)
    cs = 1;
    cs = 0;
    spi.write(0xAD); // read PWRCTL
    pwrc = spi.write(0x00); // (?)
    cs = 1;
    return(pwrc&0x08);  // 0 if its in standby
}

int AD345_check(void) {//check them &prints out register values if wrong
    char dump,pwrc,fifo,intc,intm,data,rate, loops,error=0;
    loops = 3;
    while (loops--) {
        cs = 0;
        dump = spi.write(0xAD); // read PWRCTL
        pwrc = spi.write(0x00); // (ON)
        cs = 1;
        pc.printf(".");
        cs = 0;
        dump = spi.write(0xB8); // read FIFOCTL
        fifo = spi.write(0x00); // (FIFO)
        cs = 1;
        pc.printf(".");
        cs = 0;
        dump = spi.write(0xAE); // read INT_EN
        intc = spi.write(0x00); //
        cs = 1;
        pc.printf(".");
        cs = 0;
        dump = spi.write(0xAF); // read INT_MAP
        intm = spi.write(0x00); // (INTM)
        cs = 1;
        pc.printf(".");
        cs = 0;
        dump = spi.write(0xB1); // read data
        data = spi.write(0x00); // (DATA)
        cs = 1;
        pc.printf(".");
        cs = 0;
        dump = spi.write(0xAC); // read RATE
        rate = spi.write(0x00); // (400 Hz)
        cs = 1;

        if ( fifo != SPFIFO) {
            pc.printf("\n\rError FIFO %c = 0x%02X\n\r",SPFIFO,fifo);
            error++;
        }
        if ( intc != SPINTE) {
            pc.printf("Error INTC %c = 0x%02X\n\r",SPINTE,intc);
            error++;
        }
        if ( intm != SPINTM) {
            pc.printf("Error INTM %c = 0x%02X\n\r",SPINTM,intm);
            error++;
        }
        if ( rate != SPRATE) {
            pc.printf("Error RATE %c = 0x%02X\n\r",SPRATE,rate);
            error++;
        }
        if ( data != SPDATA) {
            pc.printf("Error DATA %c = 0x%02X\n\r",SPDATA,data);
            error++;
        }
        if ( pwrc != SPPWRR) {
            pc.printf("Error POWC %c = 0x%02X\n\r",SPPWRR,pwrc);
            error++;
        }
        if (error == 0) {
            pc.printf("AD345 Setup complete\n\r");
            return(1);
        }
    }
    return(0);
}

void AD345_watermark_service(void) {
    
    service_count++;
    samptime = t.read_ms();
    samptimeS = t.read();
    pc.printf("\nTrig T : %i Tms : %i", samptimeS, samptime);
    int datxlo,datxhi,datylo,datyhi,datzlo,datzhi;     //temp variables
    int datx,daty,datz,ind;                                //temp variables
    // check there is enough room in the current buffer before writing to it
    data_size = 0;
    buf_index =0;
    for (ind=0; ind < 16; ind ++) {
        cs = 0;
        spi.write(0xF2);
        datxlo = spi.write(0x80);
        datxhi = spi.write(0x80);
        datylo = spi.write(0x80);
        datyhi = spi.write(0x80);
        datzlo = spi.write(0x80);
        datzhi = spi.write(0x80);
        cs = 1;


        datx = datxlo + datxhi*256;
        if (datx > 32000) datx = -65536+datx;
        buf[buf_index++] = datx;
        daty = datylo + datyhi*256;
        if (daty > 32000) daty = -65536+daty;
        buf[buf_index++] = daty;
        datz = datzlo + datzhi*256;
        if (datz > 32000) datz = -65536+datz;
        buf[buf_index++]=datz;
        data_size += 3;

    } // get 16 values
    // putchar(':');
    if (service_count > 30000000) { // emergency get out of jail card
        pc.printf("\n\r gone on too long");
        fclose(fp);
        for (tindex=0;tindex < 200;tindex++)
            //printf("wt=%d - %d //",times[tindex],dumps[tindex]);
            watermark.fall(NULL);
        exit(0);
    }
    SampsCollected = SampsCollected + 5;
    //pc.printf("\n\r SAMPS = %i" , SampsCollected);
    write_file(buf,data_size);   //assumes 32 bit ints
    return;
}

int AD345_data_ready(void) {// this isn't used - its just the non-interrupt version for tests.
    int  pending = 1;
    int elapse,intc,over_run;
    led =1;
    while (pending) {
        elapse = t.read_us();
        pending++;
        cs =0;
        spi.write(0xB0); // read INT_SOURCE
        intc = spi.write(0x00); // (INT_SOURCE)
        cs =1;
        if (intc&0x01) over_run++;
        if (intc&0x02) pending = 0;// watermark
        while (t.read_us() < elapse + 5);
    }
    led=0;
    return(1);
}

int open_file(int junk) {
    led = 1;
    fp = fopen("/sd/sdtest.csv", "w");

    if (!fp) {
        fprintf(stderr, "/sd/sdtest.txt could not be opened!\n");
        exit(0);
    } else {
        buf_file = 1;
        pc.printf("\n\r/sd/sdtest.txt");
    }
    //fprintf(fp, "Hello fun SD Card World!");
    return(buf_file);
}

int write_file(void *ptr, int size) { // writes file, keeps check of write times and size etc.

    pc.printf("\n\rWrite Called");
    if (buf_file == 0) open_file(1);
    led=1;
    int secondChangeFlag = 100;
    
    if(samptime - (samptimeS * 1000) <  40)
    {
    
    pc.printf("TFlag %i" , samptime - (samptimeS * 1000));
        int i = 50;
        while(samptime - (samptimeS * 1000) <  i*2.5 && i>0)
        {
            secondChangeFlag = i;
            i = i-1;
            
        }
        pc.printf(": %i    ", secondChangeFlag);
    }
   
    elapse = t.read_ms();
    int timeS = t.read();
    int timeStamp = SampsCollected;
    
    for (int i = 0; i < BUFSIZE/3; i += 1) {
    
    
        pc.printf("%i,",i);
        
        if(i == secondChangeFlag)
        {
            timeStamp = timeS;
            SampsCollected = 5-i;
        }
        else
        {
            timeStamp = SampsCollected + i - 5;
        }
        file_size += fprintf(fp, "%i,%i,%i,%i\n", timeStamp, buf[i*3],buf[(i*3)+1],buf[(i*3)+2]);
    }
    if (tindex < 399) {
        times[tindex] = t.read_ms()- elapse;
        dumps[tindex++] = size;
    }
    write_count++;
    // if(write_count%25 == 0) pc.printf("-%d",write_count);
    //pc.printf(".");
    bytes_written += (size*4);
    pc.printf("done at %i, %i", t.read_ms(), samptime - (samptimeS * 1000));
    return(1);
}


int  main() {
    int num,max=0,tot=0,val=0,vcnt=0,av=0;
    pc.baud(115200);
    pc.printf("\n\rWROTE AD345 software - 17/3/2010 Tim Owen");
    AD345_init(rate);
    AD345_check();
    t.start();                              // clock starts here 
    AD345_watermark_service();            // empty  buffer
    AD345_watermark_service();             //empty buffer
    data_size = 0;
    // place interrupt for watermark flow control
    watermark.fall(&AD345_watermark_service);
    
    while (t.read() < MAXFILESIZE) { // sit here in limbo
        led = 1;        // need something to do to fight boredom
        wait(0.5);
        led = 0;
        wait(0.5);
    }
    pc.printf("\n\r Ending normally now");
    watermark.fall(NULL);
    for (num=0; num < 400;num++) {
        //// printf("wt=%d - %d //",times[num],dumps[num]);
        if (times[num] != 0) {
            tot += times[num];
            vcnt++;
        }
        av = tot/vcnt;
        if (times[num] > max) max = times[num];
        if (times[num] > 30) { // appropriate value for 800 s/s ?
            val++;
            printf("<%d -%d>",num,times[num]);
        }
    }

    fclose(fp);
    pc.printf("\n\rAD345 calls %d, write av ms = %d, max ms = %d, >15ms = %d", service_count,av,max,val);
    pc.printf("\n\rBytes in file %d, elapse time %f, s/s %f", bytes_written, t.read(), (float)bytes_written/(4.0*CHANS*t.read()) );
    led =0;
    t.stop();
    AD345_standby();
    pc.printf("\n\rAD345 in standby mode..");
    watermark.fall(NULL);
    pc.printf("\n\rAll done and dusted........");
    return(0);
}