00001
00009 #include "SctApi.h"
00010 #include "SctApiConsts.h"
00011 #include "SctApiDebug.h"
00012 #include "SctApiHisto.h"
00013 #include "crate.h"
00014 #include "primListWrapper.h"
00015 #include "PrimBuilder.h"
00016 #include "ConfigurationUtility.h"
00017
00018 #include "RodCrate/RodModule.h"
00019
00020 #include "CommonWithDsp/primParams.h"
00021 #include "CommonWithDsp/registerIndices.h"
00022
00023 #include "ABCD/ABCDscans.h"
00024 #include "ABCD/ABCDchip.h"
00025
00026 #include "ScanResultWriter/scan.h"
00027 #include "utility.h"
00028
00029 #include "VmeDecode.h"
00030
00031 #ifdef USE_IS
00032 #include "Sct/IoExceptions.h"
00033 #include "ScanResultWriter/ScanResultWriter.h"
00034 #endif
00035 #include "Sct/SctNames.h"
00036
00037 #include "Scan.h"
00038 #include "Trigger.h"
00039 #include "SctApiException.h"
00040
00041 #include <boost/date_time/posix_time/posix_time.hpp>
00042 #include <boost/lexical_cast.hpp>
00043 #include <boost/timer.hpp>
00044
00045 #include <algorithm>
00046
00047 #include "Sct/MultiMessageDebugStream.h"
00048 #include "Idiosyncrasy.h"
00049
00050 using namespace std;
00051 using namespace Sct;
00052 using namespace SctPixelRod;
00053 using namespace boost::posix_time;
00054 using boost::shared_ptr;
00055
00056 namespace SctApi {
00057 void SctApi::doScan(boost::shared_ptr<Scan> scan) {
00058 boost::timer timer;
00059 {
00060 boost::mutex::scoped_lock lock(log().mutex());
00061 log() << "doScan - timer started\n";
00062 }
00063
00064 scan->setStartTime(second_clock::universal_time());
00065
00066
00067 boost::shared_ptr<ScanEx> extra(new ScanEx);
00068 extra->diagnosticReg = 0;
00069
00070 extra->trimScan = 0;
00071 if(scan->getScanVariable1() == ST_TRIM) {
00072
00073 extra->trimScan = 1;
00074 }
00075
00076 cout << "Do scan " << scanNumber << ":\n";
00077 scan->setRunNumber(runNumber);
00078 scan->setScanNumber(scanNumber);
00079
00080
00081 if(scan->getOption(Scan::FULL)) {
00082
00083 scanNumber += 3;
00084 } else {
00085 scanNumber += 1;
00086 }
00087
00088 if(mrs) {
00089 *mrs << "SCAN_REQUESTED" << MRS_INFORMATION
00090 << MRS_PARAM<int>("run", runNumber) << MRS_PARAM<int>("scan", scan->getScanNumber()) << MRS_TEXT("Scan requested") << ENDM;
00091 }
00092 std::cout << "about to print scan " << std::endl;
00093 scan->print();
00094 std::cout << "finished printing scan " << std::endl;
00095
00096
00097 if(scan->getScanPoints2().size() != 0 && scan->getScanPoints2().size() != scan->getScanPoints1().size()) {
00098 cout << "Can't have two different sized scan points lists!\n";
00099 if(mrs) {
00100 *mrs << "SCAN_MISMATCH" << MRS_ERROR
00101 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00102 << MRS_TEXT("doScan supplied with two different sized scan points lists!")
00103 << ENDM;
00104 }
00105 throw SctApiException("Invalid scan. Scan points mismatch");
00106 }
00107
00108 if(!checkModuleListsForScan()) {
00109 throw SctApiException("Invalid scan. Module lists check failed");
00110 }
00111
00112 std::cout << "setting up scan masks" << std::endl;
00113 setupScanMasks(*extra, scan->getOption(Scan::DISTSLAVE), scan->getScanPoints2().size() != 0);
00114 std::cout << "Done" << std::endl;
00115
00116 RodLabel zeroRod = extra->rodInfo.begin()->first;
00117
00118
00119 for(unsigned int i = 0;
00120 i<extra->groupLists.size();
00121 i++) {
00122 scan->setModuleList(i, extra->groupLists[i]);
00123 }
00124 scan->setNGroups(extra->groupLists.size());
00125
00126
00127 if(checkDebugOption(DEBUG_DIAG)) {
00128 RodScanEx &rodInfo = extra->rodInfo.find(zeroRod)->second;
00129 cout << hex << "Channels in use: 0x" << rodInfo.channels.mask0 << " 0x" << rodInfo.channels.mask1 << dec << endl;
00130
00131 for(int i=0; i<numSlaves * 2; i++) {
00132 cout << hex << "Group channels: 0x" << rodInfo.groupChannels[i].mask0 << " 0x" << rodInfo.groupChannels[i].mask1 << dec << endl;
00133 }
00134
00135 for(int i=0; i<numSlaves; i++) {
00136 cout << hex << "Slave channels: 0x" << rodInfo.slaveChannels[i].mask0 << " 0x" << rodInfo.slaveChannels[i].mask1 << dec << endl;
00137 }
00138
00139 cout << "Slave DSP bit-field: " << hex << (int)rodInfo.bitFieldDSP << dec << " nSlaves: " << rodInfo.slaves << endl;
00140
00141 hex(cout);
00142 for(int i=0; i<numSlaves; i++) {
00143 cout << "Groups on DSP " << i << ": 0x" << (int)extra->groupDspMap[i] << endl;
00144 }
00145
00146 for(int i=0; i<2; i++) {
00147 cout << "Groups to serial port " << i << ": 0x" << (int)extra->groupSpMap[i] << endl;
00148 }
00149
00150 for(int i=0; i<2; i++) {
00151 cout << "Groups using range list " << i << ": 0x" << (int)extra->groupRangeMap[i] << endl;
00152 }
00153 dec(cout);
00154 }
00155
00156 for(ScanEx::RodInfoMap::const_iterator ri = extra->rodInfo.begin();
00157 ri != extra->rodInfo.end();
00158 ri++) {
00159 if(ri->second.bitFieldDSP & 0xf == 0) {
00160 #warning "Should only abort if no slaves on all RODs?"
00161 cout << "No slaves have been deemed involved in histogramming aborting\n";
00162 if(mrs) {
00163 *mrs << MRS_ERROR
00164 << "SCAN_NODSP"
00165 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00166 << MRS_TEXT("No DSP matched to modules for scan")
00167 << MRS_PARAM<int>("partition", ri->first.partition)
00168 << MRS_PARAM<int>("crate", ri->first.crate)
00169 << MRS_PARAM<int>("rod", ri->first.rod)
00170 << ENDM;
00171 }
00172
00173 throw SctApiException("Invalid scan. A ROD doesn't have any modules attached");
00174 }
00175 }
00176 std::cout << "pre scan hardware check, time = " << timer.elapsed() << std::endl;
00177 if (!preScanHardwareCheck(*scan.get(), *extra)) throw SctApiException("Pre scan hardware check failed");
00178 std::cout << "done" << std::endl;
00179
00180 std::cout << "pre scan module setup, time = " << timer.elapsed() << std::endl;
00181 preScanModuleSetup(*scan.get());
00182 std::cout << "done" << std::endl;
00183
00184 {
00185
00186 Trigger::RODTriggers points = scan->getTrigger1()->getRODTriggers();
00187
00188 for(unsigned int i=0; i<points.size(); i++) {
00189 if(points[i].first == SOFT_RESET) {
00190 cout << "Do extra soft reset before trigger to mask soft reset in trigger\n";
00191 extra->diagnosticReg |= 1 << DR_SOFT_BC_RESET;
00192 }
00193 }
00194 }
00195
00196 bool setupGood = true;
00197
00198 try {
00199 cout << "Setup histogramming tasks ..., time = " << timer.elapsed() << std::endl;
00200 doHistogramSetup(*scan.get(), *extra);
00201 cout << " ... done setup histogramming tasks, time = " << timer.elapsed() << std::endl;
00202 } catch(SctApiException &s) {
00203 setupGood = false;
00204 }
00205
00206
00207 if(mrs) {
00208 *mrs << "SCAN_STARTED" << MRS_INFORMATION
00209 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
00210 << MRS_TEXT("Scan started")
00211 << MRS_PARAM<int>("ScanNumber", scan->getScanNumber())
00212 << MRS_PARAM<int>("ScanType1", scan->getScanVariable1())
00213 << MRS_PARAM<int>("ScanType2", scan->getScanVariable2())
00214 << ENDM;
00215 }
00216
00217 try {
00218 if(setupGood) {
00219
00220 if(scan->getOption(Scan::TIM)) {
00221 scanController.reset(new ScanControlTIMHisto(*this, scan, extra));
00222 } else {
00223 scanController.reset(new ScanControlRODHisto(*this, scan, extra));
00224 }
00225
00226 cout << "Starting histogramming ...\n";
00227 scanController->startHistogramming();
00228 cout << " ... histogramming started\n";
00229 }
00230 } catch(SctApiException &s) {
00231 setupGood = false;
00232 }
00233 std::cout << "Start polling thread time = " << timer.elapsed() << std::endl;
00234 #ifndef USE_SCAN_THREAD
00235 if(setupGood) {
00236
00237 scanLoop();
00238 }
00239 #endif
00240 }
00241
00242 void SctApi::awaitScan() {
00243 while((scanController || m_inScanLoop) || m_inRawScanLoop) {
00244 sleep(1);
00245 }
00246 }
00247
00248
00249 void SctApi::scanLoop() {
00250
00251 m_inScanLoop = true;
00252
00253 boost::shared_ptr<ScanControl> control;
00254
00255 swap(control, scanController);
00256
00257
00258 lastScanController = control;
00259
00260 if(!control) {
00261 cout << "Given null scan aborting!\n";
00262 return;
00263 }
00264
00265 control->initialisePolling();
00266
00267 int pollReturn = pollHistogramming(control, 3);
00268
00269 cout << "pollHistogramming complete (" << pollReturn << ")\n";
00270
00271 control->finishHistogram(pollReturn == 0);
00272
00273
00274 m_inScanLoop = false;
00275 }
00276
00277 void SctApi::scanPollingThread() {
00278 cout << "SCAN: Start polling thread\n";
00279
00280 while(!m_stopPolling) {
00281 sleep(1);
00282 if(scanController) {
00283 scanLoop();
00284 }
00285 }
00286 }
00287
00288 void SctApi::setupEventTrapping(const Scan &scan, const ScanEx &ex, const RodLabel rod, boost::shared_ptr<PrimListWrapper> primList) {
00289 const RodScanEx &rodInfo = ex.getRodScanInfo(rod);
00290
00291
00292 for(int slaveNumber=0; slaveNumber<numSlaves; slaveNumber++) {
00293 if((rodInfo.bitFieldDSP & (1<<slaveNumber)) && getCrate()->slavePresent(rod.rod, slaveNumber)) {
00294 int match;
00295 int modulus;
00296 int remainder;
00297
00298 switch(scan.getOption(Scan::DISTSLAVE)) {
00299 case 0:
00300
00301 match = 0;
00302 modulus = 1;
00303 remainder = 0;
00304
00305 if(scan.getOption(Scan::NTH) > 1) {
00306
00307 modulus = scan.getOption(Scan::NTH);
00308 remainder = scan.getOption(Scan::NTH_REM);
00309 }
00310 break;
00311 case 1:
00312
00313 match = slaveNumber;
00314 modulus = 1;
00315 remainder = 0;
00316 break;
00317 case 2:
00318
00319 match = 0;
00320 modulus = rodInfo.slaves;
00321 remainder = slaveNumber;
00322
00323 if(scan.getOption(Scan::NTH) > 1) {
00324 modulus = rodInfo.slaves * scan.getOption(Scan::NTH);
00325 remainder = slaveNumber * scan.getOption(Scan::NTH) + scan.getOption(Scan::NTH_REM);
00326 }
00327 break;
00328 default:
00329 match = 0;
00330 modulus = 1;
00331 remainder = 0;
00332 break;
00333 }
00334
00335 eventTrapSetup(0x1 << slaveNumber,
00336 match, modulus, remainder,
00337 scan.getOption(Scan::TIM), checkDebugOption(DEBUG_SCAN_ERROR_TRAP_ALL), primList);
00338 }
00339 }
00340 }
00341
00342 void SctApi::setupEventDump(const Scan &scan, const ScanEx &ex, const RodLabel rod, boost::shared_ptr<PrimListWrapper> primList) {
00343 if(!(checkDebugOption(DEBUG_SCAN_ERROR_TRAP) && scan.getOption(Scan::DEBUG))) return;
00344
00345 int slaveNumber = 2;
00346
00347
00348 {
00349
00350 long *evData = new long[sizeof(EVENT_TRAP_SETUP_IN)/4];
00351
00352 EVENT_TRAP_SETUP_IN &primData = *(EVENT_TRAP_SETUP_IN*)evData;
00353
00354 #if R_EVENT_TRAP_SETUP == 103
00355 primData.slvBits = 0x1 << slaveNumber;
00356 primData.numberOfEvents = COLLECT_FOREVER;
00357 primData.timeoutInUsec = 0x30000;
00358
00359 primData.extRouterSetup = 0;
00360
00361
00362
00363 primData.distribute = TRAP_DISTRIB_NEITHER;
00364
00365 primData.releaseFrames = 0;
00366 primData.permitBackPressure = 1;
00367 primData.dataMode = 0;
00368 primData.sLink = 0;
00369
00370 primData.format = TRAP_FMT_ERROR;
00371 primData.trapStray = 1;
00372 primData.iterLimit = 2;
00373
00374
00375 primData.trapConfig[0] = TRAP_CFG_ROD_EVT;
00376 primData.trapExclusionFlag[0] = 0;
00377 primData.trapFunction[0] = TRAP_FXN_RESYNCH;
00378
00379 primData.trapMatch[0] = 0;
00380 primData.trapModulus[0] = 1;
00381 primData.trapRemainder[0] = 0;
00382
00383
00384 primData.trapConfig[1] = TRAP_CFG_IDLE;
00385 primData.trapExclusionFlag[1] = 0;
00386 primData.trapFunction[1] = 0;
00387
00388 primData.trapMatch[1] = 0;
00389 primData.trapModulus[1] = 0;
00390 primData.trapRemainder[1] = 0;
00391 #else
00392 #error "Event trapping not compiled (new Primitive definition)!"
00393 #endif
00394 primList->addPrimitive(RodPrimitive(sizeof(EVENT_TRAP_SETUP_IN)/sizeof(UINT32) + 4,
00395 0, EVENT_TRAP_SETUP, R_EVENT_TRAP_SETUP, evData),
00396 evData);
00397 }
00398
00399
00400 startEventTrap(slaveNumber, primList);
00401
00402
00403 {
00404 long *taskData = new long[sizeof(START_TASK_IN)/4];
00405
00406 for(unsigned int i=0; i<sizeof(START_TASK_IN)/4; i++) {
00407 taskData[i] = 0;
00408 }
00409
00410 START_TASK_IN &taskPrim = *(START_TASK_IN *)taskData;
00411
00412 taskPrim.taskType = RESYNCH_TASK;
00413 taskPrim.taskRevision = R_RESYNCH_TASK;
00414 taskPrim.priority = 1;
00415 taskPrim.completionFlag = 1;
00416
00417 RESYNCH_TASK_IN &resynch = taskPrim.taskStruct.resynchTaskIn;
00418
00419 resynch.errorType = 0;
00420
00421 shared_ptr<PrimListWrapper> myList(new PrimListWrapper(4));
00422
00423 myList->addPrimitive(RodPrimitive(4 + sizeof(START_TASK_IN)/4,
00424 3, START_TASK, R_START_TASK, taskData),
00425 taskData);
00426
00427 PrimBuilder::instance().slavePrimList(primList, myList, slaveNumber, true, true);
00428 }
00429 }
00430
00431 void SctApi::startEventTrapping(const Scan &scan, const ScanEx &ex, const RodLabel rod, shared_ptr<PrimListWrapper> primList) {
00432 const RodScanEx &rodInfo = ex.getRodScanInfo(rod);
00433
00434 for(int slaveNumber=0; slaveNumber<numSlaves; slaveNumber++) {
00435 if((rodInfo.bitFieldDSP & (1<<slaveNumber)) && getCrate()->slavePresent(rod.rod, slaveNumber)) {
00436 startEventTrap(slaveNumber, primList);
00437 }
00438 }
00439 }
00440
00441 void SctApi::setupHistogramming(const Scan &scan, const ScanEx &ex, const RodLabel rod, bool tim,
00442 boost::shared_ptr<PrimListWrapper> primList) {
00443 const RodScanEx &rodInfo = ex.getRodScanInfo(rod);
00444
00445 int nBins = scan.getScanPoints1().size();
00446 if(!scan.getOption(Scan::BITS32)) {
00447 if(nBins%2 == 1) {
00448 nBins += 1;
00449 }
00450 }
00451
00452 for(int slaveNumber = 0; slaveNumber < 4; slaveNumber ++) {
00453 if((rodInfo.bitFieldDSP & (1<<slaveNumber)) && getCrate()->slavePresent(rod.rod, slaveNumber)) {
00454
00455 long *histoData = new long[sizeof(HISTOGRAM_SETUP_IN)/4];
00456
00457 HISTOGRAM_SETUP_IN &primData = *(HISTOGRAM_SETUP_IN*)histoData;
00458
00459 #if (R_HISTOGRAM_SETUP == 108)
00460 primData.base = (UINT32 *)0xffffffff;
00461 primData.nBins = nBins;
00462
00463 primData.dataType[0] = scan.getScanVariable1();
00464 primData.dataType[1] = scan.getScanVariable2();
00465
00466 primData.binSize = scan.getOption(Scan::BITS32)?HISTOGRAM_32BIT:HISTOGRAM_16BIT;
00467
00468 if(checkDebugOption(DEBUG_SCAN_USE_ASSEMBLER)) {
00469 primData.routineType = HISTO_ROUTINE_ASM;
00470 } else {
00471 primData.routineType = HISTO_ROUTINE_C;
00472 }
00473
00474
00475 primData.opt[0] = 0;
00476
00477 primData.opt[1] = scan.getOption(Scan::FULL)?HISTOGRAM_FULL:HISTOGRAM_CONDENSED;
00478
00479 primData.opt[2] = 0;
00480 primData.opt[3] = 0;
00481
00482 UINT8 groupMap = ex.groupDspMap[slaveNumber];
00483
00484 primData.validModules[0] = 0;
00485 primData.validModules[1] = 0;
00486
00487 primData.moduleRangeMap[0][0] = 0;
00488 primData.moduleRangeMap[0][1] = 0;
00489 primData.moduleRangeMap[1][0] = 0;
00490 primData.moduleRangeMap[1][1] = 0;
00491
00492 for(int i=0; i<8; i++) {
00493 if(groupMap & (1<<i)) {
00494 primData.validModules[0] |= rodInfo.groupChannels[i].mask0;
00495 primData.validModules[1] |= rodInfo.groupChannels[i].mask1;
00496
00497 if(ex.groupSpMap[0] & (1<<i)) {
00498 primData.moduleRangeMap[0][0] |= rodInfo.groupChannels[i].mask0;
00499 primData.moduleRangeMap[0][1] |= rodInfo.groupChannels[i].mask1;
00500 }
00501 if(ex.groupSpMap[1] & (1<<i)) {
00502 primData.moduleRangeMap[1][0] |= rodInfo.groupChannels[i].mask0;
00503 primData.moduleRangeMap[1][1] |= rodInfo.groupChannels[i].mask1;
00504 }
00505 }
00506 }
00507
00508 primData.xPtr[0] = (FLOAT32 *)0xffffffff;
00509 primData.xPtr[1] = (FLOAT32 *)0xffffffff;
00510 #elif (R_HISTOGRAM_SETUP == 105) || (R_HISTOGRAM_SETUP == 107)
00511 primData.base = (UINT32 *)0xffffffff;
00512 primData.nBins = nBins;
00513
00514 primData.padding[0] = 0;
00515 primData.padding[1] = 0;
00516
00517 primData.dataType[0] = scan.getScanVariable1();
00518 primData.dataType[1] = scan.getScanVariable2();
00519
00520 primData.binSize = scan.getOption(Scan::BITS32)?HISTOGRAM_32BIT:HISTOGRAM_16BIT;
00521
00522
00523 primData.opt[0] = HISTOGRAM_SLICE;
00524
00525 primData.opt[1] = scan.getOption(Scan::FULL)?HISTOGRAM_FULL:HISTOGRAM_CONDENSED;
00526
00527 primData.opt[2] = 0;
00528 #if(R_HISTOGRAM_SETUP == 107)
00529 primData.opt[3] = 0;
00530 #endif
00531
00532 UINT8 groupMap = ex.groupDspMap[slaveNumber];
00533
00534 primData.validModules[0] = 0;
00535 primData.validModules[1] = 0;
00536
00537 primData.moduleRangeMap[0][0] = 0;
00538 primData.moduleRangeMap[0][1] = 0;
00539 primData.moduleRangeMap[1][0] = 0;
00540 primData.moduleRangeMap[1][1] = 0;
00541
00542 for(int i=0; i<8; i++) {
00543 if(groupMap & (1<<i)) {
00544 primData.validModules[0] |= rodInfo.groupChannels[i].mask0;
00545 primData.validModules[1] |= rodInfo.groupChannels[i].mask1;
00546
00547 if(ex.groupSpMap[0] & (1<<i)) {
00548 primData.moduleRangeMap[0][0] |= rodInfo.groupChannels[i].mask0;
00549 primData.moduleRangeMap[0][1] |= rodInfo.groupChannels[i].mask1;
00550 }
00551 if(ex.groupSpMap[1] & (1<<i)) {
00552 primData.moduleRangeMap[1][0] |= rodInfo.groupChannels[i].mask0;
00553 primData.moduleRangeMap[1][1] |= rodInfo.groupChannels[i].mask1;
00554 }
00555 }
00556 }
00557
00558 primData.xPtr[0] = (FLOAT32 *)0xffffffff;
00559 primData.xPtr[1] = (FLOAT32 *)0xffffffff;
00560 #elif R_HISTOGRAM_SETUP == 104
00561 primData.base = (UINT32 *)0xffffffff;
00562 primData.rodType = ROD_TYPE_SCT;
00563 primData.nBins = nBins;
00564
00565 primData.padding[0] = 0;
00566 primData.padding[1] = 0;
00567
00568 primData.dataType[0] = scan.getScanVariable1();
00569 primData.dataType[1] = scan.getScanVariable2();
00570
00576 primData.arrangement = HISTOGRAM_SLICE;
00577 primData.dataFormat = scan.getOption(Scan::FULL)?HISTOGRAM_FULL:HISTOGRAM_CONDENSED;
00578 primData.binSize = scan.getOption(Scan::BITS32)?HISTOGRAM_32BIT:HISTOGRAM_16BIT;
00579 primData.unused = 0;
00580
00581 if(scan.getOption(Scan::DISTSLAVE) == 1) {
00582 primData.validModules[0] = rodInfo.groupChannels[slaveNumber][0];
00583 primData.validModules[1] = rodInfo.groupChannels[slaveNumber][1];
00584 primData.moduleRangeMap[0][0] = rodInfo.groupChannels[slaveNumber][0];
00585 primData.moduleRangeMap[0][1] = rodInfo.groupChannels[slaveNumber][1];
00586 } else {
00587 primData.validModules[0] = rodInfo.channels[0];
00588 primData.validModules[1] = rodInfo.channels[1];
00589 primData.moduleRangeMap[0][0] = rodInfo.channels[0];
00590 primData.moduleRangeMap[0][1] = rodInfo.channels[1];
00591 }
00592 primData.moduleRangeMap[1][0] = 0;
00593 primData.moduleRangeMap[1][1] = 0;
00594
00595 primData.xPtr[0] = (FLOAT32 *)0x3f00000;
00596 primData.xPtr[1] = (FLOAT32 *)0x3f01000;
00597 #else
00598 #error "Histogram setup not compiled (new Primitive definition)!"
00599 #endif
00600
00601 long *taskData = new long[sizeof(START_TASK_IN)/4];
00602
00603 for(unsigned int i=0; i<sizeof(START_TASK_IN)/4; i++) {
00604 taskData[i] = 0;
00605 }
00606
00607 START_TASK_IN &taskPrim = *(START_TASK_IN *)taskData;
00608
00609 taskPrim.taskType = HISTOGRAM_TASK;
00610 taskPrim.taskRevision = R_HISTOGRAM_TASK;
00611 taskPrim.priority = 1;
00612 taskPrim.completionFlag = 1;
00613
00614 HISTOGRAM_TASK_IN &histoTaskData = taskPrim.taskStruct.histogramTaskIn;
00615
00616 histoTaskData.nEvents = COLLECT_FOREVER;
00617 if(tim) {
00618 histoTaskData.controlFlag = LOCAL_SET_TRIG;
00619 } else {
00620 histoTaskData.controlFlag = MASTER_HREG;
00621 }
00622
00623 boost::shared_ptr<PrimListWrapper> myList(new PrimListWrapper(4));
00624
00625 myList->addPrimitive(RodPrimitive(4 + sizeof(HISTOGRAM_SETUP_IN)/sizeof(UINT32),
00626 2, HISTOGRAM_SETUP, R_HISTOGRAM_SETUP, histoData),
00627 histoData);
00628 myList->addPrimitive(RodPrimitive(4 + sizeof(START_TASK_IN)/4,
00629 3, START_TASK, R_START_TASK, taskData),
00630 taskData);
00631
00632 PrimBuilder::instance().slavePrimList(primList, myList, slaveNumber, true, true);
00633 }
00634 }
00635 }
00636
00637 void SctApi::startHistogramTask(const Scan &scan, const ScanEx &ex, const RodLabel rod,
00638 unsigned int startBin, unsigned int nBins, unsigned int nTrigs,
00639 boost::shared_ptr<PrimListWrapper> primList) {
00640 const RodScanEx &rodInfo = ex.getRodScanInfo(rod);
00641
00642
00643 unsigned int allBins = nBins;
00644
00645 long *ctrlData = new long[sizeof(START_TASK_IN)/4 + allBins * 2];
00646
00647 for(unsigned int i=0; i<sizeof(START_TASK_IN)/4 + allBins * 2; i++) {
00648 ctrlData[i] = 0;
00649 }
00650
00651 struct START_TASK_IN &primData = *(START_TASK_IN*)ctrlData;
00652 struct HISTOGRAM_CTRL_TASK_IN &taskData = primData.taskStruct.histoCtrlTaskIn;
00653
00654 #if (R_HISTOGRAM_CTRL_TASK == 107)
00655 primData.taskType = HISTOGRAM_CTRL_TASK;
00656 primData.taskRevision = R_HISTOGRAM_CTRL_TASK;
00657 primData.priority = 1;
00658 primData.completionFlag = 1;
00659
00660 taskData.slvBits = rodInfo.bitFieldDSP;
00661
00662 if(scan.getScanPoints2().size() > 0) {
00663 taskData.port = SP_BOTH;
00664 } else {
00665
00666
00667
00668
00669
00670 taskData.port = SP0;
00671 }
00672
00673 taskData.configRegister[0] = scan.getScanVariable1();
00674 taskData.configRegister[1] = scan.getScanVariable2();
00675
00676 taskData.configSctSet = Utility::translateBank(SCTAPI_BANK_SCAN);
00677
00678 #warning "Alan Barr (AJB) suspects that this will need to change when Dougs new configuration code arrives."
00679
00680 if(!ex.trimScan)
00681 taskData.dataSet = MODULE_BASIC;
00682 else
00683 taskData.dataSet = MODULE_TRIM;
00684
00685 taskData.groupRangeMap[0] = ex.groupRangeMap[0];
00686 taskData.groupRangeMap[1] = ex.groupRangeMap[1];
00687
00688 taskData.groupDSPMap[0] = ex.groupDspMap[0];
00689 taskData.groupDSPMap[1] = ex.groupDspMap[1];
00690 taskData.groupDSPMap[2] = ex.groupDspMap[2];
00691 taskData.groupDSPMap[3] = ex.groupDspMap[3];
00692
00693 taskData.groupSPMap[0] = ex.groupSpMap[0];
00694 taskData.groupSPMap[1] = ex.groupSpMap[1];
00695
00696 taskData.globalCtrl = 0;
00697 taskData.syncLevel = 0;
00698
00699 taskData.histoBase = (UINT32*)0xffffffff;
00700
00701 taskData.doChipOcc = 1;
00702 taskData.dataFormat = scan.getOption(Scan::FULL)?HISTOGRAM_FULL:HISTOGRAM_CONDENSED;
00703 taskData.binSize = scan.getOption(Scan::BITS32)?HISTOGRAM_32BIT:HISTOGRAM_16BIT;
00704 taskData.unused1 = 0;
00705
00706 taskData.extSetup = 0xff;
00707 taskData.dataPath = DATA_PATH_NORMAL;
00708 taskData.capture = 0;
00709 taskData.useRangeList = 0;
00710
00711 taskData.repetitions = nTrigs;
00712 taskData.nBins = nBins;
00713 taskData.bin0 = startBin;
00714
00715
00716 for(int i=0; i<5; i++) {
00717 taskData.rangeList[0].xPair[i].x0 = 0.0;
00718 taskData.rangeList[1].xPair[i].x0 = 0.0;
00719 taskData.rangeList[0].xPair[i].delta_x = 0.0;
00720 taskData.rangeList[1].xPair[i].delta_x = 0.0;
00721 }
00722
00723
00724 taskData.dataPtr[0] = (FLOAT32 *)0xffffffff;
00725 taskData.dataPtr[1] = (FLOAT32 *)0xffffffff;
00726
00727
00728 for(int i=0; i<N_CMD_LIST_CMDS; i++) {
00729 taskData.triggerSequence[0].cmd[i] = NO_CMD;
00730 taskData.triggerSequence[1].cmd[i] = NO_CMD;
00731 taskData.triggerSequence[0].data[i] = 0;
00732 taskData.triggerSequence[1].data[i] = 0;
00733 }
00734
00735
00736
00737
00738
00739
00740
00741
00742 Trigger::RODTriggers points = scan.getTrigger1()->getRODTriggers();
00743
00744 for(unsigned int i=0; i<points.size(); i++) {
00745 taskData.triggerSequence[0].cmd[i] = points[i].first;
00746 taskData.triggerSequence[0].data[i] = points[i].second;
00747 }
00748
00749 if(scan.getScanPoints2().size() > 0) {
00750 points = scan.getTrigger2()->getRODTriggers();
00751
00752 for(unsigned int i=0; i<points.size(); i++) {
00753 taskData.triggerSequence[1].cmd[i] = points[i].first;
00754 taskData.triggerSequence[1].data[i] = points[i].second;
00755 }
00756 } else {
00757
00758 }
00759
00760
00761
00762
00763
00764
00765
00766 unsigned short cmd, data;
00767
00768 scan.getTrigger1()->getCommIncr(cmd, data);
00769 taskData.incCmd[0] = cmd;
00770 taskData.incData[0] = data;
00771 scan.getTrigger2()->getCommIncr(cmd, data);
00772 taskData.incCmd[1] = cmd;
00773 taskData.incData[1] = data;
00774
00775 taskData.calLineLoop = scan.getOption(Scan::LOOPCALLINE);
00776 if(scan.getOption(Scan::DISTSLAVE) == 2) {
00777 taskData.distributionToggle = ROUTER_DISTRIB;
00778 } else {
00779 taskData.distributionToggle = MODULE_GROUP;
00780 }
00781
00782 for(int i=0; i<10; i++) {
00783 taskData.genData[i] = 0;
00784 }
00785
00786
00787 taskData.genData[0] = 0xff;
00788
00789 if(scan.getScanPoints2().size() > 0) {
00790 taskData.genData[1] = 1;
00791 taskData.genData[2] = 0x0200;
00792 }
00793
00794 #elif (R_HISTOGRAM_CTRL_TASK == 105)
00795 primData.taskType = HISTOGRAM_CTRL_TASK;
00796 primData.taskRevision = R_HISTOGRAM_CTRL_TASK;
00797 primData.priority = 0;
00798 primData.completionFlag = 1;
00799
00800 taskData.slvBits = 0xf;
00801 taskData.configSctSet = translateBank(SCTAPI_BANK_PHYSICS);
00802
00803
00804
00805 taskData.dataSet = 0;
00806 taskData.useRangeList = 0;
00807 taskData.groupRangeMap[0] = 0;
00808 taskData.groupRangeMap[1] = 0;
00809 taskData.cmdBuff = CMD_BUFFER_BOTH;
00810 taskData.dataPtr[0] = group1Data;
00811 taskData.dataPtr[1] = group2Data;
00812 taskData.repetitions = 10;
00813 taskData.nBins = 10;
00814 taskData.bin0 = 0;
00815
00816 taskData.triggerSequence[0];
00817 taskData.triggerSequence[1];
00818
00819 taskData.incCmd[0] = 0;
00820 taskData.incCmd[1] = 0;
00821 taskData.calLineLoop = 0;
00822
00823 taskData.distributionToggle = 0;
00824 taskData.incData[0] = 1;
00825 taskData.incData[1] = 1;
00826
00827 taskData.groupSPMap[0] = 0;
00828 taskData.groupSPMap[1] = 0;
00829 #else // Unknown R_HISTOGRAM_CTRL_TASK
00830 #error "Histogram Task not compiled (new Primitive definition)!"
00831 #endif
00832
00833 int offset = sizeof(START_TASK_IN)/4;
00834
00835
00836 for(unsigned int i=0; i<allBins; i++) {
00837 ctrlData[offset + i] = *(UINT32 *)&(scan.getScanPoints1()[i]);
00838 if(scan.getScanPoints2().size() == 0) {
00839 ctrlData[offset + allBins + i] = *(UINT32*)&(scan.getScanPoints1()[i]);
00840 } else {
00841 ctrlData[offset + allBins + i] = *(UINT32*)&(scan.getScanPoints2()[i]);
00842 }
00843 }
00844
00845 primList->addPrimitive(RodPrimitive(4 + sizeof(START_TASK_IN)/sizeof(UINT32) + allBins * 2,
00846 0, START_TASK, R_START_TASK, ctrlData),
00847 ctrlData);
00848 }
00849
00850
00851
00852
00853
00854
00855
00856 void SctApi::stopHistogramming(const ScanEx &ex) {
00857 for(ScanEx::RodInfoMap::const_iterator ri = ex.rodInfo.begin();
00858 ri != ex.rodInfo.end();
00859 ri++) {
00860 const RodLabel &rod = ri->first;
00861
00862 {
00863 boost::mutex::scoped_lock lock(log().mutex());
00864 log() << "Stop histogramming (controlled)\n";
00865 }
00866
00867
00868
00869
00870
00871
00872 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(2));
00873
00874 PrimBuilder &builder = PrimBuilder::instance();
00875 builder.taskOp(primList, HISTOGRAM_CTRL_TASK, TASK_STOP, 0);
00876
00877 {
00878 boost::mutex::scoped_lock lock(log().mutex());
00879 log() << "Stop histo control task\n";
00880 }
00881 sendPrimList(rod.rod, primList);
00882
00883 awaitResponse(rod.rod, 5);
00884 primList->clear();
00885
00886 cout << "Done kill control task\n";
00887
00888 for(int slaveNumber=0; slaveNumber<numSlaves; slaveNumber++) {
00889
00890 boost::shared_ptr<PrimListWrapper> slList(new PrimListWrapper(1));
00891
00892
00893
00894 builder.taskOp(slList, HISTOGRAM_TASK, TASK_STOP, 0);
00895
00896 PrimBuilder::instance().slavePrimList(primList, slList, slaveNumber, true, true);
00897 {
00898 boost::mutex::scoped_lock lock(log().mutex());
00899 log() << "Stop slave histogram task " << slaveNumber << endl;
00900 }
00901 sendPrimList(rod.rod, primList);
00902 awaitResponse(rod.rod, 5);
00903 slList->clear();
00904 primList->clear();
00905
00906 cout << "Done kill histogram task\n";
00907
00908 stopEventTrap(slaveNumber, primList);
00909
00910 {
00911 boost::mutex::scoped_lock lock(log().mutex());
00912 log() << "Stop Event trapping on slave " << slaveNumber << endl;
00913 }
00914 sendPrimList(rod.rod, primList);
00915
00916 awaitResponse(rod.rod, 5);
00917 primList->clear();
00918
00919 cout << "Done kill event trapping\n";
00920 }
00921 }
00922
00923
00924
00925 cout << "Done kill histogramming tasks\n";
00926 }
00927
00928 ScanControl::ScanControl(SctApi &api) : api(api) {}
00929
00930 void ScanControlRODHisto::readHistograms() {
00931 time_t saveTime;
00932 saveTime = time(NULL);
00933
00934
00935
00936
00937
00938 list<RodLabel> rodList = api.listRods();
00939
00940 for(list<RodLabel>::const_iterator rl = rodList.begin();
00941 rl!=rodList.end();
00942 rl++){
00943
00944 cout << "Reading out modules from ROD " << rl->rod << endl;
00945
00946
00947 for(unsigned int group = 0; group < scan->getNGroups(); group ++) {
00948 const ModuleList &groupList = scan->getModuleList(group);
00949 cout << "Modules in group " << group << " count: " << groupList.size() << endl;
00950 for(ModuleList::const_iterator mi = groupList.begin();
00951 mi!=groupList.end();
00952 mi ++) {
00953
00954 string sn = *mi;
00955 UINT32 mid = api.findModule(sn);
00956
00957 {
00958 unsigned int partition, crate, rod, channel;
00959 Utility::getpcrc(mid, partition, crate, rod, channel);
00960 if(RodLabel(partition, crate, rod) != *rl) {
00961
00962
00963 continue;
00964 }
00965 }
00966
00967 cout << "Module: " << mid << " " << sn << endl;
00968
00969 try {
00970 if(scan->getOption(Scan::FULL)) {
00971 for(int f=0; f<3; f++) {
00972 scan_result_ptrs result = readHistogramData(mid, f);
00973
00974 result.header.scanNumber += f;
00975
00976
00977 if(checkDebugOption(DEBUG_SAVE_HISTOGRAM)) {
00978 readHistogramToFile(*scan, *scanEx, mid, api.convertToString(mid), result, saveTime, f);
00979 }
00980
00981 #ifdef USE_IS
00982
00983 if(api.mrs)readHistogramToIS(*scan, *scanEx, mid, result);
00984 #endif
00985
00986 delete [] (char*)result.data;
00987 delete [] result.points;
00988 delete [] result.nEvents;
00989 delete [] result.nErrorEvents;
00990 }
00991 } else {
00992 scan_result_ptrs result = readHistogramData(mid, 0);
00993
00994 if(checkDebugOption(DEBUG_SAVE_HISTOGRAM)) {
00995 readHistogramToFile(*scan, *scanEx, mid, api.convertToString(mid), result, saveTime);
00996 }
00997 #ifdef USE_IS
00998 if(api.mrs)readHistogramToIS(*scan, *scanEx, mid, result);
00999 #endif
01000 delete [] (char*)result.data;
01001 delete [] result.points;
01002 delete [] result.nEvents;
01003 delete [] result.nErrorEvents;
01004 }
01005 } catch(SctApiException &s) {
01006 if(api.mrs) {
01007 *api.mrs << "SCAN_READOUT_FAIL" << MRS_ERROR
01008 << MRS_QUALIF("SctApi")
01009 << MRS_PARAM<int>("run", scan->getRunNumber())
01010 << MRS_PARAM<int>("scan", scan->getScanNumber())
01011 << MRS_PARAM<int>("mid", mid)
01012 << MRS_TEXT("Module readout failed") << ENDM;
01013 }
01014 }
01015 }
01016 }
01017
01018
01019 for(std::map<std::pair<RodLabel, int>,
01020 Utility::MemoryBlock> :: iterator mapIter = scanEx->histoMap.begin();
01021 mapIter != scanEx->histoMap.end();
01022 mapIter++) {
01023
01024 if(mapIter->first.first == *rl) {
01025 if(api.mrs) {
01026 *api.mrs << "SCAN_READOUT" << MRS_DIAGNOSTIC
01027 << MRS_PARAM<float>("MWords", mapIter->second.size() / 1e6)
01028 << MRS_PARAM<int>("crate", rl->crate)
01029 << MRS_PARAM<int>("rod", rl->rod)
01030 << MRS_TEXT("Releasing memory after histogram readout") << ENDM;
01031 }
01032
01033 mapIter->second = Utility::MemoryBlock();
01034 }
01035 }
01036 }
01037 }
01038
01039 scan_result_ptrs ScanControlRODHisto::readHistogramData(UINT32 mid, int frame) {
01040 scan_result_ptrs scanResult;
01041
01042
01043
01044 scanResult.data = readHistogramRawData(mid, frame);
01045
01046 int nBins = scan->getScanPoints1().size();
01047
01048
01049 api.getABCDModule(mid, SCTAPI_BANK_SCAN);
01050
01051
01052 ABCDModule moduleConfig = *api.retrieveModule(mid);
01053
01054 if(checkDebugOption(DEBUG_MODULE_CONFIG)) {
01055 cout << "Configuration after scan:\n";
01056 api.printABCDModule(mid);
01057 }
01058
01059 ScanHeader &header = scanResult.header;
01060
01061 header.version = CURRENT_SCANHEADER_VERSION;
01062 header.length = sizeof(ScanHeader);
01063 header.runNumber = scan->getRunNumber();
01064 header.scanNumber = scan->getScanNumber();
01065
01066 strncpy(header.moduleName, api.convertToString(mid).c_str(), 16);
01067 strncpy(header.startTime, to_iso_string(scan->getStartTime()).c_str(), 16);
01068 strncpy(header.endTime, to_iso_string(scan->getEndTime()).c_str(), 16);
01069 header.moduleName[15] = 0;
01070 header.startTime[15] = 0;
01071 header.endTime[15] = 0;
01072
01073
01074
01075 header.scanType = scan->getScanVariable1();
01076 header.npoints = nBins;
01077 header.size = nBins * 2 * 1024 * (scan->getOption(Scan::BITS32)?2:1);
01078 header.dataType = SR_DT_SLICE;
01079
01080 header.width = scan->getOption(Scan::BITS32)?SR_WD_32:SR_WD_16;
01081
01082 header.config = moduleConfig;
01083
01084 header.pntPoints = sizeof(ScanHeader);
01085 header.pntEvents = header.pntPoints + nBins * sizeof(FLOAT32);
01086 header.pntErrors = header.pntEvents + nBins * sizeof(UINT32);
01087 header.pntData = header.pntErrors + nBins * sizeof(UINT32);
01088
01089
01090 FLOAT32 *points = new FLOAT32[nBins];
01091 for(int i=0; i<nBins; i++) {
01092 points[i] = scan->getScanPoints1()[i];
01093 }
01094 scanResult.points = points;
01095
01096
01097 UINT32 *events = new UINT32[nBins];
01098
01099 std::pair<RodLabel, unsigned int> moduleSlave = findModuleSlave(mid);
01100
01101
01102 unsigned long *countChunk = getEventCountChunk(moduleSlave.first, moduleSlave.second);
01103
01104 for(int i=0; i<nBins; i++) {
01105 events[i] = countChunk[i];
01106
01107
01108 if(scan->getOption(Scan::LOOPCALLINE)) {
01109 events[i] >>= 2;
01110 }
01111 }
01112
01113 #if 0
01114
01115 Scan::TrigPoints trigs = scan->getVariableTrigs();
01116
01117 for(int i=0; i<nBins; i++) {
01118 if(i<lastBin[moduleSlave.first]) {
01119 events[i] = trigs[i];
01120 } else if(i == lastBin[moduleSlave.first]) {
01121 events[i] = lastEvent[moduleSlave.first];
01122 } else {
01123 events[i] = 0;
01124 }
01125 }
01126 #endif
01127
01128 scanResult.nEvents = events;
01129
01130
01131 UINT32 *errors = new UINT32[nBins];
01132 for(int i=0; i<nBins; i++) {
01133 #warning "Get real error count (if possible!)"
01134 errors[i] = 0;
01135 }
01136 scanResult.nErrorEvents = errors;
01137
01138 return scanResult;
01139 }
01140
01141 char* ScanControlRODHisto::readHistogramRawData(UINT32 mid, int frame) {
01142 int nBins = scan->getScanPoints1().size();
01143
01144
01145 int rodBins = nBins;
01146 if(!scan->getOption(Scan::BITS32))
01147 if(rodBins%2 == 1) rodBins++;
01148
01149
01150 int binSize = 0x800*(scan->getOption(Scan::BITS32)?4:2);
01151
01152 char *data = new char[nBins * binSize];
01153
01154 bool moduleBlock = false;
01155
01156
01157 unsigned int slaveNumber = 4;
01158
01159 RodLabel rodLabel;
01160 unsigned int channel;
01161 {
01162 unsigned int partition, crate, rod;
01163 Utility::getpcrc(mid, partition, crate, rod, channel);
01164 RodLabel temp(partition, crate, rod);
01165 rodLabel = temp;
01166 }
01167
01168 const RodScanEx &rodInfo = scanEx->getRodScanInfo(rodLabel);
01169
01170 for(int slave=0; slave<4; slave++) {
01171 if((channel<32 && (rodInfo.slaveChannels[slave].mask0 & 1<<channel))
01172 || (channel >= 32 && (rodInfo.slaveChannels[slave].mask1 & 1<<(channel-32)))) {
01173 if(slaveNumber == 4) {
01174 slaveNumber = slave;
01175 } else {
01176 cerr << " ****** Module found on multiple slaves this is an unsupported configuration, the first one will be downloaded??? *****\n";
01177 cerr << " ****** Well you don't expect me to add them all together do you??? *****\n";
01178 #warning "But maybe I should any way"
01179 }
01180 }
01181 }
01182
01183 if(slaveNumber == 4) {
01184 cerr << " ****** Current module not found on any slave, skipping histogram read out *****\n";
01185
01186 throw SctApiException("No mapping from module to DSP found");
01187 }
01188
01189
01190 int index = 0;
01191 int nModules = 0;
01192
01193 for(unsigned int ch=0; ch<48; ch++) {
01194 if(channel == ch) {
01195 index = nModules;
01196 }
01197 if(ch<32) {
01198 if(rodInfo.slaveChannels[slaveNumber].mask0 & 1<<ch) {
01199 nModules ++;
01200 }
01201 } else {
01202 if(rodInfo.slaveChannels[slaveNumber].mask1 & 1<<(ch-32)) {
01203 nModules ++;
01204 }
01205 }
01206 }
01207
01208
01209 unsigned long slaveOffset = 0;
01210
01211 if(moduleBlock) {
01212 slaveOffset += binSize * rodBins;
01213 } else {
01214 slaveOffset += binSize * index;
01215 }
01216
01217
01218 slaveOffset += ((binSize * rodBins * nModules) + binSize) * frame;
01219
01220 bool error = false;
01221
01222 for(int i=0; i<nBins; i++) {
01223 unsigned long *chunk = getHistogramChunk(rodLabel, slaveNumber, slaveOffset, binSize/4);
01224 unsigned long *buffer = (unsigned long *)&(data[i*binSize]);
01225
01226 if(chunk) {
01227 for(int b=0; b<binSize/4; b++) {
01228 buffer[b] = chunk[b];
01229 }
01230
01231
01232 int bin, module;
01233 int count = sscanf(&((char*)buffer)[binSize-32], "End of bin %d Module %d", &bin, &module);
01234 if(count == 2) {
01235
01236 } else {
01237 if(!error)
01238 printf("Found bad end of histogram bin (%25s)\n", &((char*)buffer)[binSize-32]);
01239 error = true;
01240 }
01241
01242 #warning "Memory leak if sendData didn't work"
01243
01244 } else {
01245 for(int b=0; b<binSize/4; b++) {
01246 buffer[b] = 0;
01247 }
01248 }
01249
01250 if(moduleBlock) {
01251 slaveOffset += binSize;
01252 } else {
01253 slaveOffset += binSize * nModules;
01254 }
01255 }
01256
01257 return data;
01258 }
01259
01260 pair<RodLabel, unsigned int> ScanControlRODHisto::findModuleSlave(unsigned int mid) {
01261 RodLabel rodLabel;
01262 unsigned int channel;
01263 {
01264 unsigned int partition, crate, rod;
01265 Utility::getpcrc(mid, partition, crate, rod, channel);
01266 RodLabel temp(partition, crate, rod);
01267 rodLabel = temp;
01268 }
01269
01270 unsigned int slaveNumber = 4;
01271
01272 const RodScanEx &rodInfo = scanEx->getRodScanInfo(rodLabel);
01273
01274 for(int slave=0; slave<4; slave++) {
01275 if((channel<32 && (rodInfo.slaveChannels[slave].mask0 & 1<<channel))
01276 || (channel >= 32 && (rodInfo.slaveChannels[slave].mask1 & 1<<(channel-32)))) {
01277 if(slaveNumber == 4) {
01278 slaveNumber = slave;
01279 } else {
01280 cerr << " ****** Module found on multiple slaves this is an unsupported configuration, the first one will be downloaded??? *****\n";
01281 cerr << " ****** Well you don't expect me to add them all together do you??? *****\n";
01282 #warning "But maybe I should any way"
01283 }
01284 }
01285 }
01286
01287 if(slaveNumber == 4) {
01288 cerr << " ****** Current module not found on any slave, skipping histogram read out *****\n";
01289
01290 throw SctApiException("No mapping from module to DSP found");
01291 }
01292
01293 return make_pair(rodLabel, slaveNumber);
01294 }
01295
01296 void readHistogramToFile(const Scan &scan, const ScanEx &ex,
01297 UINT32 mid, std::string sn, scan_result_ptrs scanData, time_t saveTime, int frame) {
01298 const int BUFF_SIZE = 50;
01299
01300 struct tm broke;
01301 broke = *(gmtime(&saveTime));
01302
01303 string tempDir = SctNames::getTempDir() + "/";
01304 int bufferLength = BUFF_SIZE + tempDir.length();
01305 char *filename = new char[bufferLength];
01306 strcpy(filename, tempDir.c_str());
01307
01308 cout << "Module: " << mid << " " << sn << endl;
01309
01310 int written = tempDir.length();
01311 if(scan.getOption(Scan::FULL)) {
01312 written += snprintf(filename + written, bufferLength - written, "Histogram%d_%s", frame, sn.c_str());
01313
01314 strftime(filename + written, bufferLength - written, "_%Y%m%d%H%M%S.bin", &broke);
01315 } else {
01316 written += snprintf(filename + written, bufferLength - written, "Histogram_%s", sn.c_str());
01317
01318 strftime(filename + written, bufferLength - written, "_%Y%m%d%H%M%S.bin", &broke);
01319 }
01320
01321 cout << "Writing histogram data to " << filename << endl;
01322
01323 saveHistogramToFile(scanData, filename);
01324
01325 cout << "done.\n";
01326
01327 delete [] filename;
01328 }
01329
01330 void saveHistogramToFile(scan_result_ptrs histo, std::string filename) {
01331 ofstream histoout(filename.c_str(), ios::binary);
01332
01333
01334 histoout.write((char*)&histo.header, histo.header.length);
01335
01336
01337 histoout.write((char*)histo.points, histo.header.pntEvents-histo.header.pntPoints);
01338
01339
01340 histoout.write((char*)histo.nEvents, histo.header.pntErrors-histo.header.pntEvents);
01341
01342
01343 histoout.write((char*)histo.nErrorEvents, histo.header.pntData-histo.header.pntErrors);
01344
01345
01346
01347
01348 histoout.write((char*)histo.data, histo.header.size*2);
01349 }
01350
01351 #ifdef USE_IS
01352
01353 void readHistogramToIS(const Scan &scan, const ScanEx &ex, UINT32 mid, scan_result_ptrs scanData) {
01354
01355
01356
01357
01358
01359 cout << "Writing histogram data to IS\n";
01360
01361
01362
01363 cout << "Module: " << mid << endl;
01364
01365 try {
01366 SctData::ScanResultWriter::publish(scanData);
01367 } catch(Sct::IoException &e) {
01368 cout << "ScanResult publish failed:\n" << e.what() << endl;
01369 e.sendToMrs(MRS_ERROR);
01370 }
01371 }
01372
01373 #endif
01374
01375 int SctApi::pollHistogramming(boost::shared_ptr<ScanControl> controller, int timeout) {
01376 int returnVal = 0;
01377
01378 bool timedout = false;
01379
01380 time_t start_time = time(0);
01381
01382 while(!timedout) {
01383 bool progressMade = false;
01384 bool newBin = false;
01385 if(controller->checkScanComplete(progressMade, newBin)) {
01386
01387 break;
01388 }
01389
01390 if(progressMade) {
01391 start_time = time(0);
01392 }
01393
01394 if(newBin) {
01395 cout << "Controller going to next bin\n";
01396
01397 controller->nextBin();
01398 } else {
01399
01400 #if USE_THREADS
01401
01402 sleep(1);
01403 #else
01404 awaitResponse(rod, 0);
01405 #endif
01406
01407 if((time(0) - start_time) > timeout) {
01408 timedout = true;
01409 returnVal = -1;
01410
01411 controller->reportTimeout();
01412 controller->reportEventErrors();
01413
01414 break;
01415 }
01416 }
01417 }
01418
01419 #if USE_IS
01420 if(m_isDict) {
01421 m_isDict->remove("SCTAPIServer.currentBin");
01422 m_isDict->remove("SCTAPIServer.maxBin");
01423 }
01424 #endif
01425
01426 return returnVal;
01427 }
01428
01429 void SctApi::doHistogramSetup(const Scan &scan, const ScanEx &extra) {
01430 for(ScanEx::RodInfoMap::const_iterator ri = extra.rodInfo.begin();
01431 ri != extra.rodInfo.end();
01432 ri++) {
01433
01434 const RodLabel &rod = ri->first;
01435
01436
01437
01438 for(int slaveNumber=0; slaveNumber<numSlaves; slaveNumber++) {
01439 if(getCrate()->slavePresent(rod.rod, slaveNumber)) {
01440 if(getCrate()->getRodRevision(rod.rod) >= 0xe) {
01441 setSlaveBlock(rod.rod, slaveNumber, 0x18000, 0x2000, 0);
01442 } else {
01443 setSlaveBlock(rod.rod, slaveNumber, 0x80008000, 0x2000, 0);
01444 }
01445 }
01446 }
01447
01448 cout << "Setup event trapping...\n";
01449
01450 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
01451
01452 setupEventTrapping(scan, extra, rod, primList);
01453 startEventTrapping(scan, extra, rod, primList);
01454
01455 setupEventDump(scan, extra, rod, primList);
01456
01457 if(checkDebugOption(DEBUG_EXTRA_DUMPS)) {
01458 standardRegisterDump(rod.rod);
01459
01460 sendPrimList(rod.rod, primList);
01461 awaitResponse(rod.rod, 5);
01462
01463 primList->clear();
01464 }
01465
01466 cout << "Histogramming setup...\n";
01467
01468 setupHistogramming(scan, extra, rod, scan.getOption(Scan::TIM), primList);
01469
01470
01471 sendPrimList(rod.rod, primList);
01472 }
01473
01474 for(ScanEx::RodInfoMap::const_iterator ri = extra.rodInfo.begin();
01475 ri != extra.rodInfo.end();
01476 ri++) {
01477
01478 const RodLabel &rod = ri->first;
01479 int responseCode = awaitResponse(rod.rod, 5);
01480 if(responseCode != 0) {
01481 cout << "Histogram setup list failed! (ROD " << rod.rod << ")\n";
01482 throw SctApiException("Histogram setup list failed! (ROD " + boost::lexical_cast<string>(rod.rod) + ")");
01483 }
01484 }
01485 }
01486
01487 void ScanControlRODHisto::startHistogramming() {
01488 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01489 ri != scanEx->rodInfo.end();
01490 ri++) {
01491 const RodLabel &rod = ri->first;
01492
01493
01494 if(scan->getOption(Scan::DEBUG)) {
01495 if(checkDebugOption(DEBUG_SCAN_AUTO_STALL)) {
01496 cout << "** Debug mode setting AUTO_STALL\n";
01497 scanEx->diagnosticReg |= (1<<DR_AUTO_STALL);
01498 }
01499
01500 if(checkDebugOption(DEBUG_SCAN_STEP_MODE)) {
01501 cout << "** Debug mode setting STEP_CTRL\n";
01502 scanEx->diagnosticReg |= (1<<DR_STEP_CTRL);
01503 }
01504
01505 if(checkDebugOption(DEBUG_SCAN_PAUSE_PULSE)) {
01506 cout << "** Debug mode setting PAUSE_PULSE\n";
01507 scanEx->diagnosticReg |= (1<<DR_PULSE_PAUSE);
01508 }
01509 }
01510
01511 if(checkDebugOption(DEBUG_SCAN_ROD_MODE_BITS)) {
01512 cout << "Setting up to use ROD mode bits\n";
01513 scanEx->diagnosticReg |= (1<<DR_USE_ROD_MASK_LUT);
01514 }
01515
01516 if(scanEx->diagnosticReg != 0x0) {
01517 cout << "Writing master diag reg: 0x" << hex << scanEx->diagnosticReg << dec << endl;
01518 api.dspSingleWrite(rod.rod, 0x80000010, scanEx->diagnosticReg, -1);
01519 } else {
01520 cout << "Clearing master diag reg\n";
01521 api.dspSingleWrite(rod.rod, 0x80000010, scanEx->diagnosticReg, -1);
01522 }
01523
01524 if(checkDebugOption(DEBUG_SCAN_USE_ASSEMBLER)) {
01525 unsigned long SDSP_IDRAM_BASE;
01526 if(api.getRodRevision(rod) >= 0xe) {
01527 SDSP_IDRAM_BASE = 0x10000;
01528 } else {
01529 SDSP_IDRAM_BASE = 0x80000000;
01530 }
01531
01532 for(int s=0; s<numSlaves; s++) {
01533 if(ri->second.bitFieldDSP & (1<<s)) {
01534 try {
01535 unsigned long val = api.dspSingleBlockRead(rod.rod,
01536 SDSP_IDRAM_BASE + 0x10, s);
01537 cout << "Read from slave " << s << " diag register: 0x" << hex << val
01538 << " which should be 0x" << (0) << dec << endl;
01539
01540
01541 unsigned long newVal = val | (1<<19);
01542 api.dspSingleBlockWrite(rod.rod, SDSP_IDRAM_BASE + 0x10, newVal, s);
01543
01544 val = api.dspSingleBlockRead(rod.rod, SDSP_IDRAM_BASE + 0x10, s);
01545 cout << "Read from slave " << s << " diag register: 0x" << hex << val
01546 << " which should be 0x" << (1<<19) << dec << endl;
01547 } catch(VmeException &v) {
01548 Utility::decodeVme(v);
01549 cerr << "VmeException turning on slave " << s << " cache\n";
01550 }
01551 }
01552 }
01553 }
01554
01555 cout << "Histogram starting...\n";
01556
01557 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
01558 api.startHistogramTask(*scan, *scanEx, rod,
01559 sectionStartBin, 1 + sectionEndBin - sectionStartBin, sectionEndTrigger,
01560 primList);
01561
01562
01563
01564
01565
01566 api.sendPrimList(rod.rod, primList);
01567 int responseCode = api.awaitResponse(rod.rod, 5);
01568
01569 if(responseCode != 0) {
01570 cout << "Histogram primitive failed! (ROD " << rod.rod << ")\n";
01571 throw SctApiException("Histogram primitive failed! (ROD " + boost::lexical_cast<string>(rod.rod) + ")");
01572 }
01573 }
01574 }
01575
01576 void SctApi::eventTrapSetup(int slaveMask, int trapMatch, int trapMod, int trapRemain, bool tim, bool error,
01577 boost::shared_ptr<PrimListWrapper> primList) {
01578 long *evData = new long[sizeof(EVENT_TRAP_SETUP_IN)/4];
01579
01580 EVENT_TRAP_SETUP_IN &primData = *(EVENT_TRAP_SETUP_IN*)evData;
01581
01582 #if R_EVENT_TRAP_SETUP == 103
01583 primData.slvBits = slaveMask;
01584 primData.numberOfEvents = COLLECT_FOREVER;
01585 primData.timeoutInUsec = 0x30000;
01586
01587 primData.extRouterSetup = 0;
01588
01589
01590
01591 primData.distribute = TRAP_DISTRIB_NEITHER;
01592
01593 primData.releaseFrames = 0;
01594 if(tim) {
01595 primData.permitBackPressure = 0;
01596 } else {
01597 primData.permitBackPressure = 1;
01598 }
01599 primData.dataMode = 0;
01600 if(tim) {
01601 primData.sLink = 1;
01602 } else {
01603 primData.sLink = 0;
01604 }
01605
01606 primData.format = error?TRAP_FMT_ERROR:TRAP_FMT_NORMAL;
01607 primData.trapStray = 1;
01608 primData.iterLimit = 2;
01609
01610 if(tim) {
01611
01612 primData.trapConfig[0] = TRAP_CFG_SLINK_EVT;
01613 } else {
01614
01615 primData.trapConfig[0] = TRAP_CFG_ROD_EVT;
01616 }
01617 primData.trapExclusionFlag[0] = 0;
01618 primData.trapFunction[0] = TRAP_FXN_HISTOGRAM;
01619
01620 primData.trapMatch[0] = trapMatch;
01621 primData.trapModulus[0] = trapMod;
01622 primData.trapRemainder[0] = trapRemain;
01623
01624
01625 primData.trapConfig[1] = TRAP_CFG_IDLE;
01626 primData.trapExclusionFlag[1] = 0;
01627 primData.trapFunction[1] = 0;
01628
01629 primData.trapMatch[1] = 0;
01630 primData.trapModulus[1] = 0;
01631 primData.trapRemainder[1] = 0;
01632 #else
01633 #error "Event trapping not compiled (new Primitive definition)!"
01634 #endif
01635 primList->addPrimitive(RodPrimitive(sizeof(EVENT_TRAP_SETUP_IN)/4 + 4,
01636 0, EVENT_TRAP_SETUP, R_EVENT_TRAP_SETUP, evData),
01637 evData);
01638 }
01639
01640 void SctApi::startEventTrap(int slaveNumber, boost::shared_ptr<PrimListWrapper> primList) {
01641 shared_ptr<PrimListWrapper> startList(new PrimListWrapper(1));
01642
01643 PrimBuilder::instance().startEvTrap(startList);
01644
01645 PrimBuilder::instance().slavePrimList(primList, startList, slaveNumber, true, true);
01646 }
01647
01648 void SctApi::stopEventTrap(int slaveNumber, boost::shared_ptr<PrimListWrapper> primList) {
01649 shared_ptr<PrimListWrapper> stopList(new PrimListWrapper(1));
01650
01651 PrimBuilder::instance().stopEvTrap(stopList);
01652
01653 PrimBuilder::instance().slavePrimList(primList, stopList, slaveNumber, true, true);
01654 }
01655
01656
01657 unsigned long *ScanControlRODHisto::getHistogramChunk(RodLabel rodLabel, int slaveNumber,
01658 unsigned long offset, unsigned long size) {
01659 try {
01660 pair<RodLabel, int> key = make_pair(rodLabel, slaveNumber);
01661
01662 Utility::MemoryBlock chunk;
01663 chunk = scanEx->histoMap[key];
01664 if(!chunk) {
01665 pair<UINT32, UINT32> chunkPos = api.sendData(rodLabel.rod, HISTOGRAM_DATA, slaveNumber);
01666
01667 cout << "SendData returned " << chunkPos.first << " " << chunkPos.second << endl;
01668 cout << " need offset " << offset << " length " << size << endl;
01669
01670 if(api.mrs) {
01671
01672 *api.mrs << "SCAN_READOUT" << MRS_DIAGNOSTIC
01673 << MRS_PARAM<float>("MWords", chunkPos.second/4e6)
01674 << MRS_PARAM<int>("crate", rodLabel.crate)
01675 << MRS_PARAM<int>("rod", rodLabel.rod)
01676 << MRS_TEXT("Scan requested histogram readout") << ENDM;
01677 }
01678
01679 unsigned long *block = api.primReadSlaveDsp(rodLabel.rod,
01680 slaveNumber, chunkPos.first, chunkPos.second/4);
01681 chunk = Utility::MemoryBlock(chunkPos.second/4, block);
01682
01683 scanEx->histoMap[key] = chunk;
01684 }
01685
01686 if((offset + size*4) > (chunk.size() * 4)) {
01687 cout << "Asked for chunk +" << offset << " length " << size << " in " << chunk.size() << "words (continuing)\n";
01688 }
01689
01690
01691 return chunk.address() + (offset / 4);
01692 } catch(SctApiException &e) {
01693 unsigned long slaveAddress;
01694
01695 if(api.getRodRevision(rodLabel) >= 0xe) {
01696 slaveAddress = 0xa00e2000;
01697 } else {
01698 slaveAddress = HISTOGRAM_DEFAULT_BASE;
01699 }
01700
01701 return api.primReadSlaveDsp(rodLabel.rod,
01702 slaveNumber, slaveAddress + offset, size);
01703 }
01704 }
01705
01706 unsigned long *ScanControlRODHisto::getEventCountChunk(RodLabel rodLabel, int slaveNumber) {
01707 try {
01708 pair<RodLabel, int> key = make_pair(rodLabel, slaveNumber);
01709
01710 Utility::MemoryBlock chunk = scanEx->evCountMap[key];
01711 if(!chunk) {
01712 pair<UINT32, UINT32> chunkPos = api.sendData(rodLabel.rod, BIN_DATA, slaveNumber);
01713
01714 cout << "SendData bin returned " << chunkPos.first << " " << chunkPos.second << endl;
01715
01716 unsigned long *block = api.primReadSlaveDsp(rodLabel.rod,
01717 slaveNumber, chunkPos.first, chunkPos.second);
01718 chunk = Utility::MemoryBlock(chunkPos.second, block);
01719
01720 scanEx->evCountMap[key] = chunk;
01721 }
01722
01723 return chunk.address();
01724 } catch(SctApiException &e) {
01725 return 0;
01726 }
01727 }
01728
01729
01730 ScanControlRODHisto::ScanControlRODHisto(SctApi &api, boost::shared_ptr<Scan> aScan, boost::shared_ptr<ScanEx> aScanEx) : ScanControl(api), scan(aScan), scanEx(aScanEx), aborting(false) {
01731 int nBins = scan->getScanPoints1().size();
01732
01733 Scan::TrigPoints trigPoints = scan->getVariableTrigs();
01734
01735 finalTrigger = trigPoints[nBins-1];
01736
01737 finalBin = nBins - 1;
01738
01739 UINT32 initialNTrigs = trigPoints[0];
01740
01741 unsigned int i = 0;
01742 while(i<trigPoints.size() && trigPoints[i] >= initialNTrigs)
01743 i++;
01744
01745
01746 sectionStartBin = 0;
01747 sectionEndBin = i - 1;
01748 if(i==trigPoints.size()) {
01749 sectionEndTrigger = scan->getVariableTrigs()[i-1];
01750 } else {
01751 sectionEndTrigger = scan->getVariableTrigs()[i-1] - scan->getVariableTrigs()[i];
01752 }
01753 cout << "Final bin = " << finalBin << " trigger = " << finalTrigger << endl;
01754
01755 cout << "Initial sectionEndBin = " << sectionEndBin << " sectionEndTrigger = " << sectionEndTrigger << endl;
01756 }
01757
01758 void ScanControlRODHisto::initialisePolling() {
01759 scanStart = time(0);
01760
01761 cout << "Histogram polling started\n";
01762
01763 sleep(1);
01764
01765 cout << "Polling histogramming task\n";
01766 cout << "scan point count " << scan->getScanPoints1().size() << endl;
01767
01768 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01769 ri != scanEx->rodInfo.end();
01770 ri++) {
01771 const RodLabel &rodLabel = ri->first;
01772
01773 if(api.mrs) {
01774 *api.mrs << "POLL_ROD" << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI")
01775 << MRS_PARAM<int>("partition", rodLabel.partition)
01776 << MRS_PARAM<int>("crate", rodLabel.crate)
01777 << MRS_PARAM<int>("rod", rodLabel.rod)
01778 << MRS_PARAM<int>("run", scan->getRunNumber())
01779 << MRS_PARAM<int>("scan", scan->getScanNumber())
01780 << MRS_PARAM<int>("firstSlave", ri->second.firstSlave)
01781 << MRS_TEXT("ROD polling started")
01782 << ENDM;
01783 }
01784 }
01785
01786 #if USE_IS
01787 if(api.m_isDict) {
01788 ISInfoInt binNumber(0);
01789 api.m_isDict->insert("SCTAPIServer.currentBin", binNumber);
01790
01791 ISInfoInt maxNumber(finalBin);
01792 api.m_isDict->insert("SCTAPIServer.maxBin", maxNumber);
01793 }
01794 #endif
01795 }
01796
01797 void ScanControlRODHisto::reportTimeout() {
01798 Sct::MultiMessageDebugStream m(true,false,true);
01799
01800 m << "You are about to get the 'Scan aborted (histogramming stalled)' "
01801 <<"message. Histogram polling timeout being reported in ["
01802 <<__FILE__<<"] at line ["<<__LINE__<<". This means that SctApi got bored waiting more than a few (search for the second argument of pollHistogramming in SctApiHisto.cxx) seconds for the results of the next bin to be sent back from the rod." ;
01803
01804 RodLabel minROD;
01805 if(scanEx->rodInfo.size() > 0) {
01806 minROD = scanEx->rodInfo.begin()->first;
01807 }
01808
01809 m << "Was expecting: finalBin=" << finalBin << ", finalTrigger=" << finalTrigger;
01810
01811
01812 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01813 ri != scanEx->rodInfo.end();
01814 ri++) {
01815 const RodLabel &rodLabel = ri->first;
01816 cout << " ROD (" << rodLabel.partition << ", " << rodLabel.crate << ", " << rodLabel.rod << "): ";
01817 cout << " Event " << lastEvent[rodLabel] << " Bin " << lastBin[rodLabel] << "\n";
01818
01819 if(lastEvent[rodLabel] < lastEvent[minROD]) {
01820 minROD = rodLabel;
01821 } else if(lastEvent[rodLabel] == lastEvent[minROD] && lastBin[rodLabel] < lastBin[minROD]) {
01822 minROD = rodLabel;
01823 }
01824 }
01825
01826
01827 m << ". Problem was perhaps localised to "
01828 << "partition " << minROD.partition
01829 << "crate" << minROD.crate
01830 << "rod" << minROD.rod
01831 << "run" << scan->getRunNumber()
01832 << "scan"<< scan->getScanNumber()
01833 << "bin"<< lastBin[minROD]
01834 << "event"<< lastEvent[minROD];
01835
01836 m.flush();
01837
01838 if(api.mrs) {
01839 *api.mrs << "SCAN_ABORTED" << MRS_ERROR
01840 << MRS_PARAM<int>("partition", minROD.partition)
01841 << MRS_PARAM<int>("crate", minROD.crate)
01842 << MRS_PARAM<int>("rod", minROD.rod)
01843 << MRS_PARAM<int>("run", scan->getRunNumber())
01844 << MRS_PARAM<int>("scan", scan->getScanNumber())
01845 << MRS_PARAM<int>("bin", lastBin[minROD]) << MRS_PARAM<int>("event", lastEvent[minROD])
01846 << MRS_TEXT("Scan aborted (histogramming stalled)") << ENDM;
01847 }
01848 }
01849
01850 void ScanControlRODHisto::nextBin() {
01851
01852 if(findNextSection()) {
01853 finalTrigger = sectionEndTrigger;
01854 finalBin = sectionEndBin;
01855 return;
01856 }
01857
01858 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01859 ri != scanEx->rodInfo.end();
01860 ri++) {
01861 const RodLabel &rod = ri->first;
01862
01863 cout << "New histogram control task...\n";
01864
01865 boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
01866 api.startHistogramTask(*scan, *scanEx, rod,
01867 sectionStartBin, 1 + sectionEndBin - sectionStartBin, sectionEndTrigger,
01868 primList);
01869
01870 api.sendPrimList(rod.rod, primList);
01871 int responseCode = api.awaitResponse(rod.rod, 5);
01872
01873 if(responseCode != 0) {
01874 cout << "Histogram primitive failed! (ROD " << rod.rod << ")\n";
01875 throw SctApiException("Histogram primitive failed! (ROD " + boost::lexical_cast<string>(rod.rod) + ")");
01876 }
01877 }
01878 }
01879
01880 bool ScanControlRODHisto::findNextSection() {
01881
01882 Scan::TrigPoints trigPoints = scan->getVariableTrigs();
01883
01884 unsigned int i = sectionEndBin + 1;
01885
01886 if(i==trigPoints.size()) {
01887
01888
01889 return true;
01890 }
01891
01892 UINT32 initialNTrigs = trigPoints[i];
01893
01894 while(i<trigPoints.size() && trigPoints[i] >= initialNTrigs)
01895 i ++;
01896
01897 bool done = false;
01898
01899 sectionStartBin = 0;
01900 sectionEndBin = i - 1;
01901
01902 if(i == trigPoints.size()) {
01903 sectionEndTrigger = scan->getVariableTrigs()[i-1];
01904 } else {
01905 sectionEndTrigger = scan->getVariableTrigs()[i-1] - scan->getVariableTrigs()[i];
01906
01907
01908
01909
01910 }
01911
01912 #if 0
01913
01914 unsigned int i = sectionEndBin + 1;
01915 UINT32 initialNTrigs = trigPoints[i];
01916 while(i<trigPoints.size() && trigPoints[i] == initialNTrigs)
01917 i++;
01918
01919 sectionStartBin = sectionEndBin + 1;
01920 sectionEndBin = i - 1;
01921 sectionEndTrigger = scan->getVariableTrigs()[i-1];
01922
01923 done = false;
01924 #endif
01925
01926 cout << "Next sectionStartBin = " << sectionStartBin << " sectionEndBin = " << sectionEndBin << " sectionEndTrigger = " << sectionEndTrigger << endl;
01927
01928 return done;
01929 }
01930
01931 bool ScanControlRODHisto::checkScanComplete(bool &progressMade, bool &newBin) {
01932 if(aborting) {
01933 return true;
01934 }
01935
01936 progressMade = false;
01937 newBin = false;
01938
01939 bool result = true;
01940
01941 int totalBin = 0;
01942
01943 map<RodLabel, bool> rodNewBinMap;
01944
01945 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
01946 ri != scanEx->rodInfo.end();
01947 ri++) {
01948 const RodLabel &rodLabel = ri->first;
01949
01950 bool rodNewBin = false;
01951
01952 if(!checkScanCompleteROD(rodLabel, progressMade, rodNewBin, totalBin)) {
01953 result = false;
01954 }
01955
01956 rodNewBinMap[rodLabel] = rodNewBin;
01957 }
01958
01959
01960 newBin = true;
01961 for(map<RodLabel, bool>::const_iterator mapIter = rodNewBinMap.begin();
01962 mapIter != rodNewBinMap.end();
01963 mapIter++) {
01964 if(mapIter->second == false) {
01965 newBin = false;
01966 } else {
01967 cout << "New bin requested by ROD (" << mapIter->first.partition << ", " << mapIter->first.crate << ", " << mapIter->first.rod << ")\n";
01968 }
01969 }
01970
01971 if(progressMade) {
01972 int progressBin = totalBin / scanEx->rodInfo.size();
01973
01974 #if USE_IS
01975 if(api.m_isDict) {
01976 ISInfoInt binNumber(progressBin);
01977 api.m_isDict->update("SCTAPIServer.currentBin", binNumber);
01978 }
01979 #endif
01980 }
01981
01982 return result;
01983 }
01984
01985 void ScanControlRODHisto::abort() {
01986 aborting = true;
01987 }
01988
01989 #warning "32 bit version unreliable!!"
01990 unsigned int ScanControlRODHisto::getEventCounter(const RodLabel &rodLabel, int slave, bool fromMaster) {
01991 if(fromMaster) {
01992
01993 unsigned long reg = api.dspSingleRead(rodLabel.rod,
01994 0x8000002c - (slave & 2) * 2, -1);
01995 unsigned int currEvent = (unsigned int) ((reg >> (16*(slave&1))) & 0xffff);
01996
01997 return currEvent;
01998 } else {
01999
02000 unsigned long reg = api.dspSingleRead(rodLabel.rod,
02001 0x8000002c, slave);
02002 return (unsigned int) reg;
02003 }
02004 }
02005
02006 bool ScanControlRODHisto::checkScanCompleteROD(const RodLabel &rodLabel, bool &progressMade, bool &newBin, int &totalBin) {
02007 int partition = rodLabel.partition;
02008 int crate = rodLabel.crate;
02009 int rod = rodLabel.rod;
02010
02011 int currBin = 0;
02012 int currEvent = 0;
02013
02014
02015 long reg = api.dspSingleRead(rod, 0x80000020, -1);
02016 currBin = (reg & 0xff);
02017
02018 RodScanEx &rodInfo = scanEx->rodInfo[rodLabel];
02019
02020
02021 currEvent = getEventCounter(rodLabel, rodInfo.firstSlave, true);
02022
02023 if(currBin != lastBin[rodLabel]) {
02024 lastBin[rodLabel] = currBin;
02025 lastEvent[rodLabel] = currEvent;
02026 cout << "Next bin " << currBin << "+" << currEvent << " on ROD (" << partition << ", " << crate << ", " << rod << ")\n";
02027
02028 progressMade = true;
02029 } else if(currEvent != lastEvent[rodLabel]) {
02030 lastEvent[rodLabel] = currEvent;
02031 cout << "Next event " << currEvent << " (bin " << currBin << ") on ROD (" << partition << ", " << crate << ", " << rod << ")\n";
02032
02033 progressMade = true;
02034 }
02035
02036 totalBin += currBin;
02037
02038
02039 if(currBin == sectionEndBin && currEvent == sectionEndTrigger) {
02040
02041 newBin = true;
02042
02043
02044 for(int s=0; s<4; s++) {
02045 if(rodInfo.bitFieldDSP & (1<<s)) {
02046 int slaveEvent = getEventCounter(rodLabel, s, true);
02047
02048 if(slaveEvent != sectionEndTrigger) {
02049 cout << " Slave " << s << " completed only " << slaveEvent << "/" << sectionEndTrigger << " triggers\n";
02050 newBin = false;
02051 }
02052 }
02053 }
02054 } else if(currBin == sectionEndBin && currEvent == (sectionEndTrigger%65536)) {
02055
02056
02057
02058 if(!progressMade) {
02059
02060 newBin = true;
02061 }
02062 }
02063
02064 if(((currBin == finalBin) && (currEvent == finalTrigger))
02065 || ((currBin == finalBin) && (currEvent == (finalTrigger%65536)) && !progressMade)) {
02066
02067
02068 lastEvent[rodLabel] = finalTrigger;
02069
02070
02071 if(api.mrs) {
02072 *api.mrs << "HISTO_SUCCESS" << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI")
02073 << MRS_PARAM<int>("partition", rodLabel.partition)
02074 << MRS_PARAM<int>("crate", rodLabel.crate)
02075 << MRS_PARAM<int>("rod", rodLabel.rod)
02076 << MRS_TEXT("Histogramming successfully complete")
02077 << ENDM;
02078 }
02079
02080 cout << "Histogramming completed successfully\n";
02081
02082 return true;
02083 }
02084
02085 return false;
02086 }
02087
02088 void ScanControlRODHisto::finishHistogram(bool success) {
02089 time_t scanEnd = time(0);
02090
02091 scan->setEndTime(second_clock::universal_time());
02092
02093 if(checkDebugOption(DEBUG_SCAN_USE_ASSEMBLER)) {
02094 for(ScanEx::RodInfoMap::const_iterator ri = scanEx->rodInfo.begin();
02095 ri != scanEx->rodInfo.end();
02096 ri++) {
02097 const RodLabel &rod = ri->first;
02098 const RodScanEx &rodInfo = ri->second;
02099
02100 unsigned long SDSP_IDRAM_BASE;
02101 if(api.getRodRevision(rod) >= 0xe) {
02102 SDSP_IDRAM_BASE = 0x10000;
02103 } else {
02104 SDSP_IDRAM_BASE = 0x80000000;
02105 }
02106
02107 for(int s=0; s<numSlaves; s++) {
02108 if(rodInfo.bitFieldDSP & (1<<s)) {
02109 try {
02110 unsigned long val = api.dspSingleBlockRead(rod.rod,
02111 SDSP_IDRAM_BASE + 0x10, s);
02112 cout << "Read from slave " << s << " diag register: 0x" << hex << val
02113 << " which should be 0x" << (1<<19) << dec << endl;
02114
02115
02116 unsigned long newVal = val | 1<<17;
02117 api.dspSingleBlockWrite(rod.rod, SDSP_IDRAM_BASE + 0x10, newVal, s);
02118 val = api.dspSingleBlockRead(rod.rod, SDSP_IDRAM_BASE + 0x10, s);
02119 cout << "Read from slave " << s << " diag register: 0x" << hex << val
02120 << " which should be 0x" << (1<<17) << endl;
02121
02122
02123 newVal = val | 1<<19;
02124 api.dspSingleBlockWrite(rod.rod, SDSP_IDRAM_BASE + 0x10, newVal, s);
02125 val = api.dspSingleBlockRead(rod.rod, SDSP_IDRAM_BASE + 0x10, s);
02126 cout << "Read from slave " << s << " diag register: 0x" << hex << val
02127 << " which should be 0x" << (0) << endl;
02128 } catch(VmeException &v) {
02129 Utility::decodeVme(v);
02130 cerr << "VmeException turning off slave " << s << " cache\n";
02131 }
02132 }
02133 }
02134 }
02135 }
02136
02137
02138
02139 if(!scan->getOption(Scan::DEBUG) || success == true) {
02140 if(api.mrs) {
02141 *api.mrs << "SCAN_FINISHED" << MRS_INFORMATION
02142 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
02143 << MRS_TEXT("Scan finished")
02144 << MRS_PARAM<int>("ScanNumber", scan->getScanNumber())
02145 << MRS_PARAM<int>("ScanType1", scan->getScanVariable1())
02146 << MRS_PARAM<int>("ScanType2", scan->getScanVariable2())
02147 << MRS_PARAM<int>("ScanTime", scanEnd - scanStart)
02148 << ENDM;
02149 }
02150
02151 cout << "Histogramming complete, " << (scanEnd - scanStart) << " seconds, tidying up...\n";
02152
02153
02154
02155
02156
02157 cout << "Reading histograms...\n";
02158
02159 readHistograms();
02160
02161 cout << "... histograms read\n";
02162 } else {
02163 if(!scan->getOption(Scan::DEBUG)) {
02164 cout << "Histogram polling failed\n";
02165
02166 if(api.mrs) {
02167 *api.mrs << "SCAN_FAILED" << MRS_INFORMATION
02168 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
02169 << MRS_TEXT("Scan polling failed")
02170 << MRS_PARAM<int>("ScanNumber", scan->getScanNumber())
02171 << MRS_PARAM<int>("ScanTime", scanEnd - scanStart)
02172 << ENDM;
02173 }
02174 }
02175 }
02176
02177 if(checkDebugOption(DEBUG_PRINT_CALIB)) {
02178 RodLabel zeroRod = scanEx->rodInfo.begin()->first;
02179
02180 api.print_calib(zeroRod.rod);
02181 }
02182
02183 if(!scan->getOption(Scan::DEBUG)) {
02184 api.stopHistogramming(*scanEx);
02185
02186
02187 postScanModuleSetup();
02188 } else {
02189 if(api.mrs) {
02190 *api.mrs << "SCAN_DEBUG" << MRS_INFORMATION
02191 << MRS_QUALIF("SCTAPI") << MRS_QUALIF("doScan")
02192 << MRS_TEXT("Scan done in debug mode, probably best to be at the command line to sort it out!")
02193 << ENDM;
02194 }
02195
02196 cout << "** In debug mode, you're responsible for terminating histogram and for readout\n";
02197 }
02198
02199 if(checkDebugOption(DEBUG_PRINT_CALIB)) {
02200 RodLabel zeroRod = scanEx->rodInfo.begin()->first;
02201
02202 api.print_calib(zeroRod.rod);
02203 }
02204
02205
02206 scan->print();
02207
02208 #if USE_IS
02209 if(api.m_isDict)
02210 api.m_isDict->remove(api.idiosyncrasy().infoServiceNameOfScanStatusObject());
02211 #endif
02212
02213 if(api.mrs)
02214 *api.mrs << "SCAN_COMPLETE" << MRS_INFORMATION << MRS_QUALIF("SctApi") << MRS_TEXT("Scan has completed") << ENDM;
02215 }
02216
02217 void ScanControlRODHisto::postScanModuleSetup() {
02218 PrimBuilder &builder = PrimBuilder::instance();
02219
02220 if(scan->getScanVariable1() == ST_TOKEN
02221 || scan->getScanVariable1() == ST_BYPASS) {
02222
02223 shared_ptr<PrimListWrapper> chipSeqList(new PrimListWrapper(1));
02224 for(int i=0; i<48; i++) {
02225 builder.writeRegister(chipSeqList, ERROR_MASK(0, i), 10, 1, 0);
02226 builder.writeRegister(chipSeqList, ERROR_MASK(1, i), 10, 1, 0);
02227 }
02228
02229 if(api.synchSendPrimListAllCrates(chipSeqList)) {
02230 cout << "Chip sequence error list failed!\n";
02231 }
02232
02233 cout << "EFB chip sequence detection turned back on\n";
02234 }
02235
02236
02237 {
02238 Trigger::RODTriggers points = scan->getTrigger1()->getRODTriggers();
02239
02240 int triggerCount = 0;
02241
02242 for(unsigned int i=0; i<points.size(); i++) {
02243
02244 if(points[i].first == L1_TRIGGER) {
02245 triggerCount++;
02246 }
02247 }
02248
02249
02250 if(triggerCount > 1 && scan->getOption(Scan::DISTSLAVE) < 3) {
02251 shared_ptr<PrimListWrapper> dblIdCheckList(new PrimListWrapper(1));
02252
02253
02254 for(int f=0; f<48; f++) {
02255
02256
02257
02258
02259
02260
02261
02262 }
02263
02264 if(api.synchSendPrimListAllCrates(dblIdCheckList)) {
02265 cout << "Double trigger BC check list failed!\n";
02266 }
02267
02268 cout << "L1 and BCID checks restored after double triggers\n";
02269 }
02270 }
02271
02272
02273
02274 }
02275
02276 bool ScanControlRODHisto::checkDebugOption(int opt) {
02277 return Debug::getInstance()->checkDebugOption((DebugOptions)opt);
02278 }
02279
02280 void ScanControlRODHisto::reportEventErrors() {
02281 api.reportEventErrors();
02282 }
02283
02284 unsigned int ScanControlRODHisto::getProcTime(const RodLabel rlabel, int dsp) {
02285 if(dsp == -1) {
02286 throw SctApiException("Can't getProcTime on MDSP");
02287 } else {
02288 int procTime;
02289
02290 unsigned long SDSP_IDRAM_BASE;
02291 if(api.getRodRevision(rlabel) >= 0xe) {
02292 SDSP_IDRAM_BASE = 0x10000;
02293 } else {
02294 SDSP_IDRAM_BASE = 0x80000000;
02295 }
02296
02297 unsigned long length;
02298 unsigned long *regs = api.dspBlockRead(rlabel.rod,
02299 SDSP_IDRAM_BASE + 0x10, 20, dsp, length);
02300
02301 if(regs) {
02302 long reg;
02303
02304
02305 reg = regs[6];
02306 procTime = ((reg >> 16) & 0xffff);
02307 } else {
02308 throw SctApiException("Failed to read getProcTime from DSP");
02309 }
02310
02311 return procTime;
02312 }
02313 }
02314
02315 ScanControlRODHisto::TrapBuffers ScanControlRODHisto::getTrapBuffers(const RodLabel rlabel, int dsp) {
02316 if(dsp == -1) {
02317 throw SctApiException("Invaled dsp passed to getTrapBuffers");
02318 } else {
02319 int ihead, itail, xhead, xtail;
02320
02321 unsigned long SDSP_IDRAM_BASE;
02322 if(api.getRodRevision(rlabel) >= 0xe) {
02323 SDSP_IDRAM_BASE = 0x10000;
02324 } else {
02325 SDSP_IDRAM_BASE = 0x80000000;
02326 }
02327
02328 unsigned long length;
02329 unsigned long *regs = api.dspBlockRead(rlabel.rod,
02330 SDSP_IDRAM_BASE + 0x10, 20, dsp, length);
02331
02332 if(regs) {
02333 long reg;
02334
02335
02336 reg = regs[1];
02337 itail = ((reg & 0xff0000) >> 16);
02338 xtail = ((reg & 0xff000000) >> 24);
02339
02340
02341 reg = regs[2];
02342 ihead = ((reg & 0xff0000) >> 16);
02343 xhead = ((reg & 0xff000000) >> 24);
02344 } else {
02345 throw SctApiException("Failed to read DSP for getTrapBuffers");
02346 }
02347
02348 return make_pair(make_pair(ihead, itail), make_pair(xhead, xtail));
02349 }
02350 }
02351
02352 void ScanControlRODHisto::dumpHistoStatus(const RodLabel rlabel, int dsp) {
02353 if(dsp == -1) {
02354 const unsigned long MDSP_IDRAM_BASE = 0x80000000;
02355
02356
02357 long reg = api.dspSingleRead(0, MDSP_IDRAM_BASE + 0x20, -1);
02358 cout << "Bin: " << (reg & 0xff)
02359 << " Cal: " << ((reg & 0xff00) >> 8)
02360 << " Errs: " << ((reg & 0xffff0000) >> 16) << endl;
02361
02362
02363 reg = api.dspSingleRead(0, MDSP_IDRAM_BASE + 0x24, -1);
02364 cout << "avg. trans " << (reg & 0xff)
02365 << " avg. len " << ((reg & 0xff00) >> 8)
02366 << " avg. proc. " << ((reg & 0xffff0000) >> 16) << endl;
02367
02368
02369 reg = api.dspSingleRead(0, MDSP_IDRAM_BASE + 0x2c, -1);
02370 cout << "Slave 0: " << (reg & 0xffff)
02371 << " Slave 1: " << ((reg & 0xffff0000) >> 16) << endl;
02372
02373
02374 reg = api.dspSingleRead(0, MDSP_IDRAM_BASE + 0x28, -1);
02375 cout << "Slave 2: " << (reg & 0xffff)
02376 << " Slave 3: " << ((reg & 0xffff0000) >> 16) << endl;
02377 } else {
02378 unsigned long SDSP_IDRAM_BASE;
02379 if(api.getRodRevision(rlabel) >= 0xe) {
02380 SDSP_IDRAM_BASE = 0x10000;
02381 } else {
02382 SDSP_IDRAM_BASE = 0x80000000;
02383 }
02384
02385 unsigned long length;
02386 unsigned long *regs = api.dspBlockRead(rlabel.rod,
02387 SDSP_IDRAM_BASE + 0x10, 20, dsp, length);
02388
02389 if(regs) {
02390 long reg;
02391
02392 cout << "TrapStatus: \n";
02393
02394
02395
02396 reg = regs[1];
02397 int words = ((reg &0xffff) >> 0);
02398 int itail = ((reg & 0xff0000) >> 16);
02399 int xtail = ((reg & 0xff000000) >> 24);
02400
02401 cout << "Event word count: " << words;
02402 cout << " IFrame tail: " << itail;
02403 cout << " XFrame tail: " << xtail << endl;
02404
02405
02406 reg = regs[2];
02407 int ihead = ((reg & 0xff0000) >> 16);
02408 int xhead = ((reg & 0xff000000) >> 24);
02409 cout << " IFrame head: " << ihead;
02410 cout << " XFrame head: " << xhead << endl;
02411
02412
02413 reg = regs[17];
02414 cout << "Trap Command/Status: "
02415 << ((reg & 0x1)?"Trailer ":"")
02416 << ((reg & 0x2)?"Transmit ":"")
02417 << ((reg & 0x4)?"Header ":"")
02418 << ((reg & 0x4)?"ISR active ":"");
02419 cout << ((reg & 0x10)?"\"Data Error\" ":"")
02420 << ((reg & 0x20)?"\"Header Error\" ":"")
02421 << ((reg & 0x40)?"\"Trailer Error\" ":"")
02422 << ((reg & 0x80)?"\"Link Error\" ":"");
02423 cout << ((reg & 0x100)?"\"Error\" ":"")
02424 << ((reg & 0x200)?"\"Overflow(old)\" ":"")
02425 << ((reg & 0x800)?"\"ISR pending\" ":"");
02426 cout << ((reg & 0x4000)?"\"Overflow error\" ":"")
02427 << ((reg & 0x8000)?"\"Overflow\" ":"");
02428 cout << endl;
02429
02430 int errCount = ((reg >> 16) & 0xff);
02431 cout << "\"Error count\": " << errCount << endl;
02432 int evCount = ((reg >> 24) & 0xff);
02433 cout << "\"Event count\": " << evCount << endl;
02434
02435
02436 reg = regs[4];
02437 int currentBin = (reg & 0xff);
02438 cout << "Bin: " << currentBin
02439 << " Cal: " << ((reg & 0x1f00) >> 8)
02440 << ((reg & 0x800)?" Cal enabled":"")
02441 << ((reg & 0x1000)?" New bin":"")
02442 << ((reg & 0x20000)?" New cal":"") << endl;
02443
02444
02445 reg = regs[5];
02446 int numEvents = reg;
02447 cout << "Num events: " << numEvents << endl;
02448
02449
02450 reg = regs[6];
02451 cout << "Histogram status: 0x" << hex << (reg & 0xffff) << dec << " " << ((reg & 0x1)?"Ready ":"")
02452 << ((reg & 0x2)?"Expecting ":"")
02453 << ((reg & 0x4)?"Processing ":"")
02454 << ((reg & 0x8)?"Done ":"") << endl;
02455
02456 int procTime = ((reg >> 16) & 0xffff);
02457 cout << "Bin err: " << ((reg >> 8) & 0xff)
02458 << " proc time: " << ((reg >> 16) & 0xffff) << endl;
02459
02460
02461 reg = regs[7];
02462 int evRecvd = reg;
02463 cout << "Events recvd: " << evRecvd << endl;
02464
02465 ofstream statusOut("TIMStatus.txt", ios_base::out | ios_base::app);
02466 statusOut << currentBin << "\t"
02467 << ihead << "\t" << itail << "\t"
02468 << xhead << "\t" << xtail << "\t"
02469 << errCount << "\t" << evCount << "\t"
02470 << evRecvd << "\t" << words << "\t" << procTime << endl;
02471 }
02472 }
02473 }
02474
02475 ScanControlTIMHisto::ScanControlTIMHisto(SctApi &api, boost::shared_ptr<Scan> aScan, boost::shared_ptr<ScanEx> aScanEx) : ScanControlRODHisto(api, aScan, aScanEx), binCount(0) {
02476 }
02477
02478 void ScanControlTIMHisto::startHistogramming() {
02479
02480 api.timWriteRegister(0x14, 0x3000);
02481
02482 shared_ptr<PrimListWrapper> preTimList(new PrimListWrapper(4));
02483 PrimBuilder::instance().rodMode(preTimList, DATA_TAKING_MODE, 0, 1, 0, 0, 1);
02484
02485 PrimBuilder::instance().writeRegister(preTimList, RTR_CMND_STAT, 7, 1, 1);
02486
02487 for(int f=0; f<8; f++) {
02488
02489
02490 PrimBuilder::instance().writeRegister(preTimList, DM_DFLT_LUT(f), 0, 16, 0x0);
02491 }
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501 cout << "Sending pre TIM setup list\n";
02502 api.synchSendPrimListAllCrates(preTimList);
02503 cout << " done sending pre TIM setup list\n";
02504
02505 hex(cout);
02506 cout << "0x" << RTR_CMND_STAT << ": 0x" << api.readRODRegister(0, RTR_CMND_STAT) << endl;
02507 cout << "0x" << ERROR_MASK(0, 0) << ": 0x" << api.readRODRegister(0, ERROR_MASK(0, 0)) << endl;
02508 cout << "0x" << ERROR_MASK(1, 0) << ": 0x" << api.readRODRegister(0, ERROR_MASK(1, 0)) << endl;
02509 cout << "0x" << DM_DFLT_LUT(0) << ": 0x" << api.readRODRegister(0, DM_DFLT_LUT(0)) << endl;
02510 cout << "0x" << DM_DFLT_LUT(1) << ": 0x" << api.readRODRegister(0, DM_DFLT_LUT(1)) << endl;
02511 dec(cout);
02512
02513 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
02514
02515 ofstream statusOut("TIMStatus.txt");
02516 statusOut << "bin\tihead\titail\txhead\txtail\terrCnt\tevCount\tevRecvd\twords\tprocTime\n";
02517 }
02518 }
02519
02520 void ScanControlTIMHisto::nextBin() {
02521 cout << "TIM histo, next bin\n";
02522
02523 std::list<BankType> banks;
02524 banks.push_back(SCTAPI_BANK_SCAN);
02525
02526 api.modifyABCDVarROD(scan->getScanVariable1(), scan->getScanPoints1()[binCount], banks);
02527
02528
02529
02530 api.sendAllABCDModules(SCTAPI_BANK_SCAN);
02531
02532
02533 shared_ptr<PrimListWrapper> setTriggerList(new PrimListWrapper(4));
02534 PrimBuilder::instance().setTrigger(setTriggerList, binCount, Utility::translateBank(SCTAPI_BANK_SCAN));
02535
02536 shared_ptr<PrimListWrapper> binTimList(new PrimListWrapper(4));
02537
02538
02539 for(int s=0; s<4; s++) {
02540 PrimBuilder::instance().slavePrimList(binTimList, setTriggerList,
02541 s, 1, 0);
02542 }
02543
02544
02545 PrimBuilder::instance().rodMode(binTimList, 0x20000, 0, 1, 0, 0, 1);
02546 PrimBuilder::instance().writeRegister(binTimList, RTR_CMND_STAT, 7, 1, 1);
02547
02548 cout << "Sending TIM setup list\n";
02549 api.synchSendPrimListAllCrates(binTimList);
02550 cout << " done sending TIM setup list\n";
02551
02552 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
02553 cout << "******************* Pre triggers status ********************\n";
02554 dumpHistoStatus(RodLabel(), 0);
02555 }
02556
02557 api.timSoftReset();
02558 api.timBCReset();
02559
02560 Scan::TrigPoints trigs = scan->getVariableTrigs();
02561
02562 cout << "Sending " << trigs[binCount] << " triggers to one crate " << endl;
02563
02564 switch(scan->getOption(Scan::TIM)) {
02565 case 1:
02566
02567 api.sendTimBurst(trigs[binCount]);
02568 break;
02569 case 2:
02570 #warning "Assumes ROD 0!!!"
02571
02572 for(unsigned int i=0; i<trigs[binCount]; i++) {
02573 api.timL1A();
02574
02575 TrapBuffers tb = getTrapBuffers(RodLabel(), 0);
02576
02577 if (!(tb.first.first == tb.first.second && tb.second.first == tb.second.second))
02578 sleep(1);
02579 }
02580 break;
02581 case 3:
02582 #warning "Assumes ROD 0!!!"
02583
02584
02585 {
02586 unsigned int sentTriggers = 0;
02587 const unsigned int trigsPerBurst = 20;
02588
02589 while(sentTriggers < trigs[binCount]) {
02590 if(sentTriggers % 1000 < trigsPerBurst) {
02591 cout << "Done " << sentTriggers << " triggers\n";
02592 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS))
02593 dumpHistoStatus(RodLabel(), 0);
02594 }
02595 int ntrigs = min(trigs[binCount]-sentTriggers, trigsPerBurst);
02596 api.sendTimBurst(ntrigs);
02597 sentTriggers += ntrigs;
02598
02599
02600 TrapBuffers tb = getTrapBuffers(RodLabel(), 0);
02601
02602 TrapBuffers oldtb;
02603 if (!(tb.first.first == tb.first.second && tb.second.first == tb.second.second))
02604 do {
02605 oldtb = tb;
02606 usleep(trigsPerBurst * 10);
02607 tb = getTrapBuffers(RodLabel(), 0);
02608
02609 if(tb.first.first == tb.first.second && tb.second.first == tb.second.second) break;
02610 if(tb == oldtb) break;
02611 } while(1);
02612 }
02613 }
02614 break;
02615 case 4:
02616 #warning "Assumes ROD 0!!!"
02617
02618
02619 {
02620 unsigned int sentTriggers = 0;
02621
02622 api.timL1A();
02623 sentTriggers ++;
02624
02625
02626
02627
02628 unsigned int procTime = getProcTime(RodLabel(), 0);
02629 double timFrequency = 0.25 * 1e6/procTime;
02630
02631 api.timSetFrequency(min(6.0, timFrequency/1000), 0);
02632
02633 cout << "*** Proc Time for 1 trigger was " << procTime << " setting frequency to " << timFrequency << "Hz\n";
02634
02635 procTime = getProcTime(RodLabel(), 0);
02636 timFrequency = 0.25 * 1e6/procTime;
02637 api.timSetFrequency(min(6.0, timFrequency/1000), 0);
02638
02639 cout << "*** Proc Time after 10 trigs was " << procTime << " setting frequency to " << timFrequency << "Hz\n";
02640
02641 if(trigs[binCount] > sentTriggers)
02642 api.sendTimBurst(trigs[binCount]-sentTriggers);
02643
02644 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
02645 cout << "******************* Post triggers status ********************\n";
02646 dumpHistoStatus(RodLabel(), 0);
02647 }
02648
02649 TrapBuffers tb = getTrapBuffers(RodLabel(), 0);
02650
02651 TrapBuffers oldtb;
02652 if (!(tb.first.first == tb.first.second && tb.second.first == tb.second.second))
02653 do {
02654 oldtb = tb;
02655 sleep(1);
02656 tb = getTrapBuffers(RodLabel(), 0);
02657
02658 if(tb.first.first == tb.first.second && tb.second.first == tb.second.second) break;
02659 if(tb == oldtb) break;
02660 } while(1);
02661 break;
02662 }
02663 }
02664
02665 if(checkDebugOption(DEBUG_TIM_SCAN_STATUS)) {
02666 cout << "******************* Post triggers status 2 ******************\n";
02667 dumpHistoStatus(RodLabel(), 0);
02668 }
02669
02670
02671
02672
02673
02674
02675 binCount ++;
02676 }
02677
02678
02679
02680 bool ScanControlTIMHisto::checkScanCompleteROD(const RodLabel &rodLabel, bool &progressMade, bool &newBin, int &totalBin) {
02681
02682 cout << "Checking TIM scan complete\n";
02683
02684 progressMade = true;
02685
02686
02687 newBin = true;
02688
02689 totalBin += binCount-1;
02690
02691
02692
02693 if((binCount-1 >= finalBin)) {
02694 return true;
02695 }
02696
02697 return false;
02698 }
02699
02700
02701
02702
02703
02704 }