00001
00006
00007
00008 #include <string.h>
00009
00010 #include <stdexcept>
00011
00012 #include "roc/defines_i2c.h"
00013 #include "roc/I2cDevice.h"
00014
00015 #include "nxyter/defines_nxyter.h"
00016 #include "nxyter/FebBase.h"
00017
00018 #include "nxyter/Feb1nxGenB.h"
00019 #include "nxyter/Feb1nxGenC.h"
00020 #include "nxyter/Feb1nxGenD.h"
00021 #include "nxyter/Feb2nxGas.h"
00022 #include "nxyter/Feb4nxBT.h"
00023
00030
00032
00039 nxyter::FebBase::FebBase() :
00040 base::Peripheral(),
00041 fPort(0),
00042 fType(0),
00043 fMainAdc(),
00044 fMonAdcDevice(),
00045 fEepromDevice()
00046 {
00047 }
00048
00049
00050 nxyter::FebBase::FebBase(base::Board* board, int port, int type) :
00051 base::Peripheral(board),
00052 fPort(port),
00053 fType(type),
00054 fMainAdc(board, port, (type/100==4)),
00055 fMonAdcDevice(board, port, 0),
00056 fEepromDevice(board, port, 0)
00057 {
00058 int numnx = type/100;
00059 fNxChip.reserve(numnx);
00060 fNxOffline.reserve(numnx);
00061 fMode4nx = (numnx == 4);
00062 fAdcChannel.reserve(numnx);
00063 }
00064
00065
00066
00067 nxyter::FebBase::~FebBase()
00068 {
00069 for (int i=0; i<fNxChip.size(); i++) delete fNxChip[i];
00070 }
00071
00072
00074
00086 nxyter::NxChip& nxyter::FebBase::nx(int nxind)
00087 {
00088 return *(fNxChip.at(nxind));
00089 }
00090
00091
00093
00102 int nxyter::FebBase::initRoc()
00103 {
00104 int rc = board().put(ROC_NX_FEB4NX, (fMode4nx ? 1 : 0));
00105 if (rc) return rc;
00106 for (int i=0; i<numNx(); i++) {
00107 if (!getNxOffline(i))
00108 rc = adc().setChannelMux(nx(i).getNxNumber(), fAdcChannel[i]);
00109 if (rc) return base::Board::operErrBuildInc(rc, 2*(i+1));
00110
00111 if (getNxOffline(i))
00112 rc = nx(i).deactivate();
00113 else
00114 rc = nx(i).activate();
00115 if (rc) return base::Board::operErrBuildInc(rc, 2*(i+1)+1);
00116 }
00117 return 0;
00118 }
00119
00120
00121
00123
00127 int nxyter::FebBase::getFebState()
00128 {
00129 for (int i=0; i<numNx(); i++) {
00130 bool active = nx(i).isactive();
00131 setNxOffline(i, !active);
00132 }
00133 return 0;
00134 }
00135
00136
00137
00139
00150 int nxyter::FebBase::probe()
00151 {
00152 int rc = 0;
00153
00154 for (int i=0; i<fNxChip.size(); i++) {
00155 if (nx(i).i2c().probe()) {
00156 setNxOffline(i, true);
00157 rc |= 1<<i;
00158 } else {
00159 setNxOffline(i, false);
00160 }
00161 }
00162 if (adc().probe()) rc |= 1<<5;
00163 return rc;
00164 }
00165
00166
00168
00178 int nxyter::FebBase::setToDefault(bool ispos0, bool ispos1)
00179 {
00180 bool pos[4];
00181 for (int i=0; i<4; i++) pos[i] = ispos0;
00182 if (fNxChip.size()==2) pos[1] = ispos1;
00183 if (fNxChip.size()==4) pos[2] = pos[3] = ispos1;
00184
00185 int rc;
00186
00187 for (int i=0; i<fNxChip.size(); i++) {
00188 if (getNxOffline(i)) continue;
00189 rc = nx(i).i2c().setToDefault(pos[i]);
00190 if (rc) return base::Board::operErrBuild(rc, i);
00191 }
00192 rc = adc().setToDefault();
00193 if (rc) return base::Board::operErrBuild(rc, 5);
00194 return 0;
00195 }
00196
00197
00199
00200 void nxyter::FebBase::printNxHeadLine(std::ostream& os, int nxind)
00201 {
00202 os << std::dec;
00203 os << "----- nXYTER at port=" << fPort
00204 << " index=" << nxind
00205 << " number=" << nx(nxind).getNxNumber()
00206 << " addr=" << uint32_t(nx(nxind).i2c().getSlaveAddr());
00207 if (getNxOffline(nxind)) {
00208 os << " ----- is set OFFLINE -----";
00209 } else {
00210 os << " --------------------------";
00211 }
00212 os << std::endl;
00213 }
00214
00215
00217
00223 void nxyter::FebBase::printRegisters(std::ostream& os, int domask)
00224 {
00225 for (int i=0; i<fNxChip.size(); i++) {
00226 printNxHeadLine(os, i);
00227 if (!getNxOffline(i)) nx(i).i2c().printRegisters(os, domask);
00228 }
00229 os << "----- ADC at port=" << fPort << " --------------------" << std::endl;
00230 adc().printRegisters(os);
00231 }
00232
00233
00235
00242 void nxyter::FebBase::resetNxI2cBus()
00243 {
00244 board().operPPP(ROC_NX_I2C_SWITCH, fPort,
00245 ROC_NX_I2C_RESET, 0,
00246 ROC_NX_I2C_RESET, 1);
00247 }
00248
00249
00251
00264 void nxyter::FebBase::resetNxI2cRegister()
00265 {
00266 board().operPPP(ROC_NX_I2C_SWITCH, fPort,
00267 ROC_NX_I2C_REGRESET, 0,
00268 ROC_NX_I2C_REGRESET, 1);
00269 }
00270
00271
00273
00283 int nxyter::FebBase::setNxTestModes(bool testpuls, bool testtrig,
00284 int calselect)
00285 {
00286 for (int i=0; i<fNxChip.size(); i++) {
00287 int rc = nx(i).i2c().setTestModes(testpuls, testtrig, calselect);
00288 if (rc) return base::Board::operErrBuild(rc, i);
00289 }
00290 return 0;
00291 }
00292
00293
00295
00303 int nxyter::FebBase::setNxRegisterAll(uint8_t reg, uint8_t val, bool veri)
00304 {
00305 for (int i=0; i<fNxChip.size(); i++) {
00306 if (getNxOffline(i)) continue;
00307 int rc = nx(i).i2c().setRegister(reg, val, veri);
00308 if (rc) return base::Board::operErrBuild(rc, i);
00309 }
00310 return 0;
00311 }
00312
00313
00314
00315
00316 int nxyter::FebBase::getNumMonAdc()
00317 {
00318 if (!monAdcSupport()) return 0;
00319
00320 return 4;
00321 }
00322
00323
00325
00334 int nxyter::FebBase::getMonAdc(int ch, uint16_t &val)
00335 {
00336 val = 0;
00337 if (!monAdcSupport()) return -1;
00338 if (ch < 0 || ch > 3) return -2;
00339
00340 uint8_t mask = 1 << (ch+4);
00341 uint16_t adcval;
00342 int rc = fMonAdcDevice.getRegister16(mask, adcval);
00343 val = adcval & 0xfff;
00344 if (((adcval>>12) & 0x3) != ch) rc = -3;
00345 return rc;
00346 }
00347
00348
00359 void nxyter::FebBase::addNxChip(int addr, int nxnum, int adcmux)
00360 {
00361 if (fNxChip.size() >= fNxChip.capacity())
00362 throw std::out_of_range("FATAL ERROR: addNxChip(), extraneous call");
00363
00364 fNxChip.push_back(new nxyter::NxChip(getBoard(), fPort, addr, nxnum));
00365 fNxOffline.push_back(false);
00366 fAdcChannel.push_back(adcmux);
00367 }
00368
00369
00371
00377 const char* nxyter::FebBase::typeToString(int type)
00378 {
00379 switch (type) {
00380 case kFeb1nx : return "Feb1nx";
00381 case kFeb1nxGenB : return "Feb1nxGenB";
00382 case kFeb1nxGenC : return "Feb1nxGenC";
00383 case kFeb1nxGenD : return "Feb1nxGenD";
00384 case kFeb2nx : return "Feb2nx";
00385 case kFeb2nxGas : return "Feb2nxGas";
00386 case kFeb4nx : return "Feb4nx";
00387 case kFeb4nxBT : return "Feb4nxBT";
00388 }
00389 return "";
00390 }
00391
00392
00394
00401 int nxyter::FebBase::stringToType(const char* str)
00402 {
00403 if (strcmp(str, "Feb1nx")==0) return kFeb1nx;
00404 if (strcmp(str, "Feb1nxGenB")==0) return kFeb1nxGenB;
00405 if (strcmp(str, "Feb1nxGenC")==0) return kFeb1nxGenC;
00406 if (strcmp(str, "Feb1nxGenD")==0) return kFeb1nxGenD;
00407 if (strcmp(str, "Feb2nx")==0) return kFeb2nx;
00408 if (strcmp(str, "Feb2nxGas")==0) return kFeb2nxGas;
00409 if (strcmp(str, "Feb4nx")==0) return kFeb4nx;
00410 if (strcmp(str, "Feb4nxBT")==0) return kFeb4nxBT;
00411
00412 return 0;
00413 }
00414
00415
00417
00447 void nxyter::FebBase::discoverFebs(base::Board* board,
00448 int& typeport0, int& typeport1,
00449 bool liberal)
00450 {
00451 static const int dim_nxlist = 7;
00452 int nxaddr[dim_nxlist];
00453 int nxtype[dim_nxlist];
00454
00455 nxaddr[0] = 8; nxtype[0] = kFeb1nxGenC;
00456 nxaddr[1] = 40; nxtype[1] = kFeb2nxGas;
00457 nxaddr[2] = 48; nxtype[2] = kFeb2nxGas;
00458 nxaddr[3] = 72; nxtype[3] = kFeb4nxBT;
00459 nxaddr[4] = 82; nxtype[4] = kFeb4nxBT;
00460 nxaddr[5] = 84; nxtype[5] = kFeb4nxBT;
00461 nxaddr[6] = 88; nxtype[6] = kFeb4nxBT;
00462
00463 bool ok_adc[2];
00464 int num_adc = 0;
00465 bool ok_nx[2][dim_nxlist];
00466 int numnx_1nxGen[2];
00467 int numnx_2nxGas[2];
00468 int numnx_4nxBT[2];
00469 numnx_1nxGen[0] = numnx_1nxGen[1] = 0;
00470 numnx_2nxGas[0] = numnx_2nxGas[1] = 0;
00471 numnx_4nxBT[0] = numnx_4nxBT[1] = 0;
00472
00473
00474 for (int port=0; port<=1; port++) {
00475 nxyter::MainAdc adc(board, port);
00476 if ( (ok_adc[port] = (adc.probe() == 0)) ) num_adc++;
00477
00478 for (int i=0; i<dim_nxlist; i++) {
00479 nxyter::NxChip nx(board, port, nxaddr[i], 0);
00480 if ( (ok_nx[port][i] = (nx.i2c().probe() == 0)) ) {
00481 if (nxtype[i] == kFeb1nxGenC) numnx_1nxGen[port]++;
00482 if (nxtype[i] == kFeb2nxGas) numnx_2nxGas[port]++;
00483 if (nxtype[i] == kFeb4nxBT) numnx_4nxBT[port]++;
00484 }
00485 }
00486 }
00487
00488 typeport0 = 0;
00489 typeport1 = 0;
00490 if (num_adc==0) return;
00491
00492 int typeport[2];
00493 typeport[0] = 0;
00494 typeport[1] = 0;
00495
00496
00497 if (not liberal) {
00498 if (ok_adc[0]) {
00499 if (numnx_1nxGen[0]==1) typeport[0] = kFeb1nxGenC;
00500 if (numnx_2nxGas[0]==2) typeport[0] = kFeb2nxGas;
00501 if (numnx_4nxBT[0]==4) typeport[0] = kFeb4nxBT;
00502 }
00503 if (ok_adc[1] && typeport[0]!=kFeb4nx) {
00504 if (numnx_1nxGen[1]==1) typeport[1] = kFeb1nxGenC;
00505 if (numnx_2nxGas[1]==2) typeport[1] = kFeb2nxGas;
00506 }
00507
00508
00509 } else {
00510 if (ok_adc[0]) {
00511 if (numnx_1nxGen[0]>0) typeport[0] = kFeb1nxGenC;
00512 if (numnx_2nxGas[0]>0) typeport[0] = kFeb2nxGas;
00513 if (numnx_4nxBT[0]>0) typeport[0] = kFeb4nxBT;
00514 }
00515 if (ok_adc[1] && typeport[0]!=kFeb4nx) {
00516 if (numnx_1nxGen[1]>0) typeport[1] = kFeb1nxGenC;
00517 if (numnx_2nxGas[1]>0) typeport[1] = kFeb2nxGas;
00518 }
00519 }
00520
00521
00522
00523
00524 for (int port=0; port<=1; port++) {
00525 if (typeport[port]) {
00526 uint16_t val;
00527 roc::I2cDevice i2c(board, port, 41);
00528 int rc = i2c.getRegister16(0x10, val);
00529 if (rc == 0) {
00530 if (typeport[port] == kFeb1nxGenC) typeport[port] = kFeb1nxGenD;
00531 }
00532 }
00533 }
00534
00535 typeport0 = typeport[0];
00536 typeport1 = typeport[1];
00537 }
00538
00539
00541
00549 nxyter::FebBase* nxyter::FebBase::newFeb(base::Board* board, int port, int type)
00550 {
00551 if ((port<0) || (port>1)) return 0;
00552
00553 switch (type) {
00554 case kFeb1nxGenB : return new Feb1nxGenB(board, port);
00555 case kFeb1nxGenC : return new Feb1nxGenC(board, port);
00556 case kFeb1nxGenD : return new Feb1nxGenD(board, port);
00557 case kFeb2nxGas : return new Feb2nxGas(board, port);
00558 case kFeb4nxBT : return new Feb4nxBT(board);
00559 }
00560 return 0;
00561 }