+ 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!