bug fixed
[u/mrichter/AliRoot.git] / RAW / AliAltroRawStreamV3.cxx
CommitLineData
f8e5b5a0 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16///////////////////////////////////////////////////////////////////////////////
17///
18/// This is a base class for reading raw data digits in Altro format.
19/// The class is able to read the RCU v3 and above formats.
20/// The main difference between the format V3 and older ones is in
21/// the coding of the 10-bit Altro payload words. In V3 3 10-bit words
22/// are coded in one 32-bit word. The bits 30 and 31 are used to identify
23/// the payload, altro header and RCU trailer contents.
24///
25///
26/// cvetan.cheshkov@cern.ch 1/04/2009
27///////////////////////////////////////////////////////////////////////////////
28
29#include "AliAltroRawStreamV3.h"
30#include "AliRawReader.h"
31#include "AliLog.h"
0148e633 32#include "AliAltroRawStream.h"
eae29211 33#include "AliRawEventHeaderBase.h"
f8e5b5a0 34
35ClassImp(AliAltroRawStreamV3)
36
37
38//_____________________________________________________________________________
39AliAltroRawStreamV3::AliAltroRawStreamV3(AliRawReader* rawReader) :
40 fIsShortDataHeader(kFALSE),
41 fDDLNumber(-1),
42 fRCUId(-1),
43 fHWAddress(-1),
44 fRawReader(rawReader),
45 fData(NULL),
46 fPosition(-1),
47 fCount(-1),
48 fStartTimeBin(-1),
49 fBunchLength(-1),
50 fBadChannel(kFALSE),
51 fPayloadSize(-1),
e76a0935 52 fChannelPayloadSize(-1),
6d4dd848 53 fBunchDataPointer(NULL),
54 fBunchDataIndex(-1),
f8e5b5a0 55 fRCUTrailerData(NULL),
56 fRCUTrailerSize(0),
57 fFECERRA(0),
58 fFECERRB(0),
59 fERRREG2(0),
60 fERRREG3(0),
f8e5b5a0 61 fActiveFECsA(0),
62 fActiveFECsB(0),
63 fAltroCFG1(0),
0148e633 64 fAltroCFG2(0),
3ce326c0 65 fOldStream(NULL),
66 fCheckAltroPayload(kTRUE)
f8e5b5a0 67{
68 // Constructor
69 // Create an object to read Altro raw digits in
70 // RCU version 3 and beyond format
71 for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = 0;
72}
73
74//_____________________________________________________________________________
75AliAltroRawStreamV3::~AliAltroRawStreamV3()
76{
77// destructor
0148e633 78// delete old stream object if one exists
79 if (fOldStream) delete fOldStream;
f8e5b5a0 80}
81
82//_____________________________________________________________________________
83AliAltroRawStreamV3::AliAltroRawStreamV3(const AliAltroRawStreamV3& stream) :
84 TObject(stream),
85 fIsShortDataHeader(stream.fIsShortDataHeader),
86 fDDLNumber(stream.fDDLNumber),
87 fRCUId(stream.fRCUId),
88 fHWAddress(stream.fHWAddress),
89 fRawReader(stream.fRawReader),
90 fData(stream.fData),
91 fPosition(stream.fPosition),
92 fCount(stream.fCount),
93 fStartTimeBin(stream.fStartTimeBin),
94 fBunchLength(stream.fBunchLength),
95 fBadChannel(stream.fBadChannel),
96 fPayloadSize(stream.fPayloadSize),
e76a0935 97 fChannelPayloadSize(stream.fChannelPayloadSize),
6d4dd848 98 fBunchDataPointer(stream.fBunchDataPointer),
99 fBunchDataIndex(stream.fBunchDataIndex),
f8e5b5a0 100 fRCUTrailerData(stream.fRCUTrailerData),
101 fRCUTrailerSize(stream.fRCUTrailerSize),
102 fFECERRA(stream.fFECERRA),
103 fFECERRB(stream.fFECERRB),
104 fERRREG2(stream.fERRREG2),
105 fERRREG3(stream.fERRREG3),
f8e5b5a0 106 fActiveFECsA(stream.fActiveFECsA),
107 fActiveFECsB(stream.fActiveFECsB),
108 fAltroCFG1(stream.fAltroCFG1),
0148e633 109 fAltroCFG2(stream.fAltroCFG2),
3ce326c0 110 fOldStream(NULL),
111 fCheckAltroPayload(stream.fCheckAltroPayload)
f8e5b5a0 112{
113 // Copy constructor
114 // Copy the bunch data array
115 for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = stream.fBunchData[i];
0148e633 116
117 if (stream.fOldStream)
118 fOldStream = new AliAltroRawStream(*stream.fOldStream);
f8e5b5a0 119}
120
121//_____________________________________________________________________________
122AliAltroRawStreamV3& AliAltroRawStreamV3::operator = (const AliAltroRawStreamV3& stream)
123{
124 // assignment operator
125 // ...
126 if(&stream == this) return *this;
127
128 fIsShortDataHeader = stream.fIsShortDataHeader;
129 fDDLNumber = stream.fDDLNumber;
130 fRCUId = stream.fRCUId;
131 fHWAddress = stream.fHWAddress;
132 fRawReader = stream.fRawReader;
133 fData = stream.fData;
134 fPosition = stream.fPosition;
135 fCount = stream.fCount;
136 fStartTimeBin = stream.fStartTimeBin;
137 fBunchLength = stream.fBunchLength;
138 fBadChannel = stream.fBadChannel;
139 fPayloadSize = stream.fPayloadSize;
e76a0935 140 fChannelPayloadSize= stream.fChannelPayloadSize;
6d4dd848 141 fBunchDataPointer = stream.fBunchDataPointer;
142 fBunchDataIndex = stream.fBunchDataIndex;
f8e5b5a0 143 fRCUTrailerData = stream.fRCUTrailerData;
144 fRCUTrailerSize = stream.fRCUTrailerSize;
145 fFECERRA = stream.fFECERRA;
146 fFECERRB = stream.fFECERRB;
147 fERRREG2 = stream.fERRREG2;
148 fERRREG3 = stream.fERRREG3;
f8e5b5a0 149 fActiveFECsA = stream.fActiveFECsA;
150 fActiveFECsB = stream.fActiveFECsB;
151 fAltroCFG1 = stream.fAltroCFG1;
152 fAltroCFG2 = stream.fAltroCFG2;
153
154 for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = stream.fBunchData[i];
155
0148e633 156 if (stream.fOldStream) {
157 if (fOldStream) delete fOldStream;
158 fOldStream = new AliAltroRawStream(stream.fRawReader);
159 *fOldStream = *stream.fOldStream;
160 }
161
3ce326c0 162 fCheckAltroPayload = stream.fCheckAltroPayload;
163
f8e5b5a0 164 return *this;
165}
166
167//_____________________________________________________________________________
168void AliAltroRawStreamV3::Reset()
169{
170// Complete reset of raw stream params
171// Reset of the raw-reader as well
172
173 fDDLNumber = fRCUId = fHWAddress = -1;
174 fPosition = fCount = -1;
175 fBunchLength = fStartTimeBin = -1;
176 fBadChannel = kFALSE;
177 fPayloadSize = -1;
e76a0935 178 fChannelPayloadSize = -1;
6d4dd848 179 fBunchDataPointer = NULL;
180 fBunchDataIndex = -1;
f8e5b5a0 181
182 fRCUTrailerData = NULL;
183 fRCUTrailerSize = 0;
184
9283f3a5 185 fFECERRA = fFECERRB = fERRREG2 = fERRREG3 = fActiveFECsA = fActiveFECsB = fAltroCFG1 = fAltroCFG2 = 0;
f8e5b5a0 186
187 if (fRawReader) fRawReader->Reset();
188
0148e633 189 if (fOldStream) fOldStream->Reset();
f8e5b5a0 190}
191
192//_____________________________________________________________________________
193Bool_t AliAltroRawStreamV3::NextDDL()
194{
195// Read the next DDL payload (CDH + RCU trailer)
196// Updates the information which is coming from these
197// two sources
198
199 fPosition = 0;
200 // Get next DDL payload
201 // return wtih false in case no more data payloads
202 // are found
203 do {
204 if (!fRawReader->ReadNextData(fData)) return kFALSE;
205 } while (fRawReader->GetDataSize() == 0);
206
207 fDDLNumber = fRawReader->GetDDLID();
e76a0935 208 fChannelPayloadSize = -1;
f8e5b5a0 209
210 UChar_t rcuVer = fRawReader->GetBlockAttributes();
211
0148e633 212 if (rcuVer < 2) {
213 // old altro format data
214 if (!fOldStream) {
215 fOldStream = new AliAltroRawStream(fRawReader);
216 AliInfo(Form("RCU firmware verion %d detected. Using AliAltroRawStream to decode the data.",
217 rcuVer));
218 }
219 Bool_t status = fOldStream->NextDDL(fData);
220 if (status) {
221 fRCUId = fOldStream->GetRCUId();
222 fRCUTrailerSize = fOldStream->GetRCUTrailerSize();
223 fOldStream->GetRCUTrailerData(fRCUTrailerData);
224 fFECERRA = fOldStream->GetFECERRA();
225 fFECERRB = fOldStream->GetFECERRB();
226 fERRREG2 = fOldStream->GetERRREG2();
227 fERRREG3 = ((UInt_t)fOldStream->GetNChAddrMismatch()) |
228 (((UInt_t)fOldStream->GetNChLengthMismatch()) << 12);
229 fActiveFECsA = fOldStream->GetActiveFECsA();
230 fActiveFECsB = fOldStream->GetActiveFECsB();
231 fAltroCFG1 = fOldStream->GetAltroCFG1();
232 fAltroCFG2 = fOldStream->GetAltroCFG2();
eae29211 233 if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData)
234 fPayloadSize = fOldStream->GetRCUPayloadSizeInSOD();
0148e633 235 }
236 return status;
237 }
f8e5b5a0 238
0148e633 239 return ReadRCUTrailer(rcuVer);
f8e5b5a0 240}
241
242//_____________________________________________________________________________
243Bool_t AliAltroRawStreamV3::NextChannel()
244{
245 // Read the next Altro channel from the
246 // raw-data stream
247 // Updates the channel hardware address member and
248 // channel data size. Sets the error flag in case
249 // RCU signals readout error in this channel
0148e633 250 if (fOldStream) {
251 Bool_t status = fOldStream->NextChannel();
e76a0935 252 if (status) {
253 fHWAddress = fOldStream->GetHWAddress();
254 fChannelPayloadSize = fOldStream->GetChannelPayloadSize();
255 }
0148e633 256 return status;
257 }
258
f8e5b5a0 259 fCount = -1;
260 fBadChannel = kFALSE;
6d4dd848 261 fBunchDataIndex = 0;
3ce326c0 262 fBunchLength = -1;
f8e5b5a0 263
264 UInt_t word = 0;
265 do {
266 word = Get32bitWord(fPosition++);
6d4dd848 267 if (fPosition > fPayloadSize) return kFALSE;
f8e5b5a0 268 }
6d4dd848 269 while ((word >> 30) != 1);
f8e5b5a0 270
271 // check for readout errors
6d4dd848 272 fBadChannel = (word >> 29) & 0x1;
f8e5b5a0 273
274 // extract channel payload and hw address
6d4dd848 275 fCount = (word >> 16) & 0x3FF;
e76a0935 276 fChannelPayloadSize = fCount;
f8e5b5a0 277 fHWAddress = word & 0xFFF;
278
6d4dd848 279 // Now unpack the altro data
280 // Revert the order of the samples
281 // inside the bunch so that the
282 // first time is first in the samples
283 // array
284 Int_t isample = 0;
285 Int_t nwords = (fCount+2)/3;
286 for (Int_t iword = 0; iword < nwords; iword++) {
287 word = Get32bitWord(fPosition++);
288 if ((word >> 30) != 0) {
289 // Unexpected end of altro channel payload
499187ca 290 AliWarning(Form("Unexpected end of payload in altro channel payload! DDL=%03d, Address=0x%x, word=0x%x",
291 fDDLNumber,fHWAddress,word));
6d4dd848 292 fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
499187ca 293 if (AliDebugLevel() > 0) HexDumpChannel();
6d4dd848 294 fCount = -1;
295 fPosition--;
296 return kFALSE;
297 }
298 fBunchData[isample++] = (word >> 20) & 0x3FF;
299 fBunchData[isample++] = (word >> 10) & 0x3FF;
300 fBunchData[isample++] = word & 0x3FF;
301 }
302
f8e5b5a0 303 return kTRUE;
304}
305
306//_____________________________________________________________________________
307Bool_t AliAltroRawStreamV3::NextBunch()
308{
309 // Read next altro bunch from the
310 // raw-data stream.
311 // Updates the start/end time-bins
312 // and the array with altro samples
0148e633 313 if (fOldStream) {
314 Bool_t status = fOldStream->NextBunch(fBunchData,fBunchLength,fStartTimeBin);
315 if (status) fBunchDataPointer = &fBunchData[0];
316 else fBunchDataPointer = NULL;
317 return status;
318 }
319
3ce326c0 320 Int_t prevTimeBin = (fBunchLength > 0) ? fStartTimeBin-fBunchLength+1 : 1024;
f8e5b5a0 321 fBunchLength = fStartTimeBin = -1;
6d4dd848 322 fBunchDataPointer = NULL;
f8e5b5a0 323
6d4dd848 324 if ((fBunchDataIndex >= fCount) || fBadChannel) return kFALSE;
f8e5b5a0 325
6d4dd848 326 fBunchLength = fBunchData[fBunchDataIndex];
3ce326c0 327 if (fBunchLength <= 2) {
328 // Invalid bunch size
499187ca 329 AliWarning(Form("Too short bunch length (%d) in Address=0x%x (DDL=%03d)!",
330 fBunchLength,fDDLNumber,fHWAddress));
3ce326c0 331 fRawReader->AddMinorErrorLog(kAltroBunchHeadErr,Form("hw=0x%x",fHWAddress));
499187ca 332 if (AliDebugLevel() > 0) HexDumpChannel();
3ce326c0 333 fCount = fBunchLength = -1;
334 return kFALSE;
335 }
6d4dd848 336 if ((fBunchDataIndex + fBunchLength) > fCount) {
f8e5b5a0 337 // Too long bunch detected
499187ca 338 AliWarning(Form("Too long bunch detected in Address=0x%x (DDL=%03d) ! Expected <= %d 10-bit words, found %d !",
339 fHWAddress,fDDLNumber,fCount-fBunchDataIndex,fBunchLength));
f8e5b5a0 340 fRawReader->AddMinorErrorLog(kAltroBunchHeadErr,Form("hw=0x%x",fHWAddress));
499187ca 341 if (AliDebugLevel() > 0) HexDumpChannel();
f8e5b5a0 342 fCount = fBunchLength = -1;
343 return kFALSE;
344 }
6d4dd848 345 fBunchDataIndex++;
f8e5b5a0 346 fBunchLength -= 2;
347
6d4dd848 348 fStartTimeBin = fBunchData[fBunchDataIndex++];
3ce326c0 349 if (fCheckAltroPayload) {
350 if ((fStartTimeBin-fBunchLength+1) < 0) {
499187ca 351 AliWarning(Form("Invalid start time-bin in Address=0x%x (DDL=%03d)! (%d-%d+1) < 0",
352 fHWAddress,fDDLNumber,fStartTimeBin,fBunchLength));
3ce326c0 353 fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
499187ca 354 if (AliDebugLevel() > 0) HexDumpChannel();
3ce326c0 355 fCount = fBunchLength = -1;
356 return kFALSE;
357 }
358 if (fStartTimeBin >= prevTimeBin) {
499187ca 359 AliWarning(Form("Invalid start time-bin in Address=0x%x (DDL=%03d)! (%d>=%d)",
360 fHWAddress,fDDLNumber,fStartTimeBin,prevTimeBin));
3ce326c0 361 fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
499187ca 362 if (AliDebugLevel() > 0) HexDumpChannel();
3ce326c0 363 fCount = fBunchLength = -1;
364 return kFALSE;
365 }
366 }
f8e5b5a0 367
6d4dd848 368 fBunchDataPointer = &fBunchData[fBunchDataIndex];
f8e5b5a0 369
6d4dd848 370 fBunchDataIndex += fBunchLength;
f8e5b5a0 371
372 return kTRUE;
373}
374
375//_____________________________________________________________________________
376UInt_t AliAltroRawStreamV3::Get32bitWord(Int_t index) const
377{
378 // This method returns the 32 bit word at a given
379 // position inside the raw data payload.
380 // The 'index' points to the beginning of the word.
381 // The method is supposed to be endian (platform)
382 // independent.
383
384 index = (index << 2);
385 UInt_t word = 0;
386 word |= fData[index++];
387 word |= fData[index++] << 8;
388 word |= fData[index++] << 16;
389 word |= fData[index++] << 24;
390
391 return word;
392}
393
394///_____________________________________________________________________________
395Bool_t AliAltroRawStreamV3::ReadRCUTrailer(UChar_t rcuVer)
396{
397 // Read the RCU trailer according
398 // to the RCU formware version
399 // specified in CDH
400 // Cross-check with version found in the
401 // trailer
402
403 fRCUTrailerData = NULL;
404 fRCUTrailerSize = 0;
405 fPayloadSize = -1;
406
407 Int_t index = fRawReader->GetDataSize()/4;
408
409 // First read 32-bit word with the
410 // trailer size (7 bits), RCU ID (9 bits) and
411 // RCU firmware version (8 bits?)
412 // The two major bit should be 11 (identifies
413 // the end of the trailer)
414 UInt_t word = Get32bitWord(--index);
415
416 if ((word >> 30) != 3) {
417 fRawReader->AddFatalErrorLog(kRCUTrailerErr,"");
418 AliError("Last RCU trailer word not found!");
419 return kFALSE;
420 }
421
422 UChar_t ver = (word >> 16) & 0xFF;
423 if (ver != rcuVer) {
424 // Wrong RCU firmware version detected
425 fRawReader->AddMajorErrorLog(kRCUVerErr,Form("%d!=%d",
426 ver,rcuVer));
427 AliDebug(1,Form("Wrong RCU firmware version detected: %d != %d",
428 ver,rcuVer));
429 }
430
431 fRCUId = (Int_t)((word >> 7) & 0x1FF);
432 Int_t trailerSize = (word & 0x7F);
433
434 // Now read the beginning of the trailer
435 // where the payload size is written
436 if (trailerSize < 2) {
437 fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d bytes",
438 trailerSize*4));
439 AliWarning(Form("Invalid trailer size found (%d bytes) !",
440 trailerSize*4));
441 return kFALSE;
442 }
443
444 trailerSize -= 2;
445 fRCUTrailerSize = trailerSize*4;
446
447 for (; trailerSize > 0; trailerSize--) {
448 word = Get32bitWord(--index);
449 if ((word >> 30) != 2) {
450 fRawReader->AddMinorErrorLog(kRCUTrailerErr,"missing 10");
451 AliWarning("Missing RCU trailer identifier pattern!");
452 continue;
453 }
454 Int_t parCode = (word >> 26) & 0xF;
455 Int_t parData = word & 0x3FFFFFF;
456 switch (parCode) {
457 case 1:
458 // ERR_REG1
459 fFECERRA = ((parData >> 13) & 0x1FFF) << 7;
460 fFECERRB = ((parData & 0x1FFF)) << 7;
461 break;
462 case 2:
463 // ERR_REG2
464 fERRREG2 = parData & 0x1FF;
465 break;
466 case 3:
467 // ERR_REG3
9283f3a5 468 fERRREG3 = parData & 0x1FFFFFF;
f8e5b5a0 469 break;
470 case 4:
f8e5b5a0 471 // FEC_RO_A
472 fActiveFECsA = parData & 0xFFFF;
473 break;
9283f3a5 474 case 5:
f8e5b5a0 475 // FEC_RO_B
476 fActiveFECsB = parData & 0xFFFF;
477 break;
9283f3a5 478 case 6:
f8e5b5a0 479 // RDO_CFG1
480 fAltroCFG1 = parData & 0xFFFFF;
481 break;
9283f3a5 482 case 7:
f8e5b5a0 483 // RDO_CFG2
484 fAltroCFG2 = parData & 0x1FFFFFF;
485 break;
486 default:
487 fRawReader->AddMinorErrorLog(kRCUTrailerErr,"undef word");
488 AliWarning(Form("Undefined parameter code %d, ignore it !",
489 parCode));
490 break;
491 }
492 }
493
494 if (index < 1) {
495 fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d raw=%d bytes",
496 fRCUTrailerSize+8,
497 fRawReader->GetDataSize()));
498 AliWarning(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
499 fRCUTrailerSize,
500 fRawReader->GetDataSize()));
501 }
502
503 fRCUTrailerData = fData + index*4;
504
505 // Now read the payload size
506 // (First word in the RCU trailer)
507 fPayloadSize = Get32bitWord(--index) & 0x3FFFFFF;
508
509 if ((fRawReader->GetDataSize() - fRCUTrailerSize - 8) != (fPayloadSize*4)) {
510 fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d tr=%d rcu=%d bytes",
511 fRawReader->GetDataSize(),
512 fRCUTrailerSize+8,
513 fPayloadSize*4));
514 AliWarning(Form("Inconsistent raw data size ! Raw data size - %d bytes (from CDH), RCU trailer - %d bytes, raw data size (from RCU trailer) - %d bytes !",
515 fRawReader->GetDataSize(),
516 fRCUTrailerSize+8,
517 fPayloadSize*4));
518 }
519
520 return kTRUE;
521}
522
523//_____________________________________________________________________________
524Int_t AliAltroRawStreamV3::GetBranch() const
525{
526 // The method provides the RCU branch index (0 or 1)
527 // for the current hardware address.
528 // In case the hardware address has not been yet
529 // initialized, the method returns -1
530 if (fHWAddress == -1) return -1;
531
532 return ((fHWAddress >> 11) & 0x1);
533}
534
535//_____________________________________________________________________________
536Int_t AliAltroRawStreamV3::GetFEC() const
537{
538 // The method provides the front-end card index
539 // for the current hardware address.
540 // In case the hardware address has not been yet
541 // initialized, the method returns -1
542 if (fHWAddress == -1) return -1;
543
544 return ((fHWAddress >> 7) & 0xF);
545}
546
547//_____________________________________________________________________________
548Int_t AliAltroRawStreamV3::GetAltro() const
549{
550 // The method provides the altro chip index
551 // for the current hardware address.
552 // In case the hardware address has not been yet
553 // initialized, the method returns -1
554 if (fHWAddress == -1) return -1;
555
556 return ((fHWAddress >> 4) & 0x7);
557}
558
559//_____________________________________________________________________________
560Int_t AliAltroRawStreamV3::GetChannel() const
561{
562 // The method provides the channel index
563 // for the current hardware address.
564 // In case the hardware address has not been yet
565 // initialized, the method returns -1
566 if (fHWAddress == -1) return -1;
567
568 return (fHWAddress & 0xF);
569}
570
571//_____________________________________________________________________________
572Bool_t AliAltroRawStreamV3::GetRCUTrailerData(UChar_t*& data) const
573{
574 // Return a pointer to the RCU trailer
575 // data. Should be called always after
576 // the RCU trailer was already processed
577 // in the GetPosition() method
578 if (!fRCUTrailerSize || !fRCUTrailerData) {
579 AliError("No valid RCU trailer data is found !");
580 data = NULL;
581 return kFALSE;
582 }
583
584 data = fRCUTrailerData;
585
586 return kTRUE;
587}
588
589//_____________________________________________________________________________
590void AliAltroRawStreamV3::PrintRCUTrailer() const
591{
592 // Prints the contents of
593 // the RCU trailer data
594 printf("RCU trailer:\n===========\n");
595 printf("FECERRA: 0x%x\nFECERRB: 0x%x\n",fFECERRA,fFECERRB);
596 printf("ERRREG2: 0x%x\n",fERRREG2);
597 printf("#channels skipped due to address mismatch: %d\n",GetNChAddrMismatch());
598 printf("#channels skipped due to bad block length: %d\n",GetNChLengthMismatch());
599 printf("Active FECs (branch A): 0x%x\nActive FECs (branch B): 0x%x\n",fActiveFECsA,fActiveFECsB);
600 printf("Baseline corr: 0x%x\n",GetBaselineCorr());
601 printf("Number of presamples: %d\nNumber of postsamples: %d\n",GetNPresamples(),GetNPostsamples());
602 printf("Second baseline corr: %d\n",GetSecondBaselineCorr());
603 printf("GlitchFilter: %d\n",GetGlitchFilter());
604 printf("Number of non-ZS postsamples: %d\nNumber of non-ZS presamples: %d\n",GetNNonZSPostsamples(),GetNNonZSPresamples());
605 printf("Number of ALTRO buffers: %d\n",GetNAltroBuffers());
606 printf("Number of pretrigger samples: %d\n",GetNPretriggerSamples());
607 printf("Number of samples per channel: %d\n",GetNSamplesPerCh());
608 printf("Sparse readout: %d\n",GetSparseRO());
609 printf("Sampling time: %e s\n",GetTSample());
610 printf("L1 Phase: %e s\n",GetL1Phase());
611 printf("AltroCFG1: 0x%x\nAltroCFG2: 0x%x\n",GetAltroCFG1(),GetAltroCFG2());
612 printf("===========\n");
613}
614
615//_____________________________________________________________________________
616void AliAltroRawStreamV3::SelectRawData(Int_t detId)
617{
618 // Select the raw data for specific
619 // detector id
620 AliDebug(1,Form("Selecting raw data for detector %d",detId));
621 fRawReader->Select(detId);
622}
623
624//_____________________________________________________________________________
625void AliAltroRawStreamV3::SelectRawData(const char *detName)
626{
627 // Select the raw data for specific
628 // detector name
629 AliDebug(1,Form("Selecting raw data for detector %s",detName));
630 fRawReader->Select(detName);
631}
632
633//_____________________________________________________________________________
634Double_t AliAltroRawStreamV3::GetTSample() const
635{
636 // Returns the sampling time
637 // in seconds. In case the rcu trailer
638 // was note read, return an invalid number (0)
639
640 if (!fRCUTrailerData) return 0.;
641
642 const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
643 UChar_t fq = (fAltroCFG2 >> 5) & 0xF;
644 Double_t tSample;
645 switch (fq) {
646 case 0:
647 // 20 MHz
648 tSample = 2.0*kLHCTimeSample;
649 break;
650 case 1:
651 // 10 Mhz
652 tSample = 4.0*kLHCTimeSample;
653 break;
654 case 2:
655 // 5 MHz
656 tSample = 8.0*kLHCTimeSample;
657 break;
658 default:
659 AliWarning(Form("Invalid sampling frequency value %d !",
660 fq));
661 tSample = 0.;
662 break;
663 }
664
665 return tSample;
666}
667
668//_____________________________________________________________________________
669Double_t AliAltroRawStreamV3::GetL1Phase() const
670{
671 // Returns the L1 phase w.r.t to the
672 // LHC clock
673 if (!fRCUTrailerData) return 0.;
674
675 const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
676 Double_t phase = ((Double_t)(fAltroCFG2 & 0x1F))*kLHCTimeSample;
677
678 Double_t tSample = GetTSample();
679 if (phase >= tSample) {
6c12d59f 680 AliWarning(Form("Invalid L1 trigger phase (%f >= %f) !",
f8e5b5a0 681 phase,tSample));
682 phase = 0.;
683 }
684
685 return phase;
686}
687
688//_____________________________________________________________________________
689void AliAltroRawStreamV3::AddMappingErrorLog(const char *message)
690{
691 // Signal a mapping error
692 // The method can be used by the TPC,PHOS,EMCAL,FMD raw stream
693 // classes in order to log an error related to bad altro mapping
694
695 if (fRawReader) fRawReader->AddMinorErrorLog(kBadAltroMapping,message);
696}
eae29211 697
698//_____________________________________________________________________________
699UChar_t *AliAltroRawStreamV3::GetRCUPayloadInSOD() const
700{
701 // Get a pointer to the data in case
702 // of SOD events
703 if (fRawReader) {
704 if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData) {
705 return fData;
706 }
707 }
708 return NULL;
709}
710
711//_____________________________________________________________________________
712Int_t AliAltroRawStreamV3::GetRCUPayloadSizeInSOD() const
713{
714 // Get the size of the RCU data in case
715 // of SOD events
716 if (fRawReader) {
717 if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData) {
718 return fPayloadSize;
719 }
720 }
721 return -1;
722}
499187ca 723
724//_____________________________________________________________________________
725
726void AliAltroRawStreamV3::HexDumpChannel() const
727{
728 // Print of the Hex Data of the current channel
729 // to decipher read-out warnings and errors
730 if (fCount>0 && fPosition>0) {
731 printf("Hex-Dump of DDL: %3d, RCU ID: %d, HWADDR: 0x%03x\n",
732 fDDLNumber,fRCUId,fHWAddress);
733 printf("32-bit - 2bit 10bit 10bit 10bit\n");
734 printf("********** **** ***** ***** *****\n");
735 Int_t nwords = (fCount+2)/3+1;
736 for (Int_t iword = 0; iword < nwords; iword++) {
737 UInt_t word32 = Get32bitWord(fPosition-nwords+iword);
738 UInt_t marker = word32 >> 30 & 0x3;
739 UInt_t word101 = word32 >> 20 & 0x3FF;
740 UInt_t word102 = word32 >> 10 & 0x3FF;
741 UInt_t word103 = word32 >> 00 & 0x3FF; // nice octal number
742 printf("0x%08x - 0b%1d%1d 0x%03x 0x%03x 0x%03x\n",
743 word32,marker>>1,marker&0x1,word101,word102,word103);
744 }
745 }
746}