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

roclib/src_nxyter/NxContext.cxx (r4864/r4110)

Go to the documentation of this file.
00001 //============================================================================
00005 //============================================================================
00006 
00007 #include "nxyter/NxContext.h"
00008 
00009 #include <stdexcept>
00010 #include <iomanip>
00011 
00012 #include "nxyter/NxI2c.h"
00013 
00026 //----------------------------------------------------------------------------
00028 
00029 nxyter::NxContext::NxContext()
00030 {
00031   for (int i=0; i<dimRegMain; i++) fRegMain[i] = 0;
00032   for (int i=0; i<dimRegTrim; i++) fRegTrim[i] = 0;
00033 }
00034 
00035 //----------------------------------------------------------------------------
00036 
00037 nxyter::NxContext::~NxContext()
00038 {
00039 }
00040 
00041 //----------------------------------------------------------------------------
00043 
00052 void nxyter::NxContext::setRegister(int reg, uint8_t val)
00053 {
00054   if (reg<0 || reg>=dimRegMain) 
00055     throw std::out_of_range("NxContext::setRegister(): reg out of range");
00056   fRegMain[reg] = val;
00057 }
00058 
00059 //----------------------------------------------------------------------------
00061 
00070 uint8_t nxyter::NxContext::getRegister(int reg) const
00071 {
00072   if (reg<0 || reg>=dimRegMain) 
00073     throw std::out_of_range("NxContext::getRegister(): reg out of range");
00074   return fRegMain[reg];
00075 }
00076 
00077 //----------------------------------------------------------------------------
00079 
00090 void nxyter::NxContext::setTrimRegister(int channel, uint8_t val)
00091 {
00092   if (channel<0 || channel>=dimRegTrim) 
00093     throw std::out_of_range("NxContext::setTrimRegister():channel out of range");
00094   fRegTrim[channel] = val & 0x3f;               // only 6 bits !!
00095 }
00096 
00097 //----------------------------------------------------------------------------
00099 
00109 uint8_t nxyter::NxContext::getTrimRegister(int channel) const
00110 {
00111   if (channel<0 || channel>=dimRegTrim) 
00112     throw std::out_of_range("NxContext::getTrimRegister(): channel out of range");
00113   return fRegTrim[channel];
00114 }
00115 
00116 //----------------------------------------------------------------------------
00118 
00125 void nxyter::NxContext::setChannelMaskBit(int channel, bool isoff)
00126 {
00127   if (channel<0 || channel>=128) 
00128     throw std::out_of_range("NxContext::setChannelMaskBit(): channel out of range");
00129 
00130   int reg = (channel>>3) & 0x1f;
00131   uint8_t mask = 1<<(channel&0x7);
00132   if (isoff) {
00133     fRegMain[reg] |=  mask;
00134   } else {
00135     fRegMain[reg] &= ~mask;
00136   }
00137 }
00138 
00139 //----------------------------------------------------------------------------
00141 
00151 void nxyter::NxContext::setChannelMaskBit(int chbeg, int chend, bool isoff,
00152                                           int chstep)
00153 {
00154   if (chstep <= 0) return;
00155   for (int ch=chbeg; ch<=chend; ch+=chstep) setChannelMaskBit(ch, isoff);
00156 }
00157 
00158 //----------------------------------------------------------------------------
00160 
00166 bool nxyter::NxContext::getChannelMaskBit(int channel) const
00167 {
00168   if (channel<0 || channel>=128) 
00169     throw std::out_of_range("NxContext::getChannelMaskBit(): channel out of range");
00170 
00171   int reg = (channel>>3) & 0x1f;
00172   uint8_t mask = 1<<(channel&0x7);
00173   
00174   return fRegMain[reg] & mask;
00175 }
00176 
00177 //----------------------------------------------------------------------------
00179 
00186 void nxyter::NxContext::setThresholdTrim(int channel, uint8_t val)
00187 {
00188   if (channel<0 || channel>=dimRegTrim) 
00189     throw std::out_of_range("NxContext::setThresholdTrim(): channel out of range");
00190 
00191   fRegTrim[channel] &= ~0x1f;               // erease lower 5 bit
00192   fRegTrim[channel] |= val & 0x1f;          // fill in lower 5 bit
00193 }
00194 
00195 //----------------------------------------------------------------------------
00197 
00208 void nxyter::NxContext::setThresholdTrim(int chbeg, int chend, uint8_t val,
00209                                          int chstep)
00210 {
00211   if (chstep <= 0) return;
00212   for (int ch=chbeg; ch<=chend; ch+=chstep) setThresholdTrim(ch, val);
00213 }
00214 
00215 //----------------------------------------------------------------------------
00217 
00223 uint8_t nxyter::NxContext::getThresholdTrim(int channel) const
00224 {
00225   if (channel<0 || channel>=dimRegTrim) 
00226     throw std::out_of_range("NxContext::getThresholdTrim(): channel out of range");
00227 
00228   return fRegTrim[channel] & 0x1f;          // return lower 5 bit
00229 }
00230 
00231 //----------------------------------------------------------------------------
00233 
00240 void nxyter::NxContext::setPowerOffMaskBit(int channel, bool isoff)
00241 {
00242   if (channel<0 || channel>=dimRegTrim) 
00243     throw std::out_of_range("NxContext::setPowerOffMaskBit(): channel out of range");
00244 
00245   if (isoff) {
00246     fRegTrim[channel] |=  0x20;
00247   } else {
00248     fRegTrim[channel] &= ~0x20;                     // erease bit 6
00249   }
00250 }
00251 
00252 //----------------------------------------------------------------------------
00254 
00265 void nxyter::NxContext::setPowerOffMaskBit(int chbeg, int chend, bool isoff,
00266                                            int chstep)
00267 {
00268   if (chstep <= 0) return;
00269   for (int ch=chbeg; ch<=chend; ch+=chstep) setPowerOffMaskBit(ch, isoff);
00270 }
00271 
00272 //----------------------------------------------------------------------------
00274 
00280 bool nxyter::NxContext::getPowerOffMaskBit(int channel) const
00281 {
00282   if (channel<0 || channel>=dimRegTrim) 
00283     throw std::out_of_range("NxContext::getPowerOffMaskBit(): channel out of range");
00284 
00285   return fRegTrim[channel] & 0x20;
00286 }
00287 
00288 
00289 //----------------------------------------------------------------------------
00291 
00295 bool nxyter::NxContext::getConfigurationBit(int n)
00296 {
00297    if ((n<0) || (n>=12)) return false;
00298    if (n<8) return (fRegMain[32] & (1 << n)) != 0;
00299    return (fRegMain[33] & (1<<(n-8))) != 0;
00300 }
00301 
00302 //----------------------------------------------------------------------------
00304 
00308 void nxyter::NxContext::setConfigurationBit(int n, bool on)
00309 {
00310    if ((n<0) || (n>=12)) return;
00311    if (n<8)
00312       fRegMain[32] = on ? (fRegMain[32] | (1 << n)) : (fRegMain[32] & ~(1 << n));
00313    else
00314       fRegMain[33] = on ? (fRegMain[33] | (1 << (n-8))) : (fRegMain[33] & ~(1 << (n-8)));
00315 }
00316 
00317 //----------------------------------------------------------------------------
00319 
00344 void nxyter::NxContext::setToDefault(bool ispos, int maskon, int poweron)
00345 {
00346   // real clean...
00347   for (int i=0; i<dimRegMain; i++) fRegMain[i] = 0;
00348   for (int i=0; i<dimRegTrim; i++) fRegTrim[i] = 0;
00349 
00350   for (int i=0; i<128; i++) {
00351     setChannelMaskBit(i, i>=maskon);        // mask=1  means channel off
00352     setPowerOffMaskBit(i, i>=poweron);      // isoff=1 means channel power off
00353     setThresholdTrim(i, 16);
00354   }
00355   setPowerOffMaskBit(128, false);
00356   setThresholdTrim(128, 16);
00357 
00358   // taken from nxyter::I2Cbus::testsetup()
00359   setRegister(kNxRegVcg,     160);
00360   setRegister(kNxRegIcgfoll, 255);
00361   setRegister(kNxRegVth,      35);
00362   setRegister(kNxRegVbfb,     30);
00363   setRegister(kNxRegVbiasF,   95);
00364   setRegister(kNxRegVbiasS,   87);
00365   setRegister(kNxRegVbiasS2, 100);
00366   setRegister(kNxRegVcm,     137);
00367   setRegister(kNxRegcal,     255);
00368   setRegister(kNxRegiCOMP,    69);
00369   setRegister(kNxRegiDUR,     15);
00370   setRegister(kNxRegiINV,     54);
00371   setRegister(kNxRegiPDH,     92);
00372   setRegister(kNxRegiTWC,     69);
00373   setRegister(kNxRegConfig0,   0);
00374   setRegister(kNxRegConfig1,  kNxC1ReadClockSelect | 0x3);
00375   
00376   // now handle what is different for positive polarity
00377   // 1. Front end polarity bit set
00378   // 2. test puls polarity bit set
00379   // 3. VBiasF default 65 rather than 95
00380   if (ispos) {
00381     uint8_t val = getRegister(kNxRegConfig1);
00382     setRegister(kNxRegConfig1, val | kNxC1FrontEndPolarity);
00383     setRegister(kNxRegConfig0, kNxC0TestPulsPolarity);
00384     setRegister(kNxRegVbiasF,   65);
00385   }
00386 }
00387 
00388 //----------------------------------------------------------------------------
00390 
00401 bool nxyter::NxContext::equal(const NxContext& rhs, int domask) const
00402 {
00403   if (domask & kDoMask) {
00404     for (int i=0; i<16; i++) {
00405       if (fRegMain[i] != rhs.fRegMain[i]) return false;
00406     }
00407   }
00408   if (domask & kDoCore) {
00409     for (int i=16; i<dimRegMain; i++) {
00410       if (i==30 || i==31) continue;         // skip unimplemented regs
00411       if (i>=34 && i<=37) continue;         // skip error counters 
00412       if (i>=40 && i<=42) continue;         // skip unimplemented regs and reg42
00413       if (fRegMain[i] != rhs.fRegMain[i]) return false;
00414     }
00415   }
00416   if (domask & kDoTrim) {
00417     for (int i=0; i<dimRegTrim; i++) {
00418       if (fRegTrim[i] != rhs.fRegTrim[i]) return false;
00419     }
00420   }
00421   return true;
00422 }
00423 
00424 //----------------------------------------------------------------------------
00426 
00470 void nxyter::NxContext::print(std::ostream& os, int domask) const
00471 {
00472   // print registers
00473   for (int i=0; i<46; i++) {
00474     if ((domask & kDoMask)==0 && i<16) continue;
00475     if ((domask & kDoCore)==0 && i>=16) continue;
00476     
00477     if (i>=34 && i<=37) continue;
00478     if (i==42) continue;
00479     const char* regname = nxyter::NxI2c::registerName(i);
00480     if ((regname==0) || (*regname==0)) continue;
00481 
00482     char sbuf[200];
00483     snprintf(sbuf, sizeof(sbuf),
00484              "Reg(%2d) %14s: 0x%02x %3u",
00485               i, regname, (unsigned) fRegMain[i], (unsigned) fRegMain[i]);
00486     os << sbuf;
00487 
00488     if (i<16) {                             // mask registers
00489       os << " :  ch :" << std::setw(3) << (8*i)+7 << "-" << std::setw(3) << (8*i) << ":";
00490       for (int j=7; j>=0; j--) os << ((fRegMain[i] & (1<<j)) ? " d" : " o");
00491       if (i==0) os << "   o=active";
00492       if (i==1) os << "   d=inactive";
00493     }
00494     
00495     if (i==32 || i==33) {
00496       for (int j=0; j<8; j++) {
00497         if (j!=0) os << "                                ";
00498 
00499         os << "bit(" << j << ") = " << ((fRegMain[i]&(1<<j)) ? 1 : 0) << " : "
00500            << nxyter::NxI2c::configurationBitName(8*(i-32)+j);
00501         if (i==32 && j!=7) os << std::endl;
00502         if (i==33 && j!=3) os << std::endl;  
00503         if (i==33 && j==3) break;
00504       }
00505     }
00506 
00507     if ((i==38) || (i==39) || (i>=43))          // delay regs
00508        os << " : delay=" << std::setw(3) << nxyter::NxI2c::settingToDelay(fRegMain[i]);
00509 
00510     os << std::endl;
00511   }
00512 
00513   if ((domask & kDoTrim)==0) return;
00514 
00515   for (int i=0; i<129; i++) {
00516     if (i%8 == 0)
00517       os << "Reg(42) TrimDAQ-Power : ch " << std::setw(3) << i << ":";
00518     os << "  " << (getPowerOffMaskBit(i) ? "d" : "u");
00519     os << " " << std::setw(2) << getThresholdTrim(i);
00520     if (i%8 == 7) os << std::endl;
00521   }
00522   os << std::endl; 
00523 }
00524 
00525 //----------------------------------------------------------------------------
00527 
00531 bool nxyter::NxContext::fillCmdFile(FILE* f, int nx)
00532 {
00533    fprintf(f,"//Actual nXYTER registers\n");
00534 
00535    // bias registers
00536    for (int reg=16;reg<30;reg++)
00537       fprintf(f,"setnx %d,%d,%d \n", nx, reg, getRegister(reg));
00538 
00539    for (int reg=32;reg<34;reg++)
00540       fprintf(f,"setnx %d,%d,%d \n", nx, reg, getRegister(reg));
00541 
00542    for (int reg=38;reg<40;reg++)
00543       fprintf(f,"setnx %d,%d,%d \n", nx, reg, getRegister(reg));
00544 
00545    for (int reg=43;reg<46;reg++)
00546       fprintf(f,"setnx %d,%d,%d \n", nx, reg, getRegister(reg));
00547 
00548 
00549    // mask values
00550    int nbeg = 0, nch = 1;
00551    bool begoff = getChannelMaskBit(0);
00552 
00553    while (nch<=128) {
00554       bool isoff = nch < 128 ? getChannelMaskBit(nch) : begoff;
00555 
00556       if ((isoff!=begoff) || (nch == 128)) {
00557          fprintf(f,"setnxmask %d,%d,%d,%d,1 \n", nx, begoff ? 1 : 0, nbeg, nch-1);
00558          nbeg = nch;
00559          begoff = isoff;
00560       }
00561       nch++;
00562    }
00563 
00564    // trimmer values
00565    nbeg = 0; nch = 1;
00566    int begtrim = getThresholdTrim(0);
00567 
00568    while (nch<=129) {
00569       int trim = nch < 129 ? getThresholdTrim(nch) : begtrim;
00570 
00571       if ((trim!=begtrim) || (nch == 129)) {
00572          fprintf(f,"setnxtrim %d,%d,%d,%d,1 \n", nx, begtrim, nbeg, nch-1);
00573          nbeg = nch;
00574          begtrim = trim;
00575       }
00576       nch++;
00577    }
00578 
00579    // power down bits
00580    nbeg = 0; nch = 1;
00581    begoff = getPowerOffMaskBit(0);
00582 
00583    while (nch<=129) {
00584       bool isoff = nch < 129 ? getPowerOffMaskBit(nch) : begoff;
00585 
00586       if ((isoff!=begoff) || (nch == 129)) {
00587          fprintf(f,"setnxpower %d,%d,%d,%d,1 \n", nx, begoff ? 1 : 0, nbeg, nch-1);
00588          nbeg = nch;
00589          begoff = isoff;
00590       }
00591       nch++;
00592    }
00593 
00594 
00595    return true;
00596 }
00597 
00598 
00599 //----------------------------------------------------------------------------
00600 // allocate storage for 'static const', rootcint needs it
00601 const int nxyter::NxContext::dimRegMain;
00602 const int nxyter::NxContext::dimRegTrim;

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