Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
SnConfigFrame.cpp
- Committer:
- uci1
- Date:
- 2013-10-05
- Revision:
- 40:1324da35afd4
- Parent:
- 39:2f17131d22a5
- Child:
- 53:9cc158391bea
File content as of revision 40:1324da35afd4:
#include "SnConfigFrame.h" #include "mbed.h" #include "SnBitUtils.h" #include "SnHeaderFrame.h" #include "Watchdog.h" extern "C" void mbed_mac_address(char *); bool SnConfigFrame::fgApplySafetyNets = true; const uint8_t SnConfigFrame::kIOVers = 8; const char* const SnConfigFrame::kDefConfFile = "/local/DEFCONF.DAT"; const char* const SnConfigFrame::kDefIPflag = "DEF"; const uint32_t SnConfigFrame::kMinCommWinPrdLowPwr = 14400; // exclusive min low power comm win period (s) const uint32_t SnConfigFrame::kMaxCommWinPrdLowPwr = 259200; // exclusive max low power comm win period (s) const uint32_t SnConfigFrame::kMinCommWinDurLowPwr = 300; // exclusive min low power comm win duration (s) const uint32_t SnConfigFrame::kMaxCommWinDurLowPwr = 3600; // exclusive max low power comm win duration (s) const uint8_t SnConfigFrame::kConfLblLen; uint64_t SnConfigFrame::fgMacAdr = 0; void SnConfigFrame::SetMacAddress() { static const uint8_t b64 = sizeof(uint64_t); static char c[b64]; mbed_mac_address(&(c[0])); // like a big endian union fgMacAdr = 0; const char* a = c+(b64-1); for (uint8_t i=0; i<b64; i++, a--) { fgMacAdr |= static_cast<uint64_t>(*a) << (i<<3); } } void SnConfigFrame::SetHardDefaults() { sprintf(fLabel,"HardDefaults"); fConfTime = 1338854400u; // Tue, 05 Jun 2012 00:00:00 GMT fRun = 0; fFirstSeq = 0; fEvtsPerSeq = 1000; fRunMode = 0; fStreamHiLoPlas = 0; fWvLoseLSB = 0; fWvLoseMSB = 4; fWvBaseline = 0; fDatPackType = ~0; uint16_t* dc = &(fDAC[0][0]); for (uint16_t i=0; i<kTotDacs; i++, dc++) { *dc = 3072u; } fNumPlas = 1; uint16_t* pl = &(fPLA[0]); for (uint8_t j=0; j<kNplas; j++, pl++) { *pl = 0x7FFFu; } fNumCardsMajLog = 2; fEnableThermTrig = 1; fForceTrigPeriod = 67u; fHeartBeatPeriod = 0; fAmpsOn = 0x0Fu; fEvtThrtlPeriodMs = 50u; fPowerMode = kAmpsDatTak|kCardDatTak|kAmpsComWin|kCardComWin|kIridComWin|kAfarComWin; fBatVoltToLowPwr = 0; fBatVoltFromLowPwr = 0; fVoltCheckPeriod = 600u; fCommWinPeriod = 3600u; fCommWinDuration = 600u; fCommSendData = static_cast<int16_t>(kUseBits); fCommWinPrdLowPwr = 86100u; fCommWinDurLowPwr = 300u; fCommWinConnectTOMin = 3u; fCommWinListenTOMin = 3u; fWatchDogPeriod = WDFAILSAFE; SetDefaultIPs(); fIsLowPower = false; memcpy(fNormLabel, fLabel, kConfLblLen); fNormPowerMode = fPowerMode; } void SnConfigFrame::SetDefaultRemoteServ() { sprintf(fRemoteServer,"%s","128.195.204.151"); } void SnConfigFrame::SetDefaultRemotePort() { fRemotePort = 6655; } void SnConfigFrame::SetDefaultMbedIP() { const uint64_t ip = GetMacAddress(); switch (ip) { case 0x0002F7F0C3B60000: // station 3 sprintf(fMbedIP,"%s","157.132.94.35"); break; case 0x0002F7F0C41C0000: // station 4 sprintf(fMbedIP,"%s","157.132.94.37"); break; case 0x0002F7F0AEE00000: // station 5 sprintf(fMbedIP,"%s","157.132.94.39"); break; case 0x0002F7F0C4450000: // station 6 sprintf(fMbedIP,"%s","157.132.94.41"); break; case 0x0002F7F0D2880000: // station 7 sprintf(fMbedIP,"%s","157.132.94.43"); break; case 0x0002F7F0C0F80000: // station 8 sprintf(fMbedIP,"%s","157.132.94.45"); break; default: // what?? sprintf(fMbedIP,"%s","157.132.94.30"); // anciet station break; }; } // brian dornick 3107 void SnConfigFrame::SetDefaultMaskIP() { sprintf(fMbedMask,"%s","255.255.255.0"); } void SnConfigFrame::SetDefaultGateIP() { sprintf(fMbedGate,"%s","157.132.94.1"); } void SnConfigFrame::SetDefaultIPs() { SetDefaultRemoteServ(); SetDefaultRemotePort(); SetDefaultMbedIP(); SetDefaultMaskIP(); SetDefaultGateIP(); } void SnConfigFrame::ApplyConnectListenSafetyNets() { if (fCommWinConnectTOMin<kDefTimeoutMin) { fCommWinConnectTOMin=kDefTimeoutMin; } if (fCommWinConnectTOMin>(fCommWinDuration/static_cast<float>(kNcomms))) { fCommWinConnectTOMin=kDefTimeoutMin; } if (fCommWinListenTOMin<kDefTimeoutMin) { fCommWinListenTOMin=kDefTimeoutMin; } if (fCommWinListenTOMin>(fCommWinDuration/static_cast<float>(kNcomms))) { fCommWinListenTOMin=kDefTimeoutMin; } } void SnConfigFrame::ApplySafetyNets() { if (fFirstSeq>kMaxFirstSeq) { fFirstSeq=kMaxFirstSeq; } if (fNumPlas>kNplas) { fNumPlas=kNplas; } if (fNumCardsMajLog>kNchans) { fNumCardsMajLog=kNchans; } if (fNumCardsMajLog<1u) { fNumCardsMajLog=1u; } if ( (fForceTrigPeriod>0) && (fForceTrigPeriod<kMinForcePer) ) { fForceTrigPeriod = kMinForcePer; } if (fEvtThrtlPeriodMs>kMaxThrottlePerMs) { fEvtThrtlPeriodMs=kMaxThrottlePerMs; } if ( (IsPoweredFor(kIridComWin)==false) && (IsPoweredFor(kAfarComWin)==false) ) { EnablePowerFor(kIridComWin); EnablePowerFor(kAfarComWin); } if (fBatVoltToLowPwr>kMaxBatVoltLowPwr) { fBatVoltToLowPwr=kMaxBatVoltLowPwr; } if (fBatVoltFromLowPwr>kMaxBatVoltLowPwr) { fBatVoltFromLowPwr=kMaxBatVoltLowPwr; } if (fBatVoltFromLowPwr<fBatVoltToLowPwr) { fBatVoltFromLowPwr=fBatVoltToLowPwr; } if (fCommWinPeriod>kMaxCommWinPeriod) { fCommWinPeriod=kMaxCommWinPeriod; } if (fCommWinPeriod<kMinCommWinPeriod) { fCommWinPeriod=kMinCommWinPeriod; } if (fCommWinDuration<kMinCommWinDur) { fCommWinDuration=kMinCommWinDur; } if (fCommWinPrdLowPwr>kMaxCommWinPeriod) { fCommWinPrdLowPwr=kMaxCommWinPeriod; } if (fCommWinDurLowPwr<kMinCommWinDur) { fCommWinDurLowPwr=kMinCommWinDur; } ApplyConnectListenSafetyNets(); if (fWatchDogPeriod>kMaxWatchDogPer) { fWatchDogPeriod=kMaxWatchDogPer; } if (fWatchDogPeriod<kMinWatchDogPer) { fWatchDogPeriod=kMinWatchDogPer; } } uint32_t SnConfigFrame::GetTimeoutTime(const uint32_t startTime, const uint32_t delta) const { // --.-----lst------.--delta--.-- // . . . // start current returnVal // // lio=lst+delta bound by comm wind dur // returns start + lio const uint32_t ct = time(0); uint32_t lst = ct-startTime; if ( (ct<startTime) || (ct==0) || (lst>kSecsPerDay) ) { // possible clock problems lst = static_cast<uint32_t>(kDefTimeoutMin)*60u; } const uint32_t lio = ((lst+delta) < GetCommWinDuration()) ? lst+delta : GetCommWinDuration(); return lio+startTime; } void SnConfigFrame::ChangeToLowPower() { // save old label memcpy(fNormLabel, fLabel, kConfLblLen); // append label // this will allow the new config to be put in the DB int slen = strlen(fLabel); static const char* tag = "_LOWPOW"; const int ml = strlen(tag)+1; if (slen > (kConfLblLen-ml) ) { memset(fLabel+kConfLblLen-ml, '\0', ml); } strncat(fLabel, tag, ml-1); // save power settings fNormPowerMode = fPowerMode; // change power settings DisablePowerFor(kAmpsDatTak); DisablePowerFor(kCardDatTak); DisablePowerFor(kIridDatTak); DisablePowerFor(kAfarDatTak); DisablePowerFor(kAmpsComWin); DisablePowerFor(kCardComWin); if ( (IsPoweredFor(kIridComWin)==false) && (IsPoweredFor(kAfarComWin)==false) ) { // TODO: turn on only iridum maybe? EnablePowerFor(kIridComWin); EnablePowerFor(kAfarComWin); } // set mode to low power fIsLowPower = true; } void SnConfigFrame::ChangeToNormPower() { // put label back memcpy(fLabel, fNormLabel, kConfLblLen); // put power settings back fPowerMode = fNormPowerMode; // set mode to normal fIsLowPower = false; } void SnConfigFrame::GetPackParsFor(const EDatPackBit d, uint8_t& loseLSB, uint8_t& loseMSB, uint16_t& wvBase) const { const bool pack = IsDatPackedFor(d); loseLSB = pack ? GetWvLoseLSB() : 0u; loseMSB = pack ? GetWvLoseMSB() : 0u; wvBase = pack ? GetWvBaseline() : 0u; } void SnConfigFrame::GetHiLoPlas(const uint16_t pla, uint16_t& hiPla, uint16_t& loPla, const bool r2l) { // split the PLA bitword into 2: one for the high threshold // and one for the low threshold. "lows" in the string will become // "highs" in the low threshold PLA. // // example 1) // PLA string = HLHL.... // hi thresh = H.H..... // lo thresh = .H.H.... // // example 2) // PLA string = HBL..... // hi thresh = HL...... // lo thresh = .LH..... // // (with . = A here, to make the example more readable) // // A = 11, B = 00 // H = 01 or 10, alternating // L = 10 or 01, alternating // 01 at leftmost bits is H // for example: // 0x7FFF = 01 11 11 11 11 11 11 11 // => HAAAAAAA for LEFT TO RIGHT // => AAAAAAAH for RIGHT TO LEFT // 0x56FF = 01 01 01 10 11 11 11 11 // => HLHHAAAA for LEFT TO RIGHT // => AAAAHHLH for RIGHT TO LEFT // // so HHHHHHHH is // 01 10 01 10 01 10 01 10 always (r2l or l2r) // // r2l = whether to read bits right to left (true) or not (false) // Mahshid liked right to left // Liang liked left to right // so we allow for either const int8_t start = (r2l) ? 0 : BITS_IN_SHORT-2; const int8_t end = (r2l) ? BITS_IN_SHORT : -2; const int8_t step = (r2l) ? 2 : -2; uint8_t hi= (r2l) ? 0x2 : 0x1; uint8_t lo= (r2l) ? 0x1 : 0x2; // set all bits to 0 hiPla = 0; loPla = 0; for (int8_t i=start; i!=end; i+=step, hi^=0x3, lo^=0x3) { const uint8_t b = (pla & (0x3<<i)) >> i; if (b==hi) { hiPla |= hi << i; loPla |= 0x3 << i; } else if (b==lo) { hiPla |= 0x3 << i; loPla |= hi << i; } else if (b==0x3) { // any hiPla |= 0x3 << i; loPla |= 0x3 << i; } else { // no check that b is something else.. should be impossible. // between hiPla |= lo << i; loPla |= lo << i; } } } bool SnConfigFrame::ReadFromFile(const char* cfile) { // intended only for reading default config file /* DIR* d; struct dirent* dent; printf("files in /local:\r\n"); if ( (d = opendir( "/local" ))!=NULL ) { while ( (dent = readdir(d))!=NULL ) { printf("%s\r\n",dent->d_name); } closedir(d); } */ bool ret = false; FILE* cf = fopen(cfile,"rb"); if (cf!=0) { // check the header and file size to be // protect a bit against corruption uint8_t hc; uint32_t hl; SnHeaderFrame::ReadFrom(cf, hc, hl); if (hc==SnHeaderFrame::kConfigCode) { const int fpos = ftell(cf); // how many bytes? fseek(cf, 0, SEEK_END); // go to end const int fend = ftell(cf); fseek(cf, fpos, SEEK_SET); // go back if (hl == fend-fpos) { ReadFrom(cf); ret = (ferror(cf)==0); } } fclose(cf); } return ret; } bool SnConfigFrame::WriteToFile(const char* cfile) const { // intended only for writing default config file bool ret = false; FILE* cf = fopen(cfile,"wb"); if (cf!=0) { WriteTo(cf); ret = (ferror(cf)==0); fclose(cf); } return ret; }