Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Revision:
8:95a325df1f6b
Parent:
6:6f002d202f59
Child:
10:3c93db1cfb12
--- a/SnCommWin.cpp	Sat Aug 04 01:48:55 2012 +0000
+++ b/SnCommWin.cpp	Wed Aug 08 23:27:37 2012 +0000
@@ -2,10 +2,14 @@
 
 #include "SnHeaderFrame.h"
 #include "SnConfigFrame.h"
+#include "SnEventFrame.h"
+#include "SnPowerFrame.h"
+#include "SnStatusFrame.h"
 #include "SnSDUtils.h"
 
 SnCommWin::ECommWinResult SnCommWin::SendData(SnConfigFrame& conf,
                                               SnEventFrame& evt,
+                                              SnPowerFrame& pow,
                                               char* const genBuf,
                                               const uint32_t bsize,
                                               const uint32_t timeout) {
@@ -15,7 +19,7 @@
     if (conf.IsSendingAllFiles()) {
         printf("sending all files\r\n");
         res = SnSDUtils::SendAllFiles(this, conf.IsDeletingFiles(), to, 
-                                      genBuf, bsize, conf, evt);
+                                      genBuf, bsize, conf, evt, pow);
     } else {
         if (conf.GetCommSendData()==0) {
             printf("no data to send\r\n");
@@ -25,7 +29,7 @@
                                   conf.GetCommSendData() // send N events
                                   : 0u; // send all events in last file
             res = SendData(SnSDUtils::GetCurFile(), SnSDUtils::GetCurFileName(),
-                           conf, evt, genBuf, bsize, nev, to);
+                           conf, evt, pow, genBuf, bsize, nev, to);
             printf("after send data cur file, res=%d\r\n",(int)res);
         }
     }
