Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
Diff: main.cpp
- Revision:
- 22:f957c4f840ad
- Parent:
- 21:ce51bb0ba4a5
- Child:
- 23:ccf39298f205
diff -r ce51bb0ba4a5 -r f957c4f840ad main.cpp --- a/main.cpp Wed Oct 10 05:54:12 2012 +0000 +++ b/main.cpp Tue Oct 16 04:47:44 2012 +0000 @@ -1,10 +1,11 @@ #include "mbed.h" +// start a watchdog as soon as possible +#include "Watchdog.h" +Watchdog::SnKickStarter gKickStarter(WDFAILSAFE); //#define USE_RTOS_TIMER //#define USE_ETH_INTERFACE - //#define EVT_TIME_PROFILE - //#define DEBUG //#define SSNOTIFY #define USE_MODSERIAL @@ -17,7 +18,6 @@ #define MODSERIAL_TX_BUF_SIZE 512 #endif #include "FATDirHandle.h" -#include "Watchdog.h" #include "EthernetPowerControl.h" #include "SnConstants.h" #include "SnBitUtils.h" @@ -26,6 +26,7 @@ #include "SnEventFrame.h" #include "SnStatusFrame.h" #include "SnHeaderFrame.h" +#include "SnHeartbeatFrame.h" #include "SnCommWin.h" #ifdef USE_ETH_INTERFACE #include "SnCommAfarTCP.h" @@ -110,6 +111,7 @@ // void ReadAllRegisters(); void ReadRegister(const uint8_t chan, int16_t* dev); +void SaveHeartbeat(); void SaveEvent(const int32_t etms); void WaitTrigAndSendClock(); void SetConfigAndMakeOutputFile(); @@ -160,11 +162,17 @@ static uint32_t gTrgNum[kNumTrgs] = {0}; // num of this type of trg received // i/o static time_t gLastCommWin = 0; // time -static uint32_t gRecentCountTime = 0; // time of most recent event (for rate) -static uint32_t gLastCountReset = 0; // start time of event count (for rate) -static uint32_t gLastEventReset = 0; // start event number (for rate) -static uint32_t gRecentEvtNum = 0; // number of most recent event (for rate) -static bool gDoResetLastCount = false; +static uint32_t gCommWinChecks = 0; +static uint32_t gNcommWinChecks = 0; +// heartbeat +static time_t gLastHrtbt = 0; +static bool gHrtbtFired = false; +static uint32_t gHrtbtNum = 0; +// rates +static double gThmDtSum = 0; // sum of all time diffs between thermal trigs +static double gEvtDtSum = 0; // sum of all time diffs between events +static uint32_t gThmNumDt = 0; // number of thermal trig time diffs added up +static uint32_t gEvtNumDt = 0; // number of event time diffs added up // this should be bigger than anything that will actually be used static const uint32_t gBufSize=SnStatusFrame::kMaxSizeOf + (2u*SnHeaderFrame::kMaxSizeOf) + SnPowerFrame::kMaxSizeOf; //static const uint32_t gB64Bsize=BASE64ENC_LEN(gBufSize)+1; @@ -200,6 +208,9 @@ PIN_heartbeat = 0; PIN_heartbeat = 1; // heartbeat pulse PIN_heartbeat = 0; + gLastHrtbt = time(0); + gHrtbtFired = true; + ++gHrtbtNum; } } @@ -211,8 +222,14 @@ } void procCommWin() { + ++gCommWinChecks; if (gReadingOut==false && gCommWinOpen==false) { - if ( (time(0) - gLastCommWin) > gConf.GetCommWinPeriod() ) { + //if ( (time(0) - gLastCommWin) > gConf.GetCommWinPeriod() ) { +#ifdef DEBUG + printf("<><><><><><> gCommWinChecks=%u, gNcommWinChecks=%u\r\n", + gCommWinChecks, gNcommWinChecks); +#endif + if ( gCommWinChecks >= gNcommWinChecks ) { #ifdef DEBUG printf("proc comm win\r\n"); #endif @@ -317,7 +334,15 @@ gEvtNum = gConf.GetFirstEvt() + evtStartCurSeq; gPowNum = evtStartCurSeq; memset(gTrgNum, 0, sizeof(uint32_t)*kNumTrgs); - gDoResetLastCount = true; + // reset rate counters + gThmDtSum = 0; + gThmNumDt = 0; + gEvtDtSum = 0; + gEvtNumDt = 0; + // reset heartbeat counters + gLastHrtbt = 0; + gHrtbtFired = false; + gHrtbtNum = 0; #ifdef DEBUG printf("Reset: gEvtNum=%u, gPowNum=%u, evtStartCS=%u\r\n", gEvtNum, gPowNum, evtStartCurSeq); @@ -326,12 +351,32 @@ void GetRates(float& thmrate, float& evtrate) { thmrate = evtrate = 0; - const uint32_t dt = gRecentCountTime - gLastCountReset; - if (dt>0) { - const float fdt = static_cast<float>(dt); - thmrate = static_cast<float>(gTrgNum[kThmTrg]) / fdt; - evtrate = static_cast<float>(gRecentEvtNum - gLastEventReset) / fdt; +#ifdef DEBUG + printf("** Getting rates: gThmNumDt=%d, gThmDtSum=%g, " + "gEvtNumDt=%d, gEvtDtSum=%g\r\n", + gThmNumDt, gThmDtSum, gEvtNumDt, gEvtDtSum); +#endif + + thmrate = (gThmDtSum>0.0) ? static_cast<float>(gThmNumDt) / (gThmDtSum/1e3) + : 0; + evtrate = (gEvtDtSum>0.0) ? static_cast<float>(gEvtNumDt) / (gEvtDtSum/1e3) + : 0; +} + +void AddToRate(const float dt, const bool isThm) { + if (isThm) { + gThmDtSum += dt; + gThmNumDt += 1u; + } else { + gEvtDtSum += dt; + gEvtNumDt += 1u; } +#ifdef DEBUG + printf("** AddToRate: dt=%g, isThm=%d\r\n",dt,(int)isThm); + printf("** AddToRate: gThmNumDt=%d, gThmDtSum=%g, " + "gEvtNumDt=%d, gEvtDtSum=%g\r\n", + gThmNumDt, gThmDtSum, gEvtNumDt, gEvtDtSum); +#endif } bool IsSeqComplete() { @@ -377,12 +422,6 @@ if (timSec>0) { float tp = timSec > maxTimSec ? maxTimSec : timSec; tp *= 1000u; // ms - /* - if (tik==gForceTicker) { - tik->start((1./10.)*1e3); - return ((1./10.)*1e3); - } else - */ tik->start(tp); return tp; } @@ -448,11 +487,15 @@ wait(0.5); led3 = 0; led4=0; wait(0.5); - //Watchdog::kick(); - if we kick the watchdog, the station is unrecoverable without physical access + // don't kick the watchdog + // if we do, the station is unrecoverable without physical access } } int main() { + // a failsafe + Watchdog::kick(WDFAILSAFE); + { gCpu.baud(115200); #if defined(SSNOTIFY) || defined(DEBUG) @@ -506,9 +549,6 @@ printf("\n\n\n\n\n\nstarting\r\n"); #endif - // a failsafe - Watchdog::kick(kWDFailsafe); - // set the clock to the BS time, if it's not set if ( (static_cast<int32_t>(time(0)))<0 ) { set_time(kBStime); @@ -562,6 +602,12 @@ WaitTrigAndSendClock(); PIN_lockRegisters = 1; // block registers during readout + + if (gHrtbtFired) { + SaveHeartbeat(); + gHrtbtFired=false; + } + #ifdef EVT_TIME_PROFILE Timer prof; prof.start(); @@ -583,37 +629,38 @@ led4=1; - // read data & calc CRC + if ( gEvent.IsForcedTrg() || gFirstEvt || + (etms>gConf.GetEvtThrtlPeriodMs()) ) { + + // read data & calc CRC #ifdef EVT_TIME_PROFILE - prof.stop(); befReadWv=prof.read_us(); prof.start(); + prof.stop(); befReadWv=prof.read_us(); prof.start(); #endif - // get the data to the MBED - gEvent.ReadWaveforms(PIN_spi, PIN_selCardHiBit, PIN_selCardLoBit); + // get the data to the MBED + gEvent.ReadWaveforms(PIN_spi, PIN_selCardHiBit, PIN_selCardLoBit); #ifdef EVT_TIME_PROFILE - prof.stop(); aftReadWv=prof.read_us(); prof.start(); + prof.stop(); aftReadWv=prof.read_us(); prof.start(); #endif - gEvent.SetCurMbedTime(); - // TODO: no way to check for external trigger? - if (gEvent.IsForcedTrg()==false) { - gEvent.SetTrgBit(kThmTrg); - gEvent.SetTrgNum(++(gTrgNum[kThmTrg])); - } // else already set by procForceTrigger - // (no need to calc if we throw this event away) - - Watchdog::kick(); // don't reset! - + gEvent.SetCurMbedTime(); + // TODO: no way to check for external trigger? + if (gEvent.IsForcedTrg()==false) { + gEvent.SetTrgBit(kThmTrg); + gEvent.SetTrgNum(++(gTrgNum[kThmTrg])); + AddToRate(ttms, true); + } // else already set by procForceTrigger + // (no need to calc if we throw this event away) + + Watchdog::kick(); // don't reset! + #ifdef DEBUG - printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false"); + printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false"); #endif - - if ( gEvent.IsForcedTrg() || gFirstEvt || - (etms>gConf.GetEvtThrtlPeriodMs()) ) { led2=1; - + /* gRecentCountTime = static_cast<uint32_t>(time(0)); gRecentEvtNum = gEvtNum; // do start time second so that if we get only one event, @@ -623,6 +670,7 @@ gLastEventReset = gEvtNum; gDoResetLastCount = false; } + */ PIN_lockRegisters = 0; // done reading, unlock so we can talk to SD card. @@ -631,6 +679,7 @@ #endif SaveEvent(etms); + AddToRate(etms, false); etms=0; #ifdef EVT_TIME_PROFILE @@ -665,6 +714,9 @@ #endif OpenCommWin(); gOpenCommWin=false; + gFirstEvt = true; + gTrgTimer.reset(); + etms=0; } else { #ifdef DEBUG printf("gOpenCommWin=false\r\n"); @@ -680,6 +732,9 @@ printf("seq complete. sngseq=%d\r\n",gConf.IsSingleSeqRunMode()); #endif MakeOutputFile(gConf.IsSingleSeqRunMode()); + gFirstEvt = true; + gTrgTimer.reset(); + etms=0; } #ifdef EVT_TIME_PROFILE prof.stop(); aftNewSeq=prof.read_us(); prof.start(); @@ -696,15 +751,33 @@ // get ready to trigger PIN_spi.format( 16, 1 ); // change to data readout format PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz - + // reset event - gEvent.ClearEvent(); + // clear after comm win, so full event can be sent with status + // but don't clear counters or trigger bits, as + gEvent.ClearEvent(true); } } // +// save a heartbeat tag +// +void SaveHeartbeat() { + if (gHrtbtNum>0) { +#ifdef DEBUG + printf("save heartbeat #%u, time %u\r\n", + gHrtbtNum-1, gLastHrtbt); +#endif + // save to SD + PIN_lockRegisters = 0; // unlock so we can talk to SD card. + SnSDUtils::WriteHeartbeatTo(SnSDUtils::GetCurFile(), + gLastHrtbt, gHrtbtNum-1); // -1 so it counts from 0 + } +} + +// // save the event // void SaveEvent(const int32_t etms) { @@ -883,6 +956,9 @@ PIN_heartbeat = 0; wait_ms(20); + gCommWinChecks = 0; + gNcommWinChecks = gConf.GetCommWinPeriod() / kCommWinLongPrdTk; + if (AreCardsPowered(true)) { // Set PLA value(s) PIN_spi.format( 16, 0 ); // change mode for DAC & PLA value setting @@ -1131,6 +1207,9 @@ // get the trigger rates float thmrate=0, evtrate=0; GetRates(thmrate, evtrate); +#ifdef DEBUG + printf("thmrate=%g, evtrate=%g\r\n",thmrate,evtrate); +#endif StopAllTickers(); @@ -1276,12 +1355,11 @@ // (probably) power down comms and power up cards,amps SetPower(false); - gFirstEvt = true; - // reset config with system powered (for DAC/PLA setting) #ifdef DEBUG printf("calling SetConfigAndMakeOutputFile\r\n"); #endif + SetConfigAndMakeOutputFile(); #ifdef DEBUG