Giles Barton-Owen / Mbed 2 deprecated SDCardACEL

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "SDFileSystem.h"
00003 
00004 SDFileSystem sd(p5, p6, p7, p8, "sd");
00005 
00006 //WWWWROTE is an interrupt driven AD345 logger - 16/3/2010 Tim Owen
00007 //This works OK for up to 1Mbyte files to flash -
00008 // misses at 1600, ? at 800s/s probably OK at 400s/s  ?????
00009 //This version writes on a read by read basis, no buffering internally
00010 //It stores in MBED flash, records by interrupt- it logs write times
00011 // usually its just OK at 1600 ss but the occasional write is too long.
00012 // needs a more reliable data store!!!!!!!!
00013 //class definitions etc
00014 //defines
00015 #define MAXFILESIZE 60               // secs
00016 #define BUFSIZE     16                   // size of 2 ram flipflop buffers
00017 #define CHANS       3                   // number of stored data values
00018 #define READSIZE   16                   // reads 16 x 3 int data values
00019 #define SS3200     0x0F                 // AD345 at 3200 s/s &c
00020 #define SS1600     0x0E
00021 #define SS800      0x0D
00022 #define SS400      0x0C
00023 #define SS200      0x0B
00024 #define SPFIFO     0x51                 // 17 samples - interrupt is dodgy if its 16 ???? curious
00025 #define SPRATE     SS400                 // see above  
00026 #define SPINTE     0x02                 //watermark
00027 #define SPINTM     0x00                 // true low
00028 #define SPDATA     0x2B                 // 16g
00029 #define SPPWRR     0x08                 // pwr ready   - run
00030 #define SPPWRS     0x00                 // pwr Standby - stop
00031 
00032 Serial pc(USBTX, USBRX);                // tx, rx
00033 DigitalOut led(LED1);                 // useful indicator of progress
00034 SPI spi(p11, p12, p13);                 // mosi, miso, sclk
00035 DigitalOut cs(p22);                     //SPI chip select true lo
00036 InterruptIn watermark(p21);             // goes lo when fifo has >21 values
00037 FILE *fp;
00038 Timer t;                               // output write file - bin
00039 
00040 
00041 //function prototypes
00042 int secondise(int in);
00043 int AD345_init(int rate);               // sets up accelerometer, rate = 100 x2 ...3200 s/s
00044 int AD345_check(void);                  // checks values in essential registers
00045 int AD345_standby(void);                // sets to standby mode to save power
00046 void AD345_watermark_service(void);     //services Watermark interrupt
00047 int show_bin_file(char* filename);      //reads binary file to screen
00048 int write_file(void*, int );
00049 int secs =0, mins = 0;
00050 // global variables
00051 int buf[BUFSIZE*CHANS];
00052 int buf_write_count;                       // number of ints in buffer to write.
00053 int buf_index=0;     // buf index points to next free space.
00054 int buf_file=0, elapse =0;           // is a file open?
00055 int rate,data_size=0,service_count=0;               //
00056 int file_size =0,write_count=0;                     // running total of writes
00057 int times[400],tindex=0,dumps[400];
00058 int bytes_written=0;
00059 int SampsCollected = 0;
00060 int samptime = 0;int samptimeS = 0;
00061 //buffer - there are 2 buffers of BUFSIZE ints each, buf_insw sets which buffer to use for input
00062 // and buf_outsw sets buffer to read.  buf_in_indx and ..._out_indx are buf pointers
00063 
00064 int secondise(int in)
00065 {
00066    float S = in/1000;
00067    int real = 0;
00068    while(real < S - 1)
00069    {
00070     real = real + 1;
00071    }
00072     return real;
00073 }
00074 
00075 int AD345_init(int rate) {
00076     //rate not used yet
00077     // Setup the spi for
00078     // 8 bit data, high steady state clock,
00079     // second edge capture, with a 1000KHz clock rate
00080     //watermark trigger via INT1 pin going lo on 21 datavalues
00081     spi.format(8,3);
00082     spi.frequency(1000000);
00083     cs = 0;
00084     pc.printf(".");  // this doesn't work - only when its copied below
00085     spi.write(0x38); // write FIFO
00086     spi.write(SPFIFO); // (mode FIFO-watermark )
00087     cs = 1;
00088     pc.printf(".");
00089     cs = 0;
00090     spi.write(0x2C); // write RATE
00091     spi.write(SPRATE); // (? Hz)
00092     cs = 1;
00093     pc.printf(".");
00094     cs = 0;
00095     spi.write(0x2E); // write INT_ENABLE
00096     spi.write(SPINTE); // (watermark)
00097     cs = 1;
00098     pc.printf(".");
00099     cs = 0;
00100     spi.write(0x2F); // write INT_MAP
00101     spi.write(SPINTM); // (to INT1
00102     cs = 1;
00103     pc.printf(".");
00104     cs =  0;
00105     spi.write(0x31); // write DATA
00106     spi.write(SPDATA); // (16g)
00107     cs = 1;
00108     cs = 0;
00109     pc.printf(".");
00110     spi.write(0x38); // write FIFO
00111     spi.write(SPFIFO); // (mode FIFO-watermark)
00112     cs = 1;
00113     pc.printf(".");
00114     cs = 0;
00115     spi.write(0x2D); // write PWRCTL
00116     spi.write(SPPWRR); // (ON)
00117     cs = 1;
00118     return(1);
00119 }
00120 
00121 int AD345_standby(void) {// sets AD345 into standby mode at the end of the run;
00122     int pwrc;
00123 
00124     pc.printf(".");
00125     cs = 0;
00126     spi.write(0x2D); // write PWRCTL
00127     spi.write(0x00); // (Standby)
00128     cs = 1;
00129     pc.printf(".");
00130     cs = 0;
00131     spi.write(0x2D); // write PWRCTL
00132     spi.write(0x00); // (Standby)
00133     cs = 1;
00134     cs = 0;
00135     spi.write(0xAD); // read PWRCTL
00136     pwrc = spi.write(0x00); // (?)
00137     cs = 1;
00138     return(pwrc&0x08);  // 0 if its in standby
00139 }
00140 
00141 int AD345_check(void) {//check them &prints out register values if wrong
00142     char dump,pwrc,fifo,intc,intm,data,rate, loops,error=0;
00143     loops = 3;
00144     while (loops--) {
00145         cs = 0;
00146         dump = spi.write(0xAD); // read PWRCTL
00147         pwrc = spi.write(0x00); // (ON)
00148         cs = 1;
00149         pc.printf(".");
00150         cs = 0;
00151         dump = spi.write(0xB8); // read FIFOCTL
00152         fifo = spi.write(0x00); // (FIFO)
00153         cs = 1;
00154         pc.printf(".");
00155         cs = 0;
00156         dump = spi.write(0xAE); // read INT_EN
00157         intc = spi.write(0x00); //
00158         cs = 1;
00159         pc.printf(".");
00160         cs = 0;
00161         dump = spi.write(0xAF); // read INT_MAP
00162         intm = spi.write(0x00); // (INTM)
00163         cs = 1;
00164         pc.printf(".");
00165         cs = 0;
00166         dump = spi.write(0xB1); // read data
00167         data = spi.write(0x00); // (DATA)
00168         cs = 1;
00169         pc.printf(".");
00170         cs = 0;
00171         dump = spi.write(0xAC); // read RATE
00172         rate = spi.write(0x00); // (400 Hz)
00173         cs = 1;
00174 
00175         if ( fifo != SPFIFO) {
00176             pc.printf("\n\rError FIFO %c = 0x%02X\n\r",SPFIFO,fifo);
00177             error++;
00178         }
00179         if ( intc != SPINTE) {
00180             pc.printf("Error INTC %c = 0x%02X\n\r",SPINTE,intc);
00181             error++;
00182         }
00183         if ( intm != SPINTM) {
00184             pc.printf("Error INTM %c = 0x%02X\n\r",SPINTM,intm);
00185             error++;
00186         }
00187         if ( rate != SPRATE) {
00188             pc.printf("Error RATE %c = 0x%02X\n\r",SPRATE,rate);
00189             error++;
00190         }
00191         if ( data != SPDATA) {
00192             pc.printf("Error DATA %c = 0x%02X\n\r",SPDATA,data);
00193             error++;
00194         }
00195         if ( pwrc != SPPWRR) {
00196             pc.printf("Error POWC %c = 0x%02X\n\r",SPPWRR,pwrc);
00197             error++;
00198         }
00199         if (error == 0) {
00200             pc.printf("AD345 Setup complete\n\r");
00201             return(1);
00202         }
00203     }
00204     return(0);
00205 }
00206 
00207 void AD345_watermark_service(void) {
00208     
00209     service_count++;
00210     samptime = t.read_ms();
00211     samptimeS = t.read();
00212     pc.printf("\nTrig T : %i Tms : %i", samptimeS, samptime);
00213     int datxlo,datxhi,datylo,datyhi,datzlo,datzhi;     //temp variables
00214     int datx,daty,datz,ind;                                //temp variables
00215     // check there is enough room in the current buffer before writing to it
00216     data_size = 0;
00217     buf_index =0;
00218     for (ind=0; ind < 16; ind ++) {
00219         cs = 0;
00220         spi.write(0xF2);
00221         datxlo = spi.write(0x80);
00222         datxhi = spi.write(0x80);
00223         datylo = spi.write(0x80);
00224         datyhi = spi.write(0x80);
00225         datzlo = spi.write(0x80);
00226         datzhi = spi.write(0x80);
00227         cs = 1;
00228 
00229 
00230         datx = datxlo + datxhi*256;
00231         if (datx > 32000) datx = -65536+datx;
00232         buf[buf_index++] = datx;
00233         daty = datylo + datyhi*256;
00234         if (daty > 32000) daty = -65536+daty;
00235         buf[buf_index++] = daty;
00236         datz = datzlo + datzhi*256;
00237         if (datz > 32000) datz = -65536+datz;
00238         buf[buf_index++]=datz;
00239         data_size += 3;
00240 
00241     } // get 16 values
00242     // putchar(':');
00243     if (service_count > 30000000) { // emergency get out of jail card
00244         pc.printf("\n\r gone on too long");
00245         fclose(fp);
00246         for (tindex=0;tindex < 200;tindex++)
00247             //printf("wt=%d - %d //",times[tindex],dumps[tindex]);
00248             watermark.fall(NULL);
00249         exit(0);
00250     }
00251     SampsCollected = SampsCollected + 5;
00252     //pc.printf("\n\r SAMPS = %i" , SampsCollected);
00253     write_file(buf,data_size);   //assumes 32 bit ints
00254     return;
00255 }
00256 
00257 int AD345_data_ready(void) {// this isn't used - its just the non-interrupt version for tests.
00258     int  pending = 1;
00259     int elapse,intc,over_run;
00260     led =1;
00261     while (pending) {
00262         elapse = t.read_us();
00263         pending++;
00264         cs =0;
00265         spi.write(0xB0); // read INT_SOURCE
00266         intc = spi.write(0x00); // (INT_SOURCE)
00267         cs =1;
00268         if (intc&0x01) over_run++;
00269         if (intc&0x02) pending = 0;// watermark
00270         while (t.read_us() < elapse + 5);
00271     }
00272     led=0;
00273     return(1);
00274 }
00275 
00276 int open_file(int junk) {
00277     led = 1;
00278     fp = fopen("/sd/sdtest.csv", "w");
00279 
00280     if (!fp) {
00281         fprintf(stderr, "/sd/sdtest.txt could not be opened!\n");
00282         exit(0);
00283     } else {
00284         buf_file = 1;
00285         pc.printf("\n\r/sd/sdtest.txt");
00286     }
00287     //fprintf(fp, "Hello fun SD Card World!");
00288     return(buf_file);
00289 }
00290 
00291 int write_file(void *ptr, int size) { // writes file, keeps check of write times and size etc.
00292 
00293     pc.printf("\n\rWrite Called");
00294     if (buf_file == 0) open_file(1);
00295     led=1;
00296     int secondChangeFlag = 100;
00297     
00298     if(samptime - (samptimeS * 1000) <  40)
00299     {
00300     
00301     pc.printf("TFlag %i" , samptime - (samptimeS * 1000));
00302         int i = 50;
00303         while(samptime - (samptimeS * 1000) <  i*2.5 && i>0)
00304         {
00305             secondChangeFlag = i;
00306             i = i-1;
00307             
00308         }
00309         pc.printf(": %i    ", secondChangeFlag);
00310     }
00311    
00312     elapse = t.read_ms();
00313     int timeS = t.read();
00314     int timeStamp = SampsCollected;
00315     
00316     for (int i = 0; i < BUFSIZE/3; i += 1) {
00317     
00318     
00319         pc.printf("%i,",i);
00320         
00321         if(i == secondChangeFlag)
00322         {
00323             timeStamp = timeS;
00324             SampsCollected = 5-i;
00325         }
00326         else
00327         {
00328             timeStamp = SampsCollected + i - 5;
00329         }
00330         file_size += fprintf(fp, "%i,%i,%i,%i\n", timeStamp, buf[i*3],buf[(i*3)+1],buf[(i*3)+2]);
00331     }
00332     if (tindex < 399) {
00333         times[tindex] = t.read_ms()- elapse;
00334         dumps[tindex++] = size;
00335     }
00336     write_count++;
00337     // if(write_count%25 == 0) pc.printf("-%d",write_count);
00338     //pc.printf(".");
00339     bytes_written += (size*4);
00340     pc.printf("done at %i, %i", t.read_ms(), samptime - (samptimeS * 1000));
00341     return(1);
00342 }
00343 
00344 
00345 int  main() {
00346     int num,max=0,tot=0,val=0,vcnt=0,av=0;
00347     pc.baud(115200);
00348     pc.printf("\n\rWROTE AD345 software - 17/3/2010 Tim Owen");
00349     AD345_init(rate);
00350     AD345_check();
00351     t.start();                              // clock starts here 
00352     AD345_watermark_service();            // empty  buffer
00353     AD345_watermark_service();             //empty buffer
00354     data_size = 0;
00355     // place interrupt for watermark flow control
00356     watermark.fall(&AD345_watermark_service);
00357     
00358     while (t.read() < MAXFILESIZE) { // sit here in limbo
00359         led = 1;        // need something to do to fight boredom
00360         wait(0.5);
00361         led = 0;
00362         wait(0.5);
00363     }
00364     pc.printf("\n\r Ending normally now");
00365     watermark.fall(NULL);
00366     for (num=0; num < 400;num++) {
00367         //// printf("wt=%d - %d //",times[num],dumps[num]);
00368         if (times[num] != 0) {
00369             tot += times[num];
00370             vcnt++;
00371         }
00372         av = tot/vcnt;
00373         if (times[num] > max) max = times[num];
00374         if (times[num] > 30) { // appropriate value for 800 s/s ?
00375             val++;
00376             printf("<%d -%d>",num,times[num]);
00377         }
00378     }
00379 
00380     fclose(fp);
00381     pc.printf("\n\rAD345 calls %d, write av ms = %d, max ms = %d, >15ms = %d", service_count,av,max,val);
00382     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()) );
00383     led =0;
00384     t.stop();
00385     AD345_standby();
00386     pc.printf("\n\rAD345 in standby mode..");
00387     watermark.fall(NULL);
00388     pc.printf("\n\rAll done and dusted........");
00389     return(0);
00390 }