Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Revision:
3:24c5f0f50bf1
Parent:
2:e67f7c158087
Child:
4:a91682e19d6b
--- a/main.cpp	Tue Jul 24 02:07:23 2012 +0000
+++ b/main.cpp	Tue Jul 31 04:59:16 2012 +0000
@@ -60,10 +60,13 @@
 // Setup SPI pins
 SPI PIN_spi( p5, p6, p7 );
 // The SD card
+
+// this needs to be first in case some other global uses a print statement
+static MODSERIAL      gCpu( USBTX, USBRX ); // defined here so it might be used for debugging output
+
 SDFileSystem sd(p5, p6, p7, p8, SnSDUtils::kSDsubDir+1);
 LocalFileSystem local("local");
 
-
 //
 // fwd declare fcns
 //
@@ -73,12 +76,14 @@
 void                      WaitTrigAndSendClock();
 void                      SetConfigAndMakeOutputFile();
 SnCommWin::ECommWinResult OpenCommWin();
+void                      MakeOutputFile(const bool stopRunning=false);
 
 //
 // globals
 //
 // readout objs
 static Ticker         gForceTicker;
+static Ticker         gHeartbeatTicker;
 static Ticker         gCommWinTicker;
 static Timer          gEvtTimer;
 static SnConfigFrame  gConf;
@@ -92,17 +97,16 @@
 static int32_t        gTrgNum[kNumTrgs] = {0}; // num of this type of trg received
 // i/o
 static time_t         gLastCommWin      = 0;
-static MODSERIAL      gCpu( USBTX, USBRX ); // defined here so it might be used for debugging output
+static const uint32_t gBufSize=SnStatusFrame::kMaxSizeOf + SnHeaderFrame::kMaxSizeOf;
+static const uint32_t gB64Bsize=BASE64ENC_LEN(gBufSize)+1;
+static char           gB64Buf[gB64Bsize];
+static char           gGenBuf[gBufSize]; // must be big enough for event or status or config!
 //static SnCommWin*     gComms[kNcomms]   = { new SnCommAfar, new SnCommUsb(&gCpu) }; // order => priority
 //static SnCommWin*     gComms[kNcomms]   = { new SnCommUsb(&gCpu) }; // order => priority
-static SnCommWin*     gComms[kNcomms]   = { new SnCommAfar }; // order => priority
-//static char           gEvtBuf[SnEventFrame::kMaxSizeOf];
-//static char           gConfBuf[SnConfigFrame::kMaxSizeOf];
-//static char           gStatBuf[SnStatusFrame::kMaxSizeOf];
-static char           gGenBuf[SnStatusFrame::kMaxSizeOf + SnHeaderFrame::kMaxSizeOf]; // must be big enough for event or status or config!
+static SnCommWin*     gComms[kNcomms]   = { new SnCommAfar(gB64Buf, gB64Bsize) }; // order => priority
 
 void procForceTrigger() {
-    //led1=!led1;
+    led3=!led3;
     if (gReadingOut==false && gCommWinOpen==false) {
         gEvent.SetTrgBit(kFrcTrg);
         gEvent.SetTrgNum((gTrgNum[kFrcTrg])++);
@@ -110,6 +114,13 @@
     }
 }
 