@@ -35,6 +39,7 @@
 SnCommWin::ECommWinResult SnCommWin::SendData(FILE* inf, const char* infn,
                                               const SnConfigFrame& curConf,
                                               SnEventFrame& evt,
+                                              SnPowerFrame& pow,
                                               char* const genBuf,
                                               const uint32_t bsize,
                                               const uint32_t nevts,
@@ -50,7 +55,7 @@
         if (res>kAllFails) {
             if (genBuf!=0) {
                 // send the contents
-                res = SendFileContents(inf, curConf, evt, genBuf,
+                res = SendFileContents(inf, curConf, evt, pow, genBuf,
                                        nevts, timeout_clock, firstEvt);
                 if (res>SnCommWin::kAllFails) {
                     // wait for handshake
@@ -70,3 +75,287 @@
     }
     return res;
 }
+
+SnCommWin::ECommWinResult SnCommWin::WaitHandshake(const uint32_t timeout,
+                                                   char* const buf,
+                                                   const uint32_t bsize,
+                                                   uint8_t& hndShkCode) {
+    printf("WaitHandshake, to=%u\r\n",timeout);
+    
+    const int mlen = ReceiveAll(buf, SnHeaderFrame::SizeOf(), timeout);
+    if (mlen>0 && static_cast<uint32_t>(mlen) == SnHeaderFrame::SizeOf()) {
+        uint32_t msgLen=0;
+        const char* b = buf;
+        SnHeaderFrame::ReadFrom(b, hndShkCode, msgLen);
+        if ((hndShkCode & SnHeaderFrame::kHndShkBits)!=0) {
+            return SnCommWin::kOkWithMsg;
+        } else {
+            // TODO: somehow handle unexpected message?
+            return SnCommWin::kUnexpectedRec;
+        }
+    }
+    return SnCommWin::kOkNoMsg;
+}
+
+SnCommWin::ECommWinResult SnCommWin::GetConfig(SnConfigFrame& conf,
+                                               const uint32_t timeOut,
+                                               char* const confBuf,
+                                               const uint32_t bsize) {
+    // confBuf assumed to alread be of allocated size
+    
+    printf("GetConfig, to=%u\r\n",timeOut);
+    
+    SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
+    if (bsize<SnHeaderFrame::kMaxSizeOf || bsize<SnConfigFrame::kMaxSizeOf) {
+        res = SnCommWin::kUndefFail;
+    } else {
+        // get header
+        const int hlen = ReceiveAll(confBuf, SnHeaderFrame::SizeOf(), timeOut);
+        if (hlen>0 && static_cast<uint32_t>(hlen)==SnHeaderFrame::SizeOf()) {
+            uint8_t mcode=0; uint32_t mlen=0;
+            const char* b = confBuf;
+            SnHeaderFrame::ReadFrom(b, mcode, mlen);
+            printf("mcode=%02x, mlen=%u\r\n", mcode, mlen);
+            if (mcode!=SnHeaderFrame::kConfigCode) {
+                res = SnCommWin::kUnexpectedRec;
+            } else {
+                // get config
+                const int clen = ReceiveAll(confBuf, mlen, timeOut);
+                if (clen>0 && static_cast<uint32_t>(clen)==mlen) {
+                    b = confBuf;
+                    conf.ReadFrom(b);
+                    res = SnCommWin::kOkWithMsg;
+                } else {
+                    res = SnCommWin::kUnexpectedRec;
+                }
+            }
+        } else {
+            res = SnCommWin::kUnexpectedRec;
+        }
+    }
+    return res;
+}
+
+SnCommWin::ECommWinResult SnCommWin::SendStatus(const SnConfigFrame& conf,
+                                                const SnEventFrame& evt,
+                                                const SnPowerFrame& pow,
+                                                char* const genBuf,
+                                                const uint32_t timeout_clock) {
+    // TODO: check if connected?
+    const uint32_t ssize = SnStatusFrame::SizeOf(SnStatusFrame::kIOVers, conf);
+    char* b = genBuf;
+    SnHeaderFrame::WriteTo(b, SnHeaderFrame::kStatusCode, ssize);
+    SnStatusFrame::WriteTo(b, GetCommType(), conf, evt, genBuf);
+#ifdef DEBUG
+    printf("status frame:\r\n");
+    for (uint32_t i=0; i<msize; i++) {
+        printf("%02X ",genBuf[i]);
+    }
+    printf("\r\n");
+#endif
+    int msiz = b-genBuf;
+    int mlen = SendAll(genBuf, msiz, timeout_clock);
+    if (mlen==msiz) {
+        printf("status sent\r\n");
+        b = genBuf;
+        SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode, 
+            pow.SizeOf(SnPowerFrame::kIOvers));
+        //SnPowerFrame::WriteTo(b, pow.GetAveV1(), pow.GetAveV2(), pow.GetTime());
+        pow.WriteTo(b);
+        msiz = b-genBuf;
+        mlen = SendAll(genBuf, msiz, timeout_clock);
+        if (mlen==msiz) {
+            return SnCommWin::kOkMsgSent;
+        }
+    }
+    return SnCommWin::kFailPartSent;
+}
+
+SnCommWin::ECommWinResult SnCommWin::SendFilename(const char* fn,
+                                                  char* const genBuf,
+                                                  const uint32_t timeout_clock) {
+    printf("afar send filename %s\r\n",fn);
+    const size_t flen = strlen(fn);
+    char* b = genBuf;
+    SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFilenameCode, flen);
+    sprintf(b, "%s", fn);
+    const int msiz = SnHeaderFrame::SizeOf()+flen;
+    const int mlen = SendAll(genBuf, msiz, timeout_clock);
+    return (msiz==mlen) ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent;
+}
+
+SnCommWin::ECommWinResult SnCommWin::SendFileContents(FILE* inf,
+                                                    const SnConfigFrame& curConf,
+                                                    SnEventFrame& evt,
+                                                    SnPowerFrame& pow,
+                                                    char* const genBuf,
+                                                    uint32_t nevts,
+                                                    const uint32_t timeout_clock,
+                                                    const uint32_t firstEvt) {
+    printf("comm win send conf and events\r\n");
+    // firstEvt==0 ==> start at beginning
+    // nevts==0 ==> all events
+    
+    const int fpos = ftell(inf);
+    if (fpos>0) {
+        fseek(inf, 0, SEEK_SET);
+    }
+    
+    printf("fpos=%d\r\n",fpos);
+    
+    // get file header
+    uint64_t macadr;
+    uint32_t run;
+    uint16_t seq;
+    SnSDUtils::ReadFileHeader(inf, macadr, run, seq, &pow);
+    
+    // check block
+    uint8_t hcode;
+    uint32_t hlen;
+    SnSDUtils::ReadBlockHeader(inf, hcode, hlen);
+    if (hcode==SnHeaderFrame::kPowerCode) {
+        pow.ReadFrom(inf);
+    }
+    
+    // TODO: check memory for temporary config/event frames?
+    // get config
+    while ((hcode!=SnHeaderFrame::kConfigCode)
+            && (feof(inf)==0)
+            && (ferror(inf)==0) ) {
+        fseek(inf, hlen, SEEK_CUR); // skip this block
+        SnSDUtils::ReadBlockHeader(inf, hcode, hlen);
+    }
+    SnConfigFrame conf;
+    conf.ReadFrom(inf);
+    
+    // get event size
+    uint8_t sLoseLSB=0, sLoseMSB=0;
+    uint16_t sWvBase=0;
+    curConf.GetPackParsFor(GetCommType(), sLoseLSB, sLoseMSB, sWvBase);
+    
+    // size of event in file
+    const uint32_t esize = SnEventFrame::SizeOf(SnEventFrame::kIOVers,
+                                                conf.GetWvLoseLSB(),
+                                                conf.GetWvLoseMSB());
+    
+    printf("esize=%u\r\n",esize);
+    
+    // how many more bytes?
+    const int fcur = ftell(inf);
+    fseek(inf, 0, SEEK_END); // go to end
+    const int fend = ftell(inf);
+    fseek(inf, fcur, SEEK_SET); // go back
+    
+    bool ok = false;
+    char* b = genBuf;
+    // send the file header
+    SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileHeadrCode,
+                           SnSDUtils::SizeOfFileHeader(SnSDUtils::kIOvers));
+    SnSDUtils::WriteFileHeader(b, macadr, run, seq);
+    int msiz = b-genBuf;
+    int mlen = SendAll(genBuf, msiz, timeout_clock);
+    if (mlen==msiz) {
+        // send power header
+        b = genBuf;
+        SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode, 
+                               pow.SizeOf(SnPowerFrame::kIOvers));
+        pow.WriteTo(b);
+        msiz = b-genBuf;
+        mlen = SendAll(genBuf, msiz, timeout_clock);
+        if (mlen==msiz) {
+            // send the config
+            b = genBuf;
+            SnHeaderFrame::WriteTo(b, SnHeaderFrame::kConfigCode, 
+                                   conf.SizeOf(SnConfigFrame::kIOVers));
+            conf.WriteTo(b);
+            msiz = b-genBuf;
+            mlen = SendAll(genBuf, msiz, timeout_clock);
+            if (mlen==msiz) {
+                ok = true;
+            }
+        }
+    }
+        
+    printf("ok=%d, nevts=%u\r\n",(int)ok,nevts);
+    
+    if (ok) {
+        // size of event sent over afar
+        const uint32_t ssize = SnEventFrame::SizeOf(SnEventFrame::kIOVers,
+                                                    sLoseLSB, sLoseMSB);
+        
+        // loop over blocks. send event & power frames
+        // until EOF or nevets have been sent
+        uint32_t evtsSent=0, powsSent=0;
+        uint8_t hc; uint32_t hl;
+        while (ok && (feof(inf)==0) 
+                  && (ferror(inf)==0) ) {
+            SnSDUtils::ReadBlockHeader(inf, hc, hl);
+            if (hc==SnHeaderFrame::kEventCode) {
+                if ((ftell(inf)+ssize)<=fend) {
+                    evt.ReadFrom(inf, genBuf,
+                        conf.GetWvLoseLSB(), conf.GetWvLoseMSB(),
+                        conf.GetWvBaseline());
+                    if (evt.GetEvtNum()>=firstEvt) {
+                        ++evtsSent;
+                        printf("sending evt %u\r\n",evtsSent);
+                        // must be after evt.Read, since that uses the buffer
+                        b = genBuf;
+                        SnHeaderFrame::WriteTo(b, SnHeaderFrame::kEventCode, ssize);
+                        evt.WriteTo(b, sLoseLSB, sLoseMSB, sWvBase); // will repack if necessary
+                        msiz = b-genBuf; //SnHeaderFrame::SizeOf()+ssize;
+                        mlen = SendAll(genBuf, msiz, timeout_clock);
+                        ok &= mlen==msiz;
+                    }
+                } else {
+                    printf("event header, but not enough bytes in file\r\n");
+                    ok = false;
+                }
+            } else if (hc==SnHeaderFrame::kPowerCode) {
+                if ((ftell(inf)+SnPowerFrame::SizeOf(SnPowerFrame::kIOvers))<=fend) {
+                    ++powsSent;
+                    pow.ReadFrom(inf);
+                    printf("sending power frame %u, v1=%g, v2=%g, t=%u\r\n",
+                        powsSent, pow.GetAveV1(), pow.GetAveV2(), pow.GetTime());
+                    b = genBuf;
+                    SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode, 
+                        SnPowerFrame::SizeOf(SnPowerFrame::kIOvers));
+                    pow.WriteTo(b);
+                    msiz = b-genBuf;
+                    mlen = SendAll(genBuf, msiz, timeout_clock);
+                    ok &= mlen==msiz;
+                } else {
+                    printf("power header, but not enough bytes in file\r\n");
+                    ok = false;
+                }
+            } else {
+                printf("unhandled block. hc=%hhu, hl=%u\r\n",
+                    hc, hl);
+                if ((ftell(inf)+hl)<=fend) {
+                    fseek(inf, hl, SEEK_CUR); // skip this block
+                } else {
+                    printf("not enough bytes in file to skip block\r\n");
+                    ok = false;
+                }
+            }
+        }
+        // send number of events sent
+        b = genBuf;
+        SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNevtsCode, sizeof(uint32_t));
+        b = SnBitUtils::WriteTo(b, evtsSent);
+        msiz = b - genBuf;
+        mlen = SendAll(genBuf, msiz, timeout_clock);
+        ok &= msiz==mlen;
+        // send number of power readings sent
+        b = genBuf;
+        SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNpwrsCode, sizeof(uint32_t));
+        b = SnBitUtils::WriteTo(b, powsSent);
+        msiz = b -genBuf;
+        mlen = SendAll(genBuf, msiz, timeout_clock);
+        ok &= msiz==mlen;
+    }
+        
+    // put file position back
+    fseek(inf, fpos, SEEK_SET);
+    
+    return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent;
+}