Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

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;