+void procHeartbeat() {
+    if (gReadingOut==false && gCommWinOpen==false) {
+        PIN_heartbeat = 1; // heartbeat pulse
+        PIN_heartbeat = 0;
+    }
+}
+
 void procCommWin() {
     if (gReadingOut==false && gCommWinOpen==false) {
         if ( (time(0) - gLastCommWin) > gConf.GetCommWinPeriod() ) {
@@ -147,7 +158,7 @@
     led2=1;
     //wait_ms(100);
     
-    printf("starting\r\n");
+    printf("\n\n\n\n\n\nstarting\r\n");
         
     // a failsafe
     Watchdog::kick(kWDFailsafe);
@@ -162,22 +173,22 @@
     gForceTicker.detach();
     gFirstEvt = true;
     
-    gConf.Reset();
+    printf("Using config %s\r\n",gConf.GetLabel());
     SetConfigAndMakeOutputFile(); // setup defaults in case no communication
     
     //
     // get config
     //
-    printf("open window\r\n");
+    //printf("open window\r\n");
     OpenCommWin();
-
+    
     // get ready to trigger
     PIN_spi.format( 16, 1 ); // change to data readout format
 
     led2=0;
     
-    bool restartEvtTimer=true;
     // the main event loop. wait for triggers in SendClock
+    gEvtTimer.start();
     while( true )
     {
         // in here, we wait for triggers from the MB-FPGA
@@ -188,16 +199,12 @@
         printf("calling wait trig\r\n");
         printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
 
-        if (restartEvtTimer) {
-            gEvtTimer.reset();
-            gEvtTimer.start();
-            restartEvtTimer=false;
-        }
         PIN_lockRegisters = 0; // allow data to come from DFPGA
         WaitTrigAndSendClock();
         PIN_lockRegisters = 1; // block registers during readout
         
-        const int32_t etms = gEvtTimer.read_ms(); // but don't stop the timer!
+        const int32_t etms = gEvtTimer.read_ms(); // time since last trigger
+        gEvtTimer.reset(); gEvtTimer.start();     // start counter from this trigger
         
         printf("wait trig send clock exited\r\n");
                 
@@ -232,14 +239,18 @@
                 
                 PIN_lockRegisters = 0; // done reading, unlock so we can talk to SD card.
                 
-                printf("save event\r\n");
                 SaveEvent(etms);
-                restartEvtTimer=true;
+
+                if (gEvtNum>=(gConf.GetFirstEvt()+gConf.GetEvtsPerFile())) {
+                    MakeOutputFile(gConf.IsSingleSeqRunMode());
+                }
+            /*
             } 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");
+            */
             }
         }
         printf("past reading out\r\n");
@@ -263,8 +274,10 @@
 void SaveEvent(const int32_t etms) {
     // write the event
         
+    printf("save event\r\n");
+
     // set the event number & dt
-    gEvent.SetEvtNum(gEvtNum++);
+    gEvent.SetEvtNum(gEvtNum);
     gEvent.SetDTms(etms);
     
     // save to SD
@@ -273,9 +286,15 @@
     // reset
     gEvent.ClearEvent();
     
+    // increment event number
+    ++gEvtNum;
+    
     printf("gEvtNum=%d\r\n",gEvtNum);
-    if (gEvtNum==10) {
-        fclose(SnSDUtils::GetCurFile());
+}
+
+void MakeOutputFile(const bool stopRunning) {
+    SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
+    if (stopRunning) {
         while (true) {
             led3 = 1; led4=1;
             wait(0.5);
@@ -284,7 +303,11 @@
             Watchdog::kick();
         }
     }
-    
+    SnSDUtils::OpenNewOutputFile(gConf.GetMacAddress(),
+                                 gConf.GetRun());
+    printf("made output file with run %u\r\n",gConf.GetRun());
+    printf("filename=%s\r\n",SnSDUtils::GetCurFileName());
+    SnSDUtils::WriteConfig(SnSDUtils::GetCurFile(), gConf);
 }
 
 //
@@ -301,6 +324,7 @@
     PIN_ADC_CS                = 1;
     PIN_DoNotRestartAllClocks = 1;
     PIN_forceTrigger          = 0;
+    PIN_heartbeat             = 0;
     wait_ms(20);
     
     // reset event, timers, trigger counters
@@ -309,12 +333,7 @@
     memset(gTrgNum, 0, sizeof(int32_t)*kNumTrgs);
     
     // make new output file
-    SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
-    SnSDUtils::OpenNewOutputFile(gConf.GetMacAddress(),
-                                 gConf.GetRun());
-    printf("made output file with run %u\r\n",gConf.GetRun());
-    printf("filename=%s\r\n",SnSDUtils::GetCurFileName());
-    SnSDUtils::WriteConfig(SnSDUtils::GetCurFile(), gConf);
+    MakeOutputFile();
     
     // TODO: turn on amps individually, when that's possible
     PIN_turn_on_amps = gConf.IsEachAmpOn() ? 0 : 1;
@@ -334,9 +353,11 @@
             SnConfigFrame::GetHiLoPlas(gConf.GetPla(pi), hi, lo);
             PIN_spi.write(hi);
             PIN_spi.write(lo);
+            printf("pla hi %hu, lo %hu\r\n",hi,lo);
         } else {
             PIN_spi.write(kNoTrigPla); // hi
             PIN_spi.write(kNoTrigPla); // lo
+            printf("pla hi %hu, lo %hu\r\n",kNoTrigPla,kNoTrigPla);
         }
         Watchdog::kick();
     }
@@ -391,9 +412,18 @@
 
     // force a trigger every...
     gForceTicker.detach();
-    gForceTicker.attach(&procForceTrigger, 
-        gConf.GetForceTrigPeriod() > kAbsMaxTimer ?
-        kAbsMaxTimer : gConf.GetForceTrigPeriod()); // force period has a maximum
+    if (gConf.GetForceTrigPeriod()>0) {
+        gForceTicker.attach(&procForceTrigger, 
+            gConf.GetForceTrigPeriod() > kAbsMaxTimer ?
+            kAbsMaxTimer : gConf.GetForceTrigPeriod()); // force period has a maximum
+    }
+    // heartbeat every ...
+    gHeartbeatTicker.detach();
+    if (gConf.GetHeartbeatPeriod()>0) {
+        gHeartbeatTicker.attach(&procHeartbeat,
+            gConf.GetHeartbeatPeriod() > kAbsMaxTimer ?
+            kAbsMaxTimer : gConf.GetHeartbeatPeriod());
+    }
     // proc a comm win every...
     gCommWinTicker.detach();
     gCommWinTicker.attach(&procCommWin,
@@ -461,11 +491,22 @@
     //  a) try to connect
     //  b) if connected, listen for config
     //  c) if config requests data, send it
+
+    gLastCommWin = time(0);
+    if (gConf.GetCommWinDuration()==0) {
+        // TODO: set min so this is not possible
+        return SnCommWin::kOkNoMsg;
+    }
     
     gCommWinOpen = true;
     Watchdog::kick(); // don't reset!
     
-    printf("opening comm window at %d\r\n", (int32_t)time(0));
+    printf("opening comm window at %d\r\n", (int32_t)gLastCommWin);
+    
+    // close the file so that the data is all written out.
+    // and open it back up at the beginning (for reading)
+    SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
+    SnSDUtils::OpenExistingFile(SnSDUtils::GetCurFileName(), true);
     
     // power system down
     PIN_turn_on_system = 1;
@@ -482,8 +523,6 @@
     const uint32_t listo = (gConf.GetCommWinDuration() < kListenTimeout) ?
         gConf.GetCommWinDuration() : kListenTimeout;
     
-    gLastCommWin = time(0);
-    
     SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
     
     bool gotNewConfig=false;
@@ -511,20 +550,22 @@
             // connected. listen for config
             *ss = false; // don't send status next time
             const SnCommWin::ECommWinResult cfgres = (*cw)->GetConfig(
-                gConf, GetTimeoutTime(gLastCommWin, listo), gGenBuf);
+                gConf, GetTimeoutTime(gLastCommWin, listo), gGenBuf, gBufSize);
             if (cfgres>=SnCommWin::kOkWithMsg) {
                 Watchdog::kick(); // don't reset!
-                printf("received config!\r\n");
+                printf("received config (%u)!\r\n",gConf.SizeOf());
                 char* b = gGenBuf;
                 gConf.WriteTo(b);
-                for (uint32_t i=0; i<gConf.SizeOf(); i++) {
+                const uint32_t csz = gConf.SizeOf();
+                for (uint32_t i=0; i<csz; i++) {
                     printf("%02x ",gGenBuf[i]);
                 }
                 printf("\r\n");
                 // send data if need be (files, some events, etc)
+                printf("send data = %d\r\n", gConf.GetCommSendData());
                 if (gConf.GetCommSendData()!=0) {
-                    
-                    res = (*cw)->SendData(gConf, gEvent, gGenBuf,
+                    printf("sending data\r\n");
+                    res = (*cw)->SendData(gConf, gEvent, gGenBuf, gBufSize,
                         GetTimeoutTime(gLastCommWin, gConf.GetCommWinDuration()));
                 } else {
                     // don't send anything