Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

SnConfigFrame.h

Committer:
uci1
Date:
2012-07-20
Revision:
1:e392595b4b76
Parent:
0:664899e0b988
Child:
3:24c5f0f50bf1

File content as of revision 1:e392595b4b76:

#ifndef SN_SnConfigFrame
#define SN_SnConfigFrame

#include <stdint.h>
#include "SnConstants.h"
#include "SnBitUtils.h"

class SnConfigFrame {
 public:
    static const uint32_t    kMinCommWinPrdLowPwr; // exclusive min low power comm win period (s)
    static const uint32_t    kMaxCommWinPrdLowPwr; // exclusive max low power comm win period (s)
    static const uint32_t    kMinCommWinDurLowPwr; // exclusive min low power comm win duration (s)
    static const uint32_t    kMaxCommWinDurLowPwr; // exclusive max low power comm win duration (s)
    static const uint8_t     kConfLblLen=64;       // length of configuration label char array (63+'\0')
    
    static const char* const kDefConfFile;  // default configuration file

    static const uint32_t   kMaxSizeOf = 
            + (9u*sizeof(uint32_t)) + (6u*sizeof(uint16_t))
            + (10u*sizeof(uint8_t)) + (3u*kNplas*sizeof(uint16_t))
            + (kTotDacs*sizeof(uint16_t))
            + (kConfLblLen*sizeof(uint8_t));

    
    enum EDatPackBit {
        kSDcard = BIT(0),
        kIrid   = BIT(1),
        kAfar   = BIT(2),
        kUSB    = BIT(3)
    };
    
    enum ESendDataBit {
        // can't use BIT(0)! (-0 = 0 => send nothing)
        kAllFiles =  BIT(1), // if bit=0 => send most recent file
        kTimeout  =  BIT(2), // if bit=0 => ignore timeout
        kDelete   =  BIT(3), // if bit=0 => do not delete sent files
        kUseBits  = -BIT(10) // useful to initialize fCommSendData as a bit word
    };
    
    // i/o version
    static const uint8_t     kIOVers;   // MUST BE INCREASED if any member var changes (==> also if kNchans, etc. change!)
    
 private:
    // !!
    // !! If any member variables change, update: SizeOf function and kIOVers value! (also if kNchans, etc. change!)
    // !!
    
    // mbed mac address
    static uint64_t fgMacAdr;              // mbed mac address
    // conf header
    char        fLabel[kConfLblLen];       // configuration label
    uint32_t    fConfTime;                 // cpu config time
    uint32_t    fRun;                      // run number
    uint32_t    fFirstEvt;                 // starting event number
    uint8_t     fStreamHiLoPlas;           // (1byte bool) if true, add the separated hi/lo thresh PLA patterns to the i/o
    // data packing
    uint8_t     fWvLoseLSB;                // number of least significant bits to lose when packing waveform data
    uint8_t     fWvLoseMSB;                // number of  most significant bits to lose when packing waveform data
    uint16_t    fWvBaseline;               // global baseline to use when packing data (useful to reduce clipping on the high end)
    uint8_t     fDatPackType;              // type of data packing. OR'd bitword: if bit 1, will pack for writing. see EDatPackBit. default: always pack (all 1's)
    // trigger setup
    uint16_t    fDAC[kNchans][kNfpgaDacs]; //[card id][dac id] values should be 0-4095 here (not checked tho)
    uint8_t     fNumPlas;                  // number of patterns to use. must be <= kNplas.
    uint16_t    fPLA[kNplas];              //[pattern id] (same for each card)
    uint8_t     fNumCardsMajLog;           // number of cards participating in the MajLogic trigger (1 to 4)
    uint8_t     fEnableThermTrig;          // (1byte bool) whether or not to allow thermal triggers
    uint16_t    fForceTrigPeriod;          // number of seconds between force triggers (0=none)
    uint16_t    fHeartBeatPeriod;          // number of seconds between heartbeats (0=none)
    uint8_t     fAmpsOn;                   // which amps are on (bit word. uint8_t => 8 amps max)
    uint16_t    fEvtThrtlPeriodMs;         // throttle period to write events (ms)
    // power
    uint8_t     fPowerMode;                // power mode bit word
    int16_t     fBatVoltLowPwr;            // battery level at which to switch to low power (not used?)
    // communication
    uint32_t    fCommWinPeriod;            // seconds between communication window startup (0=always on)
    uint32_t    fCommWinDuration;          // seconds that communication window stays open (0=always open)
    int16_t     fCommSendData;             // data to send during comm win (=0: none, >0=send up to x events from last file until comm win closes, <0=see ESendDataBit)
    uint32_t    fCommWinPrdLowPwr;         // low power communication window period (seconds) (range enforced)
    uint32_t    fCommWinDurLowPwr;         // low power communication window duration (seconds) (range enforced)
    // watchdog
    uint32_t    fWatchDogPeriod;           // number of seconds of inactivity for watchdog to issue a reset
    
