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

roclib/src_nxyter/FebUtil.cxx (r4864/r4162)

Go to the documentation of this file.
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 &&                       // if not first iteration and
00153       fTestTime>0. &&                       // finite time chosen check time
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;    // skip if offline
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;    // skip if offline
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.;      // FIXME: is that safe ??
00246 
00247   if (cleardist) dfa.clear();
00248 
00249   rocnx.fireTestPulse(0,0,0);               // FIXME: rc; ensure that pulser off
00250 
00251   uint32_t save_gpiomask;
00252   gpio.getConfig(save_gpiomask);            // FIXME: retcode
00253   uint32_t new_gpiomask = save_gpiomask;
00254   gpio.packConfig(new_gpiomask, 6, false, false, false, true, true);
00255   gpio.setConfig(new_gpiomask);             // FIXME: retcode
00256 
00257   fQdaq->nextRunNxMask(1<<nxnum);
00258   fQdaq->startRun(0, time);
00259 
00260   rocnx.fireTestPulse(100000,50000,npuls);   // FIXME: rc; fire pulser 2.5 KHz
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);            // FIXME: retcode
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     // mask off all channels not covered by current csel
00334     for (int ch=0; ch<128; ch++) {
00335       if ((ch & 0x3) != csel) cntx_run.setChannelMaskBit(ch, true);
00336     }
00337     // no readback verification here to save the test trigger mode jojo
00338     // each time here. If there a comm problems, they also show elsewhere...
00339     rc = fFeb->nx(nxind).i2c().setContext(cntx_run, nxyter::kDoMask, false);
00340     if (rc) return rc;
00341 
00342     // now set csel in conf1
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   // part 1: mask and core registers, except configuration regs
00421   static const uint8_t reglist[] = 
00422     {  0,  1,  2,  3,  4,  5,  6,  7,       // masks
00423        8,  9, 10, 11, 12, 13, 14, 15,       // "
00424       16, 17, 18, 19, 20, 21, 22, 23,       // daq regs
00425       24, 25, 26, 27, 28, 29,               // "
00426       38, 39, 43, 44, 45                    // delay regs
00427     };
00428   static const int dim_reglist = sizeof(reglist)/sizeof(reglist[0]);
00429   
00430   static const uint8_t vallist[] =
00431     {0x00, 0xff,                                     // all 0, all 1
00432      0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, // 1 bit up
00433      0xaa, 0x55,                                     // 1010..., 0101...
00434      0xcc, 0x33, 0x66,                               // 1100..., 0011..., 0110..
00435      0x0f, 0xf0                                      // 00001111, 11110000
00436     };
00437   static const int dim_vallist = sizeof(vallist)/sizeof(vallist[0]);
00438 
00439   // loop over all test patterns
00440   for (int itest=0; itest<dim_vallist; itest++) {
00441     if (!testLoop()) break;
00442 
00443     // write all regs with test patters cyclic
00444     // this way all regs see all patterns, but regs have different values
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     // read all regs check for proper values
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   // part 2: configuration regs
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   // part 3: trim registers
00520   nxyter::NxContext cntx_set;
00521   nxyter::NxContext cntx_get;
00522 
00523   static const uint8_t val5list[] =
00524     {0x00, 0x1f,                                     // all 0, all 1
00525      0x01, 0x02, 0x04, 0x08, 0x10,                   // 1 bit up
00526      0x15, 0x0a,                                     // 10101, 01010
00527      0x19, 0x0d, 0x06                                // 11001, 01101, 00110
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   // part 4: power-down registers
00576   // uses (cha/n)%2 ==0 or ==1 patterns for n=1,2,4,8,16,32,64,128,256
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   // set all adc channels to test pattern mode
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   // reset all adc channels to normal mode
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,    // all mask regs
00739                   8,9,10,11,12,13,14,15,
00740                   kNxRegcal,                // 2 daq regs
00741                   kNxRegiTWC,
00742                   kNxRegdelayTestPuls,      // 2 delay regs
00743                   kNxRegdelayTestTrig
00744   };      
00745 
00746   const static int dim_nxreg = sizeof(nxreg)/sizeof(int);
00747 
00748   uint8_t testpatt[4][dim_nxreg];
00749 
00750   // save nx mask+core register set
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; // take bits 22 to 29
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   // restore nx mask+core register set
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 //----------------------------------------------------------------------------

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