00001
00008 #include <iostream>
00009 #include <stdexcept>
00010 #include <cmath>
00011 #include <cstdio>
00012 #include <unistd.h>
00013
00014 #include <sys/stat.h>
00015 #include <sys/types.h>
00016
00017 #include <boost/bind.hpp>
00018 #include <boost/format.hpp>
00019
00020 #include "SctApi.h"
00021 #include "SctApiConsts.h"
00022 #include "SctApiDebug.h"
00023 #include "SctApiHisto.h"
00024 #include "sctConf/configRegistry.h"
00025 #include "ScanDefImpl.h"
00026 #include "TriggerImpl.h"
00027 #include "crateImpl.h"
00028 #include "autoConfig.h"
00029
00030 #include "primUtils.h"
00031 #include "primListWrapper.h"
00032 #include "PrimBuilder.h"
00033
00034 #include "extraScans.h"
00035 #include "SctApiRodInfo.h"
00036
00037 #include "ScanResultWriter/scan.h"
00038 #include "Sct/SctNames.h"
00039 #include "Sct/FibreNumberConverters.h"
00040
00041 #include "registerIndices.h"
00042
00043 #include "Sct/AbcdScans.h"
00044 #include "Sct/AbcdChip.h"
00045
00046 #include "CommonWithDsp/primParams.h"
00047
00048 #include "RodCrate/RodModule.h"
00049
00050 #include "VmeDecode.h"
00051 #include "RodCrate/TimDefine.h"
00052
00053 #include <boost/date_time/posix_time/posix_time.hpp>
00054
00055 #ifdef USE_IS
00056 #include "Sct/IoExceptions.h"
00057 #include "ScanResultWriter/dataTypes.h"
00058 #include <is/info.h>
00059 #endif
00060
00061 #include "utility.h"
00062 #include "SctApiException.h"
00063 #include "ModuleList.h"
00064 #include "DCSAccess.h"
00065 #include "SctApiDDC.h"
00066 #include "Idiosyncrasy.h"
00067 #include "Sct/MultiMessageDebugStream.h"
00068
00069 using namespace std;
00070 using namespace SctPixelRod;
00071 using namespace SctConfiguration;
00072 using namespace SctApi::Utility;
00073 using namespace boost::posix_time;
00074 using boost::shared_ptr;
00075 using SctApi::ModuleList;
00076
00077
00078 static void handle_unexpected(void);
00079
00080 namespace SctApi {
00081
00082 const unsigned int SctApi::BAD_MODULE = 0xffffffff;
00083
00084
00085
00086
00087
00088
00089
00090 SctApi::SctApi(const Idiosyncrasy & id)
00091 : mrs(0),
00092 #if USE_IS
00093 m_isDict(),
00094 #endif
00095 rodList(), rodInfoList(), moduleMap(), scanController(), lastScanController(),
00096 m_id(new Idiosyncrasy(id)),
00097 config(),
00098 m_dcsAccess(new DCSAccessDummy), m_sctApiDDC(),
00099 debugPrimList(), crateObject(),
00100 m_log(new Log(id.ucid())), lastDebugScan(), lastDebugScanEx(),
00101 scanNumber(0), runNumber(0)
00102 #if USE_SCAN_THREAD
00103 ,
00104 scanQueue_notEmpty(), scanQueue_mutex(), scanPollThread(),
00105 m_stopPolling(false), m_inScanLoop(false), m_inRawScanLoop(false)
00106 #endif
00107 {
00108 cout << "Load configuration\n";
00109 std::string backend = "xml";
00110 SctConfiguration::FactoryManager::instance().loadPlugin(backend);
00111 SctConfiguration::Factory &f = SctConfiguration::FactoryManager::instance().getFactory(backend);
00112 config.reset(f.defaultConfig());
00113 config->loadConfiguration("");
00114 m_sctApiDDC = boost::shared_ptr<SctApiDDC>(new SctApiDDC(config, m_log));
00115 setup();
00116 }
00117
00119 SctApi::SctApi(const Idiosyncrasy & id, boost::shared_ptr<Configuration> newConf)
00120 : mrs(0),
00121 #if USE_IS
00122 m_isDict(),
00123 #endif
00124 rodList(), rodInfoList(), moduleMap(), scanController(), lastScanController(),
00125 m_id(new Idiosyncrasy(id)),
00126 config(),
00127 m_dcsAccess(new DCSAccessDummy), m_sctApiDDC(),
00128 debugPrimList(), crateObject(),
00129 m_log(new Log(id.ucid())), lastDebugScan(), lastDebugScanEx(),
00130 scanNumber(0), runNumber(0)
00131 #if USE_SCAN_THREAD
00132 ,
00133 scanQueue_notEmpty(), scanQueue_mutex(), scanPollThread(),
00134 m_stopPolling(false), m_inScanLoop(false), m_inRawScanLoop(false)
00135 #endif
00136 {
00137 config = newConf;
00138 m_sctApiDDC = boost::shared_ptr<SctApiDDC>(new SctApiDDC(config, m_log));
00139 setup();
00140 }
00141
00142
00143 SctApi::~SctApi() {
00144 {
00145 boost::mutex::scoped_lock lock(log().mutex());
00146 log() << "SctApi destructor\n";
00147 log() << "\t TIME " << second_clock::universal_time() << endl;
00148 }
00149
00150 #if USE_SCAN_THREAD
00151 m_stopPolling = true;
00152 scanPollThread->join();
00153 #endif
00154
00155 }
00156
00157 SctApiConfigCache& SctApi::getModuleConfigCache(){
00158 return module_cache;
00159 }
00160
00161 const Idiosyncrasy & SctApi::idiosyncrasy() {
00162 return *m_id;
00163 }
00164
00165 const std::string SctApi::getHostName() const {
00166 char buffer[100];
00167 gethostname(buffer, 100);
00168 return std::string(buffer);
00169 }
00170
00171 bool SctApi::hasFinishedScanning() {
00172 const std::string name
00173 = this->idiosyncrasy().infoServiceNameOfScanStatusObject();
00174
00175 const ISInfo::Status badlyTypedReturnValue
00176 = m_isDict->contains(name);
00177
00178 switch (badlyTypedReturnValue) {
00179 case ISInfo::NotFound:
00180
00181 return true;
00182 case ISInfo::Success:
00183
00184 return false;
00185 default:
00186
00187 {
00188 Sct::MultiMessageDebugStream m(true,false,true);
00189 m << "SctApi tried to figure out whether scanning had finished by looking for ["
00190 << name
00191 << "] but there was a problem: an unusual ISInfo::Status (value "
00192 << badlyTypedReturnValue
00193 << ") was returned while querying IS. Possible causes might include (but be limited to) running the sw without starting the appropriate is_servers, a software bug, or high network load causing poor CORBA connections, eg timeouts. Making a guess that scanning is not taking place at the moment ...";
00194 m.flush();
00195 };
00196 return true;
00197 };
00198 };
00199
00200 void SctApi::setup()
00201 {
00202 Debug::getInstance();
00203
00204 debugPrimList.reset(new PrimListWrapper);
00205
00206
00207 set_unexpected(handle_unexpected);
00208 cout << "Installed unexpected handler\n";
00209
00210 {
00211 boost::mutex::scoped_lock lock(log().mutex());
00212 log() << "Initial setup complete\n";
00213 }
00214
00215 #if USE_SCAN_THREAD
00216 scanPollThread.reset(new boost::thread(boost::bind(&SctApi::scanPollingThread, this)));
00217 #endif
00218 }
00219
00220 void SctApi::setMrsStream(MRSStream *stream)
00221 {
00222 mrs = stream;
00223 }
00224
00225 #if USE_IS
00226 void SctApi::setIsDictionary()
00227 {
00228 m_isDict =
00229 boost::shared_ptr<ISInfoDictionary>
00230 (new ISInfoDictionary(Sct::SctNames::getPartition()));
00231 }
00232 #endif
00233
00234
00235
00236
00237 unsigned long SctApi::readRodStatusReg(unsigned int rod,
00238 long regNumber) {
00239 unsigned long result = 0;
00240
00241 {
00242 boost::mutex::scoped_lock lock(log().mutex());
00243 log() << "readRodStatusReg " << regNumber << endl;
00244 }
00245
00246 Crate *myCrate = getCrate();
00247 if(myCrate) {
00248 result = myCrate->readRodStatusReg(rod, regNumber);
00249 }
00250
00251 return result;
00252 }
00253
00254
00255 unsigned long SctApi::readRodCommandReg(unsigned int rod,
00256 long regNumber) {
00257 unsigned long result = 0;
00258
00259 {
00260 boost::mutex::scoped_lock lock(log().mutex());
00261 log() << "readRodCommandReg\n";
00262 }
00263
00264 Crate *myCrate = getCrate();
00265 if(myCrate) {
00266 result = myCrate->readRodCommandReg(rod, regNumber);
00267 }
00268
00269 return result;
00270 }
00271
00272
00273 unsigned long SctApi::dspSingleRead(unsigned int rod,
00274 const unsigned long dspAddr, long dspNumber) {
00275 unsigned long result = 0;
00276
00277 {
00278 boost::mutex::scoped_lock lock(log().mutex());
00279 log() << "dspSingleRead 0x" << hex << dspAddr << dec << endl;
00280 }
00281 Crate *myCrate = getCrate();
00282 if(myCrate) {
00283 result = myCrate->dspSingleRead(rod, dspAddr, dspNumber);
00284 }
00285
00286 return result;
00287 }
00288
00289
00290 void SctApi::dspSingleWrite(unsigned int rod,
00291 unsigned long dspAddr, unsigned long value, long dspNumber) {
00292 {
00293 boost::mutex::scoped_lock lock(log().mutex());
00294 log() << "dspSingleWrite 0x" << hex << dspAddr << " 0x" << value << dec << endl;
00295 }
00296 Crate *myCrate = getCrate();
00297 if(myCrate) {
00298 myCrate->dspSingleWrite(rod, dspAddr, value, dspNumber);
00299 }
00300 }
00301
00302 ABCDModule *SctApi::lookupConfig(UINT32 mid) {
00303 {
00304 boost::mutex::scoped_lock lock(log().mutex());
00305 log() << "lookupconfig " << mid << endl;
00306 }
00307
00308 if(moduleMap.find(mid) == moduleMap.end()) {
00309 std::cout << "AJB lookup config " << mid << " requests cache " << std::endl;
00310 cacheModuleConfig(mid);
00311 }
00312
00313 ABCDModule *result = 0;
00314
00315 if(moduleMap.find(mid) != moduleMap.end()) {
00316 result = &(moduleMap.find(mid)->second);
00317 }
00318
00319 return result;
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 void SctApi::cacheModuleConfig(UINT32 mid, std::string moduleName) {
00336 unsigned int partition, crate, rod, channel;
00337 getpcrc(mid, partition, crate, rod, channel);
00338
00339 RodLabel label(partition, crate, rod);
00340
00341 unsigned int mur, module;
00342
00343
00344 try {
00345 if(checkDebugOption(DEBUG_DIAG))
00346 cout << "Looking for partition " << partition << " crate " << crate << " rod " << rod << " channel " << channel << endl;
00347 config->translateFromROD(partition, crate, rod, channel,
00348 mur, module);
00349
00350 if(checkDebugOption(DEBUG_DIAG2))
00351 cout << "Found MUR " << mur << " module number " << module << endl;
00352 } catch(ConfigurationException &c) {
00353 cout << "Can't find module in MUR map: \n";
00354 cout << c.what() << endl;
00355
00356 {
00357 boost::mutex::scoped_lock lock(log().mutex());
00358 log() << " (Not found)\n";
00359 }
00360
00361 throw;
00362 }
00363
00364 if (moduleName=="") try {
00365 config->translateToSN(mur, module, moduleName);
00366
00367 if(checkDebugOption(DEBUG_DIAG2))
00368 cout << "Found module name " << moduleName << endl;
00369
00370 } catch(ConfigurationException &c) {
00371 cout << "Module name not found: \n";
00372 cout << c.what() << endl;
00373
00374 {
00375 boost::mutex::scoped_lock lock(log().mutex());
00376 log() << " (Not found)\n";
00377 }
00378
00379 throw;
00380 }
00381
00382
00383 bool redundantOnROD = false;
00384
00385
00386 unsigned int rchannel;
00387 unsigned int rpartition, rcrate, rrod;
00388
00389
00390 unsigned long rmid;
00391
00392 bool redundantValid;
00393
00394 try {
00395 config->translateToRROD(mur, module,
00396 rpartition, rcrate, rrod, rchannel);
00397
00398 if(partition == rpartition && crate == rcrate && rod == rrod) {
00399 redundantOnROD = true;
00400 } else {
00401 RodLabel label(partition, crate, rod);
00402 RodLabel rlabel(rpartition, rcrate, rrod);
00403
00404 RodInfo & info(getRodInfo(label));
00405 RodInfo & rinfo(getRodInfo(rlabel));
00406
00407 cout << "Off ROD module found for mid " << mid << " !!! rchannel was = " << rchannel << endl;
00408
00409 unsigned int newRchannel = 48 + rinfo.offRODTTC.size();
00410 #warning BRUCE HAS REALISED THAT SOME OF WHAT FOLLOWS EXPECTS THE UNMODIFIED VALUE OF rchannel, AND SOME OF WHAT FOLLOWS EXPECTS THE ABOE "VIRTUAL+48" rchannel SO THERE ARE ALMOST DEFINITELY BUGS IN THIS ROUTINE THAT WILL PREVENT REDUNDANT LINKS BEING HANDLED CORRECTLY! (Chris on behalf of Bruce)
00411 #warning "Bruce has had an attempt at fixing this problem, but nobody has tested it with a real system"
00412 rmid = Utility::packpcrc(rpartition, rcrate, rrod, newRchannel);
00413
00414 info.offRODTTC[mid] = rmid;
00415 rinfo.offRODRX[rmid] = mid;
00416 cout << " rchannel now = " << newRchannel << " rmid = " << rmid << endl;
00417 }
00418
00419 redundantValid = true;
00420 } catch(ConfigurationException &c) {
00421 redundantValid = false;
00422 cout << "Module redundancy not found: \n";
00423 cout << c.what() << endl;
00424
00425 {
00426 boost::mutex::scoped_lock lock(log().mutex());
00427 log() << " (Not found)\n";
00428 }
00429
00430
00431 }
00432
00433
00434 ABCDModule configuration;
00435 try {
00436 configuration = config->getModuleConfig(moduleName);
00437
00438
00439
00440
00441
00442
00443 if(configuration.select) {
00444 for(int c=0; c<12; c++) {
00445 configuration.chip[c].address |= 0x10;
00446 }
00447 configuration.mid=rmid;
00448 } else {
00449 for(int c=0; c<12; c++) {
00450 configuration.chip[c].address &= ~0x10;
00451 }
00452 configuration.mid=mid;
00453 }
00454
00455
00456 RodInfo & info(getRodInfo(label));
00457
00458 {
00459 boost::recursive_mutex::scoped_lock lock(rodInfoListAccess);
00460
00461 if (!info.fibreMappings.get()) {
00462 std::cout << "getting fibre mappings for rod " << rod << std::endl;
00463 info.fibreMappings.reset(config->getFibreMappings(partition, crate, rod));
00464 }
00465 }
00466 configuration.pTTC = info.fibreMappings[channel * 3 + 0];
00467 if(redundantOnROD) {
00468 configuration.rTTC = info.fibreMappings[rchannel * 3 + 0];
00469 } else {
00470 configuration.rTTC = OFF_ROD_TTC;
00471 };
00472
00473
00474 unsigned char rx0 = info.fibreMappings[channel * 3 + 1];
00475 if(rx0 != DATA_LINK_OFF) {
00476 configuration.rx[0] = (rx0/12)*16 + rx0%12;
00477
00478 if(rx0 < getRodInfo(label).minLink) {
00479 getRodInfo(label).minLink = rx0;
00480 }
00481 } else {
00482 configuration.rx[0] = DATA_LINK_OFF;
00483 }
00484
00485
00486 unsigned char rx1 = info.fibreMappings[channel * 3 + 2];
00487 if(rx1 != DATA_LINK_OFF) {
00488 configuration.rx[1] = (rx1/12)*16 + rx1%12;
00489
00490 if(rx1 < getRodInfo(label).minLink) {
00491 getRodInfo(label).minLink = rx1;
00492 }
00493 } else {
00494 configuration.rx[1] = DATA_LINK_OFF;
00495 }
00496
00497
00498 configuration.groupId = config->getModuleGroup(moduleName);
00499
00500
00501 if(redundantValid && configuration.select) {
00502
00503
00504 try {
00505 string redModuleName;
00506
00507 unsigned int newMur, newModule;
00508 config->translateFromROD(rpartition, rcrate, rrod, rchannel,
00509 newMur, newModule);
00510
00511 config->translateToSN(newMur, newModule, redModuleName);
00512
00513 if(checkDebugOption(DEBUG_DIAG2))
00514 cout << "Found redundant module name " << redModuleName << endl;
00515
00516 int redGroup = config->getModuleGroup(redModuleName);
00517
00518 if(redGroup != configuration.groupId) {
00519 configuration.groupId = redGroup;
00520
00521 cout << "Module group changed, should be identical to redundant partner\n";
00522
00523 if(mrs)
00524 *mrs << "MODULE_GROUP_CHANGED" << MRS_WARNING << MRS_QUALIF("SCTAPI")
00525 << MRS_PARAM<const char *>("sn", moduleName.c_str())
00526 << MRS_PARAM<const char *>("redSn", redModuleName.c_str())
00527 << MRS_PARAM<int>("group", configuration.groupId)
00528 << MRS_TEXT("Module group changed, should be identical to redundant partner")
00529 << ENDM;
00530 }
00531 } catch(ConfigurationException &c) {
00532 cout << "Module name not found: \n";
00533 cout << c.what() << endl;
00534
00535 {
00536 boost::mutex::scoped_lock lock(log().mutex());
00537 log() << " (Not found)\n";
00538 }
00539 }
00540
00541 }
00542
00543
00544 for(int l=0; l<2; l++) {
00545 const unsigned int zeroTo123Pos = configuration.rx[l];
00546
00547 const unsigned int zeroTo95Pos = Sct::FibreNumberConverters::from124FormatTo96Format(zeroTo123Pos);
00548 if (zeroTo123Pos==DATA_LINK_OFF) {
00549
00550
00551 } else if(zeroTo123Pos <= 123 && zeroTo95Pos < 96) {
00552
00553 unsigned int val = config->getModuleErrorMask(partition, crate, rod, channel, l);
00554 getRodInfo(label).linkErrorMasks[zeroTo95Pos] = val;
00555 } else {
00556 std::ostringstream os;
00557 os << "Bad fibre numbers for error mask values! Line " << __LINE__ << " of " << __FILE__ << " when 123pos = " << zeroTo123Pos << " and 95pos = " << zeroTo95Pos;
00558 if (mrs) {
00559 *mrs << "SctApi" << MRS_ERROR << MRS_TEXT(os.str()) << ENDM;
00560 } else {
00561 std::cout << "SctApi: ERROR " << os.str() << std::endl;
00562 }
00563 }
00564 }
00565
00566
00567 moduleMap.insert(make_pair(mid, configuration));
00568
00569 if(redundantValid == true && redundantOnROD == false) {
00570
00571 configuration.rx[0] = DATA_LINK_OFF;
00572 configuration.rx[1] = DATA_LINK_OFF;
00573
00574
00575 configuration.pTTC = configuration.rTTC = rchannel;
00576
00577 moduleMap.insert(make_pair(rmid, configuration));
00578
00579 cout << "Off-ROD module configuration loaded " << rmid << " put in slot " << (int)configuration.pTTC << endl;
00580
00581 if(mrs) {
00582 *mrs << "MODULE_LOADED" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
00583 << MRS_TEXT("Off-ROD module configuration loaded")
00584 << MRS_PARAM<int>("rmid", rmid)
00585 << MRS_PARAM<int>("moduleSlot", configuration.pTTC)
00586 << ENDM;
00587 }
00588 }
00589
00590
00591 cout << "\tpTTC = " << (int)configuration.pTTC << " rTTC = " << (int)configuration.rTTC
00592 << " rx[0] = " << (int)configuration.rx[0] << " rx[1] = " << (int)configuration.rx[1]
00593 << " group = " << (int)configuration.groupId;
00594
00595 for(int l=0; l<2; l++) {
00596 const unsigned char link = l?rx1:rx0;
00597 if(link < 96) {
00598 int mask = getRodInfo(label).linkErrorMasks[link];
00599 cout << (l?" errorMask1 = 0x":" errorMask0 = 0x") << hex << mask << dec;
00600 }
00601 }
00602 cout << endl;
00603
00604 if(mrs) {
00605 int link0 = configuration.rx[0];
00606 int link1 = configuration.rx[1];
00607
00608
00609 if(link0 != DATA_LINK_OFF)
00610 link0 = (link0/16) * 12 + link0%16;
00611 if(link1 != DATA_LINK_OFF)
00612 link1 = (link1/16) * 12 + link1%16;
00613
00614 *mrs << "MODULE_LOADED" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
00615 << MRS_PARAM<const char *>("sn", moduleName.c_str())
00616 << MRS_PARAM<int>("group", configuration.groupId)
00617 << MRS_PARAM<int>("select", configuration.select)
00618 << MRS_PARAM<int>("pTTC", configuration.pTTC)
00619 << MRS_PARAM<int>("rTTC", configuration.rTTC)
00620 << MRS_PARAM<int>("rx0", link0)
00621 << MRS_PARAM<int>("rx1", link1);
00622
00623 for(int l=0; l<2; l++) {
00624 const unsigned char link = l?rx1:rx0;
00625 if(link < 96) {
00626 int mask = getRodInfo(label).linkErrorMasks[link];
00627 if(mask) {
00628 *mrs << MRS_PARAM<int>(l?"errorMask1":"errorMask0", mask);
00629 }
00630 }
00631 }
00632
00633 *mrs << MRS_TEXT("Module configuration loaded")
00634 << ENDM;
00635 }
00636
00637 } catch(ConfigurationException &c) {
00638 cout << "Module not initialised: \n";
00639 cout << c.what() << endl;
00640
00641 {
00642 boost::mutex::scoped_lock lock(log().mutex());
00643 log() << " (Not found)\n";
00644 }
00645
00646 throw;
00647 }
00648 }
00649
00650 ABCDModule *SctApi::retrieveModule(UINT32 mid) {
00651 {
00652 boost::mutex::scoped_lock lock(log().mutex());
00653 log() << "retrieveModule " << mid << endl;
00654 }
00655 return lookupConfig(mid);
00656 }
00657
00658
00659 void SctApi::createDebugPrimList() {
00660 {
00661 boost::mutex::scoped_lock lock(log().mutex());
00662 log() << "createDebugPrimList\n";
00663 }
00664 debugPrimList->clear();
00665 }
00666
00667
00668 void SctApi::addDebugPrimList(unsigned long length, long index, long id, long version,
00669 unsigned long * body) {
00670 {
00671 boost::mutex::scoped_lock lock(log().mutex());
00672 log() << "addDebugPrimList ID: " << id << " length: " << length << endl;
00673 }
00674
00675 debugPrimList->addPrimitive(RodPrimitive((long)length, index, id, version, (long *)body));
00676 }
00677
00678
00679 void SctApi::sendDebugPrimList(unsigned int rod) {
00680 {
00681 boost::mutex::scoped_lock lock(log().mutex());
00682 log() << "sendDebugPrimList " << m_id->ucid() << " " << rod << endl;
00683 }
00684 sendPrimList(rod, debugPrimList);
00685 }
00686
00687
00688 void SctApi::sendDebugPrimListAll() {
00689 {
00690 boost::mutex::scoped_lock lock(log().mutex());
00691 log() << "sendDebugPrimListAll\n";
00692 }
00693
00694 sendPrimListAll(debugPrimList);
00695 }
00696
00697 void SctApi::sendDebugSlavePrimList(unsigned int rod,
00698 unsigned int slave, bool await, bool response) {
00699 {
00700 boost::mutex::scoped_lock lock(log().mutex());
00701 log() << "sendDebugSlavePrimList \n";
00702 }
00703 sendSlavePrimList(rod, debugPrimList, slave, await, response);
00704 }
00705
00706 void SctApi::debugPrimListFromFile(string fileName) {
00707 ifstream fin(fileName.c_str(), ios::binary);
00708
00709 unsigned long fileSize;
00710
00711
00712 fin.seekg(0, std::ios::end);
00713 fileSize = fin.tellg();
00714 fin.seekg(0, std::ios::beg);
00715
00716 cout << "Loading file size: " << fileSize << endl;
00717
00718 long *buffer = new long[fileSize];
00719
00720 fin.read((char *)(buffer), fileSize);
00721
00722 long listLength = buffer[0];
00723
00724 long listNumPrims = buffer[2];
00725
00726
00727 int offset = 4;
00728
00729 debugPrimList->clear();
00730
00731 for(int i=0; i<listNumPrims; i++) {
00732 long primLength = buffer[offset + 0];
00733 long primIndex = buffer[offset + 1];
00734 long primId = buffer[offset + 2];
00735 long primVersion = buffer[offset + 3];
00736
00737
00738 debugPrimList->addPrimitive(primLength - 4, primIndex, primId, primVersion, buffer + offset + 4);
00739
00740 offset += primLength;
00741 if(offset > listLength) {
00742 cout << "offset too big\n";
00743 return;
00744 }
00745 }
00746 }
00747
00748 void SctApi::dumpDebugPrimList() {
00749 dumpPrimList(debugPrimList);
00750 }
00751
00752
00753
00754
00755
00756
00757
00758
00759 int SctApi::initialiseModule(string modulename, bool toRod) {
00760 {
00761 boost::mutex::scoped_lock lock(log().mutex());
00762 log() << "InitialiseModule " << modulename << endl << flush;
00763 }
00764
00765 unsigned int partition, crate, rod, channel;
00766
00767
00768 try {
00769 unsigned int MUR, module;
00770 config->translateFromSN(modulename, MUR, module);
00771 config->translateToROD(MUR, module, partition, crate, rod, channel);
00772 } catch(ConfigurationException &c) {
00773 cout << "Module not initialised: \n";
00774 cout << c.what() << endl;
00775 return -1;
00776 }
00777
00778 unsigned long mid=packpcrc(partition, crate, rod, channel);
00779
00780 try {
00781 boost::mutex::scoped_lock lock(moduleMapAccess);
00782
00783 if (moduleMap.find(mid) == moduleMap.end()){
00784 cout << "Cache " << (toRod?"and Load ":"") << "module " << modulename << " at " <<
00785 partition << ", " << crate << ", " << rod << ", " << channel << " \n";
00786
00787 cacheModuleConfig(mid, modulename);
00788 }
00789 } catch(ConfigurationException &c) {
00790 cout << "Module not initialised: \n";
00791 cout << c.what() << endl;
00792 return -2;
00793 }
00794
00795
00796 if(toRod){
00797 std::list<BankType> banks;
00798 banks.push_back(SCTAPI_BANK_PHYSICS);
00799 banks.push_back(SCTAPI_BANK_CALIBRATION);
00800 banks.push_back(SCTAPI_BANK_SCAN);
00801 setABCDModule(mid, banks);
00802 }
00803 return 0;
00804 }
00805
00806
00807
00808
00809 int SctApi::initialiseRod(unsigned int rod) {
00810 cout << "Hopefully will later get config for " << Sct::URID(prt(),crt(), rod) << " at " << __FILE__ << " " << __LINE__ << endl;
00811 {
00812 boost::mutex::scoped_lock lock(log().mutex());
00813 log() << "InitialiseRod\n";
00814 }
00815 Crate *myCrate = getCrate();
00816 if(!myCrate) {
00817 cout << "Request for non-existent crate " << ucid() << endl;
00818 return -1;
00819 } else if(!getCrate()->RODPresent(rod)) {
00820 cout << "ROD can't be initialised further: " << ucid() << " " << rod << endl;
00821 return -2;
00822 } else {
00823
00824 SctConfiguration::RodConfig rodConf;
00825 try {
00826 cout << "Getting config for " << Sct::URID(prt(),crt(), rod) << " at " << __FILE__ << " " << __LINE__ << endl;
00827 rodConf = config->getRodConfig(prt(), crt(), rod);
00828 } catch(ConfigurationException &c) {
00829 cout << "No configuration for rod " << rod << endl;
00830 return -3;
00831 }
00832
00833 {
00834
00835 shared_ptr<PrimListWrapper> srcIdList(new PrimListWrapper(1));
00836
00837 PrimBuilder &builder = PrimBuilder::instance();
00838 int regId = 0x1a1;
00839 #ifdef SOURCE_ID
00840 regId = SOURCE_ID;
00841 #endif
00842 builder.writeRegister(srcIdList, regId, 0, 16, (crt() << 8) | rod);
00843
00844 sendPrimList(rod, srcIdList);
00845 if(awaitResponse(rod, 1) != 0) {
00846 cout << "Setting source ID on ROD failed!\n";
00847 }
00848 }
00849
00850 int startedSlaves = 0;
00851 int configuredSlaves = 0;
00852 for(int slave=0; slave < numSlaves; slave++) {
00853 try {
00854 string ip;
00855 string id;
00856 string ext;
00857
00858 if(rodConf.slaves[slave].ipramFile != "") {
00859 ip = rodConf.slaves[slave].ipramFile;
00860 id = rodConf.slaves[slave].idramFile;
00861 ext = rodConf.slaves[slave].extFile;
00862 } else {
00863 cout << " Trying defaults\n";
00864
00865 int rev = getCrate()->getRodRevision(rod);
00866
00867 char revChar = (char)(rev-0xa) + 'A';
00868
00869
00870
00871
00872 cout << " Slave config for Rev" << revChar << endl;
00873
00874 SlaveConfig slaveConfig = config->getDefaultSlaveConfig(revChar);
00875 ip = slaveConfig.ipramFile;
00876 id = slaveConfig.idramFile;
00877 ext = slaveConfig.extFile;
00878 #warning "Assumes there are valid defaults..."
00879 }
00880
00881 std::cerr << "Starting slave " << slave << std::endl;
00882 std::cerr << "(" << ip << ", " << id << ", " << ext << ")\n";
00883
00884 configuredSlaves ++;
00885
00886
00887 if(getCrate()->getRodRevision(rod) >= 0xe) {
00888 writeSlaveFile(rod, slave, ip, 0);
00889 writeSlaveFile(rod, slave, id, 0x10000);
00890 writeSlaveFile(rod, slave, ext, 0xa0000000);
00891 } else {
00892 writeSlaveFile(rod, slave, ip, 0);
00893 writeSlaveFile(rod, slave, id, 0x80000000);
00894 writeSlaveFile(rod, slave, ext, 0x2000000);
00895 }
00896
00897 startSlave(rod, slave);
00898
00899 myCrate->slaveStarted(rod, slave);
00900
00901 startedSlaves ++;
00902
00903 cout << "Slave " << slave << " on rod " << rod << " configured at TIME " << second_clock::universal_time() << endl;
00904 } catch(ConfigurationException &c) {
00905 cout << "No configuration for slave " << slave << ": " << c.what() << endl;
00906
00907 if(mrs) {
00908 *mrs << "ROD_SLAVE_INIT" << MRS_ERROR
00909 << MRS_TEXT((string("ROD slave configuration not found: ") + c.what()).c_str())
00910 << MRS_PARAM<int>("partition", prt())
00911 << MRS_PARAM<int>("crate", crt())
00912 << MRS_PARAM<int>("rod", rod)
00913 << MRS_PARAM<int>("slave", slave)
00914 << ENDM;
00915 }
00916 } catch(SctApiException &s) {
00917 cout << "Slave start failed: " << s.what() << endl;
00918
00919 if(mrs) {
00920 *mrs << "ROD_SLAVE_INIT" << MRS_ERROR
00921 << MRS_TEXT((string("ROD slave initialisation failed: ") + s.what()).c_str())
00922 << MRS_PARAM<int>("partition", prt())
00923 << MRS_PARAM<int>("crate", crt())
00924 << MRS_PARAM<int>("rod", rod)
00925 << MRS_PARAM<int>("slave", slave)
00926 << ENDM;
00927 }
00928 }
00929 }
00930
00931 if(mrs) {
00932 *mrs << "ROD_SLAVE_INIT";
00933 if(startedSlaves != configuredSlaves) {
00934 *mrs << MRS_ERROR
00935 << MRS_TEXT("ROD slave initialisation incomplete");
00936 } else {
00937 *mrs << MRS_INFORMATION
00938 << MRS_TEXT("All ROD slaves initialised");
00939 }
00940 *mrs << MRS_QUALIF("SCTAPI")
00941 << MRS_PARAM<int>("partition", prt())
00942 << MRS_PARAM<int>("crate", crt())
00943 << MRS_PARAM<int>("rod", rod)
00944 << MRS_PARAM<int>("started", startedSlaves)
00945 << MRS_PARAM<int>("configuration", configuredSlaves)
00946 << ENDM;
00947 }
00948
00949 cout << "Started " << startedSlaves << " slave DSPs\n";
00950
00951 RodLabel currRod(prt(), crt(), rod);
00952
00953 std::cout << "Not Reading out modules from ROD but actually adding rod << " << Sct::URID(prt(),crt(),rod) << " to rod list!" << std::endl;
00954
00955 addRodToList(currRod);
00956 {
00957 const RodLabel & l = this->rodList.back();
00958 std::cout << "Last rod added was " << Sct::URID(l.partition, l.crate, l.rod) << std::endl;
00959 }
00960 }
00961 return 0;
00962 }
00963
00964
00973 class PreLoadConfigurations{
00974 public:
00975 PreLoadConfigurations(SctApi* api) : api(api){}
00976 ~PreLoadConfigurations(){}
00977 void operator() (){
00978 bool success=false;
00979 try{
00980 ptime start_time(second_clock::universal_time());
00981 std::cout << "Started preloading module configurations at TIME "
00982 << start_time << std::endl;
00983 api->m_preloadModuleConfigurationsStop=false;
00984 unsigned modules = api->preloadModuleConfigurations();
00985 ptime end_time(second_clock::universal_time());
00986 time_duration load_time=(end_time-start_time);
00987 std::cout << "Preloaded " << modules << " module configurations at TIME "
00988 << end_time << ". Took " << load_time.seconds() << " seconds" << std::endl;
00989 success=true;
00990 }catch(std::exception& e){
00991 std::cerr << e.what() << std::endl;
00992 }catch(...){
00993 }
00994 if (!success){
00995 std::cerr << api->ucid() << " Pre-load of module configurations FAILED!" << std::endl;
00996 }
00997 }
00998 SctApi* api;
00999 private:
01000 PreLoadConfigurations(){}
01001 };
01002
01003
01004
01005
01006
01007 #define PRELOAD_MODULE_CONFIGURATIONS 1
01008 void SctApi::initialiseAll(int run) {
01009
01010
01011
01012
01013
01014 runNumber = run;
01015 {
01016 boost::mutex::scoped_lock lock(log().mutex());
01017 log() << "InitialiseAll " << runNumber << " foe " << m_id->ucid() << "\n";
01018 }
01019 cout << "********** SCT API initialisation started for " << m_id->ucid() <<" **********\n";
01020 {
01021 time_t startTime = time(NULL);
01022 struct tm broke = *(gmtime(&startTime));
01023
01024 char buffer[25];
01025 strftime(buffer, 25, "%H:%M:%S %Y/%m/%d", &broke);
01026
01027 cout << "***************** " << buffer << " **************\n";
01028 }
01029
01030 unsigned int totalPartitions = 0;
01031 unsigned int totalCrates = 0;
01032 unsigned int totalRods = 0;
01033 unsigned int totalModules = 0;
01034
01035
01036
01037 crateObject.reset();
01038 moduleMap.clear();
01039 debugPrimList->clear();
01040 rodList.clear();
01041 module_cache.clearAll();
01042
01043
01044 #if PRELOAD_MODULE_CONFIGURATIONS
01045 boost::thread initialisation_thread(PreLoadConfigurations(this));
01046 #endif
01047
01048
01049 list<unsigned int> partitions;
01050 try {
01051 partitions = config->listPartitions();
01052 } catch(ConfigurationException &c) {
01053 cout << "No partitions to initialise\n";
01054 cout << c.what() << endl;
01055 return;
01056 }
01057
01058 cout << "Found configuration for " << partitions.size() << " partitions\n";
01059
01060 for(list<unsigned int>::const_iterator p=partitions.begin();
01061 p!=partitions.end();
01062 p++) {
01063
01064 list<unsigned int> crates;
01065
01066 try {
01067 crates = config->listCratesInPartition(*p);
01068 } catch(ConfigurationException &c) {
01069 cout << "No crates in this partition\n";
01070 cout << c.what() << endl;
01071 continue;
01072 }
01073
01074 cout << "Found configuration for " << crates.size() << " crates\n";
01075
01076 for(list<unsigned int>::const_iterator c=crates.begin();
01077 c!=crates.end();
01078 c++) {
01079
01080 if (Sct::UCID(*p, *c)==ucid()) {
01081
01082 cout << "Found a config for our own dear crate " << ucid() << endl;
01083 try {
01084 crateObject = boost::shared_ptr<Crate>(new CrateImpl(ucid(), config));
01085
01086 if(mrs)
01087 getCrate()->setMrsStream(mrs);
01088
01089 cout << ucid() << " Initialise crate at TIME " << boost::posix_time::second_clock::universal_time() << std::endl;
01090
01091 totalRods += getCrate()->initialiseCrate();
01092
01093 #warning 'AJB WHAT ABOUT TIM2??'
01094 unsigned tim_debug_status = timReadRegister(TIM_REG_DEBUG_CTL);
01095 bool sw_disable = tim_debug_status & (1<<12);
01096 unsigned tim_busy_stat3 = timReadRegister(0x5A);
01097 bool hw_disable = tim_busy_stat3 & (1<<15);
01098
01099 if (sw_disable || hw_disable){
01100 if (mrs) {
01101 *mrs << MRS_WARNING << "TIM_FFT_VETO_DISABLED" << MRS_QUALIF("SCTAPI")
01102 << MRS_PARAM<int>("partition",ucid().partition())
01103 << MRS_PARAM<int>("crate",ucid().crate())
01104 << MRS_PARAM<int>("hardware disable",hw_disable)
01105 << MRS_PARAM<int>("software disable",sw_disable)
01106 << MRS_PARAM<int>("overall disable",(sw_disable&&hw_disable))
01107 << MRS_TEXT("Tim Fixed Frequency Veto has been DISABLED! If the magnetic field is on this could be DANGEROUS TO MODULES!") << ENDM;
01108
01109 }else{
01110 std::cout << "TIM FFTV disable : h/w disable=" << hw_disable
01111 << " s/w disable=" << sw_disable << std::endl;
01112 }
01113 }
01114
01115 list<unsigned int> rods;
01116 try {
01117 rods = config->listRodsInCrate(*p, *c);
01118 } catch(ConfigurationException &cex) {
01119 cout << "No RODs in this crate\n";
01120 cout << cex.what() << endl;
01121
01122 if(mrs) {
01123 *mrs << "CRATE_WARNING" << MRS_WARNING << MRS_QUALIF("SCTAPI")
01124 << MRS_TEXT("No configuration for RODs while initialising crate")
01125 << MRS_PARAM<int>("partition", *p)
01126 << MRS_PARAM<int>("crate", *c)
01127 << ENDM;
01128 }
01129
01130 continue;
01131 }
01132
01133
01134 m_preloadModuleConfigurationsStop=true;
01135
01136 for(list<unsigned int>::const_iterator r=rods.begin();
01137 r!=rods.end();
01138 r++) {
01139 RodLabel label(*p, *c, *r);
01140
01141
01142 cout << ucid() << " Start rod " << *r << " initialisation at TIME " << boost::posix_time::second_clock::universal_time() << std::endl;
01143
01144 if(initialiseRod(*r) != 0) {
01145 cout << "Initialisation of rod " << *r << " failed!\n";
01146
01147 continue;
01148 }
01149
01150 cout << ucid() << " Start rod " << *r << " module initialisation at TIME " << boost::posix_time::second_clock::universal_time() << std::endl;
01151
01152 list<unsigned int> MURs;
01153 try {
01154 MURs = config->listMURSInRod(*p, *c, *r);
01155 } catch(ConfigurationException &cex) {
01156 cout << "No MURs for this ROD\n";
01157 cout << cex.what() << endl;
01158 if(mrs) {
01159 *mrs << "CRATE_WARNING" << MRS_WARNING << MRS_QUALIF("SCTAPI")
01160 << MRS_TEXT("Configuration for no modules while initialising ROD")
01161 << MRS_PARAM<int>("partition", *p)
01162 << MRS_PARAM<int>("crate", *c)
01163 << MRS_PARAM<int>("ROD", *r)
01164 << ENDM;
01165 }
01166 continue;
01167 }
01168 for(list<unsigned int>::const_iterator mur=MURs.begin();
01169 mur!=MURs.end();
01170 mur++) {
01171
01172 list<string> modules;
01173 try {
01174 modules = config->listModulesInMUR(*p, *mur);
01175 } catch(ConfigurationException &c) {
01176 cout << "No modules for this MUR\n";
01177 cout << c.what() << endl;
01178 continue;
01179 }
01180
01181 for(list<string>::const_iterator m=modules.begin();
01182 m!=modules.end();
01183 m++) {
01184
01185 if(!initialiseModule(*m, true)) {
01186 totalModules ++;
01187 }
01188 }
01189 }
01190 cout << totalModules << " modules initialised at TIME " << boost::posix_time::second_clock::universal_time() << std::endl;
01191
01192 testLinkOutSelect(*r, getRodInfo(label).minLink);
01193 }
01194
01195 std::cout << getCrate()->status();
01196 totalCrates++;
01197 {
01198 Sct::MultiMessageDebugStream m(true,true);
01199 m << "Crate server for " << ucid() << " finished setting up VME and saying HI to the TIM and all the RODs and BOCs (includes reset of the RODs).";
01200 }
01201 } catch(...) {
01202
01203 cout << "Unexpected failure in crate initialisation\n";
01204
01205 if(mrs) {
01206 *mrs << "CRATE_FAILED" << MRS_ERROR << MRS_QUALIF("SCTAPI")
01207 << MRS_TEXT("Unexpected failure initialising crate")
01208 << MRS_PARAM<int>("partition", *p)
01209 << MRS_PARAM<int>("crate", *c)
01210 << ENDM;
01211 }
01212 }
01213 } else {
01214
01215 };
01216 }
01217 totalPartitions ++;
01218 }
01219
01220 #if PRELOAD_MODULE_CONFIGURATIONS
01221 initialisation_thread.join();
01222 #endif
01223
01224 setErrorMasks();
01225
01226
01227 cout << "Setup for calibration...\n";
01228 calib_init();
01229
01230 currentRunMode = SCTAPI_RUN_CALIBRATION;
01231 cout << "... Done\n";
01232
01233 cout << "Initialisation counts:\n";
01234 cout << "\ttotalPartitions: " << totalPartitions << endl;
01235 cout << "\ttotalCrates: " << totalCrates << endl;
01236 cout << "\ttotalRods: " << totalRods << endl;
01237 cout << "\ttotalModules: " << totalModules << endl;
01238
01239 if (totalCrates!=1) {
01240 Sct::MultiMessageDebugStream m(true,true,true);
01241 m.severity(MRS_ERROR);
01242 m << "CrateController for " << ucid() << " found not one but " << totalCrates << " configurations in the config database while attempting to initialiseAll.";
01243 };
01244
01245 if(mrs) {
01246 *mrs << "SCTAPIINIT_COMPLETE" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
01247 << MRS_TEXT("SCTAPI Initialisation counts")
01248 << MRS_PARAM<int>("partitions", totalPartitions)
01249 << MRS_PARAM<int>("crates", totalCrates)
01250 << MRS_PARAM<int>("rods", totalRods)
01251 << MRS_PARAM<int>("modules", totalModules)
01252 << ENDM;
01253 }
01254
01255 cout << "************** SCT API initialised ****************\n";
01256 {
01257 time_t endTime = time(NULL);
01258 struct tm broke = *(gmtime(&endTime));
01259
01260 char buffer[25];
01261 strftime(buffer, 25, "%H:%M:%S %Y/%m/%d", &broke);
01262
01263 cout << "************** " << buffer << " ****************\n";
01264 }
01265 }
01266
01267 void SctApi::startSlave(unsigned int rod, unsigned int slave)
01268 {
01269 cout << "Starting slave on " << slave << endl;
01270
01271 shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
01272
01273 PrimBuilder::instance().startSlave(primList, slave);
01274
01275 sendPrimList(rod, primList);
01276 awaitResponse(rod, 5);
01277
01278 unsigned long length;
01279 unsigned long *result = getResponse(rod, length);
01280
01281 if(result) {
01282 unsigned int slaveRet = result[8];
01283 delete [] result;
01284 if(slaveRet != slave) {
01285 cout << "Bad return (" << slaveRet << ") from start slave " << slave << " \n";
01286 throw SctApiException("Bad return value from start slave");
01287 }
01288 } else {
01289 cout << "Bad response from start slave\n";
01290 throw SctApiException("Missing return primitive from start slave");
01291 }
01292 }
01293
01294 void SctApi::setRunNumber(UINT32 newRun) {
01295 bool needsUpdate = false;
01296 if(newRun < runNumber) {
01297 if(mrs) {
01298 *mrs << "SCTAPI_RUNNUMBER" << MRS_WARNING << MRS_QUALIF("SCTAPI")
01299 << MRS_TEXT("SCTAPI runnumber decrease")
01300 << MRS_PARAM<int>("oldRunNumber", runNumber)
01301 << MRS_PARAM<int>("newRunNumber", newRun)
01302 << MRS_PARAM<int>("newScanNumber", 0)
01303 << ENDM;
01304 }
01305 cout << "**** Run number has been decreased!!\n";
01306 runNumber = newRun;
01307 needsUpdate = true;
01308 scanNumber = 0;
01309 } else if(newRun == runNumber) {
01310 if(mrs) {
01311 *mrs << "SCTAPI_RUNNUMBER" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
01312 << MRS_TEXT("SCTAPI runnumber unchanged")
01313 << MRS_PARAM<int>("oldRunNumber", runNumber)
01314 << MRS_PARAM<int>("newRunNumber", newRun)
01315 << MRS_PARAM<int>("newScanNumber", scanNumber)
01316 << ENDM;
01317 }
01318 cout << "**** Run number is unchanged scan number not reset!!!\n";
01319 } else {
01320 if(mrs) {
01321 *mrs << "SCTAPI_RUNNUMBER" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
01322 << MRS_TEXT("SCTAPI runnumber changed")
01323 << MRS_PARAM<int>("oldRunNumber", runNumber)
01324 << MRS_PARAM<int>("newRunNumber", newRun)
01325 << MRS_PARAM<int>("newScanNumber", 0)
01326 << ENDM;
01327 }
01328 runNumber = newRun;
01329 needsUpdate = true;
01330 scanNumber = 0;
01331 }
01332
01333 if(needsUpdate) {
01334 shared_ptr<PrimListWrapper> runNumberList(new PrimListWrapper(1));
01335
01336 PrimBuilder &builder = PrimBuilder::instance();
01337 int regId = 0x1a2;
01338 #ifdef RUN_NUMBER
01339 regId = RUN_NUMBER;
01340 #endif
01341 builder.writeRegister(runNumberList, regId, 0, 32, runNumber);
01342
01343 if(synchSendPrimListAll(runNumberList) != 0) {
01344 cout << "Update of run number on RODs failed!\n";
01345 }
01346 }
01347 }
01348
01349 void SctApi::setScanNumber(UINT32 newScan) {
01350 if(mrs) {
01351 *mrs << "SCTAPI_SCANNUMBER" << MRS_INFORMATION << MRS_QUALIF("SCTAPI");
01352 }
01353
01354 if(newScan < scanNumber) {
01355 cout << "**** Scan number has been decreased!!\n";
01356 if(mrs) {
01357 *mrs << MRS_TEXT("SCTAPI scannumber decreased");
01358 }
01359 } else {
01360 if(mrs) {
01361 *mrs << MRS_TEXT("SCTAPI scannumber changed");
01362 }
01363 }
01364
01365 if(mrs) {
01366 *mrs << MRS_PARAM<int>("oldScanNumber", scanNumber)
01367 << MRS_PARAM<int>("newScanNumber", newScan)
01368 << ENDM;
01369 }
01370
01371 scanNumber = newScan;
01372 }
01373
01374 UINT32 SctApi::getRunNumber() {
01375 return runNumber;
01376 }
01377
01378 UINT32 SctApi::getScanNumber() {
01379 return scanNumber;
01380 }
01381
01382 ModuleList SctApi::getModuleList()
01383 {
01384 ModuleList result;
01385
01386
01387 for(map<UINT32, ABCDModule>::const_iterator mi = moduleMap.begin();
01388 mi!=moduleMap.end();
01389 mi ++) {
01390
01391 UINT32 currMid = mi->first;
01392 result.push_back(convertToString(currMid));
01393 }
01394
01395 return result;
01396 }
01397
01398 bool SctApi::isRODPresent(unsigned int rod) {
01399 bool result = false;
01400 if(getCrate()) {
01401 if(getCrate()->RODPresent(rod)) {
01402 result = true;
01403 }
01404 }
01405
01406 return result;
01407 }
01408
01409 void SctApi::startupModules() {
01410
01411 m_dcsAccess->toStandby1();
01412
01413
01414 checkAllModulesProbe("2E");
01415
01416
01417 sendAllABCDModules(SCTAPI_BANK_PHYSICS);
01418
01419
01420 checkAllModulesProbe("E");
01421
01422
01423 m_dcsAccess->toStandby2();
01424 }
01425
01426 void SctApi::autoConfigure() {
01427 ::SctApi::AutoConf::AutoConfigurer configurer(*this);
01428 configurer.run();
01429 }
01430
01431
01432
01433
01434
01435
01436
01437 void SctApi::sendPrimList(unsigned int rod,
01438 shared_ptr<PrimListWrapper> prim) {
01439 {
01440 boost::mutex::scoped_lock lock(log().mutex());
01441 log() << "SendPrimList (" << m_id->ucid() << " " << rod << ")\n" << flush;
01442 }
01443
01444 dumpPrimList(prim);
01445
01446 if(getCrate()) {
01447 getCrate()->sendPrimList(rod, prim);
01448 } else {
01449 cout << "Request for non-existent crate " << m_id->ucid() << endl;
01450 }
01451 }
01452
01453 int SctApi::synchSendPrimList(unsigned int rod, shared_ptr<PrimListWrapper> primList, int timeout) {
01454
01455 sendPrimList(rod, primList);
01456
01457 {
01458 boost::mutex::scoped_lock lock(log().mutex());
01459 log() << "synchSendPrimList sent" << endl;
01460 }
01461 int result = 0;
01462
01463
01464 int responseCode = awaitResponse(rod, timeout);
01465
01466 if(responseCode != 0) {
01467 cout << "Synchronous primitive list failed on crate "<< ucid()<<"\n";
01468 cout << " code = " << responseCode << endl;
01469
01470 result = 1;
01471 }
01472 {
01473 boost::mutex::scoped_lock lock(log().mutex());
01474 log() << "synchSendPrimList returned " << result << endl;
01475 }
01476
01477 return result;
01478 }
01479
01480
01481
01482
01483
01484
01485
01486 void SctApi::sendPrimListAll(shared_ptr<PrimListWrapper> prim) {
01487 if(checkDebugOption(DEBUG_DIAG)){
01488 boost::mutex::scoped_lock lock(log().mutex());
01489 log() << "SendPrimListAll (" << m_id->ucid() << ")\n" << flush;
01490 }
01491
01492 dumpPrimList(prim);
01493
01494 if(getCrate()) {
01495 getCrate()->sendPrimListAll(prim);
01496 } else {
01497 cout << "Request for non-existent crate " << m_id->ucid() << endl;
01498 }
01499 }
01500
01501 int SctApi::synchSendPrimListAll(shared_ptr<PrimListWrapper> primList, int timeout) {
01502
01503 sendPrimListAll(primList);
01504
01505 {
01506 boost::mutex::scoped_lock lock(log().mutex());
01507 log() << "synchSendPrimList sent" << endl;
01508 }
01509 int result = 0;
01510
01511
01512 int responseCode = awaitResponseAll(timeout);
01513
01514 if(responseCode != 0) {
01515 cout << "Synchronous primitive list failed on crate "<< ucid()<<"\n";
01516 cout << " code = " << responseCode << endl;
01517
01518 result = 1;
01519 }
01520 {
01521 boost::mutex::scoped_lock lock(log().mutex());
01522 log() << "synchSendPrimList returned " << result << endl;
01523 }
01524
01525 return result;
01526 }
01527
01528 void SctApi::dumpPrimList(shared_ptr<PrimListWrapper> prim) {
01529 prim->list->bufferBuild();
01530
01531 long buffLength = prim->list->getBufferLength();
01532 unsigned long* bufferStart = prim->list->getBuffer();
01533
01534 if(checkDebugOption(DEBUG_DUMP_PRIM_BINARY))
01535 printMemoryBlock(log(), bufferStart, buffLength, 8);
01536
01537 if(checkDebugOption(DEBUG_SAVE_PRIM)) {
01538 static int primCount = 0;
01539
01540 string dirName = Sct::SctNames::getTempDir() + "/PrimLists";
01541
01542
01543 int mkRet = mkdir(dirName.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
01544 if(mkRet != 0) {
01545
01546 if(errno != EEXIST) {
01547 perror(("Failed to create PrimLists directory in " + Sct::SctNames::getTempDir()).c_str());
01548 }
01549 }
01550
01551 char *saveDir = getcwd(NULL, 0);
01552
01553 int chRet = chdir(dirName.c_str());
01554 if(chRet != 0) {
01555 perror("Failed to change to PrimLists directory");
01556 }
01557
01558 char fileName[100];
01559 sprintf(fileName, "PrimLists_%05d.bin", primCount++);
01560 ofstream fout(fileName, ios::binary | ios::trunc);
01561 fout.write((char*)&bufferStart[0], buffLength*4);
01562
01563 int chRet2 = chdir(saveDir);
01564 if(chRet2 != 0) {
01565 perror("Failed to return to saved directory");
01566 }
01567
01568 free(saveDir);
01569 }
01570
01571 if(checkDebugOption(DEBUG_PRINT_IN_PRIM)) {
01572
01573 if(checkDebugOption(DEBUG_LOG_PRINT_PRIM)) {
01574 ::SctApi::printOutList(bufferStart, buffLength, true, 0, log(),
01575 checkDebugOption(DEBUG_PRINT_UNKNOWN), checkDebugOption(DEBUG_PRINT_RAW));
01576 } else {
01577 ::SctApi::printOutList(bufferStart, buffLength, true, 0, cout,
01578 checkDebugOption(DEBUG_PRINT_UNKNOWN), checkDebugOption(DEBUG_PRINT_RAW));
01579 }
01580 }
01581 }
01582
01583
01584
01585
01586
01587 void SctApi::shutdownAll() {
01588 {
01589 boost::mutex::scoped_lock lock(log().mutex());
01590 log() << "SctApi told to shutdown\n";
01591 log() << "\t TIME " << second_clock::universal_time() << endl;
01592 }
01593
01594 lasersOff();
01595
01596 if(checkDebugOption(DEBUG_EXTRA_DUMPS)) {
01597 standardRegisterDumpAll();
01598 }
01599
01600 if(mrs) {
01601 *mrs << "SCTAPI_SHUTDOWN" << MRS_INFORMATION << MRS_QUALIF("SCTAPI") << MRS_TEXT("First ROD shut down") << ENDM;
01602 }
01603
01604 {
01605 boost::mutex::scoped_lock lock(log().mutex());
01606 log() << "Shutdown sequence complete\n";
01607 }
01608 }
01609
01610
01611
01612
01613 void SctApi::sendSlavePrimList(unsigned int rod,
01614 shared_ptr<PrimListWrapper> prim, unsigned int slaveNumber, bool await, bool response) {
01615 {
01616 boost::mutex::scoped_lock lock(log().mutex());
01617 log() << "SendSlavePrimlist (" << m_id->ucid() << " " << rod << ")\n" << flush;
01618 }
01619
01620 if((!getCrate())
01621 || (!getCrate()->slavePresent(rod, slaveNumber))) {
01622 cout << "***** Slave DSP (" << slaveNumber << ") was not initialised, please check the configuration and the Slave Image files\n";
01623 return;
01624 }
01625
01626 shared_ptr<PrimListWrapper> container(new PrimListWrapper(1));
01627
01628 PrimBuilder::instance().slavePrimList(container, prim, slaveNumber, await, response);
01629
01630 try {
01631 container->list->bufferBuild();
01632 }
01633 catch (PrimListException &p) {
01634 cout << p.getDescriptor() << " ";
01635 cout << p.getData1() << ", " << p.getData2() << "\n";
01636 }
01637
01638 sendPrimList(rod, container);
01639 }
01640
01641
01642
01643
01644
01645 Crate *SctApi::getCrate() const {
01646 return crateObject.get();
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657 }
01658
01659 int SctApi::awaitResponse(unsigned int rod, int timeout) {
01660 int retVal = 0;
01661 {
01662 boost::mutex::scoped_lock lock(log().mutex());
01663 log() << "AwaitResponse\n";
01664 }
01665
01666 if(getCrate()) {
01667 try {
01668 retVal = getCrate()->awaitResponse(rod, timeout);
01669 } catch(CrateException &c) {
01670 cout << "Crate exception in await response\n" << c.what() << endl;
01671 retVal = -1;
01672 } catch(BaseException &b) {
01673 cout << "Base exception in await response\n" << b << endl;
01674 retVal = -1;
01675 } catch(...) {
01676 cout << "Exception in await response\n";
01677 retVal = -1;
01678 }
01679
01680 if(retVal != 0) {
01681 if(config->isDummyCrate(prt(), crt())) {
01682
01683
01684 retVal = 0;
01685 } else {
01686 cout << "Problem during await response\n";
01687 cout << "Crate status " << ucid() << endl;
01688 try {
01689 cout << getCrate()->status();
01690 } catch(VmeException &v) {
01691 cout << "Exception getting crate status\n";
01692 ::SctApi::Utility::decodeVme(v);
01693 }
01694 }
01695 }
01696 } else {
01697 cout << "Request for non-existent crate " << m_id->ucid() << endl;
01698 }
01699
01700 if(checkDebugOption(DEBUG_DIAG)){
01701 boost::mutex::scoped_lock lock(log().mutex());
01702 log() << "\tAwaitResponse: " << retVal << endl;
01703 }
01704
01705 return retVal;
01706 }
01707
01708 int SctApi::awaitResponseAll(int timeout) {
01709 int retVal = 0;
01710
01711 if(checkDebugOption(DEBUG_DIAG)){
01712 boost::mutex::scoped_lock lock(log().mutex());
01713 log() << "AwaitResponse\n";
01714 }
01715
01716 if(getCrate()) {
01717 try {
01718 retVal = getCrate()->awaitResponseAll(timeout);
01719 } catch(CrateException &c) {
01720 cout << "Crate exception in await response all\n" << c.what() << endl;
01721 retVal = -1;
01722 } catch(BaseException &b) {
01723 cout << "Base exception in await response all\n" << b << endl;
01724 retVal = -1;
01725 } catch(...) {
01726 cout << "Exception in await response all\n";
01727 retVal = -1;
01728 }
01729
01730 if(retVal != 0) {
01731 cout << "Problem during await response all\n";
01732 }
01733 } else {
01734 cout << "Request for non-existent crate " << m_id->ucid() << endl;
01735 }
01736
01737 return retVal;
01738 }
01739
01740 unsigned long *SctApi::getResponse(unsigned int rod,
01741 unsigned long &length) {
01742 unsigned long *result;
01743
01744 if(checkDebugOption(DEBUG_DIAG_RESPONSE)){
01745 boost::mutex::scoped_lock lock(log().mutex());
01746 log() << "GetResponse\n";
01747 }
01748 if(getCrate()) {
01749 boost::shared_ptr<RodOutList> output = getCrate()->getResponse(rod);
01750
01751 if(!output) {
01752 cout << "No response from crate\n";
01753 return NULL;
01754 }
01755
01756 length = (unsigned long) output->getLength();
01757
01758 if(checkDebugOption(DEBUG_DIAG_RESPONSE))
01759 cout << "Got response from crate length = " << length << endl;
01760
01761 unsigned long *body = output->getBody();
01762
01763 result = new unsigned long[length];
01764
01765 for(unsigned int i=0; i<length; i++) {
01766 result[i] = body[i];
01767 }
01768
01769 if(body[0] != length) {
01770 cout << "Bad outlist/outlength mismatch in returned outlist (" << m_id->ucid() << " " << rod << "): " << body[0] << " != " << length << endl;
01771 return NULL;
01772 }
01773
01774 if(checkDebugOption(DEBUG_SAVE_PRIM)) {
01775 static int primCount = 0;
01776
01777 string dirName = Sct::SctNames::getTempDir() + "/PrimLists";
01778
01779
01780 int mkRet = mkdir(dirName.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
01781 if(mkRet != 0) {
01782
01783 if(errno != EEXIST) {
01784 perror(("Failed to create PrimLists directory for OutList: " + dirName).c_str());
01785 }
01786 }
01787
01788 char *saveDir = getcwd(NULL, 0);
01789
01790 int chRet = chdir(dirName.c_str());
01791 if(chRet != 0) {
01792 perror("Failed to create PrimLists directory for OutList");
01793 }
01794
01795 char fileName[100];
01796 sprintf(fileName, "OutLists_%05d.bin", primCount++);
01797 ofstream fout(fileName, ios::binary | ios::trunc);
01798 fout.write((char*)result, length*4);
01799
01800 int chRet2 = chdir(saveDir);
01801 if(chRet2 != 0) {
01802 perror("Failed to change back to saved directory");
01803 }
01804
01805 free(saveDir);
01806 }
01807
01808 if(checkDebugOption(DEBUG_PRINT_OUT_PRIM)) {
01809
01810 if(checkDebugOption(DEBUG_LOG_PRINT_PRIM)) {
01811 ::SctApi::printOutList(result, length, false, 0, log(),
01812 checkDebugOption(DEBUG_PRINT_UNKNOWN), checkDebugOption(DEBUG_PRINT_RAW));
01813 } else {
01814 ::SctApi::printOutList(result, length, false, 0, cout,
01815 checkDebugOption(DEBUG_PRINT_UNKNOWN), checkDebugOption(DEBUG_PRINT_RAW));
01816 }
01817 }
01818 } else {
01819 cout << "Request for non-existent crate " << m_id->ucid() << endl;
01820 return NULL;
01821 }
01822
01823 return result;
01824 }
01825
01826
01827
01828
01829 bool SctApi::getRodMessage(unsigned int rod,
01830 char *buffer, unsigned long &length) {
01831 {
01832 boost::mutex::scoped_lock lock(log().mutex());
01833 log() << "Get message\n";
01834 }
01835 if(getCrate()) {
01836 return getCrate()->getRodMessage(rod, buffer, length);
01837 } else {
01838 buffer[0] = 0;
01839 length = 0;
01840 return false;
01841 }
01842 }
01843
01844
01845 UINT32 SctApi::findModule(string sn) {
01846 {
01847 boost::mutex::scoped_lock lock(log().mutex());
01848 log() << "findModule " << sn << endl;
01849 }
01850
01851 unsigned int partition, crate, rod, channel;
01852
01853 try {
01854 unsigned int mur, module;
01855 config->translateFromSN(sn, mur, module);
01856 config->translateToROD(mur, module, partition, crate, rod, channel);
01857 } catch(ConfigurationException &c) {
01858 cout << "Module not found\n";
01859 return BAD_MODULE;
01860 }
01861
01862 return packpcrc(partition, crate, rod, channel);
01863 }
01864
01865 string SctApi::convertToString(UINT32 mid) {
01866 {
01867 boost::mutex::scoped_lock lock(log().mutex());
01868 log() << "convertToString " << mid << endl;
01869 }
01870
01871 unsigned int partition, crate, rod, channel;
01872 getpcrc(mid, partition, crate, rod, channel);
01873
01874 if(channel >= 48) {
01875 return "Off-ROD ";
01876 }
01877
01878 string sn;
01879
01880 try {
01881 unsigned int mur, module;
01882 config->translateFromROD(partition, crate, rod, channel, mur, module);
01883 config->translateToSN(mur, module, sn);
01884 } catch(ConfigurationException &c) {
01885 cout << "Module not found\n";
01886 return "BAD_MODULE ";
01887 }
01888
01889 return sn;
01890 }
01891
01892 UINT32 SctApi::findModule(INT32 mur, INT32 module) {
01893 {
01894 boost::mutex::scoped_lock lock(log().mutex());
01895 log() << "findModule " << mur << " " << module << endl;
01896 }
01897
01898 unsigned int partition, crate, rod, channel;
01899
01900 try {
01901 config->translateToROD(mur, module,
01902 partition, crate, rod, channel);
01903 } catch(ConfigurationException &c) {
01904 cout << "Module not found\n";
01905 return BAD_MODULE;
01906 }
01907
01908 return packpcrc(partition, crate, rod, channel);
01909 }
01910
01911 pair<INT32, INT32> SctApi::convertToMUR(UINT32 mid) {
01912 {
01913 boost::mutex::scoped_lock lock(log().mutex());
01914 log() << "convertToMUR " << mid << endl;
01915 }
01916
01917 unsigned int partition, crate, rod, channel;
01918 getpcrc(mid, partition, crate, rod, channel);
01919
01920 UINT32 mur;
01921 UINT32 module;
01922
01923 try {
01924 config->translateFromROD(partition, crate, rod, channel, mur, module);
01925 } catch(ConfigurationException &c) {
01926 cout << "Module not found\n";
01927 return make_pair(BAD_MODULE, 0);
01928 }
01929
01930 return make_pair(mur, module);
01931 }
01932
01933 UINT32 SctApi::findBarrelModule(INT32 barrel, INT32 row, INT32 number) {
01934 {
01935 boost::mutex::scoped_lock lock(log().mutex());
01936 log() << "findBarrelModule " << barrel << " " << row << " " << number << endl;
01937 }
01938
01939 unsigned int partition, crate, rod, channel;
01940
01941 try {
01942 unsigned int mur, module;
01943 config->translateFromBarrel(barrel, row, number, mur, module);
01944 config->translateToROD(mur, module,
01945 partition, crate, rod, channel);
01946 } catch(ConfigurationException &c) {
01947 cout << "Module not found\n";
01948 return BAD_MODULE;
01949 }
01950
01951 return packpcrc(partition, crate, rod, channel);
01952 }
01953
01954 void SctApi::convertToBarrelModule(UINT32 mid, UINT32 &barrel, UINT32 &row, int &number) {
01955 {
01956 boost::mutex::scoped_lock lock(log().mutex());
01957 log() << "convertToBarrelModule " << mid << endl;
01958 }
01959
01960 unsigned int partition, crate, rod, channel;
01961 getpcrc(mid, partition, crate, rod, channel);
01962
01963 try {
01964 unsigned int mur, module;
01965 config->translateFromROD(partition, crate, rod, channel, mur, module);
01966 config->translateToBarrel(mur, module, barrel, row, number);
01967 } catch(ConfigurationException &c) {
01968 cout << "Module not found\n";
01969
01970 barrel = BAD_MODULE;
01971 return;
01972 }
01973 }
01974
01975 UINT32 SctApi::findEndcapModule(INT32 disk, INT32 ring, INT32 number) {
01976 {
01977 boost::mutex::scoped_lock lock(log().mutex());
01978 log() << "findEndcapModule " << disk << " " << ring << " " << number << endl;
01979 }
01980 unsigned int partition, crate, rod, channel;
01981
01982 try {
01983 unsigned int mur, module;
01984 config->translateFromEndcap(disk, ring, number, mur, module);
01985 config->translateToROD(mur, module,
01986 partition, crate, rod, channel);
01987 } catch(ConfigurationException &c) {
01988 cout << "Module not found\n";
01989 return BAD_MODULE;
01990 }
01991
01992 return packpcrc(partition, crate, rod, channel);
01993 }
01994
01995 void SctApi::convertToEndcapModule(UINT32 mid, INT32 &disk, UINT32 &ring, UINT32 &number) {
01996 {
01997 boost::mutex::scoped_lock lock(log().mutex());
01998 log() << "convertToEndcapModule " << mid << endl;
01999 }
02000
02001 unsigned int partition, crate, rod, channel;
02002 getpcrc(mid, partition, crate, rod, channel);
02003
02004 try {
02005 unsigned int mur, module;
02006 config->translateFromROD(partition, crate, rod, channel, mur, module);
02007 config->translateToEndcap(mur, module, disk, ring, number);
02008 } catch(ConfigurationException &c) {
02009 cout << "Module not found\n";
02010 disk = BAD_MODULE;
02011 return;
02012 }
02013 }
02014
02015 #warning "These should be due to notifications from the configuration???"
02016
02017 void SctApi::loadConfiguration() {
02018 {
02019 boost::mutex::scoped_lock lock(log().mutex());
02020 log() << "loadConfiguration (default)\n";
02021 }
02022
02023 cout << "Load configuration\n";
02024 #warning "Using feature of ConfigurationXmlImpl"
02025 loadConfiguration("");
02026 }
02027
02028 void SctApi::loadConfiguration(string filename) {
02029 {
02030 boost::mutex::scoped_lock lock(log().mutex());
02031 log() << "loadConfiguration (" << filename << ")\n";
02032 }
02033
02034 try {
02035 cout << "Load configuration\n";
02036 config->loadConfiguration(filename);
02037 } catch(ConfigurationException &c) {
02038 cout << "Problem loading new configuration, check configuration service\n";
02039 }
02040
02041 cout << "Remove module configuration cache\n";
02042
02043 {
02044 boost::mutex::scoped_lock lock(moduleMapAccess);
02045 moduleMap.clear();
02046 }
02047
02048 loadModuleConfigurations();
02049 }
02050
02051 unsigned SctApi::preloadModuleConfigurations(){
02052 unsigned modulecount=0;
02053 unsigned partition = ucid().partition();
02054 unsigned crate = ucid().crate();
02055 list<unsigned int> rods;
02056 try {
02057 rods = config->listRodsInCrate(partition, crate);
02058 } catch(ConfigurationException &c) {
02059 cout << "No RODs in this crate\n";
02060 cout << c.what() << endl;
02061 return 0;
02062 }
02063
02064 for(list<unsigned int>::const_iterator r=rods.begin();
02065 r!=rods.end();
02066 r++) {
02067 RodLabel rl(partition, crate, *r);
02068 {
02069 boost::recursive_mutex::scoped_lock lock(rodInfoListAccess);
02070 if (rodInfoList.find(rl)==rodInfoList.end()){
02071 RodInfo newInfo;
02072 rodInfoList.insert(make_pair(rl, newInfo));
02073 }
02074 }
02075
02076 list<unsigned int> MURs;
02077 try {
02078 MURs = config->listMURSInRod(partition, crate, *r);
02079 } catch(ConfigurationException &c) {
02080 cout << "No MURs for this ROD\n";
02081 cout << c.what() << endl;
02082 continue;
02083 }
02084
02085 for(list<unsigned int>::const_iterator mur=MURs.begin();
02086 mur!=MURs.end();
02087 mur++) {
02088
02089 list<string> modules;
02090 try {
02091 modules = config->listModulesInMUR(partition, *mur);
02092 } catch(ConfigurationException &c) {
02093 cout << "No modules for this MUR\n";
02094 cout << c.what() << endl;
02095 continue;
02096 }
02097
02098 for(list<string>::const_iterator m=modules.begin();
02099 m!=modules.end();
02100 m++) {
02101 if (m_preloadModuleConfigurationsStop) return modulecount;
02102 if (!initialiseModule(*m, false))++modulecount;
02103 }
02104 }
02105 }
02106 return modulecount;
02107 }
02108
02109 int SctApi::loadModuleConfigurations() {
02110 int moduleConfigurations = 0;
02111
02112
02113 for(list<RodLabel>::const_iterator rl = rodList.begin();
02114 rl!=rodList.end();
02115 rl++){
02116 list<unsigned int> MURs;
02117 try {
02118 MURs = config->listMURSInRod(rl->partition, rl->crate, rl->rod);
02119 } catch(ConfigurationException &c) {
02120 cout << "No MURs for this ROD\n";
02121 cout << c.what() << endl;
02122 continue;
02123 }
02124
02125 for(list<unsigned int>::const_iterator mur=MURs.begin();
02126 mur!=MURs.end();
02127 mur++) {
02128
02129 list<string> modules;
02130 try {
02131 modules = config->listModulesInMUR(rl->partition, *mur);
02132 } catch(ConfigurationException &c) {
02133 cout << "No modules for this MUR\n";
02134 cout << c.what() << endl;
02135 continue;
02136 }
02137
02138 for(list<string>::const_iterator m=modules.begin();
02139 m!=modules.end();
02140 m++) {
02141 if(!initialiseModule(*m)) {
02142 moduleConfigurations ++;
02143 }
02144 }
02145 }
02146 }
02147
02148 cout << "Setup for calibration...\n";
02149 calib_init();
02150
02151 return moduleConfigurations;
02152 }
02153
02154 void SctApi::storeModuleConfigurations(BankType bank) {
02155 for(std::map<UINT32, ABCDModule>::const_iterator i = moduleMap.begin();
02156 i != moduleMap.end();
02157 i++) {
02158 UINT32 mid=i->first;
02159 std::string sn = "unknown";
02160 try{
02161 sn = convertToString(mid);
02162 boost::shared_ptr<const SctApiConfigCache::ModuleBanks> banks = module_cache.getFromMid(mid);
02163 if (!banks.get()) throw SctApiException("Cant save - no banks for this module");
02164 boost::shared_ptr<const ABCDModule> module = banks->get(bank);
02165 if (!module.get()) throw SctApiException("Cant save - this bank dosent exist for this module");
02166 config->configureModuleFromStructure(sn, *module);
02167 }catch(std::exception& e){
02168 if (mrs){
02169 *mrs << "CONFIG_SAVE_ERROR" << MRS_TEXT(e.what()) << MRS_QUALIF("SCTAPI")
02170 << MRS_PARAM<int>("mid", mid) << MRS_PARAM<int>("bank", bank)
02171 << MRS_PARAM<const char*>("sn",sn.c_str()) << ENDM;
02172 }
02173 }
02174 }
02175 }
02176
02177 void SctApi::storeBOCConfigurations()
02178 {
02179 log() << "Storing BOC configurations" << endl;
02180 try{
02181
02182 Crate* the_crate = getCrate();
02183 const list<unsigned> rods = the_crate->getListOfRods();
02184
02185 for (list<unsigned>::const_iterator ri=rods.begin(); ri!=rods.end(); ++ri){
02186 const unsigned rod=*ri;
02187 BOCGlobalConfig global = the_crate->currentBOCRegisters(rod);
02188 config->configureBOC(prt(), crt(), rod, global);
02189
02190 vector<BOCChannelConfig> channels = currentBOCSetup(rod);
02191 for(int ich=0; ich<48; ich++){
02192 try {
02193 unsigned MUR=0, position=0;
02194 config->translateFromROD(prt(), crt(), rod, ich, MUR, position);
02195 config->configureBOCChannel(MUR, position, channels[ich]);
02196 } catch(ConfigurationException &c) {
02197
02198 }
02199 }
02200 }
02201 }catch(std::exception& e){
02202 log() << e.what() << endl;
02203 if(mrs) {
02204 *mrs << "STORE_BOC_ERROR" << MRS_WARNING << MRS_QUALIF("SCTAPI")
02205 << MRS_TEXT(e.what()) << ENDM;
02206 }
02207 }
02208 }
02209
02210 void SctApi::configureBOC(unsigned int rod) {
02211 {
02212 boost::mutex::scoped_lock lock(log().mutex());
02213 log() << "ConfigureBOC called\n";
02214 log() << "\t TIME " << second_clock::universal_time() << endl;
02215 }
02216
02217 try {
02218 if(getCrate())
02219 getCrate()->configureBOC(rod);
02220 } catch(CrateException &c) {
02221 throw SctApiException(c);
02222 }
02223 }
02224
02225 std::vector<double> SctApi::getBOCMonitorArray(unsigned int rod) {
02226 {
02227 boost::mutex::scoped_lock lock(log().mutex());
02228 log() << "getBOCMonitorArray called\n";
02229 }
02230
02231 if(getCrate())
02232 return getCrate()->getBOCMonitorArray(rod);
02233 else
02234 throw SctApiException("Failed to getBOCMonitorArray");
02235 }
02236
02237 std::string SctApi::status() {
02238 std::ostringstream oss;
02239 {
02240 boost::mutex::scoped_lock lock(log().mutex());
02241 log() << "print all status\n";
02242 }
02243
02244 oss << "SCTAPI status:\n";
02245 oss << "Run " << runNumber << " Scan " << scanNumber << endl;
02246
02247 #if USE_THREADS
02248 oss << "Primitive thread engine enabled\n";
02249 #else
02250 oss << "Primitive thread engine disabed (dangerous in IPC)\n";
02251 #endif
02252 #if USE_SCAN_THREAD
02253 oss << "Scan polling thread enabled\n";
02254 #else
02255 oss << "Scan polling thread disabled (doScan can timeout with IPC)\n";
02256 #endif
02257 if(mrs) {
02258 *mrs << "SCTAPI_STATUS" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
02259 << MRS_PARAM<int>("run", runNumber) << MRS_PARAM<int>("scan", scanNumber)
02260 << MRS_TEXT("Run numbers") << ENDM;
02261 }
02262
02263 if(!getCrate()) {
02264 if(mrs) {
02265 *mrs << "SCTAPI_STATUS" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
02266 << MRS_TEXT("No crates loaded") << ENDM;
02267 }
02268 }
02269
02270
02271
02272
02273 {
02274 oss << "Crate: " << ucid() << " to std::out...\n";
02275 oss << getCrate()->status();
02276 }
02277
02278 oss << "Module configuration for " << moduleMap.size() << " modules:\n";
02279 for(map<UINT32, ABCDModule>::const_iterator mi = moduleMap.begin();
02280 mi!=moduleMap.end();
02281 mi ++) {
02282 UINT32 mid = mi->first;
02283
02284 string sn = convertToString(mid);
02285 ABCDModule *moduleConf = lookupConfig(mid);
02286 int group = moduleConf->groupId;
02287 int select = moduleConf->select;
02288 int prim = moduleConf->pTTC;
02289 int redun = moduleConf->rTTC;
02290 int link0 = moduleConf->rx[0];
02291 int link1 = moduleConf->rx[1];
02292
02293
02294 if(link0 != DATA_LINK_OFF)
02295 link0 = (link0/16) * 12 + link0%16;
02296 if(link1 != DATA_LINK_OFF)
02297 link1 = (link1/16) * 12 + link1%16;
02298
02299 oss.width(8);
02300 oss << mid << " " << sn << " Group: " << group << " Select: " << select;
02301 oss << "\t Pr: ";
02302 oss.width(2);
02303 oss << prim << " Red: ";
02304 oss.width(3);
02305 oss << redun << " Link 0/1: ";
02306 oss.width(3);
02307 oss << link0 << " ";
02308 oss.width(3);
02309 oss << link1 << endl;
02310
02311 if(mrs) {
02312 *mrs << "MODULE_INFO" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
02313 << MRS_PARAM<const char *>("sn",sn.c_str()) << MRS_PARAM<int>("internalId",mid)
02314 << MRS_PARAM<int>("group",group) << MRS_PARAM<int>("select",select)
02315 << MRS_PARAM<int>("primary",prim) << MRS_PARAM<int>("redundancy",redun)
02316 << MRS_PARAM<int>("link0rx",link0) << MRS_PARAM<int>("link1rx",link1)
02317 << MRS_TEXT("Module status ")
02318 << ENDM;
02319 }
02320 }
02321
02322 if(mrs) {
02323 *mrs << "SCTAPI_STATUS" << MRS_INFORMATION << MRS_QUALIF("SCTAPI")
02324 << MRS_PARAM<int>("run", runNumber) << MRS_PARAM<int>("scan", scanNumber)
02325 << MRS_TEXT("Run numbers") << ENDM;
02326 }
02327
02328 std::list<std::string> enabledDebug = listEnabledDebugOptions();
02329 if (enabledDebug.empty()){
02330 oss << "No debug options currently enabled\n";
02331 }else{
02332 oss << "Debug options currently enabled:" << endl;
02333 for (std::list<std::string>::const_iterator i=enabledDebug.begin(); i!=enabledDebug.end(); ++i){
02334 oss << "\t"<< *i << "\n";
02335 }
02336 }
02337 return oss.str();
02338 }
02339
02340
02341 void SctApi::defaultScan(int type) {
02342 {
02343 boost::mutex::scoped_lock lock(log().mutex());
02344 log() << "Send default scan number " << type << endl;
02345 }
02346 ScanDefImpl scan;
02347
02348 long *evSetup;
02349 long *histSetup;
02350 long *histStart;
02351
02352 shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
02353
02354 int histStartLength;
02355
02356 switch(type) {
02357 default:
02358 case 0:
02359 {
02360
02361 long setup[24] = {0x1, 0, 0x2000, 0,
02362 0x3, 0x1, 0, 0,
02363 0, 0, 0, 0,
02364 0x3, 0, 0, 1,
02365 0x1, 0, 0, 1,
02366 1, 0, 0, 0};
02367
02368 evSetup = new long[24];
02369 for(int i=0; i<24; i++) evSetup[i] = setup[i];
02370
02371
02372 long setupH[] = {
02373 0x20d2000, 0, 0x60, 0x01010000, 0x20200101, 1, 0, 1,
02374 0, 0, 0, 0x03f00000, 0x30f01000};
02375
02376 histSetup = new long[13];
02377 for(int i=0; i<13; i++) histSetup[i] = setupH[i];
02378
02379
02380 long startHist[4 + 63] = {
02381 16, 107, 1, 1,
02382
02383
02384
02385 0x01010001, 0x000f0001, 0x08040201, 0xf, 0x020d2000, 0x00200101, 0x0100000f, 1000,
02386 50, 0x0, 0x40a00000, 0x40a00000, 0x41200000, 0x40a00000, 0x42c80000, 0x40200000,
02387 0x43160000, 0x40a00000, 0x43480000, 0x40a00000, 0x40a00000, 0x40a00000, 0x41200000, 0x40a00000,
02388
02389 0x42c80000, 0x40200000, 0x43160000, 0x40a00000, 0x43480000, 0x40a00000, 0x0, 0x0,
02390 0x0070006a, 0x00640065, 0x00640064, 0x00000000, 0x81, 0x0, 0x0, 0x0,
02391 0x0,
02392 0x00640064, 0x00640064, 0x00640064, 0, 0, 0, 0,
02393 0, 0,
02394 0,
02395 0, 0,
02396 0, 0, 0,
02397 0, 0, 0, 0, 0,
02398 };
02399
02400 histStart = new long[4+63];
02401 for(int i=0; i<4+63; i++) histStart[i] = startHist[i];
02402
02403 histStartLength = 67;
02404 }
02405 break;
02406 case 1:
02407
02408 {
02409
02410 long setup[24] = {
02411 0x00000001, 0x00000000, 0x00002000, 0x00000000, 0x00000003, 0x00000000, 0x00000001, 0x00000000,
02412 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000000, 0x00000000, 0x00000001,
02413 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000};
02414
02415 evSetup = new long[24];
02416 for(int i=0; i<24; i++) evSetup[i] = setup[i];
02417
02418
02419 long setupH[] = {
02420 0x020d2000, 0x00000000, 0x00000008, 0x18090000, 0x00200101, 0x00000001, 0x00000000, 0x00000001,
02421 0x00000000, 0x00000000, 0x00000000, 0x03f00000, 0x03f01000};
02422
02423 histSetup = new long[13];
02424 for(int i=0; i<13; i++) histSetup[i] = setupH[i];
02425
02426
02427 long startHist[79] = {
02428 0x18090001, 0x000f0001,
02429 0x000000ff, 0x0000f00f, 0x020d2000, 0x00200101, 0x0000000f, 0x0000040a, 0x00000008, 0x00000000,
02430 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
02431 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
02432 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x0070006a, 0x00640065,
02433 0x00640064, 0x00000000, 0x00000082, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00640064,
02434 0x00640064, 0x00640064, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
02435 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
02436 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x41800000, 0x42000000,
02437 0x42400000, 0x42800000, 0x42a00000, 0x42c00000, 0x42e00000, 0x00000000, 0x41800000, 0x42000000,
02438 0x42400000, 0x42800000, 0x42a00000, 0x42c00000, 0x42e00000
02439 };
02440
02441 histStart = new long[79];
02442 for(int i=0; i<79; i++) histStart[i] = startHist[i];
02443
02444 histStartLength = 79;
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484 break;
02485 }
02486 }
02487
02488 if(!getCrate() || !getCrate()->RODPresent(0)) {
02489 cout << "No configured ROD ! Aborting default scan\n";
02490 if(mrs) {
02491 *mrs << "ROD_NONEXIST" << MRS_ERROR << MRS_QUALIF("SCTAPI")
02492 << MRS_PARAM<int>("crate", 0)
02493 << MRS_PARAM<int>("rod", 0)
02494 << MRS_TEXT("Aborting default scan (ROD not configured)") << ENDM;
02495 }
02496
02497 return;
02498 }
02499
02500 if(!getCrate()->checkBOCLasersOn(0)) {
02501 cout << "Trying to send default scan using BOC that has its lasers cut out (continuing)\n";
02502 if(mrs) {
02503 *mrs << "BOC_INTERLOCKED" << MRS_WARNING << MRS_QUALIF("SCTAPI")
02504 << MRS_PARAM<int>("crate", 0)
02505 << MRS_PARAM<int>("rod", 0)
02506 << MRS_TEXT("Default scan continuing even though BOC interlocked") << ENDM;
02507 }
02508 }
02509
02510 primList->addPrimitive(RodPrimitive(4+24, 1, 3, 103, evSetup),
02511 evSetup);
02512
02513
02514 long trap[0] = {};
02515 shared_ptr<PrimListWrapper> sPrimList(new PrimListWrapper(2));
02516 sPrimList->addPrimitive(RodPrimitive(4, 0, 4096, 101, trap),
02517 trap);
02518
02519 PrimBuilder &builder = PrimBuilder::instance();
02520
02521 builder.slavePrimList(primList, sPrimList, 0, true, true);
02522
02523
02524 sPrimList->clear();
02525 sPrimList->addPrimitive(RodPrimitive(4 + 13 , 3, 4098, 104, histSetup),
02526 histSetup);
02527 builder.slavePrimList(primList, sPrimList, 0, true, true);
02528
02529 long task[] = {32, 100, 1, 1, 0, 0};
02530 sPrimList->clear();
02531 sPrimList->addPrimitive(RodPrimitive(4 + 6, 4, 12, 101, task),
02532 task);
02533 builder.slavePrimList(primList, sPrimList, 0, true, true);
02534
02535 primList->addPrimitive(RodPrimitive(histStartLength + 4, 3, 12, 101, histStart),
02536 histStart);
02537
02538 {
02539 boost::mutex::scoped_lock lock(log().mutex());
02540 log() << "Send default scan list\n";
02541 }
02542 sendPrimList(0, primList);
02543 awaitResponse(0, 2);
02544
02545
02546
02547 unsigned long length;
02548
02549 unsigned long *result = getResponse(0, length);
02550
02551 if(result) {
02552 cout << "Got response from default scan setup\n";
02553
02554 if(checkDebugOption(DEBUG_LOG_PRINT_PRIM)) {
02555 ::SctApi::printOutList(result, length, true, 0, log(),
02556 checkDebugOption(DEBUG_PRINT_UNKNOWN), checkDebugOption(DEBUG_PRINT_RAW));
02557 } else {
02558 ::SctApi::printOutList(result, length, true, 0, cout,
02559 checkDebugOption(DEBUG_PRINT_UNKNOWN), checkDebugOption(DEBUG_PRINT_RAW));
02560 }
02561
02562 delete [] result;
02563 } else {
02564 cout << "No response from default scan setup\n";
02565 }
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575 }
02576
02577 void SctApi::tidyHistogramming() {
02578 {
02579 boost::mutex::scoped_lock lock(log().mutex());
02580 log() << "Brutal histogram stopping\n";
02581 }
02582
02583 shared_ptr<PrimListWrapper> primList(new PrimListWrapper(2));
02584
02585 PrimBuilder &builder = PrimBuilder::instance();
02586
02587 builder.taskOp(primList, HISTOGRAM_CTRL_TASK, TASK_STOP, 0);
02588
02589 for(list<RodLabel>::const_iterator rl = rodList.begin();
02590 rl!=rodList.end();
02591 rl++){
02592
02593 unsigned int rod = rl->rod;
02594
02595 {
02596 boost::mutex::scoped_lock lock(log().mutex());
02597 log() << "Tidy histogram on (" << ucid() << ", " << rod << ")\n";
02598 log() << "Stop HCT\n";
02599 }
02600 sendPrimList(rod, primList);
02601
02602 awaitResponse(rod, 2);
02603 primList->clear();
02604
02605 cout << "Done kill control task\n";
02606
02607 for(int slaveNumber=0; slaveNumber<4; slaveNumber++) {
02608 shared_ptr<PrimListWrapper> slList(new PrimListWrapper(1));
02609
02610
02611
02612 builder.taskOp(slList, HISTOGRAM_TASK, TASK_STOP, 0);
02613
02614 builder.slavePrimList(primList, slList, slaveNumber, true, true);
02615 {
02616 boost::mutex::scoped_lock lock(log().mutex());
02617 log() << "Stop histo task (" << slaveNumber << ")\n";
02618 }
02619 sendPrimList(rod, primList);
02620 awaitResponse(rod, 2);
02621 slList->clear();
02622 primList->clear();
02623
02624 cout << "Done kill histogram task\n";
02625
02626 builder.stopEvTrap(slList);
02627
02628 builder.slavePrimList(primList, slList, slaveNumber, true, true);
02629 {
02630 boost::mutex::scoped_lock lock(log().mutex());
02631 log() << "Stop ETS (" << slaveNumber << ")\n";
02632 }
02633 sendPrimList(rod, primList);
02634
02635 awaitResponse(rod, 2);
02636 primList->clear();
02637
02638 cout << "Done kill event trapping\n";
02639 }
02640
02641
02642 }
02643 }
02644
02645 void SctApi::abortScan() {
02646 if(scanController)
02647 scanController->abort();
02648 }
02649
02650 void SctApi::rodMode(unsigned int rod,
02651 int mode, int flag, int fifoSetup, int nBits, int delay, int message) {
02652 shared_ptr<PrimListWrapper> rodModeList(new PrimListWrapper(2));
02653
02654 PrimBuilder::instance().rodMode(rodModeList, mode, flag, fifoSetup, nBits, delay, message);
02655
02656 sendPrimList(rod, rodModeList);
02657
02658 int responseCode = awaitResponse(rod, 1);
02659
02660 if(responseCode != 0) {
02661 cout << "Set ROD mode failed!\n";
02662 }
02663 }
02664
02665 void SctApi::setupModuleMask(unsigned int rod,
02666 int port, int slvs) {
02667 shared_ptr<PrimListWrapper> maskList(new PrimListWrapper(1));
02668
02669 setupModuleMask(port, slvs, maskList);
02670
02671 sendPrimList(0, maskList);
02672 int responseCode = awaitResponse(0, 10);
02673
02674 if(responseCode != 0) {
02675 cout << "Module mask setup unsuccessful\n";
02676 }
02677 }
02678
02679 void SctApi::setupModuleMask(int port, int slvs, boost::shared_ptr<PrimListWrapper> primList) {
02680 PrimBuilder::instance().masksFromConfig(primList, port);
02681 PrimBuilder::instance().masksToSlaves(primList, slvs);
02682 }
02683
02684 void SctApi::calib_init() {
02685
02686 #if (R_MODULE_MASK < 101)
02687 #error "Unsupported old MODULE_MASK version"
02688 #else
02689 shared_ptr<PrimListWrapper> calibList(new PrimListWrapper(1));
02690
02691 #if USE_DUAL_PORTS
02692
02693 setupModuleMask(SP_BOTH, 0xf, calibList);
02694 #else
02695 setupModuleMask(SP0, 0xf, calibList);
02696 #endif
02697
02698 PrimBuilder &builder = PrimBuilder::instance();
02699 builder.writeRegister(calibList, RRIF_CMND_0, 0, 8, 0xff);
02700 builder.writeRegister(calibList, RRIF_CMND_0, 0, 8, 0x78);
02701
02702 if(synchSendPrimListAll(calibList) != 0) {
02703 cout << "Calib list moduleMask failed!\n";
02704 }
02705
02706 shared_ptr<PrimListWrapper> rodModeList(new PrimListWrapper(1));
02707 PrimBuilder::instance().rodMode(rodModeList, CALIBRATION_MODE + CALIBRATION_SLINK_OVERRIDE_MODE,
02708 0, 1, 1, 1, 1);
02709
02710 if(synchSendPrimListAll(rodModeList) != 0) {
02711 cout << "Calib list Rod mode on failed!\n";
02712 }
02713
02714
02715
02716 shared_ptr<PrimListWrapper> postRodModeList(new PrimListWrapper(1));
02717 if(checkDebugOption(DEBUG_CALIB_NO_SLINK)) {
02718 builder.writeRegister(postRodModeList, RTR_CMND_STAT, 3, 1, 1);
02719 } else {
02720 builder.writeRegister(postRodModeList, RTR_CMND_STAT, 3, 1, 0);
02721 }
02722
02723
02724
02725
02726
02727 if(synchSendPrimListAll(postRodModeList) != 0) {
02728 cout << "Calib init post rod mode failed!\n";
02729 }
02730 #endif
02731 }
02732
02733 void SctApi::print_calib(unsigned int rod) {
02734 #ifndef FMT_LINK_EN
02735 cout << "Register ids not known\n";
02736 #else
02737 cout << "Formatters\n";
02738
02739 cout << hex;
02740
02741 cout << " Enables\n";
02742
02743 for(int a=0; a<8; a++) {
02744 int data = readRODRegister(rod, FMT_LINK_EN(a)) & 0xffff;
02745 cout.width(4);
02746 cout << data << " ";
02747 }
02748 cout << endl;
02749
02750 cout << " Expanded\n";
02751 for(int a=0; a<8; a++) {
02752 int data = readRODRegister(rod, FMT_EXP_MODE_EN(a)) & 0xffff;
02753 cout.width(4);
02754 cout << hex;
02755 cout << data << " ";
02756 }
02757 cout << endl;
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831 cout << "Link oocupancies\n";
02832 for(int fmt=0; fmt<8; fmt++) {
02833 for(int link=0; link<12; link++) {
02834 int val = readRODRegister(rod, FMT_LINK_OCC_CNT(fmt, link)) & 0x7ff;
02835 cout << " ";
02836 Utility::printHex(val, 3);
02837 }
02838 cout << endl;
02839 }
02840
02841 cout << " Timeout error\n";
02842 for(int a=0; a<8; a++) {
02843 int data = readRODRegister(rod, FMT_TIMEOUT_ERR(a)) & 0xfff;
02844 cout.width(4);
02845 cout << hex;
02846 cout << data << " ";
02847 }
02848 cout << endl;
02849
02850 cout << " Overflow error\n";
02851 for(int a=0; a<8; a++) {
02852 int data = readRODRegister(rod, FMT_DATA_OVERFLOW_ERR(a)) & 0xfff;
02853 cout.width(4);
02854 cout << hex;
02855 cout << data << " ";
02856 }
02857 cout << endl;
02858
02859 cout << " H/T error\n";
02860 for(int a=0; a<8; a++) {
02861 int data = readRODRegister(rod, FMT_HEADER_TRAILER_ERR(a)) & 0xfff;
02862 cout.width(4);
02863 cout << hex;
02864 cout << data << " ";
02865 }
02866 cout << endl;
02867
02868 cout << " ROD busy error\n";
02869 for(int a=0; a<8; a++) {
02870 int data = readRODRegister(rod, FMT_ROD_BUSY_ERR(a)) & 0xfff;
02871 cout.width(4);
02872 cout << hex;
02873 cout << data << " ";
02874 }
02875 cout << endl;
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912 cout << "RRIF version\n";
02913 cout << readRODRegister(rod, RRIF_CODE_VERSION) << endl;
02914 cout << "RRIF status 0\n";
02915 cout << readRODRegister(rod, RRIF_STATUS_0) << endl;
02916 cout << "RRIF status 1\n";
02917 cout << readRODRegister(rod, RRIF_STATUS_1) << endl;
02918
02919 cout << "RRIF command 0\n";
02920 cout << readRODRegister(rod, RRIF_CMND_0) << endl;
02921 cout << "RRIF command 1\n";
02922 cout << readRODRegister(rod, RRIF_CMND_1) << endl;
02923
02924 cout << "Output masks\n";
02925 cout << " ";
02926 Utility::printHex(readRODRegister(rod, FE_CMND_MASK_0_LO), 8);
02927 cout << endl;
02928 cout << " ";
02929 Utility::printHex(readRODRegister(rod, FE_CMND_MASK_0_HI), 8);
02930 cout << endl;
02931 cout << " ";
02932 Utility::printHex(readRODRegister(rod, FE_CMND_MASK_1_LO), 8);
02933 cout << endl;
02934 cout << " ";
02935 Utility::printHex(readRODRegister(rod, FE_CMND_MASK_1_HI), 8);
02936 cout << endl;
02937
02938 cout << "L1ID for ports 0 and 1\n";
02939 Utility::printHex(readRODRegister(rod, CAL_L1_ID_0), 8);
02940 Utility::printHex(readRODRegister(rod, CAL_L1_ID_1), 8);
02941 cout << "BCID for ports 0 and 1\n";
02942 Utility::printHex(readRODRegister(rod, CAL_BCID), 8);
02943
02944 cout << dec;
02945 #endif
02946 }
02947
02948 unsigned long SctApi::sendTimBurst(unsigned long count, int random, bool external) {
02949 return getCrate()->sendTimBurst(count, random, external);
02950 }
02951
02952 unsigned long SctApi::sendTriggers(const Trigger* trig, unsigned long count, int scan_point){
02953 int random = trig->getRandom();
02954 double freq = trig->getFrequency();
02955 Trigger::Source source = trig->getSource();
02956 switch (source){
02957 case Trigger::SOURCE_TIM_INTERNAL:
02958 case Trigger::SOURCE_TIM_EXTERNAL:
02959 {
02960 bool use_sequencer = trig->timNeedsSequencer();
02961 bool external = (source==Trigger::SOURCE_TIM_EXTERNAL);
02962
02963 if (internal) {
02964
02965 timSetFrequency(trig->getFrequency(), timGetResetFrequency());
02966 }
02967
02968 if (use_sequencer) {
02969 printf("Sending %d triggers using the sequencer, random=%d, external=%d\n",count,random,external);
02970 Trigger::TIMTriggers timTrigs = Trigger::convertToTIMTriggers(trig->getRODTriggers(scan_point));
02971 vector<unsigned> seq(timTrigs.size());
02972 for (unsigned i=0; i<timTrigs.size(); ++i){
02973 seq[i]=timTrigs[i];
02974 }
02975 timLoadSequence(seq);
02976 return timRunSequence(count, random, external);
02977 } else {
02978 printf("Sending %d triggers, random=%d, external=%d\n",count,random,external);
02979 return sendTimBurst(count, random, external);
02980 }
02981 break;
02982 }
02983 case Trigger::SOURCE_ROD:
02984 for(list<RodLabel>::const_iterator rl = rodList.begin();
02985 rl!=rodList.end();
02986 rl++){
02987 #warning "No parallelisation here yet AJB 2005-11-25"
02988 sendRodTrigger(rl->rod, trig, count, scan_point);
02989 }
02990 break;
02991 default:
02992 if (mrs) {
02993 *mrs << "TRIG_SOURCE_UNKNOWN" << MRS_TEXT("Trigger source may not be implimented yet")
02994 << MRS_PARAM<int>("source",source)
02995 << MRS_ERROR << ENDM;
02996 }else{
02997 std::cout << "Dont yet know how to send triggers from source : " << source
02998 << " " << __FILE__ << ":" << __LINE__ << std::endl;
02999 }
03000 throw SctApiException("BadTrigger");
03001 break;
03002 }
03003 }
03004
03005 void SctApi::sendRodTrigger(unsigned int rod, const Trigger *trig, unsigned long count, int scan_point) {
03006 {
03007 boost::mutex::scoped_lock lock(log().mutex());
03008 log() << "Send Trigger\n";
03009 }
03010
03011
03012
03013
03014
03015 #if USE_DUAL_PORTS
03016 int serialPorts = SP_BOTH;
03017 #else
03018 int serialPorts = SP0;
03019 #endif
03020
03021 long *data = new long[sizeof(BUILD_STREAM_IN)/4];
03022
03023 BUILD_STREAM_IN &buildPrim = *(BUILD_STREAM_IN*)data;
03024
03025 #if (R_BUILD_STREAM == 102)
03026 Trigger::RODTriggers points = trig->getRODTriggers(scan_point);
03027
03028 for(int i=0; i<N_CMD_LIST_CMDS; i++) {
03029 buildPrim.cmdList.cmd[i] = NO_CMD;
03030 buildPrim.cmdList.data[i] = 0;
03031 }
03032 for(unsigned int i=0; i<points.size(); i++) {
03033 buildPrim.cmdList.cmd[i] = points[i].first;
03034 buildPrim.cmdList.data[i] = points[i].second;
03035 }
03036
03037 buildPrim.port = serialPorts;
03038 buildPrim.reset = 1;
03039 buildPrim.chip = 63;
03040 buildPrim.fibre = 3;
03041 buildPrim.dataLen = 0;
03042 buildPrim.data = 0;
03043
03044 shared_ptr<PrimListWrapper> sendList(new PrimListWrapper(3));
03045
03046 sendList->addPrimitive(RodPrimitive(4 + sizeof(BUILD_STREAM_IN)/4,
03047 2, BUILD_STREAM, R_BUILD_STREAM, data),
03048 data);
03049 #elif R_BUILD_STREAM == 101
03050 #error "Build stream not compiled (unsupported old version)"
03051 #else // Unknown R_BUILD_STREAM
03052 #error "Build stream not compiled (unknown primitive version, check primParams.h)"
03053 #endif
03054
03055 #if USE_DUAL_PORTS
03056
03057 PrimBuilder::instance().sendStream(sendList, serialPorts, 0);
03058 #else
03059
03060
03061 PrimBuilder::instance().sendStream(sendList, SP_BOTH, 0);
03062 #endif
03063
03064 for (unsigned i=0; i<count; ++i){
03065 sendPrimList(rod, sendList);
03066
03067 int responseCode = awaitResponse(rod, 2);
03068
03069 if(responseCode != 0) {
03070 cout << "Send trigger " << i << " failed on rod " << rod << "!\n";
03071 break;
03072 }
03073 }
03074 }
03075
03076 void SctApi::sendL1A(unsigned int rod, bool capture) {
03077 {
03078 boost::mutex::scoped_lock lock(log().mutex());
03079 log() << "Send L1A\n";
03080 }
03081
03082 long *data = new long[sizeof(BUILD_STREAM_IN)/4];
03083
03084 BUILD_STREAM_IN &buildPrim = *(BUILD_STREAM_IN*)data;
03085
03086 #if (R_BUILD_STREAM == 102)
03087 for(int i=0; i<6; i++) {
03088 buildPrim.cmdList.cmd[i] = 0x64;
03089 buildPrim.cmdList.data[i] = 0;
03090 }
03091
03092 buildPrim.cmdList.cmd[0] = 0x65;
03093
03094 buildPrim.port = SP0;
03095 buildPrim.reset = 1;
03096 buildPrim.chip = 63;
03097 buildPrim.fibre = 3;
03098 buildPrim.dataLen = 0;
03099 buildPrim.data = 0;
03100
03101 shared_ptr<PrimListWrapper> sendList(new PrimListWrapper(3));
03102
03103 sendList->addPrimitive(RodPrimitive(4 + sizeof(BUILD_STREAM_IN)/4,
03104 2, BUILD_STREAM, R_BUILD_STREAM, data),
03105 data);
03106 #elif R_BUILD_STREAM == 101
03107 #error "Build stream not compiled (unsupported old version)"
03108 #else // Unknown R_BUILD_STREAM
03109 #error "Build stream not compiled (unknown primitive version, check primParams.h)"
03110 #endif
03111
03112 #ifdef CMD_BUFFER_BOTH
03113 PrimBuilder::instance().sendStream(sendList, CMD_BUFFER_BOTH, capture);
03114 #else
03115 PrimBuilder::instance().sendStream(sendList, SP_BOTH, capture);
03116 #endif
03117
03118 sendPrimList(rod, sendList);
03119
03120 awaitResponse(rod, 2);
03121 }
03122
03123 void SctApi::bocHistogram(unsigned int rod,
03124 unsigned int samples, unsigned int numLoops) {
03125 std::cout << "BOC histogram unsupported\n";
03126 throw SctApiException("BOC histogram unsupported");
03127 }
03128
03129 void SctApi::printABCDModule(int mid) {
03130 ABCDModule *mConf = lookupConfig(mid);
03131
03132 if(mConf) {
03133 std::cout << config->printModuleConfig(*mConf);
03134 } else {
03135 cout << "Invalid module id " << mid << endl;
03136 }
03137 }
03138
03139 void SctApi::printABCDRodModule(int mid, BankType bank) {
03140 getABCDModule(mid, bank);
03141
03142 ABCDModule *mConf = lookupConfig(mid);
03143 if (mConf) std::cout << config->printModuleConfig(*mConf);
03144 }
03145
03146 void SctApi::modifyTIMParam(unsigned int type, unsigned int val) {
03147 getCrate()->modifyTIMParam(type, val);
03148 }
03149
03150 void SctApi::modifyBOCParam(unsigned int type, unsigned int val) {
03151 getCrate()->modifyBOCParam(type, val, true);
03152 }
03153
03154 void SctApi::modifyBOCParam(unsigned int rod,
03155 unsigned int channel, unsigned int type, unsigned int val) {
03156 getCrate()->modifyBOCParam(rod, channel, type, val, true);
03157 }
03158
03159 void SctApi::printBOCSetup(unsigned int rod) {
03160 getCrate()->printBOCSetup(rod);
03161 }
03162
03163 vector<BOCChannelConfig> SctApi::currentBOCSetup(unsigned int rod) {
03164 return getCrate()->currentBOCSetup(rod);
03165 }
03166
03167 void SctApi::printBOCRegisters(unsigned int rod) {
03168 getCrate()->printBOCRegisters(rod);
03169 }
03170
03171 BOCGlobalConfig SctApi::currentBOCRegisters(unsigned int rod) {
03172 return getCrate()->currentBOCRegisters(rod);
03173 }
03174
03175 void SctApi::saveBOCSetup(unsigned int rod, BankType bank) {
03176 getCrate()->saveBOCSetup(rod, bank);
03177 }
03178
03179 void SctApi::saveBOCRegisters(unsigned int rod, BankType bank) {
03180 getCrate()->saveBOCRegisters(rod, bank);
03181 }
03182
03183 void SctApi::restoreBOCSetup(unsigned int rod, BankType bank) {
03184 getCrate()->restoreBOCSetup(rod, bank);
03185 }
03186
03187 void SctApi::restoreBOCRegisters(unsigned int rod, BankType bank) {
03188 getCrate()->restoreBOCRegisters(rod, bank);
03189 }
03190
03191 void SctApi::lasersOff() {
03192 {
03193 boost::mutex::scoped_lock lock(log().mutex());
03194 log() << "Lasers off called\n";
03195 log() << "\t TIME " << second_clock::universal_time() << endl;
03196 }
03197
03198 std::cout << " *** Trying to turn lasers off ***\n";
03199 getCrate()->lasersOff();
03200 }
03201
03202 void SctApi::timSetFrequency(double trigFreq, double rstFreq) {
03203 getCrate()->timSetFrequency(trigFreq, rstFreq);
03204 }
03205
03206 double SctApi::timGetTriggerFrequency() {
03207 return getCrate()->timGetTriggerFrequency();
03208 }
03209
03210 double SctApi::timGetResetFrequency() {
03211 return getCrate()->timGetResetFrequency();
03212 }
03213
03214 void SctApi::freeTriggers() {
03215 shared_ptr<PrimListWrapper> timList(new PrimListWrapper(1));
03216
03217 #ifdef RRIF_CMND_1
03218 PrimBuilder &builder = PrimBuilder::instance();
03219
03220 builder.writeRegister(timList, RRIF_CMND_1, 1, 1, 1);
03221
03222 builder.writeRegister(timList, RRIF_CMND_1, 8, 1, 1);
03223 #else
03224 #error "Unsupported no registers"
03225 #endif
03226
03227 sendPrimListAll(timList);
03228
03229 awaitResponseAll(2);
03230
03231 getCrate()->freeTriggers();
03232 }
03233
03234 void SctApi::stopTriggers() {
03235 shared_ptr<PrimListWrapper> timList(new PrimListWrapper(1));
03236
03237 #ifdef RRIF_CMND_1
03238 PrimBuilder &builder = PrimBuilder::instance();
03239
03240 builder.writeRegister(timList, RRIF_CMND_1, 1, 1, 0);
03241
03242 builder.writeRegister(timList, RRIF_CMND_1, 8, 1, 0);
03243 #else
03244 #error "Unsupported no registers"
03245 #endif
03246
03247 sendPrimListAll(timList);
03248
03249 awaitResponseAll(2);
03250
03251 getCrate()->stopTriggers();
03252 }
03253
03254 void SctApi::timL1A() {
03255 getCrate()->timL1A();
03256 }
03257
03258 void SctApi::timCalL1A(int delay) {
03259 getCrate()->timCalL1A(delay);
03260 }
03261
03262 void SctApi::timSoftReset() {
03263
03264 getCrate()->timECR();
03265 }
03266
03267 void SctApi::timBCReset() {
03268 getCrate()->timBCR();
03269 }
03270
03271 void SctApi::timLoadSequence(const vector<unsigned>& seq){
03272 getCrate()->timLoadSequence(seq);
03273 }
03274
03275 unsigned long SctApi::timRunSequence(unsigned long trigs, int random, bool external){
03276 return getCrate()->timRunSequence(trigs, random, external);
03277 }
03278
03279 void SctApi::timVerbose() {
03280 getCrate()->timVerbose();
03281 }
03282
03283 void SctApi::timWriteRegister(int reg, UINT16 val) {
03284 getCrate()->timRegLoad(reg, val);
03285 }
03286
03287 UINT16 SctApi::timReadRegister(int reg) {
03288 return getCrate()->timRegRead(reg);
03289 }
03290
03291 void SctApi::decodeConfig(unsigned int rod,
03292 bool skipTrim, bool bypass) {
03293 unsigned long readlength;
03294 #warning "Hard-coded address, this is the serial port output buffer"
03295 unsigned long *config = dspBlockRead(rod, 0x2102000, 270 * 12, -1, readlength);
03296
03297 unsigned int pos = 0;
03298 while(pos < readlength) {
03299 if((config[pos] & 0x5760000) != 0x5700000) {
03300 cout << "Strange data: ";
03301 cout << hex << " " << pos << " " << config[pos] << dec << endl;
03302 break;
03303 }
03304
03305 unsigned int f3 = (config[pos] & 0xff000) >> 12;
03306 unsigned int f4 = (config[pos] & 0x00fc0) >> 6;
03307 unsigned int f5 = (config[pos] & 0x0003f) >> 0;
03308
03309 pos ++;
03310
03311 cout << "Chip address " << f4 << ": ";
03312 if(!bypass) {
03313 cout << hex << f3 << "/" << f5 << dec << ": ";
03314 }
03315
03316 switch(f3) {
03317 case 0x1c:
03318 {
03319 unsigned short data = (0xffff0000 & config[pos]) >> 16;
03320 switch(f5) {
03321 case 0:
03322
03323 if(!bypass) {
03324 cout << "Config: " << hex << data << dec;
03325 cout << " comp " << (data & 3)
03326 << " cal " << ((data & 0xc) >> 2)
03327 << " trim " << ((data & 0x30) >> 4)
03328 << " edge " << ((data & 0x40) >> 6)
03329 << " mask " << ((data & 0x80) >> 7)
03330 << " acc " << ((data & 0x100) >> 8)
03331 << " in_b " << ((data & 0x200) >> 9)
03332 << " out_b " << ((data & 0x400) >> 10)
03333 << " mast " << ((data & 0x800) >> 11)
03334 << " end " << ((data & 0x1000) >> 12)
03335 << " feed " << ((data & 0x2000) >> 13)
03336 << endl;
03337 } else {
03338 cout << " in_b " << ((data & 0x200) >> 9)
03339 << " out_b " << ((data & 0x400) >> 10)
03340 << " mast " << ((data & 0x800) >> 11)
03341 << " end " << ((data & 0x1000) >> 12)
03342 << " feed " << ((data & 0x2000) >> 13)
03343 << endl;
03344 }
03345 break;
03346 case 0x10:
03347 if(!bypass) {
03348 cout << "Strobe delay: " << hex
03349 << (data & 0x3f) << dec << endl;
03350 }
03351 break;
03352 case 0x18:
03353 if(!bypass) {
03354 cout << "Threshold/Cal: " << hex
03355 << ((data & 0xff00) >> 8) << "/"
03356 << (data & 0xff) << dec << endl;
03357 }
03358 break;
03359 case 0x38:
03360 if(!bypass) {
03361 cout << "preamp/shaper: " << hex
03362 << ((data & 0xff00) >> 8) << "/"
03363 << (data & 0xff) << dec << endl;
03364 }
03365 break;
03366 case 0x04:
03367 if(skipTrim || bypass) {
03368 cout << "\r \r";
03369 } else {
03370 cout << "TRIM DAC: " << hex
03371 << (data & 0xf) << " "
03372 << ((data & 0x7f0) >> 4) << dec << endl;
03373 }
03374 break;
03375 }
03376 pos ++;
03377 break;
03378 }
03379 case 0x8c:
03380 if(!bypass) {
03381
03382 cout << "Mask ";
03383 cout << hex;
03384 for(int i=0; i<4; i++) {
03385 cout << config[pos++] << " ";
03386 }
03387 cout << dec;
03388 cout << endl;
03389 pos++;
03390 } else {
03391 pos += 5;
03392 }
03393 break;
03394 case 0x0c:
03395 cout << "Something else\n";
03396 break;
03397 }
03398 }
03399 }
03400
03401 void SctApi::getrpcrc(UINT32 mid, unsigned int &rpartition, unsigned int &rcrate, unsigned int &rrod, unsigned int &rchannel) {
03402 unsigned int partition, crate, rod, channel;
03403
03404 getpcrc(mid, partition, crate, rod, channel);
03405
03406 unsigned int mur, module;
03407
03408 try {
03409 if(checkDebugOption(DEBUG_DIAG))
03410 cout << "Looking for module in partition " << partition << " crate " << crate << " rod " << rod << " channel " << channel << endl;
03411 config->translateFromROD(partition, crate, rod, channel,
03412 mur, module);
03413
03414 if(checkDebugOption(DEBUG_DIAG2))
03415 cout << "Found MUR " << mur << " module number " << module << endl;
03416 } catch(ConfigurationException &c) {
03417 cout << "Can't find module in MUR map: \n";
03418 cout << c.what() << endl;
03419
03420 {
03421 boost::mutex::scoped_lock lock(log().mutex());
03422 log() << " (Not found)\n";
03423 }
03424 throw;
03425 }
03426
03427 try {
03428 config->translateToRROD(mur, module,
03429 rpartition, rcrate, rrod, rchannel);
03430 } catch(ConfigurationException &c) {
03431 cout << "Module redundancy not found: \n";
03432 cout << c.what() << endl;
03433
03434 {
03435 boost::mutex::scoped_lock lock(log().mutex());
03436 log() << " (Not found)\n";
03437 }
03438 throw;
03439 }
03440 }
03441
03442 long SctApi::getRodSlot(unsigned int rod)
03443 {
03444 if(getCrate()) {
03445 return getCrate()->getRodSlot(rod);
03446 } else {
03447 return -1;
03448 }
03449 }
03450
03451 int SctApi::getRodRevision(unsigned int rod)
03452 {
03453 if(getCrate()) {
03454 return getCrate()->getRodRevision(rod);
03455 } else {
03456 return -1;
03457 }
03458 }
03459
03460 int SctApi::getRodRevision(const RodLabel &label)
03461 {
03462 if(getCrate()) {
03463 return getCrate()->getRodRevision(label.rod);
03464 } else {
03465 return -1;
03466 }
03467 }
03468
03469 void SctApi::testLinkOutSelect(unsigned int rod,
03470 unsigned int link)
03471 {
03472 #ifdef FMT_LINK_DATA_TEST_MUX
03473 int formatter = link/12;
03474 int intLink = link%12;
03475
03476 if(formatter > 8 || formatter < 0) {
03477 cout << "formatter out of range: " << formatter << endl;
03478 return;
03479 }
03480
03481 if(intLink > 12 || intLink < 0) {
03482 cout << "link out of range: " << intLink << endl;
03483 return;
03484 }
03485
03486 shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
03487
03488 PrimBuilder &builder = PrimBuilder::instance();
03489 builder.writeRegister(primList, FMT_LINK_DATA_TEST_MUX(formatter), 0, 4, intLink);
03490 builder.writeRegister(primList, EFB_CMND_0, 4, 4, formatter & 0x7);
03491
03492 sendPrimList(rod, primList);
03493 awaitResponse(rod, 2);
03494 #else
03495 #error "Link out select not compiled"
03496 #endif
03497 }
03498
03499 unsigned int SctApi::testLinkOutRetrieve(unsigned int rod)
03500 {
03501 #ifdef FMT_LINK_DATA_TEST_MUX
03502 int fReg = readRODRegister(rod, EFB_CMND_0);
03503 int formatter = (fReg >> 4) & 0x7;
03504
03505 int lReg = readRODRegister(rod, FMT_LINK_DATA_TEST_MUX(formatter));
03506 int intLink = lReg & 0xf;
03507
03508 return formatter * 12 + intLink;
03509 #else
03510 #error "Link out select not compiled"
03511 #endif
03512 }
03513
03514 void SctApi::setDebugOption(std::string opt) {
03515 Debug::getInstance()->setDebugOption(opt);
03516 }
03517
03518 void SctApi::unsetDebugOption(std::string opt) {
03519 Debug::getInstance()->unsetDebugOption(opt);
03520 }
03521
03522 std::list<std::string> SctApi::listEnabledDebugOptions() const{
03523 return Debug::getInstance()->listEnabledDebugOptions();
03524 }
03525
03526 std::vector<std::string> SctApi::listDebugOptions() const{
03527 return Debug::getInstance()->listDebugOptions();
03528 }
03529
03530 void SctApi::unsetBusy() {
03531 if(m_isDict) {
03532 m_isDict->remove(idiosyncrasy().infoServiceNameOfScanStatusObject());
03533 }
03534 }
03535
03536 bool SctApi::checkDebugOption(std::string opt) const{
03537 return Debug::getInstance()->checkDebugOption(opt);
03538 }
03539
03540 bool SctApi::checkDebugOption(int intOpt) const{
03541 return Debug::getInstance()->checkDebugOption((DebugOptions)intOpt);
03542 }
03543
03544 void SctApi::debugStepHistogram()
03545 {
03546 if(!lastDebugScanEx) {
03547 cout << "No last scan stored\n";
03548 return;
03549 }
03550
03551
03552 RodLabel zeroRod = lastDebugScanEx->rodInfo.begin()->first;
03553
03554
03555 #warning "Hard coded access to diagnostic register with STEP_CTRL and STEP_TRIGGER bits"
03556 dspSingleWrite(zeroRod.rod,
03557 0x80000010, lastDebugScanEx->diagnosticReg | (1<<7) | (1<<6), -1);
03558
03559 #if USE_THREADS
03560 sleep(1);
03561 #else
03562
03563 awaitResponse(zeroRod.rod, 1);
03564 #endif
03565
03566 if(checkDebugOption(DEBUG_EXTRA_DUMPS)) {
03567 standardRegisterDump(zeroRod.rod);
03568 }
03569 }
03570
03571 void SctApi::debugContinueHistogram()
03572 {
03573
03574 RodLabel zeroRod = lastDebugScanEx->rodInfo.begin()->first;
03575
03576 #warning "Hard-coded diagnostic register with STEP_TRIGGER bit"
03577 dspSingleWrite(zeroRod.rod,
03578 0x80000010, lastDebugScanEx->diagnosticReg | (1<<7), -1);
03579
03580 #if USE_THREADS
03581 sleep(1);
03582 #else
03583
03584 awaitResponse(zeroRod.rod,
03585 1);
03586 #endif
03587
03588 if(checkDebugOption(DEBUG_EXTRA_DUMPS)) {
03589 standardRegisterDump(zeroRod.rod);
03590 }
03591 }
03592
03593 void SctApi::debugAbortHistogram()
03594 {
03595 #warning "How to do this... tidyHistogramming? (not when in stalled mode!) AUTO_STALL ends at next bin!"
03596
03597 time_t start_time = time(0);
03598
03599
03600 RodLabel zeroRod = lastDebugScanEx->rodInfo.begin()->first;
03601
03602 while(1) {
03603 cout << "** Loop\n";
03604
03605 #warning "Hard coded address (Diagnostic register (STEP_TRIGGER))"
03606 dspSingleWrite(zeroRod.rod,
03607 0x80000010, (1<<7), -1);
03608 while(dspSingleRead(zeroRod.rod,
03609 0x80000010, -1) & (1<<7)) {
03610 if((time(0) - start_time) > 2) {
03611 goto breakOut;
03612 }
03613 }
03614 }
03615
03616 breakOut:
03617 tidyHistogramming();
03618 }
03619
03620 void SctApi::standardRegisterDump(RodLabel rl) {
03621 standardRegisterDump(rl.rod);
03622 }
03623
03624 void SctApi::standardRegisterDump(unsigned int rod) {
03625 static int dumpCount = 0;
03626
03627 if(!getCrate()
03628 || !getCrate()->RODPresent(rod)) {
03629 cout << "Invalid crate or ROD in standardRegisterDump\n";
03630 return;
03631 }
03632
03633 cout << "Making dump number " << dumpCount << endl;
03634
03635 string baseDir(Sct::SctNames::getTempDir());
03636
03637
03638 boost::format dirFormat("%s/Dump_%05d_%05d");
03639 dirFormat % baseDir % getpid() % (dumpCount ++);
03640
03641 string dirName(dirFormat.str());
03642
03643 cout << " in " << dirName << endl;
03644
03645 int dirRet = mkdir(dirName.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
03646 if(dirRet != 0) {
03647
03648 if(errno != EEXIST) {
03649 perror(("Failed to create Dump directory in '" + baseDir + "', aborting dump").c_str());
03650 return;
03651 }
03652 }
03653
03654 char *saveDir = getcwd(NULL, 0);
03655 int chRet = chdir(dirName.c_str());
03656 if(chRet != 0) {
03657 perror("Failed to change to Dump directory, aborting dump");
03658 return;
03659 }
03660
03661 dspBlockDumpFile(rod, 0x02400000, 0x80000, -1, "BigMDSPDump.bin");
03662
03663 dspBlockDumpFile(rod, 0x00400000, 0x800, -1, "StandardDumpFRM.bin");
03664 dspBlockDumpFile(rod, 0x00402000, 0x100, -1, "StandardDumpEFB.bin");
03665 dspBlockDumpFile(rod, 0x00402400, 0x060, -1, "StandardDumpRTR.bin");
03666 dspBlockDumpFile(rod, 0x00404400, 0x300, -1, "StandardDumpRCF.bin");
03667
03668 dspBlockDumpFile(rod, 0x02000000, 0x40000, -1, "StandardDumpMDSP_XPROG.bin");
03669 dspBlockDumpFile(rod, 0x80000000, 0x02000, -1, "StandardDumpMDSP_IDRAM.bin");
03670
03671 ofstream moduleList("StandardModuleList.txt");
03672
03673 moduleList << "Module configuration for " << moduleMap.size() << " modules:\n";
03674 for(map<UINT32, ABCDModule>::const_iterator mi = moduleMap.begin();
03675 mi!=moduleMap.end();
03676 mi ++) {
03677 UINT32 mid = mi->first;
03678
03679 string sn = convertToString(mid);
03680 ABCDModule *moduleConf = lookupConfig(mid);
03681 int group = moduleConf->groupId;
03682 int select = moduleConf->select;
03683 int prim = moduleConf->pTTC;
03684 int redun = moduleConf->rTTC;
03685 int link0 = moduleConf->rx[0];
03686 int link1 = moduleConf->rx[1];
03687
03688
03689 if(link0 != DATA_LINK_OFF)
03690 link0 = (link0/16) * 12 + link0%16;
03691 if(link1 != DATA_LINK_OFF)
03692 link1 = (link1/16) * 12 + link1%16;
03693
03694 moduleList.width(8);
03695 moduleList << mid << " " << sn << " Group: " << group << " Select: " << select;
03696 moduleList << "\t Pr: ";
03697 moduleList.width(2);
03698 moduleList << prim << " Red: ";
03699 moduleList.width(3);
03700 moduleList << redun << " Link 0/1: ";
03701 moduleList.width(3);
03702 moduleList << link0 << " ";
03703 moduleList.width(3);
03704 moduleList << link1 << endl;
03705 }
03706
03707
03708 if(getCrate()->getRodRevision(rod) >= 0xE) {
03709 for(int s=0; s<4; s++) {
03710
03711 string idramFile = "StandardDumpSDSP0_IDRAM.bin";
03712 idramFile[16] = s + '0';
03713 dspBlockDumpFile(rod, 0x00010000, 0x2000, s, idramFile);
03714 string burstFile = "StandardDumpSDSP0_BURST.bin";
03715 burstFile[16] = s + '0';
03716 dspBlockDumpFile(rod, 0x00018000, 0x2000, s, burstFile);
03717 string sdramFile = "StandardDumpSDSP0_SDRAM.bin";
03718 sdramFile[16] = s + '0';
03719 dspBlockDumpFile(rod, 0xa0040000, 0x28800, s, sdramFile);
03720 }
03721 } else {
03722 for(int s=0; s<4; s++) {
03723
03724 string idramFile = "StandardDumpSDSP0_IDRAM.bin";
03725 idramFile[16] = s + '0';
03726 dspBlockDumpFile(rod, 0x80000000, 0x2000, s, idramFile);
03727 string burstFile = "StandardDumpSDSP0_BURST.bin";
03728 burstFile[16] = s + '0';
03729 dspBlockDumpFile(rod, 0x80008000, 0x2000, s, burstFile);
03730 string sdramFile = "StandardDumpSDSP0_SDRAM.bin";
03731 sdramFile[16] = s + '0';
03732 dspBlockDumpFile(rod, 0x02040000, 0x28800, s, sdramFile);
03733 }
03734 }
03735
03736 int chSaveRet = chdir(saveDir);
03737 if(chSaveRet != 0) {
03738 perror("Failed to return to saved directory after Dump");
03739 }
03740 }
03741
03742 void SctApi::standardRegisterDumpAll() {
03743 for(list<RodLabel>::const_iterator rl = rodList.begin();
03744 rl!=rodList.end();
03745 rl++){
03746 standardRegisterDump(*rl);
03747 }
03748 }
03749
03750 void SctApi::setupScanMasks(ScanEx &extra, int distSlave, bool dual) {
03751 RodScanEx defaultInfo;
03752
03753 if(distSlave == 0) {
03754 defaultInfo.slaves = 1;
03755 defaultInfo.bitFieldDSP = 0x1;
03756 } else if(distSlave == 1) {
03757 defaultInfo.slaves = 0;
03758 defaultInfo.bitFieldDSP = 0x0;
03759 } else if(distSlave == 2) {
03760 defaultInfo.slaves = 4;
03761 defaultInfo.bitFieldDSP = 0xf;
03762 }
03763
03764 ModuleMask zeroMask = {0, 0};
03765
03766 defaultInfo.channels = zeroMask;
03767
03768 for(int i=0; i<8; i++) {
03769 defaultInfo.groupChannels[i] = zeroMask;
03770 }
03771 for(int i=0; i<4; i++) {
03772 defaultInfo.slaveChannels[i] = zeroMask;
03773 }
03774
03775
03776 if(distSlave == 0) {
03777
03778 extra.groupDspMap[0] = 0xff;
03779 extra.groupDspMap[1] = 0x0;
03780 extra.groupDspMap[2] = 0x0;
03781 extra.groupDspMap[3] = 0x0;
03782 } else if(distSlave == 2) {
03783
03784 extra.groupDspMap[0] = 0xff;
03785 extra.groupDspMap[1] = 0xff;
03786 extra.groupDspMap[2] = 0xff;
03787 extra.groupDspMap[3] = 0xff;
03788 } else {
03789 if(!dual) {
03790
03791 extra.groupDspMap[0] = 0x11;
03792 extra.groupDspMap[1] = 0x22;
03793 extra.groupDspMap[2] = 0x44;
03794 extra.groupDspMap[3] = 0x88;
03795 } else {
03796
03797 extra.groupDspMap[0] = 0x03;
03798 extra.groupDspMap[1] = 0x0c;
03799 extra.groupDspMap[2] = 0x30;
03800 extra.groupDspMap[3] = 0xc0;
03801 }
03802 }
03803
03804 if(!dual) {
03805 extra.groupSpMap[0] = 0xff;
03806 extra.groupSpMap[1] = 0x00;
03807 } else {
03808 extra.groupSpMap[0] = 0xf;
03809 extra.groupSpMap[1] = 0xf0;
03810 }
03811
03812 if(!dual) {
03813 extra.groupRangeMap[0] = 0xff;
03814 extra.groupRangeMap[1] = 0x0;
03815 } else {
03816 extra.groupRangeMap[0] = 0x0f;
03817 extra.groupRangeMap[1] = 0xf0;
03818 }
03819
03820
03821 for(map<UINT32, ABCDModule>::const_iterator mi = moduleMap.begin();
03822 mi!=moduleMap.end();
03823 mi ++) {
03824 UINT32 currMid = mi->first;
03825
03826 ABCDModule *moduleConfig = lookupConfig(currMid);
03827 unsigned int group = moduleConfig->groupId;
03828
03829 unsigned int newPartition, newCrate, newRod, newChannel;
03830 getpcrc(currMid, newPartition, newCrate, newRod, newChannel);
03831
03832 RodLabel thisRod(newPartition, newCrate, newRod);
03833
03834 RodScanEx &thisInfo = extra.getOrNewRod(thisRod, defaultInfo);
03835
03836
03837 if(moduleConfig->select) {
03838
03839 try {
03840 unsigned int rpartition, rcrate, rrod, rchannel;
03841 getrpcrc(currMid, rpartition, rcrate, rrod, rchannel);
03842
03843 if(newPartition != rpartition || newCrate != rcrate || newRod != rrod) {
03844
03845 }
03846 } catch(ConfigurationException &c) {
03847
03848 }
03849 }
03850
03851 if(newChannel<32) {
03852 if(thisInfo.channels.mask0 & 1<<newChannel) {
03853 cout << "Module already using this channel in this group\n";
03854 }
03855 thisInfo.channels.mask0 |= 1<<newChannel;
03856
03857 if(distSlave == 1) {
03858 thisInfo.groupChannels[group].mask0 |= 1<<newChannel;
03859 } else if(distSlave == 0) {
03860 thisInfo.groupChannels[0].mask0 |= 1<<newChannel;
03861 } else {
03862
03863 thisInfo.groupChannels[group].mask0 |= 1<<newChannel;
03864 }
03865 } else {
03866 if(thisInfo.channels.mask1 & 1<<(newChannel-32)) {
03867 cout << "Module already using this channel in this group\n";
03868 }
03869 thisInfo.channels.mask1 |= 1<<(newChannel-32);
03870
03871 if(distSlave == 1) {
03872 thisInfo.groupChannels[group].mask1 |= 1<<(newChannel-32);
03873 } else if(distSlave == 0) {
03874 thisInfo.groupChannels[0].mask1 |= 1<<(newChannel-32);
03875 } else {
03876
03877 thisInfo.groupChannels[group].mask1 |= 1<<(newChannel-32);
03878 }
03879 }
03880
03881 if(group+1 > extra.groupLists.size()) {
03882 extra.groupLists.resize(group + 1);
03883 }
03884 extra.groupLists[group].push_back(convertToString(currMid));
03885 }
03886
03887
03888 for(list<RodLabel>::const_iterator rl = rodList.begin();
03889 rl!=rodList.end();
03890 rl++){
03891
03892 RodScanEx &thisInfo = extra.getRodScanInfo(*rl);
03893
03894 thisInfo.slaves = 0;
03895 thisInfo.firstSlave = numSlaves;
03896
03897 for(int slave=0; slave<numSlaves; slave++) {
03898 for(int group=0; group<8; group++) {
03899 if(extra.groupDspMap[slave] & (1<<group)) {
03900 if(thisInfo.groupChannels[group].mask0 || thisInfo.groupChannels[group].mask1) {
03901 thisInfo.bitFieldDSP |= 1<<slave;
03902 }
03903
03904 thisInfo.slaveChannels[slave].mask0 |= thisInfo.groupChannels[group].mask0;
03905 thisInfo.slaveChannels[slave].mask1 |= thisInfo.groupChannels[group].mask1;
03906 }
03907 }
03908
03909 if(thisInfo.bitFieldDSP & (1<<slave)) {
03910 thisInfo.slaves++;
03911
03912 if(thisInfo.firstSlave > 3) {
03913 thisInfo.firstSlave = slave;
03914 }
03915 }
03916 }
03917 }
03918 }
03919
03920
03921 bool SctApi::checkModuleListsForScan() {
03922 if(moduleMap.begin() == moduleMap.end()) {
03923 cout << "No modules to scan!\n";
03924 if(mrs) {
03925 *mrs << "SCAN_NO_MODULES" << MRS_ERROR
03926 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
03927 << MRS_TEXT("No modules to scan")
03928 << ENDM;
03929 }
03930 return false;
03931 }
03932
03933
03934 UINT32 mid = moduleMap.begin()->first;
03935 unsigned int firstPartition, firstCrate, firstRod, firstChannel;
03936 getpcrc(mid, firstPartition, firstCrate, firstRod, firstChannel);
03937
03938 for(map<UINT32, ABCDModule>::const_iterator mi = moduleMap.begin();
03939 mi!=moduleMap.end();
03940 mi ++) {
03941 UINT32 currMid = mi->first;
03942
03943 unsigned int newPartition, newCrate, newRod, newChannel;
03944
03945 getpcrc(currMid, newPartition, newCrate, newRod, newChannel);
03946
03947
03948 if(newPartition != firstPartition) {
03949 cout << "Can't do scans on modules in different partitions (ever?)\n";
03950 if(mrs) {
03951 *mrs << "SCAN_MISMATCH" << MRS_ERROR
03952 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
03953 << MRS_TEXT("Mismatch partitions. Can't do scans on modules in different partitions (ever?)")
03954 << ENDM;
03955 }
03956 return false;
03957 }
03958
03959
03960 if(newCrate != firstCrate) {
03961 cout << "Can't do scans on modules in different crates (yet)\n";
03962 if(mrs) {
03963 *mrs << "SCAN_MISMATCH" << MRS_ERROR
03964 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
03965 << MRS_TEXT("Crate mismatch, can't do scans on modules in different crates (yet)")
03966 << ENDM;
03967 }
03968 return false;
03969 }
03970
03971 ABCDModule *config = lookupConfig(currMid);
03972
03973 if(!config) {
03974 cout << "Trying to do a scan on a module with no configuration FAILED!\n";
03975 if(mrs) {
03976 *mrs << "SCAN_NOCONFIG" << MRS_ERROR
03977 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
03978 << MRS_TEXT("Trying to do a scan on a module with no configuration FAILED!")
03979 << ENDM;
03980 }
03981 return false;
03982 }
03983
03984
03985 if(config->select) {
03986
03987 try {
03988 unsigned int rpartition, rcrate, rrod, rchannel;
03989 getrpcrc(currMid, rpartition, rcrate, rrod, rchannel);
03990
03991 if(newPartition != rpartition || newCrate != rcrate || newRod != rrod) {
03992 cout << "Can't do redundant stuff on split RODs at the moment, SCAN CANCELLED\n";
03993 return false;
03994 }
03995 } catch(ConfigurationException &c) {
03996 cout << "No mapping to redundant channel for module with select, SCAN CANCELLED\n";
03997 return false;
03998 }
03999 }
04000 }
04001
04002 return true;
04003 }
04004
04005 bool SctApi::preScanHardwareCheck(const Scan& scan, ScanEx& extra) {
04006 std::cout << "preScanHardwareCheck started at TIME " << boost::posix_time::second_clock::universal_time() << std::endl;
04007
04008 for(ScanEx::RodInfoMap::const_iterator ri = extra.rodInfo.begin();
04009 ri != extra.rodInfo.end();
04010 ri++) {
04011 const RodLabel rod = ri->first;
04012 for(int i=0; i<4; i++) {
04013 if(ri->second.bitFieldDSP & (1<<i)
04014 && getCrate()
04015 && !getCrate()->slavePresent(rod.rod, i)) {
04016 cout << "***** A slave DSP necessary for the requested scan was not initialised\n";
04017 cout << "***** please check the configuration and the Slave Image files\n";
04018 if(mrs) {
04019 *mrs << MRS_ERROR
04020 << "SCAN_NODSP"
04021 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
04022 << MRS_PARAM<int>("slavesNeeded", ri->second.bitFieldDSP)
04023 << MRS_PARAM<int>("slaveNotStarted", i)
04024 << MRS_TEXT("Required DSPs not initialised for the requested scan")
04025 << ENDM;
04026 }
04027 return false;
04028 }
04029 }
04030
04031
04032 if(!getCrate()->checkBOCLasersOn(rod.rod)) {
04033 if(!scan.getOption(Scan::DEBUG)) {
04034 cout << "Trying to do scan using BOC that has its lasers cut out (aborting)\n";
04035 if(mrs) {
04036 *mrs << "BOC_INTERLOCKED" << MRS_ERROR << MRS_QUALIF("SCTAPI")
04037 << MRS_PARAM<int>("crate", rod.crate)
04038 << MRS_PARAM<int>("rod", rod.rod)
04039 << MRS_TEXT("Scan aborting (BOC interlocked)") << ENDM;
04040 }
04041
04042 return false;
04043 } else {
04044 cout << "Trying to do scan using BOC that has its lasers cut out (continuing for debug)\n";
04045 }
04046 }
04047 }
04048 if(!checkAllModulesProbe("E")) {
04049 #warning "Possibly disable the ones that aren't returning events? (with warnings!)"
04050 if(!scan.getOption(Scan::DEBUG)) {
04051 cout << "Check all modules in scan are returning events! (aborting)\n";
04052 if(mrs) {
04053 *mrs << "SCAN_ABORTED" << MRS_ERROR << MRS_QUALIF("SCTAPI")
04054 << MRS_TEXT("Scan aborting (Modules not returning events)")
04055 << MRS_PARAM<const char*>("ucid",static_cast<string>(ucid()).c_str()) << ENDM;
04056 }
04057 return false;
04058 } else {
04059 cout << "All modules in scan are not returning events! (continuing for DEBUG)\n";
04060 if(mrs) {
04061 *mrs << "SCAN_WARNING" << MRS_WARNING << MRS_QUALIF("SCTAPI")
04062 << MRS_TEXT("Modules not all returning events (Scan continuing anyway (DEBUG))")
04063 << MRS_PARAM<const char*>("ucid",static_cast<string>(ucid()).c_str()) << ENDM;
04064 }
04065 }
04066 }
04067
04068 return true;
04069 }
04070
04071
04072
04073
04074
04075 void SctApi::preScanModuleSetup(const Scan &scan) {
04076 std::cout << "preScanModuleSetup started at TIME " << boost::posix_time::second_clock::universal_time() << std::endl;
04077 {
04078 std::list<BankType> banks;
04079 banks.push_back(SCTAPI_BANK_SCAN);
04080 setABCDModules(banks);
04081 cout << "Configuration for all modules has been uploaded to SCAN at TIME " << boost::posix_time::second_clock::universal_time() << std::endl;
04082 }
04083
04084 cout << "Do ROD configuration (masks etc)\n";
04085 calib_init();
04086
04087 if(checkDebugOption(DEBUG_PRINT_CALIB)) {
04088 UINT32 mid = moduleMap.begin()->first;
04089 unsigned int partition, crate, rod, channel;
04090 getpcrc(mid, partition, crate, rod, channel);
04091
04092 print_calib(rod);
04093 }
04094
04095 std::cout << "send all modules at TIME " << second_clock::universal_time() << std::endl;
04096 sendAllABCDModules(SCTAPI_BANK_SCAN);
04097
04098 cout << "Module Configurations for scan uploaded to RODs at time " << second_clock::universal_time() << std::endl;
04099
04100 PrimBuilder &builder = PrimBuilder::instance();
04101
04102
04103 shared_ptr<PrimListWrapper> expandFormatList(new PrimListWrapper(1));
04104 for(int i=0; i<8; i++) {
04105 if(scan.getOption(Scan::FULL)) {
04106 builder.writeRegister(expandFormatList, FMT_EXP_MODE_EN(i), 0, 12, 0xfff);
04107 } else {
04108 builder.writeRegister(expandFormatList, FMT_EXP_MODE_EN(i), 0, 12, 0x0);
04109 }
04110 }
04111
04112 if(synchSendPrimListAll(expandFormatList) != 0) {
04113 cout << "Expand mode list failed!\n";
04114 }
04115
04116 if(scan.getOption(Scan::FULL)) {
04117 cout << "Formatters set for expanded mode\n";
04118 } else {
04119 cout << "Formatters set for condensed mode\n";
04120 }
04121
04122
04123 if(scan.getScanVariable1() == ST_TOKEN
04124 || scan.getScanVariable1() == ST_BYPASS) {
04125 PrimBuilder &builder = PrimBuilder::instance();
04126
04127 shared_ptr<PrimListWrapper> chipSeqList(new PrimListWrapper(1));
04128 for(int i=0; i<48; i++) {
04129 builder.writeRegister(chipSeqList, Utility::EfbErrorMask(0, i), 10, 1, 1);
04130 builder.writeRegister(chipSeqList, Utility::EfbErrorMask(1, i), 10, 1, 1);
04131 }
04132
04133 if(synchSendPrimListAll(chipSeqList) != 0) {
04134 cout << "Chip sequence error list failed!\n";
04135 }
04136
04137 cout << "EFB chip sequence detection turned off\n";
04138 }
04139
04140
04141 {
04142 Trigger::RODTriggers points = scan.getTrigger1()->getRODTriggers();
04143
04144 int triggerCount = 0;
04145
04146 for(unsigned int i=0; i<points.size(); i++) {
04147
04148 if(points[i].first == L1_TRIGGER) {
04149 triggerCount++;
04150 }
04151 }
04152
04153
04154 if(triggerCount > 1 && scan.getOption(Scan::DISTSLAVE) < 3) {
04155 shared_ptr<PrimListWrapper> dblTrigFixList(new PrimListWrapper(1));
04156
04157
04158 for(int f=0; f<48; f++) {
04159
04160 builder.writeRegister(dblTrigFixList, Utility::EfbErrorMask(0, f), 5, 1, 1);
04161 builder.writeRegister(dblTrigFixList, Utility::EfbErrorMask(1, f), 5, 1, 1);
04162
04163
04164 builder.writeRegister(dblTrigFixList, Utility::EfbErrorMask(0, f), 6, 1, 1);
04165 builder.writeRegister(dblTrigFixList, Utility::EfbErrorMask(1, f), 6, 1, 1);
04166 }
04167
04168 if(synchSendPrimListAll(dblTrigFixList)) {
04169 cout << "Double trigger BC check list failed!\n";
04170 }
04171 cout << "L1 and BCID checks masked for double triggers\n";
04172 }
04173 }
04174
04175 cout << "Done module set-up at time " << second_clock::universal_time() << std::endl;;
04176
04177 if(checkDebugOption(DEBUG_PRINT_CALIB)) {
04178
04179 UINT32 mid = moduleMap.begin()->first;
04180 unsigned int partition, crate, rod, channel;
04181 getpcrc(mid, partition, crate, rod, channel);
04182
04183 print_calib(rod);
04184 }
04185 }
04186
04187 void SctApi::resumePolling() {
04188 getCrate()->resumePolling();
04189 }
04190
04191 void SctApi::stopPolling() {
04192 getCrate()->stopPolling();
04193 }
04194
04195 SctApiDDC * SctApi::getSctApiDDC() const {
04196 return m_sctApiDDC.get();
04197 }
04198
04199 }
04200
04201
04208 static void handle_unexpected(void) {
04209 cerr << "Unexpected exception thrown in unknown place\n";
04210
04211 try {
04212 throw;
04213 } catch (RodException &r) {
04214 cerr << "Rod Exception\n";
04215 cerr << r.getDescriptor() << ", " << r.getData1() << ", " << r.getData2() << endl;
04216 } catch (NoImageFile &f) {
04217 cerr << "No image file exception " << f.getFileName() << endl;
04218 } catch (VmeException &v) {
04219 SctApi::Utility::decodeVme(v);
04220 } catch (HpiException &h) {
04221 cerr << "HpiException:\n";
04222 hex(cerr);
04223 cerr << h.getDescriptor() << '\n';
04224 cerr << "calcAddr: " << h.getCalcAddr() << ", readAddr: " <<
04225 h.getReadAddr() << '\n';
04226 dec(cerr);
04227 } catch (PrimListException &p) {
04228 cerr << "Primlist Exception:\n";
04229 cerr << p.getDescriptor() << " " << p.getData1() << ", " << p.getData2() << endl;
04230 } catch(std::exception &e) {
04231 cerr << "std::exception with what: " << e.what() << endl;
04232 } catch(...) {
04233 cerr << "Unknown exception type\n";
04234 }
04235
04236
04237 exit(1);
04238
04239
04240
04241
04242 }
04243
04244 #if 0
04245
04246 void buildChannelMasks() {
04247 UINT32 txchannels[2];
04248 UINT32 rxchannels[4];
04249
04250 txchannels[0] = 0;
04251 txchannels[1] = 0;
04252 rxchannels[0] = 0;
04253 rxchannels[1] = 0;
04254 rxchannels[2] = 0;
04255 rxchannels[3] = 0;
04256
04257
04258 for(map<UINT32, ABCDModule>::const_iterator mi = moduleMap.begin();
04259 mi!=moduleMap.end();
04260 mi ++) {
04261 UINT32 currMid = mi->first;
04262
04263 cout << "Set up module " << currMid << endl;
04264
04265 unsigned int newPartition, newCrate, newRod;
04266
04267 #warning "How is off-ROD redundancy handled?... (old calib_init)"
04268
04269 unsigned int rcvChannel, sndChannel;
04270 getpcrc(currMid, newPartition, newCrate, newRod, rcvChannel);
04271
04272 if(lookupConfig(currMid)->select == 1) {
04273 try {
04274 unsigned int redPartition, redCrate, redRod;
04275 getrpcrc(currMid, redPartition, redCrate, redRod, sndChannel);
04276 #warning "Check same ROD? (old calib_init)"
04277 } catch(ConfigurationException &c) {
04278 sndChannel = rcvChannel;
04279 }
04280 } else {
04281 sndChannel = rcvChannel;
04282 }
04283
04284 char *mappings = config->getFibreMappings(newPartition, newCrate, newRod);
04285
04286 int txChannel = mappings[sndChannel * 3 + 0];
04287 int rx0Channel = mappings[rcvChannel * 3 + 1];
04288 int rx1Channel = mappings[rcvChannel * 3 + 2];
04289
04290 int txi, txval, rx0i, rx0val, rx1i, rx1val;
04291
04292 if(txChannel<32) { txi = 0; txval = 1<<txChannel; }
04293 else { txi = 1; txval = 1<<(txChannel-32); }
04294
04295 if(rx0Channel<32) { rx0i = 0; rx0val = 1<<rx0Channel; }
04296 else if(rx0Channel<64) { rx0i = 1; rx0val = 1<<(rx0Channel-32); }
04297 else if(rx0Channel<96) { rx0i = 2; rx0val = 1<<(rx0Channel-64); }
04298 else { rx0i = 3; rx0val = 1<<(rx0Channel-96); }
04299
04300 if(rx1Channel<16) { rx1i = 0; rx1val = 1<<rx1Channel; }
04301 else if(rx1Channel<32) { rx1i = 1; rx1val = 1<<(rx1Channel-32); }
04302 else if(rx1Channel<64) { rx1i = 2; rx1val = 1<<(rx1Channel-64); }
04303 else { rx1i = 3; rx1val = 1<<(rx1Channel-96); }
04304
04305 if(txchannels[txi] & txval) {
04306 cout << "Module already using this channel in this group\n";
04307 } else {
04308 txchannels[txi] |= txval;
04309 }
04310
04311 if(rxchannels[rx0i] & rx0val) {
04312 cout << "Module already using this channel in this group\n";
04313 } else {
04314 rxchannels[rx0i] |= rx0val;
04315 }
04316
04317 if(rxchannels[rx1i] & rx1val) {
04318 cout << "Module already using this channel in this group\n";
04319 } else {
04320 rxchannels[rx1i] |= rx1val;
04321 }
04322
04323 delete [] mappings;
04324 }
04325
04326 cout << "Calculated channel masks:\n";
04327 cout << hex;
04328 cout << "tx: 0x" << txchannels[0] << " 0x" << txchannels[1] << endl;
04329 cout << "rx: 0x" << rxchannels[0] << " 0x" << rxchannels[1] << " 0x" << rxchannels[2] << " 0x" << rxchannels[3] << endl;
04330 cout << dec;
04331 }
04332
04333 #endif