- make AliTRDtrapConfig streamable
authorjklein <jklein@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 21 Mar 2012 10:25:26 +0000 (10:25 +0000)
committerjklein <jklein@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 21 Mar 2012 10:25:26 +0000 (10:25 +0000)
  in preparation for OCDB integration

TRD/AliTRDmcmSim.cxx
TRD/AliTRDmcmSim.h
TRD/AliTRDtrapConfig.cxx
TRD/AliTRDtrapConfig.h
TRD/AliTRDtrapConfigHandler.cxx
TRD/AliTRDtrapConfigHandler.h
TRD/TRDbaseLinkDef.h

index e0a8791..15354e0 100644 (file)
@@ -42,6 +42,7 @@
 #include "AliLoader.h"
 
 #include "AliTRDfeeParam.h"
+#include "AliTRDtrapConfigHandler.h"
 #include "AliTRDtrapConfig.h"
 #include "AliTRDdigitsManager.h"
 #include "AliTRDarrayADC.h"
@@ -136,7 +137,7 @@ void AliTRDmcmSim::Init( Int_t det, Int_t robPos, Int_t mcmPos, Bool_t /* newEve
 
   if (!fInitialized) {
     fFeeParam      = AliTRDfeeParam::Instance();
-    fTrapConfig    = AliTRDtrapConfig::Instance();
+    fTrapConfig    = AliTRDtrapConfigHandler::GetTrapConfig();
   }
 
   fDetector      = det;
@@ -478,7 +479,7 @@ void AliTRDmcmSim::Draw(Option_t* const option)
       AliTRDtrackletMCM *trkl = (AliTRDtrackletMCM*) (*fTrackletArray)[iTrkl];
       Float_t padWidth = 0.635 + 0.03 * (fDetector % 6);
       Float_t offset   = padWidth/256. * ((((((fRobPos & 0x1) << 2) + (fMcmPos & 0x3)) * 18) << 8) - ((18*4*2 - 18*2 - 3) << 7)); // revert adding offset in FitTracklet
-      Int_t   ndrift   = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrNdrift, fDetector, fRobPos, fMcmPos) >> 5;
+      Int_t   ndrift   = fTrapConfig->GetDmemUnsigned(fgkDmemAddrNdrift, fDetector, fRobPos, fMcmPos) >> 5;
       Float_t slope    = 0;
       if (ndrift)
        slope = trkl->GetdY() * 140e-4 / ndrift;
@@ -1217,7 +1218,9 @@ void AliTRDmcmSim::CalcFitreg()
   //??? to be clarified:
   UInt_t adcMask = 0xffffffff;
 
-  UShort_t timebin, adcch, adcLeft, adcCentral, adcRight, hitQual, timebin1, timebin2, qtotTemp;
+  Bool_t hitQual;
+  Int_t adcLeft, adcCentral, adcRight;
+  UShort_t timebin, adcch, timebin1, timebin2, qtotTemp;
   Short_t ypos, fromLeft, fromRight, found;
   UShort_t qTotal[19+1]; // the last is dummy
   UShort_t marked[6], qMarked[6], worse1, worse2;
@@ -1255,11 +1258,21 @@ void AliTRDmcmSim::CalcFitreg()
         adcLeft  = fADCF[adcch  ][timebin];
         adcCentral  = fADCF[adcch+1][timebin];
         adcRight = fADCF[adcch+2][timebin];
-        if (fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPVBY, fDetector, fRobPos, fMcmPos) == 1)
+
+        if (fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPVBY, fDetector, fRobPos, fMcmPos) == 0) {
+         // bypass the cluster verification
+          hitQual = kTRUE;
+       }
+        else {
           hitQual = ( (adcLeft * adcRight) <
-                       (fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPVT, fDetector, fRobPos, fMcmPos) * adcCentral) );
-        else
-          hitQual = 1;
+                     ((fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPVT, fDetector, fRobPos, fMcmPos) * adcCentral*adcCentral) >> 10) );
+         if (hitQual)
+           AliDebug(5, Form("cluster quality cut passed with %3i, %3i, %3i - threshold %3i -> %i",
+                            adcLeft, adcCentral, adcRight,
+                            fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPVT, fDetector, fRobPos, fMcmPos),
+                            fTrapConfig->GetTrapReg(AliTRDtrapConfig::kTPVT, fDetector, fRobPos, fMcmPos) * adcCentral*adcCentral));
+       }
+
         // The accumulated charge is with the pedestal!!!
         qtotTemp = adcLeft + adcCentral + adcRight;
         if ( (hitQual) &&
@@ -1539,8 +1552,8 @@ void AliTRDmcmSim::FitTracklet()
   UInt_t scaleY = (UInt_t) ((0.635 + 0.03 * layer)/(256.0 * 160.0e-4) * shift);
   UInt_t scaleD = (UInt_t) ((0.635 + 0.03 * layer)/(256.0 * 140.0e-4) * shift);
 
-  Int_t deflCorr = (Int_t) fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrDeflCorr, fDetector, fRobPos, fMcmPos);
-  Int_t ndrift   = (Int_t) fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrNdrift, fDetector, fRobPos, fMcmPos);
+  Int_t deflCorr = (Int_t) fTrapConfig->GetDmemUnsigned(fgkDmemAddrDeflCorr, fDetector, fRobPos, fMcmPos);
+  Int_t ndrift   = (Int_t) fTrapConfig->GetDmemUnsigned(fgkDmemAddrNdrift, fDetector, fRobPos, fMcmPos);
 
   // local variables for calculation
   Long64_t mult, temp, denom; //???
@@ -1612,8 +1625,8 @@ void AliTRDmcmSim::FitTracklet()
 
       AliDebug(5, Form("Det: %3i, ROB: %i, MCM: %2i: deflection: %i, min: %i, max: %i",
                        fDetector, fRobPos, fMcmPos, slope,
-                       (Int_t) fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrDeflCutStart     + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos),
-                       (Int_t) fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrDeflCutStart + 1 + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos)));
+                       (Int_t) fTrapConfig->GetDmemUnsigned(fgkDmemAddrDeflCutStart     + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos),
+                       (Int_t) fTrapConfig->GetDmemUnsigned(fgkDmemAddrDeflCutStart + 1 + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos)));
 
       AliDebug(5, Form("Fit sums: x = %i, X = %i, y = %i, Y = %i, Z = %i",
                       sumX, sumX2, sumY, sumY2, sumXY));
@@ -1632,8 +1645,8 @@ void AliTRDmcmSim::FitTracklet()
 
       Bool_t rejected = kFALSE;
       // deflection range table from DMEM
-      if ((slope < ((Int_t) fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrDeflCutStart     + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos))) ||
-          (slope > ((Int_t) fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrDeflCutStart + 1 + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos))))
+      if ((slope < ((Int_t) fTrapConfig->GetDmemUnsigned(fgkDmemAddrDeflCutStart     + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos))) ||
+          (slope > ((Int_t) fTrapConfig->GetDmemUnsigned(fgkDmemAddrDeflCutStart + 1 + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos))))
         rejected = kTRUE;
 
       if (rejected && GetApplyCut())
@@ -1891,13 +1904,13 @@ Int_t AliTRDmcmSim::GetPID(Int_t q0, Int_t q1)
    ULong64_t addrQ0;
    ULong64_t addr;
 
-   UInt_t nBinsQ0 = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTnbins);  // number of bins in q0 / 4 !!
-   UInt_t pidTotalSize = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTLength);
+   UInt_t nBinsQ0 = fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTnbins, fDetector, fRobPos, fMcmPos);  // number of bins in q0 / 4 !!
+   UInt_t pidTotalSize = fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTLength, fDetector, fRobPos, fMcmPos);
    if(nBinsQ0==0 || pidTotalSize==0)  // make sure we don't run into trouble if the value for Q0 is not configured
      return 0;                        // Q1 not configured is ok for 1D LUT
 
-   ULong_t corrQ0 = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTcor0, fDetector, fRobPos, fMcmPos);
-   ULong_t corrQ1 = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTcor1, fDetector, fRobPos, fMcmPos);
+   ULong_t corrQ0 = fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTcor0, fDetector, fRobPos, fMcmPos);
+   ULong_t corrQ1 = fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTcor1, fDetector, fRobPos, fMcmPos);
    if(corrQ0==0)  // make sure we don't run into trouble if one of the values is not configured
       return 0;
 
@@ -1920,7 +1933,7 @@ Int_t AliTRDmcmSim::GetPID(Int_t q0, Int_t q1)
 
    // For a LUT with 11 input and 8 output bits, the first memory address is set to  LUT[0] | (LUT[1] << 8) | (LUT[2] << 16) | (LUT[3] << 24)
    // and so on
-   UInt_t result = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTStart+(addr/4));
+   UInt_t result = fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTStart+(addr/4), fDetector, fRobPos, fMcmPos);
    return (result>>((addr%4)*8)) & 0xFF;
 }
 
@@ -2401,16 +2414,16 @@ void AliTRDmcmSim::PrintPidLutHuman()
 
    UInt_t result;
 
-   UInt_t addrEnd = AliTRDtrapConfig::fgkDmemAddrLUTStart + fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTLength)/4; // /4 because each addr contains 4 values
-   UInt_t nBinsQ0 = fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTnbins);
+   UInt_t addrEnd = fgkDmemAddrLUTStart + fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTLength, fDetector, fRobPos, fMcmPos)/4; // /4 because each addr contains 4 values
+   UInt_t nBinsQ0 = fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTnbins, fDetector, fRobPos, fMcmPos);
 
    std::cout << "nBinsQ0: " << nBinsQ0 << std::endl;
-   std::cout << "LUT table length: " << fTrapConfig->GetDmemUnsigned(AliTRDtrapConfig::fgkDmemAddrLUTLength) << std::endl;
+   std::cout << "LUT table length: " << fTrapConfig->GetDmemUnsigned(fgkDmemAddrLUTLength, fDetector, fRobPos, fMcmPos) << std::endl;
 
    if (nBinsQ0>0) {
-     for(UInt_t addr=AliTRDtrapConfig::fgkDmemAddrLUTStart; addr< addrEnd; addr++) {
-       result = fTrapConfig->GetDmemUnsigned(addr);
-       std::cout << addr << " # x: " << ((addr-AliTRDtrapConfig::fgkDmemAddrLUTStart)%((nBinsQ0)/4))*4 << ", y: " <<(addr-AliTRDtrapConfig::fgkDmemAddrLUTStart)/(nBinsQ0/4)
+     for(UInt_t addr=fgkDmemAddrLUTStart; addr< addrEnd; addr++) {
+       result = fTrapConfig->GetDmemUnsigned(addr, fDetector, fRobPos, fMcmPos);
+       std::cout << addr << " # x: " << ((addr-fgkDmemAddrLUTStart)%((nBinsQ0)/4))*4 << ", y: " <<(addr-fgkDmemAddrLUTStart)/(nBinsQ0/4)
                 << "  #  " <<((result>>0)&0xFF)
                 << " | "  << ((result>>8)&0xFF)
                 << " | "  << ((result>>16)&0xFF)
@@ -2418,3 +2431,152 @@ void AliTRDmcmSim::PrintPidLutHuman()
      }
    }
 }
+
+
+Bool_t AliTRDmcmSim::ReadPackedConfig(AliTRDtrapConfig *cfg, 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.
+
+  AliDebugClass(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;
+
+    AliDebugClass(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++;
+
+      AliDebugClass(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;
+                 AliDebugClass(5, Form("read: 0x%08x", dataHi));
+                 data++;
+                 idx++;
+                 err += ((dataHi ^ (dat | 1)) & 0xFFFF) != 0;
+                 dat = (dataHi & 0xFFFF0000) | dat;
+               }
+             AliDebugClass(5, Form("addr=0x%04x (%s) data=0x%08x\n", caddr, cfg->GetRegName(cfg->GetRegByAddress(caddr)), dat));
+             if ( ! cfg->Poke(caddr, dat, det, rob, mcm) )
+               AliDebugClass(5, Form("(single-write): non-existing address 0x%04x containing 0x%08x\n", caddr, header));
+             if (idx > size)
+               {
+                 AliDebugClass(5, Form("(single-write): no more data, missing end marker\n"));
+                 return -err;
+               }
+           }
+         else
+           {
+             AliDebugClass(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;
+                       AliDebugClass(5, Form("read 0x%08x", header));
+                       data++;
+                       idx++;
+                       err += (header & 1);
+                       header = header >> 1;
+                       bitcnt = 31 - bwidth;
+                     }
+                   AliDebugClass(5, Form("addr=0x%04x (%s) data=0x%08x\n", caddr, cfg->GetRegName(cfg->GetRegByAddress(caddr)), header & msk));
+                   if ( ! cfg->Poke(caddr, header & msk, det, rob, mcm) )
+                     AliDebugClass(5, Form("(single-write): non-existing address 0x%04x containing 0x%08x\n", caddr, header));
+
+                   caddr += step;
+                   header = header >> bwidth;
+                   if (idx >= size)
+                     {
+                       AliDebugClass(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;
+                   AliDebugClass(5, Form("read 0x%08x", header));
+                   data++;
+                   idx++;
+                   nwords--;
+                   err += (header & 1);
+
+                   AliDebugClass(5, Form("addr=0x%04x (%s) data=0x%08x", caddr, cfg->GetRegName(cfg->GetRegByAddress(caddr)), header >> 1));
+                   if ( ! cfg->Poke(caddr, header >> 1, det, rob, mcm) )
+                     AliDebugClass(5, Form("(single-write): non-existing address 0x%04x containing 0x%08x\n", caddr, header));
+
+                   caddr += step;
+                   if (idx >= size)
+                     {
+                       AliDebugClass(5, Form("no end marker! %d words read", idx));
+                       return -err;
+                     }
+                 }
+               break;
+             }
+           default: return err;
+           } // end switch
+       } // end block case
+    }
+  } // end while
+  AliDebugClass(5, Form("no end marker! %d words read", idx));
+  return -err; // only if the max length of the block reached!
+}
index de4da5c..5d60056 100644 (file)
@@ -130,6 +130,25 @@ class AliTRDmcmSim : public TObject {
          void PrintAdcDatXml(ostream& os) const;
          void PrintAdcDatDatx(ostream& os, Bool_t broadcast=kFALSE, Int_t timeBinOffset = -1) const;
 
+  static  Bool_t ReadPackedConfig(AliTRDtrapConfig *cfg, Int_t det, UInt_t *data, Int_t size);
+
+  // DMEM addresses
+  static const Int_t fgkDmemAddrLUTcor0       = 0xC02A;
+  static const Int_t fgkDmemAddrLUTcor1       = 0xC028;
+  static const Int_t fgkDmemAddrLUTnbins      = 0xC029;
+
+  static const Int_t fgkDmemAddrLUTStart      = 0xC100; // LUT start address
+  static const Int_t fgkDmemAddrLUTEnd        = 0xC3FF; // maximum possible end address for the LUT table
+  static const Int_t fgkDmemAddrLUTLength     = 0xC02B; // address where real size of the LUT table is stored
+
+  static const Int_t fgkDmemAddrTrackletStart = 0xC0E0; // Storage area for tracklets, start address
+  static const Int_t fgkDmemAddrTrackletEnd   = 0xC0E3; // Storage area for tracklets, end address
+
+  static const Int_t fgkDmemAddrDeflCorr      = 0xc022; // DMEM address of deflection correction
+  static const Int_t fgkDmemAddrNdrift        = 0xc025; // DMEM address of Ndrift
+  static const Int_t fgkDmemAddrDeflCutStart  = 0xc030; // DMEM start address of deflection cut
+  static const Int_t fgkDmemAddrDeflCutEnd    = 0xc055; // DMEM end address of deflection cut
+
  protected:
          Bool_t    CheckInitialized() const;           // Check whether the class is initialized
 
@@ -146,7 +165,6 @@ class AliTRDmcmSim : public TObject {
 
  static const UShort_t fgkFPshifts[4];                  // shifts for pedestal filter
 
-
          Bool_t    fInitialized;                       // memory is allocated if initialized
          Int_t     fDetector;                          // Chamber ID
          Int_t     fRobPos;                            // ROB Position on chamber
index cde01f7..e847bb0 100644 (file)
 #include "AliTRDgeometry.h"
 #include "AliTRDfeeParam.h"
 #include "AliTRDtrapConfig.h"
-#include "AliTRDtrapConfigHandler.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(), fScaleQ0(0), fScaleQ1(0)
+const Int_t AliTRDtrapConfig::AliTRDtrapValue::fgkSize[] = {
+  0,
+  1,
+  540,
+  1080,
+  8*18*540,
+  4,
+  6,
+  8*18*30
+};
+Bool_t AliTRDtrapConfig::fgRegAddressMapInitialized = kFALSE;
+AliTRDtrapConfig::TrapReg_t AliTRDtrapConfig::fgRegAddressMap[] = { };
+const Int_t AliTRDtrapConfig::fgkRegisterAddressBlockStart[] = { 0x0a00, 0x3000, 0xd000 };
+const Int_t AliTRDtrapConfig::fgkRegisterAddressBlockSize[]  = { 0x0400, 0x0200, 0x0004 };
+
+AliTRDtrapConfig::AliTRDtrapConfig(const TString &name, const TString &title) :
+  TNamed(name, title)
 {
-  // default constructor, initializing array of TRAP registers
-
-  //                              Name          Address  Nbits   Reset Value
-  fRegs[kSML0]    =   SimpleReg_t("SML0",        0x0A00, 15,     0x4050     );  // Global state machine
-  fRegs[kSML1]    =   SimpleReg_t("SML1",        0x0A01, 15,     0x4200     );
-  fRegs[kSML2]    =   SimpleReg_t("SML2",        0x0A02, 15,     0x4384     );
-  fRegs[kSMMODE]  =   SimpleReg_t("SMMODE",      0x0A03, 16,     0xF0E2     );
-  fRegs[kNITM0]   =   SimpleReg_t("NITM0",       0x0A08, 14,     0x3FFF     );
-  fRegs[kNITM1]   =   SimpleReg_t("NITM1",       0x0A09, 14,     0x3FFF     );
-  fRegs[kNITM2]   =   SimpleReg_t("NITM2",       0x0A0A, 14,     0x3FFF     );
-  fRegs[kNIP4D]   =   SimpleReg_t("NIP4D",       0x0A0B, 7,      0x7F       );
-  fRegs[kCPU0CLK] =   SimpleReg_t("CPU0CLK",     0x0A20, 5,      0x07       );
-  fRegs[kCPU1CLK] =   SimpleReg_t("CPU1CLK",     0x0A22, 5,      0x07       );
-  fRegs[kCPU2CLK] =   SimpleReg_t("CPU2CLK",     0x0A24, 5,      0x07       );
-  fRegs[kCPU3CLK] =   SimpleReg_t("CPU3CLK",     0x0A26, 5,      0x07       );
-  fRegs[kNICLK]   =   SimpleReg_t("NICLK",       0x0A28, 5,      0x07       );
-  fRegs[kFILCLK]  =   SimpleReg_t("FILCLK",      0x0A2A, 5,      0x07       );
-  fRegs[kPRECLK]  =   SimpleReg_t("PRECLK",      0x0A2C, 5,      0x07       );
-  fRegs[kADCEN]   =   SimpleReg_t("ADCEN",       0x0A2E, 5,      0x07       );
-  fRegs[kNIODE]   =   SimpleReg_t("NIODE",       0x0A30, 5,      0x07       );
-  fRegs[kNIOCE]   =   SimpleReg_t("NIOCE",       0x0A32, 6,      0x21       );  // bit 5 is status bit (read-only)!
-  fRegs[kNIIDE]   =   SimpleReg_t("NIIDE",       0x0A34, 5,      0x07       );
-  fRegs[kNIICE]   =   SimpleReg_t("NIICE",       0x0A36, 5,      0x07       );
-  fRegs[kARBTIM]  =   SimpleReg_t("ARBTIM",      0x0A3F, 4,      0x0        );  // Arbiter
-  fRegs[kIA0IRQ0] =   SimpleReg_t("IA0IRQ0",     0x0B00, 12,     0x000      );  // IVT of CPU0
-  fRegs[kIA0IRQ1] =   SimpleReg_t("IA0IRQ1",     0x0B01, 12,     0x000      );
-  fRegs[kIA0IRQ2] =   SimpleReg_t("IA0IRQ2",     0x0B02, 12,     0x000      );
-  fRegs[kIA0IRQ3] =   SimpleReg_t("IA0IRQ3",     0x0B03, 12,     0x000      );
-  fRegs[kIA0IRQ4] =   SimpleReg_t("IA0IRQ4",     0x0B04, 12,     0x000      );
-  fRegs[kIA0IRQ5] =   SimpleReg_t("IA0IRQ5",     0x0B05, 12,     0x000      );
-  fRegs[kIA0IRQ6] =   SimpleReg_t("IA0IRQ6",     0x0B06, 12,     0x000      );
-  fRegs[kIA0IRQ7] =   SimpleReg_t("IA0IRQ7",     0x0B07, 12,     0x000      );
-  fRegs[kIA0IRQ8] =   SimpleReg_t("IA0IRQ8",     0x0B08, 12,     0x000      );
-  fRegs[kIA0IRQ9] =   SimpleReg_t("IA0IRQ9",     0x0B09, 12,     0x000      );
-  fRegs[kIA0IRQA] =   SimpleReg_t("IA0IRQA",     0x0B0A, 12,     0x000      );
-  fRegs[kIA0IRQB] =   SimpleReg_t("IA0IRQB",     0x0B0B, 12,     0x000      );
-  fRegs[kIA0IRQC] =   SimpleReg_t("IA0IRQC",     0x0B0C, 12,     0x000      );
-  fRegs[kIRQSW0]  =   SimpleReg_t("IRQSW0",      0x0B0D, 13,     0x1FFF     );
-  fRegs[kIRQHW0]  =   SimpleReg_t("IRQHW0",      0x0B0E, 13,     0x0000     );
-  fRegs[kIRQHL0]  =   SimpleReg_t("IRQHL0",      0x0B0F, 13,     0x0000     );
-  fRegs[kIA1IRQ0] =   SimpleReg_t("IA1IRQ0",     0x0B20, 12,     0x000      );  // IVT of CPU1
-  fRegs[kIA1IRQ1] =   SimpleReg_t("IA1IRQ1",     0x0B21, 12,     0x000      );
-  fRegs[kIA1IRQ2] =   SimpleReg_t("IA1IRQ2",     0x0B22, 12,     0x000      );
-  fRegs[kIA1IRQ3] =   SimpleReg_t("IA1IRQ3",     0x0B23, 12,     0x000      );
-  fRegs[kIA1IRQ4] =   SimpleReg_t("IA1IRQ4",     0x0B24, 12,     0x000      );
-  fRegs[kIA1IRQ5] =   SimpleReg_t("IA1IRQ5",     0x0B25, 12,     0x000      );
-  fRegs[kIA1IRQ6] =   SimpleReg_t("IA1IRQ6",     0x0B26, 12,     0x000      );
-  fRegs[kIA1IRQ7] =   SimpleReg_t("IA1IRQ7",     0x0B27, 12,     0x000      );
-  fRegs[kIA1IRQ8] =   SimpleReg_t("IA1IRQ8",     0x0B28, 12,     0x000      );
-  fRegs[kIA1IRQ9] =   SimpleReg_t("IA1IRQ9",     0x0B29, 12,     0x000      );
-  fRegs[kIA1IRQA] =   SimpleReg_t("IA1IRQA",     0x0B2A, 12,     0x000      );
-  fRegs[kIA1IRQB] =   SimpleReg_t("IA1IRQB",     0x0B2B, 12,     0x000      );
-  fRegs[kIA1IRQC] =   SimpleReg_t("IA1IRQC",     0x0B2C, 12,     0x000      );
-  fRegs[kIRQSW1]  =   SimpleReg_t("IRQSW1",      0x0B2D, 13,     0x1FFF     );
-  fRegs[kIRQHW1]  =   SimpleReg_t("IRQHW1",      0x0B2E, 13,     0x0000     );
-  fRegs[kIRQHL1]  =   SimpleReg_t("IRQHL1",      0x0B2F, 13,     0x0000     );
-  fRegs[kIA2IRQ0] =   SimpleReg_t("IA2IRQ0",     0x0B40, 12,     0x000      );  // IVT of CPU2
-  fRegs[kIA2IRQ1] =   SimpleReg_t("IA2IRQ1",     0x0B41, 12,     0x000      );
-  fRegs[kIA2IRQ2] =   SimpleReg_t("IA2IRQ2",     0x0B42, 12,     0x000      );
-  fRegs[kIA2IRQ3] =   SimpleReg_t("IA2IRQ3",     0x0B43, 12,     0x000      );
-  fRegs[kIA2IRQ4] =   SimpleReg_t("IA2IRQ4",     0x0B44, 12,     0x000      );
-  fRegs[kIA2IRQ5] =   SimpleReg_t("IA2IRQ5",     0x0B45, 12,     0x000      );
-  fRegs[kIA2IRQ6] =   SimpleReg_t("IA2IRQ6",     0x0B46, 12,     0x000      );
-  fRegs[kIA2IRQ7] =   SimpleReg_t("IA2IRQ7",     0x0B47, 12,     0x000      );
-  fRegs[kIA2IRQ8] =   SimpleReg_t("IA2IRQ8",     0x0B48, 12,     0x000      );
-  fRegs[kIA2IRQ9] =   SimpleReg_t("IA2IRQ9",     0x0B49, 12,     0x000      );
-  fRegs[kIA2IRQA] =   SimpleReg_t("IA2IRQA",     0x0B4A, 12,     0x000      );
-  fRegs[kIA2IRQB] =   SimpleReg_t("IA2IRQB",     0x0B4B, 12,     0x000      );
-  fRegs[kIA2IRQC] =   SimpleReg_t("IA2IRQC",     0x0B4C, 12,     0x000      );
-  fRegs[kIRQSW2]  =   SimpleReg_t("IRQSW2",      0x0B4D, 13,     0x1FFF     );
-  fRegs[kIRQHW2]  =   SimpleReg_t("IRQHW2",      0x0B4E, 13,     0x0000     );
-  fRegs[kIRQHL2]  =   SimpleReg_t("IRQHL2",      0x0B4F, 13,     0x0000     );
-  fRegs[kIA3IRQ0] =   SimpleReg_t("IA3IRQ0",     0x0B60, 12,     0x000      );  // IVT of CPU3
-  fRegs[kIA3IRQ1] =   SimpleReg_t("IA3IRQ1",     0x0B61, 12,     0x000      );
-  fRegs[kIA3IRQ2] =   SimpleReg_t("IA3IRQ2",     0x0B62, 12,     0x000      );
-  fRegs[kIA3IRQ3] =   SimpleReg_t("IA3IRQ3",     0x0B63, 12,     0x000      );
-  fRegs[kIA3IRQ4] =   SimpleReg_t("IA3IRQ4",     0x0B64, 12,     0x000      );
-  fRegs[kIA3IRQ5] =   SimpleReg_t("IA3IRQ5",     0x0B65, 12,     0x000      );
-  fRegs[kIA3IRQ6] =   SimpleReg_t("IA3IRQ6",     0x0B66, 12,     0x000      );
-  fRegs[kIA3IRQ7] =   SimpleReg_t("IA3IRQ7",     0x0B67, 12,     0x000      );
-  fRegs[kIA3IRQ8] =   SimpleReg_t("IA3IRQ8",     0x0B68, 12,     0x000      );
-  fRegs[kIA3IRQ9] =   SimpleReg_t("IA3IRQ9",     0x0B69, 12,     0x000      );
-  fRegs[kIA3IRQA] =   SimpleReg_t("IA3IRQA",     0x0B6A, 12,     0x000      );
-  fRegs[kIA3IRQB] =   SimpleReg_t("IA3IRQB",     0x0B6B, 12,     0x000      );
-  fRegs[kIA3IRQC] =   SimpleReg_t("IA3IRQC",     0x0B6C, 12,     0x000      );
-  fRegs[kIRQSW3]  =   SimpleReg_t("IRQSW3",      0x0B6D, 13,     0x1FFF     );
-  fRegs[kIRQHW3]  =   SimpleReg_t("IRQHW3",      0x0B6E, 13,     0x0000     );
-  fRegs[kIRQHL3]  =   SimpleReg_t("IRQHL3",      0x0B6F, 13,     0x0000     );
-  fRegs[kCTGDINI] =   SimpleReg_t("CTGDINI",     0x0B80, 32,     0x00000000 );  // Global Counter/Timer
-  fRegs[kCTGCTRL] =   SimpleReg_t("CTGCTRL",     0x0B81, 12,     0xE3F      );
-  fRegs[kC08CPU0] =   SimpleReg_t("C08CPU0",     0x0C00, 32,     0x00000000 );  // CPU constants
-  fRegs[kC09CPU0] =   SimpleReg_t("C09CPU0",     0x0C01, 32,     0x00000000 );
-  fRegs[kC10CPU0] =   SimpleReg_t("C10CPU0",     0x0C02, 32,     0x00000000 );
-  fRegs[kC11CPU0] =   SimpleReg_t("C11CPU0",     0x0C03, 32,     0x00000000 );
-  fRegs[kC12CPUA] =   SimpleReg_t("C12CPUA",     0x0C04, 32,     0x00000000 );
-  fRegs[kC13CPUA] =   SimpleReg_t("C13CPUA",     0x0C05, 32,     0x00000000 );
-  fRegs[kC14CPUA] =   SimpleReg_t("C14CPUA",     0x0C06, 32,     0x00000000 );
-  fRegs[kC15CPUA] =   SimpleReg_t("C15CPUA",     0x0C07, 32,     0x00000000 );
-  fRegs[kC08CPU1] =   SimpleReg_t("C08CPU1",     0x0C08, 32,     0x00000000 );
-  fRegs[kC09CPU1] =   SimpleReg_t("C09CPU1",     0x0C09, 32,     0x00000000 );
-  fRegs[kC10CPU1] =   SimpleReg_t("C10CPU1",     0x0C0A, 32,     0x00000000 );
-  fRegs[kC11CPU1] =   SimpleReg_t("C11CPU1",     0x0C0B, 32,     0x00000000 );
-  fRegs[kC08CPU2] =   SimpleReg_t("C08CPU2",     0x0C10, 32,     0x00000000 );
-  fRegs[kC09CPU2] =   SimpleReg_t("C09CPU2",     0x0C11, 32,     0x00000000 );
-  fRegs[kC10CPU2] =   SimpleReg_t("C10CPU2",     0x0C12, 32,     0x00000000 );
-  fRegs[kC11CPU2] =   SimpleReg_t("C11CPU2",     0x0C13, 32,     0x00000000 );
-  fRegs[kC08CPU3] =   SimpleReg_t("C08CPU3",     0x0C18, 32,     0x00000000 );
-  fRegs[kC09CPU3] =   SimpleReg_t("C09CPU3",     0x0C19, 32,     0x00000000 );
-  fRegs[kC10CPU3] =   SimpleReg_t("C10CPU3",     0x0C1A, 32,     0x00000000 );
-  fRegs[kC11CPU3] =   SimpleReg_t("C11CPU3",     0x0C1B, 32,     0x00000000 );
-  fRegs[kNMOD]    =   SimpleReg_t("NMOD",        0x0D40, 6,      0x08       );  // NI interface
-  fRegs[kNDLY]    =   SimpleReg_t("NDLY",        0x0D41, 30,     0x24924924 );
-  fRegs[kNED]     =   SimpleReg_t("NED",         0x0D42, 16,     0xA240     );
-  fRegs[kNTRO]    =   SimpleReg_t("NTRO",        0x0D43, 18,     0x3FFFC    );
-  fRegs[kNRRO]    =   SimpleReg_t("NRRO",        0x0D44, 18,     0x3FFFC    );
-  fRegs[kNES]     =   SimpleReg_t("NES",         0x0D45, 32,     0x00000000 );
-  fRegs[kNTP]     =   SimpleReg_t("NTP",         0x0D46, 32,     0x0000FFFF );
-  fRegs[kNBND]    =   SimpleReg_t("NBND",        0x0D47, 16,     0x6020     );
-  fRegs[kNP0]     =   SimpleReg_t("NP0",         0x0D48, 11,     0x44C      );
-  fRegs[kNP1]     =   SimpleReg_t("NP1",         0x0D49, 11,     0x44C      );
-  fRegs[kNP2]     =   SimpleReg_t("NP2",         0x0D4A, 11,     0x44C      );
-  fRegs[kNP3]     =   SimpleReg_t("NP3",         0x0D4B, 11,     0x44C      );
-  fRegs[kNCUT]    =   SimpleReg_t("NCUT",        0x0D4C, 32,     0xFFFFFFFF );
-  fRegs[kTPPT0]   =   SimpleReg_t("TPPT0",       0x3000, 7,      0x01       );  // Filter and Preprocessor
-  fRegs[kTPFS]    =   SimpleReg_t("TPFS",        0x3001, 7,      0x05       );
-  fRegs[kTPFE]    =   SimpleReg_t("TPFE",        0x3002, 7,      0x14       );
-  fRegs[kTPPGR]   =   SimpleReg_t("TPPGR",       0x3003, 7,      0x15       );
-  fRegs[kTPPAE]   =   SimpleReg_t("TPPAE",       0x3004, 7,      0x1E       );
-  fRegs[kTPQS0]   =   SimpleReg_t("TPQS0",       0x3005, 7,      0x00       );
-  fRegs[kTPQE0]   =   SimpleReg_t("TPQE0",       0x3006, 7,      0x0A       );
-  fRegs[kTPQS1]   =   SimpleReg_t("TPQS1",       0x3007, 7,      0x0B       );
-  fRegs[kTPQE1]   =   SimpleReg_t("TPQE1",       0x3008, 7,      0x14       );
-  fRegs[kEBD]     =   SimpleReg_t("EBD",         0x3009, 3,      0x0        );
-  fRegs[kEBAQA]   =   SimpleReg_t("EBAQA",       0x300A, 7,      0x00       );
-  fRegs[kEBSIA]   =   SimpleReg_t("EBSIA",       0x300B, 7,      0x20       );
-  fRegs[kEBSF]    =   SimpleReg_t("EBSF",        0x300C, 1,      0x1        );
-  fRegs[kEBSIM]   =   SimpleReg_t("EBSIM",       0x300D, 1,      0x1        );
-  fRegs[kEBPP]    =   SimpleReg_t("EBPP",        0x300E, 1,      0x1        );
-  fRegs[kEBPC]    =   SimpleReg_t("EBPC",        0x300F, 1,      0x1        );
-  fRegs[kEBIS]    =   SimpleReg_t("EBIS",        0x3014, 10,     0x005      );
-  fRegs[kEBIT]    =   SimpleReg_t("EBIT",        0x3015, 12,     0x028      );
-  fRegs[kEBIL]    =   SimpleReg_t("EBIL",        0x3016, 8,      0xF0       );
-  fRegs[kEBIN]    =   SimpleReg_t("EBIN",        0x3017, 1,      0x1        );
-  fRegs[kFLBY]    =   SimpleReg_t("FLBY",        0x3018, 1,      0x0        );
-  fRegs[kFPBY]    =   SimpleReg_t("FPBY",        0x3019, 1,      0x0        );
-  fRegs[kFGBY]    =   SimpleReg_t("FGBY",        0x301A, 1,      0x0        );
-  fRegs[kFTBY]    =   SimpleReg_t("FTBY",        0x301B, 1,      0x0        );
-  fRegs[kFCBY]    =   SimpleReg_t("FCBY",        0x301C, 1,      0x0        );
-  fRegs[kFPTC]    =   SimpleReg_t("FPTC",        0x3020, 2,      0x3        );
-  fRegs[kFPNP]    =   SimpleReg_t("FPNP",        0x3021, 9,      0x078      );
-  fRegs[kFPCL]    =   SimpleReg_t("FPCL",        0x3022, 1,      0x1        );
-  fRegs[kFGTA]    =   SimpleReg_t("FGTA",        0x3028, 12,     0x014      );
-  fRegs[kFGTB]    =   SimpleReg_t("FGTB",        0x3029, 12,     0x80C      );
-  fRegs[kFGCL]    =   SimpleReg_t("FGCL",        0x302A, 1,      0x1        );
-  fRegs[kFTAL]    =   SimpleReg_t("FTAL",        0x3030, 10,     0x0F6      );
-  fRegs[kFTLL]    =   SimpleReg_t("FTLL",        0x3031, 9,      0x11D      );
-  fRegs[kFTLS]    =   SimpleReg_t("FTLS",        0x3032, 9,      0x0D3      );
-  fRegs[kFCW1]    =   SimpleReg_t("FCW1",        0x3038, 8,      0x1E       );
-  fRegs[kFCW2]    =   SimpleReg_t("FCW2",        0x3039, 8,      0xD4       );
-  fRegs[kFCW3]    =   SimpleReg_t("FCW3",        0x303A, 8,      0xE6       );
-  fRegs[kFCW4]    =   SimpleReg_t("FCW4",        0x303B, 8,      0x4A       );
-  fRegs[kFCW5]    =   SimpleReg_t("FCW5",        0x303C, 8,      0xEF       );
-  fRegs[kTPFP]    =   SimpleReg_t("TPFP",        0x3040, 9,      0x037      );
-  fRegs[kTPHT]    =   SimpleReg_t("TPHT",        0x3041, 14,     0x00A0     );
-  fRegs[kTPVT]    =   SimpleReg_t("TPVT",        0x3042, 6,      0x00       );
-  fRegs[kTPVBY]   =   SimpleReg_t("TPVBY",       0x3043, 1,      0x0        );
-  fRegs[kTPCT]    =   SimpleReg_t("TPCT",        0x3044, 5,      0x08       );
-  fRegs[kTPCL]    =   SimpleReg_t("TPCL",        0x3045, 5,      0x01       );
-  fRegs[kTPCBY]   =   SimpleReg_t("TPCBY",       0x3046, 1,      0x1        );
-  fRegs[kTPD]     =   SimpleReg_t("TPD",         0x3047, 4,      0xF        );
-  fRegs[kTPCI0]   =   SimpleReg_t("TPCI0",       0x3048, 5,      0x00       );
-  fRegs[kTPCI1]   =   SimpleReg_t("TPCI1",       0x3049, 5,      0x00       );
-  fRegs[kTPCI2]   =   SimpleReg_t("TPCI2",       0x304A, 5,      0x00       );
-  fRegs[kTPCI3]   =   SimpleReg_t("TPCI3",       0x304B, 5,      0x00       );
-  fRegs[kADCMSK]  =   SimpleReg_t("ADCMSK",      0x3050, 21,     0x1FFFFF   );
-  fRegs[kADCINB]  =   SimpleReg_t("ADCINB",      0x3051, 2,      0x2        );
-  fRegs[kADCDAC]  =   SimpleReg_t("ADCDAC",      0x3052, 5,      0x10       );
-  fRegs[kADCPAR]  =   SimpleReg_t("ADCPAR",      0x3053, 18,     0x195EF    );
-  fRegs[kADCTST]  =   SimpleReg_t("ADCTST",      0x3054, 2,      0x0        );
-  fRegs[kSADCAZ]  =   SimpleReg_t("SADCAZ",      0x3055, 1,      0x1        );
-  fRegs[kFGF0]    =   SimpleReg_t("FGF0",        0x3080, 9,      0x000      );
-  fRegs[kFGF1]    =   SimpleReg_t("FGF1",        0x3081, 9,      0x000      );
-  fRegs[kFGF2]    =   SimpleReg_t("FGF2",        0x3082, 9,      0x000      );
-  fRegs[kFGF3]    =   SimpleReg_t("FGF3",        0x3083, 9,      0x000      );
-  fRegs[kFGF4]    =   SimpleReg_t("FGF4",        0x3084, 9,      0x000      );
-  fRegs[kFGF5]    =   SimpleReg_t("FGF5",        0x3085, 9,      0x000      );
-  fRegs[kFGF6]    =   SimpleReg_t("FGF6",        0x3086, 9,      0x000      );
-  fRegs[kFGF7]    =   SimpleReg_t("FGF7",        0x3087, 9,      0x000      );
-  fRegs[kFGF8]    =   SimpleReg_t("FGF8",        0x3088, 9,      0x000      );
-  fRegs[kFGF9]    =   SimpleReg_t("FGF9",        0x3089, 9,      0x000      );
-  fRegs[kFGF10]   =   SimpleReg_t("FGF10",       0x308A, 9,      0x000      );
-  fRegs[kFGF11]   =   SimpleReg_t("FGF11",       0x308B, 9,      0x000      );
-  fRegs[kFGF12]   =   SimpleReg_t("FGF12",       0x308C, 9,      0x000      );
-  fRegs[kFGF13]   =   SimpleReg_t("FGF13",       0x308D, 9,      0x000      );
-  fRegs[kFGF14]   =   SimpleReg_t("FGF14",       0x308E, 9,      0x000      );
-  fRegs[kFGF15]   =   SimpleReg_t("FGF15",       0x308F, 9,      0x000      );
-  fRegs[kFGF16]   =   SimpleReg_t("FGF16",       0x3090, 9,      0x000      );
-  fRegs[kFGF17]   =   SimpleReg_t("FGF17",       0x3091, 9,      0x000      );
-  fRegs[kFGF18]   =   SimpleReg_t("FGF18",       0x3092, 9,      0x000      );
-  fRegs[kFGF19]   =   SimpleReg_t("FGF19",       0x3093, 9,      0x000      );
-  fRegs[kFGF20]   =   SimpleReg_t("FGF20",       0x3094, 9,      0x000      );
-  fRegs[kFGA0]    =   SimpleReg_t("FGA0",        0x30A0, 6,      0x00       );
-  fRegs[kFGA1]    =   SimpleReg_t("FGA1",        0x30A1, 6,      0x00       );
-  fRegs[kFGA2]    =   SimpleReg_t("FGA2",        0x30A2, 6,      0x00       );
-  fRegs[kFGA3]    =   SimpleReg_t("FGA3",        0x30A3, 6,      0x00       );
-  fRegs[kFGA4]    =   SimpleReg_t("FGA4",        0x30A4, 6,      0x00       );
-  fRegs[kFGA5]    =   SimpleReg_t("FGA5",        0x30A5, 6,      0x00       );
-  fRegs[kFGA6]    =   SimpleReg_t("FGA6",        0x30A6, 6,      0x00       );
-  fRegs[kFGA7]    =   SimpleReg_t("FGA7",        0x30A7, 6,      0x00       );
-  fRegs[kFGA8]    =   SimpleReg_t("FGA8",        0x30A8, 6,      0x00       );
-  fRegs[kFGA9]    =   SimpleReg_t("FGA9",        0x30A9, 6,      0x00       );
-  fRegs[kFGA10]   =   SimpleReg_t("FGA10",       0x30AA, 6,      0x00       );
-  fRegs[kFGA11]   =   SimpleReg_t("FGA11",       0x30AB, 6,      0x00       );
-  fRegs[kFGA12]   =   SimpleReg_t("FGA12",       0x30AC, 6,      0x00       );
-  fRegs[kFGA13]   =   SimpleReg_t("FGA13",       0x30AD, 6,      0x00       );
-  fRegs[kFGA14]   =   SimpleReg_t("FGA14",       0x30AE, 6,      0x00       );
-  fRegs[kFGA15]   =   SimpleReg_t("FGA15",       0x30AF, 6,      0x00       );
-  fRegs[kFGA16]   =   SimpleReg_t("FGA16",       0x30B0, 6,      0x00       );
-  fRegs[kFGA17]   =   SimpleReg_t("FGA17",       0x30B1, 6,      0x00       );
-  fRegs[kFGA18]   =   SimpleReg_t("FGA18",       0x30B2, 6,      0x00       );
-  fRegs[kFGA19]   =   SimpleReg_t("FGA19",       0x30B3, 6,      0x00       );
-  fRegs[kFGA20]   =   SimpleReg_t("FGA20",       0x30B4, 6,      0x00       );
-  fRegs[kFLL00]   =   SimpleReg_t("FLL00",       0x3100, 6,      0x00       );  // non-linearity table, 64 x 6 bits
-  fRegs[kFLL01]   =   SimpleReg_t("FLL01",       0x3101, 6,      0x00       );
-  fRegs[kFLL02]   =   SimpleReg_t("FLL02",       0x3102, 6,      0x00       );
-  fRegs[kFLL03]   =   SimpleReg_t("FLL03",       0x3103, 6,      0x00       );
-  fRegs[kFLL04]   =   SimpleReg_t("FLL04",       0x3104, 6,      0x00       );
-  fRegs[kFLL05]   =   SimpleReg_t("FLL05",       0x3105, 6,      0x00       );
-  fRegs[kFLL06]   =   SimpleReg_t("FLL06",       0x3106, 6,      0x00       );
-  fRegs[kFLL07]   =   SimpleReg_t("FLL07",       0x3107, 6,      0x00       );
-  fRegs[kFLL08]   =   SimpleReg_t("FLL08",       0x3108, 6,      0x00       );
-  fRegs[kFLL09]   =   SimpleReg_t("FLL09",       0x3109, 6,      0x00       );
-  fRegs[kFLL0A]   =   SimpleReg_t("FLL0A",       0x310A, 6,      0x00       );
-  fRegs[kFLL0B]   =   SimpleReg_t("FLL0B",       0x310B, 6,      0x00       );
-  fRegs[kFLL0C]   =   SimpleReg_t("FLL0C",       0x310C, 6,      0x00       );
-  fRegs[kFLL0D]   =   SimpleReg_t("FLL0D",       0x310D, 6,      0x00       );
-  fRegs[kFLL0E]   =   SimpleReg_t("FLL0E",       0x310E, 6,      0x00       );
-  fRegs[kFLL0F]   =   SimpleReg_t("FLL0F",       0x310F, 6,      0x00       );
-  fRegs[kFLL10]   =   SimpleReg_t("FLL10",       0x3110, 6,      0x00       );
-  fRegs[kFLL11]   =   SimpleReg_t("FLL11",       0x3111, 6,      0x00       );
-  fRegs[kFLL12]   =   SimpleReg_t("FLL12",       0x3112, 6,      0x00       );
-  fRegs[kFLL13]   =   SimpleReg_t("FLL13",       0x3113, 6,      0x00       );
-  fRegs[kFLL14]   =   SimpleReg_t("FLL14",       0x3114, 6,      0x00       );
-  fRegs[kFLL15]   =   SimpleReg_t("FLL15",       0x3115, 6,      0x00       );
-  fRegs[kFLL16]   =   SimpleReg_t("FLL16",       0x3116, 6,      0x00       );
-  fRegs[kFLL17]   =   SimpleReg_t("FLL17",       0x3117, 6,      0x00       );
-  fRegs[kFLL18]   =   SimpleReg_t("FLL18",       0x3118, 6,      0x00       );
-  fRegs[kFLL19]   =   SimpleReg_t("FLL19",       0x3119, 6,      0x00       );
-  fRegs[kFLL1A]   =   SimpleReg_t("FLL1A",       0x311A, 6,      0x00       );
-  fRegs[kFLL1B]   =   SimpleReg_t("FLL1B",       0x311B, 6,      0x00       );
-  fRegs[kFLL1C]   =   SimpleReg_t("FLL1C",       0x311C, 6,      0x00       );
-  fRegs[kFLL1D]   =   SimpleReg_t("FLL1D",       0x311D, 6,      0x00       );
-  fRegs[kFLL1E]   =   SimpleReg_t("FLL1E",       0x311E, 6,      0x00       );
-  fRegs[kFLL1F]   =   SimpleReg_t("FLL1F",       0x311F, 6,      0x00       );
-  fRegs[kFLL20]   =   SimpleReg_t("FLL20",       0x3120, 6,      0x00       );
-  fRegs[kFLL21]   =   SimpleReg_t("FLL21",       0x3121, 6,      0x00       );
-  fRegs[kFLL22]   =   SimpleReg_t("FLL22",       0x3122, 6,      0x00       );
-  fRegs[kFLL23]   =   SimpleReg_t("FLL23",       0x3123, 6,      0x00       );
-  fRegs[kFLL24]   =   SimpleReg_t("FLL24",       0x3124, 6,      0x00       );
-  fRegs[kFLL25]   =   SimpleReg_t("FLL25",       0x3125, 6,      0x00       );
-  fRegs[kFLL26]   =   SimpleReg_t("FLL26",       0x3126, 6,      0x00       );
-  fRegs[kFLL27]   =   SimpleReg_t("FLL27",       0x3127, 6,      0x00       );
-  fRegs[kFLL28]   =   SimpleReg_t("FLL28",       0x3128, 6,      0x00       );
-  fRegs[kFLL29]   =   SimpleReg_t("FLL29",       0x3129, 6,      0x00       );
-  fRegs[kFLL2A]   =   SimpleReg_t("FLL2A",       0x312A, 6,      0x00       );
-  fRegs[kFLL2B]   =   SimpleReg_t("FLL2B",       0x312B, 6,      0x00       );
-  fRegs[kFLL2C]   =   SimpleReg_t("FLL2C",       0x312C, 6,      0x00       );
-  fRegs[kFLL2D]   =   SimpleReg_t("FLL2D",       0x312D, 6,      0x00       );
-  fRegs[kFLL2E]   =   SimpleReg_t("FLL2E",       0x312E, 6,      0x00       );
-  fRegs[kFLL2F]   =   SimpleReg_t("FLL2F",       0x312F, 6,      0x00       );
-  fRegs[kFLL30]   =   SimpleReg_t("FLL30",       0x3130, 6,      0x00       );
-  fRegs[kFLL31]   =   SimpleReg_t("FLL31",       0x3131, 6,      0x00       );
-  fRegs[kFLL32]   =   SimpleReg_t("FLL32",       0x3132, 6,      0x00       );
-  fRegs[kFLL33]   =   SimpleReg_t("FLL33",       0x3133, 6,      0x00       );
-  fRegs[kFLL34]   =   SimpleReg_t("FLL34",       0x3134, 6,      0x00       );
-  fRegs[kFLL35]   =   SimpleReg_t("FLL35",       0x3135, 6,      0x00       );
-  fRegs[kFLL36]   =   SimpleReg_t("FLL36",       0x3136, 6,      0x00       );
-  fRegs[kFLL37]   =   SimpleReg_t("FLL37",       0x3137, 6,      0x00       );
-  fRegs[kFLL38]   =   SimpleReg_t("FLL38",       0x3138, 6,      0x00       );
-  fRegs[kFLL39]   =   SimpleReg_t("FLL39",       0x3139, 6,      0x00       );
-  fRegs[kFLL3A]   =   SimpleReg_t("FLL3A",       0x313A, 6,      0x00       );
-  fRegs[kFLL3B]   =   SimpleReg_t("FLL3B",       0x313B, 6,      0x00       );
-  fRegs[kFLL3C]   =   SimpleReg_t("FLL3C",       0x313C, 6,      0x00       );
-  fRegs[kFLL3D]   =   SimpleReg_t("FLL3D",       0x313D, 6,      0x00       );
-  fRegs[kFLL3E]   =   SimpleReg_t("FLL3E",       0x313E, 6,      0x00       );
-  fRegs[kFLL3F]   =   SimpleReg_t("FLL3F",       0x313F, 6,      0x00       );
-  fRegs[kPASADEL] =   SimpleReg_t("PASADEL",     0x3158, 8,      0xFF       );  // end of non-lin table
-  fRegs[kPASAPHA] =   SimpleReg_t("PASAPHA",     0x3159, 6,      0x3F       );
-  fRegs[kPASAPRA] =   SimpleReg_t("PASAPRA",     0x315A, 6,      0x0F       );
-  fRegs[kPASADAC] =   SimpleReg_t("PASADAC",     0x315B, 8,      0x80       );
-  fRegs[kPASACHM] =   SimpleReg_t("PASACHM",     0x315C, 19,     0x7FFFF    );
-  fRegs[kPASASTL] =   SimpleReg_t("PASASTL",     0x315D, 8,      0xFF       );
-  fRegs[kPASAPR1] =   SimpleReg_t("PASAPR1",     0x315E, 1,      0x0        );
-  fRegs[kPASAPR0] =   SimpleReg_t("PASAPR0",     0x315F, 1,      0x0        );
-  fRegs[kSADCTRG] =   SimpleReg_t("SADCTRG",     0x3161, 1,      0x0        );
-  fRegs[kSADCRUN] =   SimpleReg_t("SADCRUN",     0x3162, 1,      0x0        );
-  fRegs[kSADCPWR] =   SimpleReg_t("SADCPWR",     0x3163, 3,      0x7        );
-  fRegs[kL0TSIM]  =   SimpleReg_t("L0TSIM",      0x3165, 14,     0x0050     );
-  fRegs[kSADCEC]  =   SimpleReg_t("SADCEC",      0x3166, 7,      0x00       );
-  fRegs[kSADCMC]  =   SimpleReg_t("SADCMC",      0x3170, 8,      0xC0       );
-  fRegs[kSADCOC]  =   SimpleReg_t("SADCOC",      0x3171, 8,      0x19       );
-  fRegs[kSADCGTB] =   SimpleReg_t("SADCGTB",     0x3172, 32,     0x37737700 );
-  fRegs[kSEBDEN]  =   SimpleReg_t("SEBDEN",      0x3178, 3,      0x0        );
-  fRegs[kSEBDOU]  =   SimpleReg_t("SEBDOU",      0x3179, 3,      0x0        );
-  fRegs[kTPL00]   =   SimpleReg_t("TPL00",       0x3180, 5,      0x00       );  // pos table, 128 x 5 bits
-  fRegs[kTPL01]   =   SimpleReg_t("TPL01",       0x3181, 5,      0x00       );
-  fRegs[kTPL02]   =   SimpleReg_t("TPL02",       0x3182, 5,      0x00       );
-  fRegs[kTPL03]   =   SimpleReg_t("TPL03",       0x3183, 5,      0x00       );
-  fRegs[kTPL04]   =   SimpleReg_t("TPL04",       0x3184, 5,      0x00       );
-  fRegs[kTPL05]   =   SimpleReg_t("TPL05",       0x3185, 5,      0x00       );
-  fRegs[kTPL06]   =   SimpleReg_t("TPL06",       0x3186, 5,      0x00       );
-  fRegs[kTPL07]   =   SimpleReg_t("TPL07",       0x3187, 5,      0x00       );
-  fRegs[kTPL08]   =   SimpleReg_t("TPL08",       0x3188, 5,      0x00       );
-  fRegs[kTPL09]   =   SimpleReg_t("TPL09",       0x3189, 5,      0x00       );
-  fRegs[kTPL0A]   =   SimpleReg_t("TPL0A",       0x318A, 5,      0x00       );
-  fRegs[kTPL0B]   =   SimpleReg_t("TPL0B",       0x318B, 5,      0x00       );
-  fRegs[kTPL0C]   =   SimpleReg_t("TPL0C",       0x318C, 5,      0x00       );
-  fRegs[kTPL0D]   =   SimpleReg_t("TPL0D",       0x318D, 5,      0x00       );
-  fRegs[kTPL0E]   =   SimpleReg_t("TPL0E",       0x318E, 5,      0x00       );
-  fRegs[kTPL0F]   =   SimpleReg_t("TPL0F",       0x318F, 5,      0x00       );
-  fRegs[kTPL10]   =   SimpleReg_t("TPL10",       0x3190, 5,      0x00       );
-  fRegs[kTPL11]   =   SimpleReg_t("TPL11",       0x3191, 5,      0x00       );
-  fRegs[kTPL12]   =   SimpleReg_t("TPL12",       0x3192, 5,      0x00       );
-  fRegs[kTPL13]   =   SimpleReg_t("TPL13",       0x3193, 5,      0x00       );
-  fRegs[kTPL14]   =   SimpleReg_t("TPL14",       0x3194, 5,      0x00       );
-  fRegs[kTPL15]   =   SimpleReg_t("TPL15",       0x3195, 5,      0x00       );
-  fRegs[kTPL16]   =   SimpleReg_t("TPL16",       0x3196, 5,      0x00       );
-  fRegs[kTPL17]   =   SimpleReg_t("TPL17",       0x3197, 5,      0x00       );
-  fRegs[kTPL18]   =   SimpleReg_t("TPL18",       0x3198, 5,      0x00       );
-  fRegs[kTPL19]   =   SimpleReg_t("TPL19",       0x3199, 5,      0x00       );
-  fRegs[kTPL1A]   =   SimpleReg_t("TPL1A",       0x319A, 5,      0x00       );
-  fRegs[kTPL1B]   =   SimpleReg_t("TPL1B",       0x319B, 5,      0x00       );
-  fRegs[kTPL1C]   =   SimpleReg_t("TPL1C",       0x319C, 5,      0x00       );
-  fRegs[kTPL1D]   =   SimpleReg_t("TPL1D",       0x319D, 5,      0x00       );
-  fRegs[kTPL1E]   =   SimpleReg_t("TPL1E",       0x319E, 5,      0x00       );
-  fRegs[kTPL1F]   =   SimpleReg_t("TPL1F",       0x319F, 5,      0x00       );
-  fRegs[kTPL20]   =   SimpleReg_t("TPL20",       0x31A0, 5,      0x00       );
-  fRegs[kTPL21]   =   SimpleReg_t("TPL21",       0x31A1, 5,      0x00       );
-  fRegs[kTPL22]   =   SimpleReg_t("TPL22",       0x31A2, 5,      0x00       );
-  fRegs[kTPL23]   =   SimpleReg_t("TPL23",       0x31A3, 5,      0x00       );
-  fRegs[kTPL24]   =   SimpleReg_t("TPL24",       0x31A4, 5,      0x00       );
-  fRegs[kTPL25]   =   SimpleReg_t("TPL25",       0x31A5, 5,      0x00       );
-  fRegs[kTPL26]   =   SimpleReg_t("TPL26",       0x31A6, 5,      0x00       );
-  fRegs[kTPL27]   =   SimpleReg_t("TPL27",       0x31A7, 5,      0x00       );
-  fRegs[kTPL28]   =   SimpleReg_t("TPL28",       0x31A8, 5,      0x00       );
-  fRegs[kTPL29]   =   SimpleReg_t("TPL29",       0x31A9, 5,      0x00       );
-  fRegs[kTPL2A]   =   SimpleReg_t("TPL2A",       0x31AA, 5,      0x00       );
-  fRegs[kTPL2B]   =   SimpleReg_t("TPL2B",       0x31AB, 5,      0x00       );
-  fRegs[kTPL2C]   =   SimpleReg_t("TPL2C",       0x31AC, 5,      0x00       );
-  fRegs[kTPL2D]   =   SimpleReg_t("TPL2D",       0x31AD, 5,      0x00       );
-  fRegs[kTPL2E]   =   SimpleReg_t("TPL2E",       0x31AE, 5,      0x00       );
-  fRegs[kTPL2F]   =   SimpleReg_t("TPL2F",       0x31AF, 5,      0x00       );
-  fRegs[kTPL30]   =   SimpleReg_t("TPL30",       0x31B0, 5,      0x00       );
-  fRegs[kTPL31]   =   SimpleReg_t("TPL31",       0x31B1, 5,      0x00       );
-  fRegs[kTPL32]   =   SimpleReg_t("TPL32",       0x31B2, 5,      0x00       );
-  fRegs[kTPL33]   =   SimpleReg_t("TPL33",       0x31B3, 5,      0x00       );
-  fRegs[kTPL34]   =   SimpleReg_t("TPL34",       0x31B4, 5,      0x00       );
-  fRegs[kTPL35]   =   SimpleReg_t("TPL35",       0x31B5, 5,      0x00       );
-  fRegs[kTPL36]   =   SimpleReg_t("TPL36",       0x31B6, 5,      0x00       );
-  fRegs[kTPL37]   =   SimpleReg_t("TPL37",       0x31B7, 5,      0x00       );
-  fRegs[kTPL38]   =   SimpleReg_t("TPL38",       0x31B8, 5,      0x00       );
-  fRegs[kTPL39]   =   SimpleReg_t("TPL39",       0x31B9, 5,      0x00       );
-  fRegs[kTPL3A]   =   SimpleReg_t("TPL3A",       0x31BA, 5,      0x00       );
-  fRegs[kTPL3B]   =   SimpleReg_t("TPL3B",       0x31BB, 5,      0x00       );
-  fRegs[kTPL3C]   =   SimpleReg_t("TPL3C",       0x31BC, 5,      0x00       );
-  fRegs[kTPL3D]   =   SimpleReg_t("TPL3D",       0x31BD, 5,      0x00       );
-  fRegs[kTPL3E]   =   SimpleReg_t("TPL3E",       0x31BE, 5,      0x00       );
-  fRegs[kTPL3F]   =   SimpleReg_t("TPL3F",       0x31BF, 5,      0x00       );
-  fRegs[kTPL40]   =   SimpleReg_t("TPL40",       0x31C0, 5,      0x00       );
-  fRegs[kTPL41]   =   SimpleReg_t("TPL41",       0x31C1, 5,      0x00       );
-  fRegs[kTPL42]   =   SimpleReg_t("TPL42",       0x31C2, 5,      0x00       );
-  fRegs[kTPL43]   =   SimpleReg_t("TPL43",       0x31C3, 5,      0x00       );
-  fRegs[kTPL44]   =   SimpleReg_t("TPL44",       0x31C4, 5,      0x00       );
-  fRegs[kTPL45]   =   SimpleReg_t("TPL45",       0x31C5, 5,      0x00       );
-  fRegs[kTPL46]   =   SimpleReg_t("TPL46",       0x31C6, 5,      0x00       );
-  fRegs[kTPL47]   =   SimpleReg_t("TPL47",       0x31C7, 5,      0x00       );
-  fRegs[kTPL48]   =   SimpleReg_t("TPL48",       0x31C8, 5,      0x00       );
-  fRegs[kTPL49]   =   SimpleReg_t("TPL49",       0x31C9, 5,      0x00       );
-  fRegs[kTPL4A]   =   SimpleReg_t("TPL4A",       0x31CA, 5,      0x00       );
-  fRegs[kTPL4B]   =   SimpleReg_t("TPL4B",       0x31CB, 5,      0x00       );
-  fRegs[kTPL4C]   =   SimpleReg_t("TPL4C",       0x31CC, 5,      0x00       );
-  fRegs[kTPL4D]   =   SimpleReg_t("TPL4D",       0x31CD, 5,      0x00       );
-  fRegs[kTPL4E]   =   SimpleReg_t("TPL4E",       0x31CE, 5,      0x00       );
-  fRegs[kTPL4F]   =   SimpleReg_t("TPL4F",       0x31CF, 5,      0x00       );
-  fRegs[kTPL50]   =   SimpleReg_t("TPL50",       0x31D0, 5,      0x00       );
-  fRegs[kTPL51]   =   SimpleReg_t("TPL51",       0x31D1, 5,      0x00       );
-  fRegs[kTPL52]   =   SimpleReg_t("TPL52",       0x31D2, 5,      0x00       );
-  fRegs[kTPL53]   =   SimpleReg_t("TPL53",       0x31D3, 5,      0x00       );
-  fRegs[kTPL54]   =   SimpleReg_t("TPL54",       0x31D4, 5,      0x00       );
-  fRegs[kTPL55]   =   SimpleReg_t("TPL55",       0x31D5, 5,      0x00       );
-  fRegs[kTPL56]   =   SimpleReg_t("TPL56",       0x31D6, 5,      0x00       );
-  fRegs[kTPL57]   =   SimpleReg_t("TPL57",       0x31D7, 5,      0x00       );
-  fRegs[kTPL58]   =   SimpleReg_t("TPL58",       0x31D8, 5,      0x00       );
-  fRegs[kTPL59]   =   SimpleReg_t("TPL59",       0x31D9, 5,      0x00       );
-  fRegs[kTPL5A]   =   SimpleReg_t("TPL5A",       0x31DA, 5,      0x00       );
-  fRegs[kTPL5B]   =   SimpleReg_t("TPL5B",       0x31DB, 5,      0x00       );
-  fRegs[kTPL5C]   =   SimpleReg_t("TPL5C",       0x31DC, 5,      0x00       );
-  fRegs[kTPL5D]   =   SimpleReg_t("TPL5D",       0x31DD, 5,      0x00       );
-  fRegs[kTPL5E]   =   SimpleReg_t("TPL5E",       0x31DE, 5,      0x00       );
-  fRegs[kTPL5F]   =   SimpleReg_t("TPL5F",       0x31DF, 5,      0x00       );
-  fRegs[kTPL60]   =   SimpleReg_t("TPL60",       0x31E0, 5,      0x00       );
-  fRegs[kTPL61]   =   SimpleReg_t("TPL61",       0x31E1, 5,      0x00       );
-  fRegs[kTPL62]   =   SimpleReg_t("TPL62",       0x31E2, 5,      0x00       );
-  fRegs[kTPL63]   =   SimpleReg_t("TPL63",       0x31E3, 5,      0x00       );
-  fRegs[kTPL64]   =   SimpleReg_t("TPL64",       0x31E4, 5,      0x00       );
-  fRegs[kTPL65]   =   SimpleReg_t("TPL65",       0x31E5, 5,      0x00       );
-  fRegs[kTPL66]   =   SimpleReg_t("TPL66",       0x31E6, 5,      0x00       );
-  fRegs[kTPL67]   =   SimpleReg_t("TPL67",       0x31E7, 5,      0x00       );
-  fRegs[kTPL68]   =   SimpleReg_t("TPL68",       0x31E8, 5,      0x00       );
-  fRegs[kTPL69]   =   SimpleReg_t("TPL69",       0x31E9, 5,      0x00       );
-  fRegs[kTPL6A]   =   SimpleReg_t("TPL6A",       0x31EA, 5,      0x00       );
-  fRegs[kTPL6B]   =   SimpleReg_t("TPL6B",       0x31EB, 5,      0x00       );
-  fRegs[kTPL6C]   =   SimpleReg_t("TPL6C",       0x31EC, 5,      0x00       );
-  fRegs[kTPL6D]   =   SimpleReg_t("TPL6D",       0x31ED, 5,      0x00       );
-  fRegs[kTPL6E]   =   SimpleReg_t("TPL6E",       0x31EE, 5,      0x00       );
-  fRegs[kTPL6F]   =   SimpleReg_t("TPL6F",       0x31EF, 5,      0x00       );
-  fRegs[kTPL70]   =   SimpleReg_t("TPL70",       0x31F0, 5,      0x00       );
-  fRegs[kTPL71]   =   SimpleReg_t("TPL71",       0x31F1, 5,      0x00       );
-  fRegs[kTPL72]   =   SimpleReg_t("TPL72",       0x31F2, 5,      0x00       );
-  fRegs[kTPL73]   =   SimpleReg_t("TPL73",       0x31F3, 5,      0x00       );
-  fRegs[kTPL74]   =   SimpleReg_t("TPL74",       0x31F4, 5,      0x00       );
-  fRegs[kTPL75]   =   SimpleReg_t("TPL75",       0x31F5, 5,      0x00       );
-  fRegs[kTPL76]   =   SimpleReg_t("TPL76",       0x31F6, 5,      0x00       );
-  fRegs[kTPL77]   =   SimpleReg_t("TPL77",       0x31F7, 5,      0x00       );
-  fRegs[kTPL78]   =   SimpleReg_t("TPL78",       0x31F8, 5,      0x00       );
-  fRegs[kTPL79]   =   SimpleReg_t("TPL79",       0x31F9, 5,      0x00       );
-  fRegs[kTPL7A]   =   SimpleReg_t("TPL7A",       0x31FA, 5,      0x00       );
-  fRegs[kTPL7B]   =   SimpleReg_t("TPL7B",       0x31FB, 5,      0x00       );
-  fRegs[kTPL7C]   =   SimpleReg_t("TPL7C",       0x31FC, 5,      0x00       );
-  fRegs[kTPL7D]   =   SimpleReg_t("TPL7D",       0x31FD, 5,      0x00       );
-  fRegs[kTPL7E]   =   SimpleReg_t("TPL7E",       0x31FE, 5,      0x00       );
-  fRegs[kTPL7F]   =   SimpleReg_t("TPL7F",       0x31FF, 5,      0x00       );
-  fRegs[kMEMRW]   =   SimpleReg_t("MEMRW",       0xD000, 7,      0x79       );  // end of pos table
-  fRegs[kMEMCOR]  =   SimpleReg_t("MEMCOR",      0xD001, 9,      0x000      );
-  fRegs[kDMDELA]  =   SimpleReg_t("DMDELA",      0xD002, 4,      0x8        );
-  fRegs[kDMDELS]  =   SimpleReg_t("DMDELS",      0xD003, 4,      0x8        );
-
-
-
-  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;
-     }
-
-  }
+  // default constructor
 
+  // initialize and reset the TRAP registers
   InitRegs();
-  ResetDmem();
-}
-
+  ResetRegs();
 
-AliTRDtrapConfig* AliTRDtrapConfig::Instance()
-{
-  // return a pointer to an instance of this class
-
-  if (!fgInstance) {
-    fgInstance = new AliTRDtrapConfig();
-    AliTRDtrapConfigHandler cfgHandler;
-    cfgHandler.LoadConfig();
+  for (Int_t iWord = 0; iWord < fgkDmemWords; ++iWord) {
+    fDmem[iWord].SetAddress(iWord + fgkDmemStartAddress);
   }
 
-  return fgInstance;
+  // initialize the map from address to register
+  if (!fgRegAddressMapInitialized) {
+    for (Int_t iReg = 0; iReg < kLastReg; iReg++) {
+      Int_t addr = fRegisterValue[iReg].GetAddr();
+      if (addr < fgkRegisterAddressBlockStart[0]) {
+       AliError(Form("Register address 0x%04x not handled in register map", addr));
+      }
+      else if (addr < fgkRegisterAddressBlockStart[0] + fgkRegisterAddressBlockSize[0]) {
+       fgRegAddressMap[addr - fgkRegisterAddressBlockStart[0]] = (TrapReg_t) iReg;
+      }
+      else if (addr < fgkRegisterAddressBlockStart[1]) {
+       AliError(Form("Register address 0x%04x not handled in register map", addr));
+      }
+      else if (addr < fgkRegisterAddressBlockStart[1] + fgkRegisterAddressBlockSize[1]) {
+       fgRegAddressMap[addr - fgkRegisterAddressBlockStart[1] + fgkRegisterAddressBlockSize[0]] = (TrapReg_t) iReg;
+      }
+      else if (addr < fgkRegisterAddressBlockStart[2]) {
+       AliError(Form("Register address 0x%04x not handled in register map", addr));
+      }
+      else if (addr < fgkRegisterAddressBlockStart[2] + fgkRegisterAddressBlockSize[2]) {
+       fgRegAddressMap[addr - fgkRegisterAddressBlockStart[2] + fgkRegisterAddressBlockSize[1] + fgkRegisterAddressBlockSize[0]] = (TrapReg_t) iReg;
+      }
+      else {
+       AliError(Form("Register address 0x%04x not handled in register map", addr));
+      }
+    }
+    fgRegAddressMapInitialized = kTRUE;
+  }
 }
 
 
 AliTRDtrapConfig::~AliTRDtrapConfig()
 {
   // destructor
-
-  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)
+  // initialize all TRAP registers
 
-   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;
-   }
+  //                              Name          Address  Nbits   Reset Value
+  fRegisterValue[kSML0]    .Init("SML0",        0x0A00, 15,     0x4050     );  // Global state machine
+  fRegisterValue[kSML1]    .Init("SML1",        0x0A01, 15,     0x4200     );
+  fRegisterValue[kSML2]    .Init("SML2",        0x0A02, 15,     0x4384     );
+  fRegisterValue[kSMMODE]  .Init("SMMODE",      0x0A03, 16,     0xF0E2     );
+  fRegisterValue[kSMCMD]   .Init("SMCMD",       0x0A04, 16,     0x0000     );
+  fRegisterValue[kNITM0]   .Init("NITM0",       0x0A08, 14,     0x3FFF     );
+  fRegisterValue[kNITM1]   .Init("NITM1",       0x0A09, 14,     0x3FFF     );
+  fRegisterValue[kNITM2]   .Init("NITM2",       0x0A0A, 14,     0x3FFF     );
+  fRegisterValue[kNIP4D]   .Init("NIP4D",       0x0A0B, 7,      0x7F       );
+  fRegisterValue[kCPU0CLK] .Init("CPU0CLK",     0x0A20, 5,      0x07       );
+  fRegisterValue[kCPU1CLK] .Init("CPU1CLK",     0x0A22, 5,      0x07       );
+  fRegisterValue[kCPU2CLK] .Init("CPU2CLK",     0x0A24, 5,      0x07       );
+  fRegisterValue[kCPU3CLK] .Init("CPU3CLK",     0x0A26, 5,      0x07       );
+  fRegisterValue[kNICLK]   .Init("NICLK",       0x0A28, 5,      0x07       );
+  fRegisterValue[kFILCLK]  .Init("FILCLK",      0x0A2A, 5,      0x07       );
+  fRegisterValue[kPRECLK]  .Init("PRECLK",      0x0A2C, 5,      0x07       );
+  fRegisterValue[kADCEN]   .Init("ADCEN",       0x0A2E, 5,      0x07       );
+  fRegisterValue[kNIODE]   .Init("NIODE",       0x0A30, 5,      0x07       );
+  fRegisterValue[kNIOCE]   .Init("NIOCE",       0x0A32, 6,      0x21       );  // bit 5 is status bit (read-only)!
+  fRegisterValue[kNIIDE]   .Init("NIIDE",       0x0A34, 5,      0x07       );
+  fRegisterValue[kNIICE]   .Init("NIICE",       0x0A36, 5,      0x07       );
+  fRegisterValue[kARBTIM]  .Init("ARBTIM",      0x0A3F, 4,      0x0        );  // Arbiter
+  fRegisterValue[kIA0IRQ0] .Init("IA0IRQ0",     0x0B00, 12,     0x000      );  // IVT of CPU0
+  fRegisterValue[kIA0IRQ1] .Init("IA0IRQ1",     0x0B01, 12,     0x000      );
+  fRegisterValue[kIA0IRQ2] .Init("IA0IRQ2",     0x0B02, 12,     0x000      );
+  fRegisterValue[kIA0IRQ3] .Init("IA0IRQ3",     0x0B03, 12,     0x000      );
+  fRegisterValue[kIA0IRQ4] .Init("IA0IRQ4",     0x0B04, 12,     0x000      );
+  fRegisterValue[kIA0IRQ5] .Init("IA0IRQ5",     0x0B05, 12,     0x000      );
+  fRegisterValue[kIA0IRQ6] .Init("IA0IRQ6",     0x0B06, 12,     0x000      );
+  fRegisterValue[kIA0IRQ7] .Init("IA0IRQ7",     0x0B07, 12,     0x000      );
+  fRegisterValue[kIA0IRQ8] .Init("IA0IRQ8",     0x0B08, 12,     0x000      );
+  fRegisterValue[kIA0IRQ9] .Init("IA0IRQ9",     0x0B09, 12,     0x000      );
+  fRegisterValue[kIA0IRQA] .Init("IA0IRQA",     0x0B0A, 12,     0x000      );
+  fRegisterValue[kIA0IRQB] .Init("IA0IRQB",     0x0B0B, 12,     0x000      );
+  fRegisterValue[kIA0IRQC] .Init("IA0IRQC",     0x0B0C, 12,     0x000      );
+  fRegisterValue[kIRQSW0]  .Init("IRQSW0",      0x0B0D, 13,     0x1FFF     );
+  fRegisterValue[kIRQHW0]  .Init("IRQHW0",      0x0B0E, 13,     0x0000     );
+  fRegisterValue[kIRQHL0]  .Init("IRQHL0",      0x0B0F, 13,     0x0000     );
+  fRegisterValue[kIA1IRQ0] .Init("IA1IRQ0",     0x0B20, 12,     0x000      );  // IVT of CPU1
+  fRegisterValue[kIA1IRQ1] .Init("IA1IRQ1",     0x0B21, 12,     0x000      );
+  fRegisterValue[kIA1IRQ2] .Init("IA1IRQ2",     0x0B22, 12,     0x000      );
+  fRegisterValue[kIA1IRQ3] .Init("IA1IRQ3",     0x0B23, 12,     0x000      );
+  fRegisterValue[kIA1IRQ4] .Init("IA1IRQ4",     0x0B24, 12,     0x000      );
+  fRegisterValue[kIA1IRQ5] .Init("IA1IRQ5",     0x0B25, 12,     0x000      );
+  fRegisterValue[kIA1IRQ6] .Init("IA1IRQ6",     0x0B26, 12,     0x000      );
+  fRegisterValue[kIA1IRQ7] .Init("IA1IRQ7",     0x0B27, 12,     0x000      );
+  fRegisterValue[kIA1IRQ8] .Init("IA1IRQ8",     0x0B28, 12,     0x000      );
+  fRegisterValue[kIA1IRQ9] .Init("IA1IRQ9",     0x0B29, 12,     0x000      );
+  fRegisterValue[kIA1IRQA] .Init("IA1IRQA",     0x0B2A, 12,     0x000      );
+  fRegisterValue[kIA1IRQB] .Init("IA1IRQB",     0x0B2B, 12,     0x000      );
+  fRegisterValue[kIA1IRQC] .Init("IA1IRQC",     0x0B2C, 12,     0x000      );
+  fRegisterValue[kIRQSW1]  .Init("IRQSW1",      0x0B2D, 13,     0x1FFF     );
+  fRegisterValue[kIRQHW1]  .Init("IRQHW1",      0x0B2E, 13,     0x0000     );
+  fRegisterValue[kIRQHL1]  .Init("IRQHL1",      0x0B2F, 13,     0x0000     );
+  fRegisterValue[kIA2IRQ0] .Init("IA2IRQ0",     0x0B40, 12,     0x000      );  // IVT of CPU2
+  fRegisterValue[kIA2IRQ1] .Init("IA2IRQ1",     0x0B41, 12,     0x000      );
+  fRegisterValue[kIA2IRQ2] .Init("IA2IRQ2",     0x0B42, 12,     0x000      );
+  fRegisterValue[kIA2IRQ3] .Init("IA2IRQ3",     0x0B43, 12,     0x000      );
+  fRegisterValue[kIA2IRQ4] .Init("IA2IRQ4",     0x0B44, 12,     0x000      );
+  fRegisterValue[kIA2IRQ5] .Init("IA2IRQ5",     0x0B45, 12,     0x000      );
+  fRegisterValue[kIA2IRQ6] .Init("IA2IRQ6",     0x0B46, 12,     0x000      );
+  fRegisterValue[kIA2IRQ7] .Init("IA2IRQ7",     0x0B47, 12,     0x000      );
+  fRegisterValue[kIA2IRQ8] .Init("IA2IRQ8",     0x0B48, 12,     0x000      );
+  fRegisterValue[kIA2IRQ9] .Init("IA2IRQ9",     0x0B49, 12,     0x000      );
+  fRegisterValue[kIA2IRQA] .Init("IA2IRQA",     0x0B4A, 12,     0x000      );
+  fRegisterValue[kIA2IRQB] .Init("IA2IRQB",     0x0B4B, 12,     0x000      );
+  fRegisterValue[kIA2IRQC] .Init("IA2IRQC",     0x0B4C, 12,     0x000      );
+  fRegisterValue[kIRQSW2]  .Init("IRQSW2",      0x0B4D, 13,     0x1FFF     );
+  fRegisterValue[kIRQHW2]  .Init("IRQHW2",      0x0B4E, 13,     0x0000     );
+  fRegisterValue[kIRQHL2]  .Init("IRQHL2",      0x0B4F, 13,     0x0000     );
+  fRegisterValue[kIA3IRQ0] .Init("IA3IRQ0",     0x0B60, 12,     0x000      );  // IVT of CPU3
+  fRegisterValue[kIA3IRQ1] .Init("IA3IRQ1",     0x0B61, 12,     0x000      );
+  fRegisterValue[kIA3IRQ2] .Init("IA3IRQ2",     0x0B62, 12,     0x000      );
+  fRegisterValue[kIA3IRQ3] .Init("IA3IRQ3",     0x0B63, 12,     0x000      );
+  fRegisterValue[kIA3IRQ4] .Init("IA3IRQ4",     0x0B64, 12,     0x000      );
+  fRegisterValue[kIA3IRQ5] .Init("IA3IRQ5",     0x0B65, 12,     0x000      );
+  fRegisterValue[kIA3IRQ6] .Init("IA3IRQ6",     0x0B66, 12,     0x000      );
+  fRegisterValue[kIA3IRQ7] .Init("IA3IRQ7",     0x0B67, 12,     0x000      );
+  fRegisterValue[kIA3IRQ8] .Init("IA3IRQ8",     0x0B68, 12,     0x000      );
+  fRegisterValue[kIA3IRQ9] .Init("IA3IRQ9",     0x0B69, 12,     0x000      );
+  fRegisterValue[kIA3IRQA] .Init("IA3IRQA",     0x0B6A, 12,     0x000      );
+  fRegisterValue[kIA3IRQB] .Init("IA3IRQB",     0x0B6B, 12,     0x000      );
+  fRegisterValue[kIA3IRQC] .Init("IA3IRQC",     0x0B6C, 12,     0x000      );
+  fRegisterValue[kIRQSW3]  .Init("IRQSW3",      0x0B6D, 13,     0x1FFF     );
+  fRegisterValue[kIRQHW3]  .Init("IRQHW3",      0x0B6E, 13,     0x0000     );
+  fRegisterValue[kIRQHL3]  .Init("IRQHL3",      0x0B6F, 13,     0x0000     );
+  fRegisterValue[kCTGDINI] .Init("CTGDINI",     0x0B80, 32,     0x00000000 );  // Global Counter/Timer
+  fRegisterValue[kCTGCTRL] .Init("CTGCTRL",     0x0B81, 12,     0xE3F      );
+  fRegisterValue[kC08CPU0] .Init("C08CPU0",     0x0C00, 32,     0x00000000 );  // CPU constants
+  fRegisterValue[kC09CPU0] .Init("C09CPU0",     0x0C01, 32,     0x00000000 );
+  fRegisterValue[kC10CPU0] .Init("C10CPU0",     0x0C02, 32,     0x00000000 );
+  fRegisterValue[kC11CPU0] .Init("C11CPU0",     0x0C03, 32,     0x00000000 );
+  fRegisterValue[kC12CPUA] .Init("C12CPUA",     0x0C04, 32,     0x00000000 );
+  fRegisterValue[kC13CPUA] .Init("C13CPUA",     0x0C05, 32,     0x00000000 );
+  fRegisterValue[kC14CPUA] .Init("C14CPUA",     0x0C06, 32,     0x00000000 );
+  fRegisterValue[kC15CPUA] .Init("C15CPUA",     0x0C07, 32,     0x00000000 );
+  fRegisterValue[kC08CPU1] .Init("C08CPU1",     0x0C08, 32,     0x00000000 );
+  fRegisterValue[kC09CPU1] .Init("C09CPU1",     0x0C09, 32,     0x00000000 );
+  fRegisterValue[kC10CPU1] .Init("C10CPU1",     0x0C0A, 32,     0x00000000 );
+  fRegisterValue[kC11CPU1] .Init("C11CPU1",     0x0C0B, 32,     0x00000000 );
+  fRegisterValue[kC08CPU2] .Init("C08CPU2",     0x0C10, 32,     0x00000000 );
+  fRegisterValue[kC09CPU2] .Init("C09CPU2",     0x0C11, 32,     0x00000000 );
+  fRegisterValue[kC10CPU2] .Init("C10CPU2",     0x0C12, 32,     0x00000000 );
+  fRegisterValue[kC11CPU2] .Init("C11CPU2",     0x0C13, 32,     0x00000000 );
+  fRegisterValue[kC08CPU3] .Init("C08CPU3",     0x0C18, 32,     0x00000000 );
+  fRegisterValue[kC09CPU3] .Init("C09CPU3",     0x0C19, 32,     0x00000000 );
+  fRegisterValue[kC10CPU3] .Init("C10CPU3",     0x0C1A, 32,     0x00000000 );
+  fRegisterValue[kC11CPU3] .Init("C11CPU3",     0x0C1B, 32,     0x00000000 );
+  fRegisterValue[kNMOD]    .Init("NMOD",        0x0D40, 6,      0x08       );  // NI interface
+  fRegisterValue[kNDLY]    .Init("NDLY",        0x0D41, 30,     0x24924924 );
+  fRegisterValue[kNED]     .Init("NED",         0x0D42, 16,     0xA240     );
+  fRegisterValue[kNTRO]    .Init("NTRO",        0x0D43, 18,     0x3FFFC    );
+  fRegisterValue[kNRRO]    .Init("NRRO",        0x0D44, 18,     0x3FFFC    );
+  fRegisterValue[kNES]     .Init("NES",         0x0D45, 32,     0x00000000 );
+  fRegisterValue[kNTP]     .Init("NTP",         0x0D46, 32,     0x0000FFFF );
+  fRegisterValue[kNBND]    .Init("NBND",        0x0D47, 16,     0x6020     );
+  fRegisterValue[kNP0]     .Init("NP0",         0x0D48, 11,     0x44C      );
+  fRegisterValue[kNP1]     .Init("NP1",         0x0D49, 11,     0x44C      );
+  fRegisterValue[kNP2]     .Init("NP2",         0x0D4A, 11,     0x44C      );
+  fRegisterValue[kNP3]     .Init("NP3",         0x0D4B, 11,     0x44C      );
+  fRegisterValue[kNCUT]    .Init("NCUT",        0x0D4C, 32,     0xFFFFFFFF );
+  fRegisterValue[kTPPT0]   .Init("TPPT0",       0x3000, 7,      0x01       );  // Filter and Preprocessor
+  fRegisterValue[kTPFS]    .Init("TPFS",        0x3001, 7,      0x05       );
+  fRegisterValue[kTPFE]    .Init("TPFE",        0x3002, 7,      0x14       );
+  fRegisterValue[kTPPGR]   .Init("TPPGR",       0x3003, 7,      0x15       );
+  fRegisterValue[kTPPAE]   .Init("TPPAE",       0x3004, 7,      0x1E       );
+  fRegisterValue[kTPQS0]   .Init("TPQS0",       0x3005, 7,      0x00       );
+  fRegisterValue[kTPQE0]   .Init("TPQE0",       0x3006, 7,      0x0A       );
+  fRegisterValue[kTPQS1]   .Init("TPQS1",       0x3007, 7,      0x0B       );
+  fRegisterValue[kTPQE1]   .Init("TPQE1",       0x3008, 7,      0x14       );
+  fRegisterValue[kEBD]     .Init("EBD",         0x3009, 3,      0x0        );
+  fRegisterValue[kEBAQA]   .Init("EBAQA",       0x300A, 7,      0x00       );
+  fRegisterValue[kEBSIA]   .Init("EBSIA",       0x300B, 7,      0x20       );
+  fRegisterValue[kEBSF]    .Init("EBSF",        0x300C, 1,      0x1        );
+  fRegisterValue[kEBSIM]   .Init("EBSIM",       0x300D, 1,      0x1        );
+  fRegisterValue[kEBPP]    .Init("EBPP",        0x300E, 1,      0x1        );
+  fRegisterValue[kEBPC]    .Init("EBPC",        0x300F, 1,      0x1        );
+  fRegisterValue[kEBIS]    .Init("EBIS",        0x3014, 10,     0x005      );
+  fRegisterValue[kEBIT]    .Init("EBIT",        0x3015, 12,     0x028      );
+  fRegisterValue[kEBIL]    .Init("EBIL",        0x3016, 8,      0xF0       );
+  fRegisterValue[kEBIN]    .Init("EBIN",        0x3017, 1,      0x1        );
+  fRegisterValue[kFLBY]    .Init("FLBY",        0x3018, 1,      0x0        );
+  fRegisterValue[kFPBY]    .Init("FPBY",        0x3019, 1,      0x0        );
+  fRegisterValue[kFGBY]    .Init("FGBY",        0x301A, 1,      0x0        );
+  fRegisterValue[kFTBY]    .Init("FTBY",        0x301B, 1,      0x0        );
+  fRegisterValue[kFCBY]    .Init("FCBY",        0x301C, 1,      0x0        );
+  fRegisterValue[kFPTC]    .Init("FPTC",        0x3020, 2,      0x3        );
+  fRegisterValue[kFPNP]    .Init("FPNP",        0x3021, 9,      0x078      );
+  fRegisterValue[kFPCL]    .Init("FPCL",        0x3022, 1,      0x1        );
+  fRegisterValue[kFGTA]    .Init("FGTA",        0x3028, 12,     0x014      );
+  fRegisterValue[kFGTB]    .Init("FGTB",        0x3029, 12,     0x80C      );
+  fRegisterValue[kFGCL]    .Init("FGCL",        0x302A, 1,      0x1        );
+  fRegisterValue[kFTAL]    .Init("FTAL",        0x3030, 10,     0x0F6      );
+  fRegisterValue[kFTLL]    .Init("FTLL",        0x3031, 9,      0x11D      );
+  fRegisterValue[kFTLS]    .Init("FTLS",        0x3032, 9,      0x0D3      );
+  fRegisterValue[kFCW1]    .Init("FCW1",        0x3038, 8,      0x1E       );
+  fRegisterValue[kFCW2]    .Init("FCW2",        0x3039, 8,      0xD4       );
+  fRegisterValue[kFCW3]    .Init("FCW3",        0x303A, 8,      0xE6       );
+  fRegisterValue[kFCW4]    .Init("FCW4",        0x303B, 8,      0x4A       );
+  fRegisterValue[kFCW5]    .Init("FCW5",        0x303C, 8,      0xEF       );
+  fRegisterValue[kTPFP]    .Init("TPFP",        0x3040, 9,      0x037      );
+  fRegisterValue[kTPHT]    .Init("TPHT",        0x3041, 14,     0x00A0     );
+  fRegisterValue[kTPVT]    .Init("TPVT",        0x3042, 6,      0x00       );
+  fRegisterValue[kTPVBY]   .Init("TPVBY",       0x3043, 1,      0x0        );
+  fRegisterValue[kTPCT]    .Init("TPCT",        0x3044, 5,      0x08       );
+  fRegisterValue[kTPCL]    .Init("TPCL",        0x3045, 5,      0x01       );
+  fRegisterValue[kTPCBY]   .Init("TPCBY",       0x3046, 1,      0x1        );
+  fRegisterValue[kTPD]     .Init("TPD",         0x3047, 4,      0xF        );
+  fRegisterValue[kTPCI0]   .Init("TPCI0",       0x3048, 5,      0x00       );
+  fRegisterValue[kTPCI1]   .Init("TPCI1",       0x3049, 5,      0x00       );
+  fRegisterValue[kTPCI2]   .Init("TPCI2",       0x304A, 5,      0x00       );
+  fRegisterValue[kTPCI3]   .Init("TPCI3",       0x304B, 5,      0x00       );
+  fRegisterValue[kADCMSK]  .Init("ADCMSK",      0x3050, 21,     0x1FFFFF   );
+  fRegisterValue[kADCINB]  .Init("ADCINB",      0x3051, 2,      0x2        );
+  fRegisterValue[kADCDAC]  .Init("ADCDAC",      0x3052, 5,      0x10       );
+  fRegisterValue[kADCPAR]  .Init("ADCPAR",      0x3053, 18,     0x195EF    );
+  fRegisterValue[kADCTST]  .Init("ADCTST",      0x3054, 2,      0x0        );
+  fRegisterValue[kSADCAZ]  .Init("SADCAZ",      0x3055, 1,      0x1        );
+  fRegisterValue[kFGF0]    .Init("FGF0",        0x3080, 9,      0x000      );
+  fRegisterValue[kFGF1]    .Init("FGF1",        0x3081, 9,      0x000      );
+  fRegisterValue[kFGF2]    .Init("FGF2",        0x3082, 9,      0x000      );
+  fRegisterValue[kFGF3]    .Init("FGF3",        0x3083, 9,      0x000      );
+  fRegisterValue[kFGF4]    .Init("FGF4",        0x3084, 9,      0x000      );
+  fRegisterValue[kFGF5]    .Init("FGF5",        0x3085, 9,      0x000      );
+  fRegisterValue[kFGF6]    .Init("FGF6",        0x3086, 9,      0x000      );
+  fRegisterValue[kFGF7]    .Init("FGF7",        0x3087, 9,      0x000      );
+  fRegisterValue[kFGF8]    .Init("FGF8",        0x3088, 9,      0x000      );
+  fRegisterValue[kFGF9]    .Init("FGF9",        0x3089, 9,      0x000      );
+  fRegisterValue[kFGF10]   .Init("FGF10",       0x308A, 9,      0x000      );
+  fRegisterValue[kFGF11]   .Init("FGF11",       0x308B, 9,      0x000      );
+  fRegisterValue[kFGF12]   .Init("FGF12",       0x308C, 9,      0x000      );
+  fRegisterValue[kFGF13]   .Init("FGF13",       0x308D, 9,      0x000      );
+  fRegisterValue[kFGF14]   .Init("FGF14",       0x308E, 9,      0x000      );
+  fRegisterValue[kFGF15]   .Init("FGF15",       0x308F, 9,      0x000      );
+  fRegisterValue[kFGF16]   .Init("FGF16",       0x3090, 9,      0x000      );
+  fRegisterValue[kFGF17]   .Init("FGF17",       0x3091, 9,      0x000      );
+  fRegisterValue[kFGF18]   .Init("FGF18",       0x3092, 9,      0x000      );
+  fRegisterValue[kFGF19]   .Init("FGF19",       0x3093, 9,      0x000      );
+  fRegisterValue[kFGF20]   .Init("FGF20",       0x3094, 9,      0x000      );
+  fRegisterValue[kFGA0]    .Init("FGA0",        0x30A0, 6,      0x00       );
+  fRegisterValue[kFGA1]    .Init("FGA1",        0x30A1, 6,      0x00       );
+  fRegisterValue[kFGA2]    .Init("FGA2",        0x30A2, 6,      0x00       );
+  fRegisterValue[kFGA3]    .Init("FGA3",        0x30A3, 6,      0x00       );
+  fRegisterValue[kFGA4]    .Init("FGA4",        0x30A4, 6,      0x00       );
+  fRegisterValue[kFGA5]    .Init("FGA5",        0x30A5, 6,      0x00       );
+  fRegisterValue[kFGA6]    .Init("FGA6",        0x30A6, 6,      0x00       );
+  fRegisterValue[kFGA7]    .Init("FGA7",        0x30A7, 6,      0x00       );
+  fRegisterValue[kFGA8]    .Init("FGA8",        0x30A8, 6,      0x00       );
+  fRegisterValue[kFGA9]    .Init("FGA9",        0x30A9, 6,      0x00       );
+  fRegisterValue[kFGA10]   .Init("FGA10",       0x30AA, 6,      0x00       );
+  fRegisterValue[kFGA11]   .Init("FGA11",       0x30AB, 6,      0x00       );
+  fRegisterValue[kFGA12]   .Init("FGA12",       0x30AC, 6,      0x00       );
+  fRegisterValue[kFGA13]   .Init("FGA13",       0x30AD, 6,      0x00       );
+  fRegisterValue[kFGA14]   .Init("FGA14",       0x30AE, 6,      0x00       );
+  fRegisterValue[kFGA15]   .Init("FGA15",       0x30AF, 6,      0x00       );
+  fRegisterValue[kFGA16]   .Init("FGA16",       0x30B0, 6,      0x00       );
+  fRegisterValue[kFGA17]   .Init("FGA17",       0x30B1, 6,      0x00       );
+  fRegisterValue[kFGA18]   .Init("FGA18",       0x30B2, 6,      0x00       );
+  fRegisterValue[kFGA19]   .Init("FGA19",       0x30B3, 6,      0x00       );
+  fRegisterValue[kFGA20]   .Init("FGA20",       0x30B4, 6,      0x00       );
+  fRegisterValue[kFLL00]   .Init("FLL00",       0x3100, 6,      0x00       );  // non-linearity table, 64 x 6 bits
+  fRegisterValue[kFLL01]   .Init("FLL01",       0x3101, 6,      0x00       );
+  fRegisterValue[kFLL02]   .Init("FLL02",       0x3102, 6,      0x00       );
+  fRegisterValue[kFLL03]   .Init("FLL03",       0x3103, 6,      0x00       );
+  fRegisterValue[kFLL04]   .Init("FLL04",       0x3104, 6,      0x00       );
+  fRegisterValue[kFLL05]   .Init("FLL05",       0x3105, 6,      0x00       );
+  fRegisterValue[kFLL06]   .Init("FLL06",       0x3106, 6,      0x00       );
+  fRegisterValue[kFLL07]   .Init("FLL07",       0x3107, 6,      0x00       );
+  fRegisterValue[kFLL08]   .Init("FLL08",       0x3108, 6,      0x00       );
+  fRegisterValue[kFLL09]   .Init("FLL09",       0x3109, 6,      0x00       );
+  fRegisterValue[kFLL0A]   .Init("FLL0A",       0x310A, 6,      0x00       );
+  fRegisterValue[kFLL0B]   .Init("FLL0B",       0x310B, 6,      0x00       );
+  fRegisterValue[kFLL0C]   .Init("FLL0C",       0x310C, 6,      0x00       );
+  fRegisterValue[kFLL0D]   .Init("FLL0D",       0x310D, 6,      0x00       );
+  fRegisterValue[kFLL0E]   .Init("FLL0E",       0x310E, 6,      0x00       );
+  fRegisterValue[kFLL0F]   .Init("FLL0F",       0x310F, 6,      0x00       );
+  fRegisterValue[kFLL10]   .Init("FLL10",       0x3110, 6,      0x00       );
+  fRegisterValue[kFLL11]   .Init("FLL11",       0x3111, 6,      0x00       );
+  fRegisterValue[kFLL12]   .Init("FLL12",       0x3112, 6,      0x00       );
+  fRegisterValue[kFLL13]   .Init("FLL13",       0x3113, 6,      0x00       );
+  fRegisterValue[kFLL14]   .Init("FLL14",       0x3114, 6,      0x00       );
+  fRegisterValue[kFLL15]   .Init("FLL15",       0x3115, 6,      0x00       );
+  fRegisterValue[kFLL16]   .Init("FLL16",       0x3116, 6,      0x00       );
+  fRegisterValue[kFLL17]   .Init("FLL17",       0x3117, 6,      0x00       );
+  fRegisterValue[kFLL18]   .Init("FLL18",       0x3118, 6,      0x00       );
+  fRegisterValue[kFLL19]   .Init("FLL19",       0x3119, 6,      0x00       );
+  fRegisterValue[kFLL1A]   .Init("FLL1A",       0x311A, 6,      0x00       );
+  fRegisterValue[kFLL1B]   .Init("FLL1B",       0x311B, 6,      0x00       );
+  fRegisterValue[kFLL1C]   .Init("FLL1C",       0x311C, 6,      0x00       );
+  fRegisterValue[kFLL1D]   .Init("FLL1D",       0x311D, 6,      0x00       );
+  fRegisterValue[kFLL1E]   .Init("FLL1E",       0x311E, 6,      0x00       );
+  fRegisterValue[kFLL1F]   .Init("FLL1F",       0x311F, 6,      0x00       );
+  fRegisterValue[kFLL20]   .Init("FLL20",       0x3120, 6,      0x00       );
+  fRegisterValue[kFLL21]   .Init("FLL21",       0x3121, 6,      0x00       );
+  fRegisterValue[kFLL22]   .Init("FLL22",       0x3122, 6,      0x00       );
+  fRegisterValue[kFLL23]   .Init("FLL23",       0x3123, 6,      0x00       );
+  fRegisterValue[kFLL24]   .Init("FLL24",       0x3124, 6,      0x00       );
+  fRegisterValue[kFLL25]   .Init("FLL25",       0x3125, 6,      0x00       );
+  fRegisterValue[kFLL26]   .Init("FLL26",       0x3126, 6,      0x00       );
+  fRegisterValue[kFLL27]   .Init("FLL27",       0x3127, 6,      0x00       );
+  fRegisterValue[kFLL28]   .Init("FLL28",       0x3128, 6,      0x00       );
+  fRegisterValue[kFLL29]   .Init("FLL29",       0x3129, 6,      0x00       );
+  fRegisterValue[kFLL2A]   .Init("FLL2A",       0x312A, 6,      0x00       );
+  fRegisterValue[kFLL2B]   .Init("FLL2B",       0x312B, 6,      0x00       );
+  fRegisterValue[kFLL2C]   .Init("FLL2C",       0x312C, 6,      0x00       );
+  fRegisterValue[kFLL2D]   .Init("FLL2D",       0x312D, 6,      0x00       );
+  fRegisterValue[kFLL2E]   .Init("FLL2E",       0x312E, 6,      0x00       );
+  fRegisterValue[kFLL2F]   .Init("FLL2F",       0x312F, 6,      0x00       );
+  fRegisterValue[kFLL30]   .Init("FLL30",       0x3130, 6,      0x00       );
+  fRegisterValue[kFLL31]   .Init("FLL31",       0x3131, 6,      0x00       );
+  fRegisterValue[kFLL32]   .Init("FLL32",       0x3132, 6,      0x00       );
+  fRegisterValue[kFLL33]   .Init("FLL33",       0x3133, 6,      0x00       );
+  fRegisterValue[kFLL34]   .Init("FLL34",       0x3134, 6,      0x00       );
+  fRegisterValue[kFLL35]   .Init("FLL35",       0x3135, 6,      0x00       );
+  fRegisterValue[kFLL36]   .Init("FLL36",       0x3136, 6,      0x00       );
+  fRegisterValue[kFLL37]   .Init("FLL37",       0x3137, 6,      0x00       );
+  fRegisterValue[kFLL38]   .Init("FLL38",       0x3138, 6,      0x00       );
+  fRegisterValue[kFLL39]   .Init("FLL39",       0x3139, 6,      0x00       );
+  fRegisterValue[kFLL3A]   .Init("FLL3A",       0x313A, 6,      0x00       );
+  fRegisterValue[kFLL3B]   .Init("FLL3B",       0x313B, 6,      0x00       );
+  fRegisterValue[kFLL3C]   .Init("FLL3C",       0x313C, 6,      0x00       );
+  fRegisterValue[kFLL3D]   .Init("FLL3D",       0x313D, 6,      0x00       );
+  fRegisterValue[kFLL3E]   .Init("FLL3E",       0x313E, 6,      0x00       );
+  fRegisterValue[kFLL3F]   .Init("FLL3F",       0x313F, 6,      0x00       );
+  fRegisterValue[kPASADEL] .Init("PASADEL",     0x3158, 8,      0xFF       );  // end of non-lin table
+  fRegisterValue[kPASAPHA] .Init("PASAPHA",     0x3159, 6,      0x3F       );
+  fRegisterValue[kPASAPRA] .Init("PASAPRA",     0x315A, 6,      0x0F       );
+  fRegisterValue[kPASADAC] .Init("PASADAC",     0x315B, 8,      0x80       );
+  fRegisterValue[kPASACHM] .Init("PASACHM",     0x315C, 19,     0x7FFFF    );
+  fRegisterValue[kPASASTL] .Init("PASASTL",     0x315D, 8,      0xFF       );
+  fRegisterValue[kPASAPR1] .Init("PASAPR1",     0x315E, 1,      0x0        );
+  fRegisterValue[kPASAPR0] .Init("PASAPR0",     0x315F, 1,      0x0        );
+  fRegisterValue[kSADCTRG] .Init("SADCTRG",     0x3161, 1,      0x0        );
+  fRegisterValue[kSADCRUN] .Init("SADCRUN",     0x3162, 1,      0x0        );
+  fRegisterValue[kSADCPWR] .Init("SADCPWR",     0x3163, 3,      0x7        );
+  fRegisterValue[kL0TSIM]  .Init("L0TSIM",      0x3165, 14,     0x0050     );
+  fRegisterValue[kSADCEC]  .Init("SADCEC",      0x3166, 7,      0x00       );
+  fRegisterValue[kSADCMC]  .Init("SADCMC",      0x3170, 8,      0xC0       );
+  fRegisterValue[kSADCOC]  .Init("SADCOC",      0x3171, 8,      0x19       );
+  fRegisterValue[kSADCGTB] .Init("SADCGTB",     0x3172, 32,     0x37737700 );
+  fRegisterValue[kSEBDEN]  .Init("SEBDEN",      0x3178, 3,      0x0        );
+  fRegisterValue[kSEBDOU]  .Init("SEBDOU",      0x3179, 3,      0x0        );
+  fRegisterValue[kTPL00]   .Init("TPL00",       0x3180, 5,      0x00       );  // pos table, 128 x 5 bits
+  fRegisterValue[kTPL01]   .Init("TPL01",       0x3181, 5,      0x00       );
+  fRegisterValue[kTPL02]   .Init("TPL02",       0x3182, 5,      0x00       );
+  fRegisterValue[kTPL03]   .Init("TPL03",       0x3183, 5,      0x00       );
+  fRegisterValue[kTPL04]   .Init("TPL04",       0x3184, 5,      0x00       );
+  fRegisterValue[kTPL05]   .Init("TPL05",       0x3185, 5,      0x00       );
+  fRegisterValue[kTPL06]   .Init("TPL06",       0x3186, 5,      0x00       );
+  fRegisterValue[kTPL07]   .Init("TPL07",       0x3187, 5,      0x00       );
+  fRegisterValue[kTPL08]   .Init("TPL08",       0x3188, 5,      0x00       );
+  fRegisterValue[kTPL09]   .Init("TPL09",       0x3189, 5,      0x00       );
+  fRegisterValue[kTPL0A]   .Init("TPL0A",       0x318A, 5,      0x00       );
+  fRegisterValue[kTPL0B]   .Init("TPL0B",       0x318B, 5,      0x00       );
+  fRegisterValue[kTPL0C]   .Init("TPL0C",       0x318C, 5,      0x00       );
+  fRegisterValue[kTPL0D]   .Init("TPL0D",       0x318D, 5,      0x00       );
+  fRegisterValue[kTPL0E]   .Init("TPL0E",       0x318E, 5,      0x00       );
+  fRegisterValue[kTPL0F]   .Init("TPL0F",       0x318F, 5,      0x00       );
+  fRegisterValue[kTPL10]   .Init("TPL10",       0x3190, 5,      0x00       );
+  fRegisterValue[kTPL11]   .Init("TPL11",       0x3191, 5,      0x00       );
+  fRegisterValue[kTPL12]   .Init("TPL12",       0x3192, 5,      0x00       );
+  fRegisterValue[kTPL13]   .Init("TPL13",       0x3193, 5,      0x00       );
+  fRegisterValue[kTPL14]   .Init("TPL14",       0x3194, 5,      0x00       );
+  fRegisterValue[kTPL15]   .Init("TPL15",       0x3195, 5,      0x00       );
+  fRegisterValue[kTPL16]   .Init("TPL16",       0x3196, 5,      0x00       );
+  fRegisterValue[kTPL17]   .Init("TPL17",       0x3197, 5,      0x00       );
+  fRegisterValue[kTPL18]   .Init("TPL18",       0x3198, 5,      0x00       );
+  fRegisterValue[kTPL19]   .Init("TPL19",       0x3199, 5,      0x00       );
+  fRegisterValue[kTPL1A]   .Init("TPL1A",       0x319A, 5,      0x00       );
+  fRegisterValue[kTPL1B]   .Init("TPL1B",       0x319B, 5,      0x00       );
+  fRegisterValue[kTPL1C]   .Init("TPL1C",       0x319C, 5,      0x00       );
+  fRegisterValue[kTPL1D]   .Init("TPL1D",       0x319D, 5,      0x00       );
+  fRegisterValue[kTPL1E]   .Init("TPL1E",       0x319E, 5,      0x00       );
+  fRegisterValue[kTPL1F]   .Init("TPL1F",       0x319F, 5,      0x00       );
+  fRegisterValue[kTPL20]   .Init("TPL20",       0x31A0, 5,      0x00       );
+  fRegisterValue[kTPL21]   .Init("TPL21",       0x31A1, 5,      0x00       );
+  fRegisterValue[kTPL22]   .Init("TPL22",       0x31A2, 5,      0x00       );
+  fRegisterValue[kTPL23]   .Init("TPL23",       0x31A3, 5,      0x00       );
+  fRegisterValue[kTPL24]   .Init("TPL24",       0x31A4, 5,      0x00       );
+  fRegisterValue[kTPL25]   .Init("TPL25",       0x31A5, 5,      0x00       );
+  fRegisterValue[kTPL26]   .Init("TPL26",       0x31A6, 5,      0x00       );
+  fRegisterValue[kTPL27]   .Init("TPL27",       0x31A7, 5,      0x00       );
+  fRegisterValue[kTPL28]   .Init("TPL28",       0x31A8, 5,      0x00       );
+  fRegisterValue[kTPL29]   .Init("TPL29",       0x31A9, 5,      0x00       );
+  fRegisterValue[kTPL2A]   .Init("TPL2A",       0x31AA, 5,      0x00       );
+  fRegisterValue[kTPL2B]   .Init("TPL2B",       0x31AB, 5,      0x00       );
+  fRegisterValue[kTPL2C]   .Init("TPL2C",       0x31AC, 5,      0x00       );
+  fRegisterValue[kTPL2D]   .Init("TPL2D",       0x31AD, 5,      0x00       );
+  fRegisterValue[kTPL2E]   .Init("TPL2E",       0x31AE, 5,      0x00       );
+  fRegisterValue[kTPL2F]   .Init("TPL2F",       0x31AF, 5,      0x00       );
+  fRegisterValue[kTPL30]   .Init("TPL30",       0x31B0, 5,      0x00       );
+  fRegisterValue[kTPL31]   .Init("TPL31",       0x31B1, 5,      0x00       );
+  fRegisterValue[kTPL32]   .Init("TPL32",       0x31B2, 5,      0x00       );
+  fRegisterValue[kTPL33]   .Init("TPL33",       0x31B3, 5,      0x00       );
+  fRegisterValue[kTPL34]   .Init("TPL34",       0x31B4, 5,      0x00       );
+  fRegisterValue[kTPL35]   .Init("TPL35",       0x31B5, 5,      0x00       );
+  fRegisterValue[kTPL36]   .Init("TPL36",       0x31B6, 5,      0x00       );
+  fRegisterValue[kTPL37]   .Init("TPL37",       0x31B7, 5,      0x00       );
+  fRegisterValue[kTPL38]   .Init("TPL38",       0x31B8, 5,      0x00       );
+  fRegisterValue[kTPL39]   .Init("TPL39",       0x31B9, 5,      0x00       );
+  fRegisterValue[kTPL3A]   .Init("TPL3A",       0x31BA, 5,      0x00       );
+  fRegisterValue[kTPL3B]   .Init("TPL3B",       0x31BB, 5,      0x00       );
+  fRegisterValue[kTPL3C]   .Init("TPL3C",       0x31BC, 5,      0x00       );
+  fRegisterValue[kTPL3D]   .Init("TPL3D",       0x31BD, 5,      0x00       );
+  fRegisterValue[kTPL3E]   .Init("TPL3E",       0x31BE, 5,      0x00       );
+  fRegisterValue[kTPL3F]   .Init("TPL3F",       0x31BF, 5,      0x00       );
+  fRegisterValue[kTPL40]   .Init("TPL40",       0x31C0, 5,      0x00       );
+  fRegisterValue[kTPL41]   .Init("TPL41",       0x31C1, 5,      0x00       );
+  fRegisterValue[kTPL42]   .Init("TPL42",       0x31C2, 5,      0x00       );
+  fRegisterValue[kTPL43]   .Init("TPL43",       0x31C3, 5,      0x00       );
+  fRegisterValue[kTPL44]   .Init("TPL44",       0x31C4, 5,      0x00       );
+  fRegisterValue[kTPL45]   .Init("TPL45",       0x31C5, 5,      0x00       );
+  fRegisterValue[kTPL46]   .Init("TPL46",       0x31C6, 5,      0x00       );
+  fRegisterValue[kTPL47]   .Init("TPL47",       0x31C7, 5,      0x00       );
+  fRegisterValue[kTPL48]   .Init("TPL48",       0x31C8, 5,      0x00       );
+  fRegisterValue[kTPL49]   .Init("TPL49",       0x31C9, 5,      0x00       );
+  fRegisterValue[kTPL4A]   .Init("TPL4A",       0x31CA, 5,      0x00       );
+  fRegisterValue[kTPL4B]   .Init("TPL4B",       0x31CB, 5,      0x00       );
+  fRegisterValue[kTPL4C]   .Init("TPL4C",       0x31CC, 5,      0x00       );
+  fRegisterValue[kTPL4D]   .Init("TPL4D",       0x31CD, 5,      0x00       );
+  fRegisterValue[kTPL4E]   .Init("TPL4E",       0x31CE, 5,      0x00       );
+  fRegisterValue[kTPL4F]   .Init("TPL4F",       0x31CF, 5,      0x00       );
+  fRegisterValue[kTPL50]   .Init("TPL50",       0x31D0, 5,      0x00       );
+  fRegisterValue[kTPL51]   .Init("TPL51",       0x31D1, 5,      0x00       );
+  fRegisterValue[kTPL52]   .Init("TPL52",       0x31D2, 5,      0x00       );
+  fRegisterValue[kTPL53]   .Init("TPL53",       0x31D3, 5,      0x00       );
+  fRegisterValue[kTPL54]   .Init("TPL54",       0x31D4, 5,      0x00       );
+  fRegisterValue[kTPL55]   .Init("TPL55",       0x31D5, 5,      0x00       );
+  fRegisterValue[kTPL56]   .Init("TPL56",       0x31D6, 5,      0x00       );
+  fRegisterValue[kTPL57]   .Init("TPL57",       0x31D7, 5,      0x00       );
+  fRegisterValue[kTPL58]   .Init("TPL58",       0x31D8, 5,      0x00       );
+  fRegisterValue[kTPL59]   .Init("TPL59",       0x31D9, 5,      0x00       );
+  fRegisterValue[kTPL5A]   .Init("TPL5A",       0x31DA, 5,      0x00       );
+  fRegisterValue[kTPL5B]   .Init("TPL5B",       0x31DB, 5,      0x00       );
+  fRegisterValue[kTPL5C]   .Init("TPL5C",       0x31DC, 5,      0x00       );
+  fRegisterValue[kTPL5D]   .Init("TPL5D",       0x31DD, 5,      0x00       );
+  fRegisterValue[kTPL5E]   .Init("TPL5E",       0x31DE, 5,      0x00       );
+  fRegisterValue[kTPL5F]   .Init("TPL5F",       0x31DF, 5,      0x00       );
+  fRegisterValue[kTPL60]   .Init("TPL60",       0x31E0, 5,      0x00       );
+  fRegisterValue[kTPL61]   .Init("TPL61",       0x31E1, 5,      0x00       );
+  fRegisterValue[kTPL62]   .Init("TPL62",       0x31E2, 5,      0x00       );
+  fRegisterValue[kTPL63]   .Init("TPL63",       0x31E3, 5,      0x00       );
+  fRegisterValue[kTPL64]   .Init("TPL64",       0x31E4, 5,      0x00       );
+  fRegisterValue[kTPL65]   .Init("TPL65",       0x31E5, 5,      0x00       );
+  fRegisterValue[kTPL66]   .Init("TPL66",       0x31E6, 5,      0x00       );
+  fRegisterValue[kTPL67]   .Init("TPL67",       0x31E7, 5,      0x00       );
+  fRegisterValue[kTPL68]   .Init("TPL68",       0x31E8, 5,      0x00       );
+  fRegisterValue[kTPL69]   .Init("TPL69",       0x31E9, 5,      0x00       );
+  fRegisterValue[kTPL6A]   .Init("TPL6A",       0x31EA, 5,      0x00       );
+  fRegisterValue[kTPL6B]   .Init("TPL6B",       0x31EB, 5,      0x00       );
+  fRegisterValue[kTPL6C]   .Init("TPL6C",       0x31EC, 5,      0x00       );
+  fRegisterValue[kTPL6D]   .Init("TPL6D",       0x31ED, 5,      0x00       );
+  fRegisterValue[kTPL6E]   .Init("TPL6E",       0x31EE, 5,      0x00       );
+  fRegisterValue[kTPL6F]   .Init("TPL6F",       0x31EF, 5,      0x00       );
+  fRegisterValue[kTPL70]   .Init("TPL70",       0x31F0, 5,      0x00       );
+  fRegisterValue[kTPL71]   .Init("TPL71",       0x31F1, 5,      0x00       );
+  fRegisterValue[kTPL72]   .Init("TPL72",       0x31F2, 5,      0x00       );
+  fRegisterValue[kTPL73]   .Init("TPL73",       0x31F3, 5,      0x00       );
+  fRegisterValue[kTPL74]   .Init("TPL74",       0x31F4, 5,      0x00       );
+  fRegisterValue[kTPL75]   .Init("TPL75",       0x31F5, 5,      0x00       );
+  fRegisterValue[kTPL76]   .Init("TPL76",       0x31F6, 5,      0x00       );
+  fRegisterValue[kTPL77]   .Init("TPL77",       0x31F7, 5,      0x00       );
+  fRegisterValue[kTPL78]   .Init("TPL78",       0x31F8, 5,      0x00       );
+  fRegisterValue[kTPL79]   .Init("TPL79",       0x31F9, 5,      0x00       );
+  fRegisterValue[kTPL7A]   .Init("TPL7A",       0x31FA, 5,      0x00       );
+  fRegisterValue[kTPL7B]   .Init("TPL7B",       0x31FB, 5,      0x00       );
+  fRegisterValue[kTPL7C]   .Init("TPL7C",       0x31FC, 5,      0x00       );
+  fRegisterValue[kTPL7D]   .Init("TPL7D",       0x31FD, 5,      0x00       );
+  fRegisterValue[kTPL7E]   .Init("TPL7E",       0x31FE, 5,      0x00       );
+  fRegisterValue[kTPL7F]   .Init("TPL7F",       0x31FF, 5,      0x00       );
+  fRegisterValue[kMEMRW]   .Init("MEMRW",       0xD000, 7,      0x79       );  // end of pos table
+  fRegisterValue[kMEMCOR]  .Init("MEMCOR",      0xD001, 9,      0x000      );
+  fRegisterValue[kDMDELA]  .Init("DMDELA",      0xD002, 4,      0x8        );
+  fRegisterValue[kDMDELS]  .Init("DMDELS",      0xD003, 4,      0x8        );
 }
 
 
 void AliTRDtrapConfig::ResetRegs()
 {
-   // Reset the content of all TRAP registers to the reset values (see TRAP User Manual)
+  // 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);
-   }
+  for (Int_t iReg = 0; iReg < kLastReg; iReg++) {
+    fRegisterValue[iReg].Reset();
+  }
 }
 
 
@@ -625,13 +553,8 @@ void AliTRDtrapConfig::ResetDmem()
 {
   // reset the data memory
 
-     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;
-       }
-     }
+  for(Int_t iAddr = 0; iAddr < fgkDmemWords; iAddr++)
+    fDmem[iAddr].Reset();
 }
 
 
@@ -645,84 +568,16 @@ Int_t AliTRDtrapConfig::GetTrapReg(TrapReg_t reg, Int_t det, Int_t rob, Int_t mc
     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 < 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 fRegisterValue[reg].GetValue(det, rob, mcm);
   }
 }
 
 
-Bool_t AliTRDtrapConfig::SetTrapReg(TrapReg_t reg, Int_t value)
-{
-  // 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;
-      return kTRUE;
-   }
-   else {
-      AliError(Form("Register %s has individual values", AliTRDtrapConfig::GetRegName(reg)));
-   }
-   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( (det>=0 && det<AliTRDgeometry::Ndet())) {
-    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
-
-      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 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
+  // set a value for the given TRAP register on all chambers,
 
-      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 {  // should never be reached
-      AliError("MCM register status neither kGlobal nor kIndividual");
-      return kFALSE;
-    }
-  }
-  else {
-    AliError(Form("Invalid detector number: %i\n", det));
-    return kFALSE;
-  }
-
-  return kFALSE;
+  return fRegisterValue[reg].SetValue(value, det);
 }
 
 
@@ -730,37 +585,7 @@ Bool_t AliTRDtrapConfig::SetTrapReg(TrapReg_t reg, Int_t value, Int_t det, Int_t
 {
   // 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 {
-      AliError(Form("Invalid value for det, ROB or MCM selected: %i, %i, %i", det, rob, mcm));
-     return kFALSE;
-   }
-
-  return kTRUE;
+  return fRegisterValue[reg].SetValue(value, det, rob, mcm);
 }
 
 
@@ -779,6 +604,7 @@ UInt_t AliTRDtrapConfig::Peek(Int_t addr, Int_t det, Int_t rob, Int_t mcm) const
     }
   }
 
+  AliError(Form("peek for invalid addr: 0x%04x", addr));
   return 0;
 }
 
@@ -790,383 +616,88 @@ Bool_t AliTRDtrapConfig::Poke(Int_t addr, UInt_t value, Int_t det, Int_t rob, In
   if ( (addr >= fgkDmemStartAddress) &&
        (addr < (fgkDmemStartAddress + fgkDmemWords)) ) {
     AliDebug(2, Form("DMEM 0x%08x : %i", addr, value));
-    SetDmem(addr, value, det, rob, mcm);
-    return kTRUE;
+    return SetDmem(addr, value, det, rob, mcm);
   }
   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 SetTrapReg(mcmReg, (UInt_t) value, det, rob, mcm);
     }
   }
 
+  AliError(Form("poke for invalid address: 0x%04x", addr));
   return kFALSE;
 }
 
 
-Bool_t AliTRDtrapConfig::SetDmem(Int_t addr, UInt_t value)
+Bool_t AliTRDtrapConfig::SetDmemAlloc(Int_t addr, Alloc_t mode)
 {
-  // Set the content of the given DMEM address
+  addr = addr - fgkDmemStartAddress;
 
-   addr = addr - fgkDmemStartAddress;
+  if(addr < 0 || addr >=  fgkDmemWords) {
+    AliError(Form("Invalid DMEM address: 0x%04x", addr+fgkDmemStartAddress));
+    return kFALSE;
+  }
+  else {
+    fDmem[addr].Allocate(mode);
+    return kTRUE;
+  }
+}
 
-   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));
+Bool_t AliTRDtrapConfig::SetDmem(Int_t addr, UInt_t value, Int_t det)
+{
+  // Set the content of the given DMEM address
 
-        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));
+  addr = addr - fgkDmemStartAddress;
 
-        fDmem[addr][i]=value;
-      }
-      break;
-   default:
-      AliError(Form("Invalid selection type"));
-      break;
-   }
+  if(addr < 0 || addr >=  fgkDmemWords) {
+    AliError(Form("No DMEM address: 0x%08x", addr+fgkDmemStartAddress));
+    return kFALSE;
+  }
 
-   return kTRUE;
+  if (!fDmem[addr].SetValue(value, det)) {
+    AliError(Form("Problem writing to DMEM address 0x%04x", addr));
+    return kFALSE;
+  }
+  else
+    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;
 
-   addr = addr - fgkDmemStartAddress;
-   Int_t roc = det%30;
-   Int_t loc;
-
-   if(addr < 0 || addr >=  fgkDmemWords) {
+  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;
+  if (!fDmem[addr].SetValue(value, det, rob, mcm)) {
+    AliError(Form("Problem writing to DMEM address 0x%04x", addr));
+    return kFALSE;
+  }
+  else
+    return kTRUE;
 }
 
 
-UInt_t AliTRDtrapConfig::GetDmemUnsigned(Int_t addr) const
-{
-  // get the content of the data memory at the given address
-  // (only if the value is the same for all MCMs)
-
-   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
 {
   // get the content of the data memory at the given address
-  // for a given MCM
+  // (only if the value is the same for all MCMs)
 
    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::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;
-           }
-       }
+  if(addr < 0 || addr >=  fgkDmemWords) {
+    AliError(Form("No DMEM address: 0x%08x", addr+fgkDmemStartAddress));
+    return 0;
+  }
 
-      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!
+  return fDmem[addr].GetValue(det, rob, mcm);
 }
 
 
@@ -1175,34 +706,21 @@ Bool_t AliTRDtrapConfig::PrintTrapReg(TrapReg_t reg, Int_t det, Int_t rob, Int_t
   // 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("%10s (%2i bits) at 0x%04x is 0x%08x and resets to: 0x%08x (currently global mode)\n",
-           GetRegName((TrapReg_t) reg),
-           GetRegNBits((TrapReg_t) reg),
-           GetRegAddress((TrapReg_t) reg),
-           fRegisterValue[reg].globalValue,
-           GetRegResetValue((TrapReg_t) reg));
+  if((det >= 0 && det < AliTRDgeometry::Ndet()) &&
+     (rob >= 0 && rob < AliTRDfeeParam::GetNrobC1()) &&
+     (mcm >= 0 && mcm < fgkMaxMcm)) {
+    printf("%10s (%2i bits) at 0x%04x 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].GetValue(det, rob, mcm),
+          GetRegResetValue((TrapReg_t) reg));
   }
-  else if (fRegisterValue[reg].state == RegValue_t::kIndividual) {
-    if((det >= 0 && det < AliTRDgeometry::Ndet()) &&
-       (rob >= 0 && rob < AliTRDfeeParam::GetNrobC1()) &&
-       (mcm >= 0 && mcm < fgkMaxMcm)) {
-      printf("%10s (%2i bits) at 0x%04x 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*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");
+  else {
+    AliError("Register value is MCM-specific: Invalid detector, ROB or MCM requested");
     return kFALSE;
   }
+
   return kTRUE;
 }
 
@@ -1221,80 +739,25 @@ Bool_t AliTRDtrapConfig::PrintTrapAddr(Int_t addr, Int_t det, Int_t rob, Int_t m
 }
 
 
-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) {
-           AliDebug(1, Form("broadcast write to %s: 0x%08x",
-                            GetRegName((TrapReg_t) mcmReg), data));
-            SetTrapReg( (TrapReg_t) mcmReg, data, det);
-         }
-          else {
-           AliDebug(1, Form("individual write to %s (%i, %i): 0x%08x",
-                            GetRegName((TrapReg_t) mcmReg), (mcmList[i]>>7), (mcmList[i]&0x7F), data));
-            SetTrapReg( (TrapReg_t) mcmReg, data, det, (mcmList[i]>>7)&0x7, (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;
+  if (address < fgkRegisterAddressBlockStart[0])
+    return kLastReg;
+  else if (address < fgkRegisterAddressBlockStart[0] + fgkRegisterAddressBlockSize[0])
+    return fgRegAddressMap[address - fgkRegisterAddressBlockStart[0]];
+  else if (address < fgkRegisterAddressBlockStart[1])
+    return kLastReg;
+  else if (address < fgkRegisterAddressBlockStart[1] + fgkRegisterAddressBlockSize[1])
+    return fgRegAddressMap[address - fgkRegisterAddressBlockStart[1] + fgkRegisterAddressBlockSize[0]];
+  else if (address < fgkRegisterAddressBlockStart[2])
+    return kLastReg;
+  else if (address < fgkRegisterAddressBlockStart[2] + fgkRegisterAddressBlockSize[2])
+    return fgRegAddressMap[address - fgkRegisterAddressBlockStart[2] + fgkRegisterAddressBlockSize[1] + fgkRegisterAddressBlockSize[0]];
+  else
+    return kLastReg;
 }
 
 
@@ -1351,3 +814,210 @@ void AliTRDtrapConfig::PrintDatx(ostream &os, UInt_t addr, UInt_t data, Int_t ro
 
    os << std::endl;
 }
+
+
+AliTRDtrapConfig::AliTRDtrapValue::AliTRDtrapValue() :
+  TObject(),
+  fAllocMode(kAllocGlobal),
+  fSize(1),
+  fData(new UInt_t[1]),
+  fValid(new Bool_t[1])
+{
+  fData[0] = 0;
+  fValid[0] = kTRUE;
+}
+
+
+Bool_t AliTRDtrapConfig::AliTRDtrapValue::Allocate(Alloc_t alloc)
+{
+  // allocate memory for the specified granularity
+
+  delete [] fData;
+  delete [] fValid;
+
+  fAllocMode = alloc;
+  fSize = fgkSize[fAllocMode];
+
+  if (fSize > 0) {
+    fData = new UInt_t[fSize];
+    fValid = new Bool_t[fSize];
+    for (Int_t i = 0; i < fSize; ++i) {
+      fData[i] = 0;
+      fValid[i] = kFALSE;
+    }
+  }
+  else {
+    fData = 0x0;
+    fValid = 0x0;
+  }
+
+  return kTRUE;
+}
+
+
+Int_t AliTRDtrapConfig::AliTRDtrapValue::GetIdx(Int_t det, Int_t rob, Int_t mcm) const
+{
+  // return Idx to access the data for the given position
+
+  Int_t idx = -1;
+
+  switch (fAllocMode) {
+  case kAllocNone:
+    idx = -1;
+    break;
+  case kAllocGlobal:
+    idx = 0;
+    break;
+  case kAllocByDetector:
+    idx = det;
+    break;
+  case kAllocByHC:
+    idx = det + (rob % 2);
+    break;
+  case kAllocByMCM:
+    idx = 18*8*det + 18*rob + mcm;
+    break;
+  case kAllocByLayer:
+    idx = det % 6;
+    break;
+  case kAllocByMCMinSM:
+    idx = 18*8*(det%30) + 18*rob + mcm;
+    break;
+  default:
+    idx = -1;
+    AliError("Invalid allocation mode");
+  }
+  if (idx < fSize) {
+    return idx;
+  }
+  else {
+    AliError(Form("Index too large %i (size %i) for %s", idx, fSize, this->GetName()));
+    return  -1;
+  }
+}
+
+
+Bool_t AliTRDtrapConfig::AliTRDtrapValue::SetData(Int_t value)
+{
+  // set the given value everywhere
+
+  for (Int_t i = 0; i < fSize; ++i) {
+    fData[i] = value;
+    fValid[i] = kFALSE;
+  }
+
+  return kTRUE;
+}
+
+
+Bool_t AliTRDtrapConfig::AliTRDtrapValue::SetData(Int_t value, Int_t det)
+{
+  // set the data for a given detector
+
+  Int_t idx = GetIdx(det, 0, 0);
+
+  if (idx >= 0) {
+    // short cut for detector-wise allocation
+    if (fAllocMode == kAllocByDetector) {
+      if (fValid[idx] && (fData[idx] != value)) {
+       AliDebug(1, Form("Overwriting previous value %i of %s with %i for %i!",
+                        fData[idx], this->GetName(), value, det));
+      }
+      fData[idx] = value;
+      fValid[idx] = kTRUE;
+      return kTRUE;
+    }
+    else {
+      for (Int_t rob = 0; rob < 8; ++rob) {
+       for (Int_t mcm = 0; mcm < 18; ++mcm) {
+         idx = GetIdx(det, rob, mcm);
+         if (fValid[idx] && (fData[idx] != value)) {
+           AliDebug(1, Form("Overwriting previous value %i of %s with %i for %i %i:%02i!",
+                            fData[idx], this->GetName(), value, det, rob, mcm));
+         }
+         fData[idx] = value;
+         fValid[idx] = kTRUE;
+       }
+      }
+      return kTRUE;
+    }
+  }
+
+  if (fAllocMode == kAllocNone) {
+    // assume nobody cares
+    return kTRUE;
+  }
+  return kFALSE;
+}
+
+Bool_t AliTRDtrapConfig::AliTRDtrapValue::SetData(Int_t value, Int_t det, Int_t rob, Int_t mcm)
+{
+  // set data for an individual MCM
+
+  Int_t idx = GetIdx(det, rob, mcm);
+
+  if (idx >= 0) {
+    if (fValid[idx] && (fData[idx] != value)) {
+      AliDebug(1, Form("Overwriting previous value %i of %s with %i for %i %i:%02i (idx: %i)!",
+                      fData[idx], this->GetName(), value, det, rob, mcm, idx));
+    }
+    fData[idx] = value;
+    fValid[idx] = kTRUE;
+    return kTRUE;
+  }
+  else if (fAllocMode == kAllocNone) {
+    return kTRUE;
+  }
+  else {
+    AliError(Form("setting failed"));
+    return kFALSE;
+  }
+}
+
+Int_t AliTRDtrapConfig::AliTRDtrapValue::GetData(Int_t det, Int_t rob, Int_t mcm) const
+{
+  // read data for the given MCM
+
+  Int_t idx = GetIdx(det, rob, mcm);
+  if (idx >= 0) {
+    if (!fValid[idx])
+      AliDebug(1,Form("reading from unwritten address: %s at idx %i: %i", this->GetName(), idx, fValid[idx]));
+    return fData[idx];
+  }
+  else {
+    AliError("read from invalid address");
+    return 0;
+  }
+}
+
+AliTRDtrapConfig::AliTRDtrapRegister::AliTRDtrapRegister() :
+  AliTRDtrapValue(),
+  fName("invalid"),
+  fAddr(0),
+  fNbits(0),
+  fResetValue(0)
+{
+  // default constructor
+
+}
+
+AliTRDtrapConfig::AliTRDtrapRegister::~AliTRDtrapRegister()
+{
+  // destructor
+
+}
+
+void AliTRDtrapConfig::AliTRDtrapRegister::Init(const char* name, Int_t addr, Int_t nBits, Int_t resetValue)
+{
+  // init the TRAP register
+
+  if (fAddr == 0) {
+    fName = name;
+    fAddr = addr;
+    fNbits = nBits;
+    fResetValue = resetValue;
+  }
+  else
+    AliFatal("Re-initialising an existing TRAP register");
+}
+
index 1e0126f..9d53449 100644 (file)
@@ -3,27 +3,43 @@
 /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
  * See cxx source for full Copyright notice                               */
 
+// Configuration of the TRD TRAcklet Processor
+// (TRD Front-End Electronics)
 //
-// Class holding the configuration of the tracklet processor
-// in the TRD FEE
-//
-
+// TRAP registers
+// TRAP data memory (DMEM)
 
 #include <TObject.h>
+#include <TNamed.h>
 #include <TString.h>
 #include <fstream>
 
-class AliTRDtrapConfig : public TObject
+class AliTRDtrapConfig : public TNamed
 {
  public:
+  AliTRDtrapConfig(const TString &name = "", const TString &title = "");
   ~AliTRDtrapConfig();
 
-  static AliTRDtrapConfig* Instance();
-
+  // allocation
+  enum Alloc_t {
+    kAllocNone,
+    kAllocGlobal,
+    kAllocByDetector,
+    kAllocByHC,
+    kAllocByMCM,
+    kAllocByMergerType,
+    kAllocByLayer,
+    kAllocByMCMinSM,
+    kAllocLast
+  }; // possible granularities for allocation
+     // common to registers and DMEM
+
+  // registers
   enum TrapReg_t { kSML0,
                  kSML1,
                  kSML2,
                  kSMMODE,
+                 kSMCMD,
                  kNITM0,
                  kNITM1,
                  kNITM2,
@@ -455,149 +471,164 @@ class AliTRDtrapConfig : public TObject
                  kDMDELS,
                  kLastReg };   // enum of all TRAP registers, to be used for access to them
 
-  const char* GetRegName(TrapReg_t reg)       const { return reg >= 0 && reg < kLastReg ? fRegs[reg].fName.Data() : ""; }
-  UShort_t    GetRegAddress(TrapReg_t reg)    const { return reg >= 0 && reg < kLastReg ? fRegs[reg].fAddr : 0; }
-  UShort_t    GetRegNBits(TrapReg_t reg)      const { return reg >= 0 && reg < kLastReg ? fRegs[reg].fNbits : 0; }
-  UInt_t      GetRegResetValue(TrapReg_t reg) const { return reg >= 0 && reg < kLastReg ? fRegs[reg].fResetValue : 0; }
-
-  TrapReg_t          GetRegByAddress(Int_t address) const;
-
-  Int_t  GetTrapReg(TrapReg_t reg, Int_t det = -1, Int_t rob = -1, Int_t mcm = -1) const;
-  Bool_t PrintTrapReg(TrapReg_t reg, Int_t det = -1, Int_t rob = -1, Int_t mcm = -1) const;
-  Bool_t PrintTrapAddr(Int_t addr, Int_t det = -1, Int_t rob = -1, Int_t mcm = -1) const;
-
-  Bool_t SetTrapReg(TrapReg_t reg, Int_t value);
+  Bool_t SetTrapRegAlloc(TrapReg_t reg, Alloc_t mode) { return fRegisterValue[reg].Allocate(mode); }
   Bool_t SetTrapReg(TrapReg_t reg, Int_t value, Int_t det);
   Bool_t SetTrapReg(TrapReg_t reg, Int_t value, Int_t det, Int_t rob, Int_t mcm);
 
-  UInt_t Peek(Int_t addr, Int_t det, Int_t rob, Int_t mcm) const;
-  Bool_t Poke(Int_t addr, UInt_t value, Int_t det, Int_t rob, Int_t mcm);
+  Int_t  GetTrapReg(TrapReg_t reg, Int_t det = -1, Int_t rob = -1, Int_t mcm = -1) const;
 
-  void InitRegs();
   void ResetRegs();
-  void ResetDmem();
 
-  // DMEM
-  Bool_t SetDmem(Int_t addr, UInt_t value);
-  //  Bool_t SetDmem(Int_t addr, UInt_t value, Int_t det);
+  // data memory (DMEM)
+  Bool_t SetDmemAlloc(Int_t addr, Alloc_t mode);
+  Bool_t SetDmem(Int_t addr, UInt_t value, Int_t det);
   Bool_t SetDmem(Int_t addr, UInt_t value, Int_t det, Int_t rob, Int_t mcm);
   Bool_t SetDmem(Int_t addr, Int_t value) { return SetDmem(addr, (UInt_t) value); }
-  //  Bool_t SetDmem(Int_t addr, Int_t value, Int_t det) { return SetDmem(addr, (UInt_t) value, det); }
   Bool_t SetDmem(Int_t addr, Int_t value, Int_t det, Int_t rob, Int_t mcm) { return SetDmem(addr, (UInt_t) value, det, rob, mcm); }
 
-  UInt_t GetDmemUnsigned(Int_t addr) const;
   UInt_t GetDmemUnsigned(Int_t addr, Int_t det, Int_t rob, Int_t mcm) const;
 
+  void ResetDmem();
+
+  // access by 16-bit address
+  UInt_t Peek(Int_t addr, Int_t det, Int_t rob, Int_t mcm) const;
+  Bool_t Poke(Int_t addr, UInt_t value, Int_t det, Int_t rob, Int_t mcm);
+
+  // helper methods
+  const char* GetRegName(TrapReg_t reg)       const { return ((reg >= 0) && (reg < kLastReg)) ? fRegisterValue[reg].GetName() : ""; }
+  UShort_t    GetRegAddress(TrapReg_t reg)    const { return ((reg >= 0) && (reg < kLastReg)) ? fRegisterValue[reg].GetAddr() : 0; }
+  UShort_t    GetRegNBits(TrapReg_t reg)      const { return ((reg >= 0) && (reg < kLastReg)) ? fRegisterValue[reg].GetNbits() : 0; }
+  UInt_t      GetRegResetValue(TrapReg_t reg) const { return ((reg >= 0) && (reg < kLastReg)) ? fRegisterValue[reg].GetResetValue() : 0; }
+
+  TrapReg_t   GetRegByAddress(Int_t address) const;
+
+  Bool_t PrintTrapReg(TrapReg_t reg, Int_t det = -1, Int_t rob = -1, Int_t mcm = -1) const;
+  Bool_t PrintTrapAddr(Int_t addr, Int_t det = -1, Int_t rob = -1, Int_t mcm = -1) const;
+
   void PrintMemDatx(ostream &os, Int_t addr) const;
   void PrintMemDatx(ostream &os, Int_t addr, Int_t det, Int_t rob, Int_t mcm) const;
   void PrintMemDatx(ostream &os, TrapReg_t reg) const;
   void PrintMemDatx(ostream &os, TrapReg_t reg, Int_t det, Int_t rob, Int_t mcm) const;
   void PrintDatx(ostream &os, UInt_t addr, UInt_t data, Int_t rob, Int_t mcm) const;
 
-  // configuration handling
-  Bool_t ReadPackedConfig(Int_t det, UInt_t *data, Int_t size);
+  static const Int_t fgkDmemStartAddress  = 0xc000; // start address in TRAP GIO
+  static const Int_t fgkDmemWords = 0x400;          // number of words in DMEM
 
-  Bool_t AddValues(UInt_t det, UInt_t cmd, UInt_t extali, Int_t addr, UInt_t data);
+  static const Int_t fgkImemStartAddress = 0xe000;  // start address in TRAP GIO
+  static const Int_t fgkImemWords = 0x1000;         // number of words in IMEM
 
-  // DMEM addresses
-  static const Int_t fgkDmemAddrLUTcor0       = 0xC02A; // address for correction factor 0
-  static const Int_t fgkDmemAddrLUTcor1       = 0xC028; // address for correction factor 1
-  static const Int_t fgkDmemAddrLUTnbins      = 0xC029; // address for number of timebins
+  static const Int_t fgkDbankStartAddress = 0xf000; // start address in TRAP GIO
+  static const Int_t fgkDbankWords = 0x0100;        // number of words in DBANK
 
-  static const Int_t fgkDmemAddrLUTStart      = 0xC100; // LUT start address
-  static const Int_t fgkDmemAddrLUTEnd        = 0xC3FF; // maximum possible end address for the LUT table
-  static const Int_t fgkDmemAddrLUTLength     = 0xC02B; // address where real size of the LUT table is stored
+ protected:
+  void InitRegs();
 
-  static const Int_t fgkDmemAddrTrackletStart = 0xC0E0; // Storage area for tracklets, start address
-  static const Int_t fgkDmemAddrTrackletEnd   = 0xC0E3; // Storage area for tracklets, end address
+  class AliTRDtrapValue : public TObject {
+  public:
+    AliTRDtrapValue();
+    virtual ~AliTRDtrapValue() {}
 
-  static const Int_t fgkDmemAddrDeflCorr      = 0xc022; // DMEM address of deflection correction
-  static const Int_t fgkDmemAddrNdrift        = 0xc025; // DMEM address of Ndrift
-  static const Int_t fgkDmemAddrDeflCutStart  = 0xc030; // DMEM start address of deflection cut
-  static const Int_t fgkDmemAddrDeflCutEnd    = 0xc055; // DMEM end address of deflection cut
+    virtual Bool_t Allocate(Alloc_t mode);
 
-  // DMEM memory in simulation;
-  static const Int_t fgkDmemStartAddress;           // start address in TRAP GIO
-  static const Int_t fgkDmemWords = 0xc400;         // number of words in DMEM
+  protected:
+    Bool_t SetData(Int_t value);
+    Bool_t SetData(Int_t value, Int_t det);
+    Bool_t SetData(Int_t value, Int_t det, Int_t rob, Int_t mcm);
 
- protected:
-  static AliTRDtrapConfig *fgInstance;  // pointer to instance (singleton)
-
-  struct SimpleReg_t {
-    TString   fName;       // Name of the register
-    UShort_t  fAddr;       // Address in GIO of TRAP
-    UShort_t  fNbits;      // Number of bits, from 1 to 32
-    UInt_t    fResetValue; // reset value
-    SimpleReg_t(const char *nnn = 0, UShort_t a = 0, UShort_t n = 0, UInt_t r = 0) :
-      fName(nnn), fAddr(a), fNbits(n), fResetValue(r) {}
-  };
+    Int_t  GetData(Int_t det, Int_t rob, Int_t mcm) const;
+
+    Int_t  GetIdx(Int_t det, Int_t rob, Int_t mcm) const;
+
+  private:
+    AliTRDtrapValue(const AliTRDtrapValue &rhs); // not implemented
+    AliTRDtrapValue& operator=(const AliTRDtrapValue &rhs); // not implemented
+
+    Alloc_t  fAllocMode;       // allocation mode
+    Int_t    fSize;            // array size
+    UInt_t  *fData;            //[fSize] data array
+    Bool_t  *fValid;           //[fSize] valid flag
 
-  struct RegValue_t {
-    enum {
-      kInvalid = 0,
-      kGlobal,
-      kIndividual
-    } state; // mode of storage (global or per MCM)
-    union {
-      Int_t globalValue;
-      Int_t *individualValue;
-    };
+    static const Int_t fgkSize[kAllocLast]; // required array dimension for different allocation modes
+
+    ClassDef(AliTRDtrapValue, 1);
   };
 
-  // configuration registers
-  SimpleReg_t fRegs[kLastReg];          // array of TRAP registers
-  RegValue_t fRegisterValue[kLastReg];  // array of TRAP register values in use
+  class AliTRDtrapRegister : public AliTRDtrapValue {
+  public:
+    AliTRDtrapRegister();
+    virtual ~AliTRDtrapRegister();
 
-  static const UInt_t fgkScsnCmdWrite=10;  // Command number for the write command
-  static const Int_t fgkMaxLinkPairs=4;    // number of linkpairs used during configuration
-  static const Int_t fgkMaxMcm;            // max. no. of MCMs to be treated
-  static const Int_t fgkMcmlistSize=256;     // list of MCMs to which a value has to be written
+    void    Init(const char* name, Int_t addr, Int_t nBits, Int_t resetValue);
+    void    Reset() { SetData(fResetValue); }
 
-  // DMEM
-  UInt_t* fDmem[fgkDmemWords]; // DMEM storage
-  Int_t fDmemDepth[fgkDmemWords]; // memory space indicator for fDmem
-
-  static const Int_t fgkDmemSizeEmpty=0; // size if no value stored
-  static const   Int_t fgkDmemSizeUniform = 1; // size for global values
-  static const   Int_t fgkDmemSizeSmIndividual = 30*8*16;   // storage for each MCM within one supermodule
-  static const   Int_t fgkDmemSizeTotalIndividual = 540*6*8*16;  // one individual value for each and every MCM in the TRD
-  static const   Int_t fgkDmemSizeSmRocIndividual = 540; // one individual value for each chamber in TRD
-
-  // Online PID
-  Double_t fScaleQ0;  // scaling factor for the x-axis of the PID table
-  Double_t fScaleQ1;  // scaling factor for the y-axis of the PID table
-
-  AliTRDtrapConfig(); // private constructor due to singleton implementation
-
-/* not yet used
-  struct BlockDescr_t {
-    UShort_t addr;
-    UShort_t nregs;
-    UShort_t nbits;
-    UShort_t step;
+    Bool_t  SetValue(Int_t value, Int_t det) { return SetData(value, det); }
+    Bool_t  SetValue(Int_t value, Int_t det, Int_t rob, Int_t mcm) { return SetData(value, det, rob, mcm); }
+
+    Int_t   GetValue(Int_t det, Int_t rob, Int_t mcm) const { return GetData(det, rob, mcm); }
+
+    const char*  GetName() const { return fName.Data(); }
+    UShort_t GetAddr() const { return fAddr; }
+    UShort_t GetNbits() const { return fNbits; }
+    UInt_t   GetResetValue() const { return fResetValue; }
+
+  protected:
+    AliTRDtrapRegister(const AliTRDtrapRegister &rhs);
+    AliTRDtrapRegister& operator=(const AliTRDtrapRegister &rhs);
+
+    // fixed properties of the register
+    // which do not need to be stored
+    TString   fName;            //! Name of the register
+    UShort_t  fAddr;            //! Address in GIO of TRAP
+    UShort_t  fNbits;           //! Number of bits, from 1 to 32
+    UInt_t    fResetValue;      //! reset value
+
+    ClassDef(AliTRDtrapRegister, 1);
   };
 
-  struct CmdReg_t {
-    char *name;
-    UShort_t addr;
+  class AliTRDtrapDmemWord : public AliTRDtrapValue {
+  public:
+    AliTRDtrapDmemWord() : AliTRDtrapValue(), fName(""), fAddr(0) {}
+    virtual ~AliTRDtrapDmemWord() {}
+
+    void    Reset() { SetData(0); }
+
+    Bool_t  SetValue(UInt_t value, Int_t det) { return SetData(value, det); }
+    Bool_t  SetValue(UInt_t value, Int_t det, Int_t rob, Int_t mcm) { return SetData(value, det, rob, mcm); }
+
+    UInt_t  GetValue(Int_t det, Int_t rob, Int_t mcm) const { return GetData(det, rob, mcm); }
+
+    void    SetAddress(UShort_t addr) { fAddr = addr; fName.Form("DMEM 0x%04x", fAddr); }
+    const char* GetName() const { return fName.Data(); }
+
+  protected:
+    AliTRDtrapDmemWord(const AliTRDtrapDmemWord &rhs); // not implemented
+    AliTRDtrapDmemWord& operator=(const AliTRDtrapDmemWord &rhs); // not implemented
+
+    TString  fName;
+    UShort_t fAddr;            //! address
+
+    ClassDef(AliTRDtrapDmemWord, 1);
   };
 
-  enum DbankProp_t { kDBankEmpty = 0,
-                   kDBankHeader,
-                   kDBankData,
-                   kDBankNoB,
-                   kDBankCRC,
-                   kDBankEHeader,
-                   kDBankSCSNData };
-*/
+  // configuration registers
+  AliTRDtrapRegister fRegisterValue[kLastReg];  // array of TRAP register values in use
 
+  // DMEM
+  AliTRDtrapDmemWord fDmem[fgkDmemWords]; // TRAP data memory
+
+  static const Int_t fgkMaxMcm;            // max. no. of MCMs to be treated
+  static const Int_t fgkMcmlistSize=256;     // list of MCMs to which a value has to be written
+
+  static Bool_t    fgRegAddressMapInitialized;
+  static TrapReg_t fgRegAddressMap[0x400 + 0x200 + 0x3];
+  static const Int_t fgkRegisterAddressBlockStart[];
+  static const Int_t fgkRegisterAddressBlockSize[];
 
  private:
   AliTRDtrapConfig& operator=(const AliTRDtrapConfig &rhs); // not implemented
   AliTRDtrapConfig(const AliTRDtrapConfig& cfg); // not implemented
 
-  ClassDef(AliTRDtrapConfig, 2);
+  ClassDef(AliTRDtrapConfig, 3);
 };
 
 #endif
-
index 2af3857..cfbd0ec 100644 (file)
@@ -29,7 +29,9 @@
 
 #include "AliLog.h"
 
+#include "AliTRDfeeParam.h"
 #include "AliTRDtrapConfig.h"
+#include "AliTRDmcmSim.h"
 #include "AliTRDgeometry.h"
 #include "AliTRDcalibDB.h"
 
 
 using namespace std;
 
-ClassImp(AliTRDtrapConfigHandler)
+AliTRDtrapConfig* AliTRDtrapConfigHandler::fgActiveTrapConfig = 0x0;
 
-AliTRDtrapConfigHandler::AliTRDtrapConfigHandler() :
+AliTRDtrapConfigHandler::AliTRDtrapConfigHandler(AliTRDtrapConfig *cfg) :
      ltuParam()
      , fRestrictiveMask((0x3ffff << 11) | (0x1f << 6) | 0x3f)
+     , fTrapConfig(cfg)
      , fGtbl()
 {
 
@@ -59,15 +62,72 @@ AliTRDtrapConfigHandler::~AliTRDtrapConfigHandler()
 
 }
 
+void AliTRDtrapConfigHandler::Init()
+{
+  if (!fTrapConfig) {
+    AliError("No TRAPconfig given");
+    return;
+  }
+
+  // setup of register allocation
+  // I/O configuration which we don't care about
+  fTrapConfig->SetTrapRegAlloc(AliTRDtrapConfig::kSEBDOU, AliTRDtrapConfig::kAllocNone);
+  // position look-up table by layer
+  for (Int_t iBin = 0; iBin < 128; iBin++)
+    fTrapConfig->SetTrapRegAlloc((AliTRDtrapConfig::TrapReg_t) (AliTRDtrapConfig::kTPL00 + iBin), AliTRDtrapConfig::kAllocByLayer);
+  // ... individual
+  fTrapConfig->SetTrapRegAlloc(AliTRDtrapConfig::kC14CPUA, AliTRDtrapConfig::kAllocByMCM);
+  fTrapConfig->SetTrapRegAlloc(AliTRDtrapConfig::kC15CPUA, AliTRDtrapConfig::kAllocByMCM);
+
+  // setup of DMEM allocation
+  for(Int_t iAddr = AliTRDtrapConfig::fgkDmemStartAddress;
+            iAddr < (AliTRDtrapConfig::fgkDmemWords + AliTRDtrapConfig::fgkDmemStartAddress); iAddr++) {
+
+    if(iAddr == AliTRDmcmSim::fgkDmemAddrDeflCorr)
+      fTrapConfig->SetDmemAlloc(iAddr, AliTRDtrapConfig::kAllocByMCMinSM);
+
+    else if(iAddr == AliTRDmcmSim::fgkDmemAddrNdrift)
+      fTrapConfig->SetDmemAlloc(iAddr, AliTRDtrapConfig::kAllocByDetector);
+
+    else if((iAddr >= AliTRDmcmSim::fgkDmemAddrDeflCutStart) && (iAddr <= AliTRDmcmSim::fgkDmemAddrDeflCutEnd))
+      fTrapConfig->SetDmemAlloc(iAddr, AliTRDtrapConfig::kAllocByMCMinSM);
+
+    else if((iAddr >= AliTRDmcmSim::fgkDmemAddrTrackletStart) && (iAddr <= AliTRDmcmSim::fgkDmemAddrTrackletEnd))
+      fTrapConfig->SetDmemAlloc(iAddr, AliTRDtrapConfig::kAllocByMCM);
+
+    else if((iAddr >= AliTRDmcmSim::fgkDmemAddrLUTStart) && (iAddr <= AliTRDmcmSim::fgkDmemAddrLUTEnd))
+      fTrapConfig->SetDmemAlloc(iAddr, AliTRDtrapConfig::kAllocGlobal);
+
+    else if(iAddr == AliTRDmcmSim::fgkDmemAddrLUTcor0)
+      fTrapConfig->SetDmemAlloc(iAddr, AliTRDtrapConfig::kAllocByMCMinSM);
+
+    else if(iAddr == AliTRDmcmSim::fgkDmemAddrLUTcor1)
+      fTrapConfig->SetDmemAlloc(iAddr, AliTRDtrapConfig::kAllocByMCMinSM);
+
+    else if(iAddr == AliTRDmcmSim::fgkDmemAddrLUTnbins)
+      fTrapConfig->SetDmemAlloc(iAddr, AliTRDtrapConfig::kAllocGlobal);
+
+    else if(iAddr == AliTRDmcmSim::fgkDmemAddrLUTLength)
+      fTrapConfig->SetDmemAlloc(iAddr, AliTRDtrapConfig::kAllocGlobal);
+
+    else
+      fTrapConfig->SetDmemAlloc(iAddr, AliTRDtrapConfig::kAllocGlobal);
+  }
+}
+
 void AliTRDtrapConfigHandler::ResetMCMs()
 {
    //
    // Reset all MCM registers and DMEM
    //
 
-   AliTRDtrapConfig *cfg = AliTRDtrapConfig::Instance();
-   cfg->ResetRegs();
-   cfg->ResetDmem();
+  if (!fTrapConfig) {
+    AliError("No TRAPconfig given");
+    return;
+  }
+
+   fTrapConfig->ResetRegs();
+   fTrapConfig->ResetDmem();
 }
 
 
@@ -77,48 +137,12 @@ Int_t AliTRDtrapConfigHandler::LoadConfig()
   // for a detailed description of the registers see the TRAP manual
   // if you want to resimulate tracklets on real data use the appropriate config instead
 
-  AliTRDtrapConfig *cfg = AliTRDtrapConfig::Instance();
-
-  // HC header configuration bits
-  cfg->SetTrapReg(AliTRDtrapConfig::kC15CPUA, 0x2102); // zs, deh
-
-  // no. of timebins
-  cfg->SetTrapReg(AliTRDtrapConfig::kC13CPUA, 24);
-
-  // pedestal filter
-  cfg->SetTrapReg(AliTRDtrapConfig::kFPNP, 4*10);
-  cfg->SetTrapReg(AliTRDtrapConfig::kFPTC, 0);
-  cfg->SetTrapReg(AliTRDtrapConfig::kFPBY, 0); // bypassed!
-
-  // gain filter
-  for (Int_t adc = 0; adc < 20; adc++) {
-    cfg->SetTrapReg(AliTRDtrapConfig::TrapReg_t(AliTRDtrapConfig::kFGA0+adc), 40);
-    cfg->SetTrapReg(AliTRDtrapConfig::TrapReg_t(AliTRDtrapConfig::kFGF0+adc), 15);
+  if (!fTrapConfig) {
+    AliError("No TRAPconfig given");
+    return -1;
   }
-  cfg->SetTrapReg(AliTRDtrapConfig::kFGTA, 20);
-  cfg->SetTrapReg(AliTRDtrapConfig::kFGTB, 2060);
-  cfg->SetTrapReg(AliTRDtrapConfig::kFGBY, 0);  // bypassed!
-
-  // tail cancellation
-  cfg->SetTrapReg(AliTRDtrapConfig::kFTAL, 200);
-  cfg->SetTrapReg(AliTRDtrapConfig::kFTLL, 0);
-  cfg->SetTrapReg(AliTRDtrapConfig::kFTLS, 200);
-  cfg->SetTrapReg(AliTRDtrapConfig::kFTBY, 0);
-
-  // tracklet calculation
-  cfg->SetTrapReg(AliTRDtrapConfig::kTPQS0, 5);
-  cfg->SetTrapReg(AliTRDtrapConfig::kTPQE0, 10);
-  cfg->SetTrapReg(AliTRDtrapConfig::kTPQS1, 11);
-  cfg->SetTrapReg(AliTRDtrapConfig::kTPQE1, 20);
-  cfg->SetTrapReg(AliTRDtrapConfig::kTPFS, 5);
-  cfg->SetTrapReg(AliTRDtrapConfig::kTPFE, 20);
-  cfg->SetTrapReg(AliTRDtrapConfig::kTPVBY, 0);
-  cfg->SetTrapReg(AliTRDtrapConfig::kTPVT, 10);
-  cfg->SetTrapReg(AliTRDtrapConfig::kTPHT, 150);
-  cfg->SetTrapReg(AliTRDtrapConfig::kTPFP, 40);
-  cfg->SetTrapReg(AliTRDtrapConfig::kTPCL, 1);
-  cfg->SetTrapReg(AliTRDtrapConfig::kTPCT, 10);
 
+  // prepare ltuParam
   // ndrift (+ 5 binary digits)
   ltuParam.SetNtimebins(20 << 5);
   // deflection + tilt correction
@@ -134,12 +158,64 @@ Int_t AliTRDtrapConfigHandler::LoadConfig()
   ltuParam.SetRawLengthCorrectionEnable(kFALSE);
   ltuParam.SetRawTiltCorrectionEnable(kFALSE);
 
-  // apply ltuParams to all detectors
-  for(Int_t det=0; det<AliTRDgeometry::Ndet(); det++) {
-     ConfigureDyCorr(det);
-     ConfigureDRange(det); // deflection range
-     ConfigureNTimebins(det);  // timebins in the drift region
-     ConfigurePIDcorr(det);  // scaling parameters for the PID
+  for (Int_t iDet = 0; iDet < 540; iDet++) {
+    // HC header configuration bits
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kC15CPUA, 0x2102, iDet); // zs, deh
+
+    // no. of timebins
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kC13CPUA, 24, iDet);
+
+    // pedestal filter
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kFPNP, 4*10, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kFPTC, 0, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kFPBY, 0, iDet); // bypassed!
+
+    // gain filter
+    for (Int_t adc = 0; adc < 20; adc++) {
+      fTrapConfig->SetTrapReg(AliTRDtrapConfig::TrapReg_t(AliTRDtrapConfig::kFGA0+adc), 40, iDet);
+      fTrapConfig->SetTrapReg(AliTRDtrapConfig::TrapReg_t(AliTRDtrapConfig::kFGF0+adc), 15, iDet);
+    }
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kFGTA, 20, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kFGTB, 2060, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kFGBY, 0, iDet);  // bypassed!
+
+    // tail cancellation
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kFTAL, 200, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kFTLL, 0, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kFTLS, 200, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kFTBY, 0, iDet);
+
+    // tracklet calculation
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kTPQS0, 5, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kTPQE0, 10, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kTPQS1, 11, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kTPQE1, 20, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kTPFS, 5, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kTPFE, 20, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kTPVBY, 0, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kTPVT, 10, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kTPHT, 150, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kTPFP, 40, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kTPCL, 1, iDet);
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kTPCT, 10, iDet);
+
+    // apply ltuParams
+    ConfigureDyCorr(iDet);
+    ConfigureDRange(iDet); // deflection range
+    ConfigureNTimebins(iDet);  // timebins in the drift region
+    ConfigurePIDcorr(iDet);  // scaling parameters for the PID
+
+    // event buffer
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kEBSF, 1, iDet);  // 0: store filtered; 1: store unfiltered
+
+    // zs applied to data stored in event buffer (sel. by EBSF)
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kEBIS, 15 << 2, iDet); // single indicator threshold (plus two digits)
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kEBIT, 30 << 2, iDet); // sum indicator threshold (plus two digits)
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kEBIL, 0xf0, iDet);   // lookup table
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kEBIN, 0, iDet);      // neighbour sensitivity
+
+    // raw data
+    fTrapConfig->SetTrapReg(AliTRDtrapConfig::kNES, (0x0000 << 16) | 0x1000, iDet);
   }
 
   // ****** hit position LUT