    void SetHardDefaults();
    
    static
    uint32_t    SizeOf(const bool streamHiLoPlas,
                       const uint8_t nplas,
                       const uint8_t lblLen) {
        // private because it cannot be used to read from a buffer
        // (the label length and fStreamHiLoPlas are not known a priori)
        // returns the num of bytes needed to stream this object
        // = size of member vars + 1 for i/o version + extra PLA strings (maybe)
        uint32_t sz = kMaxSizeOf - kConfLblLen + lblLen;
        static const uint32_t mhlp = 2u*kNplas*sizeof(uint16_t);
        const int32_t dp = (nplas-kNplas)*sizeof(uint16_t);
        const uint8_t fac = (streamHiLoPlas) ? 3u : 1u;
        sz -= (fac*dp);
        if (streamHiLoPlas==false) {
            sz -= mhlp;
        }
        return sz;
    }
   
 public:
    SnConfigFrame() { Reset(); }
    virtual ~SnConfigFrame() {}
    
    const char* GetLabel() const { return fLabel; }
    uint32_t GetLabelStrLen() const { return strlen(fLabel); }
    uint32_t GetRun() const { return fRun; }
    uint32_t GetFirstEvt() const { return fFirstEvt; }
    uint16_t GetEvtThrtlPeriodMs() const { return fEvtThrtlPeriodMs; }
    uint16_t GetForceTrigPeriod() const { return fForceTrigPeriod; }
    uint32_t GetWatchdogPeriod() const { return fWatchDogPeriod; }
    uint16_t GetDac(const uint8_t ch, const uint8_t dn) const { return fDAC[ch][dn]; }
    uint8_t  GetNumPlas() const { return fNumPlas; }
    uint16_t GetPla(const uint8_t pn) const { return fPLA[pn]; }
    uint8_t  GetNumCardsMajLog() const { return fNumCardsMajLog; }
    bool     IsThermTrigEnabled() const { return fEnableThermTrig!=0; }
    bool     IsEachAmpOn() const {
        bool allon=true;
        for (uint8_t i=0; (i<kNchans) && allon; i++) {
            allon = (fAmpsOn & BIT(i))!=0;
        }
        return allon;
    }
    // TODO: allow check for individual amps, when they can be turned on individually
    
    uint32_t GetCommWinPeriod() const { return fCommWinPeriod; }
    uint32_t GetCommWinDuration() const { return fCommWinDuration; }
    int16_t  GetCommSendData() const { return fCommSendData; }
    
    bool     IsSendingAllFiles() const
        { return (fCommSendData<0) && ((fCommSendData & kAllFiles)!=0); }
    bool     IsObeyingTimeout() const
        { return (fCommSendData<0) && ((fCommSendData & kTimeout)!=0); }
    bool     IsDeletingFiles() const
        { return (fCommSendData<0) && ((fCommSendData & kDelete)!=0); }
    
    
    const char* GetOutFileName(const char* dir) const;
    
