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