@@ -151,9 +227,6 @@ Int_t AliTRDtrapConfigHandler::LoadConfig()
   Double_t padResponseR[3]; // pad response left, central, right
   Double_t padResponseL[3]; // pad response left, central, right
 
-  for (Int_t iBin = 0; iBin < 128; iBin++)
-    cfg->SetTrapReg((AliTRDtrapConfig::TrapReg_t) (AliTRDtrapConfig::kTPL00 + iBin), 0, 0, 0, 0);
-
   for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
     TGraph gr(128);
     for (Int_t iBin = 0; iBin < 256*0.5; iBin++) {
@@ -169,24 +242,12 @@ Int_t AliTRDtrapConfigHandler::LoadConfig()
       else if (corr > 31)
         corr = 31;
       for (Int_t iStack = 0; iStack < 540/6; iStack++) {
-        cfg->SetTrapReg((AliTRDtrapConfig::TrapReg_t) (AliTRDtrapConfig::kTPL00 + iBin), corr, 6*iStack + iLayer);
+        fTrapConfig->SetTrapReg((AliTRDtrapConfig::TrapReg_t) (AliTRDtrapConfig::kTPL00 + iBin), corr, 6*iStack + iLayer);
       }
     }
   }
   // ****** hit position LUT configuration end
 
