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