]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
added functionality to handle CDH and RCU trailer
authorrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 5 May 2008 13:10:40 +0000 (13:10 +0000)
committerrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 5 May 2008 13:10:40 +0000 (13:10 +0000)
HLT/RCU/AliHLTAltroEncoder.cxx
HLT/RCU/AliHLTAltroEncoder.h
HLT/RCU/test/testAliHLTAltroEncoder.C

index 6fa525716cc0fd258c191368947af88018cabaea..d3cb664498b8c9501c22469e51dada40394e6f23 100644 (file)
@@ -25,6 +25,7 @@
 #include <cassert>
 #include <cerrno>
 #include "AliHLTAltroEncoder.h"
+#include "TArrayC.h"
 
 /** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTAltroEncoder)
@@ -40,7 +41,9 @@ AliHLTAltroEncoder::AliHLTAltroEncoder()
   fChannels(),
   fOffset(0),
   f10bitWords(0),
-  fOrder(kUnknownOrder)
+  fOrder(kUnknownOrder),
+  fpCDH(NULL),
+  fpRCUTrailer(NULL)
 {
   // see header file for class documentation
   // or
@@ -60,7 +63,9 @@ AliHLTAltroEncoder::AliHLTAltroEncoder(AliHLTUInt8_t* pBuffer, int iSize)
   fChannels(),
   fOffset(0),
   f10bitWords(0),
-  fOrder(kUnknownOrder)
+  fOrder(kUnknownOrder),
+  fpCDH(NULL),
+  fpRCUTrailer(NULL)
 {
   // see header file for class documentation
 }
@@ -68,6 +73,11 @@ AliHLTAltroEncoder::AliHLTAltroEncoder(AliHLTUInt8_t* pBuffer, int iSize)
 AliHLTAltroEncoder::~AliHLTAltroEncoder()
 {
   // see header file for class documentation
+  if (fpCDH) delete fpCDH;
+  fpCDH=NULL;
+
+  if (fpRCUTrailer) delete fpRCUTrailer;
+  fpRCUTrailer=NULL;
 }
 
 int AliHLTAltroEncoder::SetBuffer(AliHLTUInt8_t* pBuffer, int iSize)
@@ -99,7 +109,8 @@ int AliHLTAltroEncoder::AddSignal(AliHLTUInt16_t signal, AliHLTUInt16_t timebin)
   if (iResult>=0 && (iResult=Add10BitValue(signal))>=0) {
     fBunchLength++;
   }
-  assert(fOffset*4<=f10bitWords*5);
+  //  HLTDebug("fOffset: %d  (fOffset-32)*4: %d  f10bitWords*5 %d", fOffset,(fOffset-32)*4,f10bitWords*5);
+  assert((fOffset-(fpCDH?fpCDH->GetSize():0)*4)<=f10bitWords*5);//32 is here size of CDH 8 32bit words
   fPrevTimebin=timebin;
   return iResult;
 }
@@ -110,7 +121,7 @@ int AliHLTAltroEncoder::SetChannel(AliHLTUInt16_t hwaddress)
   int iResult=0;
   int added10BitWords=0;
   if (!fpBuffer) return -ENODEV;
-  if (fOffset+5>=fBufferSize) {
+  if (fOffset+5>=fBufferSize-(fpRCUTrailer?fpRCUTrailer->GetSize():0)) {
     HLTWarning("buffer too small too finalize channel: %d of %d byte(s) already used", fOffset, fBufferSize);
     return -ENOSPC;
   }
@@ -193,7 +204,7 @@ int AliHLTAltroEncoder::Add10BitValue(AliHLTUInt16_t value)
   // see header file for class documentation
   int iResult=0;
   if (!fpBuffer) return -ENODEV;
-  if (fOffset+2>=fBufferSize) {
+  if (fOffset+2>=fBufferSize-(fpRCUTrailer?fpRCUTrailer->GetSize():0)) {
     HLTWarning("buffer too small too add 10bit word: %d of %d byte(s) already used", fOffset, fBufferSize);
     return -ENOSPC;
   }
@@ -223,3 +234,74 @@ int AliHLTAltroEncoder::Pad40Bit()
   if (iResult<0) return iResult;
   return added10BitWords;
 }
+
+int AliHLTAltroEncoder::SetCDH(AliHLTUInt8_t* pCDH,int size)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (fOffset>0) {
+    HLTError("CDH can only be set prior to data");
+    iResult=-EFAULT;
+  }
+  if (size>0 && pCDH){
+    if (fpCDH == NULL){
+      fpCDH = new TArrayC(0);
+    }
+    if (fpCDH){
+      fpCDH->Set(0);
+      fpCDH->Set(size, (const char*)pCDH);
+      fOffset=size;
+    } else {
+      iResult=-ENOMEM;
+    }
+  } else {
+    iResult=-EINVAL;
+  }
+  return iResult;
+}
+
+int AliHLTAltroEncoder::SetRCUTrailer(AliHLTUInt8_t* pRCUTrailer,int size)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (size>0 && pRCUTrailer){
+    if (fpRCUTrailer == NULL){
+      fpRCUTrailer = new TArrayC(0);
+    }
+    if (fpRCUTrailer){
+      fpRCUTrailer->Set(0);
+      fpRCUTrailer->Set(size, (const char*)pRCUTrailer);
+    } else {
+      iResult=-ENOMEM;
+    }
+  } else {
+    iResult=-EINVAL;
+  }
+  return iResult;
+}
+
+int AliHLTAltroEncoder::SetLength()
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (fChannel!=AliHLTUInt16MAX && (iResult=SetChannel(fChannel))<0) {
+    HLTError("error finalizing channel");
+    return iResult;
+  }
+
+  if (fpRCUTrailer && fOffset+fpRCUTrailer->GetSize()<fBufferSize) {
+    // copy the trailer
+    AliHLTUInt32_t* pTgt=reinterpret_cast<AliHLTUInt32_t*>(fpBuffer+fOffset);
+    memcpy(pTgt, fpRCUTrailer->GetArray(), fpRCUTrailer->GetSize());
+    // set number of 10bit words
+    *pTgt=GetTotal40bitWords();
+    fOffset+=fpRCUTrailer->GetSize();
+  }
+  if (fpCDH && fOffset>fpCDH->GetSize()) {
+    memcpy(fpBuffer, fpCDH->GetArray(), fpCDH->GetSize());
+    AliHLTUInt32_t* pCdhSize=reinterpret_cast<AliHLTUInt32_t*>(fpBuffer);
+    *pCdhSize=fOffset;//set the first word in the header to be the fOffset(number of bytes added)  
+    HLTDebug("Size set in the header: %d",*pCdhSize);
+  }
+  return fOffset;
+}
index ed028a70b1080b2c0807aa5ed72fbd23ad8538b8..01bae80b604323a3d18010114e34d8f7ee9d2683 100644 (file)
@@ -19,6 +19,8 @@
 
 #define AliHLTUInt16MAX 0xffff
 
+class TArrayC;
+
 /**
  * @class AliHLTAltroEncoder
  * Encoder of the RCU/Altro data format.
  *    encoder.SetChannel(channelAddress);
  *  }
  * </pre>
- * 
+ *
+ * By default, the encoder provides only the ALTRO data, but not the common
+ * data header (in AliRoot language AliRawDataHeader) nor the RCU trailer.
+ * The CDH is 32 bytes long, the first 4 byte contain the data length excluding
+ * the CDH itsself. The CDH can be set by SetCDH(AliHLTUInt8_t*, int).
+ *
+ * The RCU trailer has varying formats, actually the last 4 byte are supposed
+ * to contain the length of the trailer itsself. The first 4 byte contain the
+ * number of 40bit ALTRO words. Currently, the RCU firmware adds only one 4 byte
+ * word, the number of 40bit wirds. The trailer can be set using 
+ * SetRCUTrailer(AliHLTUInt8_t*, int);
+ *
+ * When using CDH and Trailer the Finalize() function must be called at the end
+ * in order to copy the trailer and update the size members correctly.
+ *
  * @ingroup alihlt_rcu
  */
 class AliHLTAltroEncoder : AliHLTLogging {
@@ -102,6 +118,26 @@ class AliHLTAltroEncoder : AliHLTLogging {
    */
   int GetTotal40bitWords();
 
+  /**
+   * Sets the common data header at the beginning of the buffer
+   */
+  int SetCDH(AliHLTUInt8_t* pCDH, int size);
+
+  /**
+   * Sets the RCU trailer at the end of the buffer
+   */
+  int SetRCUTrailer(AliHLTUInt8_t* pTrailer, int size);
+
+  /**
+   * Finalize the encoded data.
+   * Finish the last channel if open, copy RCU trailer if available and update
+   * ALTRO word count in the trailer. Update the data length in the CDH if
+   * available.
+   */
+  int SetLength();
+
+  int GetOffset(){return fOffset;}
+
   enum {
     kUnknownOrder = 0,
     kAscending,
@@ -160,8 +196,14 @@ class AliHLTAltroEncoder : AliHLTLogging {
 
   /// time bin order
   int fOrder; //!transient
+  
+  /// common data header
+  TArrayC* fpCDH; //!transient
+
+  /// RCU trailer
+  TArrayC* fpRCUTrailer; //!transient
 
-  ClassDef(AliHLTAltroEncoder, 0);
+  ClassDef(AliHLTAltroEncoder, 1);
 };
 
 #endif
index 21306da1a5bc801d642b92aa254a220a3de01de1..0e49ce36bc358a20cb8deaf3543433b8168eb1a9 100644 (file)
@@ -287,9 +287,15 @@ int testAliHLTAltroEncoder()
 #endif
 
   AliHLTAltroEncoder encoder;
-  Char_t* pTgt=encData.GetArray();
-  pTgt+=sizeofAliRawDataHeader;
-  encoder.SetBuffer((AliHLTUInt8_t*)pTgt, maxAltroDataSize);
+  encoder.SetBuffer((AliHLTUInt8_t*)encData.GetArray(), encData.GetSize());
+
+  // set the common data header
+  TArrayC dummyCdh(sizeofAliRawDataHeader);
+  encoder.SetCDH((AliHLTUInt8_t*)dummyCdh.GetArray(), dummyCdh.GetSize());
+
+  // set a trailer like in the real data format of the v1 RCU format (1 trailer word)
+  Int_t trailer=0;
+  encoder.SetRCUTrailer((AliHLTUInt8_t*)&trailer, 4);
 
   if (bVerbose) cout << "number of channels: " << nofChannels << endl;
   int channelAddress=-1;
@@ -352,13 +358,14 @@ int testAliHLTAltroEncoder()
     if (bVerbose) cout << " channel " << channelAddress << ":  number of bunches " << totalBunches << endl;
 
   }
-  if (bUseAddChannelSignal && lastChannel>=0) encoder.SetChannel(lastChannel);
 
+  int dataSize=encoder.SetLength();
+  if (dataSize<0) {
+    cerr << "error finalizing encoded buffer" << endl;
+    return -1;
+  }
   int nof40bitWords=encoder.GetTotal40bitWords();
-  pTgt+=nof40bitWords*5/4;
-  *((Int_t*)pTgt)=nof40bitWords;
-  int encDataSize=sizeofAliRawDataHeader+nof40bitWords*5/4+sizeof(Int_t);
-  encData.Set(encDataSize);
+  encData.Set(dataSize);
 
   if (bVerbose) cout << "simulated data array:" << simData.GetSize() << " , ALTRO block length: " << nof40bitWords << " ALTRO words -> encoded data: " << encData.GetSize() << endl;
 
@@ -385,7 +392,7 @@ int testAliHLTAltroEncoder()
   return 0;
 }
 
-int main(int argc, const char** argv)
+int main(int /*argc*/, const char** /*argv*/)
 {
 //   CompareDumpFiles();
 //   return 0;