-  // event buffer
-  cfg->SetTrapReg(AliTRDtrapConfig::kEBSF, 1);  // 0: store filtered; 1: store unfiltered
-
-  // zs applied to data stored in event buffer (sel. by EBSF)
-  cfg->SetTrapReg(AliTRDtrapConfig::kEBIS, 15 << 2); // single indicator threshold (plus two digits)
-  cfg->SetTrapReg(AliTRDtrapConfig::kEBIT, 30 << 2); // sum indicator threshold (plus two digits)
-  cfg->SetTrapReg(AliTRDtrapConfig::kEBIL, 0xf0);   // lookup table
-  cfg->SetTrapReg(AliTRDtrapConfig::kEBIN, 0);      // neighbour sensitivity
-
-  // raw data
-  cfg->SetTrapReg(AliTRDtrapConfig::kNES, (0x0000 << 16) | 0x1000);
-
   return 0;
 }
 
@@ -201,13 +262,16 @@ Int_t AliTRDtrapConfigHandler::LoadConfig(TString filename)
    // which are two tools to inspect/export configurations from wingDB
    //
 
+  if (!fTrapConfig) {
+    AliError("No TRAPconfig given");
+    return -1;
+  }
+
    Int_t ignoredLines=0;
    Int_t ignoredCmds=0;
    Int_t readLines=0;
 
 
