Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
Diff: main.cpp
- Revision:
- 12:d472f9811262
- Parent:
- 11:de443350ec4a
- Child:
- 13:7a1fb885a8e4
--- a/main.cpp Mon Aug 13 20:44:06 2012 +0000 +++ b/main.cpp Sat Aug 18 05:00:32 2012 +0000 @@ -2,6 +2,9 @@ #define USE_RTOS_TIMER +//#define EVT_TIME_PROFILE +//#define DEBUG + #include <stdint.h> #include "SDFileSystem.h" #include "MODSERIAL.h" @@ -113,7 +116,7 @@ static Ticker gCommWinTicker; static Ticker gPowerCheckTicker; #endif -static Timer gEvtTimer; +static Timer gTrgTimer; static SnConfigFrame gConf; static SnEventFrame gEvent; static SnPowerFrame gPower; @@ -139,7 +142,9 @@ void procForceTrigger() { led3=!led3; if (gReadingOut==false && gCommWinOpen==false) { +#ifdef DEBUG printf("proc force\r\n"); +#endif gEvent.SetTrgBit(kFrcTrg); gEvent.SetTrgNum((gTrgNum[kFrcTrg])++); PIN_forceTrigger = 1; // force a trigger @@ -148,21 +153,27 @@ void procHeartbeat() { if (gReadingOut==false && gCommWinOpen==false) { +#ifdef DEBUG printf("proc heartbeat\r\n"); +#endif PIN_heartbeat = 1; // heartbeat pulse PIN_heartbeat = 0; } } void procPowerCheck() { +#ifdef DEBUG printf("proc power\r\n"); +#endif gCheckPower=true; } void procCommWin() { if (gReadingOut==false && gCommWinOpen==false) { if ( (time(0) - gLastCommWin) > gConf.GetCommWinPeriod() ) { +#ifdef DEBUG printf("proc comm win\r\n"); +#endif led3=!led3; gOpenCommWin = true; } @@ -179,7 +190,9 @@ } bool AreCardsPowered() { +#ifdef DEBUG printf("acp: PIN_turn_on_system=%d\r\n",PIN_turn_on_system.read()); +#endif return (PIN_turn_on_system.read()==0); } @@ -213,37 +226,47 @@ } void CheckPower(const bool isCommWin) { +#ifdef DEBUG printf("CheckPower\r\n"); +#endif // read power GetAvePowerReading(); // save to disk FILE* cf = SnSDUtils::GetCurFile(); if (cf!=0) { PIN_lockRegisters = 0; // unlock so we can talk to SD card. +#ifdef DEBUG printf("writing power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u, pownum=%u\r\n", gPower.GetAveV1(), gPower.GetAveV2(), gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime(), gPowNum); +#endif SnSDUtils::WritePowerTo(cf, gPower, gPowNum); } // do we need to change modes? bool changed = false; if (gConf.IsLowPowerMode()) { if (gPower.GetAveV1() > gConf.GetBatVoltLowPwr()) { +#ifdef DEBUG printf("chaing to normal power!\r\n"); +#endif gConf.ChangeToNormPower(); changed = true; } } else { if (gPower.GetAveV1() < gConf.GetBatVoltLowPwr()) { +#ifdef DEBUG printf("chaing to low power!\r\n"); +#endif gConf.ChangeToLowPower(); changed = true; } } if (changed) { SetPower(isCommWin); +#ifdef DEBUG printf("Using config %s\r\n",gConf.GetLabel()); +#endif SetConfigAndMakeOutputFile(); // setup defaults in case no communication } // checking done @@ -251,9 +274,11 @@ } void ResetCountersClearEvt() { + const uint32_t evtStartCurSeq = (SnSDUtils::GetCurSeqNum()) // no -1; start with seq=0 + * gConf.GetEvtsPerFile(); gEvent.ClearEvent(); - gEvtNum = gConf.GetFirstEvt(); - gPowNum = 0; + gEvtNum = gConf.GetFirstEvt() + evtStartCurSeq; + gPowNum = evtStartCurSeq; memset(gTrgNum, 0, sizeof(uint32_t)*kNumTrgs); gLastCountReset = static_cast<uint32_t>(time(0)); } @@ -268,17 +293,26 @@ } bool IsSeqComplete() { - printf("IsSeqComplete: eps=%u, cntpow=%d, fe=%u, pow=%u, evt=%u\r\n", +#ifdef DEBUG + printf("IsSeqComplete: eps=%u, cntpow=%d, fe=%u, pow=%u, evt=%u, seq=%hu\r\n", gConf.GetEvtsPerFile(), (int)gConf.IsCountingPowerReadings(), - gConf.GetFirstEvt(), gPowNum, gEvtNum); + gConf.GetFirstEvt(), gPowNum, gEvtNum, SnSDUtils::GetCurSeqNum()); +#endif if (gConf.GetEvtsPerFile()>0) { + const uint32_t evtEndCurSeq = (SnSDUtils::GetCurSeqNum()+1) // account for seq=0 + * gConf.GetEvtsPerFile(); +#ifdef DEBUG + printf("evtEndCurSeq=%u\r\n",evtEndCurSeq); +#endif if (gConf.IsCountingPowerReadings()) { - return (gPowNum>=gConf.GetEvtsPerFile()); + return (gPowNum>=evtEndCurSeq); } else { - return (gEvtNum>=(gConf.GetFirstEvt()+gConf.GetEvtsPerFile())); + // first event num is a one-time per run offset, not one per sequence + return (gEvtNum>=(gConf.GetFirstEvt()+evtEndCurSeq)); } + } else { + return false; } - return false; } #ifdef USE_RTOS_TIMER @@ -321,14 +355,12 @@ #endif void StopRunning() { +#ifdef DEBUG printf("stop running\r\n"); - printf("stopping force\r\n"); +#endif stopTicker(gForceTicker); - printf("stop heart\r\n"); stopTicker(gHeartbeatTicker); - printf("stop comm win\r\n"); stopTicker(gCommWinTicker); - printf("stop power check\r\n"); stopTicker(gPowerCheckTicker); while (true) { led3 = 1; led4=1; @@ -360,7 +392,9 @@ led2=1; //wait_ms(100); +#ifdef DEBUG printf("\n\n\n\n\n\nstarting\r\n"); +#endif // a failsafe Watchdog::kick(kWDFailsafe); @@ -369,7 +403,9 @@ if ( (static_cast<int32_t>(time(0)))<0 ) { set_time(kBStime); } +#ifdef DEBUG printf("time = %d\r\n",(int32_t)time(0)); +#endif gLastCommWin = time(0); // prevent comm win proc #ifdef USE_RTOS_TIMER @@ -382,13 +418,17 @@ // (probably) power down comms and power up cards,amps SetPower(false); +#ifdef DEBUG printf("Using config %s\r\n",gConf.GetLabel()); +#endif SetConfigAndMakeOutputFile(); // setup defaults in case no communication // // get config // +#ifdef DEBUG printf("call OpenCommWin\r\n"); +#endif OpenCommWin(); // get ready to trigger @@ -397,7 +437,8 @@ led2=0; // the main event loop. wait for triggers in SendClock - gEvtTimer.start(); + gTrgTimer.start(); + register int32_t etms=0; // time between written events while( true ) { // in here, we wait for triggers from the MB-FPGA @@ -405,17 +446,29 @@ led1 = !led1; +#ifdef DEBUG printf("calling wait trig\r\n"); printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false"); printf("readingout=%d\r\n",(int)gReadingOut); +#endif PIN_lockRegisters = 0; // allow data to come from DFPGA WaitTrigAndSendClock(); PIN_lockRegisters = 1; // block registers during readout +#ifdef EVT_TIME_PROFILE + Timer prof; + prof.start(); + int befReadWv=0, aftReadWv=0, befSaveEvt=0, aftSaveEvt=0, + befChkPow=0, aftChkPow=0, befNewSeq=0, aftNewSeq=0, endOfLoop=0; +#endif + if (gReadingOut) { - const int32_t etms = gEvtTimer.read_ms(); // time since last trigger - gEvtTimer.reset(); gEvtTimer.start(); // start counter from this trigger + + + const int32_t ttms = gTrgTimer.read_ms(); // time since last trigger + gTrgTimer.reset(); gTrgTimer.start(); // restart trigger timer + etms += ttms; Watchdog::kick(); // don't reset! @@ -424,10 +477,21 @@ // led4=1; +#ifdef DEBUG printf("readout\r\n"); +#endif // read data & calc CRC +#ifdef EVT_TIME_PROFILE + prof.stop(); befReadWv=prof.read_us(); prof.start(); +#endif + gEvent.ReadWaveforms(PIN_spi, PIN_selCardHiBit, PIN_selCardLoBit); + +#ifdef EVT_TIME_PROFILE + prof.stop(); aftReadWv=prof.read_us(); prof.start(); +#endif + gEvent.SetCurMbedTime(); // TODO: no way to check for external trigger? if (gEvent.IsForcedTrg()==false) { @@ -438,7 +502,9 @@ Watchdog::kick(); // don't reset! +#ifdef DEBUG printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false"); +#endif if ( gEvent.IsForcedTrg() || gFirstEvt || (etms>gConf.GetEvtThrtlPeriodMs()) ) { @@ -447,41 +513,72 @@ PIN_lockRegisters = 0; // done reading, unlock so we can talk to SD card. +#ifdef EVT_TIME_PROFILE + prof.stop(); befSaveEvt=prof.read_us(); prof.start(); +#endif + SaveEvent(etms); + etms=0; - /* - } else { - printf("forced=%s, gFirstEvt=%s, e>t %d>%hu %s\r\n", - gEvent.IsForcedTrg()?"true":"false", gFirstEvt?"true":"false", - etms, gConf.GetEvtThrtlPeriodMs(), - etms>gConf.GetEvtThrtlPeriodMs() ? "true":"false"); - */ +#ifdef EVT_TIME_PROFILE + prof.stop(); aftSaveEvt=prof.read_us(); prof.start(); +#endif } } +#ifdef DEBUG printf("past reading out\r\n"); +#endif led4=0; led2=0; - + +#ifdef EVT_TIME_PROFILE + prof.stop(); befChkPow=prof.read_us(); prof.start(); +#endif // check the power? if (gCheckPower) { +#ifdef DEBUG printf("call check power\r\n"); +#endif CheckPower(false); } +#ifdef EVT_TIME_PROFILE + prof.stop(); aftChkPow=prof.read_us(); prof.start(); +#endif +#ifdef EVT_TIME_PROFILE + prof.stop(); befNewSeq=prof.read_us(); prof.start(); +#endif // make new seq? if (IsSeqComplete()) { +#ifdef DEBUG printf("seq complete. sngseq=%d\r\n",gConf.IsSingleSeqRunMode()); +#endif MakeOutputFile(gConf.IsSingleSeqRunMode()); } - +#ifdef EVT_TIME_PROFILE + prof.stop(); aftNewSeq=prof.read_us(); prof.start(); +#endif + // open comm win? if (gOpenCommWin) { +#ifdef DEBUG printf("gOpenComWin=%s, opening\r\n",gOpenCommWin?"true":"false"); +#endif OpenCommWin(); gOpenCommWin=false; } else { +#ifdef DEBUG printf("gOpenCommWin=false\r\n"); +#endif } + +#ifdef EVT_TIME_PROFILE + prof.stop(); endOfLoop=prof.read_us(); prof.start(); + printf("befReadWv=%d, aftReadWv=%d, befSaveEvt=%d, aftSaveEvt=%d, " + "befChkPow=%d, aftChkPow=%d, befNewSeq=%d, aftNewSeq=%d, endOfLoop=%d\r\n", + befReadWv, aftReadWv, befSaveEvt, aftSaveEvt, + befChkPow, aftChkPow, befNewSeq, aftNewSeq, endOfLoop); +#endif } } @@ -491,8 +588,10 @@ // void SaveEvent(const int32_t etms) { // write the event - + +#ifdef DEBUG printf("save event\r\n"); +#endif // set the event number & dt gEvent.SetEvtNum(gEvtNum); @@ -508,15 +607,21 @@ // increment event number ++gEvtNum; +#ifdef DEBUG printf("gEvtNum=%u\r\n",gEvtNum); +#endif } void MakeOutputFile(const bool stopRunning) { PIN_lockRegisters = 0; // unlock so we can talk to SD card. +#ifdef DEBUG printf("closing output file. gEvtNum=%u, gPowNum=%u, stop=%d\r\n", gEvtNum,gPowNum,(int)stopRunning); +#endif SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile()); +#ifdef DEBUG printf("file closed\r\n"); +#endif if (stopRunning) { StopRunning(); } @@ -525,14 +630,18 @@ if (cf!=0) { wait_ms(200); GetAvePowerReading(); +#ifdef DEBUG printf("writing power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u, pownum=%u\r\n", gPower.GetAveV1(), gPower.GetAveV2(), gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime(), gPowNum); +#endif SnSDUtils::WritePowerTo(cf, gPower, gPowNum); } +#ifdef DEBUG printf("made output file with run %u\r\n",gConf.GetRun()); printf("filename=%s\r\n",SnSDUtils::GetCurFileName()); +#endif SnSDUtils::WriteConfig(SnSDUtils::GetCurFile(), gConf); } @@ -561,16 +670,20 @@ wait_ms(10); } wait(1); +#ifdef DEBUG printf("set power (iscom %d, pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n", isCommWin, gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(), PIN_iridSbd_power.read(), PIN_afar_power.read()); +#endif } // // set configuration // void SetConfigAndMakeOutputFile() { +#ifdef DEBUG printf("SetConfigAndMakeOutputFile\r\n"); +#endif // restart watchdog Watchdog::kick(gConf.GetWatchdogPeriod()); @@ -602,11 +715,15 @@ SnConfigFrame::GetHiLoPlas(gConf.GetPla(pi), hi, lo); PIN_spi.write(hi); PIN_spi.write(lo); +#ifdef DEBUG printf("pla hi %hu, lo %hu\r\n",hi,lo); +#endif } else { PIN_spi.write(kNoTrigPla); // hi PIN_spi.write(kNoTrigPla); // lo +#ifdef DEBUG printf("pla hi %hu, lo %hu\r\n",kNoTrigPla,kNoTrigPla); +#endif } Watchdog::kick(); } @@ -625,7 +742,9 @@ // the card/dac# is encoded, the order is also important // 0000 (dac0,card0), 0001 (dac0,card1), 0011 (dac0,card3), 0010 (dac0,card2), // 0110 (dac1,card2), 0111 (dac1,card3), 0101 (dac1,card1), etc. +#ifdef DEBUG printf("setting dacs\r\n"); +#endif uint16_t dv=0; for (uint8_t i=0, gri=0; i<kTotDacs; i++) { // get the gray-codes for this iteration @@ -636,7 +755,9 @@ dv <<= 4u; dv |= gri; +#ifdef DEBUG printf("dac %04x\r\n",dv); +#endif // send to FPGA PIN_start_fpga=1; @@ -646,10 +767,14 @@ Watchdog::kick(); } +#ifdef DEBUG printf("dacs set\r\n"); +#endif wait_ms(20); } else { +#ifdef DEBUG printf("cards off. skipping PLA and DAC setting\r\n"); +#endif } // Majority Logic Trigger selection (# of cards) @@ -687,10 +812,12 @@ const uint32_t pcp = resetTicker(gPowerCheckTicker, gConf.GetVoltCheckPeriod(), kAbsMaxTimer, &procPowerCheck); #endif +#ifdef DEBUG printf("attach force trig %u\r\n",ftp); printf("attach heart beat %u\r\n",hbp); printf("attach comm win %u\r\n",cwp); printf("attach power chk %u\r\n",pcp); +#endif // TODO: change comm parameters /* @@ -704,7 +831,9 @@ Watchdog::kick(); // don't reset! +#ifdef DEBUG printf("set config done\r\n"); +#endif } // @@ -712,11 +841,13 @@ // void WaitTrigAndSendClock() { +#ifdef DEBUG printf("WaitTrigAndSendClock\r\n"); printf("wait trig: (pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n", gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(), PIN_iridSbd_power.read(), PIN_afar_power.read()); printf("cards powered=%d\r\n",(int)AreCardsPowered()); +#endif if (AreCardsPowered()) { @@ -732,16 +863,22 @@ // // wait for a trigger here. // +#ifdef DEBUG printf("starting wait for trig\r\n"); +#endif gReadingOut = false; // this will allow forced triggers (see procForceTrigger()) while ( PIN_a_sf_clk == 1 ) { if (gOpenCommWin || gCheckPower) { +#ifdef DEBUG printf("break com=%d, pow=%d\r\n",gOpenCommWin,gCheckPower); +#endif return; // break out to open comms or check power } } +#ifdef DEBUG printf("starting readout. force=%d, clk=%d\r\n", PIN_forceTrigger.read(), PIN_a_sf_clk.read()); +#endif PIN_forceTrigger=0; // necessary for forced triggers, harmless for other triggers gReadingOut = true; // disallow new forced triggers // @@ -783,11 +920,15 @@ gCommWinOpen = true; Watchdog::kick(); // don't reset! +#ifdef DEBUG printf("opening comm window at %d\r\n", (int32_t)gLastCommWin); +#endif // close the file so that the data is all written out. // and open it back up at the beginning (for reading) +#ifdef DEBUG printf("close & open file. gEvtNum=%u, gPowNum=%u\r\n",gEvtNum,gPowNum); +#endif PIN_lockRegisters = 0; // unlock so we can talk to SD card. SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile()); SnSDUtils::OpenExistingFile(SnSDUtils::GetCurFileName(), true); @@ -820,9 +961,11 @@ continue; } // open window and (mabye) send status update +#ifdef DEBUG printf("calling OpenWindow. ss=%d\r\n",(int)(*ss)); printf("gtt=%u, ct=%d, lcw=%d, dur=%u\r\n",GetTimeoutTime(gLastCommWin,conto), time(0), gLastCommWin, gConf.GetCommWinDuration()); +#endif // update power reading in case we want to send it in status GetAvePowerReading(); // get the trigger rates @@ -836,24 +979,40 @@ Watchdog::kick(); // don't reset! // connected. listen for config *ss = false; // don't send status next time +#ifdef DEBUG + printf("get conf gtt=%u\r\n",GetTimeoutTime(gLastCommWin, listo)); +#endif const SnCommWin::ECommWinResult cfgres = (*cw)->GetConfig( gConf, GetTimeoutTime(gLastCommWin, listo), gGenBuf, gBufSize); if (cfgres>=SnCommWin::kOkWithMsg) { Watchdog::kick(); // don't reset! +#ifdef DEBUG printf("received config!\r\n"); + printf("send data = %d\r\n", gConf.GetCommSendData()); +#endif // send data if need be (files, some events, etc) - printf("send data = %d\r\n", gConf.GetCommSendData()); + const uint32_t winto = GetTimeoutTime(gLastCommWin, + gConf.GetCommWinDuration()); + const uint32_t gtt = gConf.IsObeyingTimeout() ? winto : 0; if (gConf.GetCommSendData()!=0) { - printf("sending data\r\n"); +#ifdef DEBUG + printf("sending data, gtt=%u. lcw=%u, dur=%u, obey=%s\r\n", + GetTimeoutTime(gLastCommWin, gConf.GetCommWinDuration()), + gLastCommWin, gConf.GetCommWinDuration(), + gConf.IsObeyingTimeout() ? "true" : "false"); +#endif res = (*cw)->SendData(gConf, gEvent, gPower, gGenBuf, gBufSize, - GetTimeoutTime(gLastCommWin, gConf.GetCommWinDuration())); + gtt, winto); } else { // don't send anything res = cfgres; } +#ifdef DEBUG printf("Got config!\r\n"); - gotNewConfig=true; +#endif + gotNewConfig = (cfgres!=SnCommWin::kOkWthMsgNoConf); Watchdog::kick(); // don't reset! + (*cw)->CloseConn(); break; } } @@ -861,7 +1020,7 @@ Watchdog::kick(); // don't reset! } - + // (probably) power down comms and power up cards,amps SetPower(false); @@ -869,11 +1028,16 @@ // reset config with system powered (for DAC/PLA setting) if (gotNewConfig) { +#ifdef DEBUG printf("calling SetConfigAndMakeOutputFile\r\n"); +#endif SetConfigAndMakeOutputFile(); - // TODO: remove + } else { + MakeOutputFile(); } +#ifdef DEBUG printf("closing comm win at %d\r\n",(int32_t)time(0)); +#endif gCommWinOpen = false; return res;