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