-   AliTRDtrapConfig *cfg = AliTRDtrapConfig::Instance();
-
    AliDebug(5, Form("Processing file %s", filename.Data()));
    std::ifstream infile;
    infile.open(filename.Data(), std::ifstream::in);
@@ -242,7 +306,7 @@ Int_t AliTRDtrapConfigHandler::LoadConfig(TString filename)
               AliDebug(1, Form("checking restriction: mask=0x%08x, rocpos=0x%08x", fRestrictiveMask, rocpos));
               if ((fRestrictiveMask & rocpos) == rocpos) {
                 AliDebug(1, Form("match: %i %i %i %i", cmd, extali, addr, data));
-                 cfg->AddValues(det, cmd, extali, addr, data);
+                 AddValues(det, cmd, extali, addr, data);
               }
            }
         }
@@ -258,7 +322,7 @@ Int_t AliTRDtrapConfigHandler::LoadConfig(TString filename)
 
         else if((cmd == fgkScsnCmdReset) ||
                 (cmd == fgkScsnCmdRobReset)) {
-          cfg->ResetRegs();
+          fTrapConfig->ResetRegs();
         }
 
         else if (cmd == fgkScsnCmdSetHC) {
@@ -269,17 +333,17 @@ Int_t AliTRDtrapConfigHandler::LoadConfig(TString filename)
 
             for (Int_t iRob = 0; iRob < 8; iRob++) {
               // HC mergers
-              cfg->SetTrapReg(AliTRDtrapConfig::kC14CPUA, 0xc << 16, iDet, iRob, 17);
-              cfg->SetTrapReg(AliTRDtrapConfig::kC15CPUA, ((1<<29) | (fullVersion<<15) | (1<<12) | (smls<<1) | (iRob%2)), iDet, iRob, 17);
+              fTrapConfig->SetTrapReg(AliTRDtrapConfig::kC14CPUA, 0xc << 16, iDet, iRob, 17);
+              fTrapConfig->SetTrapReg(AliTRDtrapConfig::kC15CPUA, ((1<<29) | (fullVersion<<15) | (1<<12) | (smls<<1) | (iRob%2)), iDet, iRob, 17);
 
               // board mergers
-              cfg->SetTrapReg(AliTRDtrapConfig::kC14CPUA, 0, iDet, iRob, 16);
-              cfg->SetTrapReg(AliTRDtrapConfig::kC15CPUA, ((1<<29) | (fullVersion<<15) | (1<<12) | (smls<<1) | (iRob%2)), iDet, iRob, 16);
+              fTrapConfig->SetTrapReg(AliTRDtrapConfig::kC14CPUA, 0, iDet, iRob, 16);
+              fTrapConfig->SetTrapReg(AliTRDtrapConfig::kC15CPUA, ((1<<29) | (fullVersion<<15) | (1<<12) | (smls<<1) | (iRob%2)), iDet, iRob, 16);
 
               // and now for the others
               for (Int_t iMcm = 0; iMcm < 16; iMcm++) {
-                cfg->SetTrapReg(AliTRDtrapConfig::kC14CPUA, iMcm | (iRob << 4) | (3 << 16), iDet, iRob, iMcm);
-                cfg->SetTrapReg(AliTRDtrapConfig::kC15CPUA, ((1<<29) | (fullVersion<<15) | (1<<12) | (smls<<1) | (iRob%2)), iDet, iRob, iMcm);
+                fTrapConfig->SetTrapReg(AliTRDtrapConfig::kC14CPUA, iMcm | (iRob << 4) | (3 << 16), iDet, iRob, iMcm);
+                fTrapConfig->SetTrapReg(AliTRDtrapConfig::kC15CPUA, ((1<<29) | (fullVersion<<15) | (1<<12) | (smls<<1) | (iRob%2)), iDet, iRob, iMcm);
               }
             }
           }
