Giles Barton-Owen
/
SDCardACEL
acc_dev
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); }