    // waveform packing info
    uint16_t GetWvBaseline() const { return fWvBaseline; }
    uint8_t  GetWvLoseLSB() const { return fWvLoseLSB; }
    uint8_t  GetWvLoseMSB() const { return fWvLoseMSB; }
    bool     IsDatPackedFor(const EDatPackBit d) const { return (fDatPackType & d)!=0; }
    void     GetPackParsFor(const EDatPackBit d,
                            uint8_t& loseLSB, uint8_t& loseMSB,
                            uint16_t& wvBase) const;
    
    // i/o
    template<class T>
    void ReadFrom(T& b) {
        // no check on the length of buf is done here
        // that should be been done already
        //
        // must match WriteTo
        
        uint8_t Rv=0;
        b               = SnBitUtils::ReadFrom(b, Rv); // i/o version
        if (Rv>0) {
            uint32_t llen=kConfLblLen;
            b           = SnBitUtils::ReadFrom(b, llen);
            b           = SnBitUtils::ReadFrom(b, fLabel, llen);
            b           = SnBitUtils::ReadFrom(b, fConfTime);
            b           = SnBitUtils::ReadFrom(b, fRun);
            b           = SnBitUtils::ReadFrom(b, fFirstEvt);
            b           = SnBitUtils::ReadFrom(b, fStreamHiLoPlas);
            b           = SnBitUtils::ReadFrom(b, fWvLoseLSB);
            b           = SnBitUtils::ReadFrom(b, fWvLoseMSB);
            b           = SnBitUtils::ReadFrom(b, fWvBaseline);
            b           = SnBitUtils::ReadFrom(b, fDatPackType);
            uint16_t* dc = &(fDAC[0][0]);
            for (uint16_t i=0; i<kTotDacs; i++, dc++) {
                b       = SnBitUtils::ReadFrom(b, *dc);
            }
            b           = SnBitUtils::ReadFrom(b, fNumPlas);
            uint16_t* pl = &(fPLA[0]);
            for (uint8_t j=0; j<fNumPlas; j++, pl++) {
                b       = SnBitUtils::ReadFrom(b, *pl);
            }
            b           = SnBitUtils::ReadFrom(b, fNumCardsMajLog);
            b           = SnBitUtils::ReadFrom(b, fEnableThermTrig);
            b           = SnBitUtils::ReadFrom(b, fForceTrigPeriod);
            b           = SnBitUtils::ReadFrom(b, fHeartBeatPeriod);
            b           = SnBitUtils::ReadFrom(b, fAmpsOn);
            b           = SnBitUtils::ReadFrom(b, fEvtThrtlPeriodMs);
            b           = SnBitUtils::ReadFrom(b, fPowerMode);
            b           = SnBitUtils::ReadFrom(b, fBatVoltLowPwr);
            b           = SnBitUtils::ReadFrom(b, fCommWinPeriod);
            b           = SnBitUtils::ReadFrom(b, fCommWinDuration);
            b           = SnBitUtils::ReadFrom(b, fCommSendData);
            b           = SnBitUtils::ReadFrom(b, fCommWinPrdLowPwr);
            b           = SnBitUtils::ReadFrom(b, fCommWinDurLowPwr);
            b           = SnBitUtils::ReadFrom(b, fWatchDogPeriod);
            if (fStreamHiLoPlas!=0) {
                uint16_t hi, lo;
                for (uint8_t j=0; j<fNumPlas; j++) {
                    b   = SnBitUtils::ReadFrom(b, hi);
                    b   = SnBitUtils::ReadFrom(b, lo);
                    // don't save these
                }
            }
        }
    }
    
