00001
00005
00006
00007 #include "nxyter/FebUtil.h"
00008
00009 #include <stdlib.h>
00010 #include <stdio.h>
00011 #include <sys/time.h>
00012 #include <time.h>
00013
00014 #include <stdexcept>
00015 #include <memory>
00016
00017 #include "base/Gpio.h"
00018 #include "nxyter/RocNx.h"
00019 #include "nxyter/NxContext.h"
00020 #include "nxyter/DistFuncArray.h"
00021
00028
00030
00031 nxyter::FebUtil::FebUtil(FebBase* feb, QuickDaq* qdaq) :
00032 fFeb(feb),
00033 fQdaq(qdaq),
00034 fLoopState(kLoopStopped),
00035 fStartLoopTime(0.),
00036 fTestLoopTime(0.),
00037 fTestTime(0.),
00038 fLoopCount(0)
00039 {
00040 }
00041
00042
00043
00044 nxyter::FebUtil::~FebUtil()
00045 {
00046 }
00047
00048
00050
00060 void nxyter::FebUtil::startLoop(double time)
00061 {
00062 fLoopState = kLoopRunning;
00063 fStartLoopTime = now();
00064 fTestTime = time;
00065 fLoopCount = 0;
00066 }
00067
00068
00070
00105 void nxyter::FebUtil::interruptLoop()
00106 {
00107 if (fLoopState == kLoopRunning) fLoopState = kLoopInterrupted;
00108 }
00109
00110
00112
00125 void nxyter::FebUtil::stopLoop()
00126 {
00127 if (fLoopState == kLoopRunning) fLoopState = kLoopStopped;
00128 }
00129
00130
00132
00148 bool nxyter::FebUtil::testLoop()
00149 {
00150 if (fLoopState != kLoopRunning) return false;
00151 fTestLoopTime = now();
00152 if (fLoopCount>0 &&
00153 fTestTime>0. &&
00154 fTestLoopTime > fStartLoopTime + fTestTime) return false;
00155 fLoopCount++;
00156 return true;
00157 }
00158
00159
00161
00175 int nxyter::FebUtil::saveFeb(nxyter::NxContext cntx[4], int domask)
00176 {
00177 if (fFeb==0) return -1;
00178
00179 int rc;
00180 for (int i=0; i<fFeb->numNx(); i++) {
00181 if (fFeb->getNxOffline(i)) continue;
00182 rc = fFeb->nx(i).i2c().getContext(cntx[i], domask);
00183 if (rc) return rc;
00184 }
00185 return 0;
00186 }
00187
00188
00190
00204 int nxyter::FebUtil::restoreFeb(nxyter::NxContext cntx[4], int domask)
00205 {
00206 if (fFeb==0) return -1;
00207
00208 int rc;
00209 for (int i=0; i<fFeb->numNx(); i++) {
00210 if (fFeb->getNxOffline(i)) continue;
00211 rc = fFeb->nx(i).i2c().setContext(cntx[i], domask, true);
00212 if (rc) return rc;
00213 }
00214 return 0;
00215 }
00216
00217
00219
00236 int nxyter::FebUtil::acquireTestTriggerData(int nxind, int npuls,
00237 DistFuncArray& dfa, bool cleardist)
00238 {
00239 if (fFeb==0 || fQdaq==0) return -1;
00240
00241 base::Gpio gpio(fFeb->getBoard());
00242 nxyter::RocNx rocnx(fFeb->getBoard());
00243
00244 int nxnum = fFeb->nx(nxind).getNxNumber();
00245 double time = double(npuls) / 2500.;
00246
00247 if (cleardist) dfa.clear();
00248
00249 rocnx.fireTestPulse(0,0,0);
00250
00251 uint32_t save_gpiomask;
00252 gpio.getConfig(save_gpiomask);
00253 uint32_t new_gpiomask = save_gpiomask;
00254 gpio.packConfig(new_gpiomask, 6, false, false, false, true, true);
00255 gpio.setConfig(new_gpiomask);
00256
00257 fQdaq->nextRunNxMask(1<<nxnum);
00258 fQdaq->startRun(0, time);
00259
00260 rocnx.fireTestPulse(100000,50000,npuls);
00261
00262 while(fQdaq->testRun()) {
00263 roc::Message& msg = fQdaq->msg();
00264
00265 if (msg.isHitMsg()) {
00266 int num = msg.getNxNumber();
00267 if (num == nxnum) {
00268 int cha = msg.getNxChNum();
00269 int adc = msg.getNxAdcValue();
00270 dfa.addEntry(cha, float(adc));
00271 }
00272 }
00273 }
00274
00275 if (fQdaq->stats().errorCount()) {
00276 fQdaq->stats().print(std::cout, 0., nxyter::QuickDaqStats::kPrintError);
00277 }
00278
00279 gpio.setConfig(save_gpiomask);
00280
00281 return 0;
00282 }
00283
00284
00286
00291 int nxyter::FebUtil::acquireTestTriggerData(int nxind, int npuls,
00292 NxDataSummary& nds)
00293 {
00294 DistFuncArray dfa(128, npuls);
00295 dfa.setMaxEntries(2*npuls);
00296 int rc = acquireTestTriggerData(nxind, npuls, dfa);
00297 nds.analyse(dfa);
00298 return rc;
00299 }
00300
00301
00303
00320 int nxyter::FebUtil::acquireTestPulserData(int nxind, const nxyter::NxContext& cntx,
00321 int npuls, DistFuncArray& dfa)
00322 {
00323 if (fFeb==0 || fQdaq==0) return -1;
00324
00325 int rc;
00326 uint8_t conf1;
00327 rc = fFeb->nx(nxind).i2c().getRegister(kNxRegConfig1, conf1);
00328 if (rc) return rc;
00329
00330 for (int csel=0; csel<=3; csel++) {
00331 NxContext cntx_run(cntx);
00332
00333
00334 for (int ch=0; ch<128; ch++) {
00335 if ((ch & 0x3) != csel) cntx_run.setChannelMaskBit(ch, true);
00336 }
00337
00338
00339 rc = fFeb->nx(nxind).i2c().setContext(cntx_run, nxyter::kDoMask, false);
00340 if (rc) return rc;
00341
00342
00343 conf1 &= ~kNxC1CalibSelectMask;
00344 conf1 |= uint8_t(csel);
00345 rc = fFeb->nx(nxind).i2c().setRegister(kNxRegConfig1, conf1, true);
00346 if (rc) return rc;
00347
00348 rc = acquireTestTriggerData(nxind, npuls, dfa, csel==0);
00349 if (rc) return rc;
00350 }
00351
00352 return 0;
00353 }
00354
00355
00357
00363 int nxyter::FebUtil::acquireTestPulserData(int nxind, const nxyter::NxContext& cntx,
00364 int npuls, NxDataSummary& nds)
00365 {
00366 DistFuncArray dfa(128, npuls);
00367 dfa.setMaxEntries(20*npuls);
00368 int rc = acquireTestPulserData(nxind, cntx, npuls, dfa);
00369 nds.analyse(dfa);
00370 return rc;
00371 }
00372
00373
00375
00381 int nxyter::FebUtil::testNxControlPath(int nxind, double time)
00382 {
00383 if (fFeb == 0) return -1;
00384 int errcnt = 0;
00385 startLoop(time);
00386 while(testLoop()) {
00387 int rc = fFeb->nx(nxind).i2c().probe();
00388 if (rc) {
00389 errcnt++;
00390 std::cout << errcnt << ":" << base::Board::operErrToString(rc) << std::endl;
00391 }
00392 }
00393 return errcnt;
00394 }
00395
00396
00398
00403 int nxyter::FebUtil::testNxRegisters(int nxind)
00404 {
00405 if (fFeb == 0) return -1;
00406 int errcnt = 0;
00407
00408 int rc;
00409 nxyter::NxContext cntx_save;
00410
00411 rc = fFeb->nx(nxind).i2c().getContext(cntx_save, kDoAll);
00412 if (rc) {
00413 errcnt++;
00414 std::cout << errcnt << ": getContext({save}): "
00415 << base::Board::operErrToString(rc) << std::endl;
00416 }
00417
00418 startLoop(0.);
00419
00420
00421 static const uint8_t reglist[] =
00422 { 0, 1, 2, 3, 4, 5, 6, 7,
00423 8, 9, 10, 11, 12, 13, 14, 15,
00424 16, 17, 18, 19, 20, 21, 22, 23,
00425 24, 25, 26, 27, 28, 29,
00426 38, 39, 43, 44, 45
00427 };
00428 static const int dim_reglist = sizeof(reglist)/sizeof(reglist[0]);
00429
00430 static const uint8_t vallist[] =
00431 {0x00, 0xff,
00432 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
00433 0xaa, 0x55,
00434 0xcc, 0x33, 0x66,
00435 0x0f, 0xf0
00436 };
00437 static const int dim_vallist = sizeof(vallist)/sizeof(vallist[0]);
00438
00439
00440 for (int itest=0; itest<dim_vallist; itest++) {
00441 if (!testLoop()) break;
00442
00443
00444
00445 for (int ireg=0; ireg<dim_reglist; ireg++) {
00446 uint8_t reg = reglist[ireg];
00447 uint8_t val = vallist[(ireg+itest)%dim_vallist];
00448 rc = fFeb->nx(nxind).i2c().setRegister(reg, val, true);
00449 if (rc) {
00450 errcnt++;
00451 std::cout << errcnt << ": setRegister(" << uint32_t(reg)
00452 << "," << std::hex << uint32_t(val) << std::dec << ") : "
00453 << base::Board::operErrToString(rc) << std::endl;
00454 }
00455 }
00456
00457
00458 for (int ireg=0; ireg<dim_reglist; ireg++) {
00459 uint8_t reg = reglist[ireg];
00460 uint8_t valexp = vallist[(ireg+itest)%dim_vallist];
00461 uint8_t val;
00462 rc = fFeb->nx(nxind).i2c().getRegister(reg, val);
00463 if (rc) {
00464 errcnt++;
00465 std::cout << errcnt << ": getRegister(" << uint32_t(reg)
00466 << "," << std::hex << uint32_t(val) << std::dec << ") : "
00467 << base::Board::operErrToString(rc) << std::endl;
00468 }
00469 if (val != valexp) {
00470 errcnt++;
00471 std::cout << errcnt << ": getRegister(" << uint32_t(reg) << ") : "
00472 << " found: " << std::hex << uint32_t(val)
00473 << " expect: " << uint32_t(valexp)
00474 << std::dec << std::endl;
00475 }
00476 }
00477 }
00478
00479
00480 for (int reg=kNxRegConfig0; reg<=kNxRegConfig1; reg++) {
00481 if (!testLoop()) break;
00482
00483 uint8_t valold;
00484 fFeb->nx(nxind).i2c().getRegister(reg, valold);
00485
00486 for (int ival=0; ival<dim_vallist; ival++) {
00487 uint8_t val = vallist[(reg+ival)%dim_vallist];
00488
00489 rc = fFeb->nx(nxind).i2c().setRegister(reg, val, true);
00490 if (rc) {
00491 errcnt++;
00492 std::cout << errcnt << ": setRegister(" << uint32_t(reg)
00493 << "," << std::hex << uint32_t(val) << std::dec << ") : "
00494 << base::Board::operErrToString(rc) << std::endl;
00495 }
00496
00497 uint8_t valget;
00498 rc = fFeb->nx(nxind).i2c().getRegister(reg, valget);
00499 if (rc) {
00500 errcnt++;
00501 std::cout << errcnt << ": getRegister(" << uint32_t(reg)
00502 << "," << std::hex << uint32_t(val) << std::dec << ") : "
00503 << base::Board::operErrToString(rc) << std::endl;
00504 }
00505
00506 if (valget != val) {
00507 errcnt++;
00508 std::cout << errcnt << ": getRegister(" << uint32_t(reg) << ") : "
00509 << " found: " << std::hex << uint32_t(valget)
00510 << " expect: " << uint32_t(val)
00511 << std::dec << std::endl;
00512 }
00513
00514 }
00515
00516 fFeb->nx(nxind).i2c().setRegister(reg, valold);
00517 }
00518
00519
00520 nxyter::NxContext cntx_set;
00521 nxyter::NxContext cntx_get;
00522
00523 static const uint8_t val5list[] =
00524 {0x00, 0x1f,
00525 0x01, 0x02, 0x04, 0x08, 0x10,
00526 0x15, 0x0a,
00527 0x19, 0x0d, 0x06
00528 };
00529 static const int dim_val5list = sizeof(val5list)/sizeof(val5list[0]);
00530
00531 for (int itest=0; itest<dim_val5list; itest++) {
00532 if (!testLoop()) break;
00533
00534 for (int cha=0; cha<129; cha++) {
00535 uint8_t val = val5list[(cha+itest)%dim_val5list];
00536 cntx_set.setPowerOffMaskBit(cha, true);
00537 cntx_set.setThresholdTrim(cha, val);
00538 }
00539
00540 rc = fFeb->nx(nxind).i2c().setContext(cntx_set, kDoTrim, false);
00541 if (rc) {
00542 errcnt++;
00543 std::cout << errcnt << ": setContext(,kDoTrim {trim check}): "
00544 << base::Board::operErrToString(rc) << std::endl;
00545 }
00546 rc = fFeb->nx(nxind).i2c().getContext(cntx_get, kDoTrim);
00547 if (rc) {
00548 errcnt++;
00549 std::cout << errcnt << ": getContext(,kDoTrim {trim check}): "
00550 << base::Board::operErrToString(rc) << std::endl;
00551 }
00552
00553 int errtest = 0;
00554 for (int cha=0; cha<129; cha++) {
00555 uint8_t valexp = val5list[(cha+itest)%dim_val5list];
00556 uint8_t val = cntx_get.getThresholdTrim(cha);
00557 if (val != valexp) {
00558 errcnt++;
00559 errtest++;
00560 std::cout << errcnt << ": trim(" << cha << ") : "
00561 << " found: " << std::hex << uint32_t(val)
00562 << " expect: " << uint32_t(valexp)
00563 << std::dec << std::endl;
00564 }
00565 }
00566
00567 if (errtest++) {
00568 std::cout << "--- set values for trim-daq test " << itest << std::endl;
00569 cntx_set.print(std::cout, kDoTrim);
00570 std::cout << "--- get values for trim-daq test" << std::endl;
00571 cntx_get.print(std::cout, kDoTrim);
00572 }
00573 }
00574
00575
00576
00577
00578 for (int itest=0; itest<18; itest++) {
00579 if (!testLoop()) break;
00580
00581 int ibit = itest%2;
00582 int idiv = 1<<(itest/2);
00583 for (int cha=0; cha<129; cha++) {
00584 bool val = (cha/idiv)%2 == ibit;
00585 cntx_set.setPowerOffMaskBit(cha, val);
00586 cntx_set.setThresholdTrim(cha, 16);
00587 }
00588 rc = fFeb->nx(nxind).i2c().setContext(cntx_set, kDoTrim, false);
00589 if (rc) {
00590 errcnt++;
00591 std::cout << errcnt << ": setContext(,kDoTrim {poff check}): "
00592 << base::Board::operErrToString(rc) << std::endl;
00593 }
00594 rc = fFeb->nx(nxind).i2c().getContext(cntx_get, kDoTrim);
00595 if (rc) {
00596 errcnt++;
00597 std::cout << errcnt << ": getContext(,kDoTrim {poff check}): "
00598 << base::Board::operErrToString(rc) << std::endl;
00599 }
00600
00601 int errtest = 0;
00602 for (int cha=0; cha<129; cha++) {
00603 bool valexp = (cha/idiv)%2 == ibit;
00604 bool val = cntx_get.getPowerOffMaskBit(cha);
00605 if (val != valexp) {
00606 errcnt++;
00607 errtest++;
00608 std::cout << errcnt << ": power(" << cha << ") : "
00609 << " found: " << val
00610 << " expect: " << valexp
00611 << std::dec << std::endl;
00612 }
00613 }
00614 if (errtest++) {
00615 std::cout << "--- set values for power-down test with ibit=" << ibit
00616 << " idiv=" << idiv << std::endl;
00617 cntx_set.print(std::cout, kDoTrim);
00618 std::cout << "--- get values for power-down test" << std::endl;
00619 cntx_get.print(std::cout, kDoTrim);
00620 }
00621 }
00622
00623 rc = fFeb->nx(nxind).i2c().setContext(cntx_save, kDoAll);
00624 if (rc) {
00625 errcnt++;
00626 std::cout << errcnt << ": setContext({restore}): "
00627 << base::Board::operErrToString(rc) << std::endl;
00628 }
00629
00630 return errcnt;
00631 }
00632
00633
00635
00640 int nxyter::FebUtil::testMainAdcControlPath(double time)
00641 {
00642 if (fFeb == 0) return -1;
00643 int errcnt = 0;
00644 startLoop(time);
00645 while(testLoop()) {
00646 int rc = fFeb->adc().probe();
00647 if (rc) {
00648 errcnt++;
00649 std::cout << errcnt << ":" << base::Board::operErrToString(rc) << std::endl;
00650 }
00651 }
00652 return errcnt;
00653 }
00654
00655
00657
00662 int nxyter::FebUtil::testMainAdcDataPath(double time)
00663 {
00664 if (fFeb == 0) return -1;
00665 int errcnt = 0;
00666 startLoop(time);
00667 int rc;
00668
00669 rc = fFeb->adc().setTestMode(0, 8);
00670 if (rc==0) rc = fFeb->adc().setTestMode(1, 8);
00671 if (rc==0) rc = fFeb->adc().setTestMode(2, 8);
00672 if (rc==0) rc = fFeb->adc().setTestMode(3, 8);
00673 if (rc) {
00674 std::cout << "failed to set test pattern mode for ADC: "
00675 << base::Board::operErrToString(rc) << std::endl;
00676 std::cout << "Abort test because startup failed..." << std::endl;
00677 return 1;
00678 }
00679
00680 uint16_t adcpatt = 0;
00681 int chmax = 2;
00682
00683 while(testLoop()) {
00684 fFeb->adc().setUserPattern(adcpatt);
00685 for (int ch=0; ch<chmax; ch++) {
00686 uint32_t val;
00687 rc = fFeb->adc().getAdcDirect(ch, val);
00688 if (rc) {
00689 std::cout << errcnt << ": adc().getAdcDirect(): "
00690 << base::Board::operErrToString(rc) << std::endl;
00691 errcnt++;;
00692 }
00693 if ((uint16_t) val != adcpatt) {
00694
00695 char sbuf[100];
00696 snprintf(sbuf, sizeof(sbuf),
00697 "%d: mismatch for adc chan=%d: found=0x%03x, expected 0x%03x",
00698 errcnt, ch, (unsigned) val, (unsigned) adcpatt);
00699
00700 std::cout << sbuf << std::endl;
00701 errcnt++;
00702 }
00703 }
00704 adcpatt = (adcpatt+1) & 0x0fff;
00705 }
00706
00707
00708 rc = fFeb->adc().setTestMode(0, 0);
00709 if (rc==0) rc = fFeb->adc().setTestMode(1, 0);
00710 if (rc==0) rc = fFeb->adc().setTestMode(2, 0);
00711 if (rc==0) rc = fFeb->adc().setTestMode(3, 0);
00712 if (rc) {
00713 std::cout << "failed to restore ADC default settings: "
00714 << base::Board::operErrToString(rc) << std::endl;
00715 errcnt++;
00716 }
00717
00718 return errcnt;
00719 }
00720
00721
00723
00729 int nxyter::FebUtil::testFebControlPathCombo(double time)
00730 {
00731 if (fFeb == 0) return -1;
00732
00733 nxyter::NxContext cntx_save[4];
00734 nxyter::NxContext cntx_test[4];
00735 int errcnt = 0;
00736 int numnx = fFeb->numNx();
00737
00738 int nxreg [] = {0,1, 2, 3, 4, 5, 6, 7,
00739 8,9,10,11,12,13,14,15,
00740 kNxRegcal,
00741 kNxRegiTWC,
00742 kNxRegdelayTestPuls,
00743 kNxRegdelayTestTrig
00744 };
00745
00746 const static int dim_nxreg = sizeof(nxreg)/sizeof(int);
00747
00748 uint8_t testpatt[4][dim_nxreg];
00749
00750
00751 for (int i=0; i<numnx; i++) {
00752 int rc = fFeb->nx(i).i2c().getContext(cntx_save[i],
00753 nxyter::kDoMask|nxyter::kDoCore);
00754 if (rc) {
00755 std::cout << "failed to save context for nxind=" << i << " :"
00756 << base::Board::operErrToString(rc) << std::endl;
00757 errcnt++;
00758 }
00759 }
00760
00761 if (errcnt) {
00762 std::cout << "Abort test because startup failed..." << std::endl;
00763 return errcnt;
00764 }
00765
00766 startLoop(time);
00767 while(testLoop()) {
00768 int rc;
00769
00770 for (int i=0; i<numnx; i++) {
00771 cntx_test[i] = cntx_save[i];
00772 for (int j=0; j<dim_nxreg; j++) {
00773 testpatt[i][j] = (random()>>22) & 0xff;
00774 cntx_test[i].setRegister(nxreg[j], testpatt[i][j]);
00775 }
00776 rc = fFeb->nx(i).i2c().setContext(cntx_test[i],
00777 nxyter::kDoMask|nxyter::kDoCore);
00778 if (rc) {
00779 std::cout << errcnt << ":setContext() on " << i << " :"
00780 << base::Board::operErrToString(rc) << std::endl;
00781 errcnt++;
00782 }
00783 }
00784
00785 for (int i=0; i<numnx; i++) {
00786 rc = fFeb->nx(i).i2c().getContext(cntx_test[i],
00787 nxyter::kDoMask|nxyter::kDoCore);
00788 if (rc) {
00789 std::cout << errcnt << ":getContext() on " << i << " :"
00790 << base::Board::operErrToString(rc) << std::endl;
00791 errcnt++;
00792 }
00793 for (int j=0; j<dim_nxreg; j++) {
00794 uint8_t val = cntx_test[i].getRegister(nxreg[j]);
00795 if (val != testpatt[i][j]) {
00796 char sbuf[200];
00797 snprintf(sbuf, sizeof(sbuf),
00798 "%d: mismatch for nxind=%d,reg=%2d: found=0x%02x, expected 0x%02x",
00799 errcnt, i, nxreg[j], (unsigned) val, (unsigned) testpatt[i][j]);
00800 std::cout << sbuf << std::endl;
00801 errcnt++;
00802 }
00803 }
00804 }
00805 }
00806
00807
00808 for (int i=0; i<numnx; i++) {
00809 int rc = fFeb->nx(i).i2c().setContext(cntx_save[i],
00810 nxyter::kDoMask|nxyter::kDoCore);
00811 if (rc) {
00812 std::cout << "failed to restore context for nxind=" << i << " :"
00813 << base::Board::operErrToString(rc) << std::endl;
00814 errcnt++;
00815 }
00816 }
00817
00818 return errcnt;
00819 }
00820
00821
00823
00861 void nxyter::FebUtil::probe(base::Board* board, bool verbose, std::ostream& os)
00862 {
00863 bool nxok[2][128];
00864 bool adcok[2];
00865
00866 if (verbose) os << "Detailed probe() return codes:" << std::endl;
00867
00868 for (int port=0; port<=1; port++) {
00869 nxyter::MainAdc adc(board, port);
00870 int rc = adc.probe();
00871 adcok[port] = (rc==0);
00872 if (verbose) {
00873 char sbuf[1000];
00874 snprintf(sbuf, sizeof(sbuf),
00875 " adc %2d : rc = %4d,%2d -> %s",
00876 port, base::Board::operErrIndex(rc),
00877 base::Board::operErrCode(rc),
00878 base::Board::operErrCodeName(rc));
00879
00880 os << sbuf << std::endl;
00881 }
00882
00883 for (int addr=2; addr<=126; addr+=2) {
00884 nxyter::NxI2c nx(board, port, addr);
00885 rc = nx.probe();
00886 nxok[port][addr] = (rc==0);
00887 if (verbose) {
00888 char sbuf[1000];
00889 snprintf(sbuf, sizeof(sbuf),
00890 " nx %2d,%3d: rc = %4d,%2d -> %s",
00891 port, addr , base::Board::operErrIndex(rc),
00892 base::Board::operErrCode(rc),
00893 base::Board::operErrCodeName(rc));
00894 os << sbuf << std::endl;
00895 }
00896 }
00897 }
00898
00899 os << "Full MainAdc.probe() and NxI2c::probe() scan found:" << std::endl;
00900 os << " port adc ----- nx i2c slave address in range 2,..,126, only even -------" << std::endl;
00901 os << " ";
00902 for (int addr=2; addr<=126; addr+=2) os << ( (addr>=100)?"1":" " );
00903 os << std::endl;
00904 os << " ";
00905 for (int addr=2; addr<=126; addr+=2) os << ((addr/10)%10);
00906 os << std::endl;
00907 os << " ";
00908 for (int addr=2; addr<=126; addr+=2) os << (addr%10);
00909 os << std::endl;
00910
00911 for (int port=0; port<=1; port++) {
00912 os << " " << port << " " << (adcok[port]?"y":"-") << " ";
00913 for (int addr=2; addr<=126; addr+=2) os << (nxok[port][addr] ? "y" : "-");
00914 os << std::endl;
00915 }
00916
00917 int ftyps[2], ftypl[2];
00918 FebBase::discoverFebs(board, ftyps[0], ftyps[1]);
00919 FebBase::discoverFebs(board, ftypl[0], ftypl[1], true);
00920
00921 os << "Autoconfigure with FebBase::discoverFebs() found:" << std::endl;
00922 for (int port=0; port<=1; port++) {
00923 os << " port " << port << " : ";
00924 if (ftyps[port]==0 && ftypl[port]==0) {
00925 os << "nothing";
00926 } else if (ftyps[port] == ftypl[port]) {
00927 os << FebBase::typeToString(ftyps[port]);
00928 } else {
00929 if (ftyps[port])
00930 os << FebBase::typeToString(ftyps[port])
00931 << " (strict mode)";
00932 if (ftypl[port])
00933 os << FebBase::typeToString(ftypl[port])
00934 << " (liberal mode, some nx missing)";
00935 }
00936 os << std::endl;
00937 }
00938 }
00939
00940
00942
00943 double nxyter::FebUtil::now()
00944 {
00945 struct timeval tv;
00946 gettimeofday(&tv, 0);
00947 return double(tv.tv_sec) + 1.e-6*double(tv.tv_usec);
00948 }
00949
00950