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),
00037 fDaqHighWater(500),
00038 fDaqFlushTimer(100),
00039 fDaqStaStoTimeout(1.),
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),
00069 fDaqHighWater(500),
00070 fDaqFlushTimer(100),
00071 fDaqStaStoTimeout(1.),
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
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
00190
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
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();
00238 fState = kDaqStopping;
00239 if (fStopCode == kDaqStopPending) fStopCode = kDaqStopByStop;
00240 fStopTime = now();
00241 }
00242
00243 if (hardstop) {
00244
00245
00246
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
00291
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
00308 if (fState == kDaqStopped) return false;
00309
00310
00311 if (fStopCode == kDaqStopByInterrupt) {
00312 stopRun(true);
00313 return false;
00314 }
00315
00316
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
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
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
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