@@ -381,7 +445,13 @@ void AliTRDtrapConfigHandler::ConfigureNTimebins(Int_t det)
    //
    // Set timebins in the drift region
    //
-  AliTRDtrapConfig::Instance()->AddValues(det, fgkScsnCmdWrite, 127, AliTRDtrapConfig::fgkDmemAddrNdrift, ltuParam.GetNtimebins());
+
+  if (!fTrapConfig) {
+    AliError("No TRAPconfig given");
+    return;
+  }
+
+  AddValues(det, fgkScsnCmdWrite, 127, AliTRDmcmSim::fgkDmemAddrNdrift, ltuParam.GetNtimebins());
 }
 
 
@@ -394,13 +464,18 @@ void AliTRDtrapConfigHandler::ConfigureDyCorr(Int_t det)
    //  This correction is in units of padwidth / (256*32)
    //
 
+  if (!fTrapConfig) {
+    AliError("No TRAPconfig given");
+    return;
+  }
+
    Int_t nRobs = AliTRDgeometry::GetStack(det) == 2 ? 6 : 8;
 
   for (Int_t r = 0; r < nRobs; r++) {
     for (Int_t m = 0; m < 16; m++) {
       Int_t dest =  1<<10 | r<<7 | m;
       Int_t dyCorrInt = ltuParam.GetDyCorrection(det, r, m);
-      AliTRDtrapConfig::Instance()->AddValues(det, fgkScsnCmdWrite, dest, AliTRDtrapConfig::fgkDmemAddrDeflCorr, dyCorrInt);
+      AddValues(det, fgkScsnCmdWrite, dest, AliTRDmcmSim::fgkDmemAddrDeflCorr, dyCorrInt);
     }
   }
 }
