Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Revision:
0:664899e0b988
Child:
1:e392595b4b76
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SnSDUtils.cpp	Sat Jun 30 02:03:51 2012 +0000
@@ -0,0 +1,148 @@
+#include "SnSDUtils.h"
+
+#include "mbed.h"
+#include "SDFileSystem.h"
+#include <string.h>
+
+#include "SnConfigFrame.h"
+#include "SnEventFrame.h"
+
+
+const char*   SnSDUtils::kSDsubDir  = "/sd";
+char          SnSDUtils::fgCurFileName[kFNBufSize];
+const uint8_t SnSDUtils::kIOvers    = 1;
+
+const char* SnSDUtils::GetOutFileName(const uint64_t macadr,
+                                      const uint32_t run,
+                                      const uint16_t seq) {
+    // returns the formatted file name, or NULL if the directory is too long
+    // and the full name cannot fit in the buffer
+    // NOTE: this fcn uses a static buffer, and so should not be called
+    // multiple times in the same line (that includes the calling of functions
+    // that call this function!)
+    //
+    // filename = SnEvtsM[6-byte hex mac adr]r[6-digit run num]s[5-digit seq num].dat
+    //  35 chars      7     +    12         +1+         5     +1+     5         + 4
+    
+    if (strlen(kSDsubDir)<(kFNBufSize-37)) {
+        static char tbuf[kFNBufSize];
+        memset(tbuf, 0, sizeof(char)*kFNBufSize);
+        // if file name format changes, GetSeqNum must be changed too
+        sprintf(tbuf, "%s/SnEvtsM%012llXr%05ds%05d.dat",
+            kSDsubDir,
+            macadr>>16, // 64 -> 48 bits
+            run, seq);
+        return tbuf;
+    } else {
+        return NULL;
+    }
+}
+
+uint16_t SnSDUtils::GetSeqNum(const uint64_t macadr,
+                              const uint32_t run) {
+    // count the files having expected filename format
+    
+    const char* fn = GetOutFileName(macadr, run, 0)
+        + strlen(kSDsubDir) + 1; // take out dir and '/'s
+    
+    DIR* d;
+    struct dirent* dent;
+    
+    uint16_t seq=0;
+    if ( (d = opendir( kSDsubDir ))!=NULL ) {
+        // don't compare seq#. don't use num of chars in case seq is >999
+        const uint32_t ncomp = strrchr(fn, 's') - fn;
+        while ( (dent = readdir(d))!=NULL ) {
+            if (strncmp(dent->d_name, fn, ncomp)==0) {
+                seq++;
+            }
+        }
+        closedir(d);
+    }
+    
+    return seq;
+}
+
+FILE* SnSDUtils::OpenExistingFile(const char* name) {
+    FILE* f = 0;
+    if (name!=NULL) {
+        f = fopen(name, "wb");
+    }
+    return f;
+}
+
+FILE* SnSDUtils::OpenNewOutputFile(const uint64_t macadr,
+                                   const uint32_t run) {
+    // opens a new file in the specified directory and writes this
+    // this mbed's mac address as the first sizeof(uint64_t) bytes (i.e. 4 bytes)
+    //
+    const uint16_t seq = GetSeqNum(macadr, run);
+    memset(fgCurFileName, 0, sizeof(char)*kFNBufSize);
+    strcpy(fgCurFileName,GetOutFileName(macadr, run, seq));
+    //fprintf(stderr,"cur file = %s (%hu)\n\r",fgCurFileName,seq);
+    FILE* f = 0;
+    if (fgCurFileName!=NULL) {
+        f = fopen(fgCurFileName, "wb");
+    }
+    return f;
+}
+
+bool SnSDUtils::WriteFileHeader(FILE* f, const uint64_t macadr) {
+    // MUST INCREMENT kIOvers if these writes are altered
+    fwrite(&kIOvers, sizeof(uint8_t), 1, f);
+    fwrite(&macadr, sizeof(uint64_t), 1, f);
+    return ferror(f);
+}
+
+bool SnSDUtils::WriteEventTo(FILE* efile, char* const evtBuf,
+                             const SnEventFrame& evt,
+                             const SnConfigFrame& conf) {
+    // write event to SD card
+        
+    uint8_t sLoseLSB=0, sLoseMSB=0;
+    uint16_t sWvBase=0;
+    conf.GetPackParsFor(SnConfigFrame::kSDcard, sLoseLSB, sLoseMSB, sWvBase);
+    const bool ret = evt.WriteTo(efile, evtBuf, sLoseLSB, sLoseMSB, sWvBase);
+    fflush(efile);
+    return ret;
+}
+
+bool SnSDUtils::WriteConfig(FILE* efile,
+                            const SnConfigFrame& conf) {
+    conf.WriteTo(efile);
+    return true;
+}
+
+void SnSDUtils::DeleteFile(FILE*& f, const char* fname) {
+    fclose(f);
+    f=0;
+    remove(fname);
+}
+
+SnCommWin::ECommWinResult SnSDUtils::SendAllFiles(SnCommWin* comm,
+                                                  const bool doDelete) {
+    
+    DIR* d;
+    struct dirent* dent;
+    
+    SnCommWin::ECommWinResult rs = SnCommWin::kUndefFail;
+    
+    if ( (d = opendir( kSDsubDir ))!=NULL ) {
+        FILE* f;
+        while ( (dent = readdir(d))!=NULL ) {
+            if (strncmp(dent->d_name, "SnEvts", 6)==0) {
+                f = SnSDUtils::OpenExistingFile(dent->d_name);
+                rs = comm->SendData(f);
+                if (rs<SnCommWin::kAllFails) {
+                    break;
+                } else if (doDelete) {
+                    DeleteFile(f, dent->d_name);
+                }
+            }
+        }
+        closedir(d);
+    }
+    
+    return rs;
+}
+