00001
00005
00006
00007 #include "nxyter/NxI2c.h"
00008
00028
00030
00037 nxyter::NxI2c::NxI2c(base::Board* board, int port,
00038 uint8_t addr) :
00039 roc::I2cDevice(board, port, addr)
00040 {
00041 }
00042
00043
00044
00045 nxyter::NxI2c::~NxI2c()
00046 {
00047 }
00048
00049
00051
00071 int nxyter::NxI2c::setContext(NxContext& cntx, int domask, bool veri)
00072 {
00073 int rc;
00074 NxContext data;
00075
00076 if (domask & kDoMask) {
00077 rc = setRegMask(cntx.dataRegisterMain());
00078 if (rc) return rc;
00079 }
00080 if (domask & kDoCore) {
00081 rc = setRegCore(cntx.dataRegisterMain());
00082 if (rc) return base::Board::operErrBuildInc(rc, 16);
00083 }
00084
00085 if (domask & kDoTrim) {
00086 rc = setRegTrim(cntx.dataRegisterTrim());
00087 if (rc) return base::Board::operErrBuildInc(rc, 128);
00088 }
00089
00090 if (veri) {
00091 rc = getContext(data, domask);
00092 if (rc) return base::Board::operErrBuildInc(rc, 1000);
00093 if (!cntx.equal(data, domask))
00094 return base::Board::operErrBuild(base::Board::kOperVerifyErr,2000);
00095 }
00096
00097 return 0;
00098 }
00099
00100
00102
00119 int nxyter::NxI2c::getContext(NxContext& cntx, int domask)
00120 {
00121 int rc;
00122
00123 if (domask & kDoMask) {
00124 rc = getRegMask(cntx.dataRegisterMain());
00125 if (rc) return rc;
00126 }
00127 if (domask & kDoCore) {
00128 rc = getRegCore(cntx.dataRegisterMain());
00129 if (rc) return base::Board::operErrBuildInc(rc, 16);
00130 }
00131 if (domask & kDoTrim) {
00132 rc = getRegTrim(cntx.dataRegisterTrim());
00133 if (rc) return base::Board::operErrBuildInc(rc, 128);
00134 }
00135
00136 return 0;
00137 }
00138
00139
00141
00149 int nxyter::NxI2c::getCounters(uint16_t& overflow, uint16_t& tokenmiss)
00150 {
00151 int rc;
00152 uint8_t data[4];
00153
00154 overflow = 0;
00155 tokenmiss = 0;
00156
00157 rc = getRegisterArray(34, data, 4);
00158 if (rc) return rc;
00159
00160 overflow = data[0] + (uint16_t(data[1]) << 8);
00161 tokenmiss = data[2] + (uint16_t(data[3]) << 8);
00162
00163 return 0;
00164 }
00165
00166
00168
00195 int nxyter::NxI2c::setTestModes(bool testpuls, bool testtrig,
00196 int calselect)
00197 {
00198 int rc;
00199 uint8_t conf0;
00200 uint8_t conf1;
00201 rc = getRegister(kNxRegConfig0, conf0);
00202 if (rc) return base::Board::operErrBuild(rc, 0);
00203 rc = getRegister(kNxRegConfig1, conf1);
00204 if (rc) return base::Board::operErrBuild(rc, 1);
00205
00206 if (testpuls) {
00207 conf0 |= kNxC0TestPulsEnable;
00208 } else {
00209 conf0 &= ~kNxC0TestPulsEnable;
00210 }
00211
00212 if (testtrig) {
00213 conf0 |= kNxC0TestTrigEnable;
00214 } else {
00215 conf0 &= ~kNxC0TestTrigEnable;
00216 }
00217
00218 if (conf1 & kNxC1FrontEndPolarity) {
00219 conf0 |= kNxC0TestPulsPolarity;
00220 } else {
00221 conf0 &= ~kNxC0TestPulsPolarity;
00222 }
00223
00224 conf1 &= ~kNxC1CalibSelectMask;
00225 conf1 |= uint8_t(calselect) & kNxC1CalibSelectMask;
00226
00227 rc = setRegister(kNxRegConfig0, conf0, true);
00228 if (rc) return base::Board::operErrBuild(rc, 2);
00229 rc = setRegister(kNxRegConfig1, conf1, true);
00230 if (rc) return base::Board::operErrBuild(rc, 3);
00231
00232 return 0;
00233 }
00234
00235
00237
00271 int nxyter::NxI2c::probe()
00272 {
00273 int rc(0), res(0);
00274 uint8_t regs[3] = {kNxRegcal, kNxRegdelayTestPuls, kNxRegdelayTestTrig};
00275 uint8_t save[3];
00276 uint8_t back[3];
00277 uint8_t patt[3] = {0x55, 0xaa, 0x5f};
00278
00279
00280 for (int i=0; i<3; i++) {
00281 rc = getRegister(regs[i], save[i]);
00282 if (rc) return base::Board::operErrBuild(rc, i);
00283 }
00284
00285
00286 for (int i=0; i<3; i++) {
00287 rc = setRegister(regs[i], patt[i]);
00288 if (rc && (res==0)) res = base::Board::operErrBuild(rc, 3+i);
00289 }
00290
00291
00292 for (int i=0; i<3; i++) {
00293 rc = getRegister(regs[i], back[i]);
00294 if (rc && (res==0)) res = base::Board::operErrBuild(rc, 6+i);
00295 if ((back[i] != patt[i]) && (res==0))
00296 res = base::Board::operErrBuild(base::Board::kOperVerifyErr, 6+i);
00297 }
00298
00299
00300 for (int i=0; i<3; i++)
00301 setRegister(regs[i], save[i], true);
00302
00303 return res;
00304 }
00305
00306
00308
00316 int nxyter::NxI2c::setToDefault(bool ispos, int maskon, int poweron)
00317 {
00318 nxyter::NxContext cntx;
00319 cntx.setToDefault(ispos, maskon, poweron);
00320 return setContext(cntx);
00321 }
00322
00323
00325
00331 void nxyter::NxI2c::printRegisters(std::ostream& os, int domask)
00332 {
00333 nxyter::NxContext cntx;
00334 int rc = getContext(cntx, domask);
00335 if (rc) {
00336 os << std::dec;
00337 os << "Failed to read nx context port: " << getPortNumber()
00338 << " addr: " << std::dec << uint16_t(getSlaveAddr())
00339 << " " << base::Board::operErrToString(rc) << std::endl;
00340 } else {
00341 cntx.print(os, domask);
00342 }
00343 }
00344
00345
00347
00355 int nxyter::NxI2c::setRegMask(const uint8_t *val)
00356 {
00357 return setRegisterArray(0, val, 16);
00358 }
00359
00360
00362
00372 int nxyter::NxI2c::setRegCore(const uint8_t *val)
00373 {
00374 int rc;
00375
00376 rc = setRegisterArray(16, val+16, 14);
00377 if (rc) return rc;
00378 rc = setRegisterArray(32, val+32, 2);
00379 if (rc) return base::Board::operErrBuildInc(rc, 14);
00380 rc = setRegisterArray(38, val+38, 2);
00381 if (rc) return base::Board::operErrBuildInc(rc, 16);
00382 rc = setRegisterArray(43, val+43, 3);
00383 if (rc) return base::Board::operErrBuildInc(rc, 19);
00384 return 0;
00385 }
00386
00387
00389
00400 int nxyter::NxI2c::setRegTrim(const uint8_t *val)
00401 {
00402 int rc = setRegister(kNxRegTrimDAQPower, val[128]);
00403 if (rc) return base::Board::operErrBuild(rc, 128);
00404 rc = setMailboxRegister(kNxRegTrimDAQPower, val, 128);
00405 if (rc) return base::Board::operErrBuildInc(rc, 1);
00406 return 0;
00407 }
00408
00409
00411
00423 int nxyter::NxI2c::getRegMask(uint8_t *val)
00424 {
00425 int rc;
00426 uint8_t conf0;
00427 rc = getRegister(kNxRegConfig0, conf0);
00428 if (rc) return rc;
00429 if (conf0 & kNxC0TestTrigEnable) {
00430 rc = setRegister(kNxRegConfig0, (conf0 & ~kNxC0TestTrigEnable));
00431 if (rc) return rc;
00432 }
00433
00434 rc = getRegisterArray(0, val, 16);
00435 if (rc) return rc;
00436
00437 if (conf0 & kNxC0TestTrigEnable) {
00438 rc = setRegister(kNxRegConfig0, conf0);
00439 if (rc) return rc;
00440 }
00441
00442 return 0;
00443 }
00444
00445
00447
00457 int nxyter::NxI2c::getRegCore(uint8_t *val)
00458 {
00459 int rc = getRegisterArray(16, val+16, 14);
00460 if (rc) return rc;
00461 rc = getRegisterArray(32, val+32, 2);
00462 if (rc) return base::Board::operErrBuildInc(rc, 14);
00463 rc = getRegisterArray(38, val+38, 2);
00464 if (rc) return base::Board::operErrBuildInc(rc, 16);
00465 rc = getRegisterArray(43, val+43, 3);
00466 if (rc) return base::Board::operErrBuildInc(rc, 19);
00467 return 0;
00468 }
00469
00470
00472
00486 int nxyter::NxI2c::getRegTrim(uint8_t *val)
00487 {
00488 int rc;
00489
00490
00491
00492
00493
00494
00495 rc = getRegister(kNxRegTrimDAQPower, val[128]);
00496 if (rc) return base::Board::operErrBuild(rc, 128);
00497
00498 uint8_t valrewrite = val[128];
00499
00500 for (int i=0; i<128; i++) {
00501 rc = setRegisterVerify(kNxRegTrimDAQPower, valrewrite, val[i]);
00502 valrewrite = val[i];
00503 if (rc) return base::Board::operErrBuild(rc, i);
00504 }
00505 rc = setRegister(kNxRegTrimDAQPower, valrewrite);
00506 if (rc) return base::Board::operErrBuild(rc, 127);
00507 return 0;
00508 }
00509
00510
00512
00513 const char* nxyter::NxI2c::registerName(int reg)
00514 {
00515 static const char* names[46] = {"mask_000_007",
00516 "mask_008_015",
00517 "mask_016_023",
00518 "mask_024_031",
00519 "mask_032_039",
00520 "mask_040_047",
00521 "mask_048_055",
00522 "mask_056_063",
00523 "mask_064_071",
00524 "mask_072_079",
00525 "mask_080_087",
00526 "mask_088_095",
00527 "mask_096_103",
00528 "mask_104_111",
00529 "mask_112_119",
00530 "mask_120_127",
00531 "Vcg",
00532 "Icgfoll",
00533 "Vth",
00534 "Vbfb",
00535 "VbiasF",
00536 "VbiasS",
00537 "VbiasS2",
00538 "Vcm",
00539 "cal",
00540 "iCOMP",
00541 "iDUR",
00542 "iINV",
00543 "iPDH",
00544 "iTWC",
00545 "",
00546 "",
00547 "Config0",
00548 "Config1",
00549 "OverflowLSB",
00550 "OverflowMSB",
00551 "MissTokenLSB",
00552 "MissTokenMSB",
00553 "delayTestPuls",
00554 "delayTestTrig",
00555 "",
00556 "",
00557 "TrimDAQ-Power",
00558 "delayClock1",
00559 "delayClock2",
00560 "delayClock3"
00561 };
00562
00563 if (reg < 0 || reg >=46) return "";
00564 return names[reg];
00565 }
00566
00567
00569
00575 const char* nxyter::NxI2c::configurationBitName(int bit)
00576 {
00577 static const char* names[12] = {"test pulse enable",
00578 "test pulse synchronize",
00579 "test pulse polarity",
00580 "test trigger enable",
00581 "test trigger synchronize",
00582 "disable 32MHz clock",
00583 "disable 128 MHz clock",
00584 "TS LSB clock select",
00585 "calibration select bit 0",
00586 "calibration select bit 1",
00587 "front-end polarity",
00588 "readout clock select"
00589 };
00590
00591 if (bit < 0 || bit >=12) return "";
00592 return names[bit];
00593 }
00594
00595
00597
00608 uint8_t nxyter::NxI2c::delayToSetting(uint8_t delay)
00609 {
00610 static const uint8_t d2s[81] = {
00611 0, 1, 3, 4, 16, 64, 48, 5, 12, 17,
00612 192, 65, 7, 19, 49, 67, 68, 13, 51, 20,
00613 193, 195, 80, 196, 15, 69, 52, 76, 21, 71,
00614 81, 112, 208, 197, 23, 204, 53, 83, 77, 28,
00615 199, 55, 113, 84, 209, 79, 205, 240, 115, 211,
00616 29, 60, 207, 85, 212, 31, 116, 241, 87, 61,
00617 243, 92, 213, 117, 63, 244, 215, 119, 93, 220,
00618 124, 245, 95, 221, 247, 125, 223, 252, 127, 253,
00619 255
00620 };
00621
00622 return (delay <= 80) ? d2s[delay] : 0xff;
00623 }
00624
00625
00627
00637 uint8_t nxyter::NxI2c::settingToDelay(uint8_t val)
00638 {
00639 for (uint8_t delay=0; delay<=80; delay++) {
00640 if (delayToSetting(delay) == val) return delay;
00641 }
00642 return 0xff;
00643 }
00644
00645