00001
00007 #include <unistd.h>
00008 #include <time.h>
00009
00010 #include <iostream>
00011 #include <fstream>
00012
00013 #include "Sct/SctNames.h"
00014 #include "Sct/Env.h"
00015
00016 #include "RodCrate/RodModule.h"
00017 #include "RodCrate/BocCard.h"
00018 #include "RodCrate/TimModule.h"
00019
00020
00021 #include "sctConf/configXMLImpl.h"
00022
00023 #include "../VmeInterface/DummyVmeInterface.h"
00024 #ifndef USE_DUMMY_VME
00025 #include "../VmeInterface/RCCVmeInterface.h"
00026 #endif
00027
00028 #include "VmeDecode.h"
00029
00030 #include "SctApiDebug.h"
00031
00032 #include "SctApiConsts.h"
00033 #include "crateImpl.h"
00034
00035 #include "extraScans.h"
00036
00037 #ifdef USE_THREADS
00038 #include <boost/bind.hpp>
00039 #endif
00040
00041
00042 #include "ABCD/ABCDscans.h"
00043
00044 using namespace SctPixelRod;
00045 using namespace SctConfiguration;
00046
00047
00048 namespace SctApi {
00049
00050
00051
00052
00053 CrateImpl::CrateImpl(unsigned int partition, unsigned int crate,
00054 boost::shared_ptr<Configuration> newConf) :
00055 rodMap(), tim(0), config(newConf), vme(0),
00056 partition(partition), crate(crate), mrs(0),
00057 m_stopPolling(false), m_enablePolling(true)
00058 {
00059
00060 std::cout << "Initialising VME interface ... \n";
00061
00062 MRSStream *tempMrs = 0;
00063
00064 if(::Sct::SctNames::isMrsValid()) {
00065 tempMrs = &(::Sct::SctNames::Mrs());
00066 std::cerr << "Crate " << partition << ", " << crate << " found temporary mrs server\n";
00067 } else {
00068 std::cerr << "Crate " << partition << ", " << crate << " no mrs server, going to standalone mode\n";
00069 }
00070
00071 if(config->isDummyCrate(partition, crate)) {
00072 vme = new SctPixelRod::DummyVmeInterface();
00073
00074 if(tempMrs) {
00075 *tempMrs << "CRATE_DUMMY" << MRS_WARNING << MRS_QUALIF("SCTAPI") << MRS_TEXT("Using DUMMY interface") << ENDM;
00076 }
00077 #ifdef USE_DUMMY_VME
00078 } else {
00079 if(tempMrs) {
00080 *tempMrs << "CRATE_DUMMY" << MRS_ERROR << MRS_QUALIF("SCTAPI") << MRS_TEXT("Non dummy crate requested, support not compiled!") << ENDM;
00081 }
00082
00083 throw CrateException("RCC support not compiled");
00084 }
00085 #else
00086 } else {
00087
00088 try {
00089 vme = new SctPixelRod::RCCVmeInterface();
00090 } catch (VmeException &v) {
00091 Utility::decodeVme(v);
00092 std::cerr << "Interface not opened exception, check host and VME drivers. Crate initialisation failed!!\n";
00093
00094 if(tempMrs) {
00095 *tempMrs << "CRATEINIT_FAILED" << MRS_ERROR << MRS_QUALIF("SCTAPI") << MRS_TEXT("Crate initialisation failed (VME interface)") << ENDM;
00096 }
00097
00098 throw CrateException("Interface not found");
00099 }
00100
00101
00102 if(vme->getLastErrcode() == 515) {
00103
00104 std::cerr << "Interface not opened error, check host and VME drivers. Crate initialisation failed!!\n";
00105
00106 if(tempMrs) {
00107 *tempMrs << "CRATEINIT_FAILED" << MRS_ERROR << MRS_QUALIF("SCTAPI") << MRS_TEXT("Crate initialisation failed (VME interface)") << ENDM;
00108 }
00109
00110 throw CrateException("Interface not found");
00111 }
00112
00113
00114 if(tempMrs) {
00115 *tempMrs << "CRATEINIT_SUCCESS" << MRS_INFORMATION << MRS_QUALIF("SCTAPI") << MRS_TEXT("Successfully initialised VME interface") << ENDM;
00116 }
00117 }
00118 #endif
00119
00120 std::cout << " ... Done\n";
00121
00122 if(config.get() == 0) {
00123 std::cout << "Load configuration\n";
00124 config.reset(new ConfigurationXMLImpl());
00125 }
00126
00127 #if USE_THREADS
00128 pollThread.reset(new boost::thread(boost::bind(&CrateImpl::pollingLoop, this)));
00129 #endif
00130 }
00131
00132
00133
00134
00135 CrateImpl::~CrateImpl() {
00136
00137 #if USE_THREADS
00138 m_stopPolling = true;
00139 pollThread->join();
00140 #endif
00141
00142 for(RodMap::const_iterator i=rodMap.begin();i!=rodMap.end();i++){
00143 std::cout << "RodModule on shutdown " << *(i->second.second) << std::endl;
00144 delete i->second.first;
00145 delete i->second.second;
00146 }
00147 delete tim;
00148
00149 delete vme;
00150 }
00151
00152 void CrateImpl::rodInitialiseThread(int rod) {
00153 if(initialiseRod(rod) != 0) {
00154 std::cout << "Initialisation of rod " << rod << " failed!\n";
00155 return;
00156 }
00157
00158 rodCounter ++;
00159
00160 if(initialiseBOC(rod) == 0) {
00161 if(Debug::getInstance()->checkDebugOption(DEBUG_DIAG)) {
00162 std::cout << "Should have initialised BOC now" << std::endl;
00163 }
00164 }
00165 }
00166
00167 int CrateImpl::initialiseCrate() {
00168 if(!initialiseTim()) {
00169 std::cout << "TIM initialise successful\n";
00170 }
00171
00172 std::list<unsigned int> rods;
00173 try {
00174 rods = config->listRodsInCrate(partition, crate);
00175 } catch(ConfigurationException &c) {
00176 std::cout << "No RODs in this crate\n";
00177 std::cout << c.what() << std::endl;
00178
00179 return 0;
00180 }
00181
00182 std::cout << "Found configuration for " << rods.size() << " rods\n";
00183
00184 std::list<boost::shared_ptr<boost::thread> > rodInitThreads;
00185
00186 rodCounter = 0;
00187
00188 for(std::list<unsigned int>::const_iterator r=rods.begin();
00189 r!=rods.end();
00190 r++) {
00191
00192 rodInitThreads.push_back(boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&CrateImpl::rodInitialiseThread, this, *r))));
00193 }
00194
00195 for(std::list<boost::shared_ptr<boost::thread> >::const_iterator thread = rodInitThreads.begin();
00196 thread != rodInitThreads.end();
00197 thread ++) {
00198
00199 if(*thread) {
00200 (*thread)->join();
00201 } else {
00202 std::cout << " Null pointer to thread!\n";
00203 }
00204 }
00205
00206 int totalRods = rodCounter;
00207
00208 return totalRods;
00209 }
00210
00211
00212
00213
00214
00215 int CrateImpl::initialiseTim() {
00216 std::cout << "Load configuration for tim\n";
00217
00218 TimConfig timConf;
00219 try {
00220 timConf = config->getTimConfig(partition, crate);
00221 } catch(ConfigurationException &c) {
00222 tim = 0;
00223 return -1;
00224 }
00225
00226 try {
00227
00228 std::cout << "Initialise TIM\n";
00229
00230 tim = new SctPixelRod::TimModule(timConf.baseAddress, timMapSize, *vme);
00231
00232 std::cout << "Constructed\n";
00233
00234 tim->reset();
00235 tim->initialize();
00236
00237 std::cout << "Initialised\n";
00238
00239 std::cout << "Started TIM\n";
00240 tim->status();
00241
00242
00243 timSetFrequency(timConf.trigFrequency, timConf.resetFrequency);
00244 } catch (SctPixelRod::TimException &r) {
00245 tim = 0;
00246
00247 std::cerr << "While initialising TIM " << partition << " " << crate << ":\n";
00248 std::cerr << "Got TimException: " << std::endl;
00249 std::cerr << r.getDescriptor() << ", " << r.getData1() << ", " << r.getData2() << std::endl;
00250 std::cerr << "Continuing...\n";
00251 } catch (VmeException &v) {
00252 tim = 0;
00253
00254 std::cout << "VmeException initialising TIM:\n";
00255 Utility::decodeVme(v);
00256
00257 return -9;
00258 } catch (...) {
00259 tim = 0;
00260
00261 std::cerr << "Unknown exception initialising TIM\n";
00262
00263 return -6;
00264 }
00265
00266 return 0;
00267 }
00268
00269
00270 std::list<unsigned> CrateImpl::getListOfRods() const{
00271 std::list<unsigned> rods;
00272 for (RodMap::const_iterator item = rodMap.begin();
00273 item != rodMap.end();
00274 item++) {
00275 rods.push_back(item->first);
00276 }
00277 return rods;
00278 }
00279
00280
00281
00282
00283 int CrateImpl::initialiseRod(unsigned int rod) {
00284 int returnValue = 0;
00285
00286 char *returnReason = "none specified";
00287
00288 int slave = 0;
00289
00290
00291 unsigned long rodAddress=1;
00292
00293 std::cout << "Load configuration for rod\n";
00294
00295 if(config->isDummyCrate(partition, crate)) {
00296
00297
00298 return 0;
00299 }
00300
00301
00302 SctPixelRod::RodModule* rodObject;
00303
00304 try {
00305 SctConfiguration::RodConfig rodConf;
00306
00307 rodConf = config->getRodConfig(partition, crate, rod);
00308
00309 rodAddress = rodConf.baseAddress;
00310
00311
00312 std::cout << "Initialise ROD " << rod << " at 0x" << std::hex << rodConf.baseAddress << std::dec << std::endl;
00313
00314 rodObject = new SctPixelRod::RodModule(rodConf.baseAddress,
00315 rodMapSize,
00316 *vme,
00317 numSlaves);
00318
00319 std::cout << "Constructed\n";
00320
00321 if(rodConf.resetLevel > 1) {
00322 std::cout << "*** ROD reset level " << rodConf.resetLevel << " (not reset) **** \n";
00323 std::cout << "*** Debug, ROD not reset **** \n";
00324 rodObject->initialize(false);
00325 } else {
00326 std::cout << "Doing full ROD reset...\n";
00327
00328 rodObject->initialize(true);
00329 std::cout << " ... done\n";
00330 }
00331
00332 std::cout << "Initialised\n";
00333
00334 std::cout << "Started ROD\n";
00335
00336 rodObject->status();
00337
00338 while(rodObject->textHandler() == TEXT_RQ_SET) {
00339 doTextBuffer(*rodObject);
00340
00341 }
00342
00343 RodStatus *currStatus = new RodStatus;
00344 currStatus->slaves = 0;
00345 #if USE_THREADS
00346 currStatus->currState = MYPRIM_STATE_IDLE;
00347
00348 #endif
00349
00350 #if USE_ROD_MODULE_SLAVES
00351 int startedSlaves = 0;
00352
00353
00354 try {
00355 for(slave=0; slave < rodConf.numSlaves; slave++) {
00356 if(rodConf.slaves[slave].ipramFile != "") {
00357 string ip(rodConf.slaves[slave].ipramFile);
00358 ip = Sct::Env::substituteVariables(ip);
00359
00360 string id(rodConf.slaves[slave].idramFile);
00361 id = Sct::Env::substituteVariables(id);
00362
00363 string ext(rodConf.slaves[slave].extFile);
00364 ext = Sct::Env::substituteVariables(ext);
00365
00366 std::cerr << "Starting slave " << slave << std::endl;
00367 std::cerr << "((" << ip << ", " << id << ", " << ext << ")\n";
00368
00369 rodObject->initSlaveDsp(ip, id, ext, slave, 'v');
00370
00371 RodOutList *outList = rodObject->getOutList();
00372 if(outList) {
00373 unsigned long* outBody = outList->getBody();
00374
00375 if(outBody) {
00376 if(outBody[3] != PRIM_LIST_REVISION) {
00377 std::cout << "Prim list revision disagrees\n";
00378 }
00379
00380 if(outBody[6] != START_SLAVE_EXECUTING) {
00381 std::cout << "Prim ID not start slave!\n";
00382 }
00383
00384 if(outBody[8] != slave) {
00385 std::cout << "Start slave says slave 0x" << std::hex << outBody[8] << std::dec << " started not " << slave << std::endl;
00386 }
00387 } else {
00388 std::cout << "No body from start slave outlist!\n";
00389 }
00390 } else {
00391 std::cout << "No response from start slave!\n";
00392 }
00393 startedSlaves ++;
00394 currStatus->slaves |= 1<<slave;
00395 }
00396 }
00397 } catch (SctPixelRod::NoImageFile &f) {
00398 std::cerr << "While initialising ROD " << partition << " " << crate << " " << rod << " slave " << slave << ":\n";
00399 std::cerr << "No image file exception " << f.getFileName() << std::endl;
00400 std::cerr << "Continuing...\n";
00401
00402 if(startedSlaves < 1) {
00403 *mrs << "ROD Slave Initialisation Failure" << MRS_ERROR << MRS_QUALIF("SCTAPI")
00404 << MRS_PARAM<const char *>("Filename", f.getFileName().c_str())
00405 << ENDM;
00406 }
00407 } catch (SctPixelRod::RodException &r) {
00408 std::cerr << "While initialising ROD " << partition << " " << crate << " " << rod << " slave " << slave << ":\n";
00409 std::cerr << "Bad ROD exception: " << std::endl;
00410 std::cerr << r.getDescriptor() << ", " << r.getData1() << ", " << r.getData2() << std::endl;
00411 std::cerr << "Continuing...\n";
00412 }
00413
00414 std::cout << "Started " << startedSlaves << " ROD slave DSPs\n";
00415 #endif
00416
00417 rodMap.insert(std::make_pair(rod, std::make_pair(currStatus, rodObject)));
00418
00419 std::cout << "ROD " << rod << " initialised\n";
00420
00421 if(mrs) {
00422 *mrs << "ROD_INIT" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
00423 << MRS_PARAM<int>("number", rod)
00424 << MRS_PARAM<int>("slot", rodObject->getSlot())
00425 << MRS_TEXT("ROD Initialised")
00426 << ENDM;
00427 }
00428 } catch(ConfigurationException &c) {
00429 std::cout << "Configuration error for rod " << rod << "\n";
00430 std::cout << "\t" << c.what() << std::endl;
00431 returnValue = -1;
00432 returnReason = "Error in configuration database";
00433 } catch (SctPixelRod::PrimListException &p) {
00434 std::cerr << "While initialising ROD " << partition << " " << crate << " " << rod << ":\n";
00435 std::cerr << "Exception sending primlist:\n";
00436 std::cerr << p.getDescriptor() << " " << p.getData1() << ", " << p.getData2() << std::endl;
00437
00438 returnReason = "PrimList exception";
00439 returnValue = -2;
00440 } catch (SctPixelRod::HpiException &h) {
00441 std::cerr << "While initialising ROD " << partition << " " << crate << " " << rod << ":\n";
00442 std::cerr << "HpiException:\n";
00443 std::hex(std::cerr);
00444 std::cerr << h.getDescriptor() << '\n';
00445 std::cerr << "calcAddr: " << h.getCalcAddr() << ", readAddr: " <<
00446 h.getReadAddr() << '\n';
00447 std::dec(std::cerr);
00448
00449 returnReason = "HPI exception";
00450 returnValue = -3;
00451 } catch (SctPixelRod::RodException &r) {
00452 std::cerr << "While initialising ROD " << partition << " " << crate << " " << rod << ":\n";
00453 std::cerr << "Rod Exception\n";
00454 std::cerr << r.getDescriptor() <<", " << r.getData1() << ", " << r.getData2()
00455 << '\n';
00456
00457 returnReason = "ROD exception";
00458 returnValue = -4;
00459 } catch (SctPixelRod::NoImageFile &f) {
00460 std::cerr << "While initialising ROD " << partition << " " << crate << " " << rod << " slave " << slave << ":\n";
00461 std::cerr << "No image file exception " << f.getFileName() << std::endl;
00462
00463 returnReason = "NoImageFile exception";
00464 returnValue = -5;
00465 } catch (VmeException &v) {
00466 std::cout << "VmeException initialising ROD:\n";
00467 Utility::decodeVme(v);
00468
00469 returnReason = "VmeException";
00470
00471 returnValue = -9;
00472 } catch (...) {
00473 std::cerr << "Unknown exception initialising ROD\n";
00474 returnValue = -6;
00475 }
00476
00477 if(returnValue < 0) {
00478 if(mrs) {
00479 *mrs << "RODINIT_FAIL" << MRS_ERROR << MRS_QUALIF("SCTAPI")
00480 << MRS_TEXT("ROD init failure")
00481 << MRS_PARAM<const char *>("reason", returnReason)
00482 << MRS_PARAM<int>("number", rod);
00483 if(rodAddress != 1)
00484 *mrs << MRS_PARAM<int>("address", rodAddress);
00485 *mrs << ENDM;
00486 }
00487 }
00488
00489 return returnValue;
00490 }
00491
00492
00493
00494
00495 int CrateImpl::initialiseBOC(unsigned int rod) {
00496 BocCard* bocCard;
00497
00498 try {
00499
00500
00501
00502
00503
00504
00505 } catch(ConfigurationException &c) {
00506 std::cout << "Request to initialise BOC with unconfigured rod\n";
00507 return -1;
00508 }
00509
00510 if(RODPresent(rod)) {
00511 try {
00512 std::cout << "Initialise BOC " << rod << std::endl;
00513
00514 bocCard = getRod(rod)->getBocCard();
00515
00516 if(bocCard == 0) {
00517
00518 return -2;
00519 }
00520
00521 bocCard->initialize();
00522 bocCard->status();
00523
00524 } catch (VmeException &v) {
00525 std::cout << "VmeException initialising BOC:\n";
00526 Utility::decodeVme(v);
00527 return -9;
00528 } catch (BocException &b) {
00529 std::cout << "BocException initialising BOC:\n";
00530 std::cout << b << std::endl;
00531 return -9;
00532 } catch (...) {
00533 std::cerr << "Unknown exception initialising BOC\n";
00534 return -6;
00535 }
00536
00537 configureBOC(rod);
00538 } else {
00539 std::cout << "Request for non-existent BOC " << partition << " " << crate << " " << rod << std::endl;
00540 return -1;
00541 }
00542
00543 return 0;
00544 }
00545
00546
00547
00548
00549 int CrateImpl::configureBOC(unsigned int rod) {
00550 if(!RODPresent(rod) || getRod(rod)->getBocCard() == 0) {
00551 std::cout << " configureBOC called on missing ROD/BOC " << rod << std::endl;
00552 throw CrateException("Trying to configure missing BOC");
00553 }
00554
00555 BocCard *bocCard = getRod(rod)->getBocCard();
00556
00557
00558 std::cout << " ************* Turning lasers on ROD " << rod << " ON ***************\n";
00559
00560 BOCGlobalConfig globalConf = config->getBOCGlobalConfig(partition, crate, rod);
00561 for(int r=0; r<9; r++) {
00562 if(globalConf.validMask & 1<<r) {
00563 switch(r) {
00564 case 0:
00565 bocCard->setClockControl(globalConf.clockControl);
00566 break;
00567 case 1:
00568 bocCard->setRxDataMode(globalConf.rxDataMode);
00569 break;
00570 case 2:
00571 if(globalConf.rxDacClear)
00572 bocCard->clearRxDac();
00573 break;
00574 case 3:
00575 if(globalConf.txDacClear)
00576 bocCard->clearTxDac();
00577 break;
00578 case 4:
00579 bocCard->setVernierFinePhase(globalConf.vernierFinePhase);
00580 break;
00581 case 5:
00582 bocCard->setVernierClockPhase0(globalConf.vernierClockPhase0);
00583 break;
00584 case 6:
00585 bocCard->setVernierClockPhase1(globalConf.vernierClockPhase1);
00586 break;
00587 case 7:
00588 bocCard->setBpmClockPhase(globalConf.bpmClockPhase);
00589 break;
00590 case 8:
00591 bocCard->setBregClockPhase(globalConf.bregClockPhase);
00592 break;
00593 }
00594 }
00595 }
00596
00597 unsigned char *mappings = config->getFibreMappings(partition, crate, rod);
00598
00599 for(int channel=0;channel<48;channel++){
00600
00601 int step = 0;
00602
00603 try {
00604 BOCChannelConfig channelConfig = config->getBOCConfig(partition, crate, rod, channel);
00605 std::cout << " Data for channel " << channel << std::endl;
00606
00607
00608 int txChannel = mappings[channel * 3 + 0];
00609 int rx0Channel = mappings[channel * 3 + 1];
00610 int rx1Channel = mappings[channel * 3 + 2];
00611
00612
00613 if(rx0Channel <= 95 && rx1Channel <= 95
00614
00615 && (((rx0Channel / 2) != (rx1Channel / 2)) || (rx0Channel == rx1Channel))) {
00616 std::cout << "Illegal rx fibre mappings for channel " << channel << std::endl;
00617 std::cout << " rx fibres must be mapped in consecutive pairs and low fibre must be even\n";
00618 if(mrs) {
00619 *mrs << "CRATE_FIBRES" << MRS_WARNING << MRS_QUALIF("SCTAPI")
00620 << MRS_TEXT("RX fibres must be mapped in consecutive pairs and low fibre must be even")
00621 << MRS_PARAM<int>("channel", channel)
00622 << MRS_PARAM<int>("fibre0", rx0Channel)
00623 << MRS_PARAM<int>("fibre1", rx1Channel)
00624 << MRS_PARAM<int>("partition", partition)
00625 << MRS_PARAM<int>("crate", crate)
00626 << MRS_PARAM<int>("rod", rod)
00627 << ENDM;
00628 }
00629 }
00630
00631
00632
00633
00634 bocCard->setLaserCurrent(txChannel, channelConfig.current);
00635 step ++;
00636 bocCard->setBpmFineDelay(txChannel, (channelConfig.delay&0xff) );
00637 step ++;
00638 bocCard->setBpmCoarseDelay(txChannel, ((channelConfig.delay>>8)&0xff));
00639 step ++;
00640 bocCard->setBpmMarkSpace(txChannel, channelConfig.markSpace);
00641 step ++;
00642
00643
00644 if((unsigned char)rx0Channel != (unsigned char)DATA_LINK_OFF) {
00645 bocCard->setRxThreshold(rx0Channel, channelConfig.threshold0);
00646 step ++;
00647 bocCard->setRxDataDelay(rx0Channel, channelConfig.delay0);
00648 step ++;
00649 }
00650 if((unsigned char)rx1Channel != (unsigned char)DATA_LINK_OFF) {
00651 bocCard->setRxThreshold(rx1Channel, channelConfig.threshold1);
00652 step ++;
00653 bocCard->setRxDataDelay(rx1Channel, channelConfig.delay1);
00654 step ++;
00655 }
00656 } catch(ConfigurationException &c) {
00657
00658
00659 } catch(BaseException &b) {
00660 std::cout << "Exception setting channel data for BOC step " << step << " ROD (" << rod << " channel " << channel << "): " << b << std::endl;
00661 }
00662 }
00663
00664 delete [] mappings;
00665
00666 return 0;
00667 }
00668
00674 int CrateImpl::sendPrimList(unsigned int rod, boost::shared_ptr<PrimListWrapper> prim) {
00675 if(RODPresent(rod)) {
00676 #if USE_THREADS
00677 if(m_stopPolling) {
00678 std::cerr << "PRIM LIST: Send prim list called when polling stopped\n";
00679 throw(CrateException("Called sendPrimList with polling stopped"));
00680 }
00681
00682 {
00683 RodStatus &stat = getRodData(rod);
00684 boost::mutex::scoped_lock lock(stat.mutex);
00685
00686 getRod(rod)->deleteOutList();
00687
00688 {
00689 boost::mutex::scoped_lock lock(primQueue_mutex);
00690 stat.listQueue.push_back(prim);
00691 primQueue_notEmpty.notify_one();
00692 }
00693
00694
00695 if(stat.currState == MYPRIM_STATE_IDLE) {
00696 stat.currState = MYPRIM_STATE_LOADED;
00697 } else {
00698 #warning "Throw exception?"
00699 std::cerr << "PRIM LIST: Sending prim list when not idle! (" << stat.currState << ")!\n";
00700 stat.currState = MYPRIM_STATE_LOADED;
00701 return -10;
00702 }
00703 }
00704 #else
00705 try {
00706
00707 getRod(rod)->deleteOutList();
00708 getRod(rod)->sendPrimList(prim->list.get());
00709 } catch (SctPixelRod::PrimListException &p) {
00710 std::cerr << "While sending primlist " << partition << " " << crate << " " << rod << ":\n";
00711 std::cerr << "Exception sending primlist:\n";
00712 std::cerr << p.getDescriptor() << " " << p.getData1() << ", " << p.getData2() << std::endl;
00713 return -6;
00714 } catch (SctPixelRod::HpiException &h) {
00715 std::cerr << "While sending primlist " << partition << " " << crate << " " << rod << ":\n";
00716 std::cerr << "HpiException:\n";
00717 std::hex(std::cerr);
00718 std::cerr << h.getDescriptor() << '\n';
00719 std::cerr << "calcAddr: " << h.getCalcAddr() << ", readAddr: " <<
00720 h.getReadAddr() << '\n';
00721 std::dec(std::cerr);
00722 return -2;
00723 } catch (SctPixelRod::RodException &r) {
00724 std::cerr << "While sending primlist " << partition << " " << crate << " " << rod << ":\n";
00725 std::cerr << "Rod Exception\n";
00726 std::cerr << r.getDescriptor() <<", " << r.getData1() << ", " << r.getData2()
00727 << '\n';
00728 return -3;
00729 } catch (SctPixelRod::NoImageFile &f) {
00730 std::cerr << "While sending primlist " << partition << " " << crate << " " << rod << ":\n";
00731 std::cerr << "No image file exception " << f.getFileName() << std::endl;
00732 return -4;
00733 } catch (...) {
00734 std::cerr << "Unknown exception sending primlist to ROD\n";
00735 return -5;
00736 }
00737
00738
00739 #endif
00740 } else {
00741 std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
00742 return -1;
00743 }
00744
00745 return 0;
00746 }
00747
00751 int CrateImpl::sendPrimListAll(boost::shared_ptr<PrimListWrapper> prim) {
00752 #if USE_THREADS
00753 {
00754 boost::mutex::scoped_lock lock(primQueue_mutex);
00755 listQueueAll.push_back(prim);
00756 primQueue_notEmpty.notify_one();
00757 }
00758
00759 return 0;
00760 #else
00761 int result = 0;
00762 for(RodMap::const_iterator item = rodMap.begin();
00763 item != rodMap.end();
00764 item++) {
00765 int rod = item->first;
00766
00767 int newResult = sendPrimList(rod, prim);
00768 if(result == 0) result = newResult;
00769 }
00770
00771 return result;
00772 #endif
00773 }
00774
00775 void CrateImpl::primListControl(unsigned int index, PLControl function) {
00776 if(RODPresent(index)) {
00777 SctPixelRod::RodModule &rod = *(getRod(index));
00778
00779 switch(function) {
00780 case C_PL_STOP:
00781 rod.setVmeCommandRegBit(CR_ABORT);
00782 break;
00783 case C_PL_PAUSE:
00784 rod.setVmeCommandRegBit(CR_PAUSE);
00785 break;
00786 case C_PL_RESUME:
00787 rod.setVmeCommandRegBit(CR_RESUME);
00788 break;
00789 case C_PL_CANCEL:
00790 rod.clearVmeCommandRegBit(CR_IN_LIST_RDY);
00791 break;
00792 }
00793 }
00794 }
00795
00796
00797
00798
00799 int CrateImpl::awaitResponse(unsigned int rod, int timeout) {
00800
00801
00802
00803
00804 using namespace SctPixelRod;
00805
00806 bool timedout = false;
00807
00808 time_t start_time = time(0);
00809
00810 if(RODPresent(rod)) {
00811 #if USE_THREADS
00812
00813
00814
00815
00816
00817 RodStatus &status = getRodData(rod);
00818
00819
00820
00821
00822 try {
00823
00824 RodPrimState localState = MYPRIM_STATE_EXECUTING;
00825 do {
00826 if((time(0) - start_time) > timeout) {
00827 timedout = true;
00828 std::cout << "Timeout from wait complete\n";
00829
00830 SctPixelRod::RodModule &myRod = *getRod(rod);
00831 std::cout << " Current state is ";
00832 switch(myRod.getPrimState()) {
00833 case PRIM_IDLE: std::cout << "IDLE"; break;
00834 case PRIM_LOADED: std::cout << "LOADED"; break;
00835 case PRIM_EXECUTING: std::cout << "EXECUTING"; break;
00836 case PRIM_WAITING: std::cout << "WAITING"; break;
00837 case PRIM_PAUSED: std::cout << "PAUSED"; break;
00838 }
00839 std::cout << std::endl;
00840 std::cout << " Local state is ";
00841 switch(localState) {
00842 case MYPRIM_STATE_LOADED: std::cout << "LOADED"; break;
00843 case MYPRIM_STATE_EXECUTING: std::cout << "EXECUTING"; break;
00844 case MYPRIM_STATE_COMPLETE: std::cout << "COMPLETE"; break;
00845 case MYPRIM_STATE_IDLE: std::cout << "IDLE"; break;
00846 }
00847 std::cout << std::endl;
00848 }
00849
00850
00851 sched_yield();
00852
00853 {
00854 boost::mutex::scoped_lock statLock(status.mutex);
00855 localState = status.currState;
00856 }
00857 } while ((localState != MYPRIM_STATE_COMPLETE)
00858 &&(!timedout));
00859
00860
00861 {
00862 boost::mutex::scoped_lock statLock(status.mutex);
00863 status.currState = MYPRIM_STATE_IDLE;
00864
00865
00866
00867
00868 }
00869
00870 if(timedout) {
00871 std::cout << "Timed out at " << timeout << " seconds\n";
00872 return -200;
00873 #warning "If timeout then should try to abort primitive..."
00874 }
00875 } catch (BaseException &b) {
00876 std::cerr << "In await response " << partition << " " << crate << " " << rod << ":\n";
00877 std::cerr << "Exception: " << b << std::endl;
00878 return -6;
00879 } catch (...) {
00880 std::cerr << "Unknown exception in await response\n";
00881 return -2;
00882 }
00883 #else // No threads
00884
00885 PrimState returnPState;
00886 TextBuffState returnTState;
00887
00888 SctPixelRod::RodModule* rod0 = getRod(rod);
00889
00890 try {
00891 int exceptCount = 0;
00892 do {
00893
00894 try {
00895 returnPState = rod0->primHandler();
00896 returnTState = rod0->textHandler();
00897 exceptCount = 0;
00898
00899 while (returnTState == TEXT_RQ_SET) {
00900 doTextBuffer(*rod0);
00901
00902
00903 returnTState = rod0->textHandler();
00904 }
00905
00906 if((time(0) - start_time) > timeout) {
00907 timedout = true;
00908 std::cout << "Timeout from wait execute\n";
00909 }
00910 } catch(VmeException &e) {
00911 exceptCount ++;
00912 if(exceptCount < 2) {
00913 std::cout << "Caught an exception, trying ignoring\n";
00914 rod0->sleep(100);
00915 } else {
00916 std::cout << " Repeat of exception, throwing anyway\n";
00917 throw;
00918 }
00919 }
00920 } while ((returnPState != PRIM_EXECUTING) && (!timedout));
00921 do {
00922 returnPState = rod0->primHandler();
00923
00924 if((time(0) - start_time) > timeout) {
00925 timedout = true;
00926 std::cout << "Timeout from wait finish\n";
00927 }
00928 } while ((returnPState != PRIM_WAITING)&&(returnPState != PRIM_IDLE) &&(!timedout));
00929
00930 if(timedout) {
00931 std::cout << "Timed out at " << timeout << " seconds\n";
00932 return -200;
00933 #warning "If timeout then should try to abort primitive..."
00934 }
00935 } catch (PrimListException &p) {
00936 std::cerr << "In await response " << partition << " " << crate << " " << rod << ":\n";
00937 std::cerr << "Exception sending primlist:\n";
00938 std::cerr << p.getDescriptor() << " " << p.getData1() << ", " << p.getData2() << std::endl;
00939 return -6;
00940 } catch (HpiException &h) {
00941 std::cerr << "In await response " << partition << " " << crate << " " << rod << ":\n";
00942 std::cerr << "HpiException:\n";
00943 std::hex(std::cerr);
00944 std::cerr << h.getDescriptor() << '\n';
00945 std::cerr << "calcAddr: " << h.getCalcAddr() << ", readAddr: " <<
00946 h.getReadAddr() << '\n';
00947 std::dec(std::cerr);
00948 return -5;
00949 } catch (VmeException &v) {
00950 std::cout << "VmeException in await response:\n";
00951 Utility::decodeVme(v);
00952
00953 return -9;
00954 } catch (RodException &r) {
00955 std::cerr << "In await response " << partition << " " << crate << " " << rod << ":\n";
00956 std::cerr << "Rod Exception\n";
00957 std::cerr << r.getDescriptor() <<", " << r.getData1() << ", " << r.getData2()
00958 << '\n';
00959 return -4;
00960 } catch (NoImageFile &f) {
00961 std::cerr << "In await response " << partition << " " << crate << " " << rod << ":\n";
00962 std::cerr << "No image file exception " << f.getFileName() << std::endl;
00963 return -3;
00964 } catch (...) {
00965 std::cerr << "Unknown exception in await response\n";
00966 return -2;
00967 }
00968
00969 #endif
00970 } else {
00971 std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
00972
00973 return -1;
00974 }
00975
00976 return 0;
00977 }
00978
00979
00980
00981
00982 int CrateImpl::awaitResponseAll(int timeout) {
00983 int result = 0;
00984 for(RodMap::const_iterator item = rodMap.begin();
00985 item != rodMap.end();
00986 item++) {
00987 int rod = item->first;
00988
00989 int newResult = awaitResponse(rod, timeout);
00990 if(result == 0) result = newResult;
00991 }
00992
00993 return 0;
00994 }
00995
00996
00997
00998
00999 boost::shared_ptr<RodOutList> CrateImpl::getResponse(unsigned int rod) {
01000 RodOutList *result = 0;
01001
01002 if(RODPresent(rod)) {
01003
01004 RodOutList *response = getRod(rod)->getOutList();
01005
01006 if(response) {
01007 result = new RodOutList(response->getLength());
01008
01009 unsigned long *oldBody = response->getBody();
01010 unsigned long *newBody = result->getBody();
01011
01012 for(int i=0; i<result->getLength(); i++) {
01013 newBody[i] = oldBody[i];
01014 }
01015
01016 getRod(rod)->deleteOutList();
01017 } else {
01018 std::cout << "**** No response found when expected\n";
01019 result = 0;
01020 }
01021 } else {
01022 std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01023 result = 0;
01024 }
01025
01026 return boost::shared_ptr<RodOutList>(result);
01027 }
01028
01029 void CrateImpl::setMrsStream(MRSStream *stream)
01030 {
01031 std::cerr << "Crate " << partition << ", " << crate << " using mrs server\n";
01032 mrs = stream;
01033 }
01034
01035
01036
01037
01038 bool CrateImpl::getRodMessage(unsigned int rod, char *buffer, unsigned long &length) {
01039 bool complete = true;
01040
01041 char myBuffer[TEXT_BUFF_SIZE];
01042 long myLength;
01043
01044 TEXT_BUFFER_TYPE dummy;
01045 if(RODPresent(rod)) {
01046 if(getRod(rod)->textHandler() == TEXT_READOUT) {
01047 getRod(rod)->getTextBuffer(myBuffer, myLength, dummy);
01048 getRod(rod)->clearTextBuffer();
01049
01050
01051 for(unsigned int i=0; i<length || i<(unsigned long)myLength; i++) {
01052 buffer[i] = myBuffer[i];
01053 }
01054
01055 if(length < (unsigned long)myLength) {
01056 complete = false;
01057 } else {
01058 length = myLength;
01059 }
01060 } else {
01061 buffer[0] = '\0';
01062 length = 0;
01063 complete = false;
01064 }
01065 }
01066
01067 return complete;
01068 }
01069
01070
01071
01072
01073 int CrateImpl::mdspBlockWrite(unsigned int rod, long dspStart, unsigned long* buffer, unsigned long numWords) {
01074 if(RODPresent(rod)) {
01075 try {
01076 getRod(rod)->mdspBlockWrite(dspStart, buffer, numWords);
01077 } catch(BaseException &b) {
01078 std::cout << "Exception writing mdsp\n";
01079 std::cout << b;
01080 return -3;
01081 } catch(...) {
01082 std::cout << "Exception writing mdsp\n";
01083 return -2;
01084 }
01085 } else {
01086 std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01087 return -1;
01088 }
01089
01090 return 0;
01091 }
01092
01093
01094
01095
01096 int CrateImpl::mdspBlockRead(unsigned int rod, long dspStart, unsigned long* buffer, unsigned long numWords) {
01097 if(RODPresent(rod)) {
01098 try {
01099
01100 getRod(rod)->mdspBlockRead(dspStart, buffer, numWords);
01101 } catch(BaseException &b) {
01102 std::cout << "Exception reading mdsp\n";
01103 std::cout << b;
01104 std::cout << "0x" << std::hex << dspStart << ", " << std::dec << numWords << std::endl;
01105 return -3;
01106 } catch(...) {
01107 std::cout << "Unknown exception reading mdsp\n";
01108 std::cout << "0x" << std::hex << dspStart << ", " << std::dec << numWords << std::endl;
01109 return -2;
01110 }
01111 } else {
01112 std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01113 return -1;
01114 }
01115
01116 return 0;
01117 }
01118
01119
01120
01121
01122 int CrateImpl::slvBlockWrite(unsigned int rod, long dspStart, unsigned long* buffer, unsigned long numWords, long dspNumber) {
01123 if(RODPresent(rod)) {
01124 try {
01125 getRod(rod)->slvBlockWrite(dspStart, buffer, numWords, dspNumber);
01126 } catch(BaseException &b) {
01127 std::cout << "Exception writing to slave\n";
01128 std::cout << b;
01129 return -3;
01130 } catch(...) {
01131 std::cout << "Exception writing to slave\n";
01132 return -2;
01133 }
01134 } else {
01135 std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01136 return -1;
01137 }
01138 return -0;
01139 }
01140
01141
01142
01143
01144 int CrateImpl::slvBlockRead(unsigned int rod, long dspStart, unsigned long* buffer, unsigned long numWords, long dspNumber) {
01145 if(RODPresent(rod)) {
01146 try {
01147 RodModule &r = *getRod(rod);
01148 #warning "Get lock so nobody else comes in and does something"
01149 unsigned long val = r.readRodStatusReg(2);
01150
01151 r.mdspSingleWrite(STATUS_REG[2], val & (~(1<<dspNumber)));
01152 r.slvBlockRead(dspStart, buffer, numWords, dspNumber);
01153 r.mdspSingleWrite(STATUS_REG[2], val);
01154 } catch(BaseException &b) {
01155 std::cout << "Exception reading slave\n";
01156 std::cout << b;
01157 return -3;
01158 } catch(...) {
01159 std::cout << "Exception reading slave\n";
01160 return -2;
01161 }
01162 } else {
01163 std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01164 return -1;
01165 }
01166 return 0;
01167 }
01168
01169 unsigned long CrateImpl::readRodStatusReg(unsigned int rod, long regNumber) {
01170 unsigned long result = 0;
01171
01172 if(RODPresent(rod)) {
01173 try {
01174 result = getRod(rod)->readRodStatusReg(regNumber);
01175 } catch(BaseException &b) {
01176 std::cout << "Exception reading rod status\n";
01177 std::cout << b;
01178 } catch(...) {
01179 std::cout << "Exception reading rod status\n";
01180 }
01181 } else {
01182 std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01183 }
01184 return result;
01185 }
01186
01187 unsigned long CrateImpl::readRodCommandReg(unsigned int rod, long regNumber) {
01188 unsigned long result = 0;
01189
01190 if(RODPresent(rod)) {
01191 try {
01192 result = getRod(rod)->readRodCommandReg(regNumber);
01193 } catch(BaseException &b) {
01194 std::cout << "Exception reading rod command\n";
01195 std::cout << b;
01196 } catch(...) {
01197 std::cout << "Exception reading rod command\n";
01198 }
01199 } else {
01200 std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01201 }
01202 return result;
01203 }
01204
01205 unsigned long CrateImpl::dspSingleRead(unsigned int rod, const unsigned long dspAddr, long dspNumber) {
01206 unsigned long result = 0;
01207
01208 if(RODPresent(rod)) {
01209 try {
01210 if(dspNumber == -1) {
01211 result = getRod(rod)->mdspSingleRead(dspAddr);
01212 } else {
01213 result = getRod(rod)->slvSingleRead(dspAddr, dspNumber);
01214 }
01215 } catch(BaseException &b) {
01216 std::cout << "Exception dsp single read\n";
01217 std::cout << b;
01218 } catch(...) {
01219 std::cout << "Exception dsp single read\n";
01220 }
01221 } else {
01222 std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01223 }
01224 return result;
01225 }
01226
01227 int CrateImpl::dspSingleWrite(unsigned int rod, unsigned long dspAddr, unsigned long buffer, long dspNumber) {
01228 if(RODPresent(rod)) {
01229 try {
01230 if(dspNumber == -1) {
01231 getRod(rod)->mdspSingleWrite(dspAddr, buffer);
01232 } else {
01233 getRod(rod)->slvSingleWrite(dspAddr, buffer, dspNumber);
01234 }
01235 } catch(BaseException &b) {
01236 std::cout << "Exception dsp single write\n";
01237 std::cout << b;
01238 } catch(...) {
01239 std::cout << "Exception dsp single write\n";
01240 return -2;
01241 }
01242 } else {
01243 std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01244 return -1;
01245 }
01246
01247 return 0;
01248 }
01249
01250 void CrateImpl::status() {
01251 std::cout << "TIM status\n";
01252 if(tim)
01253 tim->status();
01254 std::cout << std::endl;
01255
01256 if(rodMap.size() == 0) {
01257 if(mrs) {
01258 *mrs << "CRATE_STATUS" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
01259 << MRS_PARAM<int>("partition", partition) << MRS_PARAM<int>("crate", crate)
01260 << MRS_TEXT("No RODs loaded") << ENDM;
01261 }
01262 }
01263
01264 for(RodMap::const_iterator item = rodMap.begin();
01265 item != rodMap.end();
01266 item++) {
01267 RodModule &rod = *(item->second.second);
01268
01269 try {
01270
01271
01272 std::cout << "BOC status\n";
01273 if(rod.getBocCard() != 0) {
01274 rod.getBocCard()->status();
01275
01276 if(mrs) {
01277 *mrs << "BOC_STATUS" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
01278 << MRS_PARAM<int>("partition", partition) << MRS_PARAM<int>("crate", crate)
01279 << MRS_PARAM<int>("slot", rod.getSlot())
01280 << MRS_TEXT("BOC loaded") << ENDM;
01281 }
01282 } else {
01283 std::cout << "*********** No BOC status (BOC not present!!!!)\n";
01284 }
01285 } catch(ConfigurationException &c) {
01286 std::cout << "Request for status on unconfigured ROD! (impossible)\n";
01287 return;
01288 }
01289
01290 if(mrs) {
01291 *mrs << "ROD_STATUS" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
01292 << MRS_PARAM<int>("partition", partition) << MRS_PARAM<int>("crate", crate)
01293 << MRS_PARAM<int>("slot", rod.getSlot())
01294 << MRS_TEXT("ROD loaded") << ENDM;
01295 }
01296
01297 std::cout << "ROD status\n";
01298 rod.status();
01299
01300 if(rod.readRodStatusBit(0, SR_RUNNING)) {
01301 std::cout << "Running ";
01302 }
01303 if(rod.readRodStatusBit(0, SR_BUSY)) {
01304 std::cout << "Busy ";
01305 }
01306 if(rod.readRodStatusBit(0, SR_PAUSED)) {
01307 std::cout << "Paused ";
01308 }
01309 if(rod.readRodStatusBit(0, SR_OUT_LIST_RDY)) {
01310 std::cout << "Out list ready ";
01311 }
01312 if(rod.readRodStatusBit(0, SR_EXECUTING)) {
01313 std::cout << "Executing \n";
01314 unsigned long sr2 = rod.readRodStatusReg(1);
01315
01316 std::cout << "Current Primitive index = " << ((sr2 & 0xfffff0) >> 4) << std::endl;
01317 std::cout << "Current List index = " << (sr2 & 0xf);
01318 }
01319
01320 std::cout << std::endl;
01321 }
01322 }
01323
01324
01325
01326
01327
01328 SctPixelRod::RodModule *CrateImpl::getRod(unsigned int rod) const {
01329 RodMap::const_iterator found;
01330
01331 found = rodMap.find(rod);
01332 if(found == rodMap.end()) return 0;
01333 else return found->second.second;
01334 }
01335
01336 const RodStatus &CrateImpl::getRodData(unsigned int rod) const {
01337 RodMap::const_iterator found;
01338
01339 found = rodMap.find(rod);
01340 if(found == rodMap.end()) {
01341
01342
01343 std::cerr << " getRodData called on missing ROD " << rod << std::endl;
01344 throw CrateException("Asked for data on non-existant ROD (const)");
01345 }
01346 else return *(found->second.first);
01347 }
01348
01349 RodStatus &CrateImpl::getRodData(unsigned int rod) {
01350 RodMap::const_iterator found;
01351
01352 found = rodMap.find(rod);
01353 if(found == rodMap.end()) {
01354
01355
01356 std::cerr << " getRodData (const) called on missing ROD " << rod << std::endl;
01357 throw CrateException("Asked for data on non-existant ROD");
01358 }
01359 else return *(found->second.first);
01360 }
01361
01362 void CrateImpl::doTextBuffer(SctPixelRod::RodModule &rod) {
01363 TEXT_BUFFER_TYPE myTextType;
01364 TextBuffState returnTState;
01365
01366 std::cout << "Got some text: crate: " << crate << " rod slot: " << rod.getSlot() << "\n";
01367 do {
01368 returnTState = rod.textHandler();
01369 } while (returnTState != TEXT_READOUT);
01370
01371 const int maxMessagesIWantToSee=20;
01372 const bool showMeSomeMessagesIfPossible=true;
01373
01374 static int numberOfMessagesIHaveSeen=0;
01375
01376
01377 if (showMeSomeMessagesIfPossible) {
01378 const int moderateSizedIntegerMuchBiggerThanOne=10;
01379 if (numberOfMessagesIHaveSeen<maxMessagesIWantToSee+moderateSizedIntegerMuchBiggerThanOne) {
01380
01381 ++numberOfMessagesIHaveSeen;
01382 };
01383 };
01384
01385 const int showMeSomeMessagesNOW = showMeSomeMessagesIfPossible&&(numberOfMessagesIHaveSeen<=maxMessagesIWantToSee);
01386
01387 const bool textToMrs=((bool)mrs && showMeSomeMessagesNOW);
01388 if(textToMrs) {
01389 *mrs << "TEXTBUFF_ARRIVE" << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI")
01390 << MRS_PARAM<int>("partition", partition)
01391 << MRS_PARAM<int>("crate", crate)
01392 << MRS_PARAM<int>("rodSlot", rod.getSlot());
01393 }
01394
01395 char * myTextBuffer = new char[TEXT_BUFF_SIZE];
01396 long myTextLength;
01397
01398 rod.getTextBuffer(myTextBuffer, myTextLength, myTextType);
01399 rod.clearTextBuffer();
01400
01401 std::string type;
01402 switch(myTextType) {
01403 case TEXT_ERR: type = "ERROR"; break;
01404 case TEXT_INFO: type = "INFO"; break;
01405 case TEXT_DIAG: type = "DIAG"; break;
01406 case TEXT_XFER: type = "TRANSFER"; break;
01407 case TEXT_UNDEF: type = "**Undefined**"; break;
01408 }
01409
01410 std::cout << "Text " << type << " : " << myTextLength << std::endl;
01411 if(textToMrs) {
01412 *mrs << MRS_PARAM<const char *>("Type", type.c_str());
01413 }
01414
01415 if(myTextLength != 32768) {
01416 std::ostringstream message;
01417 std::ostringstream short_message;
01418 for (int i=0; i<myTextLength; i++) {
01419 message << myTextBuffer[i];
01420 if (myTextBuffer[i]!='\n' && i<100) short_message << myTextBuffer[i];
01421 }
01422 std::cout << message.str();
01423 myTextBuffer[myTextLength] = 0;
01424 if(textToMrs) {
01425 *mrs << MRS_TEXT(short_message.str().c_str())
01426 << MRS_PARAM<const char *>("Text", myTextBuffer);
01427 }
01428 } else {
01429 std::cout << "Buffersize suspiciously precisely 32768...\n";
01430 if(textToMrs) {
01431 *mrs << MRS_TEXT("Buffersize suspiciously precisely 32768...");
01432 }
01433
01434 if (false) {
01435 std::string fileName = Sct::SctNames::getLogDir() + "/SctApi32k" + type + "BufferDump.txt";
01436 std::ofstream outFile(fileName.c_str(), std::ios::binary | std::ios::app);
01437 time_t currTime = time(0);
01438 outFile << "Rod: " << rod.getSerialNumber() << " Time: " << ctime(&currTime) << std::endl;
01439 outFile.write(myTextBuffer, myTextLength);
01440 outFile << "\nEnd of dump\n";
01441 }
01442 }
01443
01444 std::cout << std::endl;
01445
01446 #warning "This should use debug level instead, but that's in SctApi not Crate!"
01447 #ifdef DEBUG
01448 std::ofstream outFile((type + "BufferDump.txt").c_str(), std::ios::binary | std::ios::app);
01449 outFile << "\nBuffer block length " << myTextLength << " rod " << rod.getSerialNumber() << std::endl;
01450 time_t currTime = time(0);
01451 outFile << "Time " << ctime(&currTime);
01452 outFile.write(myTextBuffer, myTextLength);
01453 #endif
01454
01455 if(textToMrs) {
01456 *mrs << ENDM;
01457 }
01458
01459 delete [] myTextBuffer;
01460 }
01461
01462 void CrateImpl::printBOCSetup(unsigned int rod) {
01463 if(RODPresent(rod)) {
01464 if(getRod(rod)->getBocCard() == 0) {
01465 std::cerr << " printBOCSetup called on missing BOC " << rod << std::endl;
01466 throw CrateException("No BOC for print setup");
01467 }
01468
01469 BocCard &bocCard = *(getRod(rod)->getBocCard());
01470
01471 std::cout.fill('0');
01472 for(int c=0; c<48; c++) {
01473 std::cout << "Channel ";
01474 std::cout.width(2);
01475 std::cout << c << ": I 0x";
01476 std::cout << std::hex;
01477 std::cout.width(2);
01478 std::cout << bocCard.getLaserCurrent(c) << " Delay 0x";
01479 std::cout.width(2);
01480 std::cout << bocCard.getBpmFineDelay(c) << "/0x";
01481 std::cout.width(2);
01482 std::cout << bocCard.getBpmCoarseDelay(c)
01483 << " M/S 0x";
01484 std::cout.width(2);
01485 std::cout << bocCard.getBpmMarkSpace(c);
01486 std::cout << " Input 0: Th 0x";
01487 std::cout.width(2);
01488 std::cout << bocCard.getRxThreshold(c*2) << " Delay 0x";
01489 std::cout.width(2);
01490 std::cout << bocCard.getRxDataDelay(c*2)
01491 << " Input 1: Th 0x";
01492 std::cout.width(2);
01493 std::cout << bocCard.getRxThreshold(c*2+1) << " Delay 0x";
01494 std::cout.width(2);
01495 std::cout << bocCard.getRxDataDelay(c*2+1)
01496 << std::endl;
01497 }
01498 std::cout.fill(' ');
01499 std::cout << std::dec;
01500 }
01501 }
01502
01503 std::vector<SctConfiguration::BOCChannelConfig> CrateImpl::currentBOCSetup(unsigned int rod) {
01504 std::vector<SctConfiguration::BOCChannelConfig> result;
01505
01506 if(RODPresent(rod)) {
01507 if(getRod(rod)->getBocCard() == 0) {
01508 std::cerr << " currentBOCSetup called on missing BOC " << rod << std::endl;
01509 throw CrateException("No BOC to get setup from");
01510 }
01511
01512 BocCard &bocCard = *(getRod(rod)->getBocCard());
01513
01514 for(int c=0; c<48; c++) {
01515 SctConfiguration::BOCChannelConfig chan;
01516
01517 chan.current = bocCard.getLaserCurrent(c);
01518 chan.delay = (bocCard.getBpmCoarseDelay(c) << 8) + bocCard.getBpmFineDelay(c);
01519 chan.markSpace = bocCard.getBpmMarkSpace(c);
01520 chan.threshold0 = bocCard.getRxThreshold(c*2);
01521 chan.delay0 = bocCard.getRxDataDelay(c*2);
01522 chan.threshold1 = bocCard.getRxThreshold(c*2+1);
01523 chan.delay1 = bocCard.getRxDataDelay(c*2+1);
01524
01525 result.push_back(chan);
01526 }
01527 }
01528
01529 return result;
01530 }
01531
01532 void CrateImpl::printBOCRegisters(unsigned int rod) {
01533 if(RODPresent(rod)) {
01534 if(getRod(rod)->getBocCard() == 0) {
01535 std::cerr << " printBOCRegisters called on missing BOC " << rod << std::endl;
01536 throw CrateException("No BOC for print registers");
01537 }
01538
01539 BocCard &bocCard = *(getRod(rod)->getBocCard());
01540
01541 std::cout << std::hex;
01542
01543 std::cout << "BOC register dump\n";
01544
01545 std::cout << "Clock control 0x" << bocCard.getClockControl() << std::endl;
01546 std::cout << "RX data mode 0x" << bocCard.getRxDataMode() << std::endl;
01547 std::cout << "RX DAC clear 0x" << bocCard.getRxDacClear() << std::endl;
01548 std::cout << "TX DAC clear 0x" << bocCard.getTxDacClear() << std::endl;
01549 std::cout << "Vernier fine 0x" << bocCard.getVernierFinePhase() << std::endl;
01550 std::cout << "Vernier clk 0 0x" << bocCard.getVernierClockPhase0() << std::endl;
01551 std::cout << "Vernier clk 1 0x" << bocCard.getVernierClockPhase1() << std::endl;
01552 std::cout << "BPM clk phase 0x" << bocCard.getBpmClockPhase() << std::endl;
01553 std::cout << "BReg clk phase 0x" << bocCard.getBregClockPhase() << std::endl;
01554 std::cout << "BOC reset 0x" << bocCard.getBocReset() << std::endl;
01555 std::cout << "BPM reset 0x" << bocCard.getBpmReset() << std::endl;
01556 std::cout << "BOC status 0x" << bocCard.getBocStatusRegister() << std::endl;
01557
01558 std::cout << std::dec;
01559 } else {
01560 std::cout << "No ROD found\n";
01561 }
01562 }
01563
01564 SctConfiguration::BOCGlobalConfig CrateImpl::currentBOCRegisters(unsigned int rod) {
01565 BOCGlobalConfig result;
01566
01567 if(RODPresent(rod)) {
01568 if(getRod(rod)->getBocCard() == 0) {
01569 std::cerr << " currentBOCRegisters called on missing BOC " << rod << std::endl;
01570 throw CrateException("No BOC for current registers");
01571 }
01572
01573 BocCard &bocCard = *(getRod(rod)->getBocCard());
01574
01575 result.validMask = 0x1ff;
01576 result.clockControl = bocCard.getClockControl();
01577 result.rxDataMode = bocCard.getRxDataMode();
01578 result.rxDacClear = bocCard.getRxDacClear();
01579 result.txDacClear = bocCard.getTxDacClear();
01580 result.vernierFinePhase = bocCard.getVernierFinePhase();
01581 result.vernierClockPhase0 = bocCard.getVernierClockPhase0();
01582 result.vernierClockPhase1 = bocCard.getVernierClockPhase1();
01583 result.bpmClockPhase = bocCard.getBpmClockPhase();
01584 result.bregClockPhase = bocCard.getBregClockPhase();
01585
01586
01587 }
01588
01589 return result;
01590 }
01591
01592 void CrateImpl::saveBOCSetup(unsigned int rod, BankType bank) {
01593 getRodData(rod).savedBocSetup[bank] = currentBOCSetup(rod);
01594 }
01595
01596 void CrateImpl::saveBOCRegisters(unsigned int rod, BankType bank) {
01597 getRodData(rod).savedBocRegisters[bank].reset(new BOCGlobalConfig(currentBOCRegisters(rod)));
01598 }
01599
01600 void CrateImpl::restoreBOCSetup(unsigned int rod, BankType bank) {
01601 BocCard *bocCard = getRod(rod)->getBocCard();
01602
01603 std::vector<SctConfiguration::BOCChannelConfig> &setup = getRodData(rod).savedBocSetup[bank];
01604
01605
01606
01607 for(int channel=0;channel<48;channel++){
01608 try {
01609 BOCChannelConfig channelConfig = setup[channel];
01610
01611 std::cout << " Restoring channel " << channel << std::endl;
01612
01613 int txChannel = channel;
01614 int rx0Channel = channel * 2;
01615 int rx1Channel = channel * 2 + 1;
01616
01617
01618 bocCard->setLaserCurrent(txChannel, channelConfig.current);
01619 bocCard->setBpmFineDelay(txChannel, (channelConfig.delay&0xff) );
01620 bocCard->setBpmCoarseDelay(txChannel, ((channelConfig.delay>>8)&0xff));
01621 bocCard->setBpmMarkSpace(txChannel, channelConfig.markSpace);
01622
01623
01624
01625 bocCard->setRxThreshold(rx0Channel, channelConfig.threshold0);
01626 bocCard->setRxDataDelay(rx0Channel, channelConfig.delay0);
01627
01628 bocCard->setRxThreshold(rx1Channel, channelConfig.threshold1);
01629 bocCard->setRxDataDelay(rx1Channel, channelConfig.delay1);
01630 } catch(BaseException &b) {
01631 std::cout << "Exception setting channel data for BOC " << " ROD (" << rod << " channel " << channel << "): " << b << std::endl;
01632 }
01633 }
01634 }
01635
01636 void CrateImpl::restoreBOCRegisters(unsigned int rod, BankType bank) {
01637 BocCard *bocCard = getRod(rod)->getBocCard();
01638
01639 BOCGlobalConfig &globalConf = *getRodData(rod).savedBocRegisters[bank];
01640 for(int r=0; r<9; r++) {
01641 if(globalConf.validMask & 1<<r) {
01642 switch(r) {
01643 case 0:
01644 bocCard->setClockControl(globalConf.clockControl);
01645 break;
01646 case 1:
01647 bocCard->setRxDataMode(globalConf.rxDataMode);
01648 break;
01649 case 2:
01650 if(globalConf.rxDacClear)
01651 bocCard->clearRxDac();
01652 break;
01653 case 3:
01654 if(globalConf.txDacClear)
01655 bocCard->clearTxDac();
01656 break;
01657 case 4:
01658 bocCard->setVernierFinePhase(globalConf.vernierFinePhase);
01659 break;
01660 case 5:
01661 bocCard->setVernierClockPhase0(globalConf.vernierClockPhase0);
01662 break;
01663 case 6:
01664 bocCard->setVernierClockPhase1(globalConf.vernierClockPhase1);
01665 break;
01666 case 7:
01667 bocCard->setBpmClockPhase(globalConf.bpmClockPhase);
01668 break;
01669 case 8:
01670 bocCard->setBregClockPhase(globalConf.bregClockPhase);
01671 break;
01672 }
01673 }
01674 }
01675 }
01676
01677
01678
01679
01680
01681
01682
01683 bool CrateImpl::checkBOCLasersOn(unsigned int rod) {
01684
01685
01686
01687
01688 if(RODPresent(rod)) {
01689 if(getRod(rod)->getBocCard() == 0) {
01690 return false;
01691 }
01692 return getRod(rod)->getBocCard()->getInterlockStatus();
01693 } else {
01694 return false;
01695 }
01696 }
01697
01698 void CrateImpl::enterBOCClockBy2Mode(unsigned int rod) {
01699 if(RODPresent(rod)) {
01700 if(getRod(rod)->getBocCard() == 0) {
01701 std::cerr << " enterBOCClockBy2Mode called on missing BOC " << rod << std::endl;
01702 throw CrateException("No BOC for enter clock/2");
01703 }
01704
01705 BocCard &bocCard = *(getRod(rod)->getBocCard());
01706
01707 bocCard.setRxDataMode(1);
01708 bocCard.setClockControl(2);
01709 }
01710 }
01711
01712 void CrateImpl::leaveBOCClockBy2Mode(unsigned int rod) {
01713 if(RODPresent(rod)) {
01714 if(getRod(rod)->getBocCard() == 0) {
01715 std::cerr << " leaveBOCClockBy2Mode called on missing BOC " << rod << std::endl;
01716 throw CrateException("No BOC for leave clock/2");
01717 }
01718
01719 BocCard &bocCard = *(getRod(rod)->getBocCard());
01720
01721 bocCard.setRxDataMode(0);
01722 bocCard.setClockControl(0);
01723 }
01724 }
01725
01726 std::vector<double> CrateImpl::getBOCMonitorArray(unsigned int rod) {
01727 if(!RODPresent(rod)) {
01728 std::cerr << " getBOCMonitorArray called on missing BOC " << rod << std::endl;
01729 throw CrateException("No BOC for getBOCMonitorArray");
01730 }
01731
01732 if(getRod(rod)->getBocCard() == 0) {
01733 std::cerr << " getBOCMonitorArray called on missing BOC " << rod << std::endl;
01734 throw CrateException("No BOC for getBOCMonitorArray");
01735 }
01736
01737 BocCard &bocCard = *(getRod(rod)->getBocCard());
01738
01739 std::vector<double> result;
01740
01741 for(int i=0; i<12; i++) {
01742 result.push_back(bocCard.getMonitorAdc(i));
01743 }
01744
01745 return result;
01746 }
01747
01748 void CrateImpl::modifyBOCParam(unsigned int type, unsigned int val, bool raw) {
01749 for(RodMap::const_iterator ri = rodMap.begin();
01750 ri!=rodMap.end();
01751 ri++) {
01752 int rod = ri->first;
01753 BocCard &bocCard = *(getRod(rod)->getBocCard());
01754 switch(type) {
01755
01756 case SCT_SCAN_BOC_BPM_PHASE:
01757 bocCard.setBpmClockPhase(val);
01758 break;
01759 case SCT_SCAN_BOC_BREG_PHASE:
01760 bocCard.setBregClockPhase(val);
01761 break;
01762 case SCT_SCAN_BOC_V0_PHASE:
01763 bocCard.setVernierClockPhase0(val);
01764 break;
01765 case SCT_SCAN_BOC_V1_PHASE:
01766 bocCard.setVernierClockPhase1(val);
01767 break;
01768 case SCT_SCAN_BOC_V_PHASES:
01769 bocCard.setVernierClockPhases(val);
01770 break;
01771 case SCT_SCAN_BOC_VRN_FINE:
01772 bocCard.setVernierFinePhase(val);
01773 break;
01774
01775 case SCT_SCAN_TX_CHANNELS:
01776 setupScanTx(rod, val);
01777 break;
01778 case SCT_SCAN_RAW_TX_CHANNELS:
01779 setupScanRawTx(rod, val);
01780 break;
01781 default:
01782
01783 for(int channel=0; channel<48; channel++) {
01784 modifyBOCParam(rod, channel, type, val, raw);
01785 }
01786 }
01787 }
01788 }
01789
01790 void CrateImpl::modifyBOCParam(unsigned int rod, unsigned int channel, unsigned int type, unsigned int val, bool raw) {
01791 if(RODPresent(rod)) {
01792 if(!getRod(rod)->getBocCard()) {
01793 std::cerr << " modifyBOCParam called on missing BOC " << rod << std::endl;
01794 throw CrateException("No BOC for modify BOC param");
01795 }
01796
01797 BocCard &bocCard = *(getRod(rod)->getBocCard());
01798
01799
01800 int txFibre = channel;
01801 int rxFibre1 = channel * 2 + 0;
01802 int rxFibre2 = channel * 2 + 1;
01803
01804 if(!raw) {
01805 unsigned char *mappings;
01806
01807 try {
01808 mappings = config->getFibreMappings(partition, crate, rod);
01809 } catch(ConfigurationException &c) {
01810 std::cout << "No fibre mappings for appropriate module: \n";
01811 std::cout << c.what() << std::endl;
01812 return;
01813 }
01814
01815 txFibre = mappings[channel * 3];
01816 rxFibre1 = mappings[channel * 3 + 1];
01817 rxFibre2 = mappings[channel * 3 + 2];
01818 }
01819
01820 try {
01821 switch(type) {
01822 case ST_RX_DELAY0:
01823 if(rxFibre1 != DATA_LINK_OFF) bocCard.setRxDataDelay(rxFibre1, val);
01824 break;
01825 case ST_RX_DELAY1:
01826 if(rxFibre2 != DATA_LINK_OFF) bocCard.setRxDataDelay(rxFibre2, val);
01827 break;
01828 case ST_RX_DELAY:
01829 if(rxFibre1 != DATA_LINK_OFF) bocCard.setRxDataDelay(rxFibre1, val);
01830 if(rxFibre2 != DATA_LINK_OFF) bocCard.setRxDataDelay(rxFibre2, val);
01831 break;
01832
01833 case ST_RX_THRESHOLD0:
01834 if(rxFibre1 != DATA_LINK_OFF) bocCard.setRxThreshold(rxFibre1, val);
01835 break;
01836 case ST_RX_THRESHOLD1:
01837 if(rxFibre2 != DATA_LINK_OFF) bocCard.setRxThreshold(rxFibre2, val);
01838 break;
01839 case ST_RX_THRESHOLD:
01840 if(rxFibre1 != DATA_LINK_OFF) bocCard.setRxThreshold(rxFibre1, val);
01841 if(rxFibre2 != DATA_LINK_OFF) bocCard.setRxThreshold(rxFibre2, val);
01842 break;
01843
01844 case ST_TX_CURRENT:
01845 if(txFibre != DATA_LINK_OFF) bocCard.setLaserCurrent(txFibre, val);
01846 break;
01847 case ST_TX_MARKSPACE:
01848 if(txFibre != DATA_LINK_OFF) bocCard.setBpmMarkSpace(txFibre, val);
01849 break;
01850 case ST_TX_DELAY:
01851 if(txFibre != DATA_LINK_OFF) bocCard.setBpmCoarseDelay(txFibre, (val&0xff00) >> 8);
01852 if(txFibre != DATA_LINK_OFF) bocCard.setBpmFineDelay(txFibre, (val&0xff));
01853 break;
01854 case ST_TX_COARSE:
01855 if(txFibre != DATA_LINK_OFF) bocCard.setBpmCoarseDelay(txFibre, val);
01856 break;
01857 case ST_TX_FINE:
01858 if(txFibre != DATA_LINK_OFF) bocCard.setBpmFineDelay(txFibre, val);
01859 break;
01860
01861
01862 case SCT_SCAN_BOC_BPM_PHASE:
01863 bocCard.setBpmClockPhase(val);
01864 break;
01865 case SCT_SCAN_BOC_BREG_PHASE:
01866 bocCard.setBregClockPhase(val);
01867 break;
01868 case SCT_SCAN_BOC_V0_PHASE:
01869 bocCard.setVernierClockPhase0(val);
01870 break;
01871 case SCT_SCAN_BOC_V1_PHASE:
01872 bocCard.setVernierClockPhase1(val);
01873 break;
01874 case SCT_SCAN_BOC_V_PHASES:
01875 bocCard.setVernierClockPhases(val);
01876 break;
01877 case SCT_SCAN_BOC_VRN_FINE:
01878 bocCard.setVernierFinePhase(val);
01879 break;
01880
01881
01882 case SCT_SCAN_TX_CHANNELS:
01883 setupScanTx(rod, val);
01884 break;
01885
01886 case SCT_SCAN_RAW_TX_CHANNELS:
01887 setupScanRawTx(rod, val);
01888 break;
01889
01890 default:
01891 break;
01892 }
01893 } catch(BocException &b) {
01894 std::cout << "BocException in modifyBOCParam: " << b << std::endl;
01895 throw CrateException("BOCException in modify");
01896 }
01897 }
01898 }
01899
01900 void CrateImpl::lasersOff() {
01901 for(RodMap::const_iterator ri = rodMap.begin();
01902 ri!=rodMap.end();
01903 ri++) {
01904 if(ri->second.second->getBocCard() == 0) {
01905 std::cerr << " Missing BOC in lasersOff\n";
01906 continue;
01907
01908 }
01909
01910 BocCard &bocCard = *(ri->second.second->getBocCard());
01911
01912 for(int i=0; i<48; i++) {
01913 bocCard.setLaserCurrent(i, 0);
01914 }
01915 }
01916 }
01917
01918 void CrateImpl::timSetFrequency(double trigFreq, double rstFreq) {
01919 if(tim) {
01920 std::cout << "Setting TIM frequencies: " << trigFreq << "kHz " << rstFreq << "Hz\n";
01921 int highBits;
01922
01923
01924 int power = (int)std::ceil(std::log10(trigFreq/8.0));
01925 std::cout << "trigPower " << power << std::endl;
01926 double trigBase;
01927 switch(power) {
01928 case 2: highBits = 0; trigBase = trigFreq / 10; break;
01929 case 1: highBits = 1; trigBase = trigFreq / 1; break;
01930 case 0: highBits = 2; trigBase = trigFreq / 0.1; break;
01931 case -1: highBits = 3; trigBase = trigFreq / 0.01; break;
01932 default:
01933 if(power<-1) { highBits = 3; trigBase = trigFreq / 0.01; }
01934 else { highBits = 0; trigBase = trigFreq / 10; }
01935 }
01936
01937 std::cout << "trigBase " << trigBase << std::endl;
01938 int lowBits = static_cast<int>(60.0 / trigBase);
01939
01940 if(lowBits == 1) lowBits = 0;
01941 if(lowBits == 10) lowBits = 1;
01942 if(lowBits > 6) lowBits = 7;
01943
01944 int trigNibble = (lowBits & 0x7) + ((highBits & 0xf) << 3);
01945 std::cout << "trigNibble " << trigNibble << " (" << lowBits << ", " << highBits << ")\n";
01946
01947
01948
01949
01950
01951 power = (int)std::ceil(std::log10(rstFreq/8.0));
01952 std::cout << "rstPower " << power << std::endl;
01953 double rstBase;
01954 switch(power) {
01955 case 2: highBits = 0; rstBase = rstFreq / 100; break;
01956 case 1: highBits = 1; rstBase = rstFreq / 10; break;
01957 case 0: highBits = 2; rstBase = rstFreq / 1; break;
01958 case -1: highBits = 3; rstBase = rstFreq / 0.1; break;
01959 default:
01960 if(power<-1) { highBits = 3; rstBase = rstFreq / 0.1; }
01961 else { highBits = 0; rstBase = rstFreq / 100; }
01962 }
01963
01964 std::cout << "rstBase " << rstBase << std::endl;
01965
01966 lowBits = (int)(6.0 / rstBase);
01967
01968 if(lowBits == 1) lowBits = 0;
01969 if(lowBits == 10) lowBits = 1;
01970 if(lowBits > 6) lowBits = 7;
01971
01972 int rstNibble = (lowBits & 0x7) + ((highBits & 0xf) << 3);
01973 std::cout << "rstNibble " << rstNibble << " (" << lowBits << ", " << highBits << ")\n";
01974
01975 tim->regLoad(TIM_REG_FREQUENCY, trigNibble + (rstNibble << 8));
01976 }
01977 }
01978
01979 void CrateImpl::freeTriggers() {
01980 if(tim) {
01981
01982 tim->loadBitSet(TIM_REG_ENABLES, SctPixelRod::TIM_BIT_EN_INT_TRIG);
01983 }
01984 }
01985
01986 void CrateImpl::stopTriggers() {
01987 if(tim)
01988 tim->intTrigStop();
01989 }
01990
01991 void CrateImpl::timL1A() {
01992 if(tim) {
01993 tim->issueCommand(SctPixelRod::TIM_VTRG);
01994 usleep(1);
01995 tim->loadBitClear(TIM_REG_COMMAND, SctPixelRod::TIM_VTRG);
01996 }
01997 }
01998
01999 void CrateImpl::timCalL1A(int delay) {
02000 if(tim)
02001 tim->issueVCAL(delay);
02002 }
02003
02004
02005 void CrateImpl::timECR() {
02006 if(tim) {
02007 tim->issueCommand(SctPixelRod::TIM_VECR);
02008
02009
02010 timRegLoad(2, 0x0);
02011 }
02012 }
02013
02014 void CrateImpl::timBCR() {
02015 if(tim) {
02016 tim->issueCommand(SctPixelRod::TIM_VBCR);
02017
02018
02019 timRegLoad(2, 0x0);
02020 }
02021 }
02022
02023 void CrateImpl::timFER() {
02024 if(tim) {
02025 tim->issueCommand(SctPixelRod::TIM_VFER);
02026
02027
02028 timRegLoad(2, 0x0);
02029 }
02030 }
02031
02032 void CrateImpl::sendTimBurst(int count) {
02033 if(tim) {
02034
02035 tim->regLoad(TIM_REG_BURST_COUNT, count);
02036
02037 tim->loadBitSet(TIM_REG_COMMAND, 0x200);
02038
02039
02040 tim->loadBitSet(TIM_REG_ENABLES, SctPixelRod::TIM_BIT_EN_INT_TRIG);
02041
02042
02043 tim->loadBitSet(TIM_REG_COMMAND, 0x400);
02044
02045
02046
02047
02048 while(tim->regFetch(TIM_REG_STATUS) & 0x10)
02049 ;
02050
02051
02052
02053
02054 tim->loadBitClear(TIM_REG_COMMAND, 0x400);
02055
02056
02057 tim->loadBitClear(TIM_REG_ENABLES, SctPixelRod::TIM_BIT_EN_INT_TRIG);
02058
02059
02060 tim->loadBitClear(TIM_REG_COMMAND, 0x200);
02061 }
02062 }
02063
02064 void CrateImpl::timVerbose() {
02065 for(int r = 0; r<0x34; r+=2) {
02066 std::cout.width(2);
02067 std::cout << std::hex << r << std::dec
02068 << ": 0x" << std::hex << tim->regFetch((SctPixelRod::TimRegister)r) << std::dec << std::endl;
02069 }
02070 }
02071
02072 void CrateImpl::timRegLoad(int reg, UINT16 val) {
02073 if(tim) {
02074 tim->regLoad(SctPixelRod::TimRegister(reg), val);
02075 }
02076 }
02077
02078 UINT16 CrateImpl::timRegRead(int reg) {
02079 if(tim) {
02080 return tim->regFetch(SctPixelRod::TimRegister(reg));
02081 } else {
02082 return 0;
02083 }
02084 }
02085
02086 bool CrateImpl::slavePresent(int rod, int index) const {
02087 bool present;
02088
02089 if(!RODPresent(rod))
02090 present = false;
02091 else {
02092 present = (getRodData(rod).slaves & (1<<index))?true:false;
02093 }
02094
02095 return present;
02096 }
02097
02098 void CrateImpl::slaveStarted(int rod, int slave){
02099 getRodData(rod).slaves |= 1<<slave;
02100 }
02101
02102 bool CrateImpl::RODPresent(int rod) const {
02103 return getRod(rod);
02104 }
02105
02106 long CrateImpl::getRodSlot(int rod) const {
02107 return getRod(rod)->getSlot();
02108 }
02109
02110 int CrateImpl::getRodRevision(int rod) const {
02111 return getRod(rod)->getRevision();
02112 }
02113
02114 void CrateImpl::stopPolling() {
02115 m_enablePolling = false;
02116 }
02117
02118 void CrateImpl::resumePolling() {
02119 m_enablePolling = true;
02120 }
02121
02122 void CrateImpl::setupScanTx(unsigned int rod, unsigned int channel) {
02123 BocCard &bocCard = *(getRod(rod)->getBocCard());
02124
02125 UINT32 iBuffer[48];
02126
02127 unsigned char *mappings;
02128 try {
02129 mappings = config->getFibreMappings(partition, crate, rod);
02130 } catch(ConfigurationException &c) {
02131 std::cout << "No mapping data for channel this rod\n";
02132 return;
02133 }
02134
02135
02136 for(unsigned int ch=0;ch<48;ch++){
02137 if(ch == channel) continue;
02138 int txChannel = mappings[ch * 3 + 0];
02139 iBuffer[txChannel] = 0;
02140 }
02141
02142 try {
02143 BOCChannelConfig channelConfig = config->getBOCConfig(partition, crate, rod, channel);
02144
02145 int txChannel = mappings[channel * 3 + 0];
02146 iBuffer[txChannel] = channelConfig.current;
02147 } catch(ConfigurationException &c) {
02148 std::cout << "No current configuration for channel " << channel << " leaving at 0\n";
02149 }
02150
02151
02152 bocCard.setLaserCurrent(0, iBuffer, 48);
02153 }
02154
02155 void CrateImpl::setupScanRawTx(unsigned int rod, unsigned int channel) {
02156 BocCard &bocCard = *(getRod(rod)->getBocCard());
02157
02158 UINT32 iBuffer[48];
02159
02160
02161 for(unsigned int ch=0;ch<48;ch++){
02162
02163 if(ch == channel) {
02164 #warning "This shouldn't be a constant current! (where should it come from though? Configuration may not be right...)"
02165 iBuffer[ch] = 0x90;
02166 } else {
02167 iBuffer[ch] = 0;
02168 }
02169 }
02170
02171
02172 bocCard.setLaserCurrent(0, iBuffer, 48);
02173 }
02174
02175 }