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