Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
SnConfigFrame.h
- Committer:
- uci1
- Date:
- 2015-11-24
- Revision:
- 110:d1da040a0cf2
- Parent:
- 85:3ced48ef94c5
- Child:
- 114:554fa3a956b4
File content as of revision 110:d1da040a0cf2:
#ifndef SN_SnConfigFrame #define SN_SnConfigFrame #include <stdint.h> #include "SnConstants.h" #include "SnBitUtils.h" //#define DEBUG class SnConfigFrame { public: static bool fgApplySafetyNets; // whether to apply safety bounds on certain parameters in ReadFrom (default: true) 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 kConfLblLenNoStrTerm=63; // length of configuration label char array without the terminating '\0' (must not change!! used in i/o sizes) static const uint8_t kConfLblLen=kConfLblLenNoStrTerm+1; // length of configuration label char array (63+'\0') (must not change!! used in i/o sizes) static const uint8_t kIPLen=16; // length of IP string (includes \0). matches MBED's Socket class (so no ipv6) (must not change!! used in i/o sizes) #ifdef USE_INTERFACE_CHIP static const char* const kDefConfFile; // default configuration file static const char* const kDefRemIpFilen; static const char* const kDefRemPortFilen; static const char* const kDefMbedIPFilen; static const char* const kDefMbedMaskFilen; static const char* const kDefMbedGateFilen; #endif static const char* const kDefIPflag; // flag to use IP default static const uint32_t kDefIPvalue; // value to indicate use of default IP // ATWD 4channel configs static const uint32_t kMaxSizeOfV1 = + (9u*sizeof(uint32_t)) + (6u*sizeof(uint16_t)) + (10u*sizeof(uint8_t)) + (3u*kNplasV1*sizeof(uint16_t)) // 3*Nplas because if StreamHiLo is set, will stream 3 values (composite, high side, low side) + (kTotDacsAtwd4ch*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 kMaxSizeOfV4 = kMaxSizeOfV3 + (sizeof(float)-sizeof(uint16_t)); // forced trig per to float static const uint32_t kMaxSizeOfV5 = kMaxSizeOfV4; static const uint32_t kMaxSizeOfV6 = kMaxSizeOfV5 + sizeof(uint16_t); // To/From Low Power static const uint32_t kMaxSizeOfV7 = kMaxSizeOfV6 + (2u*sizeof(uint8_t)); // add ConnTOmins, ListenTOmins static const uint32_t kMaxSizeOfV8 = kMaxSizeOfV7 - sizeof(uint32_t) + sizeof(uint16_t); // FirstEvt -> FirstSeq // SST 4channel configs static const uint32_t kMaxSizeOfV9 = kMaxSizeOfV8 - (3u*kNplasV1*sizeof(uint16_t)) // no patterns in SST - (kTotDacsAtwd4ch*sizeof(uint16_t)) + (kTotDacsSst4ch*sizeof(uint16_t)) // switch to number of SST dacs - sizeof(uint8_t) // no stream hi/lo pla flag - sizeof(uint8_t); // no num plas variable static const uint32_t kMaxSizeOfV10 = kMaxSizeOfV9 + sizeof(int8_t); // add fTempCheckPeriod // ATWD - expanding upon V8 (previous ATWD config) static const uint32_t kMaxSizeOfV11 = kMaxSizeOfV8 - sizeof(uint32_t) // label length (now always 64 bytes written) - (sizeof(uint32_t) - sizeof(uint16_t)) // fEvtsPerSeq from uint32_t to uint16_t - sizeof(uint8_t) // remove stream hi/lo pla's (always false now) - sizeof(uint8_t) // remove pack data (always done for all peripherals) - sizeof(uint8_t) // remove amps on completely - (4u*kIPLen) + (4u*sizeof(uint32_t)) // change IP from strings to numbers - (2u*kNplasV1*sizeof(uint16_t)) // no streaming of hi/lo patterns + sizeof(uint8_t) // add single freq ratio L1 trig parameter + sizeof(uint8_t) // L1 scaledown + sizeof(uint16_t) - sizeof(uint8_t) // change fEnableTherm from 8 bit to 16 bit to match trigger bit word in event + (2u*sizeof(uint8_t)) // connect and listen TOs for Irid & Afar + sizeof(uint16_t) - sizeof(uint8_t); // run mode from 8 to 16 bit integer // SST - expanding upon V10 (previous SST config) static const uint32_t kMaxSizeOfV12 = kMaxSizeOfV10 - sizeof(uint32_t) // label length (now always 64 bytes written) - (sizeof(uint32_t) - sizeof(uint16_t)) // fEvtsPerSeq from uint32_t to uint16_t - sizeof(uint8_t) // remove pack data (always done for all peripherals) - sizeof(uint8_t) // remove amps on completely - (4u*kIPLen) + (4u*sizeof(uint32_t)) // change IP from strings to numbers + sizeof(uint8_t) // add single freq ratio L1 trig parameter + sizeof(uint8_t) // L1 scaledown + sizeof(uint16_t) - sizeof(uint8_t) // change fEnableTherm from 8 bit to 16 bit to match trigger bit word in event + (2u*sizeof(uint8_t)) // connect and listen TOs for Irid & Afar + sizeof(uint16_t) - sizeof(uint8_t); // run mode from 8 to 16 bit integer static const uint32_t kMaxSizeOf = kMaxSizeOfV7; // should be the biggest one enum EDatPackBit { kSDcard = BIT(0), kIrid = BIT(1), kAfar = BIT(2), kUSB = BIT(3) }; static const uint8_t kNumDatStreams = 4; // ** note: need to change manually 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 kForceSBDdata = BIT(4), // if bit=0 => do not send data over SBD kHnShBefSendDat = BIT(5), // if bit=0 => do not wait for a handshake after GetConfig before calling SendData kSendRunSeqList = BIT(6), // if bit=1 and kAllFiles bit=0, send all files in the run/seq list (instead of most recent file) kStatSendConf = BIT(7), // if bit=1, send a config with the status update data kStatSendTrgTim = BIT(8), // if bit=1, send trigger start/stop times with the status update data kStatSendPwrDat = BIT(9), // if bit=1, send the last power frame recorded in data taking mode with the status update kStatSendEvent = BIT(10), // if bit=1, send the last event frame recorded in data taking mode with the status update kStatSendHtbt = BIT(11), // if bit=1, send the last heartbeat frame recorded in data taking mode with the status update kStatSendTmpDat = BIT(12), // if bit=1, send the last temperature frame recorded in data taking mode with the status update kUseBits = static_cast<int16_t>(-BIT(14)) // 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 kDualThreshBit = BIT(2), // if 0, single sided thresholds on SST kDiffTrigBit = BIT(3), // if 0, send result of each comparator on SST kLowPwrSBDonly = BIT(4), // if 0, low power afar/sbd power settings same as normal. if 1, afar off and sbd on during low power mode kRSListOneCW = BIT(5), // if 0, only clear run/seq list after files sent from it kIgnoreSDcard = BIT(6), // if 0, read/write data to SD card as normal. if 1, function as though no SD card is present kComPwrSimple = BIT(7), // if 0, comm periphs powered as needed during comm win. if 1, power adjusted once at start/finish of comm win kCommEachEvent = BIT(8) // if 0, comm windows only after comm period of seconds. if 1, comm winodows also after each event that qualifies for saving to SD card }; // 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 uint16_t fFirstSeq; // starting sequence number uint16_t fEvtsPerSeq; // number of events per file uint16_t fRunMode; // mode of running (see ERunMode) -- changed from uint8 to uint16 with V11+ #if CHIPBOARD==ATWD4CH // in newer versions (11+), this is always false uint8_t fStreamHiLoPlas; // (1byte bool) if true, add the separated hi/lo thresh PLA patterns to the i/o #endif // 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). starting with IOVers 11+, this is always all 1's and is not settable // trigger setup uint16_t fDAC[kNchans][kNchanDacs]; //[card id][dac id] values should be 0-4095 here (not checked tho) #if CHIPBOARD==ATWD4CH uint8_t fNumPlas; // number of patterns to use. must be <= kNplas. uint16_t fPLA[kNplas]; //[pattern id] (same for each card) #endif uint8_t fNumCardsMajLog; // number of cards participating in the MajLogic trigger (1 to 4) uint16_t fEnableThermTrig; // whether or not to allow thermal triggers. as of vers 11+, now a bit word that can enable L1 triggers in addition to in-chip triggers. that means it now must be the same size as the trigger bit word in the event! float 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). removed vers 11+, as it cannot be implemented. uint16_t fEvtThrtlPeriodMs; // throttle period to write events (ms) // power uint8_t fPowerMode; // power mode bit word: see EPowerModeBit uint16_t fBatVoltToLowPwr; // battery level at which to switch to low power (not used?) uint16_t fBatVoltFromLowPwr; // battery level at which to switch back from 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) uint8_t fCommWinConnTOMins[kNumDatStreams]; // comm win connection timeout (minutes) for each data stream (range enforced) uint8_t fCommWinListTOMins[kNumDatStreams]; // comm win listening timeout (minutes) for each data stream (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 #if CHIPBOARD==SST4CH // temp int8_t fTempCheckPeriod; // number of minutes between temperature checks. if negative, uses parasite power. if 0, never check. #endif // vers 11+ below uint8_t fSnglFreqRatio; // single frequency L1 trigger parameter = max / (tot - max). [0,255] => [0.0, 1.0] uint8_t fL1Scaledown; // save an L1 fail event every fL1Scaledown // 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 void SetSDNeedToInitFlag(); static bool IsIOversForATWD(const uint8_t rv) { return ( (rv<9) || (rv==11) ); } static uint16_t GetTotDacsForIOVers(const uint8_t rv) { if ( IsIOversForATWD(rv) ) { return kTotDacsAtwd4ch; } else { return kTotDacsSst4ch; } } static uint16_t GetMaxPlasForIOVers(const uint8_t rv) { if ( IsIOversForATWD(rv) ) { return kNplasV1; } else { return 0; } } 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; } else if (rv==3) { maxsize = kMaxSizeOfV3; } else if (rv==4) { maxsize = kMaxSizeOfV4; } else if (rv==5) { maxsize = kMaxSizeOfV5; } else if (rv==6) { maxsize = kMaxSizeOfV6; } else if (rv==7) { maxsize = kMaxSizeOfV7; } else if (rv==8) { maxsize = kMaxSizeOfV8; } else if (rv==9) { maxsize = kMaxSizeOfV9; } else if (rv==10) { maxsize = kMaxSizeOfV10; } else if (rv==11) { maxsize = kMaxSizeOfV11; } else if (rv==12) { maxsize = kMaxSizeOfV12; } uint32_t sz = maxsize; if (rv<11) { const int32_t lbldiff = kConfLblLen - lblLen; sz = maxsize - lbldiff; if ((lbldiff!=0) && (rv>=4)) { sz += 1; // the \0 at the end of the string } } #if CHIPBOARD==ATWD4CH if ( IsIOversForATWD(rv) ) { // streaming hi/lo plas separately? const uint8_t fac = (streamHiLoPlas && (rv<11)) ? 3u : 1u; const int32_t nplasNotSent = GetMaxPlasForIOVers(rv) - nplas; sz -= (fac*nplasNotSent); /* const uint32_t mhlp = 2u*GetMaxPlasForIOVers(rv)*sizeof(uint16_t); const int32_t dp = (nplas-GetMaxPlasForIOVers(rv))*sizeof(uint16_t); const uint8_t fac = (streamHiLoPlas && (rv<11)) ? 3u : 1u; sz += (fac*dp); if ((streamHiLoPlas==false) || (rv>=11)) { sz -= mhlp; // should be * (maxPlas - nplas), right? } */ } #endif return sz; } #ifdef USE_INTERFACE_CHIP bool ReadOneIPFrom(const char* ipfname, char* ipstr); #endif bool ReadDefaultRemoteServer(); bool ReadDefaultRemotePort(); bool ReadDefaultMbedIP(); bool ReadDefaultMbedMask(); bool ReadDefaultMbedGate(); void SetDefaultIPs(); void SetDefaultRemoteServ(); void SetDefaultRemotePort(); void SetDefaultMbedIP(); void SetDefaultMaskIP(); void SetDefaultGateIP(); void ApplySafetyNets(); void ApplyConnectListenSafetyNets(const uint8_t dataStreamIdx); public: SnConfigFrame(const bool applySafety=true) : fIsLowPower(false) { memset(fLabel, 0, kConfLblLen); fgApplySafetyNets = applySafety; Reset(); } virtual ~SnConfigFrame() {} void ApplyConnectListenSafetyNets(); bool IsCountingPowerReadings() const { return ((fRunMode & kCountPowerBit)!=0); } bool IsSingleSeqRunMode() const { return ((fRunMode & kSingleSeqBit)!=0); } bool IsDualThresholdMode() const { return ((fRunMode & kDualThreshBit)!=0); } bool IsDifferentialTrigMode() const { return ((fRunMode & kDiffTrigBit)!=0); } bool IsSBDonlyLowPwrMode() const { return ((fRunMode & kLowPwrSBDonly)!=0); } bool IsRunSeqListOneCommWinOnly() const { return ((fRunMode & kRSListOneCW)!=0); } bool IsIgnoringSDcard() const { return ((fRunMode & kIgnoreSDcard)!=0); } bool IsCommPowerSimple() const { return ((fRunMode & kComPwrSimple)!=0); } bool IsCommWindowEachEvent() const { return ((fRunMode & kCommEachEvent)!=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; } uint16_t GetFirstSeq() const { return fFirstSeq; } uint16_t GetEvtsPerFile() const { return fEvtsPerSeq; } inline uint16_t GetEvtThrtlPeriodMs() const { return fEvtThrtlPeriodMs; } float GetForceTrigPeriod() const { return fForceTrigPeriod; } uint16_t GetHeartbeatPeriod() const { return fHeartBeatPeriod; } uint16_t GetBatVoltToLowPwr() const { return fBatVoltToLowPwr; } uint16_t GetBatVoltFromLowPwr() const { return fBatVoltFromLowPwr; } uint16_t GetVoltCheckPeriod() const { return fVoltCheckPeriod; } uint32_t GetWatchdogPeriod() const { return fWatchDogPeriod; } #if CHIPBOARD==SST4CH uint16_t GetTempCheckPeriod() const { const uint16_t t = (fTempCheckPeriod<0) ? (-fTempCheckPeriod) : fTempCheckPeriod; return t*60; } bool IsTempUsingParasitePower() const { return (fTempCheckPeriod<0); } #else uint16_t GetTempCheckPeriod() const { return 0; } #endif uint8_t GetSingleFreqSuppRatioRaw() const { return fSnglFreqRatio; } inline float GetSingleFreqSuppRatio() const { return static_cast<float>(fSnglFreqRatio) / 255.0f; } uint16_t GetDac(const uint8_t ch, const uint8_t dn) const { return fDAC[ch][dn]; } #if CHIPBOARD==ATWD4CH uint8_t GetNumPlas() const { return fNumPlas; } uint16_t GetPla(const uint8_t pn) const { return fPLA[pn]; } #endif uint8_t GetNumCardsMajLog() const { return fNumCardsMajLog; } // bool IsThermTrigEnabled() const { return fEnableThermTrig!=0; } uint8_t GetL1Scaledown() const { return fL1Scaledown; } bool IsThermTrigEnabled() const { return (fEnableThermTrig & kThermal)!=0; } bool IsSingleFreqSuppEnabled() const { return (fEnableThermTrig & kSingleFreqSupp)!=0; } bool IsL1TrigApplied() const { return (fEnableThermTrig & kL1TrgApplied)!=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; } uint32_t GetCommWinConnectTOofIdx(const uint8_t idx) const { return (static_cast<uint32_t>( fCommWinConnTOMins[idx] ) * 60u); } uint32_t GetCommWinConnectTO(const SnConfigFrame::EDatPackBit b) const { return GetCommWinConnectTOofIdx(IndexOfDataStream(b)); } uint32_t GetCommWinListenTOofIdx(const uint8_t idx) const { return (static_cast<uint32_t>( fCommWinListTOMins[idx] ) * 60u); } uint32_t GetCommWinListenTO(const SnConfigFrame::EDatPackBit b) const { return GetCommWinListenTOofIdx(IndexOfDataStream(b)); } 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); } bool IsForcingSBDdata() const { return (fCommSendData<0) && ((fCommSendData & kForceSBDdata)!=0); } bool IsWaitingHndShkBeforeSendData() const { return (fCommSendData<0) && ((fCommSendData & kHnShBefSendDat)!=0); } bool IsSendingFilesRunSeqList() const { return (fCommSendData<0) && ((fCommSendData & kSendRunSeqList)!=0); } bool IsStatusSendingConfig() const { return (fCommSendData<0) && ((fCommSendData & kStatSendConf)!=0); } bool IsStatusSendingTrigTimes() const { return (fCommSendData<0) && ((fCommSendData & kStatSendTrgTim)!=0); } bool IsStatusSendingPowerReading() const { return (fCommSendData<0) && ((fCommSendData & kStatSendPwrDat)!=0); } bool IsStatusSendingEvent() const { return (fCommSendData<0) && ((fCommSendData & kStatSendEvent)!=0); } bool IsStatusSendingHeartbeat() const { return (fCommSendData<0) && ((fCommSendData & kStatSendHtbt)!=0); } bool IsStatusSendingTemperature() const { return (fCommSendData<0) && ((fCommSendData & kStatSendTmpDat)!=0); } uint8_t GetPowerMode() const { return fPowerMode; } int GetPowPinSetting(const EPowerModeBit p, const bool isOn) const { #if CHIPBOARD==ATWD4CH if (p==kCardDatTak || p==kCardComWin || p==kAmpsDatTak || p==kAmpsComWin) { return isOn ? 0 : 1; } else { return isOn ? 1 : 0; } #else return isOn ? 1 : 0; #endif } int GetPowPinSetting(const EPowerModeBit p) const { // return int to correspond to what DigitalOut::operator= expects return GetPowPinSetting(p, IsPoweredFor(p)); } 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; uint32_t GetTimeoutTime(const uint32_t startTime, const uint32_t delta) 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 static bool IsIOversionOk(const uint8_t rv) { return (kIOVers == rv); } template<class T> static uint8_t PeekIOversion(T& b) { // the buffer/file/whatever 'b' must be at the start of the config frame uint8_t Rv=0; SnBitUtils::ReadFrom(b, Rv); return Rv; } 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 ( IsIOversionOk(Rv) ) { if (IsLowPowerMode()) { // the low power bit is not streamed, so we need to // reset it explicitly ChangeToNormPower(); } if (Rv<11) { uint32_t llen=kConfLblLen; b = SnBitUtils::ReadFrom(b, llen); #ifdef DEBUG printf("llen=%u\r\n",llen); #endif b = SnBitUtils::ReadFrom(b, fLabel, llen); } else { b = SnBitUtils::ReadFrom(b, fLabel, kConfLblLen); } #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 if (Rv>7) { b = SnBitUtils::ReadFrom(b, fFirstSeq); } else { uint32_t fe(0); fFirstSeq = 0; b = SnBitUtils::ReadFrom(b, fe); } #ifdef DEBUG printf("firstseq=%hu\r\n",fFirstSeq); #endif if (Rv>1) { if (Rv<11) { uint32_t eps(0); b = SnBitUtils::ReadFrom(b, eps); fEvtsPerSeq = (1<<sizeof(fEvtsPerSeq))-1; // biggest value if ( eps < fEvtsPerSeq ) { fEvtsPerSeq = eps; } } else { b = SnBitUtils::ReadFrom(b, fEvtsPerSeq); } if (Rv<11) { uint8_t rm(0); b = SnBitUtils::ReadFrom(b, rm); fRunMode = rm; } else { b = SnBitUtils::ReadFrom(b, fRunMode); } } else { fEvtsPerSeq = 1000; fRunMode = 0; } #ifdef DEBUG printf("eps=%hu\r\n",fEvtsPerSeq); printf("rm=%hu\r\n",fRunMode); #endif #if CHIPBOARD==ATWD4CH if ( IsIOversForATWD(Rv) && Rv<11 ) { b = SnBitUtils::ReadFrom(b, fStreamHiLoPlas); #ifdef DEBUG printf("shilo=%d\r\n",(int)fStreamHiLoPlas); #endif } #endif // ATWD4CH 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 if (Rv<11) { b = SnBitUtils::ReadFrom(b, fDatPackType); #ifdef DEBUG printf("dp=%hhu\r\n",fDatPackType); #endif } uint16_t* dc = &(fDAC[0][0]); const uint8_t ntotdacs = GetTotDacsForIOVers(Rv); #ifdef DEBUG printf("ntotdacs=%hhu\r\n",ntotdacs); #endif for (uint16_t i=0; i<ntotdacs; i++, dc++) { b = SnBitUtils::ReadFrom(b, *dc); #ifdef DEBUG printf("dac[%hu]=%hu\r\n",i,*dc); #endif } #if CHIPBOARD==ATWD4CH if ( IsIOversForATWD(Rv) ) { 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 } } #endif // ATWD4CH b = SnBitUtils::ReadFrom(b, fNumCardsMajLog); #ifdef DEBUG printf("mj=%hhu\r\n",fNumCardsMajLog); #endif if (Rv<11) { uint8_t e(0); b = SnBitUtils::ReadFrom(b, e); fEnableThermTrig = e; } else { b = SnBitUtils::ReadFrom(b, fEnableThermTrig); } #ifdef DEBUG printf("thm=%d\r\n",(int)fEnableThermTrig); #endif if (Rv>3) { b = SnBitUtils::ReadFrom(b, fForceTrigPeriod); } else { uint16_t ftrg(0); b = SnBitUtils::ReadFrom(b, ftrg); fForceTrigPeriod = ftrg; } #ifdef DEBUG printf("force=%g\r\n",fForceTrigPeriod); #endif b = SnBitUtils::ReadFrom(b, fHeartBeatPeriod); #ifdef DEBUG printf("heart=%hu\r\n",fHeartBeatPeriod); #endif if (Rv<11) { uint8_t ampson(0); b = SnBitUtils::ReadFrom(b, ampson); #ifdef DEBUG printf("amps=%hhu (IGNORED)\r\n",ampson); #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 if (Rv<6) { b = SnBitUtils::ReadFrom(b, fBatVoltToLowPwr); fBatVoltFromLowPwr = 1.1*fBatVoltToLowPwr; } else { b = SnBitUtils::ReadFrom(b, fBatVoltToLowPwr); b = SnBitUtils::ReadFrom(b, fBatVoltFromLowPwr); } #ifdef DEBUG printf("batlow(to,from)=(%hu,%hu)\r\n",fBatVoltToLowPwr,fBatVoltFromLowPwr); #endif if (Rv>2) { b = SnBitUtils::ReadFrom(b, fVoltCheckPeriod); } else { fVoltCheckPeriod = 600u; } #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=%hd\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>6) { if (Rv>10) { // Irid first b = SnBitUtils::ReadFrom(b, fCommWinConnTOMins[IndexOfDataStream(kIrid)]); b = SnBitUtils::ReadFrom(b, fCommWinListTOMins[IndexOfDataStream(kIrid)]); // Afar next b = SnBitUtils::ReadFrom(b, fCommWinConnTOMins[IndexOfDataStream(kAfar)]); b = SnBitUtils::ReadFrom(b, fCommWinListTOMins[IndexOfDataStream(kAfar)]); } else { // older versions: set them all the same uint8_t cto, lto; b = SnBitUtils::ReadFrom(b, cto); b = SnBitUtils::ReadFrom(b, lto); for (uint8_t i=0; i<kNumDatStreams; ++i) { fCommWinConnTOMins[i] = cto; fCommWinListTOMins[i] = lto; } } } else { for (uint8_t i=0; i<kNumDatStreams; ++i) { fCommWinConnTOMins[i] = GetDefaultConnTOMinOf(GetDataStreamForIndex(i)); fCommWinListTOMins[i] = GetDefaultListTOMinOf(GetDataStreamForIndex(i)); } } #ifdef DEBUG for (uint8_t i=0; i<kNumDatStreams; ++i) { printf("data stream %hhu (%s): connectTO=%hhu, listenTO=%hhu\r\n", i, GetDataStreamNameOfIdx(i), fCommWinConnTOMins[i], fCommWinListTOMins[i]); } #endif if (Rv>2) { if (Rv<11) { b = SnBitUtils::ReadFrom(b, fRemoteServer, kIPLen); } else { // read the numerical value and convert to string uint32_t rip(0); b = SnBitUtils::ReadFrom(b, rip); GetIpStrFromVal(rip, fRemoteServer); } if (strncmp(fRemoteServer, kDefIPflag,kIPLen)==0) { SetDefaultRemoteServ(); } #ifdef DEBUG printf("rserv=%s\r\n",fRemoteServer); #endif b = SnBitUtils::ReadFrom(b, fRemotePort); if (fRemotePort==0) { SetDefaultRemotePort(); } #ifdef DEBUG printf("rport=%hu\r\n",fRemotePort); #endif if (Rv<11) { b = SnBitUtils::ReadFrom(b, fMbedIP, kIPLen); } else { // read the numerical value and convert to string uint32_t rip(0); b = SnBitUtils::ReadFrom(b, rip); GetIpStrFromVal(rip, fMbedIP); } if (strncmp(fMbedIP, kDefIPflag,kIPLen)==0) { SetDefaultMbedIP(); } #ifdef DEBUG printf("mbedip=%s\r\n",fMbedIP); #endif if (Rv<11) { b = SnBitUtils::ReadFrom(b, fMbedMask, kIPLen); } else { // read the numerical value and convert to string uint32_t rip(0); b = SnBitUtils::ReadFrom(b, rip); GetIpStrFromVal(rip, fMbedMask); } if (strncmp(fMbedMask, kDefIPflag,kIPLen)==0) { SetDefaultMaskIP(); } #ifdef DEBUG printf("mbedmask=%s\r\n",fMbedMask); #endif if (Rv<11) { b = SnBitUtils::ReadFrom(b, fMbedGate, kIPLen); } else { // read the numerical value and convert to string uint32_t rip(0); b = SnBitUtils::ReadFrom(b, rip); GetIpStrFromVal(rip, fMbedGate); } if (strncmp(fMbedGate, kDefIPflag,kIPLen)==0) { SetDefaultGateIP(); } #ifdef DEBUG printf("mbedgate=%s\r\n",fMbedGate); #endif } else { SetDefaultIPs(); } b = SnBitUtils::ReadFrom(b, fWatchDogPeriod); #ifdef DEBUG printf("watch=%u\r\n",fWatchDogPeriod); #endif #if CHIPBOARD==SST4CH if ( (IsIOversForATWD(Rv)==false) && (Rv>9) ) { b = SnBitUtils::ReadFrom(b, fTempCheckPeriod); } #ifdef DEBUG printf("temp check period=%hhd\r\n", fTempCheckPeriod); #endif #endif if (Rv>10) { b = SnBitUtils::ReadFrom(b, fSnglFreqRatio); #ifdef DEBUG printf("single freq ratio=%hhd\r\n", fSnglFreqRatio); #endif b = SnBitUtils::ReadFrom(b, fL1Scaledown); #ifdef DEBUG printf("L1 scaledown=%hhd\r\n", fL1Scaledown); #endif } #if CHIPBOARD==ATWD4CH if ( IsIOversForATWD(Rv) ) { 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 } } } #endif // ATWD4CH } else { // trying to read an invalid config version #ifdef DEBUG printf("Cannot accept config version [%hhu]. " "Expect [%hhu].",Rv,SnConfigFrame::kIOVers); #endif } if (fgApplySafetyNets) { ApplySafetyNets(); } // reset the SD card init cache, in case the SD ignore run mode changed SetSDNeedToInitFlag(); #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 b = SnBitUtils::WriteTo(b, kIOVers); // i/o version // first write the label, then explicitly write the trailing \0 // so it's for sure always there /* legacy code when io vers < 11 // account for the ending \0 uint32_t llen = strlen(fLabel); static const uint32_t maxllen = kConfLblLen-1; if (llen > maxllen) { llen = maxllen; } b = SnBitUtils::WriteTo(b, llen+1); // strlen + \0 b = SnBitUtils::WriteTo(b, fLabel, llen); */ b = SnBitUtils::WriteTo(b, fLabel, kConfLblLenNoStrTerm); b = SnBitUtils::WriteTo(b, char('\0')); b = SnBitUtils::WriteTo(b, fConfTime); b = SnBitUtils::WriteTo(b, fRun); b = SnBitUtils::WriteTo(b, fFirstSeq); b = SnBitUtils::WriteTo(b, fEvtsPerSeq); // changed to uint16 with V11+ b = SnBitUtils::WriteTo(b, fRunMode); // changed to uint16 with V11+ /* - the option is no longer written to the config #if CHIPBOARD==ATWD4CH if ( IsIOversForATWD(kIOVers) ) { b = SnBitUtils::WriteTo(b, fStreamHiLoPlas); } #endif */ b = SnBitUtils::WriteTo(b, fWvLoseLSB); b = SnBitUtils::WriteTo(b, fWvLoseMSB); b = SnBitUtils::WriteTo(b, fWvBaseline); //b = SnBitUtils::WriteTo(b, fDatPackType); // removed vers 11+ const uint16_t* dc = &(fDAC[0][0]); const uint8_t ntotdacs = GetTotDacsForIOVers(kIOVers); for (uint16_t i=0; i<ntotdacs; i++, dc++) { b = SnBitUtils::WriteTo(b, *dc); } #if CHIPBOARD==ATWD4CH if ( IsIOversForATWD(kIOVers) ) { 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); } } #endif b = SnBitUtils::WriteTo(b, fNumCardsMajLog); b = SnBitUtils::WriteTo(b, fEnableThermTrig); // 16 bits in vers 11+ b = SnBitUtils::WriteTo(b, fForceTrigPeriod); b = SnBitUtils::WriteTo(b, fHeartBeatPeriod); //b = SnBitUtils::WriteTo(b, fAmpsOn); removed vers 11+ b = SnBitUtils::WriteTo(b, fEvtThrtlPeriodMs); b = SnBitUtils::WriteTo(b, fPowerMode); b = SnBitUtils::WriteTo(b, fBatVoltToLowPwr); b = SnBitUtils::WriteTo(b, fBatVoltFromLowPwr); 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); // vers 11+, separate conn/listen timeouts for Irid and Afar b = SnBitUtils::WriteTo(b, fCommWinConnTOMins[IndexOfDataStream(kIrid)]); b = SnBitUtils::WriteTo(b, fCommWinListTOMins[IndexOfDataStream(kIrid)]); b = SnBitUtils::WriteTo(b, fCommWinConnTOMins[IndexOfDataStream(kAfar)]); b = SnBitUtils::WriteTo(b, fCommWinListTOMins[IndexOfDataStream(kAfar)]); // with vers 11+, the numerical values are stored instead of strings (saves many bytes) b = SnBitUtils::WriteTo(b, GetIpValFromStr(fRemoteServer) ); b = SnBitUtils::WriteTo(b, fRemotePort); b = SnBitUtils::WriteTo(b, GetIpValFromStr(fMbedIP) ); b = SnBitUtils::WriteTo(b, GetIpValFromStr(fMbedMask) ); b = SnBitUtils::WriteTo(b, GetIpValFromStr(fMbedGate) ); b = SnBitUtils::WriteTo(b, fWatchDogPeriod); #if CHIPBOARD==SST4CH if ( (IsIOversForATWD(kIOVers)==false) && (kIOVers>9) ) { b = SnBitUtils::WriteTo(b, fTempCheckPeriod); } #endif b = SnBitUtils::WriteTo(b, fSnglFreqRatio); // with vers 11+ b = SnBitUtils::WriteTo(b, fL1Scaledown); // with vers 11+ #if CHIPBOARD==ATWD4CH if ( IsIOversForATWD(kIOVers) ) { if (fStreamHiLoPlas!=0) { const uint16_t* pl = &(fPLA[0]); 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); } } } #endif } bool ReadFromFile(const char* cfile); bool WriteToFile(const char* cfile) const; void Reset() { memset(fLabel, 0, sizeof(char)*kConfLblLen); SetHardDefaults(); #ifdef USE_INTERFACE_CHIP if (ReadFromFile(kDefConfFile)==false) { // couldn't get default. use hardcoded version. // (reset in case a few parameters from the file // got assigned) SetHardDefaults(); } #endif #ifdef DEBUG printf("config reset to %s\r\n",fLabel); #endif } uint32_t SizeOf(const uint8_t rv=SnConfigFrame::kIOVers) 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 if rv<11 const uint8_t lbllen = (rv<11) ? strlen(fLabel) : kConfLblLen; #if CHIPBOARD==ATWD4CH return SizeOf(rv, fStreamHiLoPlas!=0, fNumPlas, lbllen); #else // SST return SizeOf(rv, false, 0, lbllen); #endif } 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); static void GetIpStrFromVal(const uint32_t ip, char(& str)[kIPLen]); static uint32_t GetIpValFromStr(const char(& str)[kIPLen]); static EDatPackBit GetDataStreamForIndex(const uint8_t idx) { switch (idx) { case 0: return kSDcard; case 1: return kIrid; case 2: return kAfar; case 3: return kUSB; default: #ifdef DEBUG printf("**** unknown stream idx [%hhu]", idx); #endif return kSDcard; }; } static uint8_t IndexOfDataStream(const SnConfigFrame::EDatPackBit b) { switch (b) { case kSDcard: return 0u; case kIrid: return 1u; case kAfar: return 2u; case kUSB: return 3u; default: #ifdef DEBUG printf("**** unknown stream bit [%u]", static_cast<uint32_t>(b)); #endif return 0; }; } static uint8_t GetDefaultConnTOMinOf(const SnConfigFrame::EDatPackBit b) { switch (b) { case kSDcard: return 1u; case kIrid: return 3u; case kAfar: return 1u; case kUSB: return 1u; default: #ifdef DEBUG printf("**** unknown stream big [%u]", static_cast<uint32_t>(b)); #endif return 3u; }; } static uint8_t GetDefaultListTOMinOf(const SnConfigFrame::EDatPackBit b) { return GetDefaultConnTOMinOf(b); } static const char* GetDataStreamName(const SnConfigFrame::EDatPackBit b) { switch (b) { case kSDcard: return "SDcard"; case kIrid: return "Iridium"; case kAfar: return "Afar"; case kUSB: return "USB"; default: #ifdef DEBUG printf("**** unknown stream bit [%u]", static_cast<uint32_t>(b)); #endif return NULL; }; } static const char* GetDataStreamNameOfIdx(const uint8_t idx) { switch (idx) { case 0u: return GetDataStreamName(kSDcard); case 1u: return GetDataStreamName(kIrid); case 2u: return GetDataStreamName(kAfar); case 3u: return GetDataStreamName(kUSB); default: #ifdef DEBUG printf("**** unknown stream index [%hhu]", idx); #endif return NULL; }; } }; #endif // SN_SnConfigFrame