• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

roclib/src_nxyter/QuickDaq.cxx (r4864/r4196)

Go to the documentation of this file.
00001 //============================================================================
00005 //============================================================================
00006 
00007 #include "nxyter/QuickDaq.h"
00008 
00009 #include <sys/time.h>
00010 #include <time.h>
00011 
00012 #include <iostream>
00013 #include <stdexcept>
00014 
00015 #include "roc/UdpBoard.h"
00016 
00017 
00024 //----------------------------------------------------------------------------
00026 
00031 nxyter::QuickDaq::QuickDaq(base::Board* board) :
00032   fBoard(board),
00033   fRocNx(board),
00034   fState(kDaqStopped),
00035   fStopCode(kDaqStopPending),
00036   fDaqLowWater(250),                        // 250 kB low water
00037   fDaqHighWater(500),                       // 500 kB high water
00038   fDaqFlushTimer(100),                      // 100 msec flush timer
00039   fDaqStaStoTimeout(1.),                    // 1 sec start/stop timeout
00040   fNextNxMaskActive(false), fNextNxMask(0),
00041   fStartTime(0.), fStopTime(0.),
00042   fStartMsgTime(0.), fStopMsgTime(0.),
00043   fMaxMsg(0.), fMaxTime(0.),
00044   fIter(board),
00045   fMsgTime(0.), fNowTime(0.)
00046 {
00047   fFebs[0] = 0;
00048   fFebs[1] = 0;
00049 }
00050 
00051 //----------------------------------------------------------------------------
00053 
00063 nxyter::QuickDaq::QuickDaq(nxyter::FebBase* feb0, nxyter::FebBase* feb1) :
00064   fBoard(feb0 ? feb0->getBoard() : (feb1 ? feb1->getBoard() : 0)),
00065   fRocNx(fBoard),
00066   fState(kDaqStopped),
00067   fStopCode(kDaqStopPending),
00068   fDaqLowWater(250),                        // 250 kB low water
00069   fDaqHighWater(500),                       // 500 kB high water
00070   fDaqFlushTimer(100),                      // 100 msec flush timer
00071   fDaqStaStoTimeout(1.),                    // 1 sec start/stop timeout
00072   fNextNxMaskActive(false), fNextNxMask(0),
00073   fStartTime(0.), fStopTime(0.),
00074   fStartMsgTime(0.), fStopMsgTime(0.),
00075   fMaxMsg(0.), fMaxTime(0.),
00076   fIter(fBoard),
00077   fMsgTime(0.),
00078   fNowTime(0.)
00079 {
00080   if (!fBoard)
00081     throw std::runtime_error("not any FEB specified");
00082 
00083   if (feb0 && feb1 && (feb0->getBoard() != feb1->getBoard()))
00084     throw std::runtime_error("FEB not hosted by same board");
00085 
00086    fFebs[0] = feb0;
00087    fFebs[1] = feb1;
00088 }
00089 
00090 //----------------------------------------------------------------------------
00095 nxyter::QuickDaq::~QuickDaq()
00096 {
00097   // if still running, stop it
00098   if (fState == kDaqRunning) {
00099     stopRun(true);
00100   }
00101 }
00102 
00103 //----------------------------------------------------------------------------
00105 
00115 int nxyter::QuickDaq::setNxTestModes(bool testpuls, bool testtrig, 
00116                                      int calselect)
00117 {
00118   for (int i=0; i<2; i++) {
00119     if (fFebs[i]) {
00120       int rc = fFebs[i]->setNxTestModes(testpuls, testtrig, calselect);
00121       if (rc) return base::Board::operErrBuildInc(rc, 10*i);
00122     }
00123   }
00124   return 0;
00125 }
00126 
00127 //----------------------------------------------------------------------------
00129 
00137 int nxyter::QuickDaq::setNxRegisterAll(uint8_t reg, uint8_t val, bool veri)
00138 {
00139   for (int i=0; i<2; i++) {
00140     if (fFebs[i]) {
00141       int rc = fFebs[i]->setNxRegisterAll(reg, val, veri);
00142       if (rc) return base::Board::operErrBuildInc(rc, 10*i);
00143     }
00144   }
00145   return 0;
00146 }
00147 
00148 //----------------------------------------------------------------------------
00150 
00151 void nxyter::QuickDaq::nextRunNxMask(int nxmask)
00152 {
00153   fNextNxMaskActive = true;
00154   fNextNxMask = nxmask;
00155 }
00156 
00157 //----------------------------------------------------------------------------
00159 
00163 int nxyter::QuickDaq::startRun(int maxmsg, double maxtime, bool noinit)
00164 {
00165   fMaxMsg  = double(maxmsg);
00166   fMaxTime = maxtime;
00167   fStats.clear();
00168 
00169   stopRun(true);
00170 
00171   if (!fBoard->stopDaq()) {
00172      fBoard->Debug(-1, "Cannot StopDaq - break QuickDaq");
00173      return 1;
00174   }
00175 
00176   if (noinit == false) {
00177     fRocNx.setNxActive(0);
00178     for (int i=0; i<2; i++) {
00179       if (fFebs[i]) fFebs[i]->initRoc();
00180     }
00181     if (fNextNxMaskActive) {
00182       uint32_t rocnxmask;
00183       fRocNx.getNxActive(rocnxmask);
00184       fRocNx.setNxActive(rocnxmask & fNextNxMask);
00185     }
00186   }
00187 
00188 
00189   // set timeout to flush data from internal buffer of driver
00190   // should reduce time for transfer of last data before stop daq
00191   roc::UdpBoard* udp = dynamic_cast<roc::UdpBoard*> (fBoard);
00192   roc::Board* rocbrd = dynamic_cast<roc::Board*> (fBoard);
00193 
00194   if (udp) {
00195      udp->setRocLowHighWater(fDaqLowWater, fDaqHighWater);
00196      udp->setRocBufferFlushTimer(fDaqFlushTimer);
00197      udp->setFlushTimeout(fDaqFlushTimer>10 ? fDaqFlushTimer/1000. : 0.01);
00198   } else
00199      fBoard->setFlushTimeout(0.01);
00200 
00201   if (rocbrd)
00202      if (rocbrd->uploadStartDaqCmdList(!noinit)) {
00203         rocbrd->Debug(-1, "Cannot init startdaq sequence - break QuickDaq");
00204         return 1;
00205      }
00206 
00207   if (!fBoard->startDaq()) {
00208      fBoard->Debug(-1, "Cannot StartDaq - break QuickDaq");
00209      return 1;
00210   }
00211 
00212   fState = kDaqStarting;
00213   fStopCode = kDaqStopPending;
00214   fStartTime = now();
00215 
00216   if (fBoard->isFile()) {
00217      fState = kDaqRunning;
00218      fStartMsgTime = now();
00219   }
00220 
00221   // now reset all 'next run' conditions
00222   fNextNxMaskActive = false;
00223   fNextNxMask = 0;
00224 
00225   return 0;
00226 }
00227 
00228 //----------------------------------------------------------------------------
00230 
00234 int nxyter::QuickDaq::stopRun(bool hardstop)
00235 {
00236   if (fState == kDaqStarting || fState == kDaqRunning) {
00237     fBoard->suspendDaq();                     // FIXME ret codes
00238     fState = kDaqStopping;
00239     if (fStopCode == kDaqStopPending) fStopCode = kDaqStopByStop;
00240     fStopTime = now();
00241   }
00242   
00243   if (hardstop) {
00244     // for a hard stop, make an effort to drain the buffers
00245     // this is needed when used with KNUT
00246     // FIXME: do we need this with DABC transport ?
00247     while ((fState == kDaqStopping) && (now() < fStopTime+0.1)) {
00248       bool valid = fIter.next(0.05);
00249       if (!valid) break;
00250     }
00251   }
00252   
00253   return 0;
00254 }
00255 
00256 //----------------------------------------------------------------------------
00258 
00288 void nxyter::QuickDaq::interruptRun()
00289 {
00290   // Note: this will typically called from a SIGINT signal handler
00291   //       thus simply set a flag, but no other calls...
00292   if (fState != kDaqStopped) fStopCode = kDaqStopByInterrupt;
00293 }
00294 
00295 //----------------------------------------------------------------------------
00297 
00298 bool nxyter::QuickDaq::testRun(double timeout)
00299 {
00300   double timein = 0.;
00301 
00302   while(true) {
00303 
00304     fNowTime = now();
00305     if (timein == 0.) timein = fNowTime;
00306     
00307     // if daq stopped, quit
00308     if (fState == kDaqStopped) return false;
00309 
00310     // if interrupted, cleanup and quit
00311     if (fStopCode == kDaqStopByInterrupt) {
00312       stopRun(true);
00313       return false;
00314     }
00315 
00316     // daq not starting, bail out
00317     if (fState==kDaqStarting && fNowTime>=fStartTime+fDaqStaStoTimeout) {
00318        std::cout << "+++ daq not starting, bail out" << std::endl;
00319        fStopCode = kDaqStopByTimeout;
00320        stopRun(true);
00321        return false;
00322     }
00323 
00324     // daq not stopping, bail out
00325     if (fState==kDaqStopping && fNowTime>=fStopTime+fDaqStaStoTimeout) {
00326        std::cout << "+++ daq not stopping, bail out" << std::endl;
00327        fStopCode = kDaqStopByTimeout;
00328        stopRun(true);
00329        return false;
00330     }
00331     
00332     // check for message limit
00333     if (fMaxMsg > 0. &&
00334         fStats[nxyter::QuickDaqStats::kNMessage] >= fMaxMsg) {
00335       if (fStopCode == kDaqStopPending) fStopCode = kDaqStopByCount;
00336       stopRun(true);
00337       return false;
00338     }
00339 
00340     // check for time limit
00341     if (fState==kDaqRunning) {
00342       if ((fMaxTime > 0.) && (fNowTime >= fStartMsgTime+fMaxTime)) {
00343         stopRun();
00344         if (fStopCode == kDaqStopPending) fStopCode = kDaqStopByTime;
00345       }
00346     }
00347     
00348     bool valid = fIter.next(0.02);
00349 
00350     if (valid) {
00351 
00352       roc::Message& msg = fIter.msg();
00353       fStats.increment(msg);
00354       
00355       if (msg.isStartDaqMsg()) {
00356         fState = kDaqRunning;
00357         fStartMsgTime = now();
00358       } else if (msg.isStopDaqMsg()) {
00359         fState = kDaqStopped;
00360         fStopMsgTime = now();
00361       } 
00362       
00363       fMsgTime = fIter.getMsgFullTimeD() * 1.e-9;
00364 
00365     } else {
00366 
00367       if (fBoard->isFile()) {
00368          fState = kDaqStopped;
00369          fStopMsgTime = now();
00370          return true;
00371       }
00372     }
00373 
00374     double time = now();
00375     bool tmo = (timeout > 0. && time-timein > timeout);
00376     fNowTime = time;
00377 
00378     if (valid || tmo) return true;
00379   }
00380 }
00381 
00382 //----------------------------------------------------------------------------
00384 
00385 double nxyter::QuickDaq::now()
00386 {
00387   struct timeval tv;
00388   gettimeofday(&tv, 0);
00389   return double(tv.tv_sec) + 1.e-6*double(tv.tv_usec);
00390 }
00391 
00392 //----------------------------------------------------------------------------

Generated on Tue Dec 10 2013 04:52:23 for ROCsoft by  doxygen 1.7.1