fInComplete(0),
fDecodeIfCorruptedTrailer(kTRUE),
fIsDecoded(kFALSE),
- fIsFatalCorruptedTrailer(kTRUE)
-// fRcuFirmwareVersion(2)
+ fIsFatalCorruptedTrailer(kTRUE)
+ // fIsFirstChannelOfPayload(kTRUE)
{
// Default constructor
}
// printf("\n AliAltroDecoder::Decode(). Please check on the return value (-1 if fataly corrupted) of the SetMemory() function\n");
return kFALSE;
}
-
+ else if (!f8DtaPtr || !f32DtaPtr ||
+ (UChar_t*)f32DtaPtr < f8DtaPtr-fSize ||
+ (UChar_t*)f32DtaPtr > f8DtaPtr)
+ {
+ return kFALSE;
+ }
else
{
// see header file for class documentation
if( ((CheckPayloadTrailer() == kTRUE) || fDecodeIfCorruptedTrailer == kTRUE ) && (fSize > 32) )
{
- // fDDLBlockCnt = 0;
fOutBufferIndex = 0;
for(Int_t i = 0; i < fNDDLBlocks; i++)
DecodeLastDDLBlock();
fOutBufferIndex = fN40AltroWords*4 - 1;
-
- // DumpData(fOutBuffer, 400,4);
-
fIsDecoded = kTRUE;
return kTRUE;
}
// cout << "Size of datablock is " << fSize << endl;
// cout << "fN40AltroWords = " << fN40AltroWords << endl;
// cout << "fN40RcuAltroWords = " << fN40RcuAltroWords << endl;
-
- printf("\n< ERROR: data integrity check failed, discarding data \n" );
- printf( "Size of datablock is %d\n", fSize);
- printf( "fN40AltroWords = %d\n", fN40AltroWords);
- printf( "fN40RcuAltroWords = %d\n", fN40RcuAltroWords);
return kFALSE;
}
+
}
}
+
Bool_t AliAltroDecoder::NextChannel(AliAltroData *altroDataPtr)
{
// Reads the next altro channel in the RCU payload after the RCU payload
if(fIsFatalCorruptedTrailer == kTRUE)
{
- // printf("\n AliAltroDecoder::NextChannel(), WARNING, attempt to decode badly corrupted data\n");
- // printf("\n AliAltroDecoder::NextChannel(), Please check on the return value (-1 if fataly corrupted) of the SetMemory() function\n");
return kFALSE;
}
if(fIsDecoded != kTRUE)
{
- // cout <<"AliAltroDecoder::NextChanne, WARNING, buffer was not decoded, decoding now.. "<< endl;
Decode();
}
// we are reading backwards, so the index is already 1 inside the block
if(fOutBufferIndex >= 7)
{
- if((fOutBuffer[fOutBufferIndex] << 4 ) | ((fOutBuffer[fOutBufferIndex-1] & 0x3c0) >> 6) == 0x2aaa)
+ if(((fOutBuffer[fOutBufferIndex] << 4 ) | ((fOutBuffer[fOutBufferIndex-1] & 0x3c0) >> 6)) == 0x2aaa)
{
altroDataPtr->SetIsComplete(kTRUE);
fComplete ++;
fOutBufferIndex --;
fNAltro10bitWords = ( (fOutBuffer[fOutBufferIndex] & 0x3f) << 4 ) | ((fOutBuffer[fOutBufferIndex -1] & (0xF << 6)) >> 6) ;
fOutBufferIndex --;
- altroDataPtr->SetHadd( ((fOutBuffer[fOutBufferIndex] & 0x3)) << 10 | ( fOutBuffer[fOutBufferIndex-1] ) );
+ altroDataPtr->SetHadd( ((fOutBuffer[fOutBufferIndex] & 0x3)) << 10 | ( fOutBuffer[fOutBufferIndex-1] ), fOutBufferIndex);
fOutBufferIndex --;
{
fOutBufferIndex = fOutBufferIndex - fNAltro10bitWords -(4 - fNAltro10bitWords%4);
}
-
- if(fOutBufferIndex > 0)
+ if(fOutBufferIndex >= 0)
{
-
- //cout << " AliAltroDecoder::NextChannel fOutBufferIndex =" << fOutBufferIndex << endl;
- // printf( "AliAltroDecoder::NextChannel fOutBufferIndex = %d", fOutBufferIndex);
altroDataPtr->SetData( &fOutBuffer[fOutBufferIndex] );
fOutBufferIndex --;
altroDataPtr->SetDataSize( fNAltro10bitWords );
return kFALSE;
}
-
}
else
{
}
+
void AliAltroDecoder::PrintInfo(AliAltroData &altrodata, Int_t n, Int_t nPerLine)
{
// prints data and address information contained in altrodata
// Sets the pointer to the memory block that should be decoded
// Returns a negative value if an inconsistency in the data is detected
-
+ // fIsFirstChannelOfPayload = kTRUE;
+ int iRet = 0;
+ fIsDecoded = kFALSE;
if(dtaPtr == 0)
{
- printf("\nAliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size) FATAL ERROR, dtaPtr = ZERO !!!!!!!!!!!!\n");
- printf("\nThis is an user error, please check in your code that you don give a zero pointer to the decoder \n");
+ // printf("\nAliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size) FATAL ERROR, dtaPtr = ZERO !!!!!!!!!!!!\n");
+ // printf("Please check your code that you don't give a zero pointer to the decoder \n");
return -99;
}
- int iRet = 0;
- Int_t tmpTrailerSize;
- fIsDecoded = kFALSE;
+ if ((Int_t)size<(fkN32HeaderWords+1)*4)
+ {
+ // printf("\nAliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size) FATAL ERROR, too little data (%d)\n", size);
+ // printf("Data buffer must contain the CDH and at least one 32bit RCU trailer word\n");
+ return -99;
+ }
+
+ UInt_t tmpTrailerSize;
f8DtaPtr =dtaPtr;
fSize = size;
f8DtaPtr =f8DtaPtr + fSize;
f32DtaPtr = (UInt_t *)f8DtaPtr;
-
- // if(fRcuFirmwareVersion ==1)
- // {
-
-
-
- //tmpTrailerSize = *(f32DtaPtr - 1);
- tmpTrailerSize = (*(f32DtaPtr - 1))&(0x7f);
-
- // printf("\nThe trailersize is %d\n", tmpTrailerSize);
-
-// for(int i=0; i<tmpTrailerSize+2; i++)
-// {
-// printf("trailer %d = %d\n", i, *(f32DtaPtr - i));
-
-// }
-
-
- // }
- // else
- // {
-
- // }
-
+ tmpTrailerSize = *(f32DtaPtr - 1);
+
+ // format of the trailer has been fixed in the RCU FW2
+ // Bit 31 to 16: 0xaaaa (16 bit)
+ // Bit 15 to 7: RCU address ( 9 bit)
+ // Bit 6 to 0: Trailer length ( 7 bit)
+ //
+ // RCU FW1 has one trailer word containing the number of
+ // 10bit Altro words. According to some early documents,
+ // it should have at least 2 32bit words: trailer length and
+ // the number of 10bit Altro words. This is the format of
+ // the simulation at time of writing (June 2008)
+ bool haveFw2=false;
+ if ((tmpTrailerSize>>16)==0xaaaa) {
+ haveFw2=true;
+ tmpTrailerSize = tmpTrailerSize&0x7f; // 7 LSBs of the last word
+ } else
if(tmpTrailerSize <= MAX_TRAILER_WORDS)
{
tmpTrailerSize = tmpTrailerSize; //assume that the last word of the buffer gives the number of trailer words
}
- else
+ // nof 10bit AltroWords * 5/4 + bytes in the CDH + 4 bytes RCU trailer
+ else if (((*(f32DtaPtr-1)*5)/4 + fkN32HeaderWords*4 + 4)<=fSize)
{
tmpTrailerSize = 1; //assume that last word is ONE, and that the this word gives the number of 40 bit altro words
}
+ else
+ {
+ tmpTrailerSize=0;
+ fIsFatalCorruptedTrailer = kTRUE;
+ iRet = -1;
+ }
- f8PayloadSize = fSize - (fkN32HeaderWords + tmpTrailerSize)*4;
- fN40AltroWords = f8PayloadSize/5;
- fNDDLBlocks = fN40AltroWords/4;
- f32LastDDLBlockSize = ((f8PayloadSize%(4*DDL_32BLOCK_SIZE))+3)/4;
-
- if(tmpTrailerSize > 0 && tmpTrailerSize < 5)
+ if(tmpTrailerSize > 0 && (fkN32HeaderWords + tmpTrailerSize)*4<=fSize)
{
- //if(fRcuFirmwareVersion ==1)
- // {
- // printf("\nfRcuFirmwareVersion ==1\n");
+ f8PayloadSize = fSize - (fkN32HeaderWords + tmpTrailerSize)*4;
+ fN40AltroWords = f8PayloadSize/5;
+ fNDDLBlocks = fN40AltroWords/4;
+ f32LastDDLBlockSize = ((f8PayloadSize%(4*DDL_32BLOCK_SIZE))+3)/4;
+
f32DtaPtr = f32DtaPtr - tmpTrailerSize;
fN40RcuAltroWords = *f32DtaPtr;
f32DtaPtr = (UInt_t *)dtaPtr + fkN32HeaderWords;
-
- // printf("\nthe number of altrowords is %d\n", fN40RcuAltroWords);
- // printf("\nthe number of altrowords is %u\n", fN40RcuAltroWords);
-
fIsFatalCorruptedTrailer = kFALSE;
-
-
-
-
- // }
-
- // else if(fRcuFirmwareVersion ==2)
- // {
- // printf("\nfRcuFirmwareVersion ==2\n");
-
- // f32DtaPtr = f32DtaPtr - tmpTrailerSize;
- // fN40RcuAltroWords = *f32DtaPtr;
- // f32DtaPtr = (UInt_t *)dtaPtr + fkN32HeaderWords;
- // fIsFatalCorruptedTrailer = kFALSE;
-
- // }
- // }
-
- // else
- // {
- // printf("ERROR, unknown RCU firmvare version");
- // }
- }
- else
- {
- printf("\n AliAltroDecoder::SetMemory, ERROR\n, trailer is corrupted");
- fIsFatalCorruptedTrailer = kTRUE;
- iRet = -1;
}
-
+
+ // all subsequent consistency checks depend on the correct initialization
+ // of the pointer and size variables
+ assert(f8DtaPtr == dtaPtr + fSize);
return iRet;
}
}
+
+
+
+
+
+
void AliAltroDecoder::DecodeLastDDLBlock()
{
// Decode one 160 bit DDL block into 16 integers.
// In order to use the same decoding function (DecodeDDLBlock())
// a copy of the the last DDL block is made and
- // if the las block does not align with 160 bits then it is padded with zeroes
+ // if the last block does not align with 160 bits then it is padded with zeroes
for(Int_t i=0; i < f32LastDDLBlockSize; i++)
{
f32DtaPtr=(UInt_t*)(f8DtaPtr-fSize+f8PayloadSize+fkN32HeaderWords*4);
}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Int_t AliAltroDecoder::CopyBackward(Byte_t* pBuffer, Int_t bufferSize)
{
// Copy the original 10/40 bit encecoded data of the current channel.
// with the 8 LSBs of the decoded 10 bit word at the beginning of
// the current channel
//assert(*pSrc==fOutBuffer[currentIndex]&0xff);
- if (*pSrc==fOutBuffer[currentIndex]&0xff) {
+ if (*pSrc==(fOutBuffer[currentIndex]&0xff)) {
// try to verfify the length of the channel
UInt_t lenCheck=*(pSrc+iCopy+2)|(*(pSrc+iCopy+3)&0x3)<<8;
Int_t AliAltroDecoder::GetRCUTrailerSize() const
{
// Provide size of RCU trailer.
- if (!f8DtaPtr) return 0;
+ if (!f8DtaPtr || !fIsDecoded || fSize==0) return 0;
assert(fSize>(f8PayloadSize+fkN32HeaderWords*sizeof(UInt_t)));
return fSize-(f8PayloadSize+fkN32HeaderWords*sizeof(UInt_t));
}