@@ -418,6 +493,11 @@ void AliTRDtrapConfigHandler::ConfigureDRange(Int_t det)
    // deflection (-64..63) is used
    //
 
+  if (!fTrapConfig) {
+    AliError("No TRAPconfig given");
+    return;
+  }
+
   Int_t nRobs = AliTRDgeometry::GetStack(det) == 2 ? 6 : 8;
 
   Int_t dyMinInt;
@@ -431,10 +511,10 @@ void AliTRDtrapConfigHandler::ConfigureDRange(Int_t det)
           // cout << "r " << r << ", m" << m << ", c " << c << ", min angle: " << localPhi-maxDeflAngle << ", max: " << localPhi+maxDeflAngle
           //   << ", min int: " << dyMinInt << ", max int: " << dyMaxInt << endl;
           Int_t dest =  1<<10 | r<<7 | m;
-          Int_t lutAddr = AliTRDtrapConfig::fgkDmemAddrDeflCutStart + 2*c;
+          Int_t lutAddr = AliTRDmcmSim::fgkDmemAddrDeflCutStart + 2*c;
           ltuParam.GetDyRange(det, r, m, c, dyMinInt, dyMaxInt);
-          AliTRDtrapConfig::Instance()->AddValues(det, fgkScsnCmdWrite, dest, lutAddr+0, dyMinInt);
-          AliTRDtrapConfig::Instance()->AddValues(det, fgkScsnCmdWrite, dest, lutAddr+1, dyMaxInt);
+          AddValues(det, fgkScsnCmdWrite, dest, lutAddr+0, dyMinInt);
+          AddValues(det, fgkScsnCmdWrite, dest, lutAddr+1, dyMaxInt);
         }
       }
    }
