Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
Diff: main.cpp
- Revision:
- 84:80b15993944e
- Parent:
- 76:f8383f0292c2
- Child:
- 97:9f3fe603e8b5
diff -r a0d38ba9d6c2 -r 80b15993944e main.cpp --- a/main.cpp Mon Feb 23 03:04:39 2015 +0000 +++ b/main.cpp Fri Oct 30 04:49:40 2015 +0000 @@ -6,22 +6,7 @@ #include "Watchdog.h" Watchdog::SnKickStarter gKickStarter(WDFAILSAFE); -//#define DISABLE_CONFIG_SAFETYNETS - -// CHIPBOARD is defined in SnConstants.h - -#define ENABLE_AFAR_COMM -#define ENABLE_SBD_COMM -//#define ENABLE_USB_COMM -//#define ENABLE_AFAR_TWITTER - -//#define USE_RTOS // change USE_RTOS in CommConstants and EthernetPower also -//#define USE_ETH_INTERFACE -//#define EVT_TIME_PROFILE -//#define DEBUG -//#define SSNOTIFY -#define USE_MODSERIAL - +// CHIPBOARD is defined in SnPreCompOptions.h #include <stdint.h> #include "SnConstants.h" @@ -37,6 +22,10 @@ }; #endif +#ifdef DEBUG +#include "SnMemMonitor.h" +#endif + #include "SDFileSystem.h" #ifdef USE_MODSERIAL #define MODSERIAL_RX_BUF_SIZE 512 @@ -76,6 +65,7 @@ #include "RtosTimer.h" #endif // USE_RTOS_TIMER #include "DS1820.h" +#include "SnL1SingleFreqSupp.h" extern "C" void mbed_reset(); @@ -201,7 +191,30 @@ SnCommWin::ECommWinResult OpenCommWin(const bool forceReconfig=false, const bool isStartupWin=false); void MakeOutputFile(const bool stopRunning=false); -void SetPower(const bool isCommWin); +bool IsPowerAllowedFor(const bool isCommWin, + const uint8_t devicesInUse, + const SnConfigFrame::EDatPackBit b); +void SetPower(const bool isCommWin, + const uint8_t devicesInUse); +void CheckPower(const bool isCommWin, + const bool saveReading=true, + const uint8_t devicesInUse= + SnConfigFrame::kIrid | + SnConfigFrame::kAfar); +void CheckTemp(); +void UpdateTemperature(); +bool AreCardsPowered(const bool checkPin); +void GetAvePowerReading(); +#if CHIPBOARD==SST4CH +void InitTempProbe(); +#endif +void ResetCountersClearEvt(); +void CalcRate(const uint32_t numtrgs, + const double tottime_ms, + float& rate); +void GetRates(float& thmrate, float& evtrate); +void AddToRate(const double dt, const bool isThm); +bool IsSeqComplete(); void procForceTrigger(); void procHeartbeat(); void procPowerCheck(); @@ -237,6 +250,7 @@ static Timer gThmTrgTimer; static Timer gAdcToMBtimer; +static Timer gSinceClkSet; static SnClockSetFrame gClkSet; static SnSignalStrengthFrame gSigStr; #ifdef DISABLE_CONFIG_SAFETYNETS @@ -245,7 +259,7 @@ static SnConfigFrame gConf; #endif // DISABLE_CONFIG_SAFETYNETS static SnEventFrame gEvent; -static SnEventFrame gLastEvent; +//static SnEventFrame gLastEvent; static SnPowerFrame gPower; static SnTempFrame gTemperature; // parameters @@ -258,13 +272,19 @@ static volatile bool gCheckTemp = false; // if it should be checked static uint32_t gPowNum = 0; static uint32_t gEvtNum = 0; // num of evt written -static uint32_t gTrgNum[kNumTrgs] = {0}; // num of this type of trg received +static volatile bool gForcedTrig = false; // forced trigger bit +static volatile bool gAdcToMBflag = false; // flag in case getting the ADC values took too long +//static uint32_t gTrgNum[kNumTrgs] = {0}; // num of this type of trg received +static uint32_t gNumThmTrigs = 0; // number of thermal triggers counted +static uint32_t gNumFrcTrigs = 0; // number of forced triggers counted +static uint8_t gL1ScaledownCount = 0; // write an event every X L1 failures // i/o static time_t gLastCommWin = 0; // time static uint32_t gCommWinChecks = 0; static uint32_t gNcommWinChecks = 0; static uint16_t gConsecCommFails = 0; // heartbeat +static SnHeartbeatFrame gHrtbt; static time_t gLastHrtbt = 0; static volatile bool gHrtbtFired = false; static uint32_t gHrtbtNum = 0; @@ -276,16 +296,26 @@ // this should be bigger than anything that will actually be used static const uint32_t gBufSize=SnStatusFrame::kMaxSizeOf + (2u*SnHeaderFrame::kMaxSizeOf) + SnPowerFrame::kMaxSizeOf + SnEventFrame::kMaxSizeOf // (this is redundant and could be removed if mem is sparse) - + 512; // breathing room -//static const uint32_t gB64Bsize=BASE64ENC_LEN(gBufSize)+1; -//static char gB64Buf[gB64Bsize]; + + 256; // breathing room static char gGenBuf[gBufSize]; // must be big enough for event or status or config! static SnCommWin* gComms[kNcomms] = { 0 }; // order => priority. afar uses RTOS, and must be made inside main #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM) static SnCommAfarNetIfTwitter* gTwit = 0; #endif +static float gChanFFT[kNsamps] = { 0 }; // only one chan at a time to save RAM +// status update data cache and flags +static SnClockSetFrame gStTrgStartClk; +static SnClockSetFrame gStTrgStopClk; +static SnPowerFrame gStPower; +static SnTempFrame gStTemperature; +static volatile bool gStNewPower(false); +static volatile bool gStNewEvent(false); +static volatile bool gStNewHeartbeat(false); +static volatile bool gStNewTemperature(false); - +#ifdef EVT_TIME_PROFILE + Timer gProfiler; +#endif void procForceTrigger() { if (gReadingOut==false && gCommWinOpen==false) { @@ -304,8 +334,11 @@ PIN_dataReady.read()); #endif // ATWD4CH #endif - gEvent.SetTrgBit(kFrcTrg); - gEvent.SetTrgNum(++(gTrgNum[kFrcTrg])); + gForcedTrig = true; + ++gNumFrcTrigs; +// ++(gTrgNum[kFrcTrg]); +// gEvent.SetTrgBit(kFrcTrg); +// gEvent.SetTrgNum(++(gTrgNum[kFrcTrg])); //PIN_forceTrigger = 0; PIN_forceTrigger = 1; // force a trigger PIN_forceTrigger = 0; @@ -469,7 +502,8 @@ } void CheckPower(const bool isCommWin, - const bool saveReading=true) { + const bool saveReading, + const uint8_t devicesInUse) { #ifdef DEBUG printf("CheckPower\r\n"); #endif @@ -521,7 +555,7 @@ } } if (changed) { - SetPower(isCommWin); // TODO: This will fail if isCommWin==false? (currently not possible, but..) + SetPower(isCommWin, devicesInUse); // TODO: This will fail if isCommWin==false? (currently not possible, but..) #ifdef DEBUG printf("Using config %s\r\n",gConf.GetLabel()); #endif @@ -531,13 +565,16 @@ gCheckPower = false; } -void ResetCountersClearEvt() { +void ResetCounters() { const uint32_t evtStartCurSeq = (SnSDUtils::GetCurSeqNum()) // no -1; start with seq=0 * gConf.GetEvtsPerFile(); - gEvent.ClearEvent(); +// gEvent.ClearEvent(); gEvtNum = evtStartCurSeq; gPowNum = evtStartCurSeq; - memset(gTrgNum, 0, sizeof(uint32_t)*kNumTrgs); +// memset(gTrgNum, 0, sizeof(uint32_t)*kNumTrgs); + gNumThmTrigs = 0; + gNumFrcTrigs = 0; + gForcedTrig = false; // reset rate counters gThmDtSum = 0; gThmNumDt = 0; @@ -547,6 +584,12 @@ gLastHrtbt = 0; gHrtbtFired = false; gHrtbtNum = 0; + // reset status data caches + gStNewPower = false; + gStNewEvent = false; + gStNewHeartbeat = false; + gStNewTemperature = false; + #ifdef DEBUG printf("Reset: gEvtNum=%u, gPowNum=%u, evtStartCS=%u\r\n", gEvtNum, gPowNum, evtStartCurSeq); @@ -598,7 +641,7 @@ bool IsSeqComplete() { #ifdef DEBUG - printf("IsSeqComplete: eps=%u, cntpow=%d, pow=%u, evt=%u, seq=%hu\r\n", + printf("IsSeqComplete: eps=%hu, cntpow=%d, pow=%u, evt=%u, seq=%hu\r\n", gConf.GetEvtsPerFile(), (int)gConf.IsCountingPowerReadings(), gPowNum, gEvtNum, SnSDUtils::GetCurSeqNum()); #endif @@ -788,6 +831,7 @@ #ifdef DEBUG printf("Restart watchdog with time [%u] at [%u]\r\n", gConf.GetWatchdogPeriod(), time(0)); + printf("Free memory = %d\r\n", FreeMem()); #endif Watchdog::kick(gConf.GetWatchdogPeriod()); @@ -920,10 +964,16 @@ printf("my gate = %s\r\n", gConf.GetMbedGate()); printf("remote server = %s : %hu\r\n", gConf.GetRemoteServer(), gConf.GetRemotePort()); + for (uint8_t i=0; i<SnConfigFrame::kNumDatStreams; ++i) { + printf("data stream %hhu (%s): connectTO=%hhu, listenTO=%hhu\r\n", + i, SnConfigFrame::GetDataStreamNameOfIdx(i), + gConf.GetCommWinConnectTOofIdx(i), + gConf.GetCommWinListenTOofIdx(i)); + } #endif // (probably) power down comms and power up cards,amps - SetPower(false); + SetPower(false, SnConfigFrame::kIrid | SnConfigFrame::kAfar); // check power again to see if voltages drooped CheckPower(false, false); @@ -931,7 +981,17 @@ // get config // #ifdef DEBUG + printf("run mode\r\n"); + printf("IsCountingPowerReadings=%d\r\n",(int)gConf.IsCountingPowerReadings()); + printf("IsSingleSeqRunMode=%d\r\n",(int)gConf.IsSingleSeqRunMode()); + printf("IsDualThresholdMode=%d\r\n",(int)gConf.IsDualThresholdMode()); + printf("IsDifferentialTrigMode=%d\r\n",(int)gConf.IsDifferentialTrigMode()); + printf("IsSBDonlyLowPwrMode=%d\r\n",(int)gConf.IsSBDonlyLowPwrMode()); + printf("IsRunSeqListOneCommWinOnly=%d\r\n",(int)gConf.IsRunSeqListOneCommWinOnly()); + printf("IsIgnoringSDcard=%d\r\n",(int)gConf.IsIgnoringSDcard()); + printf("IsCommPowerSimple=%d\r\n",(int)gConf.IsCommPowerSimple()); printf("call OpenCommWin\r\n"); + printf("Free memory = %d\r\n", FreeMem()); #endif led2 = led1 = 0; // back to "normal" for comm win OpenCommWin(true, true); // alwasy configure, even if no new config @@ -956,6 +1016,7 @@ printf("calling wait trig\r\n"); printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false"); printf("readingout=%d\r\n",(int)gReadingOut); + printf("Free memory = %d\r\n", FreeMem()); #endif if (gFirstEvt) { #ifdef DEBUG @@ -966,6 +1027,7 @@ true); gThmTrgTimer.reset(); gThmTrgTimer.start(); gAllTrgTimer.reset(); gAllTrgTimer.start(); + gStTrgStartClk = gClkSet; #if CHIPBOARD==SST4CH // reset in case a trigger arrived before we were ready // this is mostly to ensure that the chip gets reset on soft @@ -985,9 +1047,8 @@ // PIN_readingData will be set high by SnEventFrame::ReadWaveformsSST #endif // ATWD4CH #ifdef EVT_TIME_PROFILE - Timer prof; - prof.start(); - int befReadWv=0, aftReadWv=0, befSaveEvt=0, aftSaveEvt=0, + gProfiler.start(); + int befSaveEvt=0, aftSaveEvt=0, befChkPow=0, aftChkPow=0, befNewSeq=0, aftNewSeq=0, endOfLoop=0; #endif // EVT_TIME_PROFILE @@ -997,7 +1058,8 @@ const double ttms = gThmTrgTimer.read_us() / 1e3; // for rate calculation const double atms = gAllTrgTimer.read_us() / 1e3; // for throttle - if (gEvent.IsForcedTrg()==false) { +// if (gEvent.IsForcedTrg()==false) { + if (gForcedTrig) { // don't reset if not a thermal trigger gThmTrgTimer.reset(); gThmTrgTimer.start(); } @@ -1011,73 +1073,28 @@ // // TODO: no way to check for external trigger? - if (gEvent.IsForcedTrg()==false) { - gEvent.SetTrgBit(kThmTrg); - gEvent.SetTrgNum(++(gTrgNum[kThmTrg])); + if (gForcedTrig==false) { +// ++(gTrgNum[kThmTrg]); + ++gNumThmTrigs; AddToRate(ttms, true); - } // else already set by procForceTrigger + } - if ( gEvent.IsForcedTrg() || gFirstEvt || + if ( gForcedTrig || gFirstEvt || (etms>=gConf.GetEvtThrtlPeriodMs()) ) { - - // read data & calc CRC -#ifdef EVT_TIME_PROFILE - prof.stop(); befReadWv=prof.read_us(); prof.start(); -#endif // EVT_TIME_PROFILE - -#if CHIPBOARD==ATWD4CH - // get the data to the MBED - gEvent.ReadWaveformsATWD(PIN_spi, PIN_selCardHiBit, PIN_selCardLoBit); -#else - gEvent.ReadWaveformsSST(PIN_spi, PIN_readingData); - // reset in case a trigger arrived before we were ready - PIN_ResetChips = 1; -// wait_us(1); - PIN_ResetChips = 0; -#endif //ATWD4CH - -#ifdef EVT_TIME_PROFILE - prof.stop(); aftReadWv=prof.read_us(); prof.start(); -#endif // EVT_TIME_PROFILE - - gEvent.SetCurMbedTime(); - - Watchdog::kick(); // don't reset! - -#ifdef DEBUG - printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false"); -#endif - - /* - gRecentCountTime = static_cast<uint32_t>(time(0)); - gRecentEvtNum = gEvtNum; - // do start time second so that if we get only one event, - // the delta(t) will be less than 0 and the rates not calculated - if (gDoResetLastCount) { - gLastCountReset = static_cast<uint32_t>(time(0)); // to calc rates - gLastEventReset = gEvtNum; - gDoResetLastCount = false; - } - */ - -#if CHIPBOARD==ATWD4CH - PIN_lockRegisters = 0; // done reading, unlock so we can talk to the SD card -#else - // (this is redundant; it's already set low by SnEventFrame) - PIN_readingData = 0; // done reading, unlock so we can talk to the SD card -#endif // ATWD4CH #ifdef EVT_TIME_PROFILE - prof.stop(); befSaveEvt=prof.read_us(); prof.start(); + gProfiler.stop(); befSaveEvt=gProfiler.read_us(); gProfiler.start(); #endif // EVT_TIME_PROFILE - + + // want to keep this event. save it (and check if it passes L1) SaveEvent(etms); AddToRate(etms, false); etms=0; - + #ifdef EVT_TIME_PROFILE - prof.stop(); aftSaveEvt=prof.read_us(); prof.start(); + gProfiler.stop(); aftSaveEvt=gProfiler.read_us(); gProfiler.start(); #endif // EVT_TIME_PROFILE + } else { #if CHIPBOARD==SST4CH // reset in case a trigger arrived before we were ready @@ -1086,6 +1103,11 @@ #endif } + // done with this event. + // reset flags from the "old" event + gForcedTrig = false; + gAdcToMBflag = false; + led1 = 1; led4 = 0; // end signal reading out } @@ -1095,13 +1117,19 @@ if (gHrtbtFired) { led1 = 1; led4 = 1; // signal saving transient + gHrtbt.SetTime( gLastHrtbt ); + // -1 so we start counting at 0 + // counting inside proc so we have a record of the number of proc's + // even if we are saving/triggering slower than they're firing + gHrtbt.SetNum( (gHrtbtNum>0) ? (gHrtbtNum - 1) : 0 ); SaveHeartbeat(); gHrtbtFired=false; + gStNewHeartbeat = true; led1 = 1; led4 = 0; // end signal saving transient } #ifdef EVT_TIME_PROFILE - prof.stop(); befChkPow=prof.read_us(); prof.start(); + gProfiler.stop(); befChkPow=gProfiler.read_us(); gProfiler.start(); #endif // EVT_TIME_PROFILE // check the power? if (gCheckPower) { @@ -1110,10 +1138,12 @@ #endif led1 = 1; led4 = 1; // signal saving transient CheckPower(false); + gStPower = gPower; + gStNewPower = true; led1 = 1; led4 = 0; // end signal saving transient } #ifdef EVT_TIME_PROFILE - prof.stop(); aftChkPow=prof.read_us(); prof.start(); + gProfiler.stop(); aftChkPow=gProfiler.read_us(); gProfiler.start(); #endif // EVT_TIME_PROFILE if (gCheckTemp) { @@ -1122,6 +1152,8 @@ #endif led1 = 1; led4 = 1; // signal saving transient CheckTemp(); + gStTemperature = gTemperature; + gStNewTemperature = true; led1 = 1; led4 = 0; // end signal saving transient } @@ -1134,6 +1166,7 @@ SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(), gClkSet, false); + gStTrgStopClk = gClkSet; led1 = 0; // signal not waiting OpenCommWin(); led1 = 1; // end signal not waiting @@ -1150,7 +1183,7 @@ } #ifdef EVT_TIME_PROFILE - prof.stop(); befNewSeq=prof.read_us(); prof.start(); + gProfiler.stop(); befNewSeq=gProfiler.read_us(); gProfiler.start(); #endif // EVT_TIME_PROFILE // make new seq? if (IsSeqComplete()) { @@ -1162,6 +1195,7 @@ SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(), gClkSet, false); + gStTrgStopClk = gClkSet; MakeOutputFile(gConf.IsSingleSeqRunMode()); gFirstEvt = true; gThmTrgTimer.reset(); @@ -1170,14 +1204,14 @@ led1 = 1; led2 = 0; led4 = 0; // end signal saving file } #ifdef EVT_TIME_PROFILE - prof.stop(); aftNewSeq=prof.read_us(); prof.start(); + gProfiler.stop(); aftNewSeq=gProfiler.read_us(); gProfiler.start(); #endif // EVT_TIME_PROFILE #ifdef EVT_TIME_PROFILE - prof.stop(); endOfLoop=prof.read_us(); prof.start(); - printf("befReadWv=%d, aftReadWv=%d, befSaveEvt=%d, aftSaveEvt=%d, " + gProfiler.stop(); endOfLoop=gProfiler.read_us(); gProfiler.start(); + printf("befSaveEvt=%d, aftSaveEvt=%d, " "befChkPow=%d, aftChkPow=%d, befNewSeq=%d, aftNewSeq=%d, endOfLoop=%d\r\n", - befReadWv, aftReadWv, befSaveEvt, aftSaveEvt, + befSaveEvt, aftSaveEvt, befChkPow, aftChkPow, befNewSeq, aftNewSeq, endOfLoop); #endif // EVT_TIME_PROFILE @@ -1190,7 +1224,7 @@ // reset event // clear after comm win, so full event can be sent with status // but don't clear counters or trigger bits, as - gEvent.ClearEvent(true); +// gEvent.ClearEvent(true); } // end while (true) @@ -1200,20 +1234,17 @@ // save a heartbeat tag // void SaveHeartbeat() { - if (gHrtbtNum>0) { #ifdef DEBUG - printf("save heartbeat #%u, time %u\r\n", - gHrtbtNum-1, gLastHrtbt); + printf("save heartbeat #%u, time %u\r\n", + gHrtbt.GetNum(), gHrtbt.GetTime()); #endif - // save to SD + // save to SD #if CHIPBOARD==ATWD4CH - PIN_lockRegisters = 0; // unlock so we can talk to the SD card + PIN_lockRegisters = 0; // unlock so we can talk to the SD card #else - PIN_readingData = 0; // unlock so we can talk to the SD card + PIN_readingData = 0; // unlock so we can talk to the SD card #endif - SnSDUtils::WriteHeartbeatTo(SnSDUtils::GetCurFile(), - gLastHrtbt, gHrtbtNum-1); // -1 so it counts from 0 - } + SnSDUtils::WriteHeartbeatTo(SnSDUtils::GetCurFile(), gHrtbt); } // @@ -1223,31 +1254,203 @@ // write the event #ifdef DEBUG - printf("save event (%u)\r\n", gEvtNum); + // check that the event is still the same as gLastEvent + /* + bool esame = gEvent.GetMbedTime() == gLastEvent.GetMbedTime(); + esame &= gEvent.GetEvtNum() == gLastEvent.GetEvtNum(); + esame &= gEvent.GetDTms() == gLastEvent.GetDTms(); + esame &= gEvent.GetTrgNum() == gLastEvent.GetTrgNum(); + esame &= gEvent.GetTrgBits() == gLastEvent.GetTrgBits(); + esame &= gEvent.GetCRC() == gLastEvent.GetCRC(); + for (uint16_t i=0; i<kTotSamps; ++i) { + esame &= (gEvent.GetData())[i] == (gLastEvent.GetData())[i]; + } +#if CHIPBOARD!=ATWD4CH + for (uint16_t i=0; i<kNstopBytes; ++i) { + esame &= (gEvent.GetStop())[i] == (gLastEvent.GetStop())[i]; + } + printf("EEEEEEEE event==lastEvt = %s\r\n", (esame?"true":"false")); +#endif + */ +#endif + + // ok, now we can overwrite the old gEvent data + // reset event + gEvent.ClearEvent(true, true); + + // read data & calc CRC +#ifdef EVT_TIME_PROFILE + int befReadWv=0, aftReadWv=0, befWriteEvt=0, aftWriteEvt=0; + gProfiler.stop(); befReadWv=gProfiler.read_us(); gProfiler.start(); +#endif // EVT_TIME_PROFILE + +#if CHIPBOARD==ATWD4CH + // get the data to the MBED + gEvent.ReadWaveformsATWD(PIN_spi, PIN_selCardHiBit, PIN_selCardLoBit); +#else + gEvent.ReadWaveformsSST(PIN_spi, PIN_readingData); + // reset in case a trigger arrived before we were ready + PIN_ResetChips = 1; +// wait_us(1); + PIN_ResetChips = 0; +#endif //ATWD4CH + +#ifdef EVT_TIME_PROFILE + gProfiler.stop(); aftReadWv=gProfiler.read_us(); gProfiler.start(); +#endif // EVT_TIME_PROFILE + + gEvent.SetCurMbedTime(); + + Watchdog::kick(); // don't reset! + +#ifdef DEBUG + printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false"); +#endif + +#if CHIPBOARD==ATWD4CH + PIN_lockRegisters = 0; // done reading, unlock so we can talk to the SD card +#else + // (this is redundant; it's already set low by SnEventFrame) + PIN_readingData = 0; // done reading, unlock so we can talk to the SD card +#endif // ATWD4CH + +#ifdef DEBUG + printf("waveform read out. save event (%u)\r\n", gEvtNum); #endif // set the event number & dt gEvent.SetEvtNum(gEvtNum); gEvent.SetDTms(etms); + // set trigger bits + if (gForcedTrig) { + gEvent.SetTrgBit(kForced); +// gEvent.SetTrgNum(gTrgNum[kFrcTrg]); + gEvent.SetTrgNum(gNumFrcTrigs); + } else { + gEvent.SetTrgBit(kThermal); +// gEvent.SetTrgNum(gTrgNum[kThmTrg]); + gEvent.SetTrgNum(gNumThmTrigs); + } + if (gAdcToMBflag) { + gEvent.SetTrgBit(kAdcToMBflag); + } + // this is in the config too, but doesn't hurt to flip the bit + // in the event + if (gConf.IsL1TrigApplied()) { + gEvent.SetTrgBit(kL1TrgApplied); + } + + // ---- + // L1 check(s) go here! + bool L1okToSave = true; + +#ifdef DEBUG + Timer l1timer; + l1timer.start(); + printf("L1 single freq supp ratio = %hhu (%g)\r\n", + gConf.GetSingleFreqSuppRatioRaw(), + gConf.GetSingleFreqSuppRatio()); +#endif + + // TODO: move the FFT calculation out here so that + // other L1's could use it too. haven't done this already + // in order to save RAM and not cache the whole thing when + // we only have one L1 cut. + + // check L1 single frequency suppression cut + if ( gConf.IsSingleFreqSuppEnabled() ) { + const EL1TrigStatus passL1SingleFreqSupp = + SnL1SingleFreqSupp::ProcessEvent(gEvent, gChanFFT, + gConf.GetSingleFreqSuppRatio()); +#ifdef DEBUG + l1timer.stop(); + printf("L1 single freq supp took [%d] us\r\n", + l1timer.read_us()); + printf("passL1SingleFreqSupp=%s\r\n", + passL1SingleFreqSupp==kL1Pass ? "pass" + : passL1SingleFreqSupp==kL1Fail ? "fail" + : "other"); +#endif + if (passL1SingleFreqSupp==kL1Pass) { + gEvent.SetTrgBit(kSingleFreqSupp); + } else if ( (passL1SingleFreqSupp==kL1Fail) && + gConf.IsL1TrigApplied() ) { + L1okToSave = false; + } + // else if kL1UnableToProcess, the bit won't get set + // but the event can/will be saved + } + + + // NO MORE L1 checks below here! (or the scaledown won't work) + // ----- + +#ifdef EVT_TIME_PROFILE + gProfiler.stop(); befWriteEvt=gProfiler.read_us(); gProfiler.start(); +#endif // EVT_TIME_PROFILE + // save to SD #if CHIPBOARD==ATWD4CH PIN_lockRegisters = 0; // unlock so we can talk to the SD card #else PIN_readingData = 0; // unlock so we can talk to the SD card #endif - SnSDUtils::WriteEventTo(SnSDUtils::GetCurFile(), gGenBuf, gEvent, gConf); + + // scale down to override L1 trigger failures + if ( (L1okToSave==false) && (gConf.GetL1Scaledown()!=0) ) { + ++gL1ScaledownCount; + + if ( gL1ScaledownCount == gConf.GetL1Scaledown() ) { + gL1ScaledownCount = 0; + L1okToSave = true; +#ifdef DEBUG + printf("))) L1 scaledown!\r\n"); +#endif + } + } + +#ifdef DEBUG + printf("L1 scaledown count = %hhu, scaledown=%hhu, L1okToSave=%s\r\n", + gL1ScaledownCount, + gConf.GetL1Scaledown(), + L1okToSave ? "true" : "false"); + printf("event trigger bits = "); + SnBitUtils::printBits(gEvent.GetTrgBits(), true); +#endif + // always save forced triggers + if (L1okToSave || gForcedTrig) { + SnSDUtils::WriteEventTo(SnSDUtils::GetCurFile(), gGenBuf, gEvent, gConf); + + // a good event + gStNewEvent = true; + + // send it? + if ( gConf.IsCommWindowEachEvent() ) { +#ifdef DEBUG + printf("COMM EACH EVENT => gOpenCommWin = true\r\n"); +#endif + gOpenCommWin = true; + } + } + +#ifdef EVT_TIME_PROFILE + gProfiler.stop(); aftWriteEvt=gProfiler.read_us(); gProfiler.start(); + printf("befReadWv=%d, aftReadWv=%d, befWriteEvt=%d, aftWriteEvt=%d\r\n", + befReadWv, aftReadWv, befWriteEvt, aftWriteEvt); +#endif // EVT_TIME_PROFILE + // make a copy in case we need to send it with the status // (copy it because we are going to clear this event while // waiting for the next trigger) - gEvent.CopyTo(gLastEvent); +// gEvent.CopyTo(gLastEvent); // increment event number ++gEvtNum; #ifdef DEBUG - printf("gEvtNum=%u\r\n",gEvtNum); + printf("next gEvtNum=%u\r\n",gEvtNum); #endif } @@ -1275,7 +1478,7 @@ gConf.GetFirstSeq(), gConf.IsSendingFilesRunSeqList()); // reset event, timers, trigger counters - ResetCountersClearEvt(); + ResetCounters(); if (cf!=0) { #ifdef USE_RTOS Thread::wait(200); @@ -1314,7 +1517,7 @@ printf("calling PowerDown\r\n"); #endif return (*cw)->PowerDown(gConf.GetTimeoutTime(time(0), - gConf.GetCommWinConnectTO())); + gConf.GetCommWinConnectTO(type))); } } return false; @@ -1330,12 +1533,13 @@ return gConf.GetPowPinSetting(p, true) == pin.read(); } -void ChangeCardPower(const bool isCommWin) { +void ChangeCardPower(const bool isCommWin, + const bool isOn) { // change cards power const SnConfigFrame::EPowerModeBit pbit = (isCommWin) ? SnConfigFrame::kCardComWin : SnConfigFrame::kCardDatTak; - const int value = gConf.GetPowPinSetting(pbit); + const int value = gConf.GetPowPinSetting(pbit, isOn); #ifdef DEBUG printf("setting cards pin power to %d (comm=%d)\r\n", value, static_cast<int>(isCommWin)); @@ -1348,12 +1552,13 @@ #endif } -void ChangeAmpsPower(const bool isCommWin) { +void ChangeAmpsPower(const bool isCommWin, + const bool isOn) { // change amps power const SnConfigFrame::EPowerModeBit pbit = (isCommWin) ? SnConfigFrame::kAmpsComWin : SnConfigFrame::kAmpsDatTak; - const int value = gConf.GetPowPinSetting(pbit); + const int value = gConf.GetPowPinSetting(pbit, isOn); #ifdef DEBUG printf("setting amps pin power to %d (comm=%d)\r\n", value, static_cast<int>(isCommWin)); @@ -1366,7 +1571,8 @@ #endif } -void ChangeIridPower(const bool isCommWin) { +void ChangeIridPower(const bool isCommWin, + const bool isOn) { // change iridium power setting // if going from ON to OFF, call the special // power down procedure, so as not to lose @@ -1382,13 +1588,10 @@ // these checks are complicated because the iridium might // be powered off the Afar (12V) relay, // rather than the iridium (5V) relay - const bool iridToOn = (kIridPwrFromAfar) ? - (gConf.IsPoweredFor(abit) || gConf.IsPoweredFor(ibit)) : - gConf.IsPoweredFor(ibit); const bool iridFromOn = (kIridPwrFromAfar) ? IsCurrentlyPowered(abit, PIN_afar_power) : IsCurrentlyPowered(ibit, PIN_iridSbd_power); - if ( iridFromOn && (iridToOn==false) ) { + if ( iridFromOn && (isOn==false) ) { #ifdef DEBUG printf("calling PowerDown for Iridium\r\n"); #endif @@ -1396,7 +1599,7 @@ } const int value = (kIridPwrFromAfar) ? gConf.GetPowPinSetting(ibit, false) // leave the iridium relay off. use afar relay. - : gConf.GetPowPinSetting(ibit); + : gConf.GetPowPinSetting(ibit, isOn); #ifdef DEBUG printf("setting iridium pin power to %d (comm=%d)\r\n", value, static_cast<int>(isCommWin)); @@ -1410,7 +1613,8 @@ } -void ChangeAfarPower(const bool isCommWin) { +void ChangeAfarPower(const bool isCommWin, + const bool isOn) { // change the AFAR relay power setting // also power up or down the ethernet PHY port // as appropriate @@ -1424,24 +1628,19 @@ printf("pcenet bef power: status=%d\r\n",Peripheral_GetStatus(LPC1768_PCONP_PCENET)); #endif - const SnConfigFrame::EPowerModeBit ibit = (isCommWin) - ? SnConfigFrame::kIridComWin - : SnConfigFrame::kIridDatTak; const SnConfigFrame::EPowerModeBit abit = (isCommWin) ? SnConfigFrame::kAfarComWin : SnConfigFrame::kAfarDatTak; const bool afarFromOn = IsCurrentlyPowered(abit, PIN_afar_power); - const bool afarToOn = gConf.IsPoweredFor(abit) || - (kIridPwrFromAfar && gConf.IsPoweredFor(ibit)); // change ethernet PHY port power #ifdef DEBUG printf("afar pin=%d, afarFromOn=%d, afarToOn=%d\r\n", PIN_afar_power.read(), static_cast<int>(afarFromOn), - static_cast<int>(afarToOn)); + static_cast<int>(isOn)); #endif - if (afarToOn) { + if (isOn) { #ifdef DEBUG printf("PHY cowin powering up\r\n"); #endif @@ -1484,7 +1683,7 @@ #endif // change afar power - const int value = gConf.GetPowPinSetting(abit, afarToOn); + const int value = gConf.GetPowPinSetting(abit, isOn); PIN_afar_power = value; #ifdef USE_RTOS Thread::wait(1500); @@ -1499,7 +1698,25 @@ } -void SetPower(const bool isCommWin) { +bool IsPowerAllowedFor(const bool isCommWin, + const uint8_t devicesInUse, + const SnConfigFrame::EDatPackBit b) { + if (isCommWin && (gConf.IsCommPowerSimple()==false)) { + return ( (devicesInUse & b)!=0 ); + } + return true; +} + +void SetPower(const bool isCommWin, + const uint8_t devicesInUse) { + // devicesInUse could really just be a second set of "power mode" bits + // where the bit being on means "I want to change power for this device" + // but then.. how to handle the possibility that the bit word contains, + // for example, both bits AfarDatTak and AfarComWin being on? + // so instead, we keep the "isCommWin" boolean which forces the separation + // and deviceInUse is only applied when isCommWin==true + // + // multiple devices can be specified by, e.g., kIrid | kAfar #ifdef DEBUG printf("set power. isCommWin=%s\r\n",(isCommWin)?"true":"false"); printf("WD reset = %d\r\n",(int)Watchdog::didWatchdogReset()); @@ -1512,6 +1729,8 @@ printf("IsPoweredFor AmpsComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAmpsComWin)); printf("IsPoweredFor IridComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kIridComWin)); printf("IsPoweredFor AfarComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAfarComWin)); + printf("devicesInUse = %hhu\r\n", (uint8_t)devicesInUse); + printf("IsCommPowerSimple = %s\r\n", (gConf.IsCommPowerSimple() ? "true" : "false")); #endif const SnConfigFrame::EPowerModeBit cardpb = (isCommWin) @@ -1526,28 +1745,33 @@ const SnConfigFrame::EPowerModeBit afarpb = (isCommWin) ? SnConfigFrame::kAfarComWin : SnConfigFrame::kAfarDatTak; - // TODO: turn on amps individually, when that's possible // // FIRST turn the things off that should be off. // this prevents short periods of high power usage // - // iridium is more complicated because it might + const bool cardToOn = gConf.IsPoweredFor(cardpb); + const bool ampsToOn = gConf.IsPoweredFor(ampspb); + + // these are complicated because iridium might // be powered off of the afar line + // also ignore the devices in use if we're not in a comm window const bool iridToOn = (kIridPwrFromAfar) ? - gConf.IsPoweredFor(afarpb) : - gConf.IsPoweredFor(iridpb); - const bool afarToOn = gConf.IsPoweredFor(afarpb) || - (kIridPwrFromAfar && gConf.IsPoweredFor(iridpb)); + (gConf.IsPoweredFor(afarpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kIrid)) : + (gConf.IsPoweredFor(iridpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kIrid)); + const bool afarToOn = (kIridPwrFromAfar) ? + ( (gConf.IsPoweredFor(afarpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kAfar)) + ||(gConf.IsPoweredFor(iridpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kIrid)) ) : + (gConf.IsPoweredFor(afarpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kAfar)); - if (gConf.IsPoweredFor(cardpb)==false) { + if (cardToOn==false) { #ifdef DEBUG printf("power down cards\r\n"); #endif - ChangeCardPower(isCommWin); + ChangeCardPower(isCommWin, cardToOn); } - if (gConf.IsPoweredFor(ampspb)==false) { + if (ampsToOn==false) { #ifdef DEBUG printf("power down amps\r\n"); printf("ampspb=%d, is powered for =%d\r\n", @@ -1557,47 +1781,47 @@ (int)(gConf.IsPoweredFor(SnConfigFrame::kAmpsDatTak)), (int)(gConf.IsPoweredFor(SnConfigFrame::kAmpsComWin))); #endif - ChangeAmpsPower(isCommWin); + ChangeAmpsPower(isCommWin, ampsToOn); } if (iridToOn==false) { #ifdef DEBUG printf("power down irid\r\n"); #endif - ChangeIridPower(isCommWin); + ChangeIridPower(isCommWin, iridToOn); } if (afarToOn==false) { #ifdef DEBUG printf("power down afar\r\n"); #endif - ChangeAfarPower(isCommWin); + ChangeAfarPower(isCommWin, afarToOn); } // // THEN turn on things that want to go on // - if (gConf.IsPoweredFor(cardpb)) { + if (cardToOn) { #ifdef DEBUG printf("power ON cards\r\n"); #endif - ChangeCardPower(isCommWin); + ChangeCardPower(isCommWin, cardToOn); } - if (gConf.IsPoweredFor(ampspb)) { + if (ampsToOn) { #ifdef DEBUG printf("power ON amps\r\n"); #endif - ChangeAmpsPower(isCommWin); + ChangeAmpsPower(isCommWin, ampsToOn); } if (iridToOn) { #ifdef DEBUG printf("power ON iridium\r\n"); #endif - ChangeIridPower(isCommWin); + ChangeIridPower(isCommWin, iridToOn); } if (afarToOn) { #ifdef DEBUG printf("power ON afar\r\n"); #endif - ChangeAfarPower(isCommWin); + ChangeAfarPower(isCommWin, afarToOn); } #ifdef DEBUG @@ -1917,7 +2141,8 @@ printf("total time = %d us\r\n", gAdcToMBtimer.read_us()); #endif if ( kAdcToMBtimeCut < gAdcToMBtimer.read_us() ) { - gEvent.SetTrgBit(kAdcToMBflag); +// gEvent.SetTrgBit(kAdcToMBflag); + gAdcToMBflag = true; } gAdcToMBtimer.reset(); @@ -1981,6 +2206,7 @@ #ifdef DEBUG printf("config=%s\r\n", gConf.GetLabel()); printf("thmrate=%g, evtrate=%g\r\n",thmrate,evtrate); + printf("Free memory = %d\r\n", FreeMem()); #endif StopAllTickers(); @@ -2025,8 +2251,9 @@ #ifdef DEBUG printf("setting power\r\n"); #endif - // (probably) power down cards,amps and power up comms - SetPower(true); + // (probably) power down cards,amps + // don't power up comms yet (only as needed for use) + SetPower(true, 0); // time to recount files for the status update // for the startup win, don't access SD card in case we @@ -2040,23 +2267,37 @@ #ifdef DEBUG printf("start loop over comms\r\n"); #endif - bool sendStat[kNcomms]; + bool needToConnect=true; // still need to talk to the outside + bool sendStat[kNcomms]; // if need to send status over this peripheral + bool needClos[kNcomms]; // if need to call CloseConn on this peripheral for (uint8_t i=0; i<kNcomms; ++i) { sendStat[i]=true; + needClos[i]=true; } bool* ss = sendStat; + bool* nc = needClos; SnCommWin** cw = gComms; - for (uint8_t i=0; ((time(0)-gLastCommWin)<gConf.GetCommWinDuration()); ++i, ++cw, ++ss) { + for (uint8_t i=0; needToConnect && ((time(0)-gLastCommWin)<gConf.GetCommWinDuration()); + ++i, ++cw, ++ss, ++nc) { Watchdog::kick(); // don't reset! if (i==kNcomms) { i=0; cw = gComms; ss = sendStat; + nc = needClos; } // skip if no comm object if ((*cw)==0) { continue; } + + const SnConfigFrame::EDatPackBit ctype = (*cw)->GetCommType(); + + // power up for this device + if (gConf.IsCommPowerSimple()==false) { + SetPower(true, ctype); + } + // skip if no power for this comm // THIS IS VITAL! For example, if the ethernet // port is powered down, making an Ethernet obejct @@ -2071,13 +2312,17 @@ // that we don't accidently shut down comms (i.e. with // connectTO or listnTO being 0) gConf.ApplyConnectListenSafetyNets(); + const uint32_t conto = - (gConf.GetCommWinDuration() < gConf.GetCommWinConnectTO()) ? - gConf.GetCommWinDuration() : gConf.GetCommWinConnectTO(); + (gConf.GetCommWinDuration() < gConf.GetCommWinConnectTO(ctype)) ? + gConf.GetCommWinDuration() : gConf.GetCommWinConnectTO(ctype); const uint32_t listo = - (gConf.GetCommWinDuration() < gConf.GetCommWinListenTO()) ? - gConf.GetCommWinDuration() : gConf.GetCommWinListenTO(); + (gConf.GetCommWinDuration() < gConf.GetCommWinListenTO(ctype)) ? + gConf.GetCommWinDuration() : gConf.GetCommWinListenTO(ctype); + // + // try to connect to the outside if we haven't yet + // // update power reading in case we want to send it in status GetAvePowerReading(); @@ -2091,18 +2336,27 @@ // open window and (mabye) send status update #ifdef DEBUG - printf("calling OpenWindow. ss=%d\r\n",(int)(*ss)); + printf("Free memory = %d\r\n", FreeMem()); + printf("calling OpenWindow. ss=%d. ctype=%hhu (%s)\r\n", + (int)(*ss),(uint8_t)ctype,SnConfigFrame::GetDataStreamName(ctype)); printf("conto=%u, listo=%u, dur=%u, connTO=%u, lisTO=%u\r\n", conto,listo,gConf.GetCommWinDuration(), - gConf.GetCommWinConnectTO(), gConf.GetCommWinListenTO()); - printf("gtt=%u, ct=%d, lcw=%d, dur=%u\r\n",gConf.GetTimeoutTime(gLastCommWin,conto), - time(0), gLastCommWin, gConf.GetCommWinDuration()); + gConf.GetCommWinConnectTO(ctype), gConf.GetCommWinListenTO(ctype)); + printf("stopAt=%u, current=%d, lastComWin=%d, dt~%u\r\n", + gConf.GetTimeoutTime(gLastCommWin,conto), + time(0), gLastCommWin, + gConf.GetTimeoutTime(gLastCommWin,conto)-time(0)); #endif - const SnCommWin::ECommWinResult conres = (*cw)->OpenWindow( -// gConf.GetTimeoutTime(gLastCommWin, conto), *ss, gConf, gEvent, gPower, - gConf.GetTimeoutTime(gLastCommWin, conto), *ss, gConf, gLastEvent, gPower, - SnSDUtils::GetCurSeqNum(), thmrate, evtrate, gPowerOnTime, gTemperature, - gGenBuf); + + // + // open the connection and send the status update (if the + // status has not yet been sent over this peripheral) + // + const SnCommWin::ECommWinResult conres = (*cw)->OpenWindow( *ss, + gConf, gPower, gEvent, SnSDUtils::GetCurSeqNum(), thmrate, evtrate, + gPowerOnTime, gTemperature, + gGenBuf, gConf.GetTimeoutTime(gLastCommWin, conto)); + #ifdef DEBUG printf("conres = %d\r\n",static_cast<int>(conres)); #endif @@ -2110,12 +2364,13 @@ Watchdog::kick(); // don't reset! // connected. listen for config *ss = false; // don't send status next time + *nc = true; // will need to close this connection // clear watchdog reset bit now that we've told someone Watchdog::clearResetFlag(); #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM) - if ((*cw)->GetCommType()==SnConfigFrame::kAfar) { + if (ctype==SnConfigFrame::kAfar) { // if we connected by Afar doTwitter = true; } @@ -2124,6 +2379,9 @@ #ifdef DEBUG printf("get conf gtt=%u\r\n",gConf.GetTimeoutTime(gLastCommWin, listo)); #endif + // + // ask for a new config + // const SnCommWin::ECommWinResult cfgres = (*cw)->GetConfig( gConf, gConf.GetTimeoutTime(gLastCommWin, listo), gGenBuf, gBufSize); #ifdef DEBUG @@ -2136,12 +2394,30 @@ printf("received config!\r\n"); printf("send data = %d\r\n", gConf.GetCommSendData()); #endif - // send data if need be (files, some events, etc) + const uint32_t winto = gConf.GetTimeoutTime(gLastCommWin, gConf.GetCommWinDuration()); //const uint32_t gtt = gConf.IsObeyingTimeout() ? winto : 0; + // + // send status data -- do this after getting the config! + // (avoid a situation where sending all this data causes a timeout, + // thereby preventing a new config from being accepted) + // + res = (*cw)->SendStatusData(gConf, + gStTrgStartClk, gStTrgStopClk, + gStPower, gEvent, gStTemperature, + gHrtbt, gStNewPower, gStNewEvent, + gStNewHeartbeat, gStNewTemperature, + gGenBuf, winto); +#ifdef DEBUG + printf("SendStatusData res=%d\r\n", + static_cast<int32_t>(res)); +#endif + + // // check if there are any requests before sending data + // if (gConf.IsWaitingHndShkBeforeSendData()) { // send handshake request (*cw)->SendHndshkReq(gGenBuf, winto); @@ -2156,13 +2432,18 @@ if (SnCommWin::kOkWithMsg==res) { res = (*cw)->HandleHandshake(SnSDUtils::GetCurFile(), SnSDUtils::GetCurFileName(), - gConf, gLastEvent, gPower, gGenBuf, gBufSize, + gConf, gEvent, gPower, gGenBuf, gBufSize, +// gConf, gLastEvent, gPower, gGenBuf, gBufSize, winto, hndshk, hndshkLen); #ifdef DEBUG printf("HandleHandshake res = %d\r\n",static_cast<int>(res)); #endif } - } + } // if handshake before data + + // + // send data if need be (files, some events, etc) + // if (gConf.GetCommSendData()!=0) { #ifdef DEBUG printf("sending data, winto=%u. lcw=%u, dur=%u, obey=%s\r\n", @@ -2171,7 +2452,9 @@ gConf.IsObeyingTimeout() ? "true" : "false"); #endif - res = (*cw)->SendData(gConf, gLastEvent, gPower, gGenBuf, gBufSize, + res = (*cw)->SendData(gConf, +// gLastEvent, gPower, gGenBuf, gBufSize, + gEvent, gPower, gGenBuf, gBufSize, winto); #ifdef DEBUG printf("SendData res = %d\r\n",static_cast<int>(res)); @@ -2180,34 +2463,109 @@ } else { // don't send anything res = cfgres; - } + } // if send data #ifdef DEBUG printf("Got config!\r\n"); #endif Watchdog::kick(); // don't reset! - break; - } + + // need to close this connection + *nc = true; + // stop trying to connect to outside + // don't break immediately, so that we can close conn and + // maybe tweet (pff..) + needToConnect = false; + + } // if config recvd ok with message + + // + // stupid legacy twitter crap. + // + // after normal Afar connection closed, try to tweet +#if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM) + if (ctype==SnConfigFrame::kAfar) { + // tweet +#ifdef DEBUG + printf("for twitter: gTwit=%p, doTwitter=%d\r\n",gTwit,(int)doTwitter); +#endif + // send a twitter update + if ( (gTwit!=0) && doTwitter ) { + const uint32_t conto = + (gConf.GetCommWinDuration() < gTwit->GetConnectTimeout()) ? + gConf.GetCommWinDuration() : gTwit->GetConnectTimeout(); + const uint32_t listo = + (gConf.GetCommWinDuration() < gTwit->GetListenTimeout()) ? + gConf.GetCommWinDuration() : gTwit->GetListenTimeout(); +#ifdef DEBUG + printf("open twit window. conto=%u, listo=%u\r\n", + conto, listo); +#endif + const SnCommWin::ECommWinResult conres = gTwit->OpenWindow( + gConf.GetTimeoutTime(gLastCommWin, conto), false, gConf, + // gLastEvent, gPower, + gEvent, gPower, + SnSDUtils::GetCurSeqNum(), thmrate, evtrate, + gGenBuf); + if (conres>=SnCommWin::kConnected) { + Watchdog::kick(); // don't reset! + gTwit->Tweet(gConf, thmrate, evtrate, gGenBuf, + gConf.GetTimeoutTime(time(0), listo)); + } + } + } // end tweet block +#endif + } else { // OpenWindow did not connect (*cw)->CloseConn(gConf.GetTimeoutTime(gLastCommWin, listo)); + *nc = false; +#ifdef DEBUG + printf("no connect close conn. i=%d, nc=%s\r\n", + (int32_t)i, (*nc) ? "true" : "false"); +#endif } // if connected Watchdog::kick(); // don't reset! + + if (*nc) { + // need to close this connection +#ifdef DEBUG + printf("close conn extra time. i=%d, nc=%s\r\n", + (int32_t)i, (*nc) ? "true" : "false"); +#endif + const uint32_t extraDiscTime = gLastCommWin + + gConf.GetCommWinConnectTO((*cw)->GetCommType()); + (*cw)->CloseConn( + gConf.GetTimeoutTime(extraDiscTime, gConf.GetCommWinDuration())); + *nc = false; + } + + Watchdog::kick(); // don't reset! } // end loop over comms + // check Iridium time, send Iridium signal strength, and close the connection(s) cw = gComms; - for (uint8_t i=0; i<kNcomms; ++i, ++cw) { + nc = needClos; + for (uint8_t i=0; i<kNcomms; ++i, ++cw, ++nc) { if ((*cw)==0) { continue; } - const bool havePower=IsPinPowered(*cw); - if (havePower==false) { - continue; - } + + const SnConfigFrame::EDatPackBit ctype = (*cw)->GetCommType(); + + // check Iridium time + if (ctype==SnConfigFrame::kIrid) { - // check Iridium time - if ((*cw)->GetCommType()==SnConfigFrame::kIrid) { + // power up for this device + if (gConf.IsCommPowerSimple()==false) { + SetPower(true, ctype); + } + const bool havePower=IsPinPowered(*cw); + if (havePower==false) { + continue; + } + #ifdef DEBUG printf("try to set iridium time\r\n"); #endif @@ -2219,68 +2577,61 @@ printf("totime=%u, ctime=%u\r\n",totime,time(0)); #endif const bool con = (*cw)->Connect(totime); + *nc = true; + if (con) { uint32_t prvTime(0), setTime(0); const bool gottime = (*cw)->TrySetSysTimeUnix( totime, prvTime, setTime); if (gottime) { - gClkSet.SetClocks(prvTime, setTime); + gClkSet.SetClocks( prvTime, setTime, time(0), + gSinceClkSet.read_us() ); + gSinceClkSet.reset(); + gSinceClkSet.start(); #ifdef DEBUG - printf("sig str: totime=%u, ctime=%u\r\n",totime,time(0)); +// printf("sig str: totime=%u, ctime=%u\r\n",totime,time(0)); + printf("sig str: totime=%u, ctime=%u\r\n",totime,gClkSet.GetCurTime()); #endif // got time; now send signal strength (*cw)->SendSignalStrength( gGenBuf, gSigStr, totime ); - } + } // if got the iridium system time + } // if connected (again, possibly) + } // if iridium + + if (*nc) { + + // power up for this device + if (gConf.IsCommPowerSimple()==false) { + SetPower(true, ctype); } - } - // close the connection -- this must be why Twitter didn't work! - //(*cw)->CloseConn(gConf.GetTimeoutTime(gLastCommWin,gConf.GetCommWinDuration())); - // after normal Afar connection closed, try to tweet -#if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM) - if ((*cw)->GetCommType()==SnConfigFrame::kAfar) { - // tweet -#ifdef DEBUG - printf("for twitter: gTwit=%p, doTwitter=%d\r\n",gTwit,(int)doTwitter); -#endif - // send a twitter update - if ( (gTwit!=0) && doTwitter ) { - const uint32_t conto = - (gConf.GetCommWinDuration() < gTwit->GetConnectTimeout()) ? - gConf.GetCommWinDuration() : gTwit->GetConnectTimeout(); - const uint32_t listo = - (gConf.GetCommWinDuration() < gTwit->GetListenTimeout()) ? - gConf.GetCommWinDuration() : gTwit->GetListenTimeout(); + const bool havePower=IsPinPowered(*cw); + if (havePower==false) { + continue; + } + #ifdef DEBUG - printf("open twit window. conto=%u, listo=%u\r\n", - conto, listo); + printf("last loop close conn. i=%d, nc=%s\r\n", + (int32_t)i, (*nc) ? "true" : "false"); #endif - const SnCommWin::ECommWinResult conres = gTwit->OpenWindow( - gConf.GetTimeoutTime(gLastCommWin, conto), false, gConf, - gLastEvent, gPower, - SnSDUtils::GetCurSeqNum(), thmrate, evtrate, - gGenBuf); - if (conres>=SnCommWin::kConnected) { - Watchdog::kick(); // don't reset! - gTwit->Tweet(gConf, thmrate, evtrate, gGenBuf, - gConf.GetTimeoutTime(time(0), listo)); - } - } - } // end tweet block -#endif - Watchdog::kick(); // don't reset! - } // end loop: check time, tweet, etc + + const uint32_t extraDiscTime = gLastCommWin + + gConf.GetCommWinConnectTO((*cw)->GetCommType()); + (*cw)->CloseConn(gConf.GetTimeoutTime(extraDiscTime, gConf.GetCommWinDuration())); + *nc = false; + } + } // end loop: check time, close conns + /* // close connections - const uint32_t extraDiscTime = gLastCommWin + gConf.GetCommWinConnectTO(); cw = gComms; for (uint8_t i=0; i<kNcomms; ++i, ++cw) { if ((*cw)==0) { continue; } else { - (*cw)->CloseConn(gConf.GetTimeoutTime(extraDiscTime, gConf.GetCommWinDuration())); } } - + */ + } // if duration >0 /* not working. must use DEFCONF.DAT to change IP's. @@ -2315,7 +2666,7 @@ } // (probably) power down comms and power up cards,amps - SetPower(false); + SetPower(false, SnConfigFrame::kIrid | SnConfigFrame::kAfar); // reset config with system powered (for DAC/PLA setting) #ifdef DEBUG @@ -2335,6 +2686,7 @@ #ifdef DEBUG printf("closing comm win at %d\r\n",(int32_t)time(0)); + printf("Free memory = %d\r\n", FreeMem()); #endif led2 = 0;