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

Generated on Mon Feb 6 14:01:28 2006 for SCT DAQ/DCS Software - C++ by  doxygen 1.4.6