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/SnEventFrame.cpp	Sat Jun 30 02:03:51 2012 +0000
@@ -0,0 +1,250 @@
+#include "SnEventFrame.h"
+
+#include "SnCRCUtils.h"
+
+void SnEventFrame::ReadFrom(const char* const buf,
+                            const uint8_t loseLSB, const uint8_t loseMSB,
+                            const uint16_t wvBaseline) {
+    // no check on the length of buf is done here
+    // that should be been done already
+    //
+    // must match ::WriteToBuf
+    
+    union Usub {
+        const char* s;
+        const uint8_t* u;
+    } b;
+    b.s = buf;
+    
+    int8_t Rv=0;
+    b.s           = SnBitUtils::ReadFrom(b.s, Rv); // i/o version
+    if (Rv>0) {
+        b.s       = SnBitUtils::ReadFrom(b.s, fMbedTime);
+        b.s       = SnBitUtils::ReadFrom(b.s, fEvtNum);
+        b.s       = SnBitUtils::ReadFrom(b.s, fDTms);
+        b.s       = SnBitUtils::ReadFrom(b.s, fTrgNum);
+        b.s       = SnBitUtils::ReadFrom(b.s, fTrgBits);
+        b.u       = UnpackWavef(b.u, fData, loseLSB, loseMSB, wvBaseline);
+        b.s       = SnBitUtils::ReadFrom(b.s, fCRC);
+    }
+    
+}
+
+void SnEventFrame::WriteTo(char* const buf,
+                           const uint8_t loseLSB, const uint8_t loseMSB,
+                           const uint16_t wvBaseline) const {
+    // no check on the length of the buf is done here
+    // that should be done already
+    //
+    // must match ReadFromBuf
+    
+    union {
+        char* s;
+        uint8_t* u;
+    } b;
+    b.s = buf;
+    
+    b.s           = SnBitUtils::WriteTo(b.s, kIOVers); // i/o version
+
+    b.s           = SnBitUtils::WriteTo(b.s, fMbedTime);
+    b.s           = SnBitUtils::WriteTo(b.s, fEvtNum);
+    b.s           = SnBitUtils::WriteTo(b.s, fDTms);
+    b.s           = SnBitUtils::WriteTo(b.s, fTrgNum);
+    b.s           = SnBitUtils::WriteTo(b.s, fTrgBits);
+    b.u           = PackWavef(b.u, fData, loseLSB, loseMSB, wvBaseline);
+    b.s           = SnBitUtils::WriteTo(b.s, fCRC);
+
+}
+
+void SnEventFrame::CalcCRC() {
+    // CRC made using union on a little endian (mbed) processor
+    fCRC = 0u;
+    const uint16_t* dev = fData;
+    for (int16_t i=0; i<kTotSamps; i++, dev++) {
+        fCRC = update_crc32_xfer_short(fCRC, *dev);
+    }
+}
+
+bool SnEventFrame::ReadFromFileToBuf(FILE* f,
+                                     char* const evtBuf,
+                                     const uint8_t loseLSB,
+                                     const uint8_t loseMSB) {
+    // file position expected to be at this event frame already
+    bool ret = false;
+    if (f!=0) {
+        if (fread(evtBuf, SizeOf(loseLSB, loseMSB), 1u, f)!=NULL) {
+            ret = true;
+        }
+    }
+    return ret;
+}
+
+bool SnEventFrame::ReadFrom(FILE* f,
+                            char* const evtBuf,
+                            const uint8_t loseLSB, const uint8_t loseMSB,
+                            const uint16_t wvBaseline) {
+    // file position expected to be at this event frame already
+    const bool ret = ReadFromFileToBuf(f, evtBuf, loseLSB, loseMSB);
+    if (ret) {
+        ReadFrom(evtBuf, loseLSB, loseMSB, wvBaseline);
+    }
+    return ret;
+}
+
+bool SnEventFrame::WriteTo(FILE* f, char* const evtBuf,
+                           const uint8_t loseLSB, const uint8_t loseMSB,
+                           const uint16_t wvBaseline) const {
+    // file pointer should be in correct location
+    
+    WriteTo(evtBuf, loseLSB, loseMSB, wvBaseline);
+    return WriteToFileFromBuf(f, evtBuf, loseLSB, loseMSB);
+}
+
+bool SnEventFrame::WriteToFileFromBuf(FILE* f, char* const evtBuf,
+                               const uint8_t loseLSB, const uint8_t loseMSB) {
+    // file pointer should be in correct location
+    
+    bool ret = false;
+    if (f!=0) {
+        fwrite(evtBuf, SizeOf(loseLSB, loseMSB), 1u, f);
+        ret = (ferror(f)==false);
+    }
+    return ret;
+
+}
+
+
+uint8_t* SnEventFrame::PackWavef(uint8_t* const buf, const uint16_t* const data,
+                                 const uint8_t loseLSB, const uint8_t loseMSB,
+                                 const uint16_t wvBaseline) {
+    // Compress the data. This is potentially LOSSY; it depends
+    // on the dynamic range and on the options.
+    // See SnConfigFrame::fWvLoseLSB and SnConfigFrame::fWvLoseMSB.
+    // If the number of least signficant bits to lose is not 0, the
+    // compression will be lossy (decreased resolution -- this is ok
+    // if the noise of the signal is much greater than the resolution).
+    // Losing the most significant bits will only be lossy if the
+    // signal-SnConfigFrame::fWvBaseline cannot fit in the reduced
+    // dynamic range (each MSB bit reducing the DR by a factor of 2).
+    //
+    // Note that the mbed uses little endian. Behavior should be the
+    // same on big endian, but this has not been tested.
+    //
+    // Use an unsigned buffer to prevent bits being changed during
+    // an implicit unsigned -> signed cast.
+    //
+    // buf = the byte array into which the data should be packed
+    // data = the data to pack
+    // loseLSB = number of least significant bits to throw away
+    // loseMSB = number of most significant bits to throw away
+    // wvBaseline = baseline to subtract to from ADC before packing
+    
+    const uint32_t blen = SizeOfPackedWavef(loseLSB, loseMSB);
+    const uint8_t packSmpBits = BITS_IN_SHORT-loseLSB-loseMSB;
+
+    // make sure this buffer space is all 0's to start
+    memset(buf, 0, blen*sizeof(uint8_t));
+    
+    const uint16_t clipHi = uint16_t(
+       uint16_t(uint16_t(0xFFFFu >> loseLSB) << (loseLSB+loseMSB))
+                >> loseMSB);
+    
+    uint8_t* b = buf;
+    const uint16_t* dev = data;
+    uint16_t dum;
+    int8_t sbit=0;
+    for (uint16_t i=0; i<kTotSamps; i++, dev++) {
+        // dump the bits we don't want
+        dum = (*dev) - wvBaseline;
+        if (dum<clipHi) {
+          dum >>= loseLSB;
+          dum <<= (loseLSB+loseMSB);
+        } else {
+          dum = clipHi << loseMSB;
+        }
+        if (sbit<=0) {
+            // lose MSB's put in previous short (or none if sbit==0)
+            dum   <<= -sbit;
+            *b     |= dum >> 8u;         // "first" byte of the short
+            dum   <<= 8u;
+            *(b+1) |= dum >> 8u;   // "second"
+            // move to next number (dev++ in the for loop)
+            // move starting bit up
+            // but stay in this byte of the buf (do not increment b)
+            // since kPackSmpBits <= kBitsInShort, sbit can't
+            // move past the end of the current two bytes
+            sbit += packSmpBits;
+        } else {
+            // first few bits towards the end of this short
+            dum   >>= sbit;
+            *b     |= dum >> 8u;         // "first" byte of the short
+            dum   <<= 8u;
+            *(b+1) |= dum >> 8u;   // "second"
+            if ( (sbit+packSmpBits) >= BITS_IN_SHORT ) {
+               b+=2;       // move to next short in the buf
+               i--; dev--; // but stay on this number
+               // move starting bit back into the short we just filled
+               sbit -= BITS_IN_SHORT;
+            } else {
+               // stay in this buffer and move to the next number
+               // move starting bit up
+               sbit += packSmpBits;
+            }
+        }
+    }
+    
+    return buf+blen;
+}
+
+const uint8_t* SnEventFrame::UnpackWavef(const uint8_t* const buf,
+                                         uint16_t* const data,
+                                         const uint8_t loseLSB,
+                                         const uint8_t loseMSB,
+                                         const uint16_t wvBaseline) {
+    if (loseLSB==0 && loseMSB==0 && wvBaseline==0) {
+        memcpy(data, buf, kTotSamps*sizeof(uint16_t));
+    } else {
+
+        const uint8_t packSmpBits = BITS_IN_SHORT-loseLSB-loseMSB;
+    
+        // make sure data is all 0's to start
+        memset(data, 0, kTotSamps*sizeof(uint16_t));
+        
+        const uint8_t* b = buf;
+        uint16_t* dev = data;
+        uint16_t dum;
+        int8_t sbit=0;
+        for (uint16_t i=0; i<kTotSamps; i++, dev++) {
+            dum  = (*b) << 8u;
+            dum |= *(b+1);
+            if (sbit<=0) {
+                dum >>= (-sbit+loseLSB+loseMSB);
+                dum <<= loseLSB;
+                *dev |= dum;
+                // add baseline and move to next number (dev++ in the for loop)
+                *dev += wvBaseline;
+                // but stay in this short of the buf (do not increment b)
+                // move starting bit up
+                sbit += packSmpBits;
+            } else {
+                dum <<= sbit;
+                dum >>= loseMSB+loseLSB;
+                dum <<= loseLSB;
+                *dev = dum;
+                if ( (sbit+packSmpBits) >= BITS_IN_SHORT ) {
+                   b+=2;       // move to next short in the buf
+                   i--; dev--; // but stay on this number
+                   // move starting bit back into the short we just read from
+                   sbit -= BITS_IN_SHORT;
+                } else {
+                   // add baseline and move to next number (dev++ in the for loop)
+                   *dev += wvBaseline;
+                   sbit += packSmpBits;
+                }
+            } 
+        }
+    }
+    
+    return buf+SizeOfPackedWavef(loseLSB, loseMSB);
+}
+