///////////////////////////////////////////////////////////////////// // USBPixController.cxx ///////////////////////////////////////////////////////////////////// // // 10/11/08 Version 0.0 // 03/09/09 Version 1.0 for USBPix tutorial // Author: Jens Weingarten // // This is the PixController class for the Bonn USB system. // #include #include #include "USBpix.h" #include #include "PixController/PixScan.h" #include "PixController/PixScanConfig.h" #include "PixConfDBInterface/PixConfDBInterface.h" #include "Bits/Bits.h" #include "Histo/Histo.h" #include "Config/Config.h" #include "PixModule/PixModule.h" #include "PixMcc/PixMcc.h" #include "PixDcs/SleepWrapped.h" #include "PixDcs/PixDcs.h" #include "PixDcs/USB_PixDcs.h" #include "USBPixController.h" #include #include #include #define UPC_DEBUG_GEN false #define UPC_DEBUG_FLAGS false using namespace PixLib; using namespace std; UINT32 bitflip(UINT32 bits_in){ UINT32 bits_out=0; for(int k=0;k<32;k++){ if(k<16) bits_out |= (bits_in&(1<>(2*k-31); } return bits_out; } // ***************** Constructors ********************* USBPixController::USBPixController(PixModuleGroup &modGrp, DBInquire *dbInquire) : PixController(modGrp, dbInquire) { configInit(); m_conf->read(dbInquire); for(int ib=0;ib roList; roList["40 Mb/s"] = RO4OMBPS; roList["160 Mb/s"] = RO160MBPS; conf["general"].addList("ReadoutSpeed", m_readoutSpeed, RO160MBPS, roList, "Speed of data coming back from FE-I4", true); conf["general"].addBool("setSelCMD",m_selCmd, true, "set pixel register via command decoder", true); conf["general"].addBool("slowCtrlMode", m_slowCtrlMode, false, "Use slow control mode for registers", true); conf["general"].addBool("enableCmdLvl1", m_enableCmdLvl1, true, "use CMDs for trigger and injection", true); conf["general"].addBool("enableRJ45", m_enableRJ45, false, "Enable RJ45 input during scans", true); std::map triggRepList; triggRepList["Disabled"] = REPLICATION_OFF; triggRepList["Master"] = REPLICATION_MASTER; triggRepList["Slave"] = REPLICATION_SLAVE; conf["general"].addList("TriggerReplication", m_triggerReplication, REPLICATION_OFF, triggRepList, "Role of USBpix Board for Trigger Replication", true); conf["general"].addInt("IoMuxSel", m_ioMuxSel, 0, "Set bit pattern on IoMxSel pads", true); conf["general"].addInt("IoMuxIn", m_ioMuxIn, 0, "Set bit pattern on IoMxIn pads", true); conf["general"].addInt("AuxClkDiv", m_auxClkDiv, 1, "Aux. clk. 40MHz div. by given amount", true); conf["general"].addInt("IrefPads", m_irefPads, 0, "Bit pattern on Iref pads", true); // Select default values conf.reset(); m_globRegNames["TrigCnt"] = 2; m_globRegNames["Conf_AddrEnable"] = 2; m_globRegNames["Reg2Spare"] = 2; m_globRegNames["ErrMask0"] = 3; m_globRegNames["ErrMask1"] = 4; m_globRegNames["PrmpVbpRight"] = 5; m_globRegNames["Vthin"] = 5; m_globRegNames["DisVbn_CPPM"] = 6; m_globRegNames["PrmpVbp"] = 6; m_globRegNames["TdacVbp"] = 7; m_globRegNames["DisVbn"] = 7; m_globRegNames["Amp2Vbn"] = 8; m_globRegNames["Amp2VbpFol"] = 8; m_globRegNames["PrmpVbpTop"] = 9; m_globRegNames["Amp2Vbp"] = 9; m_globRegNames["FdacVbn"] = 10; m_globRegNames["Amp2Vbpf"] = 10; m_globRegNames["PrmpVbnFol"] = 11; m_globRegNames["PrmpVbpLeft"] = 11; m_globRegNames["PrmpVbpf"] = 12; m_globRegNames["PrmpVbnLcc"] = 12; m_globRegNames["Reg13Spare"] = 13; m_globRegNames["PxStrobes"] = 13; m_globRegNames["S0"] = 13; m_globRegNames["S1"] = 13; m_globRegNames["LVDSDrvIref"] = 14; m_globRegNames["BonnDac"] = 14; m_globRegNames["PllIbias"] = 15; m_globRegNames["LVDSDrvVos"] = 15; m_globRegNames["TempSensBias"] = 16; m_globRegNames["PllIcp"] = 16; m_globRegNames["Reg17Spare"] = 17; m_globRegNames["PlsrIdacRamp"] = 17; m_globRegNames["Reg18Spare"] = 18; m_globRegNames["PlsrVgOPamp"] = 18; m_globRegNames["PlsrDacBias"] = 19; m_globRegNames["Reg19Spare"] = 19; m_globRegNames["Vthin_AltCoarse"] = 20; m_globRegNames["Vthin_AltFine"] = 20; m_globRegNames["PlsrDAC"] = 21; m_globRegNames["DIGHITIN_Sel"] = 21; m_globRegNames["DINJ_Override"] = 21; m_globRegNames["HITLD_In"] = 21; m_globRegNames["Reg21Spare"] = 21; m_globRegNames["Reg22Spare2"] = 22; m_globRegNames["Colpr_Addr"] = 22; m_globRegNames["Colpr_Mode"] = 22; m_globRegNames["Reg22Spare1"] = 22; m_globRegNames["DisableColumnCnfg0"]= 23; m_globRegNames["DisableColumnCnfg1"]= 24; m_globRegNames["DisableColumnCnfg2"]= 25; m_globRegNames["TrigLat"] = 25; m_globRegNames["CMDcnt"] = 26; m_globRegNames["StopModeCnfg"] = 26; m_globRegNames["HitDisableCnfg"] = 26; m_globRegNames["EN_PLL"] = 27; m_globRegNames["Efuse_sense"] = 27; m_globRegNames["Stop_Clk"] = 27; m_globRegNames["ReadErrorReq"] = 27; m_globRegNames["ReadSkipped"] = 27; m_globRegNames["Reg27Spare"] = 27; m_globRegNames["GateHitOr"] = 27; m_globRegNames["CalEn"] = 27; m_globRegNames["SR_clr"] = 27; m_globRegNames["Latch_en"] = 27; m_globRegNames["SR_Clock"] = 27; m_globRegNames["LVDSDrvSet06"] = 28; m_globRegNames["Reg28Spare"] = 28; m_globRegNames["EN40M"] = 28; m_globRegNames["EN80M"] = 28; m_globRegNames["CLK1"] = 28; m_globRegNames["CLK0"] = 28; m_globRegNames["EN160M"] = 28; m_globRegNames["EN320M"] = 28; m_globRegNames["Reg29Spare1"] = 29; m_globRegNames["no8b10b"] = 29; m_globRegNames["Clk2OutCnfg"] = 29; m_globRegNames["EmptyRecord"] = 29; m_globRegNames["Reg29Spare2"] = 29; m_globRegNames["LVDSDrvEn"] = 29; m_globRegNames["LVDSDrvSet30"] = 29; m_globRegNames["LVDSDrvSet12"] = 29; m_globRegNames["PlsrRiseUpTau"] = 31; m_globRegNames["PlsrPwr"] = 31; m_globRegNames["PlsrDelay"] = 31; m_globRegNames["ExtDigCalSW"] = 31; m_globRegNames["ExtAnaCalSW"] = 31; m_globRegNames["Reg31Spare"] = 31; m_globRegNames["SELB0"] = 32; m_globRegNames["SELB1"] = 33; m_globRegNames["SELB2"] = 34; m_globRegNames["EfuseCref"] = 34; m_globRegNames["EfuseVref"] = 34; m_globRegNames["Chip_SN"] = 35; // new for FE-I4B m_globRegNames["Reg1Spare"] = 1; m_globRegNames["SmallHitErase"] = 1; m_globRegNames["Eventlimit"] = 1; m_globRegNames["BufVgOpAmp"] = 5; m_globRegNames["Reg6Spare"] = 6; m_globRegNames["Reg9Spare"] = 9; m_globRegNames["GADCOpAmp"] = 14; m_globRegNames["VrefDigTune"] = 18; m_globRegNames["VrefAnTune"] = 19; m_globRegNames["Reg27Spare1"] = 27; m_globRegNames["GADC_Enable"] = 27; m_globRegNames["ShiftReadBack"] = 27; m_globRegNames["Reg27Spare2"] = 27; m_globRegNames["TempSensDiodeSel"] = 30; m_globRegNames["TempSensDisable"] = 30; m_globRegNames["IleakRange"] = 30; m_globRegNames["Reg30Spare"] = 30; m_globRegNames["GADCSel"] = 31; m_globRegNames["Reg34Spare1"] = 34; m_globRegNames["PrmpVbpMsnEn"] = 34; m_globRegNames["Reg34Spare2"] = 34; m_latchNames["ENABLE"] = ENABLE+1; // must add 1, since ENABLE=0 would spoil identification of wrong names m_latchNames["CAP0"] = CAP0+1; m_latchNames["CAP1"] = CAP1+1; m_latchNames["ILEAK"] = HITBUS+1; // is both hitbus and Ileak control... m_latchNames["TDAC0"] = TDAC0+1; m_latchNames["TDAC1"] = TDAC1+1; m_latchNames["TDAC2"] = TDAC2+1; m_latchNames["TDAC3"] = TDAC3+1; m_latchNames["TDAC4"] = TDAC4+1; m_latchNames["FDAC0"] = FDAC0+1; m_latchNames["FDAC1"] = FDAC1+1; m_latchNames["FDAC2"] = FDAC2+1; m_latchNames["FDAC3"] = FDAC3+1; m_configValid = false; } // ***************** Board functionality ************** void USBPixController::initHW() { if(UPC_DEBUG_GEN){ cout<<"INFO: FPGA_filename="<LoadFirmwareFromFile(m_uC_filename.c_str())){ if(UPC_DEBUG_GEN) cout<<"ERROR: uC didn't configure"<SetDeviceHandle(tempHandle); if(UPC_DEBUG_GEN) cout <<"INFO: after uC load - found "<< m_BoardHandle[ib] << " - " << m_BoardHandle[ib]->GetName() << " with ID " << m_BoardHandle[ib]->GetId() << " and FW " << m_BoardHandle[ib]->GetFWVersion() << endl; } else{ if(UPC_DEBUG_GEN) cout<<"ERROR: no board handle found after uC load..."<DownloadXilinx(m_FPGA_filename.c_str())){ delete m_BoardHandle[ib]; m_BoardHandle[ib]=0; // this will make sure that ctrl. is fully initialised again if(UPC_DEBUG_GEN) cout<<"ERROR: FPGA didn't configure"<SetUSBHandles(m_BoardHandle[0], m_BoardHandle[1]); // re-set phase shift - needed in case of initialisation for more than one time m_USBpix->SetCurrentPhaseshift(0, m_chipIds[0]); if(m_chipIds[1]==999) m_USBpix->SetCurrentPhaseshift(0, m_chipIds[1]); updateRegs(); }else{ if(UPC_DEBUG_GEN) cout<<"ERROR: no SiUSBDevice found..."<GetName() << " with ID " << m_BoardHandle[ib]->GetId() <SetCableLengthReg(m_cableLength); // set cmd register m_USBpix->setSelCMD(m_selCmd); if(m_slowCtrlMode){ if(UPC_DEBUG_GEN) cout<<"setting USBPix to slow control mode"<SetSlowControlMode(); }else{ if(UPC_DEBUG_GEN) cout<<"setting USBPix to CMD mode"<SetCMDMode(); } if(m_enableCmdLvl1) m_USBpix->enableCMDLV1(); else m_USBpix->disableCMDLV1(); if(m_readoutSpeed==RO160MBPS) m_USBpix->enable_160Mbps_data_rate(); else m_USBpix->disable_160Mbps_data_rate(); // IoMuxSel int data, dataRB = m_USBpix->ReadRegister(CS_INMUX_CONTROL); data = (0x7 & m_ioMuxSel) + (dataRB & 0x7ffffff8); m_USBpix->WriteRegister(CS_INMUX_CONTROL, data); if(UPC_DEBUG_GEN) cout<<"setting USBPix to IoMuxSel "<ReadRegister(CS_INMUX_IN_CTRL); data = (dataRB & 0x7ffffff0) + (0xf & m_ioMuxIn); m_USBpix->WriteRegister(CS_INMUX_IN_CTRL, data); if(UPC_DEBUG_GEN) cout<<"setting USBPix to IoMuxIo "<>1; // modify by factor of 2 and clip LSB to match Malte's definition m_USBpix->SetAuxClkFreq(acReg); if(UPC_DEBUG_GEN) cout<<"setting USBPix to aux clk. freq of "<< (40./pow(2., m_auxClkDiv-6)) << " (i.e. reg. to " << acReg << ")" << endl; // Iref pad settings int invIref = (~(m_irefPads&0xf))&0xf; m_USBpix->WriteRegister(CS_IREF_PAD_SELECT, invIref); if(UPC_DEBUG_GEN) cout<<"setting USBPix to Iref pad of "<< invIref << " (was " << (m_irefPads&0xf) << " before bit flip)" << endl; }else{ throw USBPixControllerExc(USBPixControllerExc::NOBOARD, PixControllerExc::FATAL, getModGroup().getRodName()); } return; } void USBPixController::sendCommand(Bits command, int moduleMask) { Bits fesoftr(10, PIX_FE_SOFT_RESET); Bits ferefr(10, PIX_FE_REF_RESET); Bits felsync(10, PIX_MC_SYNC); Bits fetrig(10, PIX_MC_TRIGGER); Bits feecr(10, PIX_FE_EC_RESET); Bits febcr(10, PIX_FE_BC_RESET); if(command==ferefr){ int data = 0x0; m_USBpix->WriteRegister(CS_HARD_RST_CONTROL, data); } if(command==fesoftr){ for(int ib=0;ibWriteCommand(FE_GLOBAL_RESET, m_chipIds[ib]); } } if(command==felsync){ int data = 0x7; m_USBpix->WriteRegister(CS_HARD_RST_CONTROL, data); } if(command==fetrig){ for(int ib=0;ibWriteCommand(FE_EN_DATA_TAKE, m_chipIds[ib]); } unsigned char reg_data[7]={0xff,0x01,0x03,0x05,1,0xff,0x04}; m_USBpix->WriteStrbSave(reg_data); m_USBpix->WriteStrbStart(); } if(command==feecr){ for(int ib=0;ibWriteCommand(FE_ECR, m_chipIds[ib]); } } if(command==febcr){ for(int ib=0;ibWriteCommand(FE_BCR, m_chipIds[ib]); } } } void USBPixController::sendCommandOutSync(Bits commands, int moduleMask, std::vector& output) { //JW: not used } void USBPixController::sendCommandOutAsync(Bits commands, int moduleMask, int commandID) { //JW: not used } bool USBPixController::checkOutReady(int commandID) { //JW: not used return false; } void USBPixController::getOutput(int commandID, std::vector& output) { //JW: not used } void USBPixController::downloadFifo(int size) { } bool USBPixController::primitiveExists(std::string str) { return false; } //void USBPixController::ledFlash(int period, int repet, int led) { //JW: Spielerei für Board Test //} // ************ Pixel module functions **************** void USBPixController::writeModuleConfig(int moduleId, Module& config) { if(UPC_DEBUG_GEN) cout<<"INFO USBPixCtrl: called writeModuleConfig()"<MakeMeFEI4A(); if(config.feFlavour==FEI4B) m_USBpix->MakeMeFEI4B(); for(int iFe=0;iFeSetChipAdd(config.FEI4Config[iFe].FECommand.address, m_chipIds[iFe]); m_chipIds[iFe] = config.FEI4Config[iFe].FECommand.address; if(config.feFlavour==FEI4A){ m_USBpix->SetGlobalVal(TRIGCNT , globReg.TrigCnt , m_chipIds[iFe]); m_USBpix->SetGlobalVal(CONFADDRENABLE, globReg.Conf_AddrEnable , m_chipIds[iFe]); m_USBpix->SetGlobalVal(CFGSPARE2 , globReg.CFGspare2 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(ERRMASK0 , globReg.ErrMask0 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(ERRMASK1 , globReg.ErrMask1 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PRMPVBP_R , globReg.PrmpVbpRight , m_chipIds[iFe]); m_USBpix->SetGlobalVal(VTHIN , globReg.Vthin , m_chipIds[iFe]); m_USBpix->SetGlobalVal(DISVBN_CPPM , globReg.DisVbn_CPPM , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PRMPVBP , globReg.PrmpVbp , m_chipIds[iFe]); m_USBpix->SetGlobalVal(TDACVBP , globReg.TdacVbp , m_chipIds[iFe]); m_USBpix->SetGlobalVal(DISVBN , globReg.DisVbnA , m_chipIds[iFe]); m_USBpix->SetGlobalVal(AMP2VBN , globReg.Amp2Vbn , m_chipIds[iFe]); m_USBpix->SetGlobalVal(AMP2VBPFOL , globReg.Amp2VbpFol , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PRMPVBP_T , globReg.PrmpVbpTop , m_chipIds[iFe]); m_USBpix->SetGlobalVal(AMP2VBP , globReg.Amp2Vbp , m_chipIds[iFe]); m_USBpix->SetGlobalVal(FDACVBN , globReg.FdacVbn , m_chipIds[iFe]); m_USBpix->SetGlobalVal(AMP2VBPFF , globReg.Amp2Vbpf , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PRMPVBNFOL , globReg.PrmpVbnFol , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PRMPVBP_L , globReg.PrmpVbpLeft , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PRMPVBPF , globReg.PrmpVbpf , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PRMPVBNLCC , globReg.PrmpVbnLcc , m_chipIds[iFe]); m_USBpix->SetGlobalVal(REG13SPARES , globReg.spare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBE0 , (globReg.PxStrobes>>0) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBE1 , (globReg.PxStrobes>>1) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBE2 , (globReg.PxStrobes>>2) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBE3 , (globReg.PxStrobes>>3) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBE4 , (globReg.PxStrobes>>4) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBE5 , (globReg.PxStrobes>>5) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBE6 , (globReg.PxStrobes>>6) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBE7 , (globReg.PxStrobes>>7) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBE8 , (globReg.PxStrobes>>8) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBE9 , (globReg.PxStrobes>>9) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBE10 , (globReg.PxStrobes>>10) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBE11 , (globReg.PxStrobes>>11) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBE12 , (globReg.PxStrobes>>12) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBES0 , globReg.PxS0 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PXSTROBES1 , globReg.PxS1 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(LVDSDRVIREF , globReg.LVDSDrvIref , m_chipIds[iFe]); m_USBpix->SetGlobalVal(BONNDAC , globReg.BonnDac , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PLLIBIAS , globReg.PLLbias , m_chipIds[iFe]); m_USBpix->SetGlobalVal(LVDSDRVVOS , globReg.LVDSDrvVos , m_chipIds[iFe]); m_USBpix->SetGlobalVal(TEMPDENSIBIAS , globReg.TempSensBias , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PLLICP , globReg.PLLCPBias , m_chipIds[iFe]); m_USBpix->SetGlobalVal(DAC8SPARE1 , globReg.Reg17Spare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PLSRLDACRAMP , globReg.PlsrIdacRamp , m_chipIds[iFe]); m_USBpix->SetGlobalVal(DAC8SPARE2 , globReg.Reg18Spare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PLSRVGOAMP , globReg.PlsrVgOPamp , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PLSRDACBIAS , globReg.PlsrDacBias , m_chipIds[iFe]); m_USBpix->SetGlobalVal(DAC8SPARE5 , globReg.Reg19Spare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(VTHIN_ALTCOARSE, globReg.vthin_AltCoarse , m_chipIds[iFe]); m_USBpix->SetGlobalVal(VTHIN_ALTFINE , globReg.vthin_AltFine , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PLSRDAC , globReg.PlsDAC , m_chipIds[iFe]); m_USBpix->SetGlobalVal(DIGHITIN_SEL , globReg.DIGHITIN_Sel , m_chipIds[iFe]); m_USBpix->SetGlobalVal(DINJ_OVERRIDE , globReg.DINJ_Override , m_chipIds[iFe]); m_USBpix->SetGlobalVal(HITLD_IN , globReg.HITLD_In , m_chipIds[iFe]); m_USBpix->SetGlobalVal(REG21SPARES , globReg.Plsspare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(REG22SPARES1 , globReg.FENDSpare1 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(COLPR_ADDR , globReg.Colpr_Addr , m_chipIds[iFe]); m_USBpix->SetGlobalVal(COLPR_MODE , globReg.Colpr_Mode , m_chipIds[iFe]); m_USBpix->SetGlobalVal(REG22SPARES2 , globReg.FENDSpare2 , m_chipIds[iFe]); for(int icm=0;icm<16;icm++) m_USBpix->SetGlobalVal(KILLDC0-icm , (globReg.ColMask0>>icm) & 0x1, m_chipIds[iFe]); for(int icm=0;icm<16;icm++) m_USBpix->SetGlobalVal(KILLDC16-icm, (globReg.ColMask1>>icm) & 0x1, m_chipIds[iFe]); for(int icm=0;icm<8;icm++) m_USBpix->SetGlobalVal(KILLDC32-icm, (globReg.ColMask2>>icm) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(CHIP_LATENCY , globReg.TrigLat , m_chipIds[iFe]); m_USBpix->SetGlobalVal(CMDCNT0_12 , globReg.CMDcnt & 0x1fff , m_chipIds[iFe]);// skip last bit m_USBpix->SetGlobalVal(STOPMODECNFG , globReg.StopModeCnfg , m_chipIds[iFe]); m_USBpix->SetGlobalVal(HITDISCCNFG , globReg.HitDisableCnfg , m_chipIds[iFe]); m_USBpix->SetGlobalVal(ENPLL , globReg.CLKPLLCoreEnable , m_chipIds[iFe]); m_USBpix->SetGlobalVal(FE_CLK_PULSE , globReg.FE_Clk_pulse , m_chipIds[iFe]); m_USBpix->SetGlobalVal(LATCH_EN , globReg.Latch_en , m_chipIds[iFe]); m_USBpix->SetGlobalVal(SR_CLR , globReg.SR_clr , m_chipIds[iFe]); m_USBpix->SetGlobalVal(DIG_INJ , globReg.CalEn , m_chipIds[iFe]); m_USBpix->SetGlobalVal(REG27SPARES , globReg.CLKspare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(GATEHITOR , globReg.GateHitOr , m_chipIds[iFe]); m_USBpix->SetGlobalVal(RD_SKIPPED , globReg.Rd_skipped , m_chipIds[iFe]); m_USBpix->SetGlobalVal(RD_ERRORS , globReg.Rd_Errors , m_chipIds[iFe]); m_USBpix->SetGlobalVal(STOP_CLK , globReg.Stop_Clk , m_chipIds[iFe]); m_USBpix->SetGlobalVal(EFUSE_SENSE , globReg.Efuse_sense , m_chipIds[iFe]); m_USBpix->SetGlobalVal(CMDCNT13 , (globReg.CMDcnt & 0x2000)>>13, m_chipIds[iFe]); m_USBpix->SetGlobalVal(LVDSDRVSET06 , globReg.LVDSDrvSet06 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(REG28SPARES , globReg.PLLSpare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(EN_40M , globReg.EN40M , m_chipIds[iFe]); m_USBpix->SetGlobalVal(EN_80M , globReg.EN80M , m_chipIds[iFe]); m_USBpix->SetGlobalVal(CLK1_S0 , (globReg.CLK1_S012>>0)&0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(CLK1_S1 , (globReg.CLK1_S012>>1)&0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(CLK1_S2 , (globReg.CLK1_S012>>2)&0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(CLK0_S0 , (globReg.CLK0_S012>>0)&0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(CLK0_S1 , (globReg.CLK0_S012>>1)&0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(CLK0_S2 , (globReg.CLK0_S012>>2)&0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(EN_160M , globReg.EN160M , m_chipIds[iFe]); m_USBpix->SetGlobalVal(EN_320M , globReg.EN320M , m_chipIds[iFe]); m_USBpix->SetGlobalVal(REG29SPARES , globReg.LVDSspare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(DISABLE8B10B , globReg.Disable8B10B , m_chipIds[iFe]); m_USBpix->SetGlobalVal(CLK2OUTCFG , globReg.Clk2OutCnfg , m_chipIds[iFe]); m_USBpix->SetGlobalVal(EMPTYRECORD , globReg.EmptyRecord , m_chipIds[iFe]); m_USBpix->SetGlobalVal(REG29SPARE2 , globReg.LVDSspare2 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(LVDSDRVEN , globReg.LVDSDrvEn , m_chipIds[iFe]); m_USBpix->SetGlobalVal(LVDSDRVSET30 , globReg.LVDSDrvSet30 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(LVDSDRVSET12 , globReg.LVDSDrvSet12 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(RISEUPTAO , globReg.PlsrRiseUpTau , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PULSERPWR , globReg.PlsrPwr , m_chipIds[iFe]); m_USBpix->SetGlobalVal(PULSERDELAY , globReg.PlsrDelay , m_chipIds[iFe]); m_USBpix->SetGlobalVal(EXTDIGCALSW , globReg.PlsrExtDigCalSW , m_chipIds[iFe]); m_USBpix->SetGlobalVal(EXTANCALSW , globReg.PlsrExtAnaCalSW , m_chipIds[iFe]); m_USBpix->SetGlobalVal(REG31SPARES , globReg.PlsrSpare , m_chipIds[iFe]); for(int icm=0;icm<16;icm++) m_USBpix->SetGlobalVal(EFUSEDC0+icm , (globReg.Efusedc0>>icm) & 0x1 , m_chipIds[iFe]); for(int icm=0;icm<16;icm++) m_USBpix->SetGlobalVal(EFUSEDC16+icm, (globReg.Efusedc1>>icm) & 0x1 , m_chipIds[iFe]); for(int icm=0;icm<8;icm++) m_USBpix->SetGlobalVal(EFUSEDC32+icm, (globReg.Efusedc2>>icm) & 0x1 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(EFUSECREF , globReg.Efusecref , m_chipIds[iFe]); m_USBpix->SetGlobalVal(EFUSEVREF , globReg.Efusevref , m_chipIds[iFe]); m_USBpix->SetGlobalVal(EFUSECHIPSERNUM, globReg.Chip_SN , m_chipIds[iFe]); } else if(config.feFlavour==FEI4B){ m_USBpix->SetGlobalVal(B_REG1SPARE , globReg.Reg1Spare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_SMALLHITERASE , globReg.SmallHitErase , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_EVENTLIMIT , globReg.Eventlimit , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_TRIGCNT , globReg.TrigCnt , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_CONFADDRENABLE, globReg.Conf_AddrEnable , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_CFGSPARE2 , globReg.CFGspare2 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_ERRMASK0 , globReg.ErrMask0 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_ERRMASK1 , globReg.ErrMask1 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PRMPVBP_R , globReg.PrmpVbpRight , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_BUFVGOPAMP , globReg.BufVgOpAmp , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG6SPARE , globReg.Reg6Spare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PRMPVBP , globReg.PrmpVbp , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_TDACVBP , globReg.TdacVbp , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_DISVBN , globReg.DisVbnA , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_AMP2VBN , globReg.Amp2Vbn , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_AMP2VBPFOL , globReg.Amp2VbpFol , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG9SPARE , globReg.Reg9Spare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_AMP2VBP , globReg.Amp2Vbp , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_FDACVBN , globReg.FdacVbn , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_AMP2VBPFF , globReg.Amp2Vbpf , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PRMPVBNFOL , globReg.PrmpVbnFol , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PRMPVBP_L , globReg.PrmpVbpLeft , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PRMPVBPF , globReg.PrmpVbpf , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PRMPVBNLCC , globReg.PrmpVbnLcc , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG13SPARES , globReg.spare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBE0 , (globReg.PxStrobes>>0) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBE1 , (globReg.PxStrobes>>1) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBE2 , (globReg.PxStrobes>>2) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBE3 , (globReg.PxStrobes>>3) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBE4 , (globReg.PxStrobes>>4) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBE5 , (globReg.PxStrobes>>5) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBE6 , (globReg.PxStrobes>>6) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBE7 , (globReg.PxStrobes>>7) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBE8 , (globReg.PxStrobes>>8) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBE9 , (globReg.PxStrobes>>9) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBE10 , (globReg.PxStrobes>>10) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBE11 , (globReg.PxStrobes>>11) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBE12 , (globReg.PxStrobes>>12) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBES1 , globReg.PxS0 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PXSTROBES0 , globReg.PxS1 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_LVDSDRVIREF , globReg.LVDSDrvIref , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_ADCOPAMP , globReg.GADCOpAmp , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PLLIBIAS , globReg.PLLbias , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_LVDSDRVVOS , globReg.LVDSDrvVos , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_TEMPDENSIBIAS , globReg.TempSensBias , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PLLICP , globReg.PLLCPBias , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_DAC8SPARE1 , globReg.Reg17Spare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PLSRLDACRAMP , globReg.PlsrIdacRamp , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_VREFDIGTUNE , globReg.VrefDigTune , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PLSRVGOAMP , globReg.PlsrVgOPamp , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PLSRDACBIAS , globReg.PlsrDacBias , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_VREFANTUNE , globReg.VrefAnTune , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_VTHIN_ALTCOARSE, globReg.vthin_AltCoarse , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_VTHIN_ALTFINE , globReg.vthin_AltFine , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PLSRDAC , globReg.PlsDAC , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_DIGHITIN_SEL , globReg.DIGHITIN_Sel , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_DINJ_OVERRIDE , globReg.DINJ_Override , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_HITLD_IN , globReg.HITLD_In , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG21SPARES , globReg.Plsspare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG22SPARES1 , globReg.FENDSpare1 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_COLPR_ADDR , globReg.Colpr_Addr , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_COLPR_MODE , globReg.Colpr_Mode , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG22SPARES2 , globReg.FENDSpare2 , m_chipIds[iFe]); for(int icm=0;icm<16;icm++) m_USBpix->SetGlobalVal(B_KILLDC0-icm , (globReg.ColMask0>>icm) & 0x1, m_chipIds[iFe]); for(int icm=0;icm<16;icm++) m_USBpix->SetGlobalVal(B_KILLDC16-icm, (globReg.ColMask1>>icm) & 0x1, m_chipIds[iFe]); for(int icm=0;icm<8;icm++) m_USBpix->SetGlobalVal(B_KILLDC32-icm, (globReg.ColMask2>>icm) & 0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_CHIP_LATENCY , globReg.TrigLat , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_CMDCNT0_12 , globReg.CMDcnt & 0x1fff , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_STOPMODECNFG , globReg.StopModeCnfg , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_HITDISCCNFG , globReg.HitDisableCnfg , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_ENPLL , globReg.CLKPLLCoreEnable , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_SR_CLR , globReg.SR_clr , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_LATCH_EN , globReg.Latch_en , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_FE_CLK_PULSE , globReg.FE_Clk_pulse , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_DIG_INJ , globReg.CalEn , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG27SPARES2 , globReg.CLKspare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_GATEHITOR , globReg.GateHitOr , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG27SPARE1 , globReg.Reg27Spare1 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_RD_ERRORS , globReg.Rd_Errors , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_STOP_CLK , globReg.Stop_Clk , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_EFUSE_SENSE , globReg.Efuse_sense , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_ADC_EN_PULSE , globReg.GADC_Enable , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_SR_RD_EN , globReg.ShiftReadBack , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_CMDCNT13 , (globReg.CMDcnt & 0x2000)>>13, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_LVDSDRVSET06 , globReg.LVDSDrvSet06 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG28SPARES , globReg.PLLSpare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_EN_40M , globReg.EN40M , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_EN_80M , globReg.EN80M , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_CLK1_S0 , (globReg.CLK1_S012>>0)&0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_CLK1_S1 , (globReg.CLK1_S012>>1)&0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_CLK1_S2 , (globReg.CLK1_S012>>2)&0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_CLK0_S0 , (globReg.CLK0_S012>>0)&0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_CLK0_S1 , (globReg.CLK0_S012>>1)&0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_CLK0_S2 , (globReg.CLK0_S012>>2)&0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_EN_160M , globReg.EN160M , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_EN_320M , globReg.EN320M , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG29SPARES , globReg.LVDSspare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_DISABLE8B10B , globReg.Disable8B10B , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_CLK2OUTCFG , globReg.Clk2OutCnfg , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_EMPTYRECORD , globReg.EmptyRecord , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG29SPARE2 , globReg.LVDSspare2 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_LVDSDRVEN , globReg.LVDSDrvEn , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_LVDSDRVSET30 , globReg.LVDSDrvSet30 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_LVDSDRVSET12 , globReg.LVDSDrvSet12 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_TMPSENSED0 , globReg.TmpSensDiodeSel &0x1 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_TMPSENSED1 , (globReg.TmpSensDiodeSel>>1)&0x1, m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_TMPSENSEDISABLE, globReg.TmpSensDisable , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_ILEAKRANGE , globReg.IleakRange , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG30SPARES , globReg.Reg30Spare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_RISEUPTAO , globReg.PlsrRiseUpTau , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PULSERPWR , globReg.PlsrPwr , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PULSERDELAY , globReg.PlsrDelay , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_EXTDIGCALSW , globReg.PlsrExtDigCalSW , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_EXTANCALSW , globReg.PlsrExtAnaCalSW , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG31SPARES , globReg.PlsrSpare , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_ADCSELECT , globReg.GADCSel , m_chipIds[iFe]); for(int icm=0;icm<16;icm++) m_USBpix->SetGlobalVal(B_EFUSEDC0+icm , (globReg.Efusedc0>>icm) & 0x1 , m_chipIds[iFe]); for(int icm=0;icm<16;icm++) m_USBpix->SetGlobalVal(B_EFUSEDC16+icm, (globReg.Efusedc1>>icm) & 0x1 , m_chipIds[iFe]); for(int icm=0;icm<8;icm++) m_USBpix->SetGlobalVal(B_EFUSEDC32+icm, (globReg.Efusedc2>>icm) & 0x1 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG34SPARES1 , globReg.Reg34Spare1 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_PRMPVBPMSNEN , globReg.PrmpVbpMsnEn , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_REG34SPARES2 , globReg.Reg34Spare2 , m_chipIds[iFe]); m_USBpix->SetGlobalVal(B_EFUSECHIPSERNUM, globReg.Chip_SN , m_chipIds[iFe]); } else // unhandled FE type, can't process throw USBPixControllerExc(USBPixControllerExc::NOT_IMPLEMENTED, PixControllerExc::ERROR, getModGroup().getRodName()); // should we do this here? check for consistency between FEs? if(iFe==0){ if(globReg.Disable8B10B) m_USBpix->disable_8b10_Decoding(); else m_USBpix->enable_8b10_Decoding(); } // ********* GlobalRegister done! *************** // loop over individual pixel register bits and fill m_USBpix const int nlatches = 13, itdac=4, ifdac=9, nWords=(N_I4_PIXEL_COLUMNS*N_I4_PIXEL_ROWS)/32; int trimBits[nWords]; int latches[nlatches]={ENABLE, CAP1, CAP0, HITBUS, TDAC0, TDAC1, TDAC2, TDAC3, TDAC4, FDAC0, FDAC1, FDAC2, FDAC3}; for(int i=0;i=ifdac){ //FDAC starts here bit_offs = i-ifdac; // start again from 0 trimBits[pixint] |= (int)(((trims.dacFeedbackTrim[col][row]>>bit_offs)&0x1)<=itdac){ //TDAC starts here bit_offs = i-itdac; // start again from 0 trimBits[pixint] |= (int)(((trims.dacThresholdTrim[col][row]>>bit_offs)&0x1)<>bit_offs)&0x1)<SetPixelVal(PIXEL26880+j, trimBits[j], latches[i], m_chipIds[iFe]); } // ********* PixelRegister done! *************** } m_configValid = true; if(UPC_DEBUG_GEN) cout<<"INFO USBPixCtrl: end of writeModuleConfig()"<ReadGlobal(m_chipIds[ib]); } } } void USBPixController::sendGlobal(unsigned int moduleMask){ if(UPC_DEBUG_GEN) cout<<"INFO USBPixCtrl: called general sendGlobal "<WriteGlobal(m_chipIds[ib]); } } else { throw USBPixControllerExc(USBPixControllerExc::INIT_ERROR, PixControllerExc::ERROR, getModGroup().getRodName()); } } void USBPixController::sendGlobal(unsigned int moduleMask, std::string regName){ if(UPC_DEBUG_GEN) cout<<"INFO USBPixCtrl: called sendGlobal for reg. "<< regName<0){ for(int ib=0;ibWriteGlobalSingleReg(regNo, m_chipIds[ib]); } } else { throw USBPixControllerExc(USBPixControllerExc::INIT_ERROR, PixControllerExc::ERROR, getModGroup().getRodName()); } } int USBPixController::readGlobal(int regNo, int feInd){ int val = 0; if(m_USBpix!=NULL && m_configValid && regNo>0){ if(feIndReadGlobalSingleReg(regNo, m_chipIds[feInd]); } else { throw USBPixControllerExc(USBPixControllerExc::INIT_ERROR, PixControllerExc::ERROR, getModGroup().getRodName()); } return val; } void USBPixController::sendPixel(unsigned int moduleMask){ if(UPC_DEBUG_GEN) cout<<"INFO USBPixCtrl: called sendPixel"<WritePixelSingleLatchDC(latch,doublecolumn, m_chipIds[ib]); } } } } else { throw USBPixControllerExc(USBPixControllerExc::INIT_ERROR, PixControllerExc::ERROR, getModGroup().getRodName()); } } void USBPixController::sendPixel(unsigned int moduleMask, std::string regName, bool allDcsIdentical) { if(UPC_DEBUG_GEN) cout<<"INFO USBPixCtrl: called sendPixel for reg. "<< regName<=0){ for(int ib=0;ibWritePixelSingleLatch(latch, m_chipIds[ib]); else{ for (int doublecolumn = 0; doublecolumn < 40; doublecolumn++){ m_USBpix->WritePixelSingleLatchDC(latch,doublecolumn, m_chipIds[ib]); } } } } else { throw USBPixControllerExc(USBPixControllerExc::INIT_ERROR, PixControllerExc::ERROR, getModGroup().getRodName()); } } void USBPixController::sendPixel(unsigned int moduleMask, std::string regName, int DC){ if(UPC_DEBUG_GEN) cout<<"INFO USBPixCtrl: called sendPixel for reg. "<< regName << " and DC " << DC <=0 && DC<40){ DCmin = DC; DCmax = DC+1; } if(m_USBpix!=NULL && m_configValid && latch>=0){ for(int ib=0;ibWritePixelSingleLatchDC(latch,doublecolumn, m_chipIds[ib]); } } } else { throw USBPixControllerExc(USBPixControllerExc::INIT_ERROR, PixControllerExc::ERROR, getModGroup().getRodName()); } } void USBPixController::sendModuleConfig(unsigned int moduleMask) { if(UPC_DEBUG_GEN) cout<<"INFO USBPixCtrl: called sendModuleConfig"<WriteGlobal(m_chipIds[ib]); for (int doublecolumn = 0; doublecolumn < 40; doublecolumn++){ for (int latch = ENABLE; latch <= FDAC3; latch++){ m_USBpix->WritePixelSingleLatchDC(latch,doublecolumn, m_chipIds[ib]); } } } } else { throw USBPixControllerExc(USBPixControllerExc::INIT_ERROR, PixControllerExc::ERROR, getModGroup().getRodName()); } } void USBPixController::sendModuleConfig(unsigned int moduleMask, Module& config) { if(UPC_DEBUG_GEN) cout<<"INFO USBPixCtrl: called sendModuleConfig"<WriteGlobal(m_chipIds[ib]); for (int doublecolumn = 0; doublecolumn < 40; doublecolumn++){ for (int latch = ENABLE; latch <= FDAC3; latch++){ m_USBpix->WritePixelSingleLatchDC(latch,doublecolumn, m_chipIds[ib]); } } } } else { throw USBPixControllerExc(USBPixControllerExc::INIT_ERROR, PixControllerExc::ERROR, getModGroup().getRodName()); } } bool USBPixController::testGlobalRegister(int module, std::vector &data_in, std::vector &data_out, std::vector &label, bool sendCfg, int feIndex){ bool retVal = false; if(feIndex<0 || feIndex>=NBOARDS_MAX) return retVal; if(m_chipIds[feIndex]==999) return retVal; if(UPC_DEBUG_GEN) cout << "starting GR test for FE type " << (m_USBpix->FEisFEI4B()?"B":"A") << endl; if(m_USBpix!=0 && m_configValid){ if(sendCfg){ if(UPC_DEBUG_GEN) cout << "GR test - write global" << endl; m_USBpix->WriteGlobal(m_chipIds[feIndex]); } if(UPC_DEBUG_GEN) cout << "GR test - read global" << endl; m_USBpix->ReadGlobal(m_chipIds[feIndex]); if(UPC_DEBUG_GEN) cout << "GR test - comparison" << endl; retVal = true; int Address, Size, wValue, rValue; int imin=TRIGCNT, imax=READCMDERR, iign=EFUSECHIPSERNUM; if(m_USBpix->FEisFEI4B()){ imin = B_REG1SPARE; imax = B_READCMDERR; iign = B_EFUSECHIPSERNUM; } for(int i=imin;i<=imax;i++){ m_USBpix->GetGlobalVarAddVal(i, Address, Size, wValue, m_chipIds[feIndex]); m_USBpix->GetGlobalRBVarAddVal(i, Address, Size, rValue, m_chipIds[feIndex]); if(igetGlobalVarName(i)); if(wValue!=rValue) retVal = false; } else{ // fill in read value for information data_in.push_back(rValue); // shouldn't here also the write value be pushed for information? // JGK: no, would confuse later analysis data_out.push_back(rValue); label.push_back(m_USBpix->getGlobalVarName(i)); } } } return retVal; } bool USBPixController::testPixelRegister(int module, std::string regName, std::vector &data_in, std::vector &data_out, bool ignoreDCsOff, int DC, bool sendCfg, int feIndex, bool bypass) { if(UPC_DEBUG_GEN) cout << "Pixel register test in " << (bypass?"bypass":"normal") << " mode " << endl; bool retVal = false; if(feIndex<0 || feIndex>=NBOARDS_MAX) return retVal; if(m_chipIds[feIndex]==999) return retVal; bool allDcsIdentical = false; if(DC == 40) allDcsIdentical = true; int DCmin=0, DCmax=40; if(DC>=0 && DC<40){ DCmin = DC; DCmax = DCmin + 1; } if(m_USBpix!=0 && m_configValid){ int Address, Size, wValue, rValue; int latch=m_latchNames[regName]-1; // get settings of DC kill mask int DCmask[40]; for(int icm=0;icm<40;icm++) DCmask[icm]=0; if(ignoreDCsOff){ for(int icm=0;icm<16;icm++){ m_USBpix->GetGlobalVarAddVal((m_USBpix->FEisFEI4B()?B_KILLDC0:KILLDC0)-icm, Address, Size, wValue, m_chipIds[feIndex]); DCmask[icm]=wValue; } for(int icm=0;icm<16;icm++){ m_USBpix->GetGlobalVarAddVal((m_USBpix->FEisFEI4B()?B_KILLDC16:KILLDC16)-icm, Address, Size, wValue, m_chipIds[feIndex]); DCmask[16+icm]=wValue; } for(int icm=0;icm<8;icm++){ m_USBpix->GetGlobalVarAddVal((m_USBpix->FEisFEI4B()?B_KILLDC32:KILLDC32)-icm, Address, Size, wValue, m_chipIds[feIndex]); DCmask[32+icm]=wValue; } } if(latch>=0){ if(UPC_DEBUG_GEN) cout << regName << " : " << dec << latch << endl; if(sendCfg){ if(allDcsIdentical){ if(UPC_DEBUG_GEN) cout << "Pixel register test: using WritePixel(latch)" << endl; m_USBpix->WritePixelSingleLatch(latch, m_chipIds[feIndex]); }else{ if(UPC_DEBUG_GEN) cout << "Pixel register test: using WritePixel(latch, DC)" << endl; for (int doublecolumn = DCmin; doublecolumn < DCmax; doublecolumn++){ if(DCmask[doublecolumn]==0) m_USBpix->WritePixelSingleLatchDC(latch,doublecolumn, m_chipIds[feIndex]); } } } for (int doublecolumn = DCmin; doublecolumn < DCmax; doublecolumn++){ if(DCmask[doublecolumn]==0) m_USBpix->ReadPixelSingleLatchDC(latch,doublecolumn, bypass, m_chipIds[feIndex]); } retVal = true; int pixCount=0;//(N_I4_PIXEL_COLUMNS*N_I4_PIXEL_ROWS)/32-1; for (int i=PIXEL26880; i<=PIXEL32; i++){ int DCid = pixCount/21; if(DCmask[DCid]==0 && (DC<0 || DC>39 || DCid==DC) ){ m_USBpix->GetPixelVarAddVal(i, Address, Size, wValue, latch, m_chipIds[feIndex]); m_USBpix->GetPixelRBVarAddVal(i, Address, Size, rValue, latch, bypass, m_chipIds[feIndex]); data_in.push_back(wValue); data_out.push_back(rValue); if(wValue!=rValue) retVal = false; } else{ //if(UPC_DEBUG_GEN) cout << "excluding DC " << DCid << endl; data_in.push_back(0x0); data_out.push_back(0x0); } pixCount++;//--; } if(UPC_DEBUG_GEN) cout << "PR test return " << (retVal?"true":"false") << " for register " << latch << endl; } } return retVal; } // ******************************************************* // ******* Setup for runmodes: Calibration/Data Taking *** // ******************************************************* void USBPixController::setCalibrationMode() { m_USBpix->SetCalibrationMode(); for(int ib=0;ibClearSRAM(m_chipIds[ib]); } } void USBPixController::setConfigurationMode() { } void USBPixController::setRunMode() { m_USBpix->SetRunMode(); for(int ib=0;ibClearSRAM(m_chipIds[ib]); } } // ******************************************************* // ******* Setup FE operation modes ********************** // ******************************************************* void USBPixController::setFEConfigurationMode(){ if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: setting FE(s) to config. mode"<WriteCommand(FE_CONF_MODE, m_chipIds[ib]); } } void USBPixController::setFERunMode() { if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: setting FE(s) to run mode"<WriteCommand(FE_EN_DATA_TAKE, m_chipIds[ib]); } } // ******************************************************* // ********** EPROM burning/reading ********************** // ******************************************************* void USBPixController::readEPROM() { for(int ib=0;ibReadEPROMvalues(m_chipIds[ib]); } cout << "DEBUG M.B.: USBpixController::readEPROM executed. \n"; } void USBPixController::burnEPROM() { sleep(1000); m_USBpix->BurnEPROMvalues(); sleep(1000); cout << "DEBUG M.B.: USBpixController::burnEPROM executed. \n"; } bool USBPixController::moduleActive(int nmod) { //! True if module is active during scan or run //JW: Do something like this: //return config["general"]["Active"]; //JW: Then again, we only have one 'module', that should always be active... return true; } // *********************************************** // ******* Setup scanning on the board *********** // *********************************************** int USBPixController::translateScanParam(PixScan::ScanParam param) { int scanVar; switch(param) { default: scanVar = -1; break; case PixScan::NO_PAR: // needed for fast T/GDAC tuning scanVar = m_USBpix->FEisFEI4B()?B_REG13SPARES:REG13SPARES; break; case PixScan::IF: scanVar = m_USBpix->FEisFEI4B()?B_PRMPVBPF:PRMPVBPF; break; case PixScan::GDAC: scanVar = m_USBpix->FEisFEI4B()?B_VTHIN_ALTFINE:VTHIN_ALTFINE; break; case PixScan::LATENCY: scanVar = m_USBpix->FEisFEI4B()?B_CHIP_LATENCY:CHIP_LATENCY; break; case PixScan::VCAL: scanVar = m_USBpix->FEisFEI4B()?B_PLSRDAC:PLSRDAC; break; } return scanVar; } void USBPixController::writeScanConfig(PixScan &scn) { // write scan parameters if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: entering writeScanConfig()"< stuck pixel scan, merged bumps scan m_innerLoopSwap = scn.getInnerLoopSwap(); int maskstages=0; int value = -1; int shiftmask=2; const int prWords = (N_I4_PIXEL_ROWS*N_I4_PIXEL_COLUMNS/32); int pixelmask[prWords], pixelmask2[prWords]; bool xtalk = false; for(int i=0; i16){ throw USBPixControllerExc(USBPixControllerExc::NOT_IMPLEMENTED, PixControllerExc::INFO, getModGroup().getRodName()); } for(int ib=0;ibSetGlobalVal(m_USBpix->FEisFEI4B()?B_TRIGCNT:TRIGCNT, trgcnt, m_chipIds[ib]); if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: "<< (m_USBpix->FEisFEI4B()?"B_":"") << "TRIGCNT="<SetGlobalVal(m_USBpix->FEisFEI4B()?B_DIGHITIN_SEL:DIGHITIN_SEL, (int)scn.getDigitalInjection(), m_chipIds[ib]); if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: "<< (m_USBpix->FEisFEI4B()?"B_":"") << "DIGHITIN_SEL="<SetGlobalVal(m_USBpix->FEisFEI4B()?B_CHIP_LATENCY:CHIP_LATENCY , scn.getLVL1Latency(), m_chipIds[ib]); if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: Chip Latency="<WriteGlobalSingleReg(m_USBpix->IndexToRegisterNumber(m_USBpix->FEisFEI4B()?B_DIGHITIN_SEL:DIGHITIN_SEL), m_chipIds[ib]); m_USBpix->WriteGlobalSingleReg(m_USBpix->IndexToRegisterNumber(m_USBpix->FEisFEI4B()?B_CHIP_LATENCY:CHIP_LATENCY), m_chipIds[ib]); m_USBpix->WriteGlobalSingleReg(m_USBpix->IndexToRegisterNumber(m_USBpix->FEisFEI4B()?B_TRIGCNT:TRIGCNT), m_chipIds[ib]); // set strobe delay on FE from scan config if delay isn't scanned if(scn.getStrobeMCCDelayRange()!=31 && (scn.getLoopParam(0)!=PixScan::STROBE_DELAY || !scn.getLoopActive(0)) && (scn.getLoopParam(1)!=PixScan::STROBE_DELAY || !scn.getLoopActive(1)) && (scn.getLoopParam(2)!=PixScan::STROBE_DELAY || !scn.getLoopActive(2)) ){ m_USBpix->SetGlobalVal(m_USBpix->FEisFEI4B()?B_PULSERDELAY:PULSERDELAY , scn.getStrobeMCCDelay(), m_chipIds[ib]); m_USBpix->WriteGlobalSingleReg(m_USBpix->IndexToRegisterNumber(m_USBpix->FEisFEI4B()?B_PULSERDELAY:PULSERDELAY), m_chipIds[ib]); if(UPC_DEBUG_GEN) cout << "DEBUG USBPixCtrl: Chip pulser delay=" << scn.getStrobeMCCDelay() << endl; } // set VCAL on FE from scan config if VCAL isn't scanned if(scn.getFeVCal()!=8191 && (scn.getLoopParam(0)!=PixScan::VCAL || !scn.getLoopActive(0)) && (scn.getLoopParam(1)!=PixScan::VCAL || !scn.getLoopActive(1)) && (scn.getLoopParam(2)!=PixScan::VCAL || !scn.getLoopActive(2))){ m_USBpix->SetGlobalVal(m_USBpix->FEisFEI4B()?B_PLSRDAC:PLSRDAC , scn.getFeVCal(), m_chipIds[ib]); m_USBpix->WriteGlobalSingleReg(m_USBpix->IndexToRegisterNumber(m_USBpix->FEisFEI4B()?B_PLSRDAC:PLSRDAC), m_chipIds[ib]); if(UPC_DEBUG_GEN) cout << "DEBUG USBPixCtrl: Chip pulser DAC=" << scn.getFeVCal() << endl; } if(scn.getSrcTriggerType() == PixScan::FE_SELFTRIGGER) { // enable selftrigger mode in FE m_USBpix->SetGlobalVal(m_USBpix->FEisFEI4B()?B_GATEHITOR:GATEHITOR, 1, m_chipIds[ib]); m_USBpix->WriteGlobalSingleReg(m_USBpix->IndexToRegisterNumber(m_USBpix->FEisFEI4B()?B_GATEHITOR:GATEHITOR), m_chipIds[ib]); // disable ext. trigger in FPGA m_USBpix->setTriggerMode(PixScan::USBPIX_SELF_TRG);//disableExtLV1(); cout << "USBpixController: Enabled GateHitOR and disabled ExtLV1 in FPGA." << endl; } } //Loop 0 if(!scn.getLoopActive(0)) { //JW: loop 0 is not active--> set scan parameter to VCal, scan at current value if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: Scan loop 0 is not active"<1 FE! m_scanConfigArray[0] = m_USBpix->FEisFEI4B()?B_REG13SPARES:REG13SPARES; m_scanConfigArray[1] = 0; m_scanConfigArray[2] = 0; } else{ m_scanConfigArray[0] = m_USBpix->FEisFEI4B()?B_PLSRDAC:PLSRDAC; m_scanConfigArray[1] = value; m_scanConfigArray[2] = value; } m_scanConfigArray[3]=1; } else if(scn.getDspProcessing(0)) { //JW: Get ScanParameter m_scanConfigArray[0] = translateScanParam(scn.getLoopParam(0)); if(scn.getLoopVarUniform(0)) { m_scanConfigArray[1] = (int)scn.getLoopVarMin(0); m_scanConfigArray[2] = (int)scn.getLoopVarMax(0); if ((scn.getLoopVarNSteps(0) <= 1) || (scn.getLoopVarMax(0) == scn.getLoopVarMin(0))) { // calculate scan step size m_scanConfigArray[3] = 0; } else { m_scanConfigArray[3] = (int)((scn.getLoopVarMax(0) - scn.getLoopVarMin(0)) / (scn.getLoopVarNSteps(0) - 1)); } if(m_scanConfigArray[3]<1) m_scanConfigArray[3]=1; } else { throw USBPixControllerExc(USBPixControllerExc::NON_UNIFORM_POINTS_NOT_IMPLEMENTED, PixControllerExc::FATAL, getModGroup().getRodName()); } } else { //JW: loop 0 is executed on the host // scan something that isn't used and don't touch VCAL at all - otherwise won't work for >1 FE! if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: Scan loop 0 is active but on host; scanning with REG13SPARES" << endl; m_scanConfigArray[0] = m_USBpix->FEisFEI4B()?B_REG13SPARES:REG13SPARES; m_scanConfigArray[1] = 0; m_scanConfigArray[2] = 0; m_scanConfigArray[3] = 1; } m_scanConfigArray[4] = scn.getRepetitions(); //injectCount switch(scn.getMaskStageTotalSteps()) { case PixScan::STEPS_1: maskstages = 1; break; case PixScan::STEPS_2: maskstages = 2; break; case PixScan::STEPS_3: maskstages = 3; break; case PixScan::STEPS_4: maskstages = 4; break; case PixScan::STEPS_6: maskstages = 6; break; case PixScan::STEPS_8: maskstages = 8; break; case PixScan::STEPS_32: maskstages = 32; break; case PixScan::STEPS_336: maskstages = 336; break; case PixScan::STEPS_672: maskstages = 672; break; case PixScan::STEPS_26880: maskstages = 26880;break; default: maskstages = 1; break; } m_scanConfigArray[5] = scn.getMaskStageStepWidth(); //maskStepSize; m_scanConfigArray[6] = scn.getMaskStageSteps(); //maskStepCount int capMask[3]={SHIFT_CAP1, SHIFT_CAP0, SHIFT_CAP1+SHIFT_CAP0}; switch(scn.getMaskStageMode()) { // SEL: select mask also contains Clow/Chigh info now, so must deal with this here, too case PixScan::SEL: shiftmask = capMask[scn.getChargeInjCap()]; break; case PixScan::ENA: shiftmask = SHIFT_ENABLE; break; case PixScan::SEL_ENA: shiftmask = SHIFT_ENABLE+capMask[scn.getChargeInjCap()]; break; case PixScan::HITB: shiftmask = SHIFT_HITBUS; break; case PixScan::HITB_INV: shiftmask = 0x10; break; case PixScan::ENA_HITB: shiftmask = SHIFT_ENABLE+SHIFT_HITBUS; break; case PixScan::SEL_ENA_HITB: shiftmask = SHIFT_ENABLE+SHIFT_HITBUS+capMask[scn.getChargeInjCap()]; break; case PixScan::XTALK: shiftmask = SHIFT_ENABLE+capMask[scn.getChargeInjCap()]; xtalk = true; break; case PixScan::STATIC: shiftmask = 0x00; break; default: shiftmask = 0x00; break; // static } if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: shift mask is " << shiftmask << endl; m_scanConfigArray[7] = shiftmask; //use this to shift other masks if(!scn.getLoopActive(0) || !scn.getDspProcessing(0)) //JW: loop 0 not active, expect one histogram m_scanConfigArray[8]=1; else m_scanConfigArray[8]=scn.getLoopVarNSteps(0); //keep number of steps, makes things easier m_scanConfigArray[9] = (int)scn.getLoopOverDcs(); m_scanConfigArray[10] = (int)scn.getAvoidSpecialsCols(); m_scanConfigArray[11] = (int)scn.getSingleDCloop(); // **** configuration for strobe and LVL1 signals ***** unsigned char reg_data[7]; int strb_dur=scn.getStrobeDuration(); // set the following from scan panel, otherwise cross checks aren't possible //if(m_sourceScanFlag) strb_dur = 0; //source scan: no injection, just LVL1; TODO: use trigger mode, new FPGA FSM int frequency = scn.getStrobeFrequency(); int reduce_lvl1delay = 0; if (m_triggerReplication == REPLICATION_SLAVE) // In trigger replication mode there is a delay between master and slave boards, to fix this, the lvl1 delay can be reduced reduce_lvl1delay = scn.getLowerLVL1DelayIfSlaveBy(); reg_data[0] = (0x00ff & strb_dur); //set strobe duration reg_data[1] = (0xff00 & strb_dur) >> 8; //set strobe duration reg_data[2] = 0xff & scn.getConsecutiveLvl1TrigA(0); //set consecutive LVL1 if(scn.getStrobeLVL1DelayOverride()) reg_data[3] = (scn.getStrobeLVL1Delay() - reduce_lvl1delay); //set trigger delay else reg_data[3] = m_modGroup.getTriggerDelay(); reg_data[4] = scn.getRepetitions(); //set number of injections per step reg_data[5] = (0x00ff & frequency); //set injection frequency reg_data[6] = (0xff00 & frequency) >> 8; //set injection frequency if(UPC_DEBUG_GEN){ cout<<"DEBUG USBPixCtrl: strobe settings are "; for(int kk=0;kk<7;kk++) cout << kk << ": " << ((int)reg_data[kk]) << ", "; cout << endl; } m_USBpix->WriteStrbSave(reg_data); if (scn.getSrcTriggerType()==PixScan::STROBE_SCAN || scn.getSrcTriggerType()==PixScan::STROBE_EXTTRG || scn.getSrcTriggerType()==PixScan::STROBE_USBPIX_SELF_TRG) { m_USBpix->disableTriggerReplicationMaster(); if(scn.getSrcTriggerType()==PixScan::STROBE_SCAN){ if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: m_USBpix->disableExtLV1()"<setTriggerMode(PixScan::STROBE_SCAN); if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: STROBE_SCAN trigger mode set" << " - Board-ID: " << m_boardID[0] << endl; } else if (scn.getSrcTriggerType()==PixScan::STROBE_USBPIX_SELF_TRG){ m_USBpix->setTriggerMode(PixScan::USBPIX_SELF_TRG); // USBpixSelftrigger should work without LEMO connection now. if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: USBPIX_SELF_TRG trigger mode set" << " - Board-ID: " << m_boardID[0] << endl; } else { m_USBpix->setTriggerMode(PixScan::EXT_TRG); if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: USBPIX_SELF_TRG trigger mode set" << " - Board-ID: " << m_boardID[0] << endl; } } else { if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: m_USBpix->enableExtLV1()"<enableExtLV1(); // JGK: really needed? if (m_triggerReplication == REPLICATION_SLAVE) { if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: INIT setting Trigger-Mode to 5 - Board-ID: " << m_boardID[0] << endl; m_USBpix->setTriggerMode(PixScan::USBPIX_REPLICATION_SLAVE); } else { if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: INIT setting Trigger-Mode to " << scn.getSrcTriggerType() << " - Board-ID: " << m_boardID[0] << endl; m_USBpix->setTriggerMode(scn.getSrcTriggerType()); if (m_triggerReplication == REPLICATION_MASTER) m_USBpix->enableTriggerReplicationMaster(); } } // ******** prepare pixel register masks ***************** if(scn.getMaskStageTotalSteps()!=PixScan::STEPS_USER && shiftmask) { // if mask pattern set by user, don't touch if(!scn.getLoopOverDcs() && !scn.getAvoidSpecialsCols() && scn.getLoopFEI4GR(0)=="Colpr_Addr" && scn.getLoopParam(0)==PixScan::FEI4_GR && scn.getLoopActive(0)){ // make sure Colpair_Mode ist set to scan only selected DC if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: setting cpmode to 0" << endl; for(int ib=0;ibSetGlobalVal(m_USBpix->FEisFEI4B()?B_COLPR_MODE:COLPR_MODE, 0, m_chipIds[ib]); m_USBpix->WriteGlobalSingleReg(m_USBpix->IndexToRegisterNumber(m_USBpix->FEisFEI4B()?B_COLPR_ADDR:COLPR_ADDR), m_chipIds[ib]); // first, set all pixel to off if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: resetting all masks to off"<SetPixelVal(l, 0, ENABLE, m_chipIds[ib]); if(shiftmask&SHIFT_CAP1) m_USBpix->SetPixelVal(l, 0, CAP1, m_chipIds[ib]); if(shiftmask&SHIFT_CAP0) m_USBpix->SetPixelVal(l, 0, CAP0, m_chipIds[ib]); if(shiftmask&SHIFT_HITBUS) m_USBpix->SetPixelVal(l, 0xffffffff, HITBUS, m_chipIds[ib]); // NB: 0 turns connection to hitbus ON! if(shiftmask&0x10) m_USBpix->SetPixelVal(l, 0, HITBUS, m_chipIds[ib]); // NB: 1 turns connection to Ileak ON! } // writes mask to all DCs in the same way, faster if(shiftmask&SHIFT_CAP1) m_USBpix->WritePixelSingleLatch(CAP1, m_chipIds[ib]); if(shiftmask&SHIFT_CAP0) m_USBpix->WritePixelSingleLatch(CAP0, m_chipIds[ib]); if(shiftmask&SHIFT_HITBUS || shiftmask&0x10) m_USBpix->WritePixelSingleLatch(HITBUS, m_chipIds[ib]); if(shiftmask&SHIFT_ENABLE) m_USBpix->WritePixelSingleLatch(ENABLE, m_chipIds[ib]); } } if(maskstages==26880 && !scn.getLoopOverDcs() && !scn.getAvoidSpecialsCols() && scn.getLoopFEI4GR(0)=="Colpr_Addr" && scn.getLoopParam(0)==PixScan::FEI4_GR && scn.getLoopActive(0)){ // 26880 mask loop realised by outer DC loop // set 1st pixel ON in current DC int DC = (int)(scn.getLoopVarValues(0))[scn.scanIndex(0)]; if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: writing mask for DC " << DC << endl; int index = 819-21*DC; if(index=0){ if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: setting pixel "<< index << " to 1 " << endl; for(int ib=0;ibSetPixelVal(PIXEL32-index, 1, CAP1, m_chipIds[ib]); m_USBpix->WritePixelSingleLatchDC(CAP1,DC, m_chipIds[ib]); } if((shiftmask&SHIFT_CAP1) || (!(shiftmask&SHIFT_CAP1) && shiftmask&SHIFT_CAP0) || scn.getDigitalInjection()){ m_USBpix->SetPixelVal(PIXEL32-index, 1, CAP0, m_chipIds[ib]); m_USBpix->WritePixelSingleLatchDC(CAP0,DC, m_chipIds[ib]); } if(shiftmask&SHIFT_HITBUS){ m_USBpix->SetPixelVal(PIXEL32-index, 0xfffffffe, HITBUS, m_chipIds[ib]); // 0 turns hitbus ON! m_USBpix->WritePixelSingleLatchDC(HITBUS,DC, m_chipIds[ib]); } if(shiftmask&0x10){ // inv. HITBUS m_USBpix->SetPixelVal(PIXEL32-index, 1, HITBUS, m_chipIds[ib]); // 1 turns Ileak ON! m_USBpix->WritePixelSingleLatchDC(HITBUS,DC, m_chipIds[ib]); } if(shiftmask&SHIFT_ENABLE){ m_USBpix->SetPixelVal(PIXEL32-index, 1, ENABLE, m_chipIds[ib]); m_USBpix->WritePixelSingleLatchDC(ENABLE,DC, m_chipIds[ib]); } } } else if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: pixel index "<< index << " out of range (0...839) " << endl; }else{ // prepare mask pattern for (int j = 0; j < N_I4_PIXEL_COLUMNS*N_I4_PIXEL_ROWS; j++) { //JW: this loops over all pixels in the FE if(j%maskstages==0) { //if(!xtalk) pixelmask[j/32] = pixelmask[j/32] | (0x1<<(j%32)); //else pixelmask[j/32] = pixelmask[j/32] | (0x1<<((j%32)+1)); //*********** //only implemented for maskstage%4==0 if(j%32>0) { //JW: only possible if not 32-step-mask pixelmask2[j/32]= pixelmask2[j/32]| (0x1<<((j%32)+1)); pixelmask2[j/32]= pixelmask2[j/32]| (0x1<<((j%32)-1)); } else { //JW: first step for 32-step-mask pixelmask2[j/32]= pixelmask2[j/32]| 0x2; if(j/32) pixelmask2[j/32-1]= pixelmask2[j/32-1]| 0x80000000; } } } // then, load actual content and write to all DCs for(int ib=0;ibSetPixelVal(l, pixelmask[PIXEL32-l], ENABLE, m_chipIds[ib]); if(shiftmask&SHIFT_CAP1){ if(UPC_DEBUG_GEN && l == PIXEL26880) cout<<"DEBUG USBPixCtrl: turning CAP1 ON" << endl; if(!xtalk) m_USBpix->SetPixelVal(l, pixelmask[PIXEL32-l], CAP1, m_chipIds[ib]); else m_USBpix->SetPixelVal(l, pixelmask2[PIXEL32-l], CAP1, m_chipIds[ib]); } if(scn.getDigitalInjection() || (!(shiftmask&SHIFT_CAP1) && shiftmask&SHIFT_CAP0)) { // turn cap's off for digital injectionand SEL with CAP1 off if(UPC_DEBUG_GEN && l == PIXEL26880) cout<<"DEBUG USBPixCtrl: turning CAP1 OFF" << endl; m_USBpix->SetPixelVal(l, 0, CAP1, m_chipIds[ib]); } if(shiftmask&SHIFT_CAP0) { if(UPC_DEBUG_GEN && l == PIXEL26880) cout<<"DEBUG USBPixCtrl: turning CAP0 ON" << endl; if(!xtalk) m_USBpix->SetPixelVal(l, pixelmask[PIXEL32-l], CAP0, m_chipIds[ib]); else m_USBpix->SetPixelVal(l, pixelmask2[PIXEL32-l], CAP0, m_chipIds[ib]); } if(scn.getDigitalInjection() || (!(shiftmask&SHIFT_CAP0) && shiftmask&SHIFT_CAP1)) { if(UPC_DEBUG_GEN && l == PIXEL26880) cout<<"DEBUG USBPixCtrl: turning CAP0 OFF" << endl; // turn cap's off for digital injection and SEL with CAP0 off m_USBpix->SetPixelVal(l, 0, CAP0, m_chipIds[ib]); } if(shiftmask&SHIFT_HITBUS) // NB: 0 turns connection to hitbus ON! m_USBpix->SetPixelVal(l, ~(pixelmask[PIXEL32-l]), HITBUS, m_chipIds[ib]); if(shiftmask&0x10) // NB: 1 turns connection to Ileak ON! m_USBpix->SetPixelVal(l, pixelmask[PIXEL32-l], HITBUS, m_chipIds[ib]); } int DC=40; if(!scn.getLoopOverDcs() && !scn.getAvoidSpecialsCols() && scn.getLoopFEI4GR(0)=="Colpr_Addr" && scn.getLoopParam(0)==PixScan::FEI4_GR && scn.getLoopActive(0)) DC = (int)(scn.getLoopVarValues(0))[scn.scanIndex(0)]; // writes mask to all DCs in the same way, faster if((shiftmask&SHIFT_CAP1) || (!(shiftmask&SHIFT_CAP1) && shiftmask&SHIFT_CAP0) || scn.getDigitalInjection()) { if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: writing mask CAP1 for DC "<WritePixelSingleLatchDC(CAP1, DC, m_chipIds[ib]); } if((shiftmask&SHIFT_CAP0) || (!(shiftmask&SHIFT_CAP0) && shiftmask&SHIFT_CAP1) || scn.getDigitalInjection()) { if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: writing mask CAP0 for DC "<WritePixelSingleLatchDC(CAP0, DC, m_chipIds[ib]); } if(shiftmask&SHIFT_HITBUS || shiftmask&0x10){ if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: writing mask HITBUS for DC "<WritePixelSingleLatchDC(HITBUS, DC, m_chipIds[ib]); } if(shiftmask&SHIFT_ENABLE){ if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: writing mask ENABLE for DC "<WritePixelSingleLatchDC(ENABLE, DC, m_chipIds[ib]); } } } } if(scn.getHistogramFilled(PixScan::DSP_ERRORS)){ // read error GR's and service records to clear them for(int ib=0;ib srvCounts; getServiceRecords(txt, srvCounts); } // after config, switch back to data taking mode for(int ib=0;ibWriteCommand(FE_EN_DATA_TAKE, m_chipIds[ib]); } // ******** end pixel register settings ************************ // source scan if(m_sourceScanFlag) { // get histogram parameters scn.getClusterPars(m_clusterPars[0], m_clusterPars[1], m_clusterPars[2], m_clusterPars[3]); m_rawDataFilename=scn.getSourceRawFile(); m_skipSourceScanHistos=scn.getSkipSourceScanHistos(); // fill histograms that do not need clustering m_fillSrcHistos = scn.getHistogramFilled(PixScan::OCCUPANCY) || scn.getHistogramFilled(PixScan::TOT) || scn.getHistogramFilled(PixScan::LVL1); // fill histograms that need clustering m_fillClusterHistos = scn.getHistogramFilled(PixScan::HITOCC) || scn.getHistogramFilled(PixScan::CLUSTER_TOT) || scn.getHistogramFilled(PixScan::CLUSTER_SIZE) || scn.getHistogramFilled(PixScan::CLSIZE_TOT) || scn.getHistogramFilled(PixScan::SEED_TOT) || scn.getHistogramFilled(PixScan::SEED_LVL1) || scn.getHistogramFilled(PixScan::NSEEDS); // set FPGA register m_USBpix->WriteRegister(CS_TLU_TRIGGER_DATA_LENGTH, 15); // set TLU trigger data length (depends on TLU bit-file) m_USBpix->WriteRegister(CS_TLU_TRIGGER_DATA_DELAY, scn.getTLUTriggerDataDelay()); // set additional wait cycles (5) m_USBpix->SetNumberOfEvents(scn.getRepetitions()); // write #hits to FPGA register m_SourceScanEventQuantity = scn.getRepetitions(); if (scn.getSrcTriggerType()==PixScan::STROBE_SCAN || scn.getSrcTriggerType()==PixScan::STROBE_EXTTRG || scn.getSrcTriggerType()==PixScan::STROBE_USBPIX_SELF_TRG) { // need internal strobes for noise occupancy m_USBpix->WriteStrbQuantity(0); // endless sending of strobes m_USBpix->WriteStrbStart(); } //if (!scn->getTestBeamFlag()) { clearSourceScanHistos(); if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: clearSourceScanHistos()"<WriteRegister(CS_ENABLE_RJ45, (m_enableRJ45 ? 1 : 0)); if(UPC_DEBUG_GEN) cout << "DEBUG USBPixCtrl: RJ45 " << (m_enableRJ45?"ON":"OFF") << endl; //} else { // if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: RJ45 ON (beam test mode)" << endl; // m_USBreg->WriteRegister(CS_ENABLE_RJ45, 1); //} // set counter mode if(UPC_DEBUG_GEN) cout<<"DEBUG: source measurement count mode: " << scn.getSrcCountType() <SetNumberOfEvents(0);// endless running, will abort from internal time control m_SourceScanEventQuantity = 0; m_srcSecMax = scn.getRepetitions(); break; } m_USBpix->SetMeasurementMode(cntMode); } } void USBPixController::writeScanConfig(PixScanConfig &cfg) { //! Write scan parameters //cout<<"INFO: Scan configurations through PixScanConfig objects don't seem to be used anywhere"<getSourceScanFlag(); if (!m_sourceScanFlag) m_scanBusy = true; else m_sourceScanBusy = true; // write scan configuration writeScanConfig(*scn); if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: finished writeScanConfig()"<getHistogramFilled(PixScan::TOT_MEAN) || scn->getHistogramFilled(PixScan::TOT_SIGMA) || scn->getHistogramFilled(PixScan::TOT)|| scn->getHistogramFilled(PixScan::TOT0) || scn->getHistogramFilled(PixScan::TOT1) || scn->getHistogramFilled(PixScan::TOT2) || scn->getHistogramFilled(PixScan::TOT3) || scn->getHistogramFilled(PixScan::TOT4) || scn->getHistogramFilled(PixScan::TOT5) || scn->getHistogramFilled(PixScan::TOT6) || scn->getHistogramFilled(PixScan::TOT7) || scn->getHistogramFilled(PixScan::TOT8) || scn->getHistogramFilled(PixScan::TOT9) || scn->getHistogramFilled(PixScan::TOT10) || scn->getHistogramFilled(PixScan::TOT11) || scn->getHistogramFilled(PixScan::TOT12) || scn->getHistogramFilled(PixScan::TOT13) || scn->getHistogramFilled(PixScan::TOT14) || scn->getHistogramFilled(PixScan::TOT15)) { if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: Filling TOT histo"<SetTOTMode(); for(int ib=0;ibClearTOTHisto(m_chipIds[ib]); } } else if (scn->getHistogramFilled(PixScan::OCCUPANCY)) { m_USBpix->SetCalibrationMode(); if(UPC_DEBUG_GEN) cout << "DEBUG Malte: Set Hit histogramming mode.\n"; for(int ib=0;ibClearConfHisto(m_chipIds[ib]); } } // clear SRAM *here* and *before* calling USBpix::StartScan() for(int ib=0;ibClearSRAM(m_chipIds[ib]); } // to avoid race conditions: // reset scan status bits *before* calling the method USBpix::StartScan() and *before* setting m_upcScanInit to false m_USBpix->ResetScanStatus(); if (scn->getMaskStageMode() == PixScan::XTALK) { //JW: run first step of scan here if(UPC_DEBUG_GEN) cout << "DEBUG: scn->getMaskStageMode() == PixScan::XTALK" << endl; //do the first scan step - i.e. 6th arg. is 1, not m_scanConfigArray[6] if(UPC_DEBUG_GEN) cout << "DEBUG: Xtalk: m_USBPix->StartScan()" << endl; m_USBpix->StartScan(m_scanConfigArray[0], m_scanConfigArray[1], m_scanConfigArray[2], m_scanConfigArray[3], m_scanConfigArray[4], m_scanConfigArray[5], 1, m_scanConfigArray[7],(bool)m_scanConfigArray[9], (bool)m_scanConfigArray[10], (bool)m_scanConfigArray[11]); if(UPC_DEBUG_GEN) cout << "DEBUG: Xtalk: finished m_USBPix->StartScan()" << endl; //decrease number of masksteps to do by one m_scanConfigArray[6]--; //go ahead and run from the second maskstep on, if one is left if(m_scanConfigArray[6]==0){ m_upcScanInit = false; m_upcStartScanHasFinished = true; return; } for(int ib=0;ibClearSRAM(m_chipIds[ib]); } m_USBpix->ResetScanStatus(); // shift CAP masks by filling 1, ENABLE by filling 0 if(m_scanConfigArray[7]&SHIFT_ENABLE) shiftPixMask(SHIFT_ENABLE, 1); if(m_scanConfigArray[7]&SHIFT_CAP0) shiftPixMask(0x20, 1); if(m_scanConfigArray[7]&SHIFT_CAP1) shiftPixMask(0x40, 1); } if(UPC_DEBUG_GEN){ cout<<"DEBUG USBPixCtrl: scan parameters: "; for(int kk=0;kkgetSrcTriggerType()!=PixScan::STROBE_SCAN){ // start measuerement, otherwise ext. trigger is ignored if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: m_USBpix->StartMeasurement()"<StartMeasurement(); } // USBpix::StartScan() is not a thread, so setting m_upcScanInit to false enables readout of scan status // this has to happen *before* calling the method USBpix::StartScan() // now it is safe to call the method USBpix::GetScanStatus() because it will only readout member variables, *no* microcontroller access is needed m_upcScanInit = false; // start scan // this is *not* a thread so flow will stuck here until scan has finished if(UPC_DEBUG_GEN){ cout<<"DEBUG USBPixCtrl: calling USBpix::StartScan"<StartScan(m_scanConfigArray[0], m_scanConfigArray[1], m_scanConfigArray[2], m_scanConfigArray[3], m_scanConfigArray[4], m_scanConfigArray[5], m_scanConfigArray[6], m_scanConfigArray[7], (bool)m_scanConfigArray[9], // Malte: bool temporary added to choose scan mode all DCs or respect COLPR_MODE + ADDR... (bool)m_scanConfigArray[10], // JGK: bool temporary added to choose scan mode avoiding simulataneous injection into col's 0, 77, 78, 79 (bool)m_scanConfigArray[11]); // JGK: bool temporary added to choose scan mode for ToT measurements if(scn->getSrcTriggerType()!=PixScan::STROBE_SCAN){ // stop measuerement if it was started earlier on if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: m_USBpix->StopMeasurement()"<StopMeasurement(); } if(!scanret){ if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: USBpix::StartScan returns " << (scanret?"true":"false") << endl; // to do: throw an exception } } else { // source scan if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: starting source scan"<SetRunMode(); // write new raw file m_newRawDataFile = true; // clear SRAM for(int ib=0;ibClearSRAM(m_chipIds[ib]); } // start source scan here m_USBpix->StartMeasurement(); m_srcSecStart = clock()/CLOCKS_PER_SEC; } // setting m_upcScanInit to false to make readout of scan status information possible. // now all scan status bits are set properly, race conditions are avoided // normal scan needs a special treatment since not implemented as a thread m_upcScanInit = false; // m_scanDone has to be asserted here, not in nTrigger() // this is due to the bad implementation of strobe scan and because of USBpix::StartScan() is not a thread m_upcStartScanHasFinished = true; } void USBPixController::stopScan() { if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: entering stopScan()"<SetScanCancelled()"<SetScanCancelled(); // set cancel flag, so we know that scan was cancelled/stopped m_upcScanCancelled = true; } else if(m_upcScanBusy && m_sourceScanBusy) { // source scan if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: m_USBpix->StopMeasurement()"<StopMeasurement(); m_USBpix->WriteStrbStop(); // in case strobe was started; shouldn't harm otherwise m_USBpix->SetNumberOfEvents(0); // Make sure number of events to count is 0 after scan. Might be troublesome in strobe scan with external/self triggering otherwise. m_SourceScanEventQuantity = 0; // set cancel flag, so we know that scan was cancelled/stopped m_upcScanCancelled = true; } } // ******* Histogram treatment on the board ****** bool USBPixController::fitHistos() { //! Fit collected histograms return false; } void USBPixController::getFitResults(HistoType type, unsigned int mod, unsigned int slv, std::vector< Histo * > &thr, std::vector< Histo * > &noise, std::vector< Histo * > &chi2) { //! Read a Fit from Dsp } void USBPixController::getErrorHistos(unsigned int dsp, Histo* &his) { //! Read collected error arrays std::ostringstream nam, tit; nam << "FE_errors"; tit << "FE Errors"; int histsize = 0, errbins=(32+5); // 0..31: service records; 32: CMDErrReg SEU, 33: CMDErrReg BitFlip, 34: CMDErrReg Trg BitFlip, 35: CMDErrReg hdr BitFlip, 36: EOCHLSkipped for(int ib=0;ibset(32+ib*errbins, readGlobal(42, ib)&0x3f); his->set(33+ib*errbins, (readGlobal(42, ib)&0x7c0)>>6); his->set(34+ib*errbins, (readGlobal(42, ib)&0x3800)>>11); his->set(35+ib*errbins, (readGlobal(42, ib)&0xc000)>>14); his->set(36+ib*errbins, (readGlobal(41, ib)&0xff00)>>8); } std::string txt; std::vector srvCounts; getServiceRecords(txt, srvCounts); for(unsigned int i=0;iset(ih, srvCounts[i]); } } void USBPixController::clearSourceScanHistos() { if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: entered clearSourceScanHistos()"<ClearHitHistoFromRawData(m_chipIds[ib]); m_USBpix->ClearHitTOTHistoFromRawData(m_chipIds[ib]); m_USBpix->ClearHitLV1HistoFromRawData(m_chipIds[ib]); m_USBpix->ClearClusterSizeHistoFromRawData(m_chipIds[ib]); m_USBpix->ClearClusterTOTHistoFromRawData(m_chipIds[ib]); m_USBpix->ClearClusterSeedTOTHistoFromRawData(m_chipIds[ib]); m_USBpix->ClearClusterSeedLV1HistoFromRawData(m_chipIds[ib]); m_USBpix->ClearClusterSeedHistoFromRawData(m_chipIds[ib]); m_USBpix->ClearClusterSeedPerTriggerHistoFromRawData(m_chipIds[ib]); } } void USBPixController::writeRawDataFile(bool close_file, int chipIndex) { // to do: currently called if any of the boards has a full SRAM if (UPC_DEBUG_GEN) cout << "DEBUG USBPixCtrl: WriteFileFromRawData("<WriteFileFromRawData(m_rawDataFilename, chipIndex, m_newRawDataFile, close_file, m_fillSrcHistos, m_fillClusterHistos, m_clusterPars[0], m_clusterPars[1], m_clusterPars[2], m_clusterPars[3]); if (UPC_DEBUG_GEN) cout << "DEBUG USBPixCtrl: WriteFileFromRawData return " << (retval?"true":"false") << endl; } } void USBPixController::getHisto(HistoType type, unsigned int mod, unsigned int slv, std::vector< std::vector > &his) { // Read a histogram if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: entered getHisto()"< vh; //make sure, the vector we his.push_back(vh); //want to write to exists if(mod!=0) mod = 0; //need only treat one module at the moment his[mod].clear(); //clear vector for writing // source scan needs special types of histograms if(m_sourceScanFlag) { if (type == OCCUPANCY || type == HITOCC) MadeHitHisto = true; if (TOTmode) MadeTOTHisto = true; } //JW: the scan configuration should be the one from the last scan, //JW: i.e. the scan, whose data we're downloading int bins = m_scanConfigArray[8]; if(UPC_DEBUG_GEN) cout << "DEBUG USBPixCtrl: bins=" << bins << ", MadeHitHisto=" << (MadeHitHisto?"true":"false") << ", MadeTOTHisto=" << (MadeTOTHisto?"true":"false") << endl; // *** now loop over the innermost scanloop, e.g. VCal *** for(int i=0; iGetHitHistoFromRawData(col, row, nr_hits, m_chipIds[ib]); // source scan else if(type==HITOCC) m_USBpix->GetClusterSeedHistoFromRawData(col, row, 0, nr_hits, m_chipIds[ib]); // normal scan }else m_USBpix->GetConfHisto(col, row, i, nr_hits, m_chipIds[ib]); // normal scan, configuration parameter i starts from 0 h->set(colm, row, nr_hits); } else { TOTsumsqr=0; TOTsum=0; hitsum=0; TOTsqravg=0; TOTavg=0; for(int tot=0; tot<16; tot++) { if(MadeTOTHisto) m_USBpix->GetHitTOTHistoFromRawData(col, row, tot, nr_hits, m_chipIds[ib]); // source scan ToT else m_USBpix->GetTOTHisto(col, row, tot, nr_hits, m_chipIds[ib]); // normal scan ToT TOTsumsqr+=(nr_hits*tot*tot); TOTsum+=(nr_hits*tot); hitsum+=nr_hits; ToThis[tot]+=nr_hits; if(type == TOT0 && tot == 0 ){ h->set(colm, row, nr_hits); } if(type == TOT1 && tot == 1 ){ h->set(colm, row, nr_hits); } if(type == TOT2 && tot == 2 ){ h->set(colm, row, nr_hits); } if(type == TOT3 && tot == 3 ){ h->set(colm, row, nr_hits); } if(type == TOT4 && tot == 4 ){ h->set(colm, row, nr_hits); } if(type == TOT5 && tot == 5 ){ h->set(colm, row, nr_hits); } if(type == TOT6 && tot == 6 ){ h->set(colm, row, nr_hits); } if(type == TOT7 && tot == 7 ){ h->set(colm, row, nr_hits); } if(type == TOT8 && tot == 8 ){ h->set(colm, row, nr_hits); } if(type == TOT9 && tot == 9 ){ h->set(colm, row, nr_hits); } if(type == TOT10 && tot == 10 ){ h->set(colm, row, nr_hits); } if(type == TOT11 && tot == 11 ){ h->set(colm, row, nr_hits); } if(type == TOT12 && tot == 12 ){ h->set(colm, row, nr_hits); } if(type == TOT13 && tot == 13 ){ h->set(colm, row, nr_hits); } if(type == TOT14 && tot == 14 ){ h->set(colm, row, nr_hits); } if(type == TOT15 && tot == 15 ){ h->set(colm, row, nr_hits); } } if(hitsum > 1) { TOTsqravg = (double)TOTsumsqr/(double)hitsum; TOTavg = (double)TOTsum/(double)hitsum; TOTsigma = ((double)(TOTsqravg-TOTavg*TOTavg)/(double)(hitsum-1)); } else { TOTsqravg = 0; TOTavg = 0; TOTsigma = 0; } if(type == TOT_MEAN) { h->set(colm, row, (double)TOTavg); } else if(type == TOT_SIGMA) { h->set(colm, row, (double)TOTsigma); } else if(type == OCCUPANCY) { h->set(colm, row, (double)hitsum); } } } } } } if(type == TOT) { for(int i=0;i<16;i++) h->set(i, (double)ToThis[i]); } int value, cvalue; if(type==LVL1 || type==CLUSTER_SIZE || type==SEED_LVL1 || type==NSEEDS) { for(int i=0;i<16;i++){ value = 0; for(int ib=0;ibGetHitLV1HistoFromRawData(i, cvalue, m_chipIds[ib]); break; case CLUSTER_SIZE: m_USBpix->GetClusterSizeHistoFromRawData(i, cvalue, m_chipIds[ib]); break; case SEED_LVL1: m_USBpix->GetClusterSeedLV1HistoFromRawData(i, 0, cvalue, m_chipIds[ib]); break; case NSEEDS: m_USBpix->GetClusterSeedPerTriggerHistoFromRawData(i, cvalue, m_chipIds[ib]); break; default: value = 0; } value += cvalue; } h->set(i, (double)value); } } if(type==CLSIZE_TOT) { for(int i=0;i<15;i++){ for(int j=0;j<16;j++){ value = 0; for(int ib=0;ibGetClusterTOTHistoFromRawData(i, j, cvalue, m_chipIds[0]); // j = 0: every cluster size value += cvalue; } h->set(i, j, (double)value); } } } if(type==CLUSTER_TOT || type==SEED_TOT) { for(int i=0;i<16;i++){ value = 0; for(int ib=0;ibGetClusterTOTHistoFromRawData(i, 0, cvalue, m_chipIds[0]); // j = 0: every cluster size else m_USBpix->GetClusterSeedTOTHistoFromRawData(i, 0, cvalue, m_chipIds[0]); value += cvalue; } h->set(i, (double)value); } } his[mod].push_back(h); //JW: DO NOT DELETE h HERE! It is passed to the vector his not as pointer but as itself... if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: histogram downloaded"<GetScanStatus(m_scanReady, m_scanCancelled, m_scanError, m_scanStep); if(UPC_DEBUG_FLAGS) cout<<"DEBUG USBPixCtrl: m_USBpix->GetScanStatus()"<m_srcSecMax) stopScan(); } // to do : check if the displayed quantities can be revised for >1 FE int collectedTriggersTotal=0; for(int ib=0;ibGetSourceScanStatus() board "<GetSourceScanStatus(m_sramFull, measurementRunning, sramFillLevel, collectedTriggers, triggerRate, m_chipIds[ib]); m_measurementRunning |= measurementRunning; if(m_sramFillLevel > sramFillLevel) m_sramFillLevel = sramFillLevel; if(m_triggerRate < triggerRate) m_triggerRate = triggerRate; collectedTriggersTotal += collectedTriggers; if(!measurementRunning/* && m_sramReadoutReady*/) { // TODO if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: MeasRunning(" << ib << ") = false => reading SRAM..."<WriteStrbStop(); // to be sure injection/trigger FSM is stopped. Additional call makes no harm... m_USBpix->SetNumberOfEvents(0); // Make sure number of events to count is 0 after scan. Might be troublesome in strobe scan with external/self triggering otherwise. m_SourceScanEventQuantity = 0; m_USBpix->ReadSRAM(m_chipIds[ib]); writeRawDataFile(true, m_chipIds[ib]); m_USBpix->ClearSRAM(m_chipIds[ib]); } else if(measurementRunning && m_sramFull/* && m_sramReadoutReady*/) { // TODO if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: SRAMFull(" << ib << ") => reading SRAM..."<ReadSRAM(m_chipIds[ib]); int tafter = clock()/CLOCKS_PER_SEC; m_srcSecStart += tafter-tbefore; writeRawDataFile(false, m_chipIds[ib]); m_newRawDataFile = false; m_USBpix->ClearSRAM(m_chipIds[ib]); } } if ((m_SourceScanEventQuantity != 0) && (collectedTriggersTotal >= m_SourceScanEventQuantity)) stopScan(); if(UPC_DEBUG_GEN) cout<<"DEBUG: SRAMReadoutReady: "<<(m_sramReadoutReady?"true":"false")<<" SRAMFull: "<<(m_sramFull?"true":"false")<<" measurementPause: "<<(m_measurementPause?"true":"false")<<" measurementRunning: "<<(m_measurementRunning?"true":"false")<<" collectedTriggers: "<* &data) { //} void USBPixController::hwInfo(string &txt){ txt = ""; for(int ib=0;ibGetName()) + "\n"; stringstream a; a << m_BoardHandle[ib]->GetId(); txt += "Board ID: " + a.str() + "\n"; stringstream b; b << m_BoardHandle[ib]->GetFWVersion(); txt += "uC Firmware: " + b.str() + "\n"; // create temporary adapter card interace to read ID USBPixDCS USBADC(m_BoardHandle[ib]); USBADC.Init(); stringstream c; c << USBADC.GetId(); txt += "Adapter card ID: " + c.str() + "\n"; } } return; } void USBPixController::shiftPixMask(int mask, int steps){ if(m_USBpix!=0){ const int nmasks=7; int maskTags1[nmasks]={SHIFT_ENABLE, SHIFT_CAP0, SHIFT_CAP1, SHIFT_HITBUS, 0x10, 0x20, 0x40}; int maskTags2[nmasks]={ENABLE, CAP0, CAP1, HITBUS, HITBUS, CAP0, CAP1}; for(int imask=0;imaskShiftPixMask(maskTags2[imask], steps, m_chipIds[ib], (maskTags1[imask]==SHIFT_HITBUS || maskTags1[imask]==0x20 || maskTags1[imask]==0x40)); } } } } return; } int USBPixController::readHitBusScaler(int mod, int ife, PixScan* scn){ return (int)checkRxState(RX0); } void USBPixController::updateDeviceHandle(){ for(int ib=0;ibSetDeviceHandle(tempHandle); if(UPC_DEBUG_GEN) cout <<"INFO: USBPixController::updateDeviceHandle found "<< m_BoardHandle[ib]->GetName() << " with ID " << m_BoardHandle[ib]->GetId() <GetSyncScanResult(SyncScanResultsX[ib], SyncScanResultsY[ib], nPhBins, m_chipIds[ib]); for(int i=1;i*/SyncScanResultsY[ib][i]!=0 && /*cr[ib]->*/SyncScanResultsX[ib][i]!=0) cout << 69* /*cr[ib]->*/SyncScanResultsX[ib][i] << " - " << /*cr[ib]->*/SyncScanResultsY[ib][i] << endl; } } int iend_max = 0, iend[NBOARDS_MAX]; for(int ib=0;ib*/SyncScanResultsY[ib][i]==0 && /*cr[ib]->*/SyncScanResultsX[ib][i]==0) { iend[ib] = i; break; } } if(iend[ib]>iend_max) iend_max = iend[ib]; } Histo *h = 0; if(nFe==1){ if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: syncScan: creating histogram in " << (iend[0]-1) << " bins " << endl; h = new Histo("Errorrate_0", "Error-rate-vs-phase mod 0", iend[0]-1, (/*cr[0]->*/SyncScanResultsX[0][1]-0.5)*69, (/*cr[0]->*/SyncScanResultsX[0][iend[0]-1]+0.5)*69); for(int i=1;iset(i-1, /*cr[0]->*/SyncScanResultsY[0][i]); } else{ if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: syncScan: creating histogram in " << (iend_max-1) << " bins " << endl; h = new Histo("Errorrate_0", "Error-rate-vs-phase_index and FE ID mod 0", iend_max-1, -0.5, -1.5+(double)iend_max, nFe, -0.5, -0.5+(double)nFe); for(int ib=0;ibset(i-1, ib, /*cr[ib]->*/SyncScanResultsY[ib][i]); } } return h; } SiUSBDevice* USBPixController::getUsbHandle(){ return m_BoardHandle[0]; } bool USBPixController::checkRxState(rxTypes type){ bool retval = false; switch(type){ case RX0: retval = m_USBpix->CheckRX0State(); break; case RX1: retval = m_USBpix->CheckRX1State(); break; case RX2: retval = m_USBpix->CheckRX2State(); break; case EXT_TRG: retval = m_USBpix->CheckExtTriggerState(); break; default: break; } //if(UPC_DEBUG_GEN) cout<<"USBPixController::checkRxState returns " << (retval?"TRUE":"FALSE") << endl; return retval; } void USBPixController::getServiceRecords(std::string &txt, std::vector &srvCounts){ if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: called getServiceRecords" << endl; int nFe=0; const unsigned int asize = SRAM_WORDSIZE-1; unsigned int *SRAMwordsRB = (unsigned int*) malloc(asize * sizeof(unsigned int)); if(SRAMwordsRB==0) throw USBPixControllerExc(USBPixControllerExc::ALLOC_PROBLEM, PixControllerExc::ERROR, getCtrlName()); for(int ib=0;ibStartMeasurement(); for(int ib=0;ibSendReadErrors(m_chipIds[ib]); if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: finished m_USBpix->SendReadErrors(m_chipIds[ib]) for board " << ib << endl; } sleep(500); m_USBpix->StopMeasurement(); // Not needed since interface function implemented std::stringstream srvrecStream; for(int ib=0;ibReadSRAM(m_chipIds[ib]); m_USBpix->GetSRAMWordsRB(SRAMwordsRB, asize, m_chipIds[ib]); if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: got SSRAMwordsRB for board " << ib << endl; srvrecStream << "FE " << ib; for (int word = 0; word < (int)asize; word++){ if (!EMPTY_RECORD_MACRO(SRAMwordsRB[word]) && SERVICE_RECORD_MACRO(SRAMwordsRB[word])){ int recID = SERVICE_RECORD_CODE_MACRO(SRAMwordsRB[word]); int recCnt = SERVICE_RECORD_COUNTER_MACRO(SRAMwordsRB[word]); srvrecStream << "Code \t" << recID << "\t Counter \t" << recCnt << endl; if(recID>=0 && recID<31) srvCounts[recID+ib*32] = recCnt; } } m_USBpix->ClearSRAM(m_chipIds[ib]); } txt = srvrecStream.str(); delete SRAMwordsRB; if(UPC_DEBUG_GEN) cout<<"DEBUG USBPixCtrl: service record request returns " << txt << endl; } bool USBPixController::testScanChain(std::string chainName, std::vector data_in, std::string &data_out, std::string data_cmp, bool shift_only, bool se_while_pulse, bool si_while_pulse, PixDcs *dcs, double &curr_bef, double &curr_after, int feIndex){ USBPixDcs *updcs = dynamic_cast(dcs); USBPixDCS *dll_upd=0; if(updcs!=0) dll_upd = updcs->getHwPtr(); // to do: define specific exception for this type of error else throw USBPixControllerExc(USBPixControllerExc::NO_PIXDCS, PixControllerExc::ERROR, getCtrlName()); int value, add, size; int scanChain = -1, indStart=-1, indEnd=-1; bool passFlag = true; if(chainName=="DOB"){ scanChain = SC_DOB; indStart = SCDOB0; indEnd = SCDOB2; } else if(chainName=="CMD"){ scanChain = SC_CMD; indStart = SCCMD0; indEnd = SCCMD8; } else if(chainName=="ECL"){ scanChain = SC_ECL; if(m_USBpix->FEisFEI4B()){ indStart = B_SCECL0; indEnd = B_SCECL108; } else{ indStart = SCECL0; indEnd = SCECL99; } } // to do: define specific exception for this type of error else throw USBPixControllerExc(USBPixControllerExc::UNKNOWN_CHAIN, PixControllerExc::ERROR, getCtrlName()+" (scan chain "+ chainName+")"); if(data_in.size()!=(unsigned int)(indEnd-indStart+1)) throw USBPixControllerExc(USBPixControllerExc::WRONG_DATASIZE, PixControllerExc::ERROR, getCtrlName()); for (int index = indStart; index <= indEnd; index++) m_USBpix->SetScanChainValue(scanChain, index, data_in[index-indStart], feIndex); m_USBpix->RunScanChain(scanChain, dll_upd, curr_bef, curr_after, shift_only, se_while_pulse, si_while_pulse, feIndex); data_out =""; for (int index = indStart; index <= indEnd; index++){ m_USBpix->GetScanChainValueRB(scanChain, index, size, add, value, feIndex); std::string rval,eval; for(int is=0; is