]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - RAW/AliAltroDecoder.cxx
Possibility to apply an event selection based on a logical function of the trigger...
[u/mrichter/AliRoot.git] / RAW / AliAltroDecoder.cxx
index 0c78c64c75af5e2f7fc7525f6fad09ba18a35c4e..f6c9e65832ac7b2fd8a17cdeb3885895aa610b66 100644 (file)
@@ -61,8 +61,8 @@ AliAltroDecoder::AliAltroDecoder() : f32DtaPtr(0),
                                     fInComplete(0),
                                     fDecodeIfCorruptedTrailer(kTRUE),
                                     fIsDecoded(kFALSE),
-                                     fIsFatalCorruptedTrailer(kTRUE) 
-//              fRcuFirmwareVersion(2)
+                                    fIsFatalCorruptedTrailer(kTRUE)
+  //                                fIsFirstChannelOfPayload(kTRUE)
 {
  // Default constructor
 }
@@ -103,7 +103,12 @@ Bool_t AliAltroDecoder::Decode()
       //     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
@@ -127,7 +132,6 @@ Bool_t AliAltroDecoder::Decode()
 
       if(  ((CheckPayloadTrailer() == kTRUE) || fDecodeIfCorruptedTrailer == kTRUE  )  &&  (fSize > 32) )
        {
-         //      fDDLBlockCnt = 0;
          fOutBufferIndex = 0;
 
          for(Int_t i = 0; i < fNDDLBlocks; i++)
@@ -137,9 +141,6 @@ Bool_t AliAltroDecoder::Decode()
 
          DecodeLastDDLBlock(); 
          fOutBufferIndex =  fN40AltroWords*4  -  1;
-  
-         //      DumpData(fOutBuffer, 400,4);
-    
          fIsDecoded = kTRUE;
          return kTRUE;
        }
@@ -150,18 +151,15 @@ Bool_t AliAltroDecoder::Decode()
 //       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
@@ -171,8 +169,6 @@ Bool_t AliAltroDecoder::NextChannel(AliAltroData *altroDataPtr)
 
   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;
     } 
   
@@ -181,7 +177,6 @@ Bool_t AliAltroDecoder::NextChannel(AliAltroData *altroDataPtr)
 
       if(fIsDecoded != kTRUE)
        {
-         //      cout <<"AliAltroDecoder::NextChanne, WARNING, buffer was not decoded, decoding now.. "<< endl;
          Decode();
        }
 
@@ -191,7 +186,7 @@ Bool_t AliAltroDecoder::NextChannel(AliAltroData *altroDataPtr)
       // 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 ++;
@@ -205,7 +200,7 @@ Bool_t AliAltroDecoder::NextChannel(AliAltroData *altroDataPtr)
          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 --;
 
@@ -217,13 +212,9 @@ Bool_t AliAltroDecoder::NextChannel(AliAltroData *altroDataPtr)
            {
              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 );
@@ -235,7 +226,6 @@ Bool_t AliAltroDecoder::NextChannel(AliAltroData *altroDataPtr)
              return kFALSE;
            }
 
-
        }
       else
        {
@@ -289,6 +279,7 @@ Float_t AliAltroDecoder::GetFailureRate()
 }
 
 
+
 void AliAltroDecoder::PrintInfo(AliAltroData &altrodata, Int_t n, Int_t nPerLine)
 {
   // prints data and address information contained in altrodata 
@@ -314,103 +305,78 @@ int AliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size)
   // 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;
 
 }
@@ -464,12 +430,18 @@ void AliAltroDecoder::DecodeDDLBlock()
 }
 
 
+
+
+
+
+
+
 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++)
     {
@@ -482,6 +454,34 @@ void AliAltroDecoder::DecodeLastDDLBlock()
   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.
@@ -523,7 +523,7 @@ Int_t AliAltroDecoder::CopyBackward(Byte_t* pBuffer, Int_t bufferSize)
        // 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;
@@ -576,7 +576,7 @@ Bool_t  AliAltroDecoder::GetRCUTrailerData(UChar_t*& data) const
 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));
 }