]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TRD/AliTRDtrapConfig.cxx
Coverity report problems
[u/mrichter/AliRoot.git] / TRD / AliTRDtrapConfig.cxx
index cd1140f5aead7d440c08b439bddf592f017be41b..3619f5ddff0b6ffbaf31307c395612b9acafbba9 100644 (file)
@@ -1,13 +1,44 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////
+//                                                                        //
+//  TRAP config                                                           //
+//                                                                        //
+//  Author: J. Klein (Jochen.Klein@cern.ch)                               //
+//                                                                        //
+////////////////////////////////////////////////////////////////////////////
+
 #include "AliLog.h"
 
+#include "AliTRDgeometry.h"
+#include "AliTRDfeeParam.h"
 #include "AliTRDtrapConfig.h"
 
+#include <fstream>
+#include <iostream>
+#include <iomanip>
+
 ClassImp(AliTRDtrapConfig)
 
 AliTRDtrapConfig* AliTRDtrapConfig::fgInstance = 0x0;
+const Int_t AliTRDtrapConfig::fgkMaxMcm = AliTRDfeeParam::GetNmcmRob() + 2;
+const Int_t AliTRDtrapConfig::fgkDmemStartAddress = 0xc000;
 
 AliTRDtrapConfig::AliTRDtrapConfig() : 
