Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
SnConfigFrame.h
- Committer:
- uci1
- Date:
- 2012-08-18
- Revision:
- 12:d472f9811262
- Parent:
- 8:95a325df1f6b
- Child:
- 13:7a1fb885a8e4
File content as of revision 12:d472f9811262:
#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 uint8_t kIPLen=16; // length of IP string. matches MBED's Socket class (so no ipv6) static const char* const kDefConfFile; // default configuration file static const uint32_t kMaxSizeOfV1 = + (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)); static const uint32_t kMaxSizeOfV2 = kMaxSizeOfV1 + sizeof(uint32_t) + sizeof(uint8_t); static const uint32_t kMaxSizeOfV3 = kMaxSizeOfV2 + (2u*sizeof(uint16_t)) + (4u*kIPLen*sizeof(char)); static const uint32_t kMaxSizeOf = kMaxSizeOfV3; 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(15) // useful to initialize fCommSendData as a bit word }; enum EPowerModeBit { kAmpsDatTak = BIT(0), kCardDatTak = BIT(1), kIridDatTak = BIT(2), kAfarDatTak = BIT(3), kAmpsComWin = BIT(4), kCardComWin = BIT(5), kIridComWin = BIT(6), kAfarComWin = BIT(7) }; enum ERunMode { kSingleSeqBit = BIT(0), // if 0, infinite sequences kCountPowerBit = BIT(1), // if 0, count events }; // 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 uint32_t fEvtsPerSeq; // number of events per file uint8_t fRunMode; // mode of running (see ERunMode) 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: see EPowerModeBit int16_t fBatVoltLowPwr; // battery level at which to switch to low power (not used?) uint16_t fVoltCheckPeriod; // how often to check the voltages (s) // 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) char fRemoteServer[kIPLen]; // IP address of remote server (for afar) uint16_t fRemotePort; // port number of remote server (for afar) char fMbedIP[kIPLen]; // IP address of this mbed char fMbedMask[kIPLen]; // IP address of this mbed mask char fMbedGate[kIPLen]; // IP address of this mbed gateway // watchdog uint32_t fWatchDogPeriod; // number of seconds of inactivity for watchdog to issue a reset // in case of low power, store regular settings // these are not sent over i/o or stored in the file // so they are not included in SizeOf bool fIsLowPower; char fNormLabel[kConfLblLen]; uint8_t fNormPowerMode; void SetHardDefaults(); static uint32_t SizeOf(const uint8_t rv, 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 maxsize = kMaxSizeOf; if (rv==1) { maxsize = kMaxSizeOfV1; } else if (rv==2) { maxsize = kMaxSizeOfV2; } uint32_t sz = maxsize - 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() : fIsLowPower(false) { Reset(); } virtual ~SnConfigFrame() {} bool IsCountingPowerReadings() const { return ((fRunMode & kCountPowerBit)!=0); } bool IsSingleSeqRunMode() const { return ((fRunMode & kSingleSeqBit)!=0); } bool IsLowPowerMode() const { return fIsLowPower; } 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; } uint32_t GetEvtsPerFile() const { return fEvtsPerSeq; } uint16_t GetEvtThrtlPeriodMs() const { return fEvtThrtlPeriodMs; } uint16_t GetForceTrigPeriod() const { return fForceTrigPeriod; } uint16_t GetHeartbeatPeriod() const { return fHeartBeatPeriod; } uint16_t GetBatVoltLowPwr() const { return fBatVoltLowPwr; } uint16_t GetVoltCheckPeriod() const { return fVoltCheckPeriod; } 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 const char* GetRemoteServer() const { return fRemoteServer; } uint16_t GetRemotePort() const { return fRemotePort; } const char* GetMbedIP() const { return fMbedIP; } const char* GetMbedMask() const { return fMbedMask; } const char* GetMbedGate() const { return fMbedGate; } uint32_t GetCommWinPeriod() const { return fIsLowPower ? fCommWinPrdLowPwr : fCommWinPeriod; } uint32_t GetCommWinDuration() const { return fIsLowPower ? fCommWinDurLowPwr : 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); } uint8_t GetPowerMode() const { return fPowerMode; } int GetPowPinSetting(const EPowerModeBit p) const { // return int to correspond to what DigitalOut::operator= expects const bool on = IsPoweredFor(p); if (p==kCardDatTak || p==kCardComWin || p==kAmpsDatTak || p==kAmpsComWin) { return on ? 0 : 1; } else { return on ? 1 : 0; } } bool IsPoweredFor(const EPowerModeBit p) const { return ((fPowerMode & p)!=0); } void EnablePowerFor(const EPowerModeBit p) { fPowerMode |= p; } void DisablePowerFor(const EPowerModeBit p) { fPowerMode &= ~p; } void ChangeToLowPower(); void ChangeToNormPower(); 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 #ifdef DEBUG printf("Rv=%hhu\r\n",Rv); #endif if (Rv>0) { uint32_t llen=kConfLblLen; b = SnBitUtils::ReadFrom(b, llen); #ifdef DEBUG printf("llen=%u\r\n",llen); #endif b = SnBitUtils::ReadFrom(b, fLabel, llen); #ifdef DEBUG printf("lbl=%s\r\n",fLabel); #endif b = SnBitUtils::ReadFrom(b, fConfTime); #ifdef DEBUG printf("ct=%u\r\n",fConfTime); #endif b = SnBitUtils::ReadFrom(b, fRun); #ifdef DEBUG printf("run=%u\r\n",fRun); #endif b = SnBitUtils::ReadFrom(b, fFirstEvt); #ifdef DEBUG printf("fe=%u\r\n",fFirstEvt); #endif if (Rv>1) { b = SnBitUtils::ReadFrom(b, fEvtsPerSeq); #ifdef DEBUG printf("eps=%u\r\n",fEvtsPerSeq); #endif b = SnBitUtils::ReadFrom(b, fRunMode); #ifdef DEBUG printf("rm=%hhu\r\n",fRunMode); #endif } b = SnBitUtils::ReadFrom(b, fStreamHiLoPlas); #ifdef DEBUG printf("shilo=%d\r\n",(int)fStreamHiLoPlas); #endif b = SnBitUtils::ReadFrom(b, fWvLoseLSB); #ifdef DEBUG printf("lsb=%hhu\r\n",fWvLoseLSB); #endif b = SnBitUtils::ReadFrom(b, fWvLoseMSB); #ifdef DEBUG printf("msb=%hhu\r\n",fWvLoseMSB); #endif b = SnBitUtils::ReadFrom(b, fWvBaseline); #ifdef DEBUG printf("bl=%hu\r\n",fWvBaseline); #endif b = SnBitUtils::ReadFrom(b, fDatPackType); #ifdef DEBUG printf("dp=%hhu\r\n",fDatPackType); #endif uint16_t* dc = &(fDAC[0][0]); for (uint16_t i=0; i<kTotDacs; i++, dc++) { b = SnBitUtils::ReadFrom(b, *dc); #ifdef DEBUG printf("dac[%hu]=%hu\r\n",i,*dc); #endif } b = SnBitUtils::ReadFrom(b, fNumPlas); #ifdef DEBUG printf("npla=%hhu\r\n",fNumPlas); #endif uint16_t* pl = &(fPLA[0]); for (uint8_t j=0; j<fNumPlas; j++, pl++) { b = SnBitUtils::ReadFrom(b, *pl); #ifdef DEBUG printf("pla[%hhu]=%hu\r\n",j,*pl); #endif } b = SnBitUtils::ReadFrom(b, fNumCardsMajLog); #ifdef DEBUG printf("mj=%hhu\r\n",fNumCardsMajLog); #endif b = SnBitUtils::ReadFrom(b, fEnableThermTrig); #ifdef DEBUG printf("thm=%d\r\n",(int)fEnableThermTrig); #endif b = SnBitUtils::ReadFrom(b, fForceTrigPeriod); #ifdef DEBUG printf("force=%hu\r\n",fForceTrigPeriod); #endif b = SnBitUtils::ReadFrom(b, fHeartBeatPeriod); #ifdef DEBUG printf("heart=%hu\r\n",fHeartBeatPeriod); #endif b = SnBitUtils::ReadFrom(b, fAmpsOn); #ifdef DEBUG printf("amps=%hhu\r\n",fAmpsOn); #endif b = SnBitUtils::ReadFrom(b, fEvtThrtlPeriodMs); #ifdef DEBUG printf("throt=%hu\r\n",fEvtThrtlPeriodMs); #endif b = SnBitUtils::ReadFrom(b, fPowerMode); #ifdef DEBUG printf("pow=%hhu\r\n",fPowerMode); #endif b = SnBitUtils::ReadFrom(b, fBatVoltLowPwr); #ifdef DEBUG printf("batlow=%hd\r\n",fBatVoltLowPwr); #endif if (Rv>2) { b = SnBitUtils::ReadFrom(b, fVoltCheckPeriod); #ifdef DEBUG printf("vltchk=%hu\r\n",fVoltCheckPeriod); #endif } b = SnBitUtils::ReadFrom(b, fCommWinPeriod); #ifdef DEBUG printf("cmper=%u\r\n",fCommWinPeriod); #endif b = SnBitUtils::ReadFrom(b, fCommWinDuration); #ifdef DEBUG printf("cmdur=%u\r\n",fCommWinDuration); #endif b = SnBitUtils::ReadFrom(b, fCommSendData); #ifdef DEBUG printf("send=%d\r\n",fCommSendData); #endif b = SnBitUtils::ReadFrom(b, fCommWinPrdLowPwr); #ifdef DEBUG printf("cmperlp=%u\r\n",fCommWinPrdLowPwr); #endif b = SnBitUtils::ReadFrom(b, fCommWinDurLowPwr); #ifdef DEBUG printf("cmdurlp=%u\r\n",fCommWinDurLowPwr); #endif if (Rv>2) { b = SnBitUtils::ReadFrom(b, fRemoteServer, kIPLen); #ifdef DEBUG printf("rserv=%s\r\n",fRemoteServer); #endif b = SnBitUtils::ReadFrom(b, fRemotePort); #ifdef DEBUG printf("rport=%hu\r\n",fRemotePort); #endif b = SnBitUtils::ReadFrom(b, fMbedIP, kIPLen); #ifdef DEBUG printf("mbedip=%s\r\n",fMbedIP); #endif b = SnBitUtils::ReadFrom(b, fMbedMask, kIPLen); #ifdef DEBUG printf("mbedmask=%s\r\n",fMbedMask); #endif b = SnBitUtils::ReadFrom(b, fMbedGate, kIPLen); #ifdef DEBUG printf("mbedgate=%s\r\n",fMbedGate); #endif } b = SnBitUtils::ReadFrom(b, fWatchDogPeriod); #ifdef DEBUG printf("watch=%u\r\n",fWatchDogPeriod); #endif if (fStreamHiLoPlas!=0) { uint16_t hi, lo; for (uint8_t j=0; j<fNumPlas; j++) { b = SnBitUtils::ReadFrom(b, hi); #ifdef DEBUG printf("hi=%hu\r\n",hi); #endif b = SnBitUtils::ReadFrom(b, lo); #ifdef DEBUG printf("lo=%hu\r\n",lo); #endif // don't save these } } } #ifdef DEBUG printf("read from done\r\n"); #endif } 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, fEvtsPerSeq); b = SnBitUtils::WriteTo(b, fRunMode); 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, fVoltCheckPeriod); 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, fRemoteServer, kIPLen); b = SnBitUtils::WriteTo(b, fRemotePort); b = SnBitUtils::WriteTo(b, fMbedIP, kIPLen); b = SnBitUtils::WriteTo(b, fMbedMask, kIPLen); b = SnBitUtils::WriteTo(b, fMbedGate, kIPLen); 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 uint8_t rv) 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(rv, 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