Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
SnConfigFrame.cpp
- Committer:
- uci1
- Date:
- 2015-02-23
- Revision:
- 80:5440d12fc155
- Parent:
- 79:97c650d58640
- Child:
- 81:6667e2adb926
File content as of revision 80:5440d12fc155:
#include "SnConfigFrame.h" #include "mbed.h" //#define DEBUG #include "SnBitUtils.h" #include "SnHeaderFrame.h" #include "Watchdog.h" #include "SnSDUtils.h" extern "C" void mbed_mac_address(char *); bool SnConfigFrame::fgApplySafetyNets = true; #if CHIPBOARD==ATWD4CH const uint8_t SnConfigFrame::kIOVers = 8; #else // SST const uint8_t SnConfigFrame::kIOVers = 10; #endif #ifdef USE_INTERFACE_CHIP const char* const SnConfigFrame::kDefConfFile = "/local/DEFCONF.DAT"; const char* const SnConfigFrame::kDefRemIpFilen = "/local/REMOTIP.TXT"; const char* const SnConfigFrame::kDefRemPortFilen = "/local/REMOTPRT.TXT"; const char* const SnConfigFrame::kDefMbedIPFilen = "/local/MBEDIP.TXT"; const char* const SnConfigFrame::kDefMbedMaskFilen = "/local/MBEDMASK.TXT"; const char* const SnConfigFrame::kDefMbedGateFilen = "/local/MBEDGATE.TXT"; #endif 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]; // NOTE: the function below may not be the one provided by MBED! // see main.cpp 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); } #ifdef DEBUG printf("MAC=%012llX\r\n", fgMacAdr>>16); // 64 -> 48 bits #endif } void SnConfigFrame::SetHardDefaults() { sprintf(fLabel,"Stn10HardDefR80"); fConfTime = 1338854400u; // Tue, 05 Jun 2012 00:00:00 GMT fRun = 0; fFirstSeq = 0; fEvtsPerSeq = 300; #if CHIPBOARD==ATWD4CH fRunMode = kRSListOneCW; fStreamHiLoPlas = 0; #else // not ATWD4CH fRunMode = kDualThreshBit | kDiffTrigBit | kRSListOneCW; #endif fWvLoseLSB = 0; fWvLoseMSB = 4; fWvBaseline = 0; fDatPackType = kSDcard | kIrid | kAfar | kUSB; uint16_t* dc = &(fDAC[0][0]); for (uint16_t i=0; i<kTotDacs; i++, dc++) { *dc = 3072u; } #if CHIPBOARD==ATWD4CH fNumPlas = 1; uint16_t* pl = &(fPLA[0]); for (uint8_t j=0; j<kNplas; j++, pl++) { *pl = 0x7FFFu; } #endif fNumCardsMajLog = 2; fEnableThermTrig = 0; fForceTrigPeriod = 0; fHeartBeatPeriod = 0; fAmpsOn = 0x0Fu; fEvtThrtlPeriodMs = 0; fPowerMode = kIridComWin | kAfarComWin; fBatVoltToLowPwr = 0; fBatVoltFromLowPwr = 0; fVoltCheckPeriod = 127u; fCommWinPeriod = 600u; fCommWinDuration = 600u; fCommSendData = static_cast<int16_t>(kUseBits); fCommWinPrdLowPwr = 86100u; fCommWinDurLowPwr = 300u; fCommWinConnectTOMin = 3u; fCommWinListenTOMin = 3u; fWatchDogPeriod = WDFAILSAFE; #if CHIPBOARD==ATWD4CH fTempCheckPeriod = 0; #else // not ATWD4CH fTempCheckPeriod = -8; #endif SetDefaultIPs(); fIsLowPower = false; memcpy(fNormLabel, fLabel, kConfLblLen); fNormPowerMode = fPowerMode; ApplyConnectListenSafetyNets(); } void SnConfigFrame::SetDefaultRemoteServ() { if (false==ReadDefaultRemoteServer()) { sprintf(fRemoteServer,"%s","128.195.204.151"); } } void SnConfigFrame::SetDefaultRemotePort() { if (false==ReadDefaultRemotePort()) { fRemotePort = 6655; } } void SnConfigFrame::SetDefaultMbedIP() { // see ReadDefaultIPFile // // these hardcoded defaults are only here // "in case". they make it difficult/impossible // to swap boards in the field without internet // access to change the mbed program const uint64_t ip = GetMacAddress(); if (false==ReadDefaultMbedIP()) { switch (ip) { case 0x0002F7F0AEE00000: // stn 20, atwd mb 1 sprintf(fMbedIP,"%s","157.132.94.30"); break; case 0x0002F7F2244B0000: // stn 13, board 102 sprintf(fMbedIP,"%s","157.132.94.31"); break; case 0x0002F7F20A9C0000: // stn 14, board 104 sprintf(fMbedIP,"%s","157.132.94.33"); break; case 0x0002F7F21A8A0000: // board 111 sprintf(fMbedIP,"%s","157.132.94.34"); break; case 0x0002F7F0C3B60000: // station 3, atwd mb 5 sprintf(fMbedIP,"%s","157.132.94.35"); break; case 0x0002F7F0C41C0000: // station 4 case 0x0002F7F1F7A80000: // stn 15, board 110 sprintf(fMbedIP,"%s","157.132.94.37"); break; case 0x0002F7F0C61A0000: // station 10, atwd mb 8 sprintf(fMbedIP,"%s","157.132.94.39"); break; case 0x0002F7F0C4450000: // station 6 case 0x0002F7F1E9ED0000: // board 108 case 0x0002F7F224440000: // stn 19, board 105 sprintf(fMbedIP,"%s","157.132.94.41"); break; case 0x0002F7F175B70000: // station 11 case 0x0002F7F1F2120000: // board 113 case 0x0002F7F202C10000: // stn 17, board 109 sprintf(fMbedIP,"%s","157.132.94.43"); break; default: // what?? sprintf(fMbedIP,"%s","157.132.94.45"); // usually for tent break; }; } } // brian dornick 3107 void SnConfigFrame::SetDefaultMaskIP() { if (false==ReadDefaultMbedMask()) { sprintf(fMbedMask,"%s","255.255.255.0"); } } void SnConfigFrame::SetDefaultGateIP() { if (false==ReadDefaultMbedGate()) { sprintf(fMbedGate,"%s","157.132.94.1"); } } #ifdef USE_INTERFACE_CHIP bool SnConfigFrame::ReadOneIPFrom(const char* ipfname, char* ipstr) { bool ok = false; FILE* ipf = fopen(ipfname, "r"); if (ipf!=0) { uint8_t ipbytes[4] = {0,0,0,0}; const int nr = fscanf(ipf,"%hhu.%hhu.%hhu.%hhu\n", &(ipbytes[0]), &(ipbytes[1]), &(ipbytes[2]), &(ipbytes[3])); if (4==nr) { const int nc = sprintf(ipstr,"%hhu.%hhu.%hhu.%hhu", ipbytes[0], ipbytes[1], ipbytes[2], ipbytes[3]); ok = nc>0; } fclose(ipf); } #ifdef DEBUG printf("ReadOneIPInto : ipstr=[%s], ok=%d\r\n", ipstr, (int)ok); #endif return ok; } #endif bool SnConfigFrame::ReadDefaultRemoteServer() { #ifdef USE_INTERFACE_CHIP const bool ok = ReadOneIPFrom(kDefRemIpFilen, fRemoteServer); #ifdef DEBUG printf("remote = %s\r\n", fRemoteServer); #endif return ok; #else // do not USE_INTERFACE_CHIP return false; #endif // USE_INTERFACE_CHIP } bool SnConfigFrame::ReadDefaultRemotePort() { #ifdef USE_INTERFACE_CHIP bool ok = false; FILE* pf = fopen(kDefRemPortFilen, "r"); if (pf!=0) { ok = (1==fscanf(pf, "%hu\n", &fRemotePort)); fclose(pf); } #ifdef DEBUG printf("port = %hu\r\n", fRemotePort); #endif return ok; #else // do not USE_INTERFACE_CHIP return false; #endif // USE_INTERFACE_CHIP } bool SnConfigFrame::ReadDefaultMbedIP() { #ifdef USE_INTERFACE_CHIP const bool ok = ReadOneIPFrom(kDefMbedIPFilen, fMbedIP); #ifdef DEBUG printf("mbed = %s\r\n", fMbedIP); #endif return ok; #else // do not USE_INTERFACE_CHIP return false; #endif // USE_INTERFACE_CHIP } bool SnConfigFrame::ReadDefaultMbedMask() { #ifdef USE_INTERFACE_CHIP const bool ok = ReadOneIPFrom(kDefMbedMaskFilen, fMbedMask); #ifdef DEBUG printf("mask = %s\r\n", fMbedMask); #endif return ok; #else // do not USE_INTERFACE_CHIP return false; #endif // USE_INTERFACE_CHIP } bool SnConfigFrame::ReadDefaultMbedGate() { #ifdef USE_INTERFACE_CHIP const bool ok = ReadOneIPFrom(kDefMbedGateFilen, fMbedGate); #ifdef DEBUG printf("gate = %s\r\n", fMbedGate); #endif return ok; #else // do not USE_INTERFACE_CHIP return false; #endif // USE_INTERFACE_CHIP } void SnConfigFrame::SetDefaultIPs() { GetMacAddress(); // just to make sure it gets read SetDefaultRemoteServ(); SetDefaultRemotePort(); SetDefaultMbedIP(); SetDefaultMaskIP(); SetDefaultGateIP(); } void SnConfigFrame::ApplyConnectListenSafetyNets() { if (fCommWinConnectTOMin<kDefTimeoutMin) { fCommWinConnectTOMin=kDefTimeoutMin; } if (fCommWinConnectTOMin>(fCommWinDuration/(60.*static_cast<float>(kNcomms)))) { fCommWinConnectTOMin=kDefTimeoutMin; } if (fCommWinListenTOMin<kDefTimeoutMin) { fCommWinListenTOMin=kDefTimeoutMin; } if (fCommWinListenTOMin>(fCommWinDuration/(60.*static_cast<float>(kNcomms)))) { fCommWinListenTOMin=kDefTimeoutMin; } } void SnConfigFrame::ApplySafetyNets() { if (fFirstSeq>kMaxFirstSeq) { fFirstSeq=kMaxFirstSeq; } #if CHIPBOARD==ATWD4CH if (fNumPlas>kNplas) { fNumPlas=kNplas; } #endif 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 ( IsSBDonlyLowPwrMode() ) { EnablePowerFor(kIridComWin); DisablePowerFor(kAfarComWin); } else if ( (IsPoweredFor(kIridComWin)==false) && (IsPoweredFor(kAfarComWin)==false) ) { // TODO: turn on only iridum maybe? EnablePowerFor(kIridComWin); EnablePowerFor(kAfarComWin); } // else same as normal for Irid and Afar Com Win // 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); } */ #ifdef DEBUG printf("trying to read config [%s]\r\n",cfile); #endif bool ret = false; FILE* cf = fopen(cfile,"rb"); if (cf!=0) { #ifdef DEBUG printf("opened file\r\n"); #endif // check the header and file size to be // protect a bit against corruption uint8_t hc; uint32_t hl; SnHeaderFrame::ReadFrom(cf, hc, hl); #ifdef DEBUG printf("hc=%hhu, hl=%u\r\n",hc,hl); #endif 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 #ifdef DEBUG printf("fend-fpos=%d-%d=%d\r\n",fend,fpos,fend-fpos); #endif if (hl == fend-fpos) { ReadFrom(cf); ret = (ferror(cf)==0); #ifdef DEBUG printf("ret = %d\r\n",(int)ret); #endif } } 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; } void SnConfigFrame::SetSDNeedToInitFlag() { // reset the SD card init cache, in case the SD ignore run mode changed SnSDUtils::SetDoNeedToInit(); }