-  TObject()
+  TObject(), fScaleQ0(0), fScaleQ1(0)
 {
   // default constructor, initializing array of TRAP registers
 
@@ -446,99 +477,544 @@ AliTRDtrapConfig::AliTRDtrapConfig() :
   fRegs[kDMDELA]  =   SimpleReg_t("DMDELA",      0xD002, 4,      0x8        );
   fRegs[kDMDELS]  =   SimpleReg_t("DMDELS",      0xD003, 4,      0x8        );
 
-  for (Int_t iReg = 0; iReg < kLastReg; iReg++) {
-    fRegisterValue[iReg].globalValue = GetRegResetValue((TrapReg_t) iReg);
-    fRegisterValue[iReg].state = RegValue_t::kGlobal;
-//    printf("%-8s: 0x%08x\n", GetRegName((TrapReg_t) iReg), fRegisterValue[iReg].globalValue);
+
+
+  for(Int_t iAddr = 0; iAddr < fgkDmemWords; iAddr++) {
+     
+     if(iAddr == fgkDmemAddrDeflCorr - fgkDmemStartAddress) {
+       fDmem[iAddr] = new UInt_t[fgkDmemSizeSmIndividual];
+       fDmemDepth[iAddr] = fgkDmemSizeSmIndividual;
+     }
+
+     else if(iAddr == fgkDmemAddrNdrift - fgkDmemStartAddress) {
+       fDmem[iAddr] = new UInt_t[fgkDmemSizeSmRocIndividual];
+       fDmemDepth[iAddr] = fgkDmemSizeSmRocIndividual;
+     }
+
+     else if(iAddr >= fgkDmemAddrDeflCutStart-fgkDmemStartAddress && iAddr <= fgkDmemAddrDeflCutEnd-fgkDmemStartAddress) {
+       fDmem[iAddr]  = new UInt_t[fgkDmemSizeSmIndividual];   
+       fDmemDepth[iAddr] = fgkDmemSizeSmIndividual;
+     }
+
+     else if(iAddr >= fgkDmemAddrTrackletStart-fgkDmemStartAddress && iAddr <= fgkDmemAddrTrackletEnd-fgkDmemStartAddress) {
+       fDmem[iAddr]  = new UInt_t[fgkDmemSizeTotalIndividual];
+       fDmemDepth[iAddr] = fgkDmemSizeTotalIndividual;
+     }
+
+     else if(iAddr >= fgkDmemAddrLUTStart-fgkDmemStartAddress && iAddr <= fgkDmemAddrLUTEnd-fgkDmemStartAddress) {
+       fDmem[iAddr]  = new UInt_t;   // same value for all MCMs
+       fDmemDepth[iAddr] = fgkDmemSizeUniform;
+    }
+
+     else if(iAddr == fgkDmemAddrLUTcor0-fgkDmemStartAddress) {
+       fDmem[iAddr]  = new UInt_t[fgkDmemSizeSmIndividual];   
+       fDmemDepth[iAddr]  = fgkDmemSizeSmIndividual;
+     }
+
+     else if(iAddr == fgkDmemAddrLUTcor1-fgkDmemStartAddress) {
+       fDmem[iAddr]  = new UInt_t[fgkDmemSizeSmIndividual];   
+       fDmemDepth[iAddr]  = fgkDmemSizeSmIndividual;
+     }
+       
+     else if(iAddr == fgkDmemAddrLUTnbins-fgkDmemStartAddress) {
+       fDmem[iAddr]  = new UInt_t;   // same value for all MCMs
+       fDmemDepth[iAddr] = fgkDmemSizeUniform;
+     }
+
+     else if(iAddr == fgkDmemAddrLUTLength-fgkDmemStartAddress) {
+       fDmem[iAddr]  = new UInt_t;   // same value for all MCMs
+       fDmemDepth[iAddr] = fgkDmemSizeUniform;
+     }
+
+     else {
+       fDmem[iAddr] = NULL;
+       fDmemDepth[iAddr] = fgkDmemSizeEmpty;
+     }
+     
   }
+
+  InitRegs();
+  ResetDmem();
 }
 
+
 AliTRDtrapConfig* AliTRDtrapConfig::Instance()
 {
   // return a pointer to an instance of this class
 
-  if (!fgInstance)
+  if (!fgInstance) {
     fgInstance = new AliTRDtrapConfig();
+    fgInstance->LoadConfig();
+  }
+
   return fgInstance;
 }
 
-Int_t AliTRDtrapConfig::GetTrapReg(TrapReg_t reg, Int_t det, Int_t rob, Int_t mcm)
+
+AliTRDtrapConfig::~AliTRDtrapConfig()
+{
+  for(Int_t iAddr = 0; iAddr < fgkDmemWords; iAddr++) {
+     if(iAddr == fgkDmemAddrDeflCorr - fgkDmemStartAddress)
+       delete [] fDmem[iAddr];
+
+     else if(iAddr == fgkDmemAddrNdrift - fgkDmemStartAddress)
+       delete [] fDmem[iAddr];
+
+     else if(iAddr >= fgkDmemAddrDeflCutStart-fgkDmemStartAddress && iAddr <= fgkDmemAddrDeflCutEnd-fgkDmemStartAddress)
+       delete [] fDmem[iAddr];
+
+     else if(iAddr >= fgkDmemAddrTrackletStart-fgkDmemStartAddress && iAddr <= fgkDmemAddrTrackletEnd-fgkDmemStartAddress)
+       delete [] fDmem[iAddr];
+
+     else if(iAddr >= fgkDmemAddrLUTStart-fgkDmemStartAddress && iAddr <= fgkDmemAddrLUTEnd-fgkDmemStartAddress)
+       delete fDmem[iAddr];
+
+     else if(iAddr == fgkDmemAddrLUTcor0-fgkDmemStartAddress)
+       delete [] fDmem[iAddr];
+
+     else if(iAddr == fgkDmemAddrLUTcor1-fgkDmemStartAddress)
+       delete [] fDmem[iAddr];
+       
+     else if(iAddr == fgkDmemAddrLUTnbins-fgkDmemStartAddress)
+       delete fDmem[iAddr];
+
+     else if(iAddr == fgkDmemAddrLUTLength-fgkDmemStartAddress)
+       delete fDmem[iAddr];
+  }
+}
+
+
+void AliTRDtrapConfig::InitRegs()
+{
+   // Reset the content of all TRAP registers to the reset values (see TRAP User Manual)
+
+   for (Int_t iReg = 0; iReg < kLastReg; iReg++) {
+
+     fRegisterValue[iReg].individualValue = 0x0;
+
+     fRegisterValue[iReg].globalValue = GetRegResetValue((TrapReg_t) iReg);
+     fRegisterValue[iReg].state = RegValue_t::kGlobal;
+   }
+}
+
+
+void AliTRDtrapConfig::ResetRegs()
+{
+   // Reset the content of all TRAP registers to the reset values (see TRAP User Manual)
+
+   for (Int_t iReg = 0; iReg < kLastReg; iReg++) {
+      if(fRegisterValue[iReg].state == RegValue_t::kIndividual) {
+       if (fRegisterValue[iReg].individualValue) {
+         delete [] fRegisterValue[iReg].individualValue;
+         fRegisterValue[iReg].individualValue = 0x0;
+       }
+      }
+
+      fRegisterValue[iReg].globalValue = GetRegResetValue((TrapReg_t) iReg);
+      fRegisterValue[iReg].state = RegValue_t::kGlobal;
+      //    printf("%-8s: 0x%08x\n", GetRegName((TrapReg_t) iReg), fRegisterValue[iReg].globalValue);
+   }
+}
+
+
+void AliTRDtrapConfig::ResetDmem()
+{
+     for(Int_t iAddr = 0; iAddr < fgkDmemWords; iAddr++) {
+       if(fDmemDepth[iAddr] == 0)
+          continue;
+       for(Int_t j=0; j < fDmemDepth[iAddr]; j++) {
+          fDmem[iAddr][j]=0;
+       }
+     }
+}
+
+
+Int_t AliTRDtrapConfig::GetTrapReg(TrapReg_t reg, Int_t det, Int_t rob, Int_t mcm) const
 {
   // get the value of an individual TRAP register 
   // if it is individual for TRAPs a valid TRAP has to be specified
 
   if ((reg < 0) || (reg >= kLastReg)) {
     AliError("Non-existing register requested");
-    return -1;
+    return 0;
   }
   else {
     if (fRegisterValue[reg].state == RegValue_t::kGlobal) {
       return fRegisterValue[reg].globalValue;
     }
     else if (fRegisterValue[reg].state == RegValue_t::kIndividual) {
-      if ((det < 0) || (det > 539) || (rob < 0) || (rob > 7) || (mcm < 0) || (mcm > 15)) {
-        AliError("Invalid MCM specified!");
-        return -1;
-      }
-      else {
-        Int_t mcmid = 0;
-        return fRegisterValue[reg].individualValue[mcmid];
-      }
+       if((det >= 0 && det < AliTRDgeometry::Ndet()) && 
+          (rob >= 0 && rob < AliTRDfeeParam::GetNrobC1()) && 
+          (mcm >= 0 && mcm < fgkMaxMcm)) {
+         return fRegisterValue[reg].individualValue[det*AliTRDfeeParam::GetNrobC1()*fgkMaxMcm + rob*fgkMaxMcm + mcm];
+       }
+       else {
+         AliError("Invalid MCM specified or register is individual");
+         return 0;
+       }
+    }
+    else {  // should never be reached
+      AliError("MCM register status neither kGlobal nor kIndividual");
+      return 0;
     }
   }
-  return -1;
 }
 
-Bool_t AliTRDtrapConfig::SetTrapReg(TrapReg_t reg, Int_t value, Int_t det, Int_t rob, Int_t mcm)
+
+Bool_t AliTRDtrapConfig::SetTrapReg(TrapReg_t reg, Int_t value)
 {
-  // set the value for the given TRAP register 
-  // if no MCM is specified the value is stored as global,
-  // i.e. the same for all TRAPs
+  // set a global value for the given TRAP register,
+  // i.e. the same value for all TRAPs
 
-  if ((det == -1) && (rob == -1) && (mcm == -1)) {
-    if (fRegisterValue[reg].state == RegValue_t::kGlobal) {
+   if (fRegisterValue[reg].state == RegValue_t::kGlobal) {
       fRegisterValue[reg].globalValue = value;
-    } 
-    else if (fRegisterValue[reg].state == RegValue_t::kIndividual) {
-      delete [] fRegisterValue[reg].individualValue;
-      fRegisterValue[reg].state = RegValue_t::kGlobal;
+      return kTRUE;
+   }
+   else {
+      AliError("Register has individual values");
+   }
+   return kFALSE;
+}
+
+
+Bool_t AliTRDtrapConfig::SetTrapReg(TrapReg_t reg, Int_t value, Int_t det)
+{
+  // set a global value for the given TRAP register,
+  // i.e. the same value for all TRAPs
+
+   if (fRegisterValue[reg].state == RegValue_t::kGlobal) {
       fRegisterValue[reg].globalValue = value;
-    }
-    else {
+      return kTRUE;
+   }
+   else if (fRegisterValue[reg].state == RegValue_t::kIndividual) {
+      // if the register is in idividual mode but a broadcast is requested, the selected register is 
+      // set to value for all MCMs on the chamber
+
+      if( (det>=0 && det<AliTRDgeometry::Ndet())) {
+        for(Int_t rob=0; rob<AliTRDfeeParam::GetNrobC1(); rob++) {
+           for(Int_t mcm=0; mcm<fgkMaxMcm; mcm++)
+              fRegisterValue[reg].individualValue[det*AliTRDfeeParam::GetNrobC1()*fgkMaxMcm + rob*fgkMaxMcm + mcm] = value;
+        }
+      }
+      else {
+        AliError(Form("Invalid detector number: %i\n", det));
+        return kFALSE;
+      }
+   }
+   else {  // should never be reached
+      AliError("MCM register status neither kGlobal nor kIndividual");
       return kFALSE;
-    }
+   }
+   
+   return kFALSE;
+}
+
+
+Bool_t AliTRDtrapConfig::SetTrapReg(TrapReg_t reg, Int_t value, Int_t det, Int_t rob, Int_t mcm)
+{
+  // set the value for the given TRAP register of an individual MCM 
+
+  //std::cout << "-- reg: 0x" << std::hex << fRegs[reg].addr << 
+  //std::dec << ", data " << value << ", det " << det << ", rob " << rob << ", mcm " << mcm << std::endl;
+
+   if( (det >= 0 && det < AliTRDgeometry::Ndet()) && 
+       (rob >= 0 && rob < AliTRDfeeParam::GetNrobC1()) && 
+       (mcm >= 0 && mcm < fgkMaxMcm) ) {
+     if (fRegisterValue[reg].state == RegValue_t::kGlobal) {
+       Int_t defaultValue = fRegisterValue[reg].globalValue;
+       
+       fRegisterValue[reg].state = RegValue_t::kIndividual;
+       fRegisterValue[reg].individualValue = new Int_t[AliTRDgeometry::Ndet()*AliTRDfeeParam::GetNrobC1()*fgkMaxMcm];
+
+       for(Int_t i = 0; i < AliTRDgeometry::Ndet()*AliTRDfeeParam::GetNrobC1()*fgkMaxMcm; i++)
+          fRegisterValue[reg].individualValue[i] = defaultValue; // set the requested register of all MCMs to the value previously stored
+
+       fRegisterValue[reg].individualValue[det*AliTRDfeeParam::GetNrobC1()*fgkMaxMcm + rob*fgkMaxMcm + mcm] = value;
+     }
+     else if (fRegisterValue[reg].state == RegValue_t::kIndividual) {
+       fRegisterValue[reg].individualValue[det*AliTRDfeeParam::GetNrobC1()*fgkMaxMcm + rob*fgkMaxMcm + mcm] = value;
+     }
+     else {  // should never be reached
+       AliError("MCM register status neither kGlobal nor kIndividual");
+       return kFALSE;
+     }
   }
-  else if ((det < 0) || (det > 539) || (rob < 0) || (rob > 7) || (mcm < 0) || (mcm > 7)) {
-    AliError("Invalid MCM specified");
-    return kFALSE;
+   else {
+      AliError(Form("Invalid value for det, ROB or MCM selected: %i, %i, %i", det, rob, mcm));
+     return kFALSE;
+   }
+
+  return kTRUE;
+}
+
+
+UInt_t AliTRDtrapConfig::Peek(Int_t addr, Int_t det, Int_t rob, Int_t mcm) const
+{
+  // reading from given address
+
+  if ( (addr >= fgkDmemStartAddress) && 
+       (addr < (fgkDmemStartAddress + fgkDmemWords)) ) {
+    return GetDmemUnsigned(addr, det, rob, mcm);
   }
   else {
-    if (fRegisterValue[reg].state == RegValue_t::kGlobal) {
-      fRegisterValue[reg].state = RegValue_t::kIndividual;
-      fRegisterValue[reg].individualValue = new Int_t[540*38*16];
-      fRegisterValue[reg].individualValue[det*38*16 + rob*16 + mcm] = value;
-    }
-    else if (fRegisterValue[reg].state == RegValue_t::kIndividual) {
-      fRegisterValue[reg].individualValue[det*38*16 + rob*16 + mcm] = value;
+    TrapReg_t mcmReg = GetRegByAddress(addr);
+    if ( mcmReg >= 0 && mcmReg < kLastReg) {
+      return (UInt_t) GetTrapReg(mcmReg, det, rob, mcm);
     }
-    else {
-      return kFALSE;
+  }
+
+  return 0;
+}
+
+
+Bool_t AliTRDtrapConfig::Poke(Int_t addr, UInt_t value, Int_t det, Int_t rob, Int_t mcm)
+{
+  // writing to given address
+
+  if ( (addr >= fgkDmemStartAddress) && 
+       (addr < (fgkDmemStartAddress + fgkDmemWords)) ) {
+    AliDebug(2, Form("DMEM 0x%08x : %i", addr, value));
+    SetDmem(addr, value, det, rob, mcm);
+    return kTRUE;
+  }
+  else {
+    TrapReg_t mcmReg = GetRegByAddress(addr);
+    if ( mcmReg >= 0 && mcmReg < kLastReg) {
+      AliDebug(2, Form("Register: %s : %i\n", GetRegName(mcmReg), value));
+      SetTrapReg(mcmReg, (UInt_t) value, det, rob, mcm);
+      return kTRUE;
     }
   }
-  return kTRUE;
+  
+  return kFALSE;
+}
+
+
+Bool_t AliTRDtrapConfig::SetDmem(Int_t addr, UInt_t value)
+{
+  // Set the content of the given DMEM address 
+
+   addr = addr - fgkDmemStartAddress;
+
+   if(addr < 0 || addr >=  fgkDmemWords) {
+      AliError(Form("No DMEM address: 0x%08x", addr+fgkDmemStartAddress));
+      return kFALSE;
+   }
+
+   switch(fDmemDepth[addr]) {
+   case fgkDmemSizeEmpty:
+      AliDebug(4, Form("DMEM address %i not active", addr));
+      return kFALSE;
+      break;
+   case fgkDmemSizeUniform:
+      if(fDmem[addr][0]!=0)
+        AliDebug(5, Form("Warning: Setting new value to DMEM 0x%08x", addr+fgkDmemStartAddress));
+
+      fDmem[addr][0] = value;
+      break;
+   case fgkDmemSizeSmIndividual:
+      for(Int_t i=0; i<fgkDmemSizeSmIndividual; i++) {
+        if(fDmem[addr][i]!=0)
+           AliDebug(5, Form("Warning: Setting new value to DMEM 0x%08x", addr+fgkDmemStartAddress));
+
+        fDmem[addr][i]=value;
+      }
+      break;
+   case fgkDmemSizeTotalIndividual:
+      for(Int_t i=0; i<fgkDmemSizeTotalIndividual; i++) {
+        if(fDmem[addr][i]!=0)
+           AliDebug(5, Form("Warning: Setting new value to DMEM 0x%08x", addr+fgkDmemStartAddress));
+
+        fDmem[addr][i]=value;
+      }
+      break;
+   case fgkDmemSizeSmRocIndividual:
+      for(Int_t i=0; i<fgkDmemSizeSmRocIndividual; i++) {
+        if(fDmem[addr][i]!=0)
+           AliDebug(5, Form("Warning: Setting new value to DMEM 0x%08x", addr+fgkDmemStartAddress));
+
+        fDmem[addr][i]=value;
+      }
+      break;
+   default:
+      AliError(Form("Invalid selection type"));
+      break;
+   }
+
+   return kTRUE;
+}
+
+
+Bool_t AliTRDtrapConfig::SetDmem(Int_t addr, UInt_t value, Int_t det, Int_t rob, Int_t mcm)
+{
+  // Set the content of the given DMEM address 
+
+   addr = addr - fgkDmemStartAddress;
+   Int_t roc = det%30;
+   Int_t loc;
+   
+   if(addr < 0 || addr >=  fgkDmemWords) {
+      AliError(Form("No DMEM address: 0x%08x", addr+fgkDmemStartAddress));
+      return kFALSE;
+   }
+
+   Int_t detFactor=8*16;
+   Int_t robFactor=16;
+
+   switch(fDmemDepth[addr]) {
+   case fgkDmemSizeEmpty:
+      AliDebug(4, Form("DMEM address 0x%08x not active", addr+fgkDmemStartAddress));
+      return kFALSE;
+      break;
+   case fgkDmemSizeUniform:
+      if(fDmem[addr][0]!=0)
+        AliDebug(5, Form("Warning: Setting new value to DMEM 0x%08x", addr+fgkDmemStartAddress));
+
+      fDmem[addr][0] = value;
+      break;
+   case fgkDmemSizeSmIndividual:
+      loc = detFactor*roc + robFactor*rob + mcm;
+      if(loc < fgkDmemSizeSmIndividual) {
+        if(fDmem[addr][loc]!=0)
+           AliDebug(5, Form("Warning: Setting new value to DMEM 0x%08x", addr+fgkDmemStartAddress));
+
+        fDmem[addr][loc] = value;
+      }
+      else {
+        AliError(Form("DMEM sub-address %i out of scope", loc));
+        return kFALSE;
+      }
+      break;
+   case fgkDmemSizeTotalIndividual:
+      loc = detFactor*det + robFactor*rob + mcm;
+      if(loc < fgkDmemSizeTotalIndividual) {
+        if(fDmem[addr][loc]!=0)
+           AliDebug(5, Form("Warning: Setting new value to DMEM 0x%08x", addr+fgkDmemStartAddress));
+        
+        fDmem[addr][loc]=value;
+      }
+      else {
+        AliError(Form("DMEM sub-address %i out of scope", loc));
+        return kFALSE;
+      }
+      break;
+   case fgkDmemSizeSmRocIndividual:
+      if(det < fgkDmemSizeSmRocIndividual) {
+        if(fDmem[addr][det]!=0)
+           AliDebug(5, Form("Warning: Setting new value to DMEM 0x%08x", addr+fgkDmemStartAddress));
+
+        fDmem[addr][det]=value;
+      }
+      else {
+        AliError(Form("DMEM sub-address %i out of scope", det));
+        return kFALSE;
+      }
+      
+      break;
+   default:
+      AliError(Form("Invalid selection type"));
+      return kFALSE;
+      break;
+   }
+   
+   return kTRUE;
 }
 
+
+UInt_t AliTRDtrapConfig::GetDmemUnsigned(Int_t addr) const
+{
+   addr = addr - fgkDmemStartAddress;
+   if(addr < 0 || addr >=  fgkDmemWords) {
+      AliError(Form("No DMEM address: 0x%08x", addr+fgkDmemStartAddress));
+      return 0;
+   }
+
+   if(fDmemDepth[addr] == fgkDmemSizeUniform)
+      return fDmem[addr][0];
+   else {
+      AliError(Form("No global DMEM value at 0x%08x", addr+fgkDmemStartAddress));
+      return 0;
+   }
+   return 0;
+}
+
+UInt_t AliTRDtrapConfig::GetDmemUnsigned(Int_t addr, Int_t det, Int_t rob, Int_t mcm) const
+{
+   addr = addr - fgkDmemStartAddress;
+   Int_t roc = det%30;
+   Int_t loc;
+   
+   if(addr < 0 || addr >=  fgkDmemWords) {
+      AliError(Form("No DMEM address: 0x%08x", addr+fgkDmemStartAddress));
+      return 0;
+   }
+
+   Int_t detFactor=8*16;
+   Int_t robFactor=16;
+
+   switch(fDmemDepth[addr]) {
+   case fgkDmemSizeEmpty:
+      AliDebug(4, Form("DMEM address 0x%08x not active", addr+fgkDmemStartAddress));
+      return 0;
+      break;
+   case fgkDmemSizeUniform:
+      return fDmem[addr][0];
+      break;
+   case fgkDmemSizeSmIndividual:
+      loc = detFactor*roc + robFactor*rob + mcm;
+      if(loc < fgkDmemSizeSmIndividual) {
+        return fDmem[addr][loc];
+      }
+      else {
+        AliError(Form("DMEM sub-address %i out of scope", loc));
+        return 0;
+      }
+      break;
+   case fgkDmemSizeTotalIndividual:
+      loc = detFactor*det + robFactor*rob + mcm;
+      if(loc < fgkDmemSizeTotalIndividual) {
+        return fDmem[addr][loc];
+      }
+      else {
+        AliError(Form("DMEM sub-address %i out of scope", loc));
+        return 0;
+      }
+      break;
+   case fgkDmemSizeSmRocIndividual:
+      if(det < fgkDmemSizeSmRocIndividual) {
+        return fDmem[addr][det];
+      }
+      else {
+        AliError(Form("DMEM sub-address %i out of scope", det));
+        return 0;
+      }
+      break;
+   default:
+      AliError(Form("Invalid selection type"));
+      return 0;
+      break;
+   }
+   
+   return 0;
+}
+
+
 Bool_t AliTRDtrapConfig::LoadConfig()
 {
   // load a set of TRAP register values (configuration)
-  // so far only a default set is implemented for testing
+  // here a default set is implemented for testing
   // for a detailed description of the registers see the TRAP manual
 
+  // HC header configuration bits
+  SetTrapReg(kC15CPUA, 0x2102); // zs, deh
+
+  // no. of timebins
+  SetTrapReg(kC13CPUA, 24); 
 
   // pedestal filter
   SetTrapReg(kFPNP, 4*10);
   SetTrapReg(kFPTC, 0);
-  SetTrapReg(kFPBY, 1);
+  SetTrapReg(kFPBY, 0); // bypassed!
   
   // gain filter
   for (Int_t adc = 0; adc < 20; adc++) {
@@ -550,10 +1026,10 @@ Bool_t AliTRDtrapConfig::LoadConfig()
   SetTrapReg(kFGBY, 0);  // bypassed!
 
   // tail cancellation
-  SetTrapReg(kFTAL, 270);
-  SetTrapReg(kFTLL, 348);
-  SetTrapReg(kFTLS, 449);
-  SetTrapReg(kFTBY, 1);
+  SetTrapReg(kFTAL, 267);
+  SetTrapReg(kFTLL, 356);
+  SetTrapReg(kFTLS, 387);
+  SetTrapReg(kFTBY, 0);
 
   // tracklet calculation
   SetTrapReg(kTPQS0, 5);
@@ -564,29 +1040,201 @@ Bool_t AliTRDtrapConfig::LoadConfig()
   SetTrapReg(kTPFE, 20);
   SetTrapReg(kTPVBY, 0);
   SetTrapReg(kTPVT, 10);
-  SetTrapReg(kTPHT, 100);
+  SetTrapReg(kTPHT, 150);
   SetTrapReg(kTPFP, 40);
-  SetTrapReg(kTPCL, 3);
-  SetTrapReg(kTPCT, 5);
+  SetTrapReg(kTPCL, 1);
+  SetTrapReg(kTPCT, 10);
+
+  // ndrift (+ 5 binary digits)
+  SetDmem(0xc025, 20 << 5);
+  // deflection + tilt correction
+  SetDmem(0xc022, 0); 
+  // deflection range table
+  for (Int_t iTrklCh = 0; iTrklCh < 18; iTrklCh++) {
+    SetDmem(0xc030 + 2 * iTrklCh, -64); // min. deflection
+    SetDmem(0xc031 + 2 * iTrklCh,  63); // max. deflection
+  }
   
+  // hit position LUT
+  const UShort_t lutPos[128] = {
+    0,  1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  6,  7,  7,  8,  8,  9,  9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15,
+    16, 16, 16, 17, 17, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 26, 26, 26, 26,
+    27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 27, 27, 27, 27, 26,
+    26, 26, 26, 25, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 18, 18, 17, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  7};
+  for (Int_t iCOG = 0; iCOG < 128; iCOG++)
+    SetTrapReg((TrapReg_t) (kTPL00 + iCOG), lutPos[iCOG]);
+
   // event buffer
   SetTrapReg(kEBSF, 1);  // 0: store filtered; 1: store unfiltered
   // zs applied to data stored in event buffer (sel. by EBSF)
-  SetTrapReg(kEBIS, 5 << 2); // single indicator threshold (plus two digits)
-  SetTrapReg(kEBIT, 5 << 2); // sum indicator threshold (plus two digits)
+  SetTrapReg(kEBIS, 15 << 2); // single indicator threshold (plus two digits)
+  SetTrapReg(kEBIT, 30 << 2); // sum indicator threshold (plus two digits)
   SetTrapReg(kEBIL, 0xf0);   // lookup table
-  SetTrapReg(kEBIN, 1);      // no neighbour sensitivity
+  SetTrapReg(kEBIN, 0);      // neighbour sensitivity
+
+  // raw data
+  SetTrapReg(kNES, (0x0000 << 16) | 0x1000);
 
   return kTRUE;
 }
 
-void AliTRDtrapConfig::PrintTrapReg(TrapReg_t reg, Int_t det, Int_t rob, Int_t mcm)
+
+Bool_t AliTRDtrapConfig::ReadPackedConfig(Int_t hc, UInt_t *data, Int_t size) 
+{
+  // Read the packed configuration from the passed memory block
+  //
+  // To be used to retrieve the TRAP configuration from the 
+  // configuration as sent in the raw data. 
+
+  AliDebug(1, "Reading packed configuration");
+
+  Int_t det = hc/2;
+
+  Int_t idx = 0;
+  Int_t err = 0;
+  Int_t step, bwidth, nwords, exitFlag, bitcnt;
+  
+  UShort_t caddr;
+  UInt_t dat, msk, header, dataHi;
+  
+  while (idx < size && *data != 0x00000000) {
+    
+    Int_t rob = (*data >> 28) & 0x7;
+    Int_t mcm = (*data >> 24) & 0xf;
+
+    AliDebug(1, Form("Config of det. %3i MCM %i:%02i (0x%08x)", det, rob, mcm, *data));
+    data++;
+    
+    while (idx < size && *data != 0x00000000) {
+      
+      header = *data;
+      data++;
+      idx++;
+      
+      AliDebug(5, Form("read: 0x%08x", header));
+      
+      if (header & 0x01) // single data
+       {
+         dat   = (header >>  2) & 0xFFFF;       // 16 bit data 
+         caddr = (header >> 18) & 0x3FFF;    // 14 bit address 
+         
+         if (caddr != 0x1FFF)  // temp!!! because the end marker was wrong
+           {
+             if (header & 0x02) // check if > 16 bits
+               {
+                 dataHi = *data;
+                 AliDebug(5, Form("read: 0x%08x", dataHi));
+                 data++;
+                 idx++;
+                 err += ((dataHi ^ (dat | 1)) & 0xFFFF) != 0;
+                 dat = (dataHi & 0xFFFF0000) | dat;
+               }
+             AliDebug(5, Form("addr=0x%04x (%s) data=0x%08x\n", caddr, GetRegName(GetRegByAddress(caddr)), dat));
+             if ( ! Poke(caddr, dat, det, rob, mcm) )
+               AliDebug(5, Form("(single-write): non-existing address 0x%04x containing 0x%08x\n", caddr, header));
+             if (idx > size)
+               {
+                 AliDebug(5, Form("(single-write): no more data, missing end marker\n"));
+                 return -err;
+               }
+           }
+         else
+           {
+             AliDebug(5, Form("(single-write): address 0x%04x => old endmarker?\n", caddr));
+             return err;
+           }
+       }
+      
+      else               // block of data  
+       {
+         step   =  (header >>  1) & 0x0003;
+         bwidth = ((header >>  3) & 0x001F) + 1;
+         nwords =  (header >>  8) & 0x00FF;
+         caddr  =  (header >> 16) & 0xFFFF;
+         exitFlag = (step == 0) || (step == 3) || (nwords == 0);
+         
+         if (exitFlag) 
+           break;
+         
+         switch (bwidth)
+           {
+           case    15:
+           case    10:
+           case     7:
+           case     6:
+           case     5:
+             {
+               msk = (1 << bwidth) - 1;
+               bitcnt = 0;
+               while (nwords > 0)
+                 {
+                   nwords--;
+                   bitcnt -= bwidth;
+                   if (bitcnt < 0)
+                     {
+                       header = *data;
+                       AliDebug(5, Form("read 0x%08x", header));
+                       data++;
+                       idx++;
+                       err += (header & 1);
+                       header = header >> 1;
+                       bitcnt = 31 - bwidth;
+                     }
+                   AliDebug(5, Form("addr=0x%04x (%s) data=0x%08x\n", caddr, GetRegName(GetRegByAddress(caddr)), header & msk));
+                   if ( ! Poke(caddr, header & msk, det, rob, mcm) )
+                     AliDebug(5, Form("(single-write): non-existing address 0x%04x containing 0x%08x\n", caddr, header));
+                   
+                   caddr += step;
+                   header = header >> bwidth;
+                   if (idx >= size)
+                     {
+                       AliDebug(5, Form("(block-write): no end marker! %d words read\n", idx));
+                       return -err;
+                     }
+                 }
+               break;
+             } // end case 5-15                                         
+           case 31:
+             {
+               while (nwords > 0)
+                 {
+                   header = *data;
+                   AliDebug(5, Form("read 0x%08x", header));
+                   data++;
+                   idx++;
+                   nwords--;
+                   err += (header & 1);
+                   
+                   AliDebug(5, Form("addr=0x%04x (%s) data=0x%08x", caddr, GetRegName(GetRegByAddress(caddr)), header >> 1));
+                   if ( ! Poke(caddr, header >> 1, det, rob, mcm) )
+                     AliDebug(5, Form("(single-write): non-existing address 0x%04x containing 0x%08x\n", caddr, header));
+                   
+                   caddr += step;
+                   if (idx >= size)
+                     {
+                       AliDebug(5, Form("no end marker! %d words read", idx));
+                       return -err;
+                     }
+                 }
+               break;
+             }
+           default: return err;
+           } // end switch 
+       } // end block case
+    }
+  } // end while
+  AliDebug(5, Form("no end marker! %d words read", idx));
+  return -err; // only if the max length of the block reached!                       
+}
+
+
+Bool_t AliTRDtrapConfig::PrintTrapReg(TrapReg_t reg, Int_t det, Int_t rob, Int_t mcm) const
 {
-  // print the information about the given register
+  // print the value stored in the given register
   // if it is individual a valid MCM has to be specified
 
   if (fRegisterValue[reg].state == RegValue_t::kGlobal) {
-    printf("%s (%i bits) at 0x%08x is 0x%08x and resets to: 0x%08x\n", 
+    printf("%s (%i bits) at 0x%08x is 0x%08x and resets to: 0x%08x (currently global mode)\n", 
            GetRegName((TrapReg_t) reg),
            GetRegNBits((TrapReg_t) reg),
            GetRegAddress((TrapReg_t) reg),
@@ -594,16 +1242,154 @@ void AliTRDtrapConfig::PrintTrapReg(TrapReg_t reg, Int_t det, Int_t rob, Int_t m
            GetRegResetValue((TrapReg_t) reg));
   }
   else if (fRegisterValue[reg].state == RegValue_t::kIndividual) {
-    if ((det < 0) || (det > 539) || (rob < 0) || (rob > 7) || (mcm < 0) || (mcm > 7)) {
-      AliError("Register value is MCM-specific but an invalid MCM is specified");
-    }
-    else {
-      printf("%s (%i bits) at 0x%08x is 0x%08x and resets to: 0x%08x\n", 
+    if((det >= 0 && det < AliTRDgeometry::Ndet()) && 
+       (rob >= 0 && rob < AliTRDfeeParam::GetNrobC1()) && 
+       (mcm >= 0 && mcm < fgkMaxMcm)) {
+      printf("%s (%i bits) at 0x%08x is 0x%08x and resets to: 0x%08x (currently individual mode)\n", 
              GetRegName((TrapReg_t) reg),
              GetRegNBits((TrapReg_t) reg),
              GetRegAddress((TrapReg_t) reg),
-             fRegisterValue[reg].individualValue[det*38*16 + rob*16 + mcm],
+             fRegisterValue[reg].individualValue[det*AliTRDfeeParam::GetNrobC1()*fgkMaxMcm + rob*fgkMaxMcm + mcm],
              GetRegResetValue((TrapReg_t) reg));
     }
+    else {
+      AliError("Register value is MCM-specific: Invalid detector, ROB or MCM requested");
+      return kFALSE;
+    }
+  }
+  else {  // should never be reached
+    AliError("MCM register status neither kGlobal nor kIndividual");
+    return kFALSE;
+  }
+  return kTRUE;
+}
+
+
+Bool_t AliTRDtrapConfig::PrintTrapAddr(Int_t addr, Int_t det, Int_t rob, Int_t mcm) const
+{
+  // print the value stored at the given address in the MCM chip
+  TrapReg_t reg = GetRegByAddress(addr);
+  if (reg >= 0 && reg < kLastReg) {
+    return PrintTrapReg(reg, det, rob, mcm);
+  }
+  else {
+    AliError(Form("There is no register at address 0x%08x in the simulator", addr));
+    return kFALSE;
+  }
+}
+
+
+Bool_t AliTRDtrapConfig::AddValues(UInt_t det, UInt_t cmd, UInt_t extali, Int_t addr, UInt_t data)
+{
+   // transfer the informations provided by LoadConfig to the internal class variables
+
+  if(cmd != fgkScsnCmdWrite) {
+    AliError(Form("Invalid command received: %i", cmd));
+    return kFALSE;
+  }
+
+  TrapReg_t mcmReg = GetRegByAddress(addr);
+  Int_t rocType = AliTRDgeometry::GetStack(det) == 2 ? 0 : 1;
+
+  static const int mcmListSize=40;  // 40 is more or less arbitrary
+  Int_t mcmList[mcmListSize];
+
+  // configuration registers
+  if(mcmReg >= 0 && mcmReg < kLastReg) {
+    
+    for(Int_t linkPair=0; linkPair<fgkMaxLinkPairs; linkPair++) {
+      if(AliTRDfeeParam::ExtAliToAli(extali, linkPair, rocType, mcmList, mcmListSize)!=0) {
+       Int_t i=0;
+        while(mcmList[i] != -1 && i<mcmListSize) {
+          if(mcmList[i]==127)
+            SetTrapReg( (TrapReg_t) mcmReg, data, det);
+          else
+            SetTrapReg( (TrapReg_t) mcmReg, data, det, (mcmList[i]>>7), (mcmList[i]&0x7F));
+          i++;
+        }
+      }
+    }
+    return kTRUE;
   }
+  // DMEM
+  else if ( (addr >= fgkDmemStartAddress) && 
+           (addr < (fgkDmemStartAddress + fgkDmemWords))) {
+    for(Int_t linkPair=0; linkPair<fgkMaxLinkPairs; linkPair++) {
+      if(AliTRDfeeParam::ExtAliToAli(extali, linkPair, rocType, mcmList, mcmListSize)!=0) {
+        Int_t i=0;
+        while(mcmList[i] != -1 && i < mcmListSize) {
+          if(mcmList[i] == 127)
+            SetDmem(addr, data, det, 0, 127);
+          else
+            SetDmem(addr, data, det, mcmList[i] >> 7, mcmList[i] & 0x7f);
+          i++;
+        }
+      }
+    }
+    return kTRUE;
+  }
+  else 
+    return kFALSE;
+}
+
+
+AliTRDtrapConfig::TrapReg_t AliTRDtrapConfig::GetRegByAddress(Int_t address) const
+{
+  // get register by its address
+  // used for reading of configuration data as sent to real FEE
+
+  TrapReg_t mcmReg = kLastReg;
+  Int_t reg  = 0;
+  do {
+    if(fRegs[reg].fAddr == address)
+      mcmReg = (TrapReg_t) reg;
+    reg++;
+  }  while (mcmReg == kLastReg && reg < kLastReg);
+
+  return mcmReg;
+}
+
+
+void AliTRDtrapConfig::PrintMemDatx(ostream &os, Int_t addr) const
+{
+   PrintMemDatx(os, addr, 0, 0, 127);
+}
+
+void AliTRDtrapConfig::PrintMemDatx(ostream &os, Int_t addr, Int_t det, Int_t rob, Int_t mcm) const
+{
+   if(addr < fgkDmemStartAddress || addr >= fgkDmemStartAddress+fgkDmemWords) {
+      AliError(Form("Invalid DMEM address 0x%08x!", addr));
+      return;
+   }
+   PrintDatx(os, addr, GetDmemUnsigned(addr, det, rob, mcm), rob, mcm);
+}
+
+
+void AliTRDtrapConfig::PrintMemDatx(ostream &os, TrapReg_t reg) const
+{
+   PrintMemDatx(os, reg, 0, 0, 127);
+}
+
+
+void AliTRDtrapConfig::PrintMemDatx(ostream &os, TrapReg_t reg, Int_t det, Int_t rob, Int_t mcm) const
+{
+   if(reg>= kLastReg) {
+      AliError(Form("Invalid register %i!", reg));
+      return;
+   }
+   PrintDatx(os, GetRegAddress(reg), GetTrapReg(reg, det, rob, mcm), rob, mcm);
+}
+
+
+void AliTRDtrapConfig::PrintDatx(ostream &os, UInt_t addr, UInt_t data, Int_t rob, Int_t mcm) const
+{
+   os << std::setw(5) << 10 
+      << std::setw(8) << addr
+      << std::setw(12) << data;
+   if(mcm==127)
+      os << std::setw(8) << 127;
+   else
+      os << std::setw(8) << AliTRDfeeParam::AliToExtAli(rob, mcm);
+   
+   os << std::endl;
 }