@@ -475,8 +555,13 @@ void AliTRDtrapConfigHandler::ConfigurePIDcorr(Int_t det)
    // and transfer them to AliTRDtrapConfig
    //
 
-   static const Int_t addrLUTcor0 = AliTRDtrapConfig::fgkDmemAddrLUTcor0;
-   static const Int_t addrLUTcor1 = AliTRDtrapConfig::fgkDmemAddrLUTcor1;
+  if (!fTrapConfig) {
+    AliError("No TRAPconfig given");
+    return;
+  }
+
+   static const Int_t addrLUTcor0 = AliTRDmcmSim::fgkDmemAddrLUTcor0;
+   static const Int_t addrLUTcor1 = AliTRDmcmSim::fgkDmemAddrLUTcor1;
 
    UInt_t cor0;
    UInt_t cor1;
@@ -490,8 +575,85 @@ void AliTRDtrapConfigHandler::ConfigurePIDcorr(Int_t det)
            ltuParam.GetCorrectionFactors(det, r, m, 9, cor0, cor1, fGtbl.GetGainTableROC(det)->GetGainTableMCM(r, m)->GetMCMGain());
         else
            ltuParam.GetCorrectionFactors(det, r, m, 9, cor0, cor1);
-        AliTRDtrapConfig::Instance()->AddValues(det, fgkScsnCmdWrite, dest, addrLUTcor0, cor0);
-        AliTRDtrapConfig::Instance()->AddValues(det, fgkScsnCmdWrite, dest, addrLUTcor1, cor1);
+        AddValues(det, fgkScsnCmdWrite, dest, addrLUTcor0, cor0);
+        AddValues(det, fgkScsnCmdWrite, dest, addrLUTcor1, cor1);
     }
   }
 }
