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