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