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;
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;
00192 fRegTrim[channel] |= val & 0x1f;
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;
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;
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
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);
00352 setPowerOffMaskBit(i, i>=poweron);
00353 setThresholdTrim(i, 16);
00354 }
00355 setPowerOffMaskBit(128, false);
00356 setThresholdTrim(128, 16);
00357
00358
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
00377
00378
00379
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;
00411 if (i>=34 && i<=37) continue;
00412 if (i>=40 && i<=42) continue;
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
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) {
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))
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
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
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
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
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
00601 const int nxyter::NxContext::dimRegMain;
00602 const int nxyter::NxContext::dimRegTrim;