    template <class T>
    void WriteTo(T& b) const {
        // no check on the length of the buf is done here
        // that should be done already
        //
        // must match ReadFromBuf
        //
        // intentionally not writing mac address here, so we don't have to read it in
        
        const uint32_t llen = strlen(fLabel);
        
        b           = SnBitUtils::WriteTo(b, kIOVers); // i/o version
        b           = SnBitUtils::WriteTo(b, llen);
        b           = SnBitUtils::WriteTo(b, fLabel, llen);
        b           = SnBitUtils::WriteTo(b, fConfTime);
        b           = SnBitUtils::WriteTo(b, fRun);
        b           = SnBitUtils::WriteTo(b, fFirstEvt);
        b           = SnBitUtils::WriteTo(b, fStreamHiLoPlas);
        b           = SnBitUtils::WriteTo(b, fWvLoseLSB);
        b           = SnBitUtils::WriteTo(b, fWvLoseMSB);
        b           = SnBitUtils::WriteTo(b, fWvBaseline);
        b           = SnBitUtils::WriteTo(b, fDatPackType);
        const uint16_t* dc = &(fDAC[0][0]);
        for (uint16_t i=0; i<kTotDacs; i++, dc++) {
            b       = SnBitUtils::WriteTo(b, *dc);
        }
        b           = SnBitUtils::WriteTo(b, fNumPlas);
        const uint16_t* pl = &(fPLA[0]);
        for (uint8_t j=0; j<fNumPlas; j++, pl++) {
            b       = SnBitUtils::WriteTo(b, *pl);
        }
        b           = SnBitUtils::WriteTo(b, fNumCardsMajLog);
        b           = SnBitUtils::WriteTo(b, fEnableThermTrig);
        b           = SnBitUtils::WriteTo(b, fForceTrigPeriod);
        b           = SnBitUtils::WriteTo(b, fHeartBeatPeriod);
        b           = SnBitUtils::WriteTo(b, fAmpsOn);
        b           = SnBitUtils::WriteTo(b, fEvtThrtlPeriodMs);
        b           = SnBitUtils::WriteTo(b, fPowerMode);
        b           = SnBitUtils::WriteTo(b, fBatVoltLowPwr);
        b           = SnBitUtils::WriteTo(b, fCommWinPeriod);
        b           = SnBitUtils::WriteTo(b, fCommWinDuration);
        b           = SnBitUtils::WriteTo(b, fCommSendData);
        b           = SnBitUtils::WriteTo(b, fCommWinPrdLowPwr);
        b           = SnBitUtils::WriteTo(b, fCommWinDurLowPwr);
        b           = SnBitUtils::WriteTo(b, fWatchDogPeriod);
        if (fStreamHiLoPlas!=0) {
            pl = fPLA;
            uint16_t hi, lo;
            for (uint8_t j=0; j<fNumPlas; j++, pl++) {
                GetHiLoPlas(*pl, hi, lo);
                b   = SnBitUtils::WriteTo(b, hi);
                b   = SnBitUtils::WriteTo(b, lo);
            }
        }
    }
    
    bool ReadFromFile(const char* cfile);
    bool WriteToFile(const char* cfile) const;
    
    void Reset() {
        memset(fLabel, 0, sizeof(char)*kConfLblLen);
        if (ReadFromFile(kDefConfFile)==false) {
            // couldn't get default. use hardcoded version.
            SetHardDefaults();
        }
    }
        
    uint32_t    SizeOf() const {
        // returns the num of bytes needed to stream this object
        // = size of member vars + 1 for i/o version + extra PLA strings (maybe)
        //   + length of label string
        return SizeOf(fStreamHiLoPlas!=0, fNumPlas, strlen(fLabel));
    }

    static void     SetMacAddress();
    static uint64_t GetMacAddress() {
        if (fgMacAdr==0) {
            SetMacAddress();
        }
        return fgMacAdr;
    }
    
    static uint32_t GetLabelMaxLen() { return kConfLblLen; }

    static void GetHiLoPlas(const uint16_t pla,
                            uint16_t& hiPla,
                            uint16_t& loPla,
                            const bool r2l=false);
};

#endif // SN_SnConfigFrame