Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Related Pages

SctApiEvent.cxx

00001 
00007 #include <set>
00008 
00009 #include "SctApi.h"
00010 #include "crate.h"
00011 #include "utility.h"
00012 
00013 #include "SctApiDebug.h"
00014 
00015 #include "Sct/SctNames.h"
00016 
00017 using namespace std;
00018 using namespace SctApi::Utility;
00019 
00020 namespace {
00021   void decodeEventWord(UINT16 currWord, int errorType, bool &linkCondensed, 
00022                        string &type, vector<pair<string, int> > &arguments, vector<string> &errors);
00023 
00024   vector<string> decodeEventFlags(UINT32 flags);
00025 
00026   list<pair<int, int> > getFragmentList(UINT32 *buffer);
00027 
00028   struct FibreLocation {
00029     SctApi::RodLabel rod; 
00030     unsigned int slave, fibre;
00031     std::string firstError;
00032     bool operator<(const FibreLocation &rhs) const {
00033       // firstError string intentionally not compared
00034       if(rod < rhs.rod) return true;
00035       if(slave < rhs.slave) return true;
00036       if(fibre < rhs.fibre) return true;
00037       return false;
00038     }
00039   };
00040 }
00041 
00042 namespace SctApi {
00043   const int eventSize = 0x400;
00044   const int eventWords = eventSize / 4;
00045   const int frameCount = 32;
00046 
00047   inline UINT32 eventWord(const UINT32 * const buffer, const int frame, const int index) {
00048     unsigned int offset = (eventWords * frame + index) % (frameCount * eventWords); 
00049     return buffer[offset];
00050   }
00051 
00054   bool hasPostSeptember2004Firmware(const UINT32 * const frameBuffer, const int frame) {
00055     const int version = eventWord(frameBuffer, frame, 3);
00056     return (version != 0);
00057   }
00058 
00059   inline int findEOF(UINT32 *buffer, int startFrame) {
00060     int eofAt = 0;
00061     while(eventWord(buffer, startFrame, eofAt) != 0xe0f00000 && eofAt < (eventWords * frameCount)) eofAt ++;
00062 
00063     if(eofAt < (eventWords * frameCount)) {
00064       return eofAt;
00065     } else {
00066       return -1;
00067     }
00068   }
00069 
00070 void SctApi::scanEvents(unsigned int rod, int sl, bool extFlag, bool errorType) {
00071   int beginSl, endSl;
00072 
00073   if(sl == -1) {
00074     beginSl = 0;
00075     endSl = 4;
00076   } else {
00077     beginSl = sl;
00078     endSl = sl+1;
00079   }
00080 
00081   for(int slave = beginSl; slave<endSl; slave++) {
00082     if(sl == -1) {
00083       cout << "Slave: " << slave << endl;
00084     }
00085 
00086     int lastFrame = getLastEventFrame(rod, slave);
00087 
00088     if(lastFrame == -1) {
00089       cout << " No frames in buffer\n";
00090     } else {
00091       cout << " Start of last event at frame: " << lastFrame << endl;
00092     }
00093 
00094     UINT32 *frameBuffer = readEventBuffer(rod, slave, extFlag, errorType);
00095 
00096     if(frameBuffer == 0) {
00097       cout << "Couldn't load memory\n";
00098       return;
00099     }
00100 
00101     int trailerLength;
00102     int headerLength;
00103 
00104     if(errorType) {
00105       headerLength = 6;
00106       trailerLength = 8;
00107     } else {
00108       headerLength = 9;
00109       trailerLength = 5;
00110     }
00111 
00112     list<pair<int, int> > fragments = getFragmentList(frameBuffer);
00113 
00114     for(list<pair<int, int> >::const_iterator iter = fragments.begin();
00115         iter != fragments.end();
00116         iter++) {
00117       cout << "Fragment from ";
00118       cout.width(2);
00119       cout << iter->first << "-";
00120       cout.width(2);
00121       cout << iter->second;
00122 
00123       int L1ID, BCID;
00124       if(errorType) {
00125         L1ID = eventWord(frameBuffer, iter->first, 2);
00126         BCID = eventWord(frameBuffer, iter->first, 3);
00127       } else {
00128 
00129     if (hasPostSeptember2004Firmware(frameBuffer, iter->first)) {
00130           cout << " (New) ";
00131           L1ID = eventWord(frameBuffer, iter->first, 6);
00132           BCID = eventWord(frameBuffer, iter->first, 7);
00133           headerLength=10;
00134         } else {
00135           cout << " (Old) ";
00136           L1ID = eventWord(frameBuffer, iter->first, 5);
00137           BCID = eventWord(frameBuffer, iter->first, 6);
00138         }
00139       }
00140 
00141       cout << " L1 ";
00142       cout.width(4);
00143       cout << L1ID << " BCID ";
00144       cout.width(4);
00145       cout << BCID << endl;
00146 
00147       int eofAt = findEOF(frameBuffer, iter->first);
00148       int errorCount = eventWord(frameBuffer, iter->first, eofAt-trailerLength);
00149       if(errorCount > 0) {
00150         cout << " Error count = " << errorCount; 
00151 
00152         int errorFlags = eventWord(frameBuffer, iter->first, eofAt-trailerLength + 1);
00153 
00154         cout << " flags = 0x" << hex << errorFlags << dec;
00155 
00156         vector<string> flagStrings = decodeEventFlags(errorFlags);
00157         for(vector<string>::const_iterator iter = flagStrings.begin();
00158             iter != flagStrings.end();
00159             iter++) {
00160           cout << " " << *iter;
00161         }
00162 
00163         cout << endl;
00164       }
00165     }
00166   }
00167 }
00168 
00169 void SctApi::decodeEvent(unsigned int rod, 
00170                          int slave, int index, bool extFlag, bool errorType) {
00171   UINT32 *frameBuffer = readEventBuffer(rod, slave, extFlag, errorType);
00172 
00173   if(frameBuffer == 0) {
00174     cout << "Couldn't load memory\n";
00175     return;
00176   }
00177 
00178   int lastFrame = -1;
00179 
00180   // Finds one beyond last
00181   for(int i=index+1; i<frameCount+index; i++) {
00182     if((eventWord(frameBuffer, i, -1) & 0xff0e0000) == 0x400e0000) {
00183       lastFrame = i;
00184       break;
00185     } 
00186   }
00187 
00188   if(lastFrame == -1) {
00189     cout << "Can't find end of frame\n";
00190     return;
00191   } else {
00192     cout << "Found " << (lastFrame - index) << " frames of event data\n";
00193   }
00194 
00195   if((eventWord(frameBuffer, lastFrame, -1) & 0xff0e0000) != 0x400e0000) {
00196     cout << "Event trailer marker not found " << eventWord(frameBuffer, lastFrame, -1) << endl;
00197     return;
00198   } 
00199 
00200   if(eventWord(frameBuffer, index, 0) == 0xb0f00000) { 
00201     cout << "Found header\n";
00202   } else {
00203     cout << "Bad header 0x" << hex << eventWord(frameBuffer, index, 0) << dec << endl;
00204     return;
00205   }
00206 
00207   if(eventWord(frameBuffer, index, 1) == 0xee1234ee) {
00208     cout << "Valid header\n";
00209   } else {
00210     cout << "Bad check 0x" << hex << eventWord(frameBuffer, index, 1) << dec << endl;
00211   }
00212 
00213   UINT32 headerLength;     // Including bof
00214   UINT32 trailerLength;    // Excluding eof
00215 
00216   if(errorType) {
00217     // Added AJB 1/july/2005
00218     if (true){//hasPostSeptember2004Firmware(frameBuffer, index)) {
00219       headerLength = 7;
00220       trailerLength = 8;
00221       cout << "Guessing new formatter version:\n";
00222       cout << "L1ID = 0x" << hex << eventWord(frameBuffer, index, 3) 
00223        << " BCID = 0x" << eventWord(frameBuffer, index, 4) << dec << endl;
00224       cout << "Trigger type = " << eventWord(frameBuffer, index, 5) 
00225        << " Event type = " << eventWord(frameBuffer, index, 6) << endl;
00226       // end of AJB addition
00227     }else{
00228       headerLength = 6;
00229       trailerLength = 8;
00230       cout << "L1ID = 0x" << hex << eventWord(frameBuffer, index, 2) 
00231        << " BCID = 0x" << eventWord(frameBuffer, index, 3) << dec << endl;
00232       cout << "Trigger type = " << eventWord(frameBuffer, index, 4) 
00233        << " Event type = " << eventWord(frameBuffer, index, 5) << endl;
00234     }
00235   } else {
00236     headerLength = 9;
00237     trailerLength = 5;
00238 
00239     if(eventWord(frameBuffer, index, 2) != headerLength) {
00240       cout << "Unknown header length (" << eventWord(frameBuffer, index, 2) << ")\n";
00241     } 
00242 
00243     if (hasPostSeptember2004Firmware(frameBuffer, index)) {
00244       
00245       cout << "Guessing new formatter version:\n";
00246       cout << "Version: " << eventWord(frameBuffer, index, 3) 
00247            << " ID: " << eventWord(frameBuffer, index, 4)
00248            << " Run number = " << eventWord(frameBuffer, index, 5) << endl;
00249       cout << hex << "L1ID = 0x" << (eventWord(frameBuffer, index, 6) & 0xfffffff )
00250            << " BCID = 0x" << eventWord(frameBuffer, index, 7) 
00251            << " TType = 0x" << eventWord(frameBuffer, index, 8) 
00252            << " det type = 0x" << eventWord(frameBuffer, index, 9) << dec << endl;
00253 
00254       // The below assumes the old definition of headerLength (ie including 0xbof)
00255       headerLength=10;
00256     } else {
00257       cout << "Guessing old formatter version:\n";
00258       cout << "Version: " << eventWord(frameBuffer, index, 3) 
00259            << " ID: " << eventWord(frameBuffer, index, 4) << endl;
00260       cout << hex << "L1ID = 0x" << eventWord(frameBuffer, index, 5) 
00261            << " BCID = 0x" << eventWord(frameBuffer, index, 6) 
00262            << " TType = 0x" << eventWord(frameBuffer, index, 7) 
00263            << " det type = " << eventWord(frameBuffer, index, 8) << endl;
00264     }
00265   } 
00266 
00267   int eofAt = findEOF(frameBuffer, index);
00268 
00269   if(eofAt != -1) {
00270     cout << "Found end of frame!\n";
00271   } else {
00272     cout << "EOF not found\n";
00273     return;
00274   }
00275 
00276   int eventLength = eofAt-headerLength-trailerLength;
00277 
00278   UINT32 rawOffset = headerLength;
00279 
00280   // Something different to the first word
00281   UINT16 lastWord = 1 + ((eventWord(frameBuffer, index, rawOffset) & 0xffff0000) >> 16);
00282   UINT32 repeats = 0;
00283 
00284   bool linkCondensed = true;
00285 
00286   for(int i=0; i<eventLength * 2; i++) {
00287     UINT16 currWord;
00288     {
00289       UINT32 rawWord = eventWord(frameBuffer, index, rawOffset + i/2);
00290       if(i&1) {
00291         currWord = rawWord & 0x00ffff;
00292       } else {
00293         currWord = (rawWord & 0xffff0000) >> 16;
00294       }
00295     }
00296 
00297     if(currWord == lastWord) {
00298       repeats ++;
00299       continue;
00300     } else if(repeats) {
00301       cout << "        Repeated " << repeats << " times\n";
00302       repeats = 0;
00303     }
00304 
00305     lastWord = currWord;
00306 
00307     cout.width(4);
00308     cout.fill('0');
00309     cout << hex << currWord << dec;
00310     cout.fill(' ');
00311 
00312     string type;
00313     vector<pair<string, int> > arguments;
00314     vector<string> errors;
00315 
00316     decodeEventWord(currWord, errorType, linkCondensed, 
00317                     type, arguments, errors);
00318 
00319     cout << " " << type << " ";
00320     for(vector<pair<string, int> > :: const_iterator iter = arguments.begin();
00321         iter != arguments.end();
00322         iter ++) {
00323       cout << "  " << iter->first << ": 0x" << hex << iter->second << dec;
00324     }
00325 
00326     if(errors.size() > 0) {
00327       cout << "  ERRORS: ";
00328     }
00329     for(vector<string> :: const_iterator iter = errors.begin();
00330         iter != errors.end();
00331         iter ++) {
00332       cout << " " << *iter;
00333     }
00334     cout << endl;
00335 
00336   }
00337 
00338   if(repeats) {
00339     cout << "        Repeated " << repeats << " times\n";
00340     repeats = 0;
00341   }
00342 
00343   cout << "Error count = " << eventWord(frameBuffer, index, eofAt-trailerLength) << endl;
00344   cout << "Error flags = 0x" << hex << eventWord(frameBuffer, index, eofAt-trailerLength + 1) << dec << endl;
00345 
00346   int flags = eventWord(frameBuffer, index, eofAt-trailerLength + 1);
00347   vector<string> flagStrings = decodeEventFlags(flags);
00348   for(vector<string>::const_iterator iter = flagStrings.begin();
00349       iter != flagStrings.end();
00350       iter++) {
00351     cout << *iter << " ";
00352   }
00353 
00354   if(flagStrings.size() > 0) 
00355     cout << endl;
00356 
00357   if(errorType) {
00358     cout << "Error Status:  0: No data 1: Good data 2: BC or L1 error 3: Timeout\n" << hex;
00359 
00360     for(int es = 0; es < 6; es++) {
00361       UINT16 esWord = eventWord(frameBuffer, index, eofAt-trailerLength + 2 + es);
00362       for(int i=0; i<8; i++) {
00363         cout << (esWord & 0x3) << " ";
00364         esWord >>= 2;
00365       }
00366     }
00367 
00368     cout << dec << endl;
00369   } else {
00370     cout << "nData = " << eventWord(frameBuffer, index, eofAt-2) 
00371          << " words found = " << (eofAt - (headerLength + trailerLength)) << endl;
00372   }
00373 
00374   cout << "EOF = 0x" << hex << eventWord(frameBuffer, index, eofAt) << dec << endl;
00375 
00376   if(checkDebugOption(DEBUG_DUMP_RAW_EVENT)) {
00377     // Print out all the raw data afterwards
00378     int wordsPerLine = 8;
00379 
00380 #warning "Is it more useful as it was (only print out the event data)"
00381     for(int i=index; i<lastFrame; i++) {
00382       printMemoryBlock(cout, (long unsigned *)frameBuffer[(i % frameCount) * eventWords], eventWords, wordsPerLine);
00383     }
00384   }
00385   if(checkDebugOption(DEBUG_DIAG)) {
00386     cout << (lastFrame - index) << " frames finished in frame " << lastFrame << " with 0x";
00387     cout.fill('0'); cout.width(8);
00388     cout << hex << int(eventWord(frameBuffer, lastFrame, -1)) << dec << endl;
00389     cout.fill(' ');
00390   }
00391 }
00392 
00393 /*
00394   Called to see what went wrong at the end of a scan... 
00395 
00396   Write everything to ScanErrors.txt
00397 
00398   Brief summary to MRS, also to stdout (needs implementing!)
00399 */
00400 void SctApi::reportEventErrors() {
00401 
00402 #warning "Get run and scan into file name? Meanwhile append"
00403   string fileName = Sct::SctNames::getLogDir() + "/SctApi.ScanErrors.txt";
00404   ofstream outFile(fileName.c_str(), std::ios::binary | std::ios::app);
00405   time_t currTime = time(0);
00406   outFile << "Start of event report for scan: Time " << ctime(&currTime) << std::endl;
00407 
00408   // scanNumber is incremented before the scan starts, this will be wrong...
00409   outFile << "\t\tRun number: " << runNumber << " (next) Scan number: " << scanNumber << std::endl;
00410   // So we can match one with the other
00411   cout << "Event errors reported at time: " << ctime(&currTime) << " to " << fileName << std::endl;
00412 
00413   // In a standard scan these aren't set
00414   bool extFlag = false;
00415   bool errorType = false;
00416 
00417   // Errors in ROD/slave/rxfibre
00418   set<FibreLocation> errorMask;
00419 
00420   for(list<RodLabel>::const_iterator rl = rodList.begin();
00421       rl!=rodList.end();
00422       rl++){
00423     for(int slave=0; slave<4; slave++) {
00424       int currentFibre = -1;
00425       int lastFrame = getLastEventFrame(rl->rod, slave);
00426 
00427       outFile << "Crate: " << rl->crate << " Rod: " << rl->rod << " Slave: " << slave << endl;
00428 //       if(mrs) {
00429 //         *mrs << "EVENT_REPORT" << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI") 
00430 //              << MRS_PARAM<int>("partition", rl->partition)
00431 //              << MRS_PARAM<int>("crate", rl->crate)
00432 //              << MRS_PARAM<int>("rod", rl->rod)
00433 //              << MRS_PARAM<int>("slave", slave);
00434 //       }
00435       if(lastFrame == -1) {
00436         outFile << "Event trap empty\n";
00437 //         if(mrs) *mrs << MRS_TEXT("Event trap empty");
00438       } else {
00439         outFile << "Start of last event at frame " << lastFrame << endl;
00440 //         if(mrs) *mrs << MRS_PARAM<int>("lastFrame", lastFrame)
00441 //                      << MRS_TEXT("Start of last event at frame");
00442       }
00443 //       if(mrs) *mrs << ENDM;
00444 
00445       UINT32 *eventBuffer = readEventBuffer(rl->rod, slave, extFlag, errorType);
00446 
00447       if(eventBuffer == 0) {
00448         cout << "Couldn't load memory\n";
00449         return;
00450       }
00451 
00452       int trailerLength;
00453       int headerLength;
00454       if(errorType) {
00455         headerLength = 6;
00456         trailerLength = 8;
00457       } else {
00458         headerLength = 9;
00459         trailerLength = 5;
00460       }
00461 
00462       list<pair<int, int> > fragments = getFragmentList(eventBuffer);
00463 
00464       for(list<pair<int, int> >::const_iterator iter = fragments.begin();
00465           iter != fragments.end();
00466           iter++) {
00467 
00468         int L1ID, BCID;
00469         if(errorType) {
00470           L1ID = eventWord(eventBuffer, iter->first, 2);
00471           BCID = eventWord(eventBuffer, iter->first, 3);
00472         } else {
00473       if (hasPostSeptember2004Firmware(eventBuffer, iter->first)) {
00474             outFile << "Guessing new (post Oct '04) formatter version:\n";
00475             L1ID = eventWord(eventBuffer, iter->first, 6);
00476             BCID = eventWord(eventBuffer, iter->first, 7);
00477             headerLength=10;
00478           } else {
00479             outFile << "Guessing old formatter version:\n";
00480             L1ID = eventWord(eventBuffer, iter->first, 5);
00481             BCID = eventWord(eventBuffer, iter->first, 6);
00482           }
00483         }
00484 
00485         outFile << "Event Fragment: BCID: " << BCID << " L1ID: " << L1ID << endl;
00486 //         if(mrs) 
00487 //           *mrs << "FRAGMENT_REPORT" << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI") 
00488 //                << MRS_PARAM<int>("partition", rl->partition)
00489 //                << MRS_PARAM<int>("crate", rl->crate)
00490 //                << MRS_PARAM<int>("rod", rl->rod)
00491 //                << MRS_PARAM<int>("slave", slave)
00492 //                << MRS_PARAM<int>("bcid", BCID)
00493 //                << MRS_PARAM<int>("l1id", L1ID);
00494 
00495         int eofAt = findEOF(eventBuffer, iter->first);
00496 
00497         int eventLength = eofAt-headerLength-trailerLength;
00498 
00499         bool linkCondensed = false;
00500 
00501         int errorCount = eventWord(eventBuffer, iter->first, eofAt-trailerLength);
00502 
00503         if(errorCount > 0) {
00504           outFile << " Fragment in interval (" << iter->first << ", " << iter->second << "): " 
00505                   << errorCount << " errors\n";
00506 //           if(mrs)
00507 //             *mrs << MRS_PARAM<int>("errorCount", errorCount);
00508 
00509           int errorFlags = eventWord(eventBuffer, iter->first, eofAt-trailerLength + 1);
00510           vector<string> flagStrings = decodeEventFlags(errorFlags);
00511 
00512           string flagString;
00513 
00514           for(vector<string>::const_iterator iter = flagStrings.begin();
00515               iter != flagStrings.end();
00516               iter++) {
00517             flagString += *iter;
00518             flagString += " ";
00519           }
00520 
00521           outFile << " Error flags for frame: " << flagString << endl;
00522 //           if(mrs)
00523 //             *mrs << MRS_PARAM<const char *>("errorFlags", flagString.c_str());
00524         } else {
00525           // Try not to use the word error where there are no errors :-)
00526           outFile << " Fragment in interval (" << iter->first << ", " << iter->second << ")\n";
00527         }
00528 
00529 //         if(mrs) *mrs << ENDM;
00530 
00531     // Something different to the first word
00532     UINT16 lastWord = 0xffff;
00533     int repeats = 0;
00534 
00535         for(int i=0; i<eventLength * 2; i++) {
00536           UINT16 currWord;
00537           {
00538             UINT32 rawWord = eventWord(eventBuffer, iter->first, headerLength + i/2);
00539             if(i&1) {
00540               currWord = rawWord & 0x0000ffff;
00541             } else {
00542               currWord = (rawWord & 0xffff0000) >> 16;
00543             }
00544           }
00545 
00546       if(currWord == lastWord) {
00547         repeats ++;
00548         continue;
00549       } else if(repeats) {
00550         outFile << "   Repeated " << repeats << " more times\n";
00551         repeats = 0;
00552       }
00553 
00554       lastWord = currWord;
00555 
00556           string type;
00557           vector<pair<string, int> > arguments;
00558           vector<string> errors;
00559 
00560           decodeEventWord(currWord, errorType, linkCondensed, 
00561                           type, arguments, errors);
00562 
00563           if(type == "Header") {
00564             for(int i=0; i<arguments.size(); i++) {
00565               if(arguments[i].first == "Link") {
00566                 currentFibre = arguments[i].second;
00567               }
00568             }
00569           }
00570 
00571           if(errors.size() > 0) {
00572             outFile << " Event word with errors: " << type << endl;
00573 //             if(mrs) 
00574 //               *mrs << "EVENT_WORD" << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI") 
00575 //                    << MRS_TEXT("Event word with errors")
00576 //                    << MRS_PARAM<const char *>("wordType", type.c_str());
00577 
00578             // Something not right in output...
00579             if(currentFibre != -1) {
00580               FibreLocation f = {*rl, slave, currentFibre, errors[0]};
00581               errorMask.insert(f);
00582             }
00583           } else {
00584             outFile << " Event word: " << type << endl;
00585           }
00586 
00587           if(type == "Trailer") {
00588             currentFibre = -1;
00589           }
00590 
00591           outFile.width(4);
00592           outFile.fill('0');
00593           outFile << "  0x" << hex << currWord << dec;
00594           outFile.fill(' ');
00595 
00596           for(vector<pair<string, int> > :: const_iterator iter = arguments.begin();
00597               iter != arguments.end();
00598               iter ++) {
00599             outFile << " \"" << iter->first << "\": 0x" << hex << iter->second << dec;
00600 //             if(mrs && errors.size() > 0)
00601 //               *mrs << MRS_PARAM<int>(iter->first.c_str(), iter->second);
00602           }
00603 
00604           outFile << endl;
00605 
00606           if(errors.size() > 0) {
00607             string errorString;
00608             for(vector<string> :: const_iterator iter = errors.begin();
00609                 iter != errors.end();
00610                 iter ++) {
00611               errorString += " " + *iter;
00612             }
00613 
00614             outFile << "   Event errors: " << errorString << endl;
00615 //             if(mrs)
00616 //               *mrs << MRS_PARAM<const char *>("errors", errorString.c_str())
00617 //                    << ENDM;
00618           }
00619         }  // End of word loop
00620 
00621     if(repeats) {
00622       outFile << "   Repeated " << repeats << " more times\n";
00623       repeats = 0;
00624     }
00625       } // End of fragment
00626     } // Loop over slaves
00627   } // Loop over RODs
00628 
00629   for(set<FibreLocation>::const_iterator i = errorMask.begin(); 
00630       i != errorMask.end();
00631       i++) {
00632     const FibreLocation &f = *i;
00633     if(mrs) 
00634       *mrs << "EVENT_ERROR" << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI") 
00635            << MRS_TEXT("Error(s) in event from fibre")
00636            << MRS_PARAM<int>("partition", f.rod.partition)
00637            << MRS_PARAM<int>("crate", f.rod.crate)
00638            << MRS_PARAM<int>("rod", f.rod.rod)
00639            << MRS_PARAM<int>("slave", f.slave)
00640            << MRS_PARAM<int>("fibre", f.fibre)
00641            << MRS_PARAM<const char *>("firstError", f.firstError.c_str())
00642            << ENDM;
00643   }
00644 
00645   outFile << "End of event report for scan\n";
00646   outFile << "****************************\n";
00647 }
00648 
00649 UINT32 *SctApi::readEventBuffer(unsigned int rod, 
00650                                 int slave, bool extFlag, bool errorType) {
00651   long bufferBase;
00652   if(extFlag)
00653     bufferBase = 0x2092000;
00654   else {
00655     if(getCrate()->getRodRevision(rod) >= 0xe) {
00656       bufferBase = 0x18000; // BURST_BFR_BASE;
00657     } else {
00658       bufferBase = 0x80008000;
00659     }
00660   }
00661 
00662   // Storage for 32 frames
00663   UINT32 *frameBuffer = new UINT32[eventWords * 32];
00664 
00665   unsigned long *mem = primReadSlaveDsp(rod,
00666                                         slave, bufferBase, eventWords * 32);
00667 
00668   if(mem) {
00669     copy(mem, mem + eventWords*32, frameBuffer);
00670     delete [] mem;
00671   } else {
00672     return 0;
00673   }
00674 
00675   return frameBuffer;
00676 }
00677 
00678 int SctApi::getLastEventFrame(unsigned int rod, int slave) {
00679   unsigned long IDRAM_BASE;
00680   if(getCrate()->getRodRevision(rod) >= 0xe) {
00681     IDRAM_BASE = 0x10000;
00682   } else {
00683     IDRAM_BASE = 0x80000000;
00684   }
00685 
00686   unsigned long *regs = primReadSlaveDsp(rod, slave, IDRAM_BASE + 0x10, 20);
00687   unsigned long trapStat0 = regs[1]; 
00688 //   unsigned long trapStat1 = regs[2];
00689 
00690   int eventWordCount = trapStat0 & 0xffff;
00691   int frameTail = (trapStat0 & 0xff0000) >> 16;
00692 
00693   int eventFrames = (eventWordCount / eventWords) + 1;
00694 
00695   delete [] regs;
00696 
00697   return (frameTail - eventFrames) % frameCount;
00698 }
00699 
00700 } // Close SctApi namespace
00701 
00702 namespace {
00703 
00704 void decodeEventWord(UINT16 currWord, int errorType, bool &linkCondensed, 
00705                      string &type, vector<pair<string, int> > &arguments, vector<string> &errors) {
00706   type = "UNKNOWN";
00707   arguments.clear();
00708   errors.clear();
00709 
00710   switch((currWord & 0xe000) >> 13) {
00711   case 0:
00712     {
00713       if(currWord & 0x1f80) 
00714         type = "INVALID";
00715       else {
00716         // Flagged error
00717         type = "Flagged error";
00718         errors.push_back("FLAGGED");
00719         arguments.push_back(make_pair("chip", (currWord & 0x78) >> 3));
00720         arguments.push_back(make_pair("value", currWord & 0x7));
00721       }
00722     }
00723     break;
00724   case 1:
00725     {
00726       // Header
00727       type = "Header";
00728       if(errorType) {
00729         // No indication of whether its condensed...??
00730         arguments.push_back(make_pair("L1", ((currWord & 0x0f00) >> 8)));
00731         arguments.push_back(make_pair("BCID", ((currWord & 0xff))));
00732         if(currWord & 0x1000) {
00733           errors.push_back("Preamble err");
00734         }
00735       } else {
00736         arguments.push_back(make_pair("Link", (currWord & 0x7f)));
00737         if(currWord & 0x100) {
00738           arguments.push_back(make_pair("Condensed mode", 1));
00739           linkCondensed = true;
00740         } else {
00741           linkCondensed = false;
00742         }
00743         if(currWord & 0x200) 
00744           errors.push_back("BC err");
00745         if(currWord & 0x400)
00746           errors.push_back("L1 err");
00747         if(currWord & 0x800)
00748           errors.push_back("Time out err");
00749         if(currWord & 0x1000)
00750           errors.push_back("Preamble err");
00751       }
00752     }
00753     break;
00754   case 2:
00755     {
00756       if(currWord & 0x3ff) 
00757         type = "INVALID";
00758       else {
00759         // Trailer
00760         type = "Trailer";
00761         if(currWord & 0x400)
00762           errors.push_back("Data overflow err");
00763         if(currWord & 0x800)
00764           errors.push_back("H/T limit err");
00765         if(currWord & 0x1000)
00766           errors.push_back("Trailer bit err");
00767       }
00768     }
00769     break;
00770   case 3:
00771     {
00772       if(currWord & 0x300) 
00773         type = "INVALID";
00774       else {
00775         // Raw data
00776         type = "Raw";
00777         arguments.push_back(make_pair("bits", ((currWord & 0x1c00) >> 10) + 1));
00778         arguments.push_back(make_pair("value", (currWord & 0xff)));
00779       }
00780     }
00781     break;
00782   default:
00783     // Everything else (hits)
00784     {
00785       if((currWord & 0x2) == 0) {
00786         // Check if it should be condensed
00787         if(linkCondensed || errorType) {
00788           arguments.push_back(make_pair("Chip", ((currWord & 0x7800) >> 11)));
00789           arguments.push_back(make_pair("Channel", ((currWord & 0x7f0) >> 4)));
00790           if(currWord & 1) {
00791             type = "Condensed double hit";
00792             if(currWord & 0x4) errors.push_back("Error in hit1");
00793             if(currWord & 0x8) errors.push_back("Error in hit2");
00794           } else {
00795             type = "Condensed hit";
00796             if(currWord & 0x4) errors.push_back("Error in hit");
00797           }
00798         }
00799       }
00800 
00801       // Only check if expanded is a posibility
00802       if(!linkCondensed || errorType) {
00803         if(currWord & 0x8 == 0) {
00804           type = "1st hit clust exp";
00805           arguments.push_back(make_pair("Chip", ((currWord & 0x7800) >> 11)));
00806           arguments.push_back(make_pair("Channel", ((currWord & 0x7f0) >> 4)));
00807           arguments.push_back(make_pair("hits", currWord & 0x7));
00808         } else {
00809           if((currWord & 0x7f00) == 0) {
00810             type = "Clust exp";
00811             arguments.push_back(make_pair("hits", currWord & 0x7));
00812             if(currWord & 0x80) {
00813               arguments.push_back(make_pair("hits2", (currWord & 0x70) >> 4));
00814             }
00815           }
00816         }
00817       }
00818     }
00819   }
00820 }
00821 
00822 vector<string> decodeEventFlags(UINT32 flags) {
00823   vector<string> result;
00824 
00825   if(flags & 0x1) result.push_back("HEADER");
00826   if(flags & 0x2) result.push_back("TRAILER");
00827   if(flags & 0x4) result.push_back("FLAGGED");
00828   if(flags & 0x8) result.push_back("\"HIT PATTERN\"");
00829   if(flags & 0x10) result.push_back("SYNC");
00830   if(flags & 0x20) result.push_back("L1ID");
00831   if(flags & 0x40) result.push_back("BCID");
00832   if(flags & 0x80) result.push_back("TIMEOUT");
00833   if(flags & 0x100) result.push_back("\"ALMOST FULL\"");
00834   if(flags & 0x200) result.push_back("OVERFLOW");
00835   if(flags & 0x400) result.push_back("\"CHIP SEQ\"");
00836   if(flags & 0x800) result.push_back("\"BAD CHIP\"");
00837 
00838   return result;
00839 }
00840 
00841 list<pair<int, int> > getFragmentList(UINT32 *eventBuffer) {
00842   list<pair<int, int> > fragments;
00843   int firstEnd = -1; 
00844 
00845   int lastBegin = -1;
00846   int lastEnd = -1;
00847 
00848   for(int i=0; i<SctApi::frameCount; i++) {
00849     if((SctApi::eventWord(eventBuffer, i, 0) == 0xb0f00000)
00850        && (SctApi::eventWord(eventBuffer, i, 1) == 0xee1234ee)) {
00851       lastBegin = i;
00852     }
00853 
00854     if((SctApi::eventWord(eventBuffer, i+1, -1) & 0xff0e0000) == 0x400e0000) {
00855       if(lastBegin == -1) 
00856         firstEnd = i;
00857       lastEnd = i;
00858       if(lastBegin != -1) {
00859         fragments.push_back(make_pair(lastBegin, lastEnd));
00860         lastBegin = lastEnd = -1;
00861       }
00862     }
00863   }
00864 
00865   if(firstEnd != -1 && lastBegin != -1) {
00866     fragments.push_back(make_pair(lastBegin, firstEnd));
00867   }
00868 
00869   return fragments;
00870 }
00871 
00872 } // Close null namespace

Generated on Fri Sep 16 18:01:57 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5