+
+
+Bool_t AliTRDtrapConfigHandler::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 (!fTrapConfig) {
+    AliError("No TRAPconfig given");
+    return kFALSE;
+  }
+
+  if(cmd != fgkScsnCmdWrite) {
+    AliError(Form("Invalid command received: %i", cmd));
+    return kFALSE;
+  }
+
+  AliTRDtrapConfig::TrapReg_t mcmReg = fTrapConfig->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 < AliTRDtrapConfig::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) {
+           AliDebug(1, Form("broadcast write to %s: 0x%08x",
+                            fTrapConfig->GetRegName((AliTRDtrapConfig::TrapReg_t) mcmReg), data));
+            fTrapConfig->SetTrapReg( (AliTRDtrapConfig::TrapReg_t) mcmReg, data, det);
+         }
+          else {
+           AliDebug(1, Form("individual write to %s (%i, %i): 0x%08x",
+                            fTrapConfig->GetRegName((AliTRDtrapConfig::TrapReg_t) mcmReg), (mcmList[i]>>7), (mcmList[i]&0x7F), data));
+            fTrapConfig->SetTrapReg( (AliTRDtrapConfig::TrapReg_t) mcmReg, data, det, (mcmList[i]>>7)&0x7, (mcmList[i]&0x7F));
+         }
+          i++;
+        }
+      }
+    }
+    return kTRUE;
+  }
+  // DMEM
+  else if ( (addr >= AliTRDtrapConfig::fgkDmemStartAddress) &&
+           (addr < (AliTRDtrapConfig::fgkDmemStartAddress + AliTRDtrapConfig::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)
+            fTrapConfig->SetDmem(addr, data, det, 0, 127);
+          else
+            fTrapConfig->SetDmem(addr, data, det, mcmList[i] >> 7, mcmList[i] & 0x7f);
+          i++;
+        }
+      }
+    }
+    return kTRUE;
+  }
+  else if ( (addr >= AliTRDtrapConfig::fgkImemStartAddress) &&
+           (addr < (AliTRDtrapConfig::fgkImemStartAddress + AliTRDtrapConfig::fgkImemWords))) {
+    // IMEM is ignored for now
+    ;
+  }
+  else if ( (addr >= AliTRDtrapConfig::fgkDbankStartAddress) &&
+           (addr < (AliTRDtrapConfig::fgkDbankStartAddress + AliTRDtrapConfig::fgkImemWords))) {
+    // DBANK is ignored for now
+    ;
+  }
+  else {
+    AliError(Form("Writing to unhandled address 0x%04x", addr));
+    return kFALSE;
+  }
+}
index 2e9d251..68598be 100644 (file)
 #include <TObject.h>
 #include "AliTRDltuParam.h"
 #include "AliTRDCalOnlineGainTable.h"
-
-class AliTRDtrapConfig;
+#include "AliTRDtrapConfig.h"
 
 class AliTRDtrapConfigHandler : public TObject {
  public:
-                    AliTRDtrapConfigHandler();
+                    AliTRDtrapConfigHandler(AliTRDtrapConfig *cfg);
   virtual          ~AliTRDtrapConfigHandler();
 
+  void Init();                                                // Set DMEM allocation modes
   void ResetMCMs();                                           // Reset all trap registers and DMEM of the MCMs
   Int_t LoadConfig();                                         // load a default configuration suitable for simulation
   Int_t LoadConfig(TString filename);                         // load a TRAP configuration from a file
@@ -33,6 +33,8 @@ class AliTRDtrapConfigHandler : public TObject {
   // Int_t poke(Int_t rob, Int_t mcm, Int_t addr, UInt_t value);   // not implemented yet
 
  private:
+  Bool_t AddValues(UInt_t det, UInt_t cmd, UInt_t extali, Int_t addr, UInt_t data);
+
   void  ConfigureDyCorr(Int_t det);                             // deflection length correction due to Lorentz angle and tilted pad correction
   void  ConfigureDRange(Int_t det);                             // deflection range LUT,  range calculated according to B-field (in T) and pt_min (in GeV/c)
   void  ConfigureNTimebins(Int_t det);                          // timebins in the drift region
@@ -64,12 +66,36 @@ class AliTRDtrapConfigHandler : public TObject {
   static const Int_t fgkPadsPerMCM = 18;   // readout pads per MCM
   static const Int_t fgkMCMperROBRow = 4;  // MCMs per ROB row
 
+  static const Int_t fgkMaxLinkPairs=4;    // number of linkpairs used during configuration
+  static const Int_t fgkMcmlistSize=256;     // list of MCMs to which a value has to be written
+
   AliTRDltuParam     ltuParam;             // ltuParam class for the actual calculation of the parameters
 
   UInt_t fRestrictiveMask;                 // mask to restrict subsequent commands to specified chambers
 
+  AliTRDtrapConfig *fTrapConfig;           // pointer to TRAP config in use
   AliTRDCalOnlineGainTable fGtbl;          // gain table
 
+  // to be moved to AliTRDcalibDB:
+public:
+  static AliTRDtrapConfig* GetTrapConfig() {
+    if (fgActiveTrapConfig) {
+      printf("returning existing TRAP config\n");
+      return fgActiveTrapConfig;
+    }
+    else {
+      printf("creating new TRAP config\n");
+      fgActiveTrapConfig = new AliTRDtrapConfig();
+      AliTRDtrapConfigHandler cfgHandler(fgActiveTrapConfig);
+      cfgHandler.Init();
+      cfgHandler.LoadConfig();
+      return fgActiveTrapConfig;
+    }
+  }
+  // static void SetTrapConfig(AliTRDtrapConfig *trapcfg) { fgActiveTrapConfig = trapcfg; }
+protected:
+  static AliTRDtrapConfig* fgActiveTrapConfig;
+
   ClassDef(AliTRDtrapConfigHandler,0)
 };
 
index 69b9987..a167919 100644 (file)
@@ -91,6 +91,9 @@
 #pragma link C++ class  AliTRDtrapConfigHandler+;
 #pragma link C++ class  AliTRDltuParam+;
 #pragma link C++ class  AliTRDtrapConfig+;
+#pragma link C++ class  AliTRDtrapConfig::AliTRDtrapValue+;
+#pragma link C++ class  AliTRDtrapConfig::AliTRDtrapRegister+;
+#pragma link C++ class  AliTRDtrapConfig::AliTRDtrapDmemWord+;
 #pragma link C++ class  AliTRDtrackletBase+;
 #pragma link C++ class  AliTRDtrackletGTU+;
 #pragma link C++ class  AliTRDtrackletMCM+;