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