00001 #include <sys/mman.h>
00002 #include <sys/types.h>
00003 #include <sys/stat.h>
00004 #include <fcntl.h>
00005 #include <unistd.h>
00006
00007 #include <stdio.h>
00008
00009 #include <ipc/core.h>
00010 #include "cmdl/cmdargs.h"
00011
00012 #include <iostream>
00013 #include <vector>
00014 #include <string>
00015 #include <utility>
00016
00017 #include <boost/shared_ptr.hpp>
00018
00019
00020 #include "CommonWithDsp/processor.h"
00021
00022 #ifdef USE_CONFIG_FOR_EVENT_DECODER
00023 #include "sctConf/configRegistry.h"
00024 #include "sctConf/configuration.h"
00025 #include "config/Configuration.h"
00026 #endif
00027
00028 #ifdef USE_CONFIG_FOR_EVENT_DECODER
00029 using namespace SctConfiguration;
00030
00031 boost::shared_ptr<SctConfiguration::Configuration> config;
00032 #endif
00033
00034 using namespace std;
00035
00036 namespace {
00037 void decodeEventWord(UINT16 currWord, int errorType, bool &linkCondensed,
00038 string &type, vector<pair<string, int> > &arguments, vector<string> &errors);
00039
00040 vector<string> decodeEventFlags(UINT32 flags);
00041
00042 bool findNextEvent(UINT32* &start, UINT32* &finish, UINT32 *end, UINT32 startWord);
00043
00044 void decodeEvent(UINT32 *buffer, int length);
00045 }
00046
00047 inline std::string str(const char * word)
00048 {
00049 return word ? word : "";
00050 }
00051
00052 int main(int argc, char **argv) {
00053
00054
00055 #ifdef USE_CONFIG_FOR_EVENT_DECODER
00056 CmdArgBool use_config ('c',"use_config","Should we use a config to look up modules from links?",CmdArg::isOPT);
00057 #endif
00058 CmdArgStr input_file ("input_file","Name of input_file to read ROD fragment data from");
00059
00060 CmdLine cmd(*argv,
00061 #ifdef USE_CONFIG_FOR_EVENT_DECODER
00062 &use_config,
00063 #endif
00064 &input_file,NULL);
00065 cmd.description("An event stream decoder.");
00066
00067 CmdArgvIter argvIter(--argc,++argv);
00068 if (cmd.parse(argvIter))
00069 {
00070 std::cerr << "ERROR [eventStreamDecoder] Error parsing command line." << std::endl ;
00071 return EXIT_FAILURE;
00072 }
00073
00074 #ifdef USE_CONFIG_FOR_EVENT_DECODER
00075
00076 unsigned convert = use_config.flags();
00077 if ( convert & CmdArg::GIVEN ) {
00078
00079 unsigned configflags = configuration.flags();
00080 if ((!(configflags & CmdArg::GIVEN) && (!(configflags & CmdArg::VALGIVEN)))) {
00081 cout << "*** No configuration file string given on the command line" << endl;
00082 cout << "*** Using " << std::getenv("SCTDAQ_ROD_CONFIGURATION_PATH") << endl;
00083 configuration=std::getenv("SCTDAQ_ROD_CONFIGURATION_PATH");
00084 }
00085
00086 IPCCore::init(argc, argv);
00087 {
00088 std::string backendName = "xml";
00089 SctConfiguration::FactoryManager::instance().loadPlugin(backendName);
00090
00091 cout<< "The configuration service gets initialized from the default file" << endl;
00092 SctConfiguration::Factory &f = SctConfiguration::FactoryManager::instance().getFactory(backendName);
00093 cout<< "Now the configuration service gets reset from the default/user-defined file" << endl;
00094 config.reset(f.fromFile(str(configuration)));
00095 }
00096 }
00097 #endif
00098
00099 struct stat statStruct;
00100 int st = stat(input_file, &statStruct);
00101
00102 if(st!=0) {
00103 perror("Stat failed\n");
00104 return 1;
00105 }
00106
00107 int length = statStruct.st_size;
00108
00109 printf("Length: %d\n", length);
00110
00111 int fd = open(input_file, O_RDONLY);
00112
00113 if(fd == -1) {
00114 perror("File open failed\n");
00115 return 1;
00116 }
00117
00118 UINT32 *buffer = (UINT32 *)mmap(0, length, PROT_READ, MAP_PRIVATE, fd, 0);
00119 UINT32 *endBuffer = &buffer[length/4];
00120
00121 UINT32 *begin = buffer;
00122 UINT32 *end = buffer;
00123 bool found = findNextEvent(begin, end, endBuffer, 0xee1234ee);
00124
00125 while(found) {
00126 printf("Event from %d to %d\n", begin-buffer, end-buffer);
00127
00128 decodeEvent(begin, end-1-begin);
00129
00130
00131 found = findNextEvent(begin, end, endBuffer, 0xee1234ee);
00132 }
00133 }
00134
00135 namespace {
00136
00137
00138 bool findNextEvent(UINT32* &start, UINT32* &finish, UINT32 *end, UINT32 startWord) {
00139 start ++;
00140 if(start >= end) return false;
00141
00142 while(*start != startWord) {
00143 start++;
00144 if(start >= end) return false;
00145 }
00146
00147 finish = start+1;
00148
00149 while(!( ((*finish & 0x00ffff00) == 0x00123400) || ((*finish & 0xffff0000) == 0x12340000))) {
00150
00151 if(finish >= end) break;
00152 finish++;
00153 }
00154 return true;
00155 }
00156
00157 inline UINT32 eventWord(const UINT32 * const buffer, const int index, const int length) {
00158 if (index > length) {
00159 cout << "Attempt to read from the end of the buffer " << dec << index << " " << length << hex << endl;
00160 return 0;
00161 } else {
00162 return buffer[index-1];
00163 }
00164 }
00165
00166 void decodeEvent(UINT32 *frameBuffer, int length) {
00167 if(frameBuffer[0] == 0xee1234ee) {
00168 cout << "Valid header\n";
00169 } else {
00170 cout << "Bad check 0x" << hex << frameBuffer[0] << dec << endl;
00171 }
00172
00173 UINT32 headerLength = 9;
00174 UINT32 trailerLength = 5;
00175
00176 if(frameBuffer[1] != headerLength) {
00177 cout << "Unknown header length (" << frameBuffer[1] << ")\n";
00178 }
00179
00180 cout << "New formatter version:\n";
00181 cout << "Version: 0x" << hex << eventWord(frameBuffer, 3, length) << dec
00182 << " ID: " << eventWord(frameBuffer, 4, length)
00183 << " Run number = " << eventWord(frameBuffer, 5, length) << endl;
00184 cout << "L1ID = 0x" << hex << eventWord(frameBuffer, 6, length) << dec
00185 << " BCID = 0x" << hex << eventWord(frameBuffer, 7, length) << dec
00186 << " TType = " << eventWord(frameBuffer, 8, length)
00187 << " det type = " << eventWord(frameBuffer, 9, length) << endl;
00188
00189
00190 headerLength=10;
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 int eventLength = length - headerLength - trailerLength + 2;
00203
00204 UINT32 rawOffset = headerLength;
00205
00206
00207 UINT16 lastWord = 1 + ((eventWord(frameBuffer, rawOffset, length) & 0xffff0000) >> 16);
00208 UINT32 repeats = 0;
00209
00210 bool linkCondensed = true;
00211
00212 for(int i=0; i<eventLength * 2; i++) {
00213 UINT16 currWord;
00214 {
00215 UINT32 rawWord = eventWord(frameBuffer, rawOffset + i/2, length);
00216 if(i&1) {
00217 currWord = rawWord & 0x00ffff;
00218 } else {
00219 currWord = (rawWord & 0xffff0000) >> 16;
00220 }
00221 }
00222
00223 if(currWord == lastWord) {
00224 repeats ++;
00225 continue;
00226 } else if(repeats) {
00227 cout << " Repeated " << repeats << " times\n";
00228 repeats = 0;
00229 }
00230
00231 lastWord = currWord;
00232
00233 cout.width(4);
00234 cout.fill('0');
00235 cout << hex << currWord << dec;
00236 cout.fill(' ');
00237
00238 string type;
00239 vector<pair<string, int> > arguments;
00240 vector<string> errors;
00241
00242 decodeEventWord(currWord, 0, linkCondensed,
00243 type, arguments, errors);
00244
00245 cout << " " << type << " ";
00246 for(vector<pair<string, int> > :: const_iterator iter = arguments.begin();
00247 iter != arguments.end();
00248 iter ++) {
00249 cout << " " << iter->first << ": " << iter->second;
00250 }
00251
00252 if(errors.size() > 0) {
00253 cout << " ERRORS: ";
00254 }
00255 for(vector<string> :: const_iterator iter = errors.begin();
00256 iter != errors.end();
00257 iter ++) {
00258 cout << " " << *iter;
00259 }
00260 cout << endl;
00261
00262 }
00263
00264 if(repeats) {
00265 cout << " Repeated " << repeats << " times\n";
00266 repeats = 0;
00267 }
00268
00269 cout << "Error count = 0x" << hex << eventWord(frameBuffer, length-trailerLength + 2, length) << dec << endl;
00270 cout << "Error flags = 0x" << hex << eventWord(frameBuffer, length-trailerLength + 3, length) << dec << endl;
00271
00272 int flags = eventWord(frameBuffer, length-trailerLength + 3, length);
00273 vector<string> flagStrings = decodeEventFlags(flags);
00274 for(vector<string>::const_iterator iter = flagStrings.begin();
00275 iter != flagStrings.end();
00276 iter++) {
00277 cout << *iter << " ";
00278 }
00279
00280 if(flagStrings.size() > 0)
00281 cout << endl;
00282
00283 cout << "nData = " << eventWord(frameBuffer, length-trailerLength + 5, length)
00284 << " words found = " << (length - (headerLength + trailerLength) + 2) << endl;
00285 }
00286
00287 void decodeEventWord(UINT16 currWord, int errorType, bool &linkCondensed,
00288 string &type, vector<pair<string, int> > &arguments, vector<string> &errors) {
00289 type = "UNKNOWN";
00290 arguments.clear();
00291 errors.clear();
00292
00293 switch((currWord & 0xe000) >> 13) {
00294 case 0:
00295 {
00296 if(currWord & 0x1f80)
00297 type = "INVALID";
00298 else {
00299
00300 type = "Flagged error";
00301 errors.push_back("FLAGGED");
00302 arguments.push_back(make_pair("chip", (currWord & 0x78) >> 3));
00303 arguments.push_back(make_pair("value", currWord & 0x7));
00304 }
00305 }
00306 break;
00307 case 1:
00308 {
00309
00310 type = "Header";
00311 if(errorType) {
00312
00313 arguments.push_back(make_pair("L1", ((currWord & 0x0f00) >> 8)));
00314 arguments.push_back(make_pair("BCID", ((currWord & 0xff))));
00315 if(currWord & 0x1000) {
00316 errors.push_back("Preamble err");
00317 }
00318 } else {
00319 int link = (currWord & 0x7f);
00320 arguments.push_back(make_pair("Link", link));
00321
00322
00323
00324 #ifdef USE_CONFIG_FOR_EVENT_DECODER
00325 if (config.get()) try {
00326 unsigned int mur, module, channel;
00327 unsigned int order = (link%128)/16;
00328 unsigned side = link%2;
00329 channel = (order*6) + (link%12)/2;
00330
00331 config->translateFromROD(0,0,link/128, channel, mur, module);
00332 #warning 'above line might still be BROKEN! needs to be TESTED!!! :( BD'
00333 arguments.push_back(make_pair("MUR", mur));
00334 arguments.push_back(make_pair("Module",module));
00335 arguments.push_back(make_pair("Side",side));
00336 } catch ( std::exception& E ) {
00337 cout << " Caught exception in config lookup " << E.what() << endl;
00338 }
00339 #endif
00340
00341 if(currWord & 0x100) {
00342 arguments.push_back(make_pair("Condensed mode", 1));
00343 linkCondensed = true;
00344 } else {
00345 linkCondensed = false;
00346 }
00347 if(currWord & 0x200)
00348 errors.push_back("BC err");
00349 if(currWord & 0x400)
00350 errors.push_back("L1 err");
00351 if(currWord & 0x800)
00352 errors.push_back("Time out err");
00353 if(currWord & 0x1000)
00354 errors.push_back("Preamble err");
00355 }
00356 }
00357 break;
00358 case 2:
00359 {
00360 if(currWord & 0x3ff)
00361 type = "INVALID";
00362 else {
00363
00364 type = "Trailer";
00365 if(currWord & 0x400)
00366 errors.push_back("Data overflow err");
00367 if(currWord & 0x800)
00368 errors.push_back("H/T limit err");
00369 if(currWord & 0x1000)
00370 errors.push_back("Trailer bit err");
00371 }
00372 }
00373 break;
00374 case 3:
00375 {
00376 if(currWord & 0x300)
00377 type = "INVALID";
00378 else {
00379
00380 type = "Raw";
00381 arguments.push_back(make_pair("bits", ((currWord & 0x1c00) >> 10) + 1));
00382 arguments.push_back(make_pair("value", (currWord & 0xff)));
00383 }
00384 }
00385 break;
00386 default:
00387
00388 {
00389 if((currWord & 0x2) == 0) {
00390
00391 if(linkCondensed || errorType) {
00392 arguments.push_back(make_pair("Chip", ((currWord & 0x7800) >> 11)));
00393 arguments.push_back(make_pair("Channel", ((currWord & 0x7f0) >> 4)));
00394 if(currWord & 1) {
00395 type = "Condensed double hit";
00396 if(currWord & 0x4) errors.push_back("Error in hit1");
00397 if(currWord & 0x8) errors.push_back("Error in hit2");
00398 } else {
00399 type = "Condensed hit";
00400 if(currWord & 0x4) errors.push_back("Error in hit");
00401 }
00402 }
00403 }
00404
00405
00406 if(!linkCondensed || errorType) {
00407 if((currWord & 0x8) == 0) {
00408 type = "1st hit clust exp";
00409 arguments.push_back(make_pair("Chip", ((currWord & 0x7800) >> 11)));
00410 arguments.push_back(make_pair("Channel", ((currWord & 0x7f0) >> 4)));
00411 arguments.push_back(make_pair("hits", currWord & 0x7));
00412 } else {
00413 if((currWord & 0x7f00) == 0) {
00414 type = "Clust exp";
00415 arguments.push_back(make_pair("hits", currWord & 0x7));
00416 if(currWord & 0x80) {
00417 arguments.push_back(make_pair("hits2", (currWord & 0x70) >> 4));
00418 }
00419 }
00420 }
00421 }
00422 }
00423 }
00424 }
00425
00426 vector<string> decodeEventFlags(UINT32 flags) {
00427 vector<string> result;
00428
00429 if(flags & 0x1) result.push_back("HEADER");
00430 if(flags & 0x2) result.push_back("TRAILER");
00431 if(flags & 0x4) result.push_back("FLAGGED");
00432 if(flags & 0x8) result.push_back("\"HIT PATTERN\"");
00433 if(flags & 0x10) result.push_back("SYNC");
00434 if(flags & 0x20) result.push_back("L1ID");
00435 if(flags & 0x40) result.push_back("BCID");
00436 if(flags & 0x80) result.push_back("TIMEOUT");
00437 if(flags & 0x100) result.push_back("\"ALMOST FULL\"");
00438 if(flags & 0x200) result.push_back("OVERFLOW");
00439 if(flags & 0x400) result.push_back("\"CHIP SEQ\"");
00440 if(flags & 0x800) result.push_back("\"BAD CHIP\"");
00441
00442 return result;
00443 }
00444 }