///////////////////////////////////////////////////////////////// // // // FED debugging tool // // // // Author: John Coughlan // // date: 06/05/2003 // // notes: based on Matt Noy's VME interface debugging tool // // // // // ///////////////////////////////////////////////////////////////// // CAEN Bus Adapter added by Jon Fulcher 19.06.2005 // version used for pedestal loading tests nov 2005 // latest version of code found as of 08.12.05 // use #define offsets in single read write methods // added user input for fixed peds and cluster thresholds 08.12.05 jac // version checked out from cern cvs 30.01.06 // now using local cvs repository on cmsfed1.te 08.03.2006 // added check for status of Serial Command line before each Serial Read and Write 08.03.06 // recovered code (version was dated 11.05.08) after cmsfed1 hdisk failure 24.08.06 jac // and don't exit on serial command line failure 30.08.06 jac // allow user to specify ammount of formatted spy data to display 20.09.06 jac // added new daq reg two and be status two registers 09.11.06 jac #ifndef _FFv1Object_hh_ #define _FFv1Object_hh_ #include "StopWatch.hh" //#include "VMEDummyBusAdapter.hh" //#define BUILD_CAEN #ifdef BUILD_CAEN #include "CAEN2718LinuxPCIBusAdapter.hh" #else #include "SBS620x86LinuxBusAdapter.hh" #endif /* #include "VMEBusAdapterInterface.hh" #ifdef BUILD_NIVXI #include "MXI2x86LinuxBusAdapter_test.hh" #elseifdef BUILD_CAEN #include "CAENVMElib.h" #else #include "SBS620x86LinuxBusAdapter.hh" #endif */ #include "VMEAddressTableASCIIReader.hh" #include "VMEDevice.hh" #include "VMEAddressTable.hh" #include #include #include #include using namespace std; // simple FED MMAP ; BYTE offsets const unsigned int FED_Serial_BRAM = 0x0000; const unsigned int FED_Serial_Write = 0x0800; const unsigned int FED_Serial_Read = 0x0804; const unsigned int FED_Serial_Status = 0x080c; const unsigned int FED_Board_ID = 0x0810; const unsigned int FED_Readout_Buffer_Length = 0x0820; const unsigned int FED_Readout_Event_Ctr = 0x0824; const unsigned int FED_Readout_Event_Length = 0x0828; const unsigned int FED_Readout_CSR = 0x082c; const unsigned int FED_Firmware_ID = 0x0830; const unsigned int FED_Clock_Select = 0x0834; const unsigned int FED_Reset = 0x0838; const unsigned int FED_VME_Status = 0x083c; const unsigned int FED_TTC_Clk_Ctr = 0x0840; const unsigned int FED_BP_Clk_Ctr = 0x0844; const unsigned int FED_Spy_Cmd_LSB = 0x0850; const unsigned int FED_Spy_Cmd_MSB = 0x0854; const unsigned int FED_EPROM_Write = 0x0860; const unsigned int FED_EPROM_Read = 0x0864; const unsigned int FED_LM82_Write = 0x0868; const unsigned int FED_LM82_Read = 0x086c; const unsigned int FED_ADM1025_Write = 0x0870; const unsigned int FED_ADM1025_Read = 0x0874; const unsigned int FED_SystemACEBase = 0x0880; const unsigned int FED_Readout_BRAM = 0x8000; // Assume VME Memory Card in A32 is at base = 0x0200'0000 const unsigned int DPM_Test_Card_Base = 0x02000000; // base register on DPM //const unsigned int DPM_Test_Card = 0x1EE0000; // assumes FED in slot 18 so offset from 12'000 unsigned int DPM_Test_Card; // now use actual slot nr to calculate ttcvi base relative to FED for HAL // Assume VME Memory Card in A24 is at base = 0x--40'0000 const unsigned int DPM_Test_Card_A24 = 0x2e0000; // assumes FED in slot 18 so offset from 12'0000 // Assume TTCvi in A24 has base fixed = 0x--A0'0000 const unsigned int TTCvi_Card_Base = 0xA00000; // hex settings on card // const unsigned int TTCvi_Card = 0x8e0000; // assumes FED in slot 18 so offset from 12'0000 unsigned int TTCvi_Card; // now use actual slot nr to calculate ttcvi base relative to FED for HAL const unsigned int TTCvi_CSR1 = 0x80; const unsigned int TTCvi_CSR2 = 0x82; const unsigned int TTCvi_Module_Reset = 0x84; const unsigned int TTCvi_SW_L1A = 0x86; const unsigned int TTCvi_L1A_Ctr_MSB = 0x88; const unsigned int TTCvi_L1A_Ctr_LSB = 0x8a; const unsigned int TTCvi_Ctr_Reset = 0x8c; const unsigned int TTCvi_BGO0_Mode = 0x90; const unsigned int TTCvi_Inhibit0_Delay = 0x92; const unsigned int TTCvi_Inhibit0_Duration = 0x94; const unsigned int TTCvi_BGO0_Write = 0x96; const unsigned int TTCvi_BGO1_Mode = 0x98; const unsigned int TTCvi_Inhibit1_Delay = 0x9a; const unsigned int TTCvi_Inhibit1_Duration = 0x9c; const unsigned int TTCvi_BGO1_Write = 0x9e; const unsigned int TTCvi_BGO2_Mode = 0xa0; const unsigned int TTCvi_Inhibit2_Delay = 0xa2; const unsigned int TTCvi_Inhibit2_Duration = 0xa4; const unsigned int TTCvi_BGO2_Write = 0xa6; const unsigned int TTCvi_BGO3_Mode = 0xa8; const unsigned int TTCvi_Inhibit3_Delay = 0xaa; const unsigned int TTCvi_Inhibit3_Duration = 0xac; const unsigned int TTCvi_BGO3_Write = 0xae; const unsigned int TTCvi_BGO0_FIFO = 0xb0; const unsigned int TTCvi_BGO1_FIFO = 0xb4; const unsigned int TTCvi_BGO2_FIFO = 0xb8; const unsigned int TTCvi_BGO3_FIFO = 0xbc; const unsigned int TTCvi_Long_Async_MSB = 0xc0; const unsigned int TTCvi_Long_Async_LSB= 0xc2; const unsigned int TTCvi_Short_Async = 0xc4; const unsigned int TTCvi_TRIGWORD1 = 0xc8; const unsigned int TTCvi_TRIGWORD2 = 0xca; // ------------------------ const int FED_SPY_ARM = 0x7; const int FED_SPY_FIRE = 0x8; const int FED_DELAY_ID = 0x6; // uses same CDC mechanism as SPY commands // s/w codes only const int FED_EVT_FORMAT_SCOPE = 1; const int FED_EVT_FORMAT_ZS = 2; const int FED_EVT_FORMAT_SLINK = 3; // my locations for using Serial EPROM to store FED serial nr ...etc const int FED_EPROM_FEDID1 = 512; // $f const int FED_EPROM_FEDID2 = 513; // $e const int FED_EPROM_FEDID3 = 514; // $d const int FED_EPROM_FEDID4 = 515; // $1 const int FED_EPROM_SERNR1 = 516; // $msb const int FED_EPROM_SERNR2 = 517; // $lsb // Fake Event Data RAM Addrs const int FakeOffset = 0x1FFA; const int FakeTickLevel = 0x1FFB; const int FakeLowerPhase = 0x1FFC; const int FakeUpperPhase = 0x1FFD; const int FakeFrameInterval = 0x1FFE; const int FakeFrameRepetition = 0x1FFF; // FEDIndustry Test //const int INDUSTRY_RESULTS_OFFSET = 0; //const int INDUSTRY_NUM_RESULT_BYTES = 32; const int INDUSTRY_RESULTS_OFFSET = 1536; const int INDUSTRY_NUM_RESULT_BYTES = 74; FILE *output_file; FILE *cf_image_file_output; FILE *cf_image_file_input; FILE *readout_file; FILE *fakedata_file; // readout buffer const unsigned int MAX_READOUT_LENGTH = 1024*32 *2; // x4 bytes per long = max evt 256 Kbytes (8 fragments) unsigned long readout_buffer[MAX_READOUT_LENGTH]; // test destination for vme event readout const int fe_max = 8; const int fibre_max = 12; const int chan_max = 96; const int strip_max = 256; // Lookup Table for FEDv2 chan numbering using Francois's scheme // FEDv2 channel conventions 23.02.2005 // FE nr : FE modules 1 - 8 Bot - Top // Fibre nr : Fibres 1 - 12 on each FE Bot - Top // FED Chan nr = FE nr * 100 + Fibre nr unsigned int lut_chan[chan_max]; const int eprom_max = 2*1024; //const unsigned int eprom_max = 1024; //unsigned int data[eprom_max]; // codes used by firmware const unsigned int DAQ_EVT_TYPE_PHYSICS = 0x1; const unsigned int DAQ_EVT_TYPE_CALIBN = 0x2; const unsigned int DAQ_EVT_TYPE_TEST = 0x3; // FE FPGA codes are 5 bits const unsigned int FED_FE_MODE_SCOPE = 0x01; const unsigned int FED_FE_MODE_FRAMES = 0x02; const unsigned int FED_FE_MODE_VIRGRAW = 0x4; const unsigned int FED_FE_MODE_ZS = 0x08; const unsigned int FED_FE_MODE_PROCRAW = 0x10; // BE FPGA codes are 4 bits ; additional codes used for FAKE 17.06.05 const unsigned int FED_EVT_TYPE_SCOPE = 0x1; const unsigned int FED_EVT_TYPE_VIRGRAW = 0x2; const unsigned int FED_EVT_TYPE_VIRGRAW_FAKE = 0x3; const unsigned int FED_EVT_TYPE_PROCRAW = 0x6; const unsigned int FED_EVT_TYPE_PROCRAW_FAKE = 0x7; const unsigned int FED_EVT_TYPE_ZS = 0xa; const unsigned int FED_EVT_TYPE_ZS_FAKE = 0xb; const unsigned int FED_EVT_TYPE_ZS_LITE = 0xc; const unsigned int FED_EVT_TYPE_ZS_LITE_FAKE = 0xd; const unsigned int FED_TRK_HEADER_OLD = 0; const unsigned int FED_TRK_HEADER_FULL_DEBUG = 1; const unsigned int FED_TRK_HEADER_APV_ERROR = 2; // lengths in 32 bit words const unsigned int daq_header_len = 2; const unsigned int daq_trailer_len = 2; // ignoring dummy tracker trailer const unsigned int trk_header_prototype = 32; const unsigned int trk_header_special = 2; const unsigned int trk_header_full_debug = 32; const unsigned int trk_header_apv_error = 6; unsigned int fibre_thresh_calc[chan_max]; // calculated frame threshold from 1st event ; 0-15 (* 32 adc counts) unsigned int fibre_thresh_fix[chan_max]; unsigned int fibre_ped_calc[chan_max]; // for present will assume pedestal is SAME for all strips on fibre unsigned int fibre_low_thresh[chan_max]; // for present will assume cluster thresholds are SAME for all strips on fibre unsigned int fibre_high_thresh[chan_max]; class FFv1Object// ,Task { public: FFv1Object(unsigned long crate_nr, unsigned long baseAddr, string addrTable); ~FFv1Object(); char userPrompt(unsigned long crate_nr, unsigned long base_addr, unsigned long ser_nr); int FFv1Object::preliminaryTest(string & addrItem); int FFv1Object::checkData(unsigned long * dataIn, unsigned long * dataOut, unsigned long len); int FFv1Object::readBlockMemTest(); int FFv1Object::writeBlockMemTest(); int FFv1Object::ffv1BlockWrite(unsigned long * src, unsigned long length, unsigned long offset=0); int FFv1Object::ffv1BlockRead(unsigned long * dest, unsigned long length, unsigned long offset=0); int FFv1Object::ffv1SingleWrite(unsigned long src, unsigned long offset=0); // passes data by value int FFv1Object::ffv1SingleRead(unsigned long * dest, unsigned long offset=0); int FFv1Object::ffv1SingleReadA24D16(unsigned long * dest, unsigned long offset=0); int FFv1Object::ffv1SingleWriteA24D16(unsigned long src, unsigned long offset=0); // passes data by value int FFv1Object::ffv1SingleWriteA24D32(unsigned long src, unsigned long offset=0); // passes data by value int SetOptoRx(int chip, int value); int SetRunMode(int chip, int mode); int SetScopeLength(int chip, int len); int SendSWTrig(int verbosity); int ReadOptoRx(int chip, unsigned int* data); int ReadScopeLength(int chip, unsigned int* data); int EnableAPVChans(int chip, int data); int SetFrameThresholds(int chip, int data); int SetPedestal(int chip, int data); unsigned int fedCmd(int chip_id, int designator, int cmd_len, int r_w); unsigned int cdcCmd(int chip_id, int designator, int cmd_len); int FillVMEMem(int data); int FillVMEEventMem(int data); int DumpVMEMem(void); int SetClockSkew(int fe_chip, int delay_chip, int delay_chan, int coarse, int fine, int verbosity); int SpyArm(int fe_chip, int delay_chip); int SpyCommand(int fe_chip, int delay_chip, int spy_cmd, int spy_bits ); int SpyDisplay(int offset, unsigned int nr_words); int BECommand(int be_code, int be_rw, unsigned int* be_data, int verbosity); int DisplayBEStatus(int flag); int BuffersAvailable(unsigned int* buffers_pending, int verbosity); int InitBE(int run_type, unsigned int trigger_source, unsigned int trk_hdr_format); int TestFrameFinding(int num_triggers, int num_microsecs); int FECommand(int fe_id, int fe_code, int fe_rw, unsigned int* fe_data, int verbosity); //int TestReadout(int num_trigs, unsigned int num_secs, int verbosity, int event_format, int stop_flag); int TestReadout(int num_trigs, unsigned int num_secs, int verbosity, int stop_flag, int bt_flag); int ClearReadoutCSR(int verbosity); int CheckEvent(unsigned long* event_buffer, unsigned long event_length, int event_nr, int* error, unsigned int trig_nr, int event_format, int stop_flag, int crc_check, int* error_crc); int CheckEventNew(unsigned long* event_buffer, unsigned long event_length, int event_nr, int* error, unsigned int trig_nr, int stop_flag, int crc_check, int* error_crc, int verbosity); int DumpEventToFile(unsigned long* event_buffer, unsigned long event_length, int verbosity); int CheckCRC(unsigned long* event_buffer, unsigned long event_length, int verbosity); int DisplayVMEStatus(int verbosity); int SetTTCrx(int value); int ReadTTCrx(unsigned int* data); int ResetFED(int verbosity); int SelectClock(int clock, int verbosity); int DisplayClockCounters(int verbosity); int DisplayFirmwareVersions(FILE* file, int flag); int DisplayFEStatus(int flag); int DisplayClockStatus(int verbosity); int DisplaySystemACE(int verbosity); int ReadSystemACE(unsigned int reg_offset, unsigned int* value, int verbosity); int WriteSystemACE(unsigned int reg_offset, unsigned int value, int verbosity); int WordModeSystemACE(int verbosity); int ResetSystemACE(int verbosity); int ReloadFPGASystemACE(unsigned long cfg_addr, int verbosity); int AccessCFSectorSystemACE(unsigned int lba, unsigned int nr_sectors, int verbosity, int file_flag, int ace_write, int ace_test, int ace_loop); int DisplayTemperatures(int verbosity); int SetLM82_TCrits(unsigned int tcrit, int verbosity); int ReadLM82(int chip_id, int reg_id, unsigned int *data, int verbosity); int WriteLM82(int chip_id, int reg_id, unsigned int *data, int verbosity); int ReadVMELM82(unsigned int addr, unsigned int *data, int verbosity); int WriteVMELM82(unsigned int addr, unsigned int *data, int verbosity); int DisplayADM1025(int flag, int verbosity); int ReadADM1025(unsigned int addr, unsigned int *data, int verbosity); int WriteADM1025(unsigned int addr, unsigned int data, int verbosity); int DumpSerialEPROM(unsigned int eprom_quadrant, int verbosity); int ReadSerialEPROM(unsigned int addr, unsigned int *data, int verbosity); int WriteSerialEPROM(unsigned int addr, unsigned int *data, int verbosity); int EnableWriteEPROM(unsigned int enable_eprom, int verbosity); int ReadSerNrEPROM(unsigned int *sernr, unsigned int *fedid, int verbosity); int WriteSerNrEPROM(unsigned int sernr, unsigned int fedver, int verbosity); int DisplayTTCrx(int verbosity); int ReadTTCrxBXCtr(int verbosity, unsigned int* bx_ctr, unsigned int* evt_ctr); int ResetTTCrx(int verbosity); int ReadTTCrx(int reg_id, unsigned int *data, int verbosity); int WriteTTCrx(int reg_id, unsigned int *data, int verbosity); int WriteTTCrxFineSkew1(unsigned int* skew, int verbosity); int DumpMemory(unsigned int start_addr, unsigned int nr_words, int block_transfer); int FillMemory(unsigned int start_addr, unsigned int nr_words, unsigned int pattern_type, unsigned int pattern, int block_transfer); int TestReadBLT(unsigned int nr_words, unsigned int nr_tests, unsigned int memory); int TestWriteBLT(unsigned int nr_words, unsigned int nr_tests, unsigned int memory); int WriteTrimDAC(int chip_id, int chan, unsigned int *data, int verbosity); int ResetTrimDAC(int chip_id, int verbosity); int ShutdownTrimDAC(int chip_id, int verbosity); int DisplayFrameThresholds(int verbosity); int LoadFrameThresholds(int verbosity, int mode, unsigned int thresh); int ReadFrameThresholds(int chip, unsigned int* data, int verbosity); int WriteFrameThresholds(int chip, unsigned int* data, int verbosity); int DisplayFibreBufferLevels(int verbosity); int ReadFibreBufferLevels(int chip, unsigned int* data, int verbosity); int DisplayFibrePedestals(int verbosity); int LoadFibrePedestals(int mode, int value, int verbosity); int WriteFibrePedestals(int chip, unsigned int* data, int mode, int verbosity); int ReadFibrePedestals(int chip, unsigned int* data, int verbosity); int DisplayClusterThresholds(int verbosity); int LoadClusterThresholds(int mode, int lowfix, int highfix, int verbosity); int WriteClusterThresholds(int chip, unsigned int* low_thresh, unsigned int* high_thresh, int mode, int verbosity); int ReadClusterThresholds(int chip, unsigned int* low, unsigned int* high, int verbosity); int TTCvi_Display(unsigned int start_addr, int verbosity); int TTCvi_Read(unsigned int start_addr, unsigned int reg, unsigned long* value, int verbosity); int TTCvi_Write(unsigned int start_addr, unsigned int reg, unsigned long value, int verbosity); int TTCvi_WriteD32(unsigned int start_addr, unsigned int reg, unsigned long value, int verbosity); int TTCvi_Select_Trigger(unsigned int start_addr, int trig_src, int rand_rate, int verbosity); int TTCvi_Select_Orbit(unsigned int start_addr, int orbit, int verbosity); int TTCvi_Select_Counter(unsigned int start_addr, int ctr, int verbosity); int TTCvi_SW_Trigger(unsigned int start_addr, int verbosity); int TTCvi_Reset_Module(unsigned int start_addr, int verbosity); int TTCvi_Reset_Counters(unsigned int start_addr, int verbosity); int TTCvi_BGO_Reset_FIFO(unsigned int start_addr, int ttcvi_bgo_nr, int verbosity); int TTCvi_BGO_Inhibit(unsigned int start_addr, int ttcvi_bgo_nr, unsigned long ttcvi_bgo_delay, unsigned long ttcvi_bgo_duration, int verbosity); int TTCvi_BGO_Mode(unsigned int start_addr, int ttcvi_bgo_nr, int ttcvi_bgo_enable, int ttcvi_bgo_sync, int ttcvi_bgo_single, int ttcvi_bgo_fifo, int verbosity); int TTCvi_BGO_Write(unsigned int start_addr, int ttcvi_bgo_nr, int verbosity); int TTCvi_BGO_Retransmit(unsigned int start_addr, int ttcvi_bgo_nr, int verbosity); int TTCvi_BGO_Data(unsigned int start_addr, int ttcvi_bgo_nr, int ttcvi_data, int verbosity); int TTCvi_Async_Short(unsigned int start_addr, unsigned long ttcvi_short_cmd, int verbosity); int TTCvi_Async_Long(unsigned int start_addr, unsigned long ttcvi_long_ttcaddr, unsigned long ttcvi_long_subaddr, unsigned long ttcvi_long_data, unsigned long ttcvi_long_ext, int verbosity); int TestReadoutFromFile(int verbosity, int event_format, int event_nr, int endian_swap); //int TestReadoutFromFile(int verbosity, int event_nr, int endian_swap); int ReadDelayFPGAID(int fe_chip, int delay_chip, unsigned long* fpga_id); int ReadDelayFPGAClockSkewDone(int fe_chip, int delay_chip, int* skew_done); int DisplayTrackerHeaderMonitor(int verbosity); int DisplayBEStatusTWO(int verbosity); void ReadEPROMData(); int EnableFakeEventData(int fe_nr, int verbosity); int LoadFakeEventData(int fe_nr, int fibre_nr, int apv_reorder, int tick_only, int verbosity); int DumpFakeEventData(int fe_nr, int fibre_nr, int verbosity); int LoadFakeData(int fe_nr, int fibre_nr, int apv_reorder, int tick_only, int verbosity); int DumpFakeData(int fe_nr, int fibre_nr, int verbosity); int WriteFakeAddr(int fe_nr, unsigned int *addr, int verbosity); int WriteFakeData(int fe_nr, unsigned int *data, int verbosity); int WriteFakeDataMultiple(int fe_nr, unsigned int *data, int nwords, int verbosity); int ReadFakeData(int fe_nr, unsigned int *data, int verbosity); int SetFESuperMode(int fe_nr, unsigned int mode, int verbosity); int VMEWriteLoop(unsigned int offset, unsigned int data, unsigned int num_loops); int VMEReadLoop(unsigned int offset, unsigned int num_loops, int check); int CheckSerialStatus(unsigned int fed_cmd, int verbosity); private: void FFv1Object::wait(unsigned long ws, unsigned long wms); protected: VMEAddressTableASCIIReader ffv1AddrTblRdr_; VMEAddressTable ffv1AddrTable_; /* #ifdef BUILD_NIVXI MXI2x86LinuxBusAdapter_test ffv1BusAdapter_; #else SBS620x86LinuxBusAdapter ffv1BusAdapter_; #endif */ #ifdef BUILD_CAEN CAEN2718LinuxPCIBusAdapter ffv1BusAdapter_; #else SBS620x86LinuxBusAdapter ffv1BusAdapter_; #endif VMEDevice ffv1Device_; }; // //constructor with non default base address and address table... // FFv1Object::FFv1Object(unsigned long crate_nr, unsigned long baseAddr, string addrTable): ffv1AddrTblRdr_(addrTable), ffv1AddrTable_("I2C VME Address Map",ffv1AddrTblRdr_), ffv1BusAdapter_(crate_nr), ffv1Device_(ffv1AddrTable_,ffv1BusAdapter_,baseAddr) { } FFv1Object::~FFv1Object() { } // jac changed to take long rather than *long int FFv1Object::ffv1SingleWrite(unsigned long src, unsigned long offset) { try { ffv1Device_.unmaskedWrite("FFv1BaseItemSingleDataNonPriv",src,HAL_NO_VERIFY,(offset<<2)); } catch(HardwareAccessException & e) { cout<<"exception from ffv1SingleWrite(), unmaskedWrite() :\n "<readBlock"< unmaskedRead "<>temp; choice=temp[0]; temp.erase(); choice=tolower(choice); if((choice>='a' && choice<='z') || (choice>='0' && choice<='9')) isValid=false; else cout<<"\n*********** unrecognised choice, ***********\n*********** please enter another ***********\n\n" <1000000)/*ensure that the correct range is used for millisec */ { ws=static_cast(wus/1000000); wus=wus%1000000; } //printf("WAIT: Seconds = %d, Milliseconds = %d.\n", ws, wms); rqtp.tv_sec=ws;/*set the time structure*/ rqtp.tv_nsec=1000*wus; if((nsret=nanosleep(&rqtp, &rmtp))!=0) { rqtp=rmtp; cout<<"WAIT: error in nanosleep, nsret = %"<1) cout << " Send SW Trigger (using BE command register)" << '\n'; // old way using FPGA designator 9 // unsigned int fed_cmd = fedCmd(9, 0x0f, 1, 0); // any cmd to be fpga generates s/w pulse // unsigned int fed_data = 0x1<<(32-1); // if (verbosity >1) cout << "fed_cmd = $ " << hex << fed_cmd << " ; fed_data = $ " << fed_data << '\n'; // return 0; // ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer // ffv1SingleWrite(fed_data, FED_Serial_BRAM/4 + 1); // data is irrelevant // ffv1SingleWrite(2, FED_Serial_Write/4); // send cmd string // new way unsigned int value = 1; BECommand(8, 0, &value, verbosity); return 0; } int FFv1Object::ReadOptoRx(int chip, unsigned int* data) { cout << "Readback FE Chip # " << chip << " OptoRx Controls" << '\n'; unsigned int fed_cmd = fedCmd(chip, 0x16, 8, 1); cout << "fed_cmd = $ " << hex << fed_cmd << '\n'; // return 0; CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_Read/4); // sends read cmd // usleep(100); unsigned long fed_data = *data; CheckSerialStatus(fed_cmd, 0); ffv1SingleRead(&fed_data, FED_Serial_BRAM/4); // readback memory *data = fed_data >> (32-8); return 0; } int FFv1Object::ReadScopeLength(int chip, unsigned int* data) { cout << "Readback FE Chip # " << chip << " Scope Length" << '\n'; unsigned int fed_cmd = fedCmd(chip, 0x11, 10, 1); cout << "fed_cmd = $ " << hex << fed_cmd << '\n'; // return 0; CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_Read/4); // sends read cmd //usleep(100); unsigned long fed_data = *data; CheckSerialStatus(fed_cmd, 0); ffv1SingleRead(&fed_data, FED_Serial_BRAM/4); // readback memory *data = fed_data >> (32-10); return 0; } unsigned int FFv1Object::fedCmd(int chip_id, int cmd_desig, int cmd_len, int r_w) { unsigned int cmd_word = 0; // unsigned int swap_word = 0; #define chip_id_mask 0xe0ffffff #define cmd_desig_mask 0xffc1ffff #define cmd_len_mask 0xffff0000 // cout << "fe fpga = " << chip_id << " cmd designator = $ " << hex << cmd_desig << " cmd length = " << dec << cmd_len << " R/W = " << r_w << '\n'; // construct the 32 bit cmd string cmd_word = 0x20810000; /* x = (chip_id << 24) | cmd_word; */ /* printf(" x = 0x%08x \n", x ); */ if (r_w == 1) cmd_len++; // read command length must be one more than write else if (r_w == 2) { cmd_len+=2; // read only regs need 2 extra bit shifts r_w = 1; // must put back normal read bit to make cmd_word } if (chip_id >= 0 && chip_id <= 7) chip_id++; // s/w nr 0-7 matches fpga cmd nr 1-8 ; don't change 15 broadcast cmd_word |= r_w << 22 | chip_id << 24 | cmd_desig << 17 | cmd_len; // cout << "fed cmd = $ " << hex << cmd_word << '\n'; return cmd_word; // no more swapping needed. // // finally swap bits around as hardware expects msb's first.. uggh // // i.e. swap pairs of bits 31:0 ; 30:1 ; 29:2 ... 16:15 // for (i=0; i<16; i++) { // swap_word |= (cmd_word >> (31-2*i) & 1 << i) | (cmd_word << (31-2*i)) & 1 << (31-i); // } // printf("bit swapped command = 0x%08x \n", swap_word); return 0; } unsigned int FFv1Object::cdcCmd(int chip_id, int cmd_desig, int cmd_len) { unsigned int cmd_word = 0; cmd_word = 0x90200000; cmd_word |= chip_id << 29 | cmd_desig << 22 | cmd_len << 5; // cout << "cdc cmd = $ " << hex << cmd_word << '\n'; return cmd_word; } int FFv1Object::FillVMEMem(int data) { cout << " Fill FED VME Memory buffer with = 0x" << hex << data << dec <<'\n'; // usleep(500); // 2 KB BRAM => 512 long words for (int i=0; i<512; i++) { ffv1SingleWrite(data, i); } return 0; } int FFv1Object::FillVMEEventMem(int data) { // cout << " Fill FED VME Event buffer with = 0x" << hex << data << dec <<'\n'; // 32 KB event memory for (int i=0; i<32*1024/4; i++) { ffv1SingleWrite(data, FED_Readout_BRAM/4 + i); } return 0; } int FFv1Object::DumpVMEMem(void) { unsigned long int data; cout << " FED VME Memory Buffer:" <<'\n'; // usleep(500); // show first few locations for (int i=0; i<8; i++) { ffv1SingleRead(&data, i); cout << hex << data << " , "; } cout << '\n'; return 0; } int FFv1Object::SetClockSkew(int fe_chip, int delay_chip, int delay_chan, int coarse, int fine, int verbosity) { // // CDC dial thru command if (verbosity > 1) cout << dec << "FE Chip # " << 8-fe_chip << " Delay FPGA # " << delay_chip << " Delay Chan # " << delay_chan << " Coarse = " << coarse << " Fine = " << fine << '\n'; #ifdef FED_NEW_FINE_SKEW unsigned int cdc_len = 40; // +1 for 64 fine steps unsigned int tot_len = 67; #else unsigned int cdc_len = 36; // changed back from 37 to 36 on 23.09.2003 // unsigned int tot_len = cdc_len + 27; unsigned int tot_len = 63; // changed from 64 to 63 on 23.09.2003 #endif // printf("enter cdc cmd length => " ); // cin >> cdc_len; // printf("enter total cmd length => " ); // cin >> tot_len; if (verbosity > 1) { printf("total cmd len = %d; cdc len = %d \n", tot_len, cdc_len ); printf("clearing memory location after command string! \n" ); } #ifdef FED_NEW_FINE_SKEW unsigned int fed_cmd = fedCmd(fe_chip, 0x15, tot_len, 0); unsigned int cdc_cmd = cdcCmd(delay_chip, 0x01, cdc_len); #else unsigned int fed_cmd = fedCmd(fe_chip, 0x15, tot_len, 0); unsigned int cdc_cmd = cdcCmd(delay_chip, 0x01, cdc_len); #endif int coarse_def = 0; // for unselected channels int fine_def = 0; int coarse_new[4]; int fine_new[4]; if (verbosity > 1) printf("for unselected channels : coarse = %d ; fine = %d \n", coarse_def, fine_def ); unsigned int fed_data1; unsigned int fed_data2; unsigned int fed_data3; switch (delay_chan) { case 4: coarse_new[0] = coarse; coarse_new[1] = coarse; coarse_new[2] = coarse; coarse_new[3] = coarse; fine_new[0] = fine; fine_new[1] = fine; fine_new[2] = fine; fine_new[3] = fine; break; case 0: coarse_new[0] = coarse; coarse_new[1] = coarse_def; coarse_new[2] = coarse_def; coarse_new[3] = coarse_def; fine_new[0] = fine; fine_new[1] = fine_def; fine_new[2] = fine_def; fine_new[3] = fine_def; break; case 1: coarse_new[0] = coarse_def; coarse_new[1] = coarse; coarse_new[2] = coarse_def; coarse_new[3] = coarse_def; fine_new[0] = fine_def; fine_new[1] = fine; fine_new[2] = fine_def; fine_new[3] = fine_def; break; case 2: coarse_new[0] = coarse_def; coarse_new[1] = coarse_def; coarse_new[2] = coarse; coarse_new[3] = coarse_def; fine_new[0] = fine_def; fine_new[1] = fine_def; fine_new[2] = fine; fine_new[3] = fine_def; break; case 3: coarse_new[0] = coarse_def; coarse_new[1] = coarse_def; coarse_new[2] = coarse_def; coarse_new[3] = coarse; fine_new[0] = fine_def; fine_new[1] = fine_def; fine_new[2] = fine_def; fine_new[3] = fine; break; default: printf("Warning: Illegal selection. No channels changed \n" ); return -1; break; } #ifdef FED_NEW_FINE_SKEW fed_data1 = cdc_cmd | coarse_new[0] << 1 | fine_new[0] >> 5; fed_data2 = fine_new[0] << 27 | coarse_new[1] << 23 | fine_new[1] << 21 | coarse_new[2] << 17 | fine_new[2] << 7 | coarse_new[3] << 3 | fine_new[3] >> 3; fed_data3 = fine_new[3] << 29; #else fed_data1 = cdc_cmd | coarse_new[0] << 1 | fine_new[0] >> 4; fed_data2 = fine_new[0] << 28 | coarse_new[1] << 24 | fine_new[1] << 19 | coarse_new[2] << 15 | fine_new[2] << 10 | coarse_new[3] << 6 | fine_new[3] << 1; fed_data3 = 0; #endif if (verbosity > 1) cout << "fed_cmd = $ " << hex << fed_cmd << " ; fed_data1 = $ " << fed_data1 << " ; fed_data2 = $ " << fed_data2 << "; fed_data3 = $ " << fed_data3 << '\n'; if (verbosity > 1) { printf("Clock Skew changed values: \n"); printf("FED chan : Coarse : Fine \n"); if (fe_chip == 15 ) { for (int k=0; k<8; k++) { if (delay_chip == 3) { for (int j=0; j<3; j++) { // delay fpgas for (int i=0; i<4; i++) { printf(" %d %d %d \n", (8-k) * 100 + (12 - j*4) - i, coarse_new[i], fine_new[i] ); } } } else { for (int i=0; i<4; i++) { printf(" %d %d %d \n", (8-k) * 100 + (12 - delay_chip*4) - i, coarse_new[i], fine_new[i] ); } } } } else { if (delay_chip == 3) { for (int j=0; j<3; j++) { // delay fpgas for (int i=0; i<4; i++) { printf(" %d %d %d \n", (8-fe_chip) * 100 + (12 - j*4) - i, coarse_new[i], fine_new[i] ); } } } else { for (int i=0; i<4; i++) { printf(" %d %d %d \n", (8-fe_chip) * 100 + (12 - delay_chip*4) - i, coarse_new[i], fine_new[i] ); } } } } CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer ffv1SingleWrite(fed_data1, FED_Serial_BRAM/4 + 1); // cdc cmd and data ffv1SingleWrite(fed_data2, FED_Serial_BRAM/4 + 2); ffv1SingleWrite(fed_data3, FED_Serial_BRAM/4 + 3); ffv1SingleWrite(0, FED_Serial_BRAM/4 + 4); // 26.09.03 ; clear next word to avoid hangup in serial decoder (this stops every second command being ignored!) ffv1SingleWrite(4, FED_Serial_Write/4); // send cmd string return 0; } int FFv1Object::SpyArm(int fe_chip, int delay_chip) { // // CDC dial thru command cout << dec << "FE Chip # " << 8-fe_chip << " Delay chip # " << delay_chip << '\n'; unsigned int cdc_len = 1; unsigned int tot_len = 28; printf("total cmd len = %d; cdc len = %d \n", tot_len, cdc_len ); printf("clearing memory location after command string! \n" ); unsigned int fed_cmd = fedCmd(fe_chip, 0x15, tot_len, 0); // nb "write" cmd type unsigned int cdc_cmd = cdcCmd(delay_chip, FED_SPY_ARM, cdc_len); unsigned int fed_data = cdc_cmd | 0x1 << (32 - tot_len); // append data = 1 bit to ARM cout << "fed_cmd = $ " << hex << fed_cmd << " ; fed_data = $ " << fed_data << '\n'; CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer ffv1SingleWrite(fed_data, FED_Serial_BRAM/4 + 1); // cdc cmd ffv1SingleWrite(0, FED_Serial_BRAM/4 + 2); // clear next word to avoid hangup in serial decoder (this stops every second command being ignored!) ffv1SingleWrite(2, FED_Serial_Write/4); // send cmd string return 0; } int FFv1Object::SpyCommand(int fe_chip, int delay_chip, int spy_cmd, int spy_bits) { // CDC dial thru command // NB Spy commands are classified as "WRITE" but use Read Registers mechanism // CDC cmd part goes in new spy cmd LSB // FED cmd part goes in new spy cmd MSB (this triggers action either ARM or FIRE) // NB Delay Firmware ID behaves like a SPY read command cout << dec << "FE Chip # " << 8-fe_chip << " Delay chip # " << delay_chip << '\n'; unsigned int cdc_len = 1; if (spy_cmd == FED_SPY_ARM) { printf(" SPY ARM \n"); cdc_len = 1; } else if (spy_cmd == FED_SPY_FIRE) { printf(" SPY FIRE \n"); //cdc_len = 40880; //cdc_len = 41000; cdc_len = spy_bits; if (delay_chip == 3) { printf("Error Can only FIRE one Delay Chip at a time. \n"); return 1; } } else if (spy_cmd == FED_DELAY_ID) { printf(" DELAY Firmware ID \n"); //cdc_len = 40880; //cdc_len = 41000; cdc_len = spy_bits; if (delay_chip == 3) { printf("Error Can only Read ID from one Delay Chip at a time. \n"); return 1; } } else { printf("Error Unknown SPY command \n"); return 1; } unsigned int tot_len = cdc_len + 27; printf("total cmd len = %d; cdc len = %d \n", tot_len, cdc_len ); unsigned int fed_cmd = fedCmd(fe_chip, 0x15, tot_len, 0); // nb "write" cmd type unsigned int cdc_cmd = cdcCmd(delay_chip, spy_cmd, cdc_len); CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(cdc_cmd, FED_Spy_Cmd_LSB/4); printf("wrote cdc LSB command = $ %08x at addr = $ %08x \n", (unsigned int) cdc_cmd, (unsigned int) FED_Spy_Cmd_LSB); ffv1SingleWrite(fed_cmd, FED_Spy_Cmd_MSB/4); // act of writing sends SpyArm command printf("wrote fed MSB command = $ %08x at addr = $ %08x \n", (unsigned int) fed_cmd, (unsigned int) FED_Spy_Cmd_MSB); CheckSerialStatus(fed_cmd, 0); /* // check serial status word for (int i=0; i<4; i++) { unsigned long serial_status; ffv1SingleRead(&serial_status, FED_Serial_Status/4); printf("serial status after CDC command = $ %08x \n", (unsigned int) serial_status); } */ return 0; } const unsigned int max_spy_words = 512; // max 32 bit words in serial memory const int max_spy_bits = max_spy_words * 32; unsigned char spy_data_bits[max_spy_bits]; unsigned long int spy_data[4][max_spy_words]; // 4 channels of 10 bit words / Delay int FFv1Object::SpyDisplay(int offset, unsigned int nr_words) { // Displays formatted contents of Serial Memory from response to Spy Fire command if (nr_words > max_spy_words) { nr_words = max_spy_words; } int nr_bits = nr_words * 32; int nr_samples = (nr_bits - offset) / 40; // 4 * 10 bits per SPY sample for (unsigned int i=0; i> j & 0x1; } } printf("Spy Bit Data : Just first few values \n"); for (unsigned int i=0; i<8; i++) { // just show first few data printf("Word %02d : ", i); for (int j=0; j<32; j++) { printf("%d ", spy_data_bits[i*32 + j]); } printf("\n"); } printf("\n"); printf("offset of spy bits = %d \n", offset); // construct 10 bit data words for delay channel 0,1,2,3 repeated int bit = 9; int chan = 0; int sample = 0; unsigned long int data = 0; // int offset = 32+12; // spy bits are preceded by unknown nr of '0's for (int i=offset; i 1) cout << dec << "BE Chip cmd code # " << be_code << " R/W = " << be_rw << '\n'; // note now doubling nr of BE FPGA commands by also using FPGA code 16 if (be_code >= 32 ) fpga_code = 16; else fpga_code = 10; // nb when constructing the fed cmd string the be_code field needs to be = be_code % 32 if (be_rw == 0) { fed_cmd = fedCmd(fpga_code, be_code%32, be_cmd_len[be_code], 0); fed_data = *be_data<<(32-be_cmd_len[be_code]); if (verbosity > 1) cout << "fed_cmd = $ " << hex << fed_cmd << " ; fed_data = $ " << fed_data << '\n'; if (verbosity > 1) cout << "BE command name = " << be_cmd_name[be_code] << '\n'; CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer ffv1SingleWrite(fed_data, (FED_Serial_BRAM+4)/4); ffv1SingleWrite(2, FED_Serial_Write/4); // send cmd string } else { if (be_code >= 16 && be_code <= 29) // all read only ! { fed_cmd = fedCmd(fpga_code, be_code%32, be_cmd_len[be_code], 2); // r_w =2 must add 2 to length command } else { fed_cmd = fedCmd(fpga_code, be_code%32, be_cmd_len[be_code], 1); } CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_Read/4); // sends read cmd // usleep(100); removed 08.03.06 // should check Ser Status register here CheckSerialStatus(fed_cmd, 0); ffv1SingleRead(&fed_data, FED_Serial_BRAM/4); // readback memory if (be_code >=16 && be_code <= 29) // readonly registers, must compensate for an extra bit shifted out by serial logic { fed_data <<= 1 ; ffv1SingleRead(&fed_data2, (FED_Serial_BRAM+4)/4); // in case of 32 bit values where last bit appears in next memory location fed_data |= (fed_data2 >> 31); } if (be_code == 26 ) { // yuk! do nothing else with ttc chan b long cmd *be_data = fed_data; } else { *be_data = fed_data>>(32-be_cmd_len[be_code]); } if (verbosity > 1) cout << "fed_cmd = $ " << hex << fed_cmd << " ; fed_data = $ " << fed_data << '\n'; if (verbosity > 1) cout << "BE command name = " << be_cmd_name[be_code] << '\n'; if (verbosity > 1) cout << "Reading: data (hex) = " << hex << *be_data << '\n'; } if (verbosity <= 1) { // usleep(1000); // need to wait between serial commands ; removed 08.03.06 } return 0; } const char* be_status_name[32] = {\ " ",\ " FE FPGA Data Fifo EMPTY",\ " FE Evt Len Fifo EMPTY",\ " L1A & BX Fifo EMPTY",\ " Trk Hdr Fifo EMPTY",\ " Tot Length Fifo EMPTY",\ " Frame Addr Fifo EMPTY",\ " QDR EMPTY",\ " ",\ " FE FPGA Data Fifo PARTIAL FULL",\ " FE Evt Len Fifo PARTIAL FULL",\ " L1A & BX Fifo PARTIAL FULL",\ " Trk Hdr Fifo PARTIAL FULL",\ " Tot Length Fifo PARTIAL FULL",\ " Frame Addr Fifo PARTIAL FULL",\ " QDR PARTIAL FULL",\ " ",\ " FE FPGA Data Fifo FULL",\ " FE Evt Len Fifo FULL",\ " L1A & BX Fifo FULL",\ " Trk Hdr Fifo FULL",\ " Tot Length Fifo FULL",\ " Frame Addr Fifo FULL",\ " QDR FULL",\ " Tracker Header Monitor READY",\ " TTCrx READY",\ " BX Error at Orbit Reset",\ " BackPressure Flag",\ " SLINK FULL Flag",\ " SLINK DOWN",\ " Internal Freeze",\ " Temperature Interrupt b" }; const char* be_status_two_name[32] = {\ " ",\ " FE FPGA Data Fifo HALF FULL",\ " FE Evt Len Fifo HALF FULL",\ " L1A & BX Fifo HALF FULL",\ " Trk Hdr Fifo HALF FULL",\ " Tot Length Fifo HALF FULL",\ " Frame Addr Fifo HALF FULL",\ " QDR HALF FULL",\ " ",\ " ",\ " FE Evt Len Fifo PARTIAL EMPTY",\ " L1A & BX Fifo PARTIAL EMPTY",\ " Trk Hdr Fifo PARTIAL EMPTY",\ " Tot Length Fifo PARTIAL EMPTY",\ " Frame Addr Fifo PARTIAL EMPTY",\ " QDR PARTIAL EMPTY",\ " TTS READY",\ " TTS BUSY",\ " TTS OUT OF SYNC",\ " TTS WARNING OVERFLOW",\ " ",\ " ",\ " ",\ " ",\ " ",\ " ",\ " ",\ " ",\ " ",\ " ",\ " ",\ " " }; int FFv1Object::DisplayBEStatus(int flag) { unsigned int l1a_cnt, bx_cnt, unread_frame_cnt, unread_word_cnt, total_frame_cnt; unsigned int be_status, be_status_two, ttc_ready, ttc_chanb_short, ttc_chanb_long, ttc_chanb_long_ttcaddr, ttc_chanb_long_subaddr, ttc_chanb_long_data; unsigned int fpga_code, daq_reg, daq_reg2, trk_hdr, bx_offset; unsigned int evt_type, fov, fmm; unsigned int bx_max; unsigned int verbosity = 0; if (flag == 1) { unsigned int trig_src, be_mode, ttc_ctrl, test_reg, fe_enable, be_link, be_enable; unsigned int fed_id; BECommand(1, 1, &trig_src, verbosity); BECommand(2, 1, &be_mode, verbosity); BECommand(3, 1, &ttc_ctrl, verbosity); BECommand(4, 1, &test_reg, verbosity); BECommand(5, 1, &fe_enable, verbosity); BECommand(6, 1, &be_link, verbosity); BECommand(7, 1, &be_enable, verbosity); BECommand(10, 1, &fed_id, verbosity); BECommand(13, 1, &daq_reg, verbosity); BECommand(35, 1, &daq_reg2, verbosity); BECommand(14, 1, &trk_hdr, verbosity); BECommand(15, 1, &bx_offset, verbosity); BECommand(30, 1, &evt_type, verbosity); BECommand(31, 1, &fov, verbosity); // extended BE codes BECommand(33, 1, &bx_max, verbosity); BECommand(34, 1, &fmm, verbosity); cout << "\nBE Control Registers: " << '\n'; cout << " 1) Trigger Source = $ " << hex << trig_src << '\n'; cout << " 2) BE Mode = $ " << hex << be_mode << '\n'; cout << " 3) TTCrx Ctrl = $ " << hex << ttc_ctrl << '\n'; cout << " 4) Test Register = $ " << hex << test_reg << '\n'; cout << " 5) FE Enable = $ " << hex << fe_enable << '\n'; cout << " 6) BE Link = $ " << hex << be_link << '\n'; cout << " 7) BE Enable = $ " << hex << be_enable << '\n'; cout << "10) FED ID Reg = $ " << hex << fed_id << '\n'; cout << "13) DAQ Register = $ " << hex << daq_reg << '\n'; cout << "35)DAQ Register Two = $ " << hex << daq_reg2 << '\n'; cout << "14) Trk Header = $ " << hex << trk_hdr << '\n'; cout << "30)Default Evt Type = $ " << hex << evt_type <<'\n'; cout << "31) FOV = $ " << hex << fov << '\n'; cout << "15) BX offset = $ " << hex << bx_offset << " ; " << dec << bx_offset << '\n'; cout << "33) Bx Max = $ " << hex << bx_max << " ; " << dec << bx_max << '\n'; cout << '\n'; } // BECommand(24, 1, &ttc_status, verbosity); BECommand(16, 1, &be_status, verbosity); BECommand(29, 1, &be_status_two, verbosity); BECommand(17, 1, &l1a_cnt, verbosity); BECommand(18, 1, &bx_cnt, verbosity); BECommand(19, 1, &unread_frame_cnt, verbosity); BECommand(20, 1, &ttc_ready, verbosity); BECommand(21, 1, &fpga_code, verbosity); BECommand(22, 1, &unread_word_cnt, verbosity); BECommand(23, 1, &total_frame_cnt, verbosity); BECommand(26, 1, &ttc_chanb_long, verbosity); BECommand(27, 1, &ttc_chanb_short, verbosity); ttc_chanb_short >>= 5; // extract data field ttc_chanb_long_data = ttc_chanb_long & 0xff; ttc_chanb_long_subaddr = ttc_chanb_long >> 8 & 0xff; ttc_chanb_long_ttcaddr = ttc_chanb_long >> 18 & 0x3fff; cout << "BE Status Registers: " << '\n'; // cout << "21) FPGA Usercode = $ " << hex << fpga_code << '\n'; // cout << "16) BE Status = $ " << hex << be_status << '\n'; printf("21) FPGA Usercode = $ %08x\n", (unsigned int) fpga_code); // cout << "17) L1A ctr = " << dec << l1a_cnt-1 << '\n'; cout << "17) L1A ctr = " << dec << l1a_cnt << '\n'; cout << "18) BX ctr = " << dec << bx_cnt << " $" << hex << bx_cnt << "(hex)" << '\n'; cout << "23) Total Frame ctr = " << dec << total_frame_cnt << '\n'; cout << "19) Unread Frame ctr = " << dec << unread_frame_cnt << '\n'; cout << "22) Unread Word (64bit) ctr = " << dec << unread_word_cnt << " $ " << hex << unread_word_cnt << '\n'; cout << "20) TTC Ready = $ " << hex << ttc_ready << '\n'; cout << "27) TTC ChanB Short Brdcast : Data = $ " << hex << ttc_chanb_short << '\n'; printf("26) TTC ChanB Long Single : TTC Addr = $%04x ; Sub Addr = $%02x ; Data = $%02x \n", ttc_chanb_long_ttcaddr, ttc_chanb_long_subaddr, ttc_chanb_long_data); // printf("29) BE Status Register TWO:\n"); // DisplayBEStatusTWO(1); printf("\n16) BE Status = $ %08x\n", (unsigned int) be_status); printf(" Bit : Condition : Status | Bit : Condition : Status\n"); for (int i=31; i>=16; i-- ) { printf(" %2d : %s : %1d | %2d : %s : %1d \n", i, be_status_name[31-i], (unsigned int) (((unsigned int) be_status) >> i) & 0x1, i-16, be_status_name[31-i+16], (unsigned int) (((unsigned int) be_status) >> (i-16)) & 0x1 ); } printf("\n29) BE Status TWO = $ %08x\n", (unsigned int) be_status_two); printf(" Bit : Condition : Status | Bit : Condition : Status\n"); for (int i=31; i>=16; i-- ) { printf(" %2d : %s : %1d | %2d : %s : %1d \n", i, be_status_two_name[31-i], (unsigned int) (((unsigned int) be_status_two) >> i) & 0x1, i-16, be_status_two_name[31-i+16], (unsigned int) (((unsigned int) be_status_two) >> (i-16)) & 0x1 ); } printf("\n34) FMM Test Register: Ready/Busy/Out of Sync/Warn Overflow = $%01x\n", fmm & 0xf); for (int i=3; i>=0; i--) { printf(" %01x /", fmm >> i & 0x1); } return 0; } int FFv1Object::BuffersAvailable(unsigned int* buffers_pending, int verbosity) { // unsigned int be_status, unread_frame_cnt; // // if all partial (and full) flags are clear for N reads we can take another trigger // for (int i=0; i<10; i++) { // BECommand(16, 1, &be_status, verbosity); // if (verbosity > 1) cout << "BE Status = $ " << hex << be_status << '\n'; // if ((be_status & 0x00ffff00) != 0) { // return 1; // } // } BECommand(19, 1, buffers_pending, verbosity); // if (buffers_pending > 20) { // return 1; // } return 0; } int FFv1Object::InitBE(int run_type, unsigned int trigger_source, unsigned int trk_hdr_format) { unsigned int be_mode, ttc_ctrl, test_reg, fe_enable, be_link, be_enable; unsigned int fed_id; unsigned int dummy = 1; unsigned int verbosity = 0; unsigned int evt_type = 1; unsigned int fov = 1; test_reg = 0x00; // disable test patterns, disable ignoring of vme throttle fe_enable = 0xff; // all enabled //fe_enable = 0x00; // all disabled be_link = 0x02; // v-link be_enable = 0x03; // accept triggers, accept frames //evt_type = 0x2; // test //fov = 0x3; // test ttc_ctrl = 0x0; // to avoid compilation warning messages // fed_id = 0xfed; // my id code fed_id = 0x1; be_mode = run_type; printf("event type = $%1x \n", be_mode); /* if (run_type == 1) { be_mode = 0x1; // scope } else if (run_type == 2) { be_mode = 0x2; // ff virgin raw } else if (run_type == 3) { be_mode = 0xa; // ff zero-suppressed } else if (run_type == 4) { be_mode = 0x6; // ff processed raw } else { cout << "Sorry Illegal Run Type " << '\n'; return 1; } */ if (trk_hdr_format < 1 || trk_hdr_format > 2) { cout << "Sorry Illegal Tracker Header Format " << '\n'; return 1; } BECommand(9, 0, &dummy, verbosity); // reset status/ counters, value written not important BECommand(1, 0, &trigger_source, verbosity); BECommand(2, 0, &be_mode, verbosity); BECommand(4, 0, &test_reg, verbosity); BECommand(5, 0, &fe_enable, verbosity); BECommand(6, 0, &be_link, verbosity); BECommand(10, 0, &fed_id, verbosity); BECommand(14, 0, &trk_hdr_format, verbosity); BECommand(30, 0, &evt_type, verbosity); BECommand(31, 0, &fov, verbosity); BECommand(7, 0, &be_enable, verbosity); // should be last command ? return 0; } int FFv1Object::TestFrameFinding(int num_triggers, int num_microsecs) { // simulate a frame finding run cout << "Simulate Frame Finding with: Nr Triggers = " << dec << num_triggers << " and apv frames for " << num_microsecs << " microsecs" << '\n'; unsigned int test_reg, saved; unsigned int verbosity = 0; // 2 disables usleep() inside BECommand // send dummy triggers to fill l1a/bx fifos for (int i = 0; i 1) cout << dec << "FE Chip # " << fe_id << " cmd code # " << fe_code << " R/W = " << fe_rw << '\n'; if (fe_rw == 0) // writes { fed_cmd = fedCmd(fe_id, fe_code, fe_cmd_len[fe_code], 0); fed_data = *fe_data<<(32-fe_cmd_len[fe_code]); if (verbosity > 1) cout << "fed_cmd = $ " << hex << fed_cmd << " ; fed_data = $ " << fed_data << '\n'; if (verbosity > 1) cout << "FE command name = " << fe_cmd_name[fe_code] << '\n'; CheckSerialStatus(fed_cmd, verbosity); ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer ffv1SingleWrite(fed_data, FED_Serial_BRAM/4 + 1); ffv1SingleWrite(2, FED_Serial_Write/4); // send cmd string } else { if (fe_code == 3 || fe_code == 20 || fe_code == 27) // readonly regs { fed_cmd = fedCmd(fe_id, fe_code, fe_cmd_len[fe_code], 2); // r_w =2 must add 2 to length command } else { fed_cmd = fedCmd(fe_id, fe_code, fe_cmd_len[fe_code], 1); } CheckSerialStatus(fed_cmd, verbosity); ffv1SingleWrite(fed_cmd, FED_Serial_Read/4); // sends read cmd // usleep(100); removed 08.03.06 CheckSerialStatus(fed_cmd, verbosity); ffv1SingleRead(&fed_data, FED_Serial_BRAM/4); // readback memory if (fe_code == 3 || fe_code == 18 || fe_code == 20 || fe_code == 27) // readonly regs // readonly registers, must compensate for an extra bit shifted out by serial logic { fed_data <<= 1 ; ffv1SingleRead(&fed_data2, FED_Serial_BRAM/4 + 1); // in case of 32 bit values where last bit appears in next memory location fed_data |= (fed_data2 >> 31); } *fe_data = fed_data>>(32-fe_cmd_len[fe_code]); if (verbosity > 1) cout << "fed_cmd = $ " << hex << fed_cmd << " ; fed_data = $ " << fed_data << '\n'; if (verbosity > 1) cout << "FE command name = " << fe_cmd_name[fe_code] << '\n'; if (verbosity > 1) cout << "Reading: data (hex) = " << hex << *fe_data << '\n'; } if (verbosity <= 1) { // usleep(1000); // need to wait between serial commands // usleep(1); // reduced 08.11.05 , removed 08.03.06 } #ifdef WAIT_STATES usleep(1); #endif return 0; } int FFv1Object::ClearReadoutCSR(int verbosity) { // clearing csr allows next event to be readout unsigned long readout_status; unsigned int clear = 0; ffv1SingleRead(&readout_status, FED_Readout_CSR/4); if (verbosity > 1) cout << "Before Clear Event Pending: Status = " << readout_status << '\n'; usleep(100); ffv1SingleWrite(clear, FED_Readout_CSR/4); usleep(1000); ffv1SingleRead(&readout_status, FED_Readout_CSR/4); if (verbosity > 1) cout << "After Clear Event Pending: Status = " << readout_status << '\n'; return 0; } int FFv1Object::ResetFED(int verbosity) { // reset register in VME resets all FPGAs and clock chain unsigned int clear = 0; ffv1SingleWrite(clear, FED_Reset/4); usleep(100); if (verbosity > 1) cout << "Sent a RESET to the FED" << '\n'; usleep(1000000); // safe wait for DCMs to lock ; hakved 08.03.06 if (verbosity > 1) cout << "Clear VME Event Memory" << '\n'; FillVMEEventMem(0xbeefface); return 0; } //int FFv1Object::TestReadout(int num_trigs, unsigned int num_secs, int verbosity, int event_format, int stop_flag) int FFv1Object::TestReadout(int num_trigs, unsigned int num_secs, int verbosity, int stop_flag, int bt_flag) { unsigned long readout_status; unsigned long buffer_length; unsigned long event_length = 0; unsigned long event_number; unsigned long fragment_number = 0; unsigned long total_length; // unsigned int buffers_pending = 0; unsigned long* bufp; int error = 0; int error_crc = 0; // unsigned long data; // unsigned int num_secs = 10; // unsigned int num_triggers = 3; unsigned int dummy; unsigned int i = 0; int trig_nr = 0; unsigned int readout_nr = 0; unsigned int error_nr = 0; unsigned int start = (unsigned int) time((time_t*) &dummy); // unsigned int now = (unsigned int) time((time_t*) &dummy); unsigned int now = start; bufp = readout_buffer; // one shot run , pile events up in QDR before reading out while (trig_nr < num_trigs && trig_nr < 100) { SendSWTrig(0); if (trig_nr%10 == 0) printf("Trigger nr = %d \n", trig_nr); usleep(5000); // be safe and wait for front ends to empty trig_nr++; } unsigned int first_trigger = 1; // 1 = for detailed printout on first event ; 0 for no printout int nblts = 0; if (first_trigger == 1) { printf("=====================================================================================\n"); if (bt_flag == 1) printf("Turbo Block Transfer VME Readout\n"); else printf("Single Cycle VME Readout\n"); } if (num_secs == 0) num_secs = 3; // while ((now - start) < num_secs && (readout_nr < trig_nr || num_trigs == 0)) { while ((now - start) < num_secs) { // continuous sending s/w triggers, check fed partial full flags are clear // if (num_trigs == -1) { // while (BuffersAvailable(&buffers_pending, 2) == 0) { // SendSWTrig(0); // trig_nr++; // } // } // printf("trig_nr = %d \n", trig_nr); // ...else we just wait for external hardware triggers if (num_trigs == -1) { SendSWTrig(0); trig_nr++; usleep(1000); } else { // printf("Waiting for 1 minute to allow TTCvi setup\n"); // sleep(60); // wait to setup ttcvi triggers } // unsigned long* bufp = readout_buffer; ffv1SingleRead(&readout_status, FED_Readout_CSR/4); // fill local buffer while event fragments are pending // must be a while loop so that bufp doesn't get reinitialised during multiple fragment events while (readout_status & 0x1) { fragment_number++; ffv1SingleRead(&buffer_length, FED_Readout_Buffer_Length/4); ffv1SingleRead(&total_length, FED_Readout_Event_Length/4); ffv1SingleRead(&event_number, FED_Readout_Event_Ctr/4); if (verbosity >= 2) cout << "Event Pending: Status = " << dec << readout_status << '\n'; if (verbosity >= 2) cout << "Event Number = " << dec << event_number << '\n'; if (verbosity >= 2) cout << "Fragment Number = " << dec << fragment_number << '\n'; if (verbosity >= 2) cout << "Buffer Size (32 bit words) = " << dec << buffer_length << " $ " << hex << buffer_length << '\n'; if (verbosity >= 2) cout << "Total Transferred (32 bit words) = " << dec << total_length << " $ " << hex << total_length << '\n'; event_length += buffer_length; if (verbosity >= 2) cout << "Event Length (32 bit words) = " << dec << event_length << " $ " << hex << event_length << '\n'; if (event_length > MAX_READOUT_LENGTH) { printf("** WARNING: Event Length = %d (words) is too large for Readout Buffer, Stopping \n", (unsigned int) event_length); break; } StopWatch timer(0); timer.start(); if (bt_flag == 1) { // Turbo Block Transfer let HAL split transfers ; max 4096 bytes?? /* int nr_blts = buffer_length*4/4096 + 1; // split into 4096 byte blocks unsigned long blt_len; for (int j=nr_blts; j>0; j--) { if (j == 1) { // last block blt_len = buffer_length*4 - ((nr_blts-1)*4096); } else { blt_len = 4096; // bytes } ffv1BlockRead(bufp, blt_len, FED_Readout_BRAM + (nr_blts-j)*4096); // for block access start address and length must be in BYTES ! bufp+=blt_len/4; // word ptr nblts++; if (verbosity >= 2) printf("Nr BLTs = %d ; blt_len = %d ; bufp = %d \n", (unsigned int) nblts, (unsigned int) blt_len, (unsigned int) bufp); } */ // assuming Turbo Block Transfer can handle any length // printf("Block Transfer...\n"); // usleep(1000000); // ? #ifdef BUILD_CAEN // normal BLT with arbitrary length (works for CAEN , not for SBS?) ffv1BlockRead(bufp, buffer_length*4, FED_Readout_BRAM); // for block access start address and length must be in BYTES ! bufp+=buffer_length; #else // SBS BLT only works with lengths multiples of 256 bytes ?? { unsigned long buffer_blocks_blt; unsigned long buffer_length_single; unsigned long buffer_start_single; buffer_blocks_blt = buffer_length / 64; // in 32 bit words buffer_length_single = buffer_length % 64; // remainder must be done in single cycles ffv1BlockRead(bufp, buffer_blocks_blt*64*4, FED_Readout_BRAM); // for block access start address and length must be in BYTES ! bufp+=buffer_blocks_blt*64; buffer_start_single = buffer_blocks_blt * 64; // in 32 bit words for (unsigned int i=0; i= 2) printf("bufp = %d \n", (unsigned int) bufp); } // last fragment is stored in buffer, we can now check event if (readout_status == 0x3) { timer.stop(); if (readout_nr == 0) DumpEventToFile(readout_buffer, event_length, verbosity); // save event to output file int crc_check = CheckCRC(readout_buffer, event_length, 0); // CheckEvent(readout_buffer, event_length, (int) event_number, &error, first_trigger, event_format, stop_flag, crc_check); CheckEventNew(readout_buffer, event_length, (int) event_number, &error, first_trigger, stop_flag, crc_check, &error_crc, 1); if (error != 0) { printf("*** ERROR : The format of readdout event = %04d was BAD. \n", readout_nr); error_nr++; if (stop_flag == 1) return 1; } readout_nr++; nblts = 0; fragment_number = 0; event_length = 0; bufp = readout_buffer; // next event overwrites previous // added 07.09.05 for (unsigned int i=0; i 1) cout << "After Clear Event Pending: Status = " << readout_status << '\n'; } now = (unsigned int) time((time_t*) &dummy); } printf("\n"); printf("################## Test Summary ################## \n"); printf(" Sent %d Software Triggers. \n", trig_nr); printf(" Readout %d Events with %d Format Errors. \n", readout_nr, error_nr); printf("################################################## \n"); return 0; } int FFv1Object::CheckEvent(unsigned long* event_buffer, unsigned long event_length, int event_nr, int* error, unsigned int trig_nr, int event_format, int stop_flag, int crc_check, int* error_crc) { // FE nr : FE modules 0 - 7 // Fibre nr : Fibres 0 - 11 on each FE // Chan nr : Chans 0 -95 unsigned int trk_hdr_new[2]; unsigned int trk_hdr_offset = 0; unsigned int trk_hdr_format = 0; unsigned int trk_evt_type = 0; unsigned int apve_addr = 0; unsigned int apv_err = 0; unsigned int be_status = 0; unsigned int fe_pipeaddr[8]; unsigned int fe_len[8]; unsigned int fe_status[8][12]; unsigned int fibre_len[chan_max]; unsigned int fibre_code[chan_max]; vector fibre_data[chan_max]; unsigned int ped_sum[chan_max]; unsigned int ped_sum_square[chan_max]; double ped_mean[chan_max]; double ped_rms[chan_max]; int ped_diff[chan_max]; unsigned int ped_max[chan_max]; unsigned int ped_min[chan_max]; unsigned int fibre_thresh[chan_max]; unsigned int fibre_med1[chan_max]; unsigned int fibre_med2[chan_max]; unsigned int fibre_code_ref = 0; unsigned int fibre_len_ref = 0; unsigned int look_fe = 1; unsigned int first_fe = 0; vector fe_data[8]; vector::iterator fibreIter; unsigned int header_len = daq_header_len + trk_header_prototype; // in 32 bit words ; old style header //unsigned int fe_data[12][1024]; // code below relies on length of first fibre being zero for (int i=0; i SLINK word # %d (DAQ hdr) (msb) = $%08x ; doesn't match expected = $%08x\n", 1, (unsigned int) (event_buffer[0] & 0xff000000), 0x51000000); *error = 1; if (stop_flag == 1) return 1; } // comment out checking if not fixed headers /* if (event_buffer[1] != 0xfff00118) { printf("*** ERROR => SLINK word # %d (DAQ hdr) (lsb) = $%08x ; doesn't match expected = $%08x\n", 1, (unsigned int) event_buffer[1], 0xfff00118); *error = 1; if (stop_flag == 1) return 1; } if (event_buffer[2] != 0xed1a0000) { printf("*** ERROR => SLINK word # %d (Trk hdr) (msb) = $%08x ; doesn't match expected = $%08x \n", 2, (unsigned int) event_buffer[2], 0xed1a0000); *error = 1; if (stop_flag == 1) return 1; } if (event_buffer[3] != 0xff000000) { printf("*** ERROR => SLINK word # %d (Trk hdr) (lsb) = $%08x ; doesn't match expected = $%08x \n", 2, (unsigned int) event_buffer[3], 0xff000000); *error = 1; if (stop_flag == 1) return 1; } */ unsigned int fe_len[8]; for (unsigned int fe=0; fe<8; fe++) { for (unsigned int i=0; i<4; i++) { if (i == 2) { // contains fe length fe_len[fe] = event_buffer[4 + 4*fe + i] >> 16 & 0xffff; if (fe == 0) { // fixed bits in first length // comment out checking if not fixed headers /* if ((event_buffer[4 + 4*fe + i] & 0xffff) != 0x0) printf("*** ERROR => SLINK word # %d (Trk FE %d) (msb) = $%08x ; doesn't match expected = $%08x \n", (4 + 4*fe + i)/2 + 1, 8-fe, (unsigned int) event_buffer[4 + 4*fe + i], (unsigned int) event_buffer[4 + 2] | 0xffff); */ } else { // comment out checking if not fixed headers /* if (event_buffer[4 + 4*fe + i] != event_buffer[4 + 2]) printf("*** ERROR => SLINK word # %d (Trk FE %d) (msb) = $%08x ; doesn't match expected = $%08x \n", (4 + 4*fe + i)/2 + 1, 8-fe, (unsigned int) event_buffer[4 + 4*fe + i], (unsigned int) event_buffer[4 + 2] | 0xffff); */ } } else { // comment out checking if not fixed headers /* if (event_buffer[4 + 4*fe + i] != 0x0) { if (i%2 == 0) printf("*** ERROR => SLINK word # %d (Trk FE %d) (msb) = $%08x ; doesn't match expected = $%08x \n", (4 + 4*fe + i)/2 + 1, 8-fe, (unsigned int) event_buffer[4 + 4*fe + i], 0x0); else printf("*** ERROR => SLINK word # %d (Trk FE %d) (lsb) = $%08x ; doesn't match expected = $%08x \n", (4 + 4*fe + i)/2 + 1, 8-fe, (unsigned int) event_buffer[4 + 4*fe + i], 0x0); *error = 1; if (stop_flag == 1) return 1; } */ } } if (fe_len[fe] != fe_len[0]) printf("*** ERROR => FE Length nr $%04x = $%08x ; doesn't match expected = $%04x\n", fe, fe_len[fe], fe_len[0]); } // nr slink words per fe unsigned int fe_words = fe_len[0]/8; if (fe_len[0]%8 != 0) fe_words += 1; // payload was a counter $aa0NNNNNaa0NNNNN where NNNNNN is 18 bit QDR write addr pointer // which starts from a new value in each event (counts up till end of event data, and may wraparound in event) /* unsigned int start_addr = event_buffer[36] & 0x0003ffff; unsigned int counter = 0; for (unsigned int i=36; i<(event_length - 2); i++) { // for (unsigned int i=36; i<40; i++) { if (event_buffer[i] != (0xaa000000 | ((start_addr + counter) % 0x400000))) { if (i%2 == 0) printf("*** ERROR => SLINK word # %d (msb) = $%08x ; doesn't match expected = $%08x \n", i/2 + 1, (unsigned int) event_buffer[i], (0xaa000000 | ((start_addr + counter) % 0x40000))); else printf("*** ERROR => SLINK word # %d (lsb) = $%08x ; doesn't match expected = $%08x \n", i/2 + 1, (unsigned int) event_buffer[i], (0xaa000000 | ((start_addr + counter) % 0x40000))); *error = 1; if (stop_flag == 1) return 1; } if (i%2 == 1) counter++; } */ // new counter data is $XYXYXYXY when $XY is an 8 bit wrapping counter unsigned int start_addr = event_buffer[36] & 0xff; unsigned int counter = 0; for (unsigned int i=36; i<(event_length - 2); i++) { unsigned int pattern = (start_addr + counter)% 0x100; unsigned int expected = ( (pattern << 24) | (pattern << 16) | (pattern << 8) | pattern ); if (event_buffer[i] != expected) { if (i%2 == 0) printf("*** ERROR => SLINK word # %d (msb) = $%08x ; doesn't match expected = $%08x \n", i/2 + 1, (unsigned int) event_buffer[i], expected ); else printf("*** ERROR => SLINK word # %d (lsb) = $%08x ; doesn't match expected = $%08x \n", i/2 + 1, (unsigned int) event_buffer[i], expected ); *error = 1; if (stop_flag == 1) return 1; } if (i%2 == 1) counter++; if (i%2 == 0 && *error == 1) printf("FE nr = %d ; counter = %d ; word = %d of %d \n", 8-(counter/fe_words), counter, counter%fe_words, fe_words); if (i%2 ==1 && *error == 1) break; } // comment out checking if not fixed headers /* if ((event_buffer[event_length - 2] & 0xff000000) != 0xa0000000) { printf("*** ERROR => SLINK word # %d (DAQ trailer) (msb) = $%08x ; doesn't match expected = $%08x\n", (unsigned int) event_length/2, (unsigned int) (event_buffer[event_length - 2] & 0xff000000), 0xa0000000); *error = 1; if (stop_flag == 1) return 1; } */ // comment out checking if not fixed headers /* if ((event_buffer[event_length - 1] & 0x0000ffff) != 0x00000ff8) { printf("*** ERROR => SLINK word # %d (DAQ trailer) (lsb) = $%08x ; doesn't match expected = $%08x \n", (unsigned int) event_length/2, (unsigned int) (event_buffer[event_length - 1] & 0x0000ffff), 0x000000f8); *error = 1; if (stop_flag == 1) return 1; } */ unsigned int daq_len = event_buffer[event_length - 2] & 0xffffff; // nr of 64 bit words unsigned int daq_crc = event_buffer[event_length - 1] >> 16 & 0xffff; if (daq_len != event_length/2) { printf("*** ERROR => Event Length in trailer = %d (64 bit words) doesn't match expected = %d \n", daq_len, (unsigned int) event_length/2 ); *error = 1; if (stop_flag == 1) return 1; } if (daq_crc != (unsigned int) crc_check) { printf("\n*** ERROR => CRC in event trailer = $%04x but re-computed CRC = $%04x \n", daq_crc, crc_check ); *error_crc = 1; // *error = 1; // if (stop_flag == 1) return 1; } } else { // daq header daq_event_type = event_buffer[0] >> 24 & 0xf; l1a_nr = event_buffer[0] & 0xffffff; bx_nr = event_buffer[1] >> 20 & 0xfff; fed_id = event_buffer[1] >> 8 & 0xfff; // printf("\nEvent Format = %d \n", event_format ); if (trig_nr == 1 || event_nr%1000 == 1) printf("VME Event Nr = %6d ; Event Length = %6d (32 bit words) \n\v", event_nr, (unsigned int) event_length ); if (trig_nr == 1) printf("DAQ Header : L1A Nr = %6d ; Bx Nr = %6d ; Evt Type = $ %02x ; Fed ID = $ %04x \n", l1a_nr, bx_nr, (unsigned int) daq_event_type, (unsigned int) fed_id ); // CERN can use different IDs // if (fed_id != 0xFED) { // cout << "Error: fed_id != 0xFED. Stopping event check." << '\n'; // *error = 1; // if (stop_flag == 1) return 1; // } // changed for first event l1a = 1 rather than 0 jac 9/12/2004 // event_nr < 0 means ignore when checking event read from file if (l1a_nr != (unsigned int) event_nr && event_nr >= 0) { printf("*** ERROR => L1A = %d ($%02x) doesn't match Readout Event Nr = %d \n", l1a_nr, (unsigned int) (l1a_nr), event_nr); *error = 1; if (stop_flag == 1) return 1; } // check for a new style tracker header format (has $ED at start of first word after DAQ header) if not it is an old style header if (event_buffer[2] >> 24 == 0xED) { // new style trk_hdr_format = (event_buffer[2] & 0x00f00000) >> 20; trk_evt_type = (event_buffer[2] & 0x000f0000) >> 16; apve_addr = (event_buffer[2] & 0x0000ff00) >> 8; apv_err = (event_buffer[2] & 0x000000ff); be_status = event_buffer[3]; trk_hdr_new[0] = event_buffer[2]; trk_hdr_new[1] = event_buffer[3]; trk_hdr_offset = 2; if (trk_hdr_format == FED_TRK_HEADER_FULL_DEBUG) { header_len = daq_header_len + trk_header_special + trk_header_full_debug; } else { header_len = daq_header_len + trk_header_special + trk_header_apv_error; } if (trig_nr == 1) { printf("Trk Header : Format = %2d ; Evt Type = %2d ; APVE Addr = $ %02x ; APV Error = $ %02x \n", trk_hdr_format, (signed) trk_evt_type, apve_addr, apv_err ); printf("Trk Header : BE Status = $ %08x \n\n", be_status ); } } if (trk_hdr_format == FED_TRK_HEADER_APV_ERROR) { // don't have fe lengths in this mode ! for (int i=0; i<8; i++) { // loop over fe fpgas fe_len[i] = 1; // set non-zero } } else { // tracker header ; old style part for (int i=0; i<8; i++) { // loop over fe fpgas fe_len[i] = event_buffer[i*4 + 4 + trk_hdr_offset] >> 16 & 0xffff; // nr of bytes fe_pipeaddr[i] = event_buffer[i*4 + 5 + trk_hdr_offset] >> 8 & 0xff; fe_status[i][0] = event_buffer[i*4 + 5 + trk_hdr_offset] >> 2 & 0x3f; fe_status[i][1] = ((event_buffer[i*4 + 4 + trk_hdr_offset] & 0x3) << 4) | (event_buffer[i*4 + 2 + trk_hdr_offset] >> 28 & 0xf); fe_status[i][2] = event_buffer[i*4 + 2 + trk_hdr_offset] >> 22 & 0x3f; fe_status[i][3] = event_buffer[i*4 + 2 + trk_hdr_offset] >> 16 & 0x3f; fe_status[i][4] = event_buffer[i*4 + 2 + trk_hdr_offset] >> 10 & 0x3f; fe_status[i][5] = event_buffer[i*4 + 2 + trk_hdr_offset] >> 4 & 0x3f; fe_status[i][6] = ((event_buffer[i*4 + 2 + trk_hdr_offset] & 0xf) << 2) | (event_buffer[i*4 + 3 + trk_hdr_offset] >> 30 & 0x3); fe_status[i][7] = event_buffer[i*4 + 3 + trk_hdr_offset] >> 24 & 0x3f; fe_status[i][8] = event_buffer[i*4 + 3 + trk_hdr_offset] >> 18 & 0x3f; fe_status[i][9] = event_buffer[i*4 + 3 + trk_hdr_offset] >> 12 & 0x3f; fe_status[i][10] = event_buffer[i*4 + 3 + trk_hdr_offset] >> 6 & 0x3f; fe_status[i][11] = event_buffer[i*4 + 3 + trk_hdr_offset] & 0x3f; } if (trig_nr == 1) { printf("FE Nr \tLength\tPipe $ \tFE Status Bits $ (0-11) \n"); printf("\t(bytes) \tAddress \n"); for (int i=0; i<8; i++) { // loop over fe fpgas // if (look_fe != 0 && fe_len[i] != 0) { // first_fe = i; // get first non zero fe length for comparing with other fe's // look_fe = 0; // stop looking // } printf("%d \t%06x \t%02x \t\t", 8-i, fe_len[i], fe_pipeaddr[i]); for (int j=0; j<12; j++) { printf("%02x ", fe_status[i][j]); } printf("\n"); } } for (int i=0; i<8; i++) { // loop over fe fpgas if (look_fe != 0 && fe_len[i] != 0) { first_fe = i; // get first non zero fe length for comparing with other fe's look_fe = 0; // stop looking } } for (int i=0; i<8; i++) { // loop over fe fpgas if (fe_len[i] != 0 && fe_len[i] != fe_len[first_fe]) { printf("*** ERROR: Tracker Header: FE # %d ; Length = $%04x (bytes) is different from FE # %d ; Length = $%04x (bytes) \n", 8-i, (unsigned int) fe_len[i], first_fe, (unsigned int) fe_len[first_fe]); *error = 1; if (stop_flag == 1) return 1; } } } unsigned int nwords = header_len - 1; // skip headers // put tracker payload data from each FE into a vector of bytes for later manipulations for (int fe_nr=0; fe_nr<8; fe_nr++) { // loop over fe fpgas if (fe_len[fe_nr] != 0) { int k =0; unsigned char value; for (unsigned int nbytes=0; nbytes> (24 - k*8)) & 0xff; // printf("word # %d ; byte # %d ; k = %d ; buffer = $ %08x ; value = $ %02x \n",nwords, nbytes, k, event_buffer[nwords], value); fe_data[fe_nr].push_back(value); } // start of each block of FE data is aligned on 64 bit word boundary, skip padding at end if (k != 3) nwords++; if (nwords %2 == 0) nwords++; // printf("fe nr = %d ; nwords = %d \n", 8-fe_nr, nwords); } } if (event_format == FED_EVT_FORMAT_SLINK) { printf("* WARNING: Event Format = SLINK Patterns. Stopping here. \n"); return 0; } if (event_format == FED_EVT_FORMAT_ZS) { // variable length data from FEs for (unsigned int fe_nr=0; fe_nr<8; fe_nr++) { // printf("fe_nr = %d \n", 8-fe_nr); fibreIter = fe_data[fe_nr].begin(); // printf("*fibreIter = %d \n", *fibreIter); if (fe_len[fe_nr] != 0) { unsigned int fibre_nr = 0; // first fibre at fixed location fibre_len[fe_nr*12+fibre_nr] = *(fibreIter+1) * 256 + *(fibreIter); fibre_code[fe_nr*12+fibre_nr] = *(fibreIter+2); fibre_code_ref = fibre_code[first_fe*12+fibre_nr]; if (fibre_code[fe_nr*12+fibre_nr] != 0xea) { printf("FE nr = %d ; Fibre nr = %d : Sorry Fibre code = $ %02x is not ZS \n", 8-fe_nr, 0, fibre_code[fe_nr*12+fibre_nr]); *error = 1; if (stop_flag == 1) return 1; } if (fibre_len[fe_nr*12+fibre_nr] > (8 * 1024)) { printf("FE nr = %d ; Fibre nr = %d : Fibre length is too long = %d \n", 8-fe_nr, fibre_nr, fibre_len[fe_nr*12+fibre_nr]); *error = 1; if (stop_flag == 1) return 1; } if (trig_nr == 1 ) { printf("FE nr %d ; 1st fibre len = %d bytes ; 1st fibre code = $ %02x \n", 8-fe_nr, fibre_len[fe_nr*12], fibre_code[fe_nr*12]); } // remaining 11 fibres for (unsigned int fibre_nr=1; fibre_nr<12; fibre_nr++) { // printf("fibre_nr = %d\n", fibre_nr); fibreIter+=fibre_len[fe_nr*12+fibre_nr-1]; // add previous length to pointer to get to start of this fibre // printf("got fibreIter \n"); fibre_len[fe_nr*12+fibre_nr] = *(fibreIter+1) * 256 + *fibreIter; // printf("fibre_len = %d\n", fibre_len[fe_nr*12+fibre_nr]); fibre_code[fe_nr*12+fibre_nr] = *(fibreIter+2); // printf("fibre_code = %02x\n", fibre_code[fe_nr*12+fibre_nr]); if (fibre_code[fe_nr*12+fibre_nr] != fibre_code_ref) { printf("*** ERROR => FE nr = %d ; Fibre nr = %d : Fibre code = $ %02x is different from reference = $ %02x \n", 8-fe_nr, fibre_nr, fibre_code[fe_nr*12+fibre_nr], fibre_code_ref); *error = 1; if (stop_flag == 1) return 1; } } } } } else { // fixed length modes including Scope mode // check lengths and codes on 1st fibre for all 8 FE modules // NN this WON'T work for zero suppressed modes or s-link test patterns for (unsigned int fe_nr=0; fe_nr<8; fe_nr++) { if (fe_len[fe_nr] != 0) { unsigned int fibre_nr = 0; // first fibre at fixed location fibre_len[fe_nr*12+fibre_nr] = *(fe_data[fe_nr].begin()+1) * 256 + *(fe_data[fe_nr].begin()); fibre_code[fe_nr*12+fibre_nr] = *(fe_data[fe_nr].begin()+2); // first fibre header on first non-zero FE (found earlier) is the reference for comparison // nb ref doesn't change up to 8 times round loop, uggh fibre_code_ref = fibre_code[first_fe*12+fibre_nr]; fibre_len_ref = fibre_len[first_fe*12+fibre_nr]; if (fibre_code[fe_nr*12+fibre_nr] != 0xe5 && fibre_code[fe_nr*12+fibre_nr] != 0xe6) { printf("FE nr = %d ; Fibre nr = %d : Sorry can't handle Fibre code = $ %02x \n", 8-fe_nr, 0, fibre_code[fe_nr*12+fibre_nr]); *error = 1; if (stop_flag == 1) return 1; } if (fibre_len[fe_nr*12+fibre_nr] > (8 * 1024)) { printf("FE nr = %d ; Fibre nr = %d : Fibre length is too long = %d \n", 8-fe_nr, fibre_nr, fibre_len[fe_nr*12+fibre_nr]); *error = 1; if (stop_flag == 1) return 1; } if (trig_nr == 1 ) { printf("FE nr %d ; 1st fibre len = %d bytes ; 1st fibre code = $ %02x \n", 8-fe_nr, fibre_len[fe_nr*12], fibre_code[fe_nr*12]); } // fill fibre data for (unsigned int sample_nr=0; sample_nr < (fibre_len[fe_nr*12+fibre_nr]-3)/2; sample_nr++) { int sample = *(fe_data[fe_nr].begin()+fibre_len[fe_nr*12+fibre_nr]*fibre_nr+4+sample_nr*2) * 256 + *(fe_data[fe_nr].begin()+fibre_len[fe_nr*12+fibre_nr]*fibre_nr+3+sample_nr*2); fibre_data[fe_nr*12+fibre_nr].push_back(sample); // printf("FE nr = %d ; Fibre nr = %d : sample_nr = %d ; sample = %d \n", 8-fe_nr, fibre_nr, sample_nr, sample); } // remaining 11 fibres at offsets determined by first fibre , nb won't work for zero suppress modes ! for (unsigned int fibre_nr=1; fibre_nr<12; fibre_nr++) { fibre_len[fe_nr*12+fibre_nr] = *(fe_data[fe_nr].begin()+(fibre_nr*fibre_len[fe_nr*12]+1)) * 256 + *(fe_data[fe_nr].begin()+(fibre_nr*fibre_len[fe_nr*12])); fibre_code[fe_nr*12+fibre_nr] = *(fe_data[fe_nr].begin()+(fibre_nr*fibre_len[fe_nr*12]+2)); // printf("FE nr = %d ; Fibre nr = %d : Fibre code = $ %02x ; Fibre Length = $ %02x (%d dec) \n", // 8-fe_nr, fibre_nr, fibre_code[fe_nr*12+fibre_nr], fibre_len[fe_nr*12+fibre_nr], fibre_len[fe_nr*12+fibre_nr]); if (fibre_code[fe_nr*12+fibre_nr] != fibre_code_ref) { printf("*** ERROR => FE nr = %d ; Fibre nr = %d : Fibre code = $ %02x is different from reference = $ %02x \n", 8-fe_nr, fibre_nr, fibre_code[fe_nr*12+fibre_nr], fibre_code_ref); *error = 1; if (stop_flag == 1) return 1; } if (fibre_len[fe_nr*12+fibre_nr] != fibre_len_ref) { printf("*** ERROR => FE nr = %d ; Fibre nr = %d : Fibre length = $%02x is different from reference = $%02x \n", 8-fe_nr, fibre_nr, (unsigned int) fibre_len[fe_nr*12+fibre_nr], (unsigned int) fibre_len_ref); *error = 1; if (stop_flag == 1) return 1; } // fill fibre data for (unsigned int sample_nr=0; sample_nr < (fibre_len[fe_nr*12+fibre_nr]-3)/2; sample_nr++) { int sample = *(fe_data[fe_nr].begin()+fibre_len[fe_nr*12+fibre_nr]*fibre_nr+4+sample_nr*2) * 256 + *(fe_data[fe_nr].begin()+fibre_len[fe_nr*12+fibre_nr]*fibre_nr+3+sample_nr*2); fibre_data[fe_nr*12+fibre_nr].push_back(sample); // printf("FE nr = %d ; Fibre nr = %d : sample_nr = %d ; sample = %d \n", 8-fe_nr, fibre_nr, sample_nr, sample); } } } else { // printf("FE mod %d ; is zero length \n", 8-fe_nr); } } // printf(" fibre codes \n"); // for (unsigned int fe_nr=0; fe_nr<8; fe_nr++) { // for (unsigned int fibre_nr=0; fibre_nr<12; fibre_nr++) { // if (fibre_nr%12 == 0) printf("\n"); // printf(" %02x ", fibre_code[fe_nr*12+fibre_nr]); // } // } // printf("\n"); if (trig_nr == 1) { printf("Fibre Data :\n"); printf("Chan Nr : \n"); int diff = 0; for (int chan_nr=0; chan_nr::iterator it = fibre_data[chan_nr].begin(); it != fibre_data[chan_nr].end(); ++it) { ped_sum[chan_nr] += *it; ped_sum_square[chan_nr] += (*it * *it); if (j < 100) { // assumes some ticks at start of pattern // assume max value is tick ! if ((unsigned int) *it > ped_max[chan_nr]) { ped_max[chan_nr] = *it; } // assume min is baseline if ((unsigned int) *it < ped_min[chan_nr]) { ped_min[chan_nr] = *it; } if (j>0) { // there is nothing to cf 1st sample to diff = (int) abs( (int) (*it - *(it-1)) ); if (diff > ped_diff[chan_nr]) { ped_diff[chan_nr] = diff; } } } if (j<20) printf("%4d ", *it); j++; } printf("\n"); // compute pedestals means and rms ped_mean[chan_nr] = (double) ped_sum[chan_nr] / (double) j; ped_rms[chan_nr] = (double) ped_sum_square[chan_nr] / (double) j - ped_mean[chan_nr] * ped_mean[chan_nr]; if (ped_rms[chan_nr] < 0.0) ped_rms[chan_nr] *= -1.0; fibre_thresh[chan_nr] = (ped_max[chan_nr] - ped_min[chan_nr]) / 2 + ped_min[chan_nr]; // raw adc counts // these calculated global variables are used to load fed registers fibre_ped_calc[chan_nr] = ped_min[chan_nr]; // assume minimum is baseline pedestal fibre_thresh_calc[chan_nr] = fibre_thresh[chan_nr]/32; // convert to register contents 0-15 (* 32 adc counts) // compute tick thresholds } printf("\n"); printf("Pedestals Mean (rms) : \n"); printf("FE nr / Chan nr : \n"); printf(" \t 0 \t\t 1\t\t 2\t\t 3\t\t 4\t\t 5\t\t 6\t\t 7\t\t 8\t\t 9\t\t 10\t\t 11\n"); for (int fe_nr=0; fe_nr 900.0 || ped_rms[fe_nr*12 + fibre_nr] > 1.0) ? '*' : ' '); } } printf("\n"); printf("\n"); printf("Min->Max : \n"); printf("FE nr / Chan nr : \n"); printf(" \t 0 \t\t 1\t\t 2\t\t 3\t\t 4\t\t 5\t\t 6\t\t 7\t\t 8\t\t 9\t\t 10\t\t 11\n"); for (int fe_nr=0; fe_nr%4d(%4d) %c; ", ped_min[fe_nr*12 + fibre_nr], ped_max[fe_nr*12 + fibre_nr], ped_max[fe_nr*12 + fibre_nr] - ped_min[fe_nr*12 + fibre_nr], (ped_max[fe_nr*12 + fibre_nr] - ped_min[fe_nr*12 + fibre_nr] < 400) ? '*' : ' '); } } printf("\n"); printf("\n"); printf("Fibre Thresholds Calculated : \n"); printf("FE nr / Chan nr : \n"); printf(" \t 0 \t\t 1\t\t 2\t\t 3\t\t 4\t\t 5\t\t 6\t\t 7\t\t 8\t\t 9\t\t 10\t\t 11\n"); for (int fe_nr=0; fe_nr> 16 & 0xffff; unsigned int daq_evt_stat = event_buffer[nwords] >> 8 & 0xf; unsigned int daq_tts_stat = event_buffer[nwords] >> 4 & 0xf; nwords++; if (nwords%2 != 0) { printf("*** ERROR => Total number of words (32 bit) = %d should be EVEN \n", nwords ); *error = 1; } if (daq_crc != (unsigned int) crc_check) { printf("*** ERROR => CRC in event trailer = $%04x but re-computed CRC = $%04x \n", daq_crc, crc_check ); *error = 1; } if (trig_nr == 1) { printf("DAQ Trailer : Evt Length = %8d (64 bit words) ; CRC = $ %04x \n", daq_len, daq_crc ); printf("DAQ Trailer : Evt Status = $ %01x ; TTS Status = $ %01x \n", daq_evt_stat, daq_tts_stat ); printf("\nRe-computed CRC = $ %04x \n", crc_check); } if (daq_len != nwords/2) { printf("*** ERROR => Event Length in trailer = %d doesn't match calculated = %d \n", daq_len, nwords/2 ); printf("DAQ Trailer word reads $ %08x-%08x ? \n", daq_trailer_low, daq_trailer_high ); *error = 1; } } // *error = 1; // test only ! if (*error == 0) { if (trig_nr == 1) printf("\nThe format of this event was OK. \n"); } return 0; } int FFv1Object::CheckEventNew(unsigned long* event_buffer, unsigned long event_length, int event_nr, int* error, unsigned int trig_nr, int stop_flag, int crc_check, int* error_crc, int verbosity) { // new event checking recognises all header and payload formats based on information in event // FEDv2 channel conventions 23.02.2005 // FE nr : FE modules 1 - 8 Bot - Top // Fibre nr : Fibres 1 - 12 on each FE Bot - Top // FED Chan nr = FE nr * 100 + Fibre nr // put complete event into a vector of bytes for later manipulations vector event_data; vector::iterator evtP; unsigned long word; unsigned char ch; if (trig_nr == 1) printf("\nNEW Event Checking ...\n\n"); *error = 0; // clear error flag before checking for new event for (int i=0; i<(int)event_length; i++) { word = *event_buffer++; for (int j=3; j>=0; j--) { ch = (word >> j*8) & 0xff; // printf("ch= %02x\n", ch); event_data.push_back(ch); } } evtP = event_data.begin(); char *daq_evt_type_str[16] = {"UNDEFINED", "PHYSICS", "CALIBRATION", "TEST", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", }; unsigned int boe = 0; unsigned int daq_evt_type = 0; unsigned int l1a_nr = 0; unsigned int bx_nr = 0; unsigned int fed_id = 0; unsigned int fov = 0; // process daq header boe = *evtP >> 4; daq_evt_type = *evtP++ & 0xf; for (int j=2; j>=0; j--) { l1a_nr |= *evtP++ << j*8; } unsigned int temp = 0; for (int j=2; j>=0; j--) { temp |= *evtP++ << j*8; } bx_nr = temp >> 12; fed_id = temp & 0xfff; fov = *evtP++ >>4; if (trig_nr == 1 || event_nr%1000 == 1) printf("DAQ Header : BOE = $%1x ; Evt Type = $%02x ; L1A Nr = %6d ; Bx Nr = $%03x (%4d); Fed ID = $%04x ; FOV = $%1x\n", boe, (unsigned int) daq_evt_type, l1a_nr, bx_nr, bx_nr, (unsigned int) fed_id, fov ); if (trig_nr == 1) printf("DAQ Event Type = %s \n", daq_evt_type_str[daq_evt_type] ); // tracker header char *trk_evt_type_str[16] = {"UNDEFINED", "SCOPE MODE", "VIRGIN RAW REAL", "VIRGIN RAW FAKE", "UNDEFINED", "UNDEFINED", "PROCESSED RAW REAL", "PROCESSED RAW FAKE", "UNDEFINED", "UNDEFINED", "ZERO-SUPPRESSED REAL", "ZERO-SUPPRESSED FAKE", "ZS-LITE REAL", "ZS-LITE FAKE", "UNDEFINED", "UNDEFINED" }; char *trk_hdr_format_str[16] = {"OLD STYLE", "FULL DEBUG", "APV ERROR", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED"}; unsigned int reserved1 = 0; unsigned int trk_hdr_format = 0; unsigned int trk_evt_type = 0; unsigned int apve_addr = 0; unsigned int apv_err = 0; unsigned int fe_enable = 0; unsigned int fe_overflow = 0; unsigned int be_status = 0; reserved1 = *evtP; if (reserved1 != 0xED) { trk_hdr_format = FED_TRK_HEADER_OLD; // same as Full Debug except no special header word trk_evt_type = daq_evt_type; fe_enable = 0xff; fe_overflow = 0xff; // ignore l1a check agains evt num as l1a may start at 0 // printf("ERROR : Can't process OLD style Tracker Header Formats \n"); // return -1; } else { // NEW special header word for all standard tracker headers // printf("NEW Tracker Header Format ...\n"); evtP++; // reserved1 already processed trk_hdr_format = *evtP >> 4; trk_evt_type = *evtP++ & 0xf; apve_addr = *evtP++; apv_err = *evtP++; for (int j=3; j>=0; j--) { be_status |= *evtP++ << j*8; } fe_enable = be_status >> 24; // fe_enable = 0xff; fe_overflow = be_status >> 16 & 0xff; // fe_overflow = 0xff; if (trig_nr == 1) printf("TRACKER Header : Reserved = $%02x ; Hdr Format = $%1x ; Trk Event Type = $%1x ; APVE Addr = $%02x ; APV Err = $%02x ; FE Enable = $%02x ; FE Overflow = $%02x ; BE Status= $%08x\n", reserved1, trk_hdr_format, trk_evt_type, apve_addr, apv_err, fe_enable, fe_overflow, be_status ); if (apv_err != 0xff) { // printf("*** ERROR : Some FE APVs = $%02x did not agree with Golden APVE value \n", apv_err); // *error = 1; // if (stop_flag == 1) return 1; } // changed for first event l1a = 1 rather than 0 jac 9/12/2004 // event_nr < 0 means ignore when checking event read from file if (l1a_nr != (unsigned int) event_nr && event_nr >= 0) { printf("*** ERROR => L1A = %d ($%02x) doesn't match Readout Event Nr = %d \n", l1a_nr, (unsigned int) (l1a_nr), event_nr); *error = 1; if (stop_flag == 1) return 1; } } if (trig_nr == 1) printf("TRACKER Event Type = %s \n", trk_evt_type_str[trk_evt_type] ); if (trig_nr == 1) printf("TRACKER Header Format = %s \n", trk_hdr_format_str[trk_hdr_format] ); // process remainder of tracker header depending on format unsigned int fe_pipeaddr[8]; unsigned int fe_len[8]; unsigned int fe_status[8][12]; unsigned int fe_reserved[8]; if (trk_hdr_format == FED_TRK_HEADER_APV_ERROR) { unsigned int apv_flags[8]; unsigned char temp[24]; // 6 words of packed fibre apv error status for (int i=0; i<24; i++) { temp[i] = *evtP++; printf("i = %d ; temp = %02x \n", i, temp[i]); } apv_flags[0] = temp[5] << 16 | temp[6] << 8 | temp[7]; apv_flags[1] = temp[2] << 16 | temp[3] << 8 | temp[4]; apv_flags[2] = temp[15] << 16 | temp[0] << 8 | temp[1]; apv_flags[3] = temp[12] << 16 | temp[13] << 8 | temp[14]; apv_flags[4] = temp[9] << 16 | temp[10] << 8 | temp[11]; apv_flags[5] = temp[22] << 16 | temp[23] << 8 | temp[8]; apv_flags[6] = temp[19] << 16 | temp[20] << 8 | temp[21]; apv_flags[7] = temp[16] << 16 | temp[17] << 8 | temp[18]; for (int i=0; i<7; i++) { printf("i = %d ; apv_flags = %06x \n", i, apv_flags[i]); } // NB not sure of Saeed's ordering of APV status bits for (int fe=0; fe<8; fe++) { for (int i=0; i<12; i++) { fe_status[fe][i] = apv_flags[fe] >> (22-2*i) & 0x3; } } if (trig_nr == 1) { printf("FE Nr \tFE Status Bits $ (0-11) \n"); for (int i=0; i<8; i++) { printf("%d \t\t", 8-i); for (int j=0; j<12; j++) { printf("%1x ", fe_status[i][j]); } printf("\n"); } } } else { // Full Tracker Headers for (int fe=0; fe<8; fe++) { // fe fpgas unsigned int temp[4]; for (int i=0; i<4; i++) { // 4 words of fibre info per fe temp[i] = 0; for (int j=3; j>=0; j--) { temp[i] |= *evtP++ << j*8; } // printf("i=%d temp=$%08x \n", i, temp[i]); } fe_len[fe] = temp[2] >> 16 & 0xffff; // nr of bytes fe_pipeaddr[fe] = temp[3] >> 8 & 0xff; fe_status[fe][0] = temp[3] >> 2 & 0x3f; fe_status[fe][1] = ((temp[3] & 0x3) << 4) | (temp[0] >> 28 & 0xf); fe_status[fe][2] = temp[0] >> 22 & 0x3f; fe_status[fe][3] = temp[0] >> 16 & 0x3f; fe_status[fe][4] = temp[0] >> 10 & 0x3f; fe_status[fe][5] = temp[0] >> 4 & 0x3f; fe_status[fe][6] = ((temp[0] & 0xf) << 2) | (temp[1] >> 30 & 0x3); fe_status[fe][7] = temp[1] >> 24 & 0x3f; fe_status[fe][8] = temp[1] >> 18 & 0x3f; fe_status[fe][9] = temp[1] >> 12 & 0x3f; fe_status[fe][10] = temp[1] >> 6 & 0x3f; fe_status[fe][11] = temp[1] & 0x3f; fe_reserved[fe] = (temp[2] << 16 | temp[3] >> 16); // stores daq register ...etc } if (trig_nr == 1) { printf("DAQ Register = $%08x \n\n", fe_reserved[7] ); printf("FE Nr \tLength $\tPipe \tFibre APV Status $\n"); printf("\t(bytes) \tAddr $ \t12 11 10 9 8 7 6 5 4 3 2 1\n"); for (int i=0; i<8; i++) { // fe fpgas printf("%d \t%06x \t%02x \t", 8-i, fe_len[i], fe_pipeaddr[i]); for (int j=0; j<12; j++) { // fibres printf("%02x ", fe_status[i][j]); } printf("\n"); } printf("\n\n"); } } // process tracker payload depending on tracker event type // NB assumes ALL FE FPGAs are enabled in readout (until status bits are provided in header) unsigned int fibre_len[chan_max]; unsigned int fibre_code[chan_max]; unsigned int fibre_code_ref = 0; vector fibre_data[chan_max]; unsigned int ped_sum[chan_max]; unsigned int ped_sum_square[chan_max]; double ped_mean[chan_max]; double ped_rms[chan_max]; int ped_diff[chan_max]; unsigned int ped_max[chan_max]; unsigned int ped_min[chan_max]; unsigned int fibre_thresh[chan_max]; unsigned int fibre_med1[chan_max]; unsigned int fibre_med2[chan_max]; unsigned int fibre_clusters[chan_max]; const unsigned int max_strips = 255; const unsigned int max_cluster_data = 1024; // guess for (int i=0; i Unrecognised Tracker Event Type = $%1x \n", trk_evt_type); *error = 1; if (stop_flag == 1) return 1; break; } for (int fe=0; fe<8; fe++) { unsigned int fe_bytes = 0; unsigned int data_bytes = 0; vector::iterator evtP_start = evtP; // keep count to work out padding at end of fe fpga block vector::iterator evtP_temp; // keep count during cluster data if (fe_enable & (0x01 << fe)) { for (int fib=0; fib<12; fib++) { // get fibre header info for (int j=0; j<2; j++) { // loop is up as msb is first in stream fibre_len[fib] |= *evtP++ << j*8; } if (trk_evt_type != FED_EVT_TYPE_ZS_LITE && trk_evt_type != FED_EVT_TYPE_ZS_LITE_FAKE) { fibre_code[fib] = *evtP++; //printf("FED Chan = %3d ; fibre nr = %d ; tot len bytes = $%04x ; code =$%02x\n", // ((8-fe)*100 + 12-fib), 12-fib, fibre_len[fib], fibre_code[fib]); if (fibre_code[fib] != fibre_code_ref ) { printf("*** ERROR => FED Chan = %3d ; FE nr = %d ; Fibre nr = %d ; Fibre code = $ %02x is different from expected = $ %02x \n", ((8-fe)*100 + 12-fib), 8-fe, 12-fib, fibre_code[fib], fibre_code_ref ); *error = 1; if (stop_flag == 1) return 1; } } if (trk_evt_type == FED_EVT_TYPE_ZS || trk_evt_type == FED_EVT_TYPE_ZS_FAKE || trk_evt_type == FED_EVT_TYPE_ZS_LITE || trk_evt_type == FED_EVT_TYPE_ZS_LITE_FAKE ) { unsigned int cluster_addr = 0; unsigned int cluster_len = 0; if (trk_evt_type == FED_EVT_TYPE_ZS || trk_evt_type == FED_EVT_TYPE_ZS_FAKE ) { // median information for (int j=0; j<2; j++) { // loops are up as msb is first in stream fibre_med1[fe*12 + fib] |= *evtP++ << j*8; } for (int j=0; j<2; j++) { fibre_med2[fe*12 + fib] |= *evtP++ << j*8; } data_bytes = fibre_len[fib] - 7; //printf("FED Chan = %3d ; fibre nr = %d ; data bytes = $%04x\n", ((8-fe)*100 + 12-fib), 12-fib, data_bytes); } else { // ZS-lite data_bytes = fibre_len[fib] - 2; //printf("FED Chan = %3d ; fibre nr = %d ; data bytes = $%04x\n", ((8-fe)*100 + 12-fib), 12-fib, data_bytes); } if (data_bytes > max_cluster_data) { printf("*** ERROR => FED Chan = %3d ; FE nr = %d ; Fibre nr = %d: Number of Cluster bytes on Fibre = %d > %d \n", ((8-fe)*100 + 12-fib), 8-fe, 12-fib, data_bytes, max_cluster_data); *error = 1; if (stop_flag == 1) return 1; } evtP_temp = evtP; // cluster information if (data_bytes == 0) { fibre_clusters[fe*12 + fib] = 0; } else { while ((unsigned int) (evtP - evtP_temp) < data_bytes) { cluster_addr = *evtP++; if (cluster_addr > max_strips ) { printf("*** ERROR => FED Chan = %3d ; FE nr = %d ; Fibre nr = %d : Cluster Nr = %d ; Cluster Address = %d is > %d \n", ((8-fe)*100 + 12-fib), 8-fe, 12-fib, fibre_clusters[fe*12 + fib], cluster_addr, max_strips); *error = 1; if (stop_flag == 1) return 1; } cluster_len = *evtP++; if (cluster_len > max_strips ) { printf("*** ERROR => FED Chan = %3d ; FE nr = %d ; Fibre nr = %d : Cluster Nr = %d ; Cluster Length = %d is > %d \n", ((8-fe)*100 + 12-fib), 8-fe, 12-fib, fibre_clusters[fe*12 + fib], cluster_len, max_strips); *error = 1; if (stop_flag == 1) return 1; } for (unsigned int i=0; i 1) printf("i=%d ; data = %d; ", i, (unsigned char) *evtP); evtP++; // skip data } fibre_clusters[fe*12 + fib]++; if (verbosity > 1) printf("\nFED Chan = %3d : cluster nr = %d ; cluster addr = $%02x ; cluster len = $%02x\n", ((8-fe)*100 + 12-fib), fibre_clusters[fe*12 + fib], cluster_addr, cluster_len); } } } else { // raw data formats data_bytes = fibre_len[fib] - 3; if (data_bytes%2 != 0) { printf("*** ERROR => FED Chan = %3d ; FE nr = %d ; Fibre nr = %d : Number of Raw Data bytes = %d is NOT an Even number \n", ((8-fe)*100 + 12-fib), 8-fe, 12-fib, data_bytes); *error = 1; if (stop_flag == 1) return 1; } // get fibre raw data 10 bit samples unsigned char lsb, msb; for (unsigned int i=0; i FE nr = %d : Computed length = %d bytes is different from header = %d bytes ($%04x) \n", 8-fe, fe_bytes, fe_len[fe], fe_len[fe] ); *error = 1; if (stop_flag == 1) return 1; } } } // analyse data if (trig_nr == 1) { if (trk_evt_type == FED_EVT_TYPE_ZS || trk_evt_type == FED_EVT_TYPE_ZS_FAKE) { printf("Fibre Data :\n"); printf("Chan Nr : Median 1 ; Median 2 ; Nr Clusters\n"); for (int chan_nr=0; chan_nr::iterator it = fibre_data[chan_nr].begin(); it != fibre_data[chan_nr].end(); ++it) { ped_sum[chan_nr] += *it; ped_sum_square[chan_nr] += (*it * *it); if (j < 100) { // assumes some ticks at start of pattern // assume max value is tick ! if ((unsigned int) *it > ped_max[chan_nr]) { ped_max[chan_nr] = *it; } // assume min is baseline if ((unsigned int) *it < ped_min[chan_nr]) { ped_min[chan_nr] = *it; } if (j>0) { // there is nothing to cf 1st sample to diff = (int) abs( (int) (*it - *(it-1)) ); if (diff > ped_diff[chan_nr]) { ped_diff[chan_nr] = diff; } } } if (j<20) printf("%4d ", *it); j++; } if ((chan_nr+1) % 12 == 0) printf("\n--------"); printf("\n"); // compute pedestals means and rms ped_mean[chan_nr] = (double) ped_sum[chan_nr] / (double) j; ped_rms[chan_nr] = (double) ped_sum_square[chan_nr] / (double) j - ped_mean[chan_nr] * ped_mean[chan_nr]; if (ped_rms[chan_nr] < 0.0) ped_rms[chan_nr] *= -1.0; fibre_thresh[chan_nr] = (ped_max[chan_nr] - ped_min[chan_nr]) / 2 + ped_min[chan_nr]; // raw adc counts // these calculated global variables are used to load fed registers fibre_ped_calc[chan_nr] = ped_min[chan_nr]; // assume minimum is baseline pedestal fibre_thresh_calc[chan_nr] = fibre_thresh[chan_nr]/32; // convert to register contents 0-15 (* 32 adc counts) // compute tick thresholds } printf("\n"); printf("Pedestals Mean (rms) : \n"); printf("FE nr / Fibre nr : \n"); printf(" \t12 \t\t11 \t\t10\t\t 9\t\t 8\t\t 7\t\t 6\t\t 5\t\t 4\t\t 3\t\t 2\t\t 1\n"); for (int fe_nr=0; fe_nr 900.0 || ped_rms[fe_nr*12 + fibre_nr] > 1.0) ? '*' : ' '); } } printf("\n"); printf("\n"); printf("Min->Max : \n"); printf("FE nr / Fibre nr : \n"); printf(" \t12 \t\t11 \t\t10\t\t 9\t\t 8\t\t 7\t\t 6\t\t 5\t\t 4\t\t 3\t\t 2\t\t 1\n"); for (int fe_nr=0; fe_nr%4d(%3d)%c;", ped_min[fe_nr*12 + fibre_nr], ped_max[fe_nr*12 + fibre_nr], ped_max[fe_nr*12 + fibre_nr] - ped_min[fe_nr*12 + fibre_nr], (ped_max[fe_nr*12 + fibre_nr] - ped_min[fe_nr*12 + fibre_nr] < 400) ? '*' : ' '); } } printf("\n"); printf("\n"); printf("Fibre Thresholds Calculated : \n"); printf("FE nr / Fibre nr : \n"); printf(" 12 11 10 9 8 7 6 5 4 3 2 1\n"); for (int fe_nr=0; fe_nr> 4; for (int j=2; j>=0; j--) { daq_len |= *evtP++ << j*8; // length in 64 bit words } for (int j=1; j>=0; j--) { daq_crc |= *evtP++ << j*8; } daq_evt_stat = *evtP++ & 0xf; daq_tts_stat = *evtP++ >> 4; if (trig_nr == 1) { printf("\n\nDAQ Trailer : Evt Length = $%04x (%8d x 64 bit words) ; CRC = $ %04x \n", daq_len, daq_len, daq_crc ); printf("DAQ Trailer : Evt Status = $ %01x ; TTS Status = $ %01x \n", daq_evt_stat, daq_tts_stat ); printf("\nRe-computed CRC = $ %04x \n", crc_check); } if (daq_crc != (unsigned int) crc_check) { printf("*** ERROR => CRC in event trailer = $%04x but re-computed CRC = $%04x \n", daq_crc, crc_check ); *error_crc = 1; // *error = 1; } unsigned int tot_bytes = evtP - event_data.begin(); if (daq_len*8 != tot_bytes) { printf("*** ERROR => DAQ Event Length in Trailer = $%04x bytes ; but processsed = $%04x bytes in event\n", daq_len*8, tot_bytes ); *error = 1; } if (*error == 0) { if (trig_nr == 1) printf("\nThe format of this event was OK. \n"); } return 0; } int FFv1Object::DisplayVMEStatus(int verbosity) { unsigned long firmware_id; unsigned long clock_select; unsigned long vme_status; unsigned long serial_status; unsigned long fed_id; unsigned long ttc_clk_ctr[2]; unsigned long bp_clk_ctr[2]; unsigned long readout_status; unsigned long buffer_length; unsigned long event_length; unsigned long event_number; unsigned long data1, data2; if (verbosity > 1) cout << '\n' << "VME Registers: " << '\n'; ffv1SingleRead(&firmware_id, FED_Firmware_ID/4); ffv1SingleRead(&clock_select, FED_Clock_Select/4); ffv1SingleRead(&vme_status, FED_VME_Status/4); ffv1SingleRead(&serial_status, FED_Serial_Status/4); ffv1SingleRead(&fed_id, FED_Board_ID/4); printf("FED Board ID Reg (should be $00000fed) = $%08x \n", (unsigned int) fed_id); if (verbosity > 1) cout << "Firmware ID = $ " << hex << firmware_id << '\n'; if (verbosity > 1) cout << "VME Status Reg = $ " << hex << vme_status << '\n'; if (verbosity > 1) cout << "Serial Status Reg = $ " << hex << serial_status << '\n'; if (verbosity > 1) cout << "Clock Select = " << dec << clock_select << '\n'; ffv1SingleRead(&ttc_clk_ctr[0], FED_TTC_Clk_Ctr/4); usleep(100); ffv1SingleRead(&ttc_clk_ctr[1], FED_TTC_Clk_Ctr/4); ffv1SingleRead(&bp_clk_ctr[0], FED_BP_Clk_Ctr/4); usleep(100); ffv1SingleRead(&bp_clk_ctr[1], FED_BP_Clk_Ctr/4); if (verbosity > 1) cout << "TTC Clock Ctr = " << ttc_clk_ctr[0] << '\n'; if (verbosity > 1) cout << "BP Clock Ctr = " << bp_clk_ctr[0] << '\n'; if (verbosity > 1) cout << "TTC Clock Ctr (after 100 microsec) = " << ttc_clk_ctr[1] << '\n'; if (verbosity > 1) cout << "BP Clock Ctr (after 100 microsec) = " << bp_clk_ctr[1] << '\n'; if (verbosity > 1) cout << "TTC Clock Ctr change = " << ttc_clk_ctr[1] - ttc_clk_ctr[0] << '\n'; if (verbosity > 1) cout << "BP Clock Ctr change = " << bp_clk_ctr[1]- bp_clk_ctr[0] << '\n'; ffv1SingleRead(&readout_status, FED_Readout_CSR/4); ffv1SingleRead(&buffer_length, FED_Readout_Buffer_Length/4); ffv1SingleRead(&event_length, FED_Readout_Event_Length/4); ffv1SingleRead(&event_number, FED_Readout_Event_Ctr/4); if (verbosity > 1) cout << '\n' << "Readout Status: " << '\n'; if (verbosity > 1) cout << "Event Pending: Status = " << readout_status << '\n'; if (verbosity > 1) cout << "Event Number = " << event_number << '\n'; if (verbosity > 1) cout << "Buffer Length (32) = " << dec << buffer_length << " $ " << hex << buffer_length << '\n'; if (verbosity > 1) cout << "Event Length (32) = " << dec << event_length << " $ " << hex << event_length << '\n'; // readout event // cout << "Sample\t\t | Data " << '\n'; // for (int i=0; i<16; i++) { // ffv1SingleRead(&data, FED_Readout_BRAM/4 + i); // // cout << showbase; // // cout << hex << setw(8) << setfill(0) << i << "\t 0x" << data << '\n'; // cout.width(8); // cout << hex << i << "\t 0x" << data << '\n'; // } printf("Event Data => \n "); printf("(64 bit) word nr | data (hex) \n"); for (int i=0; i<1600; i+=2) { ffv1SingleRead(&data1, FED_Readout_BRAM/4 + i); ffv1SingleRead(&data2, FED_Readout_BRAM/4 + i+1); printf(" %03d | %08x%08x \n", i/2, (unsigned int) data1, (unsigned int) data2); } return 0; } int FFv1Object::DisplayClockCounters(int verbosity) { unsigned long ttc_clk_ctr[2]; unsigned long bp_clk_ctr[2]; unsigned int ttc_ready; // BECommand(20, 1, &ttc_ready, verbosity); // cout << "20) TTC Ready = $ " << hex << ttc_ready << '\n'; ffv1SingleRead(&ttc_clk_ctr[0], FED_TTC_Clk_Ctr/4); usleep(100); ffv1SingleRead(&ttc_clk_ctr[1], FED_TTC_Clk_Ctr/4); ffv1SingleRead(&bp_clk_ctr[0], FED_BP_Clk_Ctr/4); usleep(100); ffv1SingleRead(&bp_clk_ctr[1], FED_BP_Clk_Ctr/4); if (verbosity > 1) cout << "TTC Clock Ctr = " << dec << ttc_clk_ctr[0] << '\n'; if (verbosity > 1) cout << "TTC Clock Ctr (after 100 microsec) = " << dec << ttc_clk_ctr[1] << '\n'; if (verbosity > 1) cout << "TTC Clock Ctr change = " << dec << ttc_clk_ctr[1] - ttc_clk_ctr[0] << '\n'; if (verbosity > 1) cout << "BP Clock Ctr = " << dec << bp_clk_ctr[0] << '\n'; if (verbosity > 1) cout << "BP Clock Ctr (after 100 microsec) = " << dec << bp_clk_ctr[1] << '\n'; if (verbosity > 1) cout << "BP Clock Ctr change = " << dec << bp_clk_ctr[1]- bp_clk_ctr[0] << '\n'; int error = 0; int max = 100; for (int i=0; i 1) cout << "Testing Clock Selection: " << '\n'; ffv1SingleRead(&clock_select, FED_Clock_Select/4); // ffv1SingleRead(&vme_status, FED_VME_Status/4); if (verbosity > 1) cout << "Clock Select before change = " << dec << clock_select << '\n'; // if (verbosity > 1) cout << "VME Status Reg = $ " << hex << vme_status << '\n'; // ffv1SingleRead(&ttc_clk_ctr, FED_TTC_Clk_Ctr/4); // ffv1SingleRead(&bp_clk_ctr, FED_BP_Clk_Ctr/4); // if (verbosity > 1) cout << "TTC Clock Ctr = " << ttc_clk_ctr << '\n'; // if (verbosity > 1) cout << "BP Clock Ctr = " << bp_clk_ctr << '\n'; // usleep(100); // ffv1SingleRead(&ttc_clk_ctr, FED_TTC_Clk_Ctr/4); // ffv1SingleRead(&bp_clk_ctr, FED_BP_Clk_Ctr/4); // if (verbosity > 1) cout << "TTC Clock Ctr = " << ttc_clk_ctr << '\n'; // if (verbosity > 1) cout << "BP Clock Ctr = " << bp_clk_ctr << '\n'; if (verbosity > 1) cout << "Trying to change clock setting to : " << clock << '\n'; ffv1SingleWrite(clock, FED_Clock_Select/4); // after changing clock do a vme reset // ResetFED(2); // usleep(5000000); // safe wait for DCMs to lock usleep(1000000); // safe wait for DCMs to lock // ResetFED(2); // usleep(5000000); // safe wait for DCMs to lock // ffv1SingleRead(&test, FED_Firmware_ID/4); ffv1SingleRead(&clock_select, FED_Clock_Select/4); ffv1SingleRead(&vme_status, FED_VME_Status/4); if (verbosity > 1) cout << "Clock Selected = " << dec << clock_select << '\n'; if (verbosity > 1) cout << "VME Status Reg = $ " << hex << vme_status << '\n'; return 0; } int FFv1Object::SetTTCrx(int data) { unsigned int fed_cmd = fedCmd(10, 0x3, 2, 0); unsigned int fed_data = data<<(32-2); /// cout << "fed_cmd = $ " << hex << fed_cmd << " ; fed_data = $ " << fed_data << '\n'; // return 0; // usleep(10); CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer ffv1SingleWrite(fed_data, FED_Serial_BRAM/4 + 1); ffv1SingleWrite(2, FED_Serial_Write/4); // send cmd string return 0; } int FFv1Object::ReadTTCrx(unsigned int* data) { /// cout << "Readback Chip # " << chip << " LM82" << '\n'; unsigned int fed_cmd = fedCmd(10, 0xb, 1, 1); /// cout << "fed_cmd = $ " << hex << fed_cmd << '\n'; // return 0; // usleep(100); CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_Read/4); // sends read cmd // usleep(100); unsigned long fed_data = *data; CheckSerialStatus(fed_cmd, 0); ffv1SingleRead(&fed_data, FED_Serial_BRAM/4); // readback memory //cout << "fed_data = $ " << hex << fed_data << '\n'; *data = fed_data >> (32-1); return 0; } int FFv1Object::DisplayFirmwareVersions(FILE* file, int verbosity) { // no longer used by System ACE CFlash code unsigned int fpga_code_fe[fe_max], fpga_code_be; unsigned long fpga_code_vme; unsigned long fpga_code_delay; for (int fe_nr = 0; fe_nr < fe_max; fe_nr++) { FECommand(fe_nr, 3, 1, &fpga_code_fe[fe_nr], verbosity); } BECommand(21, 1, &fpga_code_be, verbosity); ffv1SingleRead(&fpga_code_vme, FED_Firmware_ID/4); unsigned int sernr, fedid; ReadSerNrEPROM(&sernr, &fedid, 1); fprintf(file, " Firmware Versions ; FED Ser Nr = %03d \n", sernr); for (int fe_nr = 0; fe_nr < fe_max; fe_nr++) { fprintf(file, " FE FPGA nr = %d : vers = $ %08x \n", 8-fe_nr, fpga_code_fe[fe_nr]); } fprintf(file, " BE FPGA : vers = $ %08x \n", fpga_code_be); fprintf(file, " VME FPGA : vers = $ %08x \n", (unsigned int) fpga_code_vme); unsigned long ref = 0; unsigned long error = 0; for (int fe_nr = 0; fe_nr < fe_max; fe_nr++) { for (int i=0; i<3; i++) { ReadDelayFPGAID(fe_nr, i, &fpga_code_delay); printf("fe = %d ; chip = %d ; DELAY FPGA ID = $ %08x \n", 8-fe_nr, i, (unsigned int) fpga_code_delay); if (fe_nr == 0 && i == 0) { ref = fpga_code_delay; fprintf(file, " DELAY FPGA : vers = $ %08x \n", (unsigned int) ref); } else { if (fpga_code_delay != ref) { fprintf(file, "ERROR *** DELAY FPGA fe_nr = %d ; delay chip = %d : vers = $%08x is NOT same as ref (fe_nr = 0 chip = 0) = $%08x \n", 8-fe_nr, i, (unsigned int) fpga_code_delay, (unsigned int) ref); error = 1; } } } } if (error == 0) fprintf(file, "All 24 DELAY FPGA have same vers ID \n"); return 0; } int FFv1Object::DisplayFEStatus(int verbosity) { unsigned int fpga_code[fe_max], mode[fe_max], scope_len[fe_max], optorx_ctrl[fe_max], adc_ctrl[fe_max], fibre_enable[fe_max], super_mode[fe_max], trigger_counter[fe_max]; for (int fe_nr = 0; fe_nr < fe_max; fe_nr++) { FECommand(fe_nr, 3, 1, &fpga_code[fe_nr], verbosity); FECommand(fe_nr, 16, 1, &mode[fe_nr], verbosity); FECommand(fe_nr, 17, 1, &scope_len[fe_nr], verbosity); FECommand(fe_nr, 22, 1, &optorx_ctrl[fe_nr], verbosity); FECommand(fe_nr, 23, 1, &adc_ctrl[fe_nr], verbosity); FECommand(fe_nr, 2, 1, &fibre_enable[fe_nr], verbosity); // called tick command in manual FECommand(fe_nr, 30, 1, &super_mode[fe_nr], verbosity); FECommand(fe_nr, 18, 1, &trigger_counter[fe_nr], verbosity); } printf("FE Status \n"); printf("FE nr \tFPGA \t\tMode $ \tSuper $ Scope \tOptoRx \tADC \tFibre \t\tTrigger\n"); printf("\tCode $ \t\t\tMode \tLen \tCtrl $ \tCtrl $ \tEnables $ \tCounter\n"); for (int fe_nr = 0; fe_nr < fe_max; fe_nr++) { printf("%d \t%08x \t%02x \t%02x \t%d \t%02x \t%06x \t%06x \t\t%d \n", 8-fe_nr, fpga_code[fe_nr], mode[fe_nr], super_mode[fe_nr], scope_len[fe_nr], optorx_ctrl[fe_nr],adc_ctrl[fe_nr], fibre_enable[fe_nr], trigger_counter[fe_nr]); } return 0; } int FFv1Object::DisplayClockStatus(int verbosity) { unsigned long firmware_id; unsigned long clock_select; unsigned long vme_status; if (verbosity > 2) printf("DisplayClockStatus \n"); cout << '\n' << "VME Registers: " << '\n'; ffv1SingleRead(&firmware_id, FED_Firmware_ID/4); ffv1SingleRead(&clock_select, FED_Clock_Select/4); ffv1SingleRead(&vme_status, FED_VME_Status/4); cout << "Firmware ID = $ " << hex << firmware_id << '\n'; cout << "VME Status Reg = $ " << hex << vme_status << '\n'; cout << "Clock Select = " << dec << clock_select << '\n'; return 0; } int FFv1Object::DisplaySystemACE(int verbosity) { unsigned long reg[0x40]; if (verbosity > 2) printf("DisplaySystemACE \n"); printf("System ACE Registers \n"); // // put access into WORD mode if not already // ffv1SingleRead(®[0], FED_SystemACEBase/4 + 0); // // printf("Checking mode = $%04x\n", reg[0]); // if ((reg[0] & 0x1) == 0) { // unsigned long value = reg[0] | 0x1; // ffv1SingleWrite(value, FED_SystemACEBase/4 + 0); // printf("Setting SystemACE into WORD mode\n"); // } for (int i=0; i<0x10; i++) { // just read registers, not data buffer area ffv1SingleRead(®[i], FED_SystemACEBase/4 + i); // ffv1SingleRead(®[i], FED_SystemACEBase/4 + i); // test repeat read // usleep(50000); // was 10000 } /* printf("Dump...\n"); printf("Reg Nr $ : Value $\n"); for (int i=0; i<0x10; i++) { printf("%02x : %08x \n", i, (unsigned int) reg[i]); } */ // printf("...\n"); // for (int i=0x20; i<0x40; i++) { // printf("%02x : %08x \n", i, reg[i]); // } printf("Formatted $...\n"); printf(" BUSMODE : ----%04x \n", (unsigned int) reg[0]&0xffff); printf(" STATUS : %08x \n", (unsigned int) ((reg[3]&0xffff)<<16 | reg[2]&0xffff)); printf(" ERROR : %08x \n", (unsigned int) ((reg[5]&0xffff)<<16 | reg[4]&0xffff)); printf(" CFGLBA : %08x \n", (unsigned int) ((reg[7]&0xfff)<<16 | reg[6]&0xffff)); printf(" MPULBA : %08x \n", (unsigned int) ((reg[9]&0xfff)<<16 | reg[8]&0xffff)); printf("SECCNTCMD : ----%04x \n", (unsigned int) reg[0xa]&0xffff); printf(" VERSION : ----%04x \n", (unsigned int) reg[0xb]&0xffff); printf(" CONTROL : %08x \n", (unsigned int) ((reg[0xd]&0xffff)<<16 | reg[0xc]&0xffff)); printf(" FATSTAT : ----%04x \n", (unsigned int) reg[0xe]&0xffff); printf("------------------------------\n"); printf("\nSTATUSREG:\n"); printf(" CFGLOCK : %1x \n", (unsigned int) reg[2]&0x1); printf(" MPULOCK : %1x \n", (unsigned int) (reg[2]&0x2)>>1); printf(" CFGERROR : %1x \n", (unsigned int) (reg[2]&0x4)>>2); printf(" CFCERROR : %1x \n", (unsigned int) (reg[2]&0x8)>>3); printf(" CFDETECT : %1x \n", (unsigned int) (reg[2]&0x10)>>4); printf(" DATABUFRDY : %1x \n", (unsigned int) (reg[2]&0x20)>>5); printf("DATABUFMODE : %1x \n", (unsigned int) (reg[2]&0x40)>>6); printf(" CFGDONE : %1x \n", (unsigned int) (reg[2]&0x80)>>7); printf("RDYFORCFCMD : %1x \n", (unsigned int) (reg[2]&0x100)>>8); printf(" CFGMODEPIN : %1x \n", (unsigned int) (reg[2]&0x200)>>9); printf(" CDFADDRPIN : %1x \n", (unsigned int) (reg[2]&0xe00)>>13); printf(" CFBSY : %1x \n", (unsigned int) (reg[3]&0x2)>>1); printf(" CFRDY : %1x \n", (unsigned int) (reg[3]&0x4)>>2); printf(" CFDWF : %1x \n", (unsigned int) (reg[3]&0x8)>>3); printf(" CFDSC : %1x \n", (unsigned int) (reg[3]&0x10)>>4); printf(" CFDRQ : %1x \n", (unsigned int) (reg[3]&0x20)>>5); printf(" CFCORR : %1x \n", (unsigned int) (reg[3]&0x40)>>6); printf(" CFERR : %1x \n", (unsigned int) (reg[3]&0x80)>>7); printf("------------------------------\n"); printf("\nERRORREG:\n"); printf("CARDRESETERR : %1x \n", (unsigned int) reg[4]&0x1); printf(" CARDRDYERR : %1x \n", (unsigned int) (reg[4]&0x2)>>1); printf(" CARDREADERR : %1x \n", (unsigned int) (reg[4]&0x4)>>2); printf("CARDWRITEERR : %1x \n", (unsigned int) (reg[4]&0x8)>>3); printf("SECTORRDYERR : %1x \n", (unsigned int) (reg[4]&0x10)>>4); printf(" CFGADDRERR : %1x \n", (unsigned int) (reg[4]&0x20)>>5); printf(" CFGFAILED : %1x \n", (unsigned int) (reg[4]&0x40)>>6); printf(" CFGREADERR : %1x \n", (unsigned int) (reg[4]&0x80)>>7); printf(" CFGINSTRERR : %1x \n", (unsigned int) (reg[4]&0x100)>>8); printf(" CFGINITERR : %1x \n", (unsigned int) (reg[4]&0x200)>>9); printf(" CFBBK : %1x \n", (unsigned int) (reg[4]&0x800)>>11); printf(" CFUNC : %1x \n", (unsigned int) (reg[4]&0x1000)>>12); printf(" CFIDNF : %1x \n", (unsigned int) (reg[4]&0x2000)>>13); printf(" CFABORT : %1x \n", (unsigned int) (reg[4]&0x4000)>>14); printf(" CFAMNF : %1x \n", (unsigned int) (reg[4]&0x8000)>>15); printf("------------------------------\n"); printf("\nCONTROLREG:\n"); printf(" FORCELOCKREQ : %1x \n", (unsigned int) reg[0xc]&0x1); printf(" LOCKREQ : %1x \n", (unsigned int) (reg[0xc]&0x2)>>1); printf(" FORCECFGADDR : %1x \n", (unsigned int) (reg[0xc]&0x4)>>2); printf(" FORCECFGMODE : %1x \n", (unsigned int) (reg[0xc]&0x8)>>3); printf(" CFGMODE : %1x \n", (unsigned int) (reg[0xc]&0x10)>>4); printf(" CFGSTART : %1x \n", (unsigned int) (reg[0xc]&0x20)>>5); printf(" CFGSEL : %1x \n", (unsigned int) (reg[0xc]&0x40)>>6); printf(" CFGRESET : %1x \n", (unsigned int) (reg[0xc]&0x80)>>7); printf("DATABUFRDYIRQ : %1x \n", (unsigned int) (reg[0xc]&0x100)>>8); printf(" ERRORIRQ : %1x \n", (unsigned int) (reg[0xc]&0x200)>>9); printf(" CFGDONEIRQ : %1x \n", (unsigned int) (reg[0xc]&0x400)>>10); printf(" RESETIRQ : %1x \n", (unsigned int) (reg[0xc]&0x800)>>11); printf(" CFGPROG : %1x \n", (unsigned int) (reg[0xc]&0x1000)>>12); printf(" CFGADDR : %1x \n", (unsigned int) (reg[0xc]&0xe000)>>13); printf(" CFGRSVD : %1x \n", (unsigned int) reg[0xd]&0x7); printf("------------------------------\n"); printf("\nFATSTATREG:\n"); printf("MBRVALID : %1x \n", (unsigned int) reg[0xe]&0x1); printf("PBRVALID : %1x \n", (unsigned int) (reg[0xe]&0x2)>>1); printf("MBRFAT12 : %1x \n", (unsigned int) (reg[0xe]&0x4)>>2); printf("PBRFAT12 : %1x \n", (unsigned int) (reg[0xe]&0x8)>>3); printf("MBRFAT16 : %1x \n", (unsigned int) (reg[0xe]&0x10)>>4); printf("PBRFAT16 : %1x \n", (unsigned int) (reg[0xe]&0x20)>>5); printf("CALCFAT12 : %1x \n", (unsigned int) (reg[0xe]&0x40)>>6); printf("CALCFAT16 : %1x \n", (unsigned int) (reg[0xe]&0x80)>>7); printf("------------------------------\n"); // for (int i=0x20; i<0x40; i++) { // printf(" DATABUF %02x : ----%04x \n", i, reg[i]&0xffff); // } return 0; } int FFv1Object::ReadSystemACE(unsigned int reg_offset, unsigned int* ace_data, int verbosity) { unsigned long value; if (verbosity > 2) printf("ReadSystemACE \n"); ffv1SingleRead(&value, FED_SystemACEBase/4 + reg_offset); *ace_data = value; return 0; } int FFv1Object::WriteSystemACE(unsigned int reg_offset, unsigned int ace_data, int verbosity) { if (verbosity > 2) printf("WriteSystemACE \n"); ffv1SingleWrite(ace_data, FED_SystemACEBase/4 + reg_offset); return 0; } int FFv1Object::WordModeSystemACE(int verbosity) { // must be done before anything else to get 16 bit word access unsigned long saved, value; // put access into WORD mode if not already ffv1SingleRead(&saved, FED_SystemACEBase/4 + 0); if ((saved & 0x1) == 0) { value = saved | 0x1; ffv1SingleWrite(value, FED_SystemACEBase/4 + 0); if (verbosity > 1) printf("Setting SystemACE into WORD mode\n"); } return 0; } int FFv1Object::ResetSystemACE(int verbosity) { unsigned long value; if (verbosity > 1) printf("Resetting SystemACE controller... \n"); value = 0x0080; // CFGRESET ffv1SingleWrite(value, FED_SystemACEBase/4 + 0x0c ); return 0; } int FFv1Object::ReloadFPGASystemACE(unsigned long cfg_addr, int verbosity) { // this causes the controller to reload the fpga chain unsigned long saved, value; if (cfg_addr > 7) cfg_addr = 0; if (verbosity > 1) printf("Reloading FPGA chain from Compact Flash... \n"); value = 0x0; ffv1SingleWrite(value, FED_SystemACEBase/4 + 0x0c ); // ffv1SingleRead(&saved, FED_SystemACEBase/4 + 0x0c); value = 0x0080; // CFGRESET ffv1SingleWrite(value, FED_SystemACEBase/4 + 0x0c ); usleep(100000); // CFGSTART | FORCECFGMODE ; overrides CFGMODE pin // value = 0x0028; // CFGADDR | FORCECFGMODE | FORCECFGADDR ; overrides CFGMODE and CFGADDR pins value = 0x002c | ((cfg_addr & 0x7) << 13); if (verbosity > 1) printf("value = $%04x \n", (unsigned int) value); ffv1SingleWrite(value, FED_SystemACEBase/4 + 0x0c ); usleep(10000000); // read status ffv1SingleRead(&saved, FED_SystemACEBase/4 + 0x02); if (verbosity > 1) printf("status = $%04x \n", (unsigned int) saved); if (verbosity > 1) printf("Clearing CFG register. \n"); value = 0x0; ffv1SingleWrite(value, FED_SystemACEBase/4 + 0x0c ); return 0; } int FFv1Object::AccessCFSectorSystemACE(unsigned int lba, unsigned int nr_sectors, int verbosity, int file_flag, int ace_write, int ace_test, int ace_loop) { unsigned long saved, value, status; unsigned int fpga_code_fe, fpga_code_be; unsigned long fpga_code_vme, fpga_code_delay; // // put access into WORD mode if not already // ffv1SingleRead(&saved, FED_SystemACEBase/4 + 0); // if ((saved & 0x1) == 0) { // value = saved | 0x1; // ffv1SingleWrite(value, FED_SystemACEBase/4 + 0); // printf("Setting SystemACE into WORD mode\n"); // } if (ace_write == 1 && ace_loop == 0) { cf_image_file_input = fopen( "cf_image_input.txt", "r" ); if ( cf_image_file_input == NULL ) { printf( "*** ERROR => Couldn't open Compact Image INPUT File = 'cf_image_input.txt'\n"); return 1; } if (verbosity > 1) printf("Opened CF Image INPUT File... \n"); } if (ace_write == 0 && ace_loop == 0) { cf_image_file_output = fopen( "cf_image_output.txt", "w" ); if ( cf_image_file_output == NULL ) { printf( "*** ERROR => Couldn't open Compact Image OUTPUT File = 'cf_image_output.txt'\n"); return 1; } if (verbosity > 1) printf("Opened CF Image OUTPUT File... \n"); } // see system ace spec p39 if (verbosity > 1) printf("Accessing data on Compact Flash... \n"); if (ace_write != 1) { if (ace_loop == 0) { // hardware access needed FECommand(1, 3, 1, &fpga_code_fe, verbosity); BECommand(21, 1, &fpga_code_be, verbosity); ReadDelayFPGAID(0, 0, &fpga_code_delay); ffv1SingleRead(&fpga_code_vme, FED_Firmware_ID/4); fprintf(cf_image_file_output, " FE FPGA : vers = $ %08x \n", (unsigned int) fpga_code_fe); // assumes all FEs are the same fprintf(cf_image_file_output, " BE FPGA : vers = $ %08x \n", (unsigned int) fpga_code_be); fprintf(cf_image_file_output, "DELAY FPGA : vers = $ %08x \n", (unsigned int) fpga_code_delay); // assumes all Delays are the same fprintf(cf_image_file_output, " VME FPGA : vers = $ %08x \n", (unsigned int) fpga_code_vme); // DisplayFirmwareVersions(cf_image_file_output, 1); } } if (nr_sectors > 256) nr_sectors = 256; // h/w limit // if (file_flag) fprintf(cf_image_file_output, "Compact Flash Dump \n"); // if (file_flag) fprintf(cf_image_file_output, "Logical Block Address = $%04x ; Nr Sectors = %03d \n", lba, nr_sectors); if (verbosity > 1) printf("status = $ %08x\n", (unsigned int) status); // Get CF Lock if (ace_test == 0) { unsigned long mpu_lock = 0; ffv1SingleRead(&saved, FED_SystemACEBase/4 + 0x0c); //usleep(50000); // added value = saved | 0x0002; // LOCKREQ ffv1SingleWrite(value, FED_SystemACEBase/4 + 0x0c ); //usleep(50000); // added for (int i=0; i<20; i++) { // was 10 ffv1SingleRead(&status, FED_SystemACEBase/4 + 0x02); ffv1SingleRead(&status, FED_SystemACEBase/4 + 0x02); // test repeat if (status & 0x0002) { mpu_lock = 1; if (verbosity > 1) printf("CF locked successfully by MPU \n"); if (verbosity > 1) printf("status = $ %08x\n", (unsigned int) status); break; } usleep(10000); // was 10000 } if (mpu_lock == 0) { printf("WARNING: Timeout locking CF \n"); return 1; } // Check if Ready for command unsigned int cmd_rdy = 0; for (int i=0; i<20; i++) { // was 10 ffv1SingleRead(&status, FED_SystemACEBase/4 + 0x02); ffv1SingleRead(&status, FED_SystemACEBase/4 + 0x02); // test repeat if (status & 0x0100) { cmd_rdy = 1; if (verbosity > 1) printf("CF ready for command \n"); if (verbosity > 1) printf("status = $ %08x\n", (unsigned int) status); break; } usleep(10000); // was 10000 } if (cmd_rdy == 0) { printf("WARNING: Timeout waiting for ready for command CF \n"); return 1; } } // write sector logical block address unsigned long lba_low, lba_high; lba_low = lba & 0xffff; lba_high = lba >> 16 & 0xfff; if (ace_test == 0) { ffv1SingleWrite(lba_low, FED_SystemACEBase/4 + 0x08 ); //usleep(50000); // added ffv1SingleWrite(lba_high, FED_SystemACEBase/4 + 0x09 ); //usleep(50000); // added } // write sector count unsigned long sec_cnt, sec_cmd; if (ace_write == 1) { sec_cmd = 4; // write CF } else { sec_cmd = 3; // read CF } if (nr_sectors == 256) { sec_cnt = 0; // set to 0 to read entire sector } else { sec_cnt = nr_sectors; } value = ((sec_cmd & 0x7) << 8) | (sec_cnt & 0xff); if (ace_test == 0) { ffv1SingleWrite(value, FED_SystemACEBase/4 + 0x0a ); //usleep(50000); // added } // Reset CFGJTAG // this causes the controller to reload the fpga chain // skip this step, doesn't seem to be needed. // ffv1SingleRead(&saved, FED_SystemACEBase/4 + 0x0c); // value = saved | 0x0080; // CFGRESET // ffv1SingleWrite(value, FED_SystemACEBase/4 + 0x0c ); // Read Data Buffer repeatedly to get all sector data int nr_bufs; nr_bufs = nr_sectors * 512/32; if (ace_write == 1) { // fscanf(cf_image_file_input, "Compact Flash Dump \n"); // fscanf(cf_image_file_input, "Logical Block Address = $%*04x ; Nr Sectors = %*03d \n"); if (ace_loop == 0) { fscanf(cf_image_file_input, " FE FPGA : vers = $ %08x \n", &fpga_code_fe); // assumes all FEs are the same fscanf(cf_image_file_input, " BE FPGA : vers = $ %08x \n", &fpga_code_be); fscanf(cf_image_file_input, "DELAY FPGA : vers = $ %08x \n", (unsigned int *) &fpga_code_delay); // assumes all Delays are the same fscanf(cf_image_file_input, " VME FPGA : vers = $ %08x \n", (unsigned int *) &fpga_code_vme); /* fscanf(cf_image_file_input, " Firmware Versions \n"); for (int fe_nr = 0; fe_nr < fe_max; fe_nr++) { fscanf(cf_image_file_input, " FE FPGA nr = %d : vers = $ %08x \n", &fe_nr, &fpga_code_fe[fe_nr]); } fscanf(cf_image_file_input, " BE FPGA : vers = $ %08x \n", &fpga_code_be); fscanf(cf_image_file_input, " VME FPGA : vers = $ %08x \n", (unsigned int *) &fpga_code_vme); */ // fprintf(cf_image_file_output, " Firmware Versions in Image\n"); // for (unsigned int fe_nr = 0; fe_nr < fe_max; fe_nr++) { // fprintf(cf_image_file_output, " FE FPGA nr = %d : vers = $ %08x \n", 8-fe_nr, fpga_code_fe[fe_nr]); // } // fprintf(cf_image_file_output, " BE FPGA : vers = $ %08x \n", fpga_code_be); // fprintf(cf_image_file_output, " VME FPGA : vers = $ %08x \n", (unsigned int) fpga_code_vme); } } for (int buf=0; buf 1) printf("CF Data Buffer Ready \n"); if (verbosity > 1) printf("status = $ %08x\n", (unsigned int) status); break; } usleep(10000); // was 10000 } if (buf_rdy == 0) { printf("WARNING: Timeout waiting CF Data Buffer Ready: Buf nr = %d \n", buf); return 1; } } if (ace_write == 1) { unsigned long dummy = 1234; if ((buf % 16) == 0) { fscanf(cf_image_file_input, "LBA = $ %04x \n", (unsigned int *) &dummy); // if (verbosity > 1) fprintf(cf_image_file_output, "dummy lba = $ %03x\n", dummy); } unsigned long value; for (int word=0; word<16; word++) { // CF FIFO is 16 (16 bit) words deep fscanf(cf_image_file_input, "%04x ", (unsigned int *) &value); // value = buf*16 + word; // if (verbosity > 1) printf("WRITE: Buf nr = %d : Word nr = %d : Data = $%04x \n", buf, word, value); if (verbosity > 1) fprintf(cf_image_file_output, "WRITE: Buf nr = %d : Word nr = %d : Data = $%04x \n", buf, word, (unsigned int) value); if (ace_test == 0) ffv1SingleWrite(value, FED_SystemACEBase/4 + 0x20 ); } fscanf(cf_image_file_input, "\n"); } else { // Hopefully can read some data from the CFlash card! if (file_flag) { // if ((buf > 0) && (buf % 16) == 0) fprintf(cf_image_file_output, "%03d \n", buf/16); if ((buf % 16) == 0) fprintf(cf_image_file_output, "LBA = $ %04x \n", ace_loop * 256 + buf/16); } if (verbosity > 1) printf("LBA = $ %04x \n", ace_loop * 256 + buf/16); // added for (int word=0; word<16; word++) { // CF FIFO is 16 (16 bit) words deep unsigned long data = 0; if (ace_test == 0) { ffv1SingleRead(&data, FED_SystemACEBase/4 + 0x20); // NB can read from same address to empty fifo // usleep(50000); // added } if (buf < 32) { if (verbosity > 1) printf("READ: Buf nr = %d : Word nr = %d : Data = $%04x \n", buf, word, (unsigned int) data); } if (file_flag) fprintf(cf_image_file_output, "%04x ", (unsigned int) data); // save to file } if (file_flag) fprintf(cf_image_file_output, "\n"); } } // clean up // Reset CFGJTAG and LOCKREQ if (ace_test == 0) { ffv1SingleRead(&saved, FED_SystemACEBase/4 + 0x0c); value = saved & ~0x0080; // CFGRESET ffv1SingleWrite(value, FED_SystemACEBase/4 + 0x0c ); ffv1SingleRead(&saved, FED_SystemACEBase/4 + 0x0c); value = saved & ~0x0002; // LOCKREQ ffv1SingleWrite(value, FED_SystemACEBase/4 + 0x0c ); } // if (ace_write == 1) { // fclose(cf_image_file_input ); // if ( fclose(cf_image_file_input) != 0 ) // { // printf( "*** ERROR => Couldn't close Compact Image File = 'cf_image.txt'\n"); // return 1; // } // } // printf("Finished Accessing Compact Flash Card contents\n"); return 0; } int FFv1Object::DisplayTemperatures(int verbosity) { unsigned int local_temp[fe_max+2], remote_temp[fe_max+2], status[fe_max+2], man_id[fe_max+2], rd_cfg[fe_max+2], rd_loc_high[fe_max+2], rd_rem_high[fe_max+2], rd_tcrit[fe_max+2]; // +2 for BE & VME FPGAs for (int fe_nr = 0; fe_nr < fe_max+2; fe_nr++) { // printf("fe_nr = %d\n", fe_nr); ReadLM82(fe_nr, 0, &local_temp[fe_nr], verbosity); // local temp ReadLM82(fe_nr, 1, &remote_temp[fe_nr], verbosity); // remote fpga temp ReadLM82(fe_nr, 2, &status[fe_nr], verbosity); // status ReadLM82(fe_nr, 3, &rd_cfg[fe_nr], verbosity); // configuration read ReadLM82(fe_nr, 5, &rd_loc_high[fe_nr], verbosity); // read local high temp setpoint ReadLM82(fe_nr, 7, &rd_rem_high[fe_nr], verbosity); // read remote high temp setpoint ReadLM82(fe_nr, 0x42, &rd_tcrit[fe_nr], verbosity); // read critical temp ReadLM82(fe_nr, 0xfe, &man_id[fe_nr], verbosity); // manufacturer's id } printf("Temperature Status Chip \n"); printf("Chip \tLocal \tRemote \tStatus \tConfig \tID \tLoc \tRem \tTCrit \n"); printf("FE Nr \tTemp C \tTemp C \t$ \t$ \t$ \tHigh C \tHigh C \tC \n"); for (int fe_nr = 0; fe_nr < fe_max; fe_nr++) { // temps are 2's complement printf("%d \t%03d \t%03d \t%02x \t%02x \t%02x \t%03d \t%03d \t%03d \n", 8-fe_nr, local_temp[fe_nr], remote_temp[fe_nr], status[fe_nr], rd_cfg[fe_nr], man_id[fe_nr], rd_loc_high[fe_nr], rd_rem_high[fe_nr], rd_tcrit[fe_nr]); } printf("---------------------------------------------------------------------\n"); printf(" BE \t%03d \t%03d \t%02x \t%02x \t%02x \t%03d \t%03d \t%03d \n", local_temp[8], remote_temp[8], status[8], rd_cfg[8], man_id[8], rd_loc_high[8], rd_rem_high[8], rd_tcrit[8]); printf("VME \t%03d \t%03d \t%02x \t%02x \t%02x \t%03d \t%03d \t%03d \n", local_temp[9], remote_temp[9], status[9], rd_cfg[9], man_id[9], rd_loc_high[9], rd_rem_high[9], rd_tcrit[9]); return 0; } int FFv1Object::SetLM82_TCrits(unsigned int tcrit, int verbosity) { // sets local and remote shutdown temperature if (tcrit > 127) tcrit = 70; unsigned int cfg_mask; for (int lm82_nr=8; lm82_nr>0; lm82_nr--) { cfg_mask = 0xff; // must set D3 and D5 to 1 before changing TCRIT limit WriteLM82(lm82_nr-1, 0x09, &cfg_mask, verbosity); // mask T_CRIT in config reg WriteLM82(lm82_nr-1, 0x5a, &tcrit, verbosity); // set T_CRIT value cfg_mask = 0x28; // setting D2 and D4 0 enables TCRIT signal on Local and Remote Temperatures WriteLM82(lm82_nr-1, 0x09, &cfg_mask, verbosity); // enable T_CRIT in config reg } /* cfg_mask = 0xff; // must set D3 and D5 to 1 before changing TCRIT limit // printf("mask T_CRIT in config reg..\n"); WriteLM82(0, 0x09, &cfg_mask, verbosity); // mask T_CRIT in config reg // printf("set T_CRIT value..\n"); WriteLM82(0, 0x5a, &tcrit, verbosity); // set T_CRIT value cfg_mask = 0x28; // setting D2 and D4 0 enables TCRIT signal on Local and Remote Temperatures // printf("enable T_CRIT in config reg..\n"); WriteLM82(0, 0x09, &cfg_mask, verbosity); // enable T_CRIT in config reg */ return 0; } int FFv1Object::ReadLM82(int chip_id, int reg_id, unsigned int *data, int verbosity) { // reads back data from LM82 internal reg_id unsigned int lm82_ctrl = 1 << 16 | reg_id << 8; unsigned int lm82_status; if (chip_id < fe_max ) { FECommand(chip_id, 5, 0, &lm82_ctrl, verbosity); // send read request usleep(1); FECommand(chip_id, 27, 1, &lm82_status, verbosity); // read back status to get data } else if (chip_id == 8) { BECommand(12, 0, &lm82_ctrl, verbosity); // send read request usleep(1); BECommand(25, 1, &lm82_status, verbosity); // read back status to get data } else if (chip_id == 9) { ReadVMELM82(reg_id, &lm82_status, verbosity); } else { printf("LM82Read: Illegal chip_id = %d \n", chip_id); return 1; } if (verbosity > 1) printf("ReadLM82: lm82_status = $%08x \n", (unsigned int) lm82_status); if (lm82_status & 0x100 || lm82_status & 0x200) { printf("LM82Read: ERROR in LM82 access : $ %08x \n", (unsigned int) lm82_status); } *data = lm82_status & 0xff; return 0; } int FFv1Object::WriteLM82(int chip_id, int reg_id, unsigned int *data, int verbosity) { // writes data to LM82 internal reg_id unsigned int lm82_ctrl = reg_id << 8 | (*data & 0xff); unsigned int lm82_status; if (verbosity > 1) printf("WriteLM82: lm82_ctrl = $%08x \n", (unsigned int) lm82_ctrl); if (chip_id < fe_max ) { FECommand(chip_id, 5, 0, &lm82_ctrl, verbosity); // send write request usleep(1); FECommand(chip_id, 27, 1, &lm82_status, verbosity); // read back status just for error bits } else if (chip_id == 8) { BECommand(12, 0, &lm82_ctrl, verbosity); // send write request usleep(1); BECommand(25, 1, &lm82_status, verbosity); // read back status just for error bits } else if (chip_id == 9) { WriteVMELM82(reg_id, data, verbosity); } else { printf("LM82Write: Illegal chip_id = %d \n", chip_id); return 1; } if (lm82_status & 0x100 || lm82_status & 0x200) { printf("LM82Write: ERROR in I2C access \n"); } return 0; } int FFv1Object::ReadVMELM82(unsigned int reg_id, unsigned int *data, int verbosity) { unsigned long write = 1 << 16 | reg_id << 8; unsigned long read = 0; if (verbosity > 1) printf("ReadVMELM82: write = $%08x \n", (unsigned int) write); ffv1SingleWrite(write, FED_LM82_Write/4); // send addr to read usleep(1); // was 5 ffv1SingleRead(&read, FED_LM82_Read/4); // read data if (verbosity > 1) printf("ReadVMELM82: read = $%08x \n", (unsigned int) read); *data = read & 0xff; if (read & 0x100 || read & 0x200) { printf("ReadVMELM82: ERROR in LM82 access : $ %08x \n", (unsigned int) read); return 1; } return 0; } int FFv1Object::WriteVMELM82(unsigned int reg_id, unsigned int *data, int verbosity) { unsigned long write = reg_id << 8 | (*data & 0xff); unsigned long read = 0; if (verbosity > 1) printf("WriteVMELM82: write = $%08x \n", (unsigned int) write); ffv1SingleWrite(write, FED_LM82_Write/4); // send addr and data usleep(1000); ffv1SingleRead(&read, FED_LM82_Read/4); // read just to check for errors if (read & 0x100 || read & 0x200) { printf("WriteVMELM82: ERROR in LM82 access : Read = $%08x \n", (unsigned int) read); return 1; } return 0; } int FFv1Object::DisplayADM1025(int flag, int verbosity) { int reg[0x50]; if (flag == 3) printf("ADM1025 Voltage Monitor Chip \n"); if (flag == 3) printf("Reg nr $ \t; Value $ \n"); for (int i=0x15; i<0x50; i++) { ReadADM1025(i, (unsigned int*) ®[i], verbosity); if (flag == 3) printf("%02x \t; %02x \n", i, reg[i]); } printf("\nADM1025 Voltage Readings \n"); printf(" Nominal | Measured | Error \n"); printf(" 2.50 V | %5.3f V | %d \n", 2.5 + (float)(reg[0x20] - 0xc0) * 0.013, reg[0x41]&0x01 ); printf(" 1.50 V | %5.3f V | %d \n", 1.5 + (float)(reg[0x21] - 0x80) * 0.012, (reg[0x41]&0x02)>>1 ); printf(" 3.30 V | %5.3f V | %d \n", 3.3 + (float)(reg[0x22] - 0xc0) * 0.017, (reg[0x41]&0x04)>>2 ); printf(" 5.00 V | %5.3f V | %d \n", 5.0 + (float)(reg[0x23] - 0xc0) * 0.026, (reg[0x41]&0x08)>>3 ); printf("12.00 V | %5.3f V | %d \n", 12.0 + (float)(reg[0x24] - 0xc0) * 0.062, reg[0x42]&0x01 ); printf("\nLocal Temp = %d C (error = %d) \n", reg[0x27], (reg[0x41]&0x10)>>4 ); printf("PGOOD = %d ; TSHUTDOWN# = %d \n", reg[0x47]&0x01, (reg[0x47]&0x02)>>1 ); return 0; } int FFv1Object::ReadADM1025(unsigned int reg_id, unsigned int *data, int verbosity) { unsigned long write = 1 << 16 | reg_id << 8; unsigned long read = 0; if (verbosity > 1) printf("ReadADM1025: write = $%08x \n", (unsigned int) write); ffv1SingleWrite(write, FED_ADM1025_Write/4); // send addr to read usleep(1); ffv1SingleRead(&read, FED_ADM1025_Read/4); // read data if (verbosity > 1) printf("ReadADM1025: read = $%08x \n", (unsigned int) read); *data = read & 0xff; if (read & 0x100 || read & 0x200) { printf("ReadADM1025: ERROR in ADM1025 access \n"); return 1; } return 0; } int FFv1Object::WriteADM1025(unsigned int reg_id, unsigned int data, int verbosity) { unsigned long write = reg_id << 8 | (data & 0xff); unsigned long read = 0; if (verbosity > 1) printf("WriteADM1025: write = $%08x \n", (unsigned int) write); ffv1SingleWrite(write, FED_ADM1025_Write/4); // send addr and data usleep(1000); ffv1SingleRead(&read, FED_ADM1025_Read/4); // read just to check for errors if (read & 0x100 || read & 0x200) { printf("WriteADM1025: ERROR in ADM1025 access : Read = $%08x \n", (unsigned int) read); return 1; } return 0; } int FFv1Object::DumpSerialEPROM(unsigned int eprom_quadrant, int verbosity) { unsigned int data[eprom_max/4]; // only read one quadrant at a time printf("Takes a few seconds... \n"); if (eprom_quadrant > 3) eprom_quadrant = 0; for (int i = 0; i < eprom_max/4; i++) { ReadSerialEPROM(eprom_quadrant * eprom_max/4 + i, &data[i], verbosity); // if (i < 8) printf(" %02d : %02x \n", i, data[i]); } printf("\n"); printf("Serial EPROM contents : \n\n"); printf(" "); for (unsigned int i=0; i<32; i++) { printf("%2d ", i); } for (unsigned int i=0; i 1) printf("ReadSerialEPROM: eprom_write = $%08x \n", (unsigned int) eprom_write); ffv1SingleWrite(eprom_write, FED_EPROM_Write/4); // send addr to read usleep(5); ffv1SingleRead(&eprom_read, FED_EPROM_Read/4); // read data if (verbosity > 1) printf("ReadSerialEPROM: eprom_read = $%08x \n", (unsigned int) eprom_read); *data = eprom_read & 0xff; if (eprom_read & 0x100 || eprom_read & 0x200) { printf("ReadSerialEPROM: ERROR in EPROM access \n"); return 1; } return 0; } int FFv1Object::WriteSerialEPROM(unsigned int addr, unsigned int *data, int verbosity) { unsigned long eprom_write = addr << 8 | (*data & 0xff); unsigned long eprom_read = 0; if (verbosity > 1) printf("WriteSerialEPROM: eprom_write = $%08x \n", (unsigned int) eprom_write); ffv1SingleWrite(eprom_write, FED_EPROM_Write/4); // send addr and data usleep(1000); ffv1SingleRead(&eprom_read, FED_EPROM_Read/4); // read just to check for errors if (eprom_read & 0x100 || eprom_read & 0x200) { printf("WriteSerialEPROM: ERROR in EPROM access : Read = $%08x \n", (unsigned int) eprom_read); return 1; } return 0; } int FFv1Object::EnableWriteEPROM(unsigned int enable_eprom, int verbosity) { // set up write protect register $7ff unsigned int data; data = 0x02; // enable WEL WriteSerialEPROM(0x7ff, &data, verbosity); data = 0x06; // enable RWEL ; fixed on 06.05.2004 WriteSerialEPROM(0x7ff, &data, verbosity); switch (enable_eprom) { case 0 : data = 0x02; // bp0 = 0 ; bp1 = 0 ; WPEN = 0 => no protection break; case 1 : data = 0x0a; // bp0 = 1 ; bp1 = 0 ; WPEN = 0 => block protect upper quarter of memory break; case 2 : data = 0x12; // bp0 = 0 ; bp1 = 1 ; WPEN = 0 => block protect upper half of memory break; case 3 : data = 0x1a; // bp0 = 1 ; bp1 = 1 ; WPEN = 0 => block protect all memory break; case 4 : data = 0x92; // bp0 = 0 ; bp1 = 1 ; WPEN = 1 => block protect upper half of memory & write protect enable break; default: data = 0x02; // no protection break; } WriteSerialEPROM(0x7ff, &data, verbosity); return 0; } int FFv1Object::ReadSerNrEPROM(unsigned int *sernr, unsigned int *fedid, int verbosity) { // unsigned int data[4]; unsigned int temp1, temp2; /* ReadSerialEPROM(FED_EPROM_FEDID1, &data[0], verbosity); ReadSerialEPROM(FED_EPROM_FEDID2, &data[1], verbosity); ReadSerialEPROM(FED_EPROM_FEDID3, &data[2], verbosity); ReadSerialEPROM(FED_EPROM_FEDID4, &data[3], verbosity); *fedid = ((data[0] & 0xff) << 24) | ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | ((data[3] & 0xff)); */ // ReadSerialEPROM(FED_EPROM_SERNR2, sernr, verbosity); *fedid = 0; // FED Industry Test results ReadSerialEPROM(INDUSTRY_RESULTS_OFFSET+0, &temp1, verbosity); ReadSerialEPROM(INDUSTRY_RESULTS_OFFSET+1, &temp2, verbosity); *sernr = ((temp1 & 0xFF) * 10 ) + ((temp2 & 0xFF) / 10); return 0; } int FFv1Object::WriteSerNrEPROM(unsigned int sernr, unsigned int fedver, int verbosity) { EnableWriteEPROM(0, verbosity); // enable writing to all eprom, nb can't read previous setting yet unsigned int data[4] = {0xf, 0xe, 0xd, 0x1}; WriteSerialEPROM(FED_EPROM_FEDID1, &data[0], verbosity); WriteSerialEPROM(FED_EPROM_FEDID2, &data[1], verbosity); WriteSerialEPROM(FED_EPROM_FEDID3, &data[2], verbosity); // WriteSerialEPROM(FED_EPROM_FEDID4, &data[3], verbosity); WriteSerialEPROM(FED_EPROM_FEDID4, &fedver, verbosity); WriteSerialEPROM(FED_EPROM_SERNR2, &sernr, verbosity); return 0; } const int ttc_reg_max = 29; const char* ttc_reg_name[ttc_reg_max] = { "fine delay 1", "fine delay 2", "coarse delay", "control", "", "", "", "", "single error count<7:0>", "single error count<15:8>", "double error count<7:0>", "double error count<15:8>", "", "", "", "", "ID<7:0>", "MasterModeA<1:0>,ID<13:8>", "MasterModeB<1:0>,I2C_ID<5:0>", "Config 1", "Config 2", "Config 3", "Status", "", "BX Ctr <7:0>", "BX Ctr <15:8>", "Evt Ctr <7:0>", "Evt Ctr <15:8>", "Evt Ctr <23:16>" }; int FFv1Object::DisplayTTCrx(int verbosity) { unsigned int ttc_data[ttc_reg_max]; printf("TTC Status: \n"); printf("Reg Nr \t Data $ \n"); for (int reg_nr = 0; reg_nr < ttc_reg_max; reg_nr++) { ReadTTCrx(reg_nr, &ttc_data[reg_nr], verbosity); printf(" %02d : %02x ; ", reg_nr, ttc_data[reg_nr]); cout << ttc_reg_name[reg_nr] << '\n'; } return 0; } int FFv1Object::ReadTTCrxBXCtr(int verbosity, unsigned int* bx_ctr, unsigned int* evt_ctr) { unsigned int bx1, bx2; unsigned int evt1, evt2, evt3; ReadTTCrx(24, &bx1, verbosity); ReadTTCrx(25, &bx2, verbosity); *bx_ctr = bx2 * 0xff + bx1; ReadTTCrx(26, &evt1, verbosity); ReadTTCrx(27, &evt2, verbosity); ReadTTCrx(28, &evt3, verbosity); *evt_ctr = evt3 * 0xffff + evt2 * 0xff + evt1; return 0; } int FFv1Object::WriteTTCrxFineSkew1(unsigned int* skew, int verbosity) { unsigned int skew_psec; // mapping from ttcrx manual appendix A unsigned int n = *skew % 15; unsigned int m = ((*skew/15) - n + 14)%16; skew_psec = 16*n + m; printf("skew = %d ; n = %d ; m = %d ; skew_psec = %d \n", *skew, n, m, skew_psec); WriteTTCrx(0, &skew_psec, verbosity); // don't care about register nr return 0; } int FFv1Object::ResetTTCrx(int verbosity) { // local reset to TTCrx unsigned int reset_cmd = 1 << 15; WriteTTCrx(0, &reset_cmd, verbosity); // don't care about register nr return 0; } int FFv1Object::ReadTTCrx(int reg_id, unsigned int *data, int verbosity) { // reads back data from TTCrx internal registers unsigned int ttc_ctrl = reg_id << 9 | 1 << 8; unsigned int ttc_status; BECommand(3, 0, &ttc_ctrl, verbosity); // send read request usleep(1000); BECommand(24, 1, &ttc_status, verbosity); // read back status to get data if (verbosity > 1) printf("ReadTTCrx: ttc_status = $%08x \n", (unsigned int) ttc_status); if (ttc_status & 0x100 || ttc_status & 0x200) { printf("TTCrxRead: ERROR in TTCrx access \n"); } *data = ttc_status & 0xff; return 0; } int FFv1Object::WriteTTCrx(int reg_id, unsigned int *data, int verbosity) { // writes data to TTCrx internal reg_id unsigned int ttc_ctrl = reg_id << 9 | (*data & 0xff); unsigned int ttc_status; if (verbosity > 1) printf("WriteTTCrx: ttc_ctrl = $%08x \n", (unsigned int) ttc_ctrl); BECommand(3, 0, &ttc_ctrl, verbosity); // send write request usleep(1000); BECommand(24, 1, &ttc_status, verbosity); // read back status just for error bits if (ttc_status & 0x100 | ttc_status & 0x200) { printf("TTCWrite: ERROR in I2C access \n"); } return 0; } const unsigned int max_words = 8192; // 32 Kbytes is size of VME event memory unsigned long int bram_data[max_words]; int FFv1Object::DumpMemory(unsigned int start_addr, unsigned int nr_words, int block_transfer) { if (nr_words > (unsigned int) max_words) nr_words = max_words; for (unsigned int i=0; i (unsigned int) max_words) nr_words = max_words; for (unsigned int i=0; i (unsigned int) max_words) nr_words = max_words; for (unsigned int i=0; i 1) printf("WriteTrimDAC: fe fpga = %02d ; fibre chan = %02d ; value = %02d \n", chip_id, 12-i, value); // adds wait state } } else { value = chan << 8 | (*data & 0xff); FECommand(chip_id, 6, 0, &value, verbosity); if (verbosity > 1) printf("WriteTrimDAC: fe fpga = %02d ; fibre chan = %02d ; value = %02d \n", chip_id, 12-chan, value); } return 0; } int FFv1Object::ResetTrimDAC(int chip_id, int verbosity) { // TrimDACs are Write Only unsigned int value = 1 << 13; if (verbosity > 1) printf("ResetTrimDAC: fe fpga = %02d ; value = $%04x \n", chip_id, (unsigned int) value); FECommand(chip_id, 6, 0, &value, verbosity); return 0; } int FFv1Object::ShutdownTrimDAC(int chip_id, int verbosity) { // TrimDACs are Write Only unsigned int value = 1 << 12; if (verbosity > 1) printf("ShutdownTrimDAC: fe fpga = %02d ; value = $%04x \n", chip_id, (unsigned int) value); FECommand(chip_id, 6, 0, &value, verbosity); return 0; } int FFv1Object::DisplayFrameThresholds(int verbosity) { unsigned int thresh[fe_max][fibre_max]; for (int fe_nr = 0; fe_nr < fe_max; fe_nr++) { ReadFrameThresholds(fe_nr, thresh[fe_nr], verbosity); } printf("\n"); printf("Fibre Frame Thresholds : \n"); printf("FE nr / Chan nr : \n"); printf(" 12 11 10 9 8 7 6 5 4 3 2 1\n"); for (int fe_nr=0; fe_nr 1) { for (int fibre_nr = 0; fibre_nr < fibre_max; fibre_nr++) { // printf("writing fibre thresholds \n"); printf("chip %d ; fibre %d ; thresh = %d \n", chip, 12-fibre_nr, data[fibre_nr]); } } unsigned int fed_data1 = data[0] << 27 | data[1] << 22 | data[2] << 17 | data[3] << 12 | data[4] << 7 | data[5] << 2 | data[6] >> 3; unsigned int fed_data2 = data[6] << 29 | data[7] << 24 | data[8] << 19 | data[9] << 14 | data[10] << 9 | data[11] << 4; cout << "fed_cmd = $ " << hex << fed_cmd << " ; fed_data1 = $ " << fed_data1 << " ; fed_data2 = $ " << fed_data2 << '\n'; // return 0; CheckSerialStatus(fed_cmd, 0); // usleep(0); ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer ffv1SingleWrite(fed_data1, FED_Serial_BRAM/4 + 1); ffv1SingleWrite(fed_data2, FED_Serial_BRAM/4 + 2); ffv1SingleWrite(3, FED_Serial_Write/4); // send cmd string return 0; } int FFv1Object::ReadFrameThresholds(int chip, unsigned int* data, int verbosity) { unsigned long fed_data1, fed_data2; unsigned int fed_cmd = fedCmd(chip, 0x04, 60, 1); CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_Read/4); // sends read cmd // usleep(100); CheckSerialStatus(fed_cmd, 0); ffv1SingleRead(&fed_data1, FED_Serial_BRAM/4); ffv1SingleRead(&fed_data2, FED_Serial_BRAM/4 + 1); // 2 long words for all 60 bits of threshold information if (verbosity > 1) { printf("data1 = $%08x ; data2 =$%08x \n", (unsigned int) fed_data1, (unsigned int) fed_data2); } data[0] = fed_data1 >> 27 & 0x1f; data[1] = fed_data1 >> 22 & 0x1f; data[2] = fed_data1 >> 17 & 0x1f; data[3] = fed_data1 >> 12 & 0x1f; data[4] = fed_data1 >> 7 & 0x1f; data[5] = fed_data1 >> 2 & 0x1f; data[6] = (fed_data1 << 3 & 0x18) | (fed_data2 >> 29 & 0x7); data[7] = fed_data2 >> 24 & 0x1f; data[8] = fed_data2 >> 19 & 0x1f; data[9] = fed_data2 >> 14 & 0x1f; data[10] = fed_data2 >> 9 & 0x1f; data[11] = fed_data2 >> 4 & 0x1f; if (verbosity > 1) { for (int fibre_nr = 0; fibre_nr < fibre_max; fibre_nr++) { printf("reading fibre thresholds \n"); printf("fibre %d ; thresh = %d \n", 12-fibre_nr, data[fibre_nr]); } } return 0; } int FFv1Object::DisplayFibreBufferLevels(int verbosity) { unsigned int buffers[fe_max][fibre_max]; for (int fe_nr = 0; fe_nr < fe_max; fe_nr++) { ReadFibreBufferLevels(fe_nr, buffers[fe_nr], verbosity); } printf("\n"); printf("Fibre FREE Buffer Levels : \n"); printf("FE nr / Chan nr : \n"); printf("\t12 \t11 \t 10\t 9\t 8\t 7\t 6\t 5\t 4\t 3\t 2\t 1\n"); for (int fe_nr=0; fe_nr> 19 & 0x1fff; data[1] = fed_data[0] >> 6 & 0x1fff; data[2] = (fed_data[0] << 7 & 0x1fc0) | (fed_data[1] >> 25 & 0x3f); data[3] = fed_data[1] >> 12 & 0x1fff; data[4] = (fed_data[1] << 1 & 0x1ffe) | (fed_data[2] >> 31 & 0x1); data[5] = fed_data[2] >> 18 & 0x1fff; data[6] = fed_data[2] >> 5 & 0x1fff; data[7] = (fed_data[2] << 8 & 0x1f00) | (fed_data[3] >> 24 & 0xff); data[8] = fed_data[3] >> 11 & 0x1fff; data[9] = (fed_data[3] << 2 & 0x1ffc) | (fed_data[4] >> 30 & 0x2); data[10] = fed_data[4] >> 17 & 0x1fff; data[11] = fed_data[4] >> 4 & 0x1fff; if (verbosity > 1) { for (int fibre_nr = 0; fibre_nr < fibre_max; fibre_nr++) { printf("reading fe buffer levels \n"); printf("fibre %d ; buff level = %04x \n", 12-fibre_nr, data[fibre_nr]); } } return 0; } int FFv1Object::LoadFibrePedestals(int mode, int value, int verbosity) { // if mode = 0 uses ped values calculated from scope mode capture if (mode != 0) { for (int i=0; i= 0; fe_nr--) { // for (int fe_nr = 0; fe_nr < 1; fe_nr++) { WriteFibrePedestals(fe_nr, &fibre_ped_calc[fe_nr*12], mode, verbosity); } return 0; } int FFv1Object::DisplayFibrePedestals(int verbosity) { // unsigned int peds[fe_max][fibre_max]; unsigned int peds[chan_max]; // for (int fe_nr = 0; fe_nr < 1; fe_nr++) { for (int fe_nr = 0; fe_nr < fe_max; fe_nr++) { // ReadFibrePedestals(fe_nr, peds[fe_nr], verbosity); ReadFibrePedestals(fe_nr, &peds[fe_nr*12], verbosity); // if (verbosity > 1) { // for (unsigned int fibre_nr = 0; fibre_nr < fibre_max; fibre_nr++) { // printf("reading back pedestals \n"); // printf("fibre %d ; pedestal = %d \n", fe_nr*12+fibre_nr, peds[fe_nr*12+fibre_nr]); // } // } } printf("\n"); printf("Fibre Pedestals (SAME value on all 256 strips) : \n"); printf("FE nr / Chan nr : \n"); printf(" \t11\t 10\t 9\t 8\t 7\t 6\t 5\t 4\t 3\t 2\t 1\t 0\n"); for (int fe_nr=0; fe_nr> 4 | 0x01000040; // ignore cluster data but enable both APVs as valid strips word2 = data0 << 28; // this print statement may interfere with loading? if (verbosity > 1) printf("fibre %d ; start addr = $%08x ; word1 = $%08x ; word2 = $%08x \n", 12-fibre_nr, (unsigned int) start_addr, (unsigned int) word1, (unsigned int) word2); // usleep(0); // added 03.08.05 ; this cured loading and readback of RAM data ; needed at RAL 01.02.2006 fed_cmd = fedCmd(chip, 0xe, 12, 0); // ped address CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer ffv1SingleWrite(start_addr, FED_Serial_BRAM/4 + 1); ffv1SingleWrite(2, FED_Serial_Write/4); // send cmd string // load same pedestal data for each strip, address autoincrements for pair of fibres if (mode == 0 || mode == 1 || mode == 5 || mode == 6) { for (int strip_nr=0; strip_nr 1) printf("fibre %d ; start addr = $%08x ; strip nr = %d ; word1 = $%08x ; word2 = $%08x \n", 12-fibre_nr, (unsigned int) start_addr, (unsigned int) strip_nr, (unsigned int) word1, (unsigned int) word2); // tests if (mode == 6) { data0++; data1++; word1 = data1 << 14 | data0 >> 4 | 0x01000040; // ignore cluster data but enable both APVs as valid strips word2 = data0 << 28; } } } // multiple data strings.... // serial memory is 2Kbytes deep and can hold 512 words, but each pedestal cmd needs 3 words // so can't do in one serial memory fill else if (mode == 2) { fed_cmd = fedCmd(chip, 0xd, 36, 0); // ped data // for (int strip_nr=0; strip_nr> 4 | 0x01000040; // ignore cluster data but enable both APVs as valid strips word2 = data0 << 28; } ffv1SingleWrite(word1, strip_nr*3 + 1); ffv1SingleWrite(word2, strip_nr*3 + 2); // 2 words needed for 36 bits of pedestal data } ffv1SingleWrite(3*4, FED_Serial_Write/4); // send stream of command/data packets // usleep(1); } } /* if (verbosity > 1) { for (unsigned int fibre_nr = 0; fibre_nr < (unsigned int) fibre_max; fibre_nr++) { printf("writing pedestals \n"); printf("fibre %d ; pedestal = %d \n", 12-fibre_nr, data[fibre_nr]); } } */ return 0; } int FFv1Object::ReadFibrePedestals(int chip, unsigned int* data, int verbosity) { unsigned int fed_cmd; unsigned long addr; unsigned long word1, word2; for (int fibre_nr=0; fibre_nr 1) printf("fibre %d ; addr = $%08x \n", 12-fibre_nr, (unsigned int) addr); fed_cmd = fedCmd(chip, 0xe, 12, 0); CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer ffv1SingleWrite(addr, FED_Serial_BRAM/4 + 1); ffv1SingleWrite(2, FED_Serial_Write/4); // send cmd string // for (int strip_nr=0; strip_nr> 14 & 0x3ff; data[fibre_nr] = (word1 << 4 & 0x3f0) | (word2 >> 28); if (verbosity > 1) printf("fibre %d ; strip = %d ; addr = $%08x ; ped even fibre = %d ; ped odd fibre = %d \n", 12-fibre_nr, strip_nr, (unsigned int) addr, data[fibre_nr], data[fibre_nr+1]); if (verbosity == 1) { if (strip_nr==0) printf("fe nr = %d ; fibre nr = %d \n", chip, 12-fibre_nr); if (strip_nr%8==0) printf("\n"); printf("%4d %4d ", data[fibre_nr], data[fibre_nr+1]); } // autoincrement doesnt work for reads in VHDL version according to Oz // but it does seem to work in practice! 27.10.2005 // should be ok for writes still /*****/ // need to increment addr in properly !! // add code here... // addr += (1<<20); // addr written to serial memory is right shifted // usleep(100); // // fed_cmd = fedCmd(chip, 0xe, 12, 0); // // ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer // ffv1SingleWrite(addr, FED_Serial_BRAM/4 + 1); //usleep(0); // ffv1SingleWrite(2, FED_Serial_Write/4); // send cmd string // usleep(100); } } return 0; } int FFv1Object::LoadClusterThresholds(int mode, int lowfix, int highfix, int verbosity) { if (mode == 0 || mode == 1) { for (int i=0; i> 4; word2 = low_thresh[fibre_nr] << 28; // this print statement may interfere with loading? if (verbosity > 1) printf("fibre %d ; start addr = $%08x ; word1 = $%08x ; word2 = $%08x \n", 12-fibre_nr, (unsigned int) start_addr, (unsigned int) word1, (unsigned int) word2); // usleep(0); // added 03.08.05 ; this cured loading and readback of RAM data , needed at RAL 01/02/2006 fed_cmd = fedCmd(chip, 0xe, 12, 0); // ped address CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer ffv1SingleWrite(start_addr, FED_Serial_BRAM/4 + 1); ffv1SingleWrite(2, FED_Serial_Write/4); // send cmd string // load same threshold data for each strip, address autoincrements for pair of fibres if (mode == 1) { // test multiple serial commands... fed_cmd = fedCmd(chip, 0xd, 36, 0); // cluster data CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer ffv1SingleWrite(word1, FED_Serial_BRAM/4 + 1); ffv1SingleWrite(word2, FED_Serial_BRAM/4 + 2); // 2 words needed for 36 bits of pedestal data ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4 + 3); // fill cmd string in buffer ffv1SingleWrite(word1, FED_Serial_BRAM/4 + 4); ffv1SingleWrite(word2, FED_Serial_BRAM/4 + 5); // 2 words needed for 36 bits of pedestal data ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4 + 6); // fill cmd string in buffer ffv1SingleWrite(word1, FED_Serial_BRAM/4 + 7); ffv1SingleWrite(word2, FED_Serial_BRAM/4 + 8); // 2 words needed for 36 bits of pedestal data ffv1SingleWrite(9, FED_Serial_Write/4); // sending 3 command strings } else // normal way... { for (int strip_nr=0; strip_nr 1) { for (unsigned int fibre_nr = 0; fibre_nr < (unsigned int) fibre_max; fibre_nr++) { printf("writing cluster thresholds \n"); printf("fibre %d ; low thresh = %d ; high thresh = %d \n", 12-fibre_nr, low_thresh[fibre_nr], high_thresh[fibre_nr]); } } return 0; } int FFv1Object::ReadClusterThresholds(int chip, unsigned int* low, unsigned int* high, int verbosity) { unsigned int fed_cmd; unsigned long addr; unsigned long word1, word2; for (int fibre_nr=0; fibre_nr 1) printf("fibre %d ; addr = $%08x \n", 12-fibre_nr, (unsigned int) addr); fed_cmd = fedCmd(chip, 0xe, 12, 0); CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer ffv1SingleWrite(addr, FED_Serial_BRAM/4 + 1); ffv1SingleWrite(2, FED_Serial_Write/4); // send cmd string // usleep(1000); // ffv1SingleWrite(2, FED_Serial_Write/4); // send cmd string // for (int strip_nr=0; strip_nr> 14 & 0xff; low[fibre_nr] = (word1 << 4 & 0xf0) | (word2 >> 28); high[fibre_nr+1] = word1 >> 23 & 0xff; high[fibre_nr] = word1 >> 5 & 0xff; if (verbosity > 1) printf("fibre %d ; strip = %d ; addr = $%08x ; low even fibre = %d ; low odd fibre = %d ; high even fibre = %d ; high odd fibre = %d \n", 12-fibre_nr, strip_nr, (unsigned int) addr, low[fibre_nr], low[fibre_nr+1], high[fibre_nr], high[fibre_nr+1]); // autoincrement doesnt work for reads in VHDL version according to Oz // but it does seem to work in practice! 27.10.2005 // should be ok for writes still /* // need to increment addr in properly !! // add code here... addr += (1 << 20); // addr written to serial memory is right shifted fed_cmd = fedCmd(chip, 0xe, 12, 0); ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4); // fill cmd string in buffer ffv1SingleWrite(addr, FED_Serial_BRAM/4 + 1); ffv1SingleWrite(2, FED_Serial_Write/4); // send cmd string */ } } return 0; } const int max_ttcvi_regs = 32; int FFv1Object::TTCvi_Display(unsigned int start_addr, int verbosity) { if (verbosity > 2) printf("TTCvi_Display \n"); unsigned long ttcvi_regs[max_ttcvi_regs]; // unsigned long value = 0; // unsigned long offset = 0; // unsigned short svalue = 0; for (int i=0; i> 1 & 0x1)); printf("FIFO 1 : \t%1x \t%1x\n", (unsigned int) (ttcvi_regs[1] >> 2 & 0x1), (unsigned int) (ttcvi_regs[1] >> 3 & 0x1)); printf("FIFO 2 : \t%1x \t%1x\n", (unsigned int) (ttcvi_regs[1] >> 4 & 0x1), (unsigned int) (ttcvi_regs[1] >> 5 & 0x1)); printf("FIFO 3 : \t%1x \t%1x\n", (unsigned int) (ttcvi_regs[1] >> 6 & 0x1), (unsigned int) (ttcvi_regs[1] >> 7 & 0x1)); printf("\n"); printf("Evt/Orbit Ctr = $%06x \n", (unsigned int) (((ttcvi_regs[2] & 0xff) << 16) | (ttcvi_regs[3] & 0xffff)) ); printf("\n"); printf("Inhibit<0>: Delay = %4d ; Duration = %3d\n", (unsigned int) (ttcvi_regs[4] & 0xfff), (unsigned int) (ttcvi_regs[5] & 0xff)); printf("Inhibit<1>: Delay = %4d ; Duration = %3d\n", (unsigned int) (ttcvi_regs[6] & 0xfff), (unsigned int) (ttcvi_regs[7] & 0xff)); printf("Inhibit<2>: Delay = %4d ; Duration = %3d\n", (unsigned int) (ttcvi_regs[8] & 0xfff), (unsigned int) (ttcvi_regs[9] & 0xff)); printf("Inhibit<3>: Delay = %4d ; Duration = %3d\n", (unsigned int) (ttcvi_regs[10] & 0xfff), (unsigned int) (ttcvi_regs[11] & 0xff)); printf("\n"); printf("BGo<0>: Mode = $%01x\n", (unsigned int) (ttcvi_regs[12] & 0xf)); printf("BGo<1>: Mode = $%01x\n", (unsigned int) (ttcvi_regs[13] & 0xf)); printf("BGo<2>: Mode = $%01x\n", (unsigned int) (ttcvi_regs[14] & 0xf)); printf("BGo<3>: Mode = $%01x\n", (unsigned int) (ttcvi_regs[15] & 0xf)); printf("\n"); printf("TRIGWORD1 = $%04x\n", (unsigned int) (ttcvi_regs[16] & 0x3fff)); printf("TRIGWORD2 = $%04x\n", (unsigned int) (ttcvi_regs[17] & 0x3fff)); return 0; } int FFv1Object::TTCvi_Read(unsigned int start_addr, unsigned int reg, unsigned long* value, int verbosity) { if (verbosity > 2) printf("TTCvi_Read \n"); ffv1SingleReadA24D16(value, start_addr/2 + reg/2); return 0; } int FFv1Object::TTCvi_Write(unsigned int start_addr, unsigned int reg, unsigned long value, int verbosity) { if (verbosity > 1) printf("TTCvi_Write : reg = $%02x ; value = $%08x \n", (unsigned int) reg, (unsigned int) value); ffv1SingleWriteA24D16(value, start_addr/2 + reg/2); return 0; } // long word access for BGO FIFOs int FFv1Object::TTCvi_WriteD32(unsigned int start_addr, unsigned int reg, unsigned long value, int verbosity) { if (verbosity > 1) printf("TTCvi_WriteD32 : reg = $%02x ; value = $%08x \n", (unsigned int) reg, (unsigned int) value); ffv1SingleWriteA24D32(value, start_addr/4 + reg/4); return 0; } int FFv1Object::TTCvi_Select_Trigger(unsigned int start_addr, int trig_src, int rand_rate, int verbosity) { unsigned long saved = 0; unsigned long value = 0; TTCvi_Read(start_addr, TTCvi_CSR1, &saved, verbosity); if (verbosity > 1) printf("trig src = %d \n", trig_src); switch (trig_src) { case 0 : // random value = (saved & 0x8ff8) | (0x5 | ((rand_rate & 0x7) << 12)); break; case 1 : // calibn value = (saved & 0xfff8) | 0x6 ; break; case 2 : // vme value = (saved & 0xfff8) | 0x4; break; case 3 : // l1a<0> value = (saved & 0xfff8) | 0x0; break; case 4 : // l1a<1> value = (saved & 0xfff8) | 0x1; break; case 5 : // l1a<2> value = (saved & 0xfff8) | 0x2; break; case 6 : // l1a<3> value = (saved & 0xfff8) | 0x3; break; case 7 : // disable value = (saved & 0xfff8) | 0x7; break; default: break; } if (verbosity > 1) printf("value = $%04x \n", (unsigned int) value); TTCvi_Write(start_addr, TTCvi_CSR1, value, verbosity); return 0; } int FFv1Object::TTCvi_Select_Orbit(unsigned int start_addr, int orbit, int verbosity) { unsigned long saved = 0; unsigned long value = 0; TTCvi_Read(start_addr, TTCvi_CSR1, &saved, verbosity); value = (saved & 0xfff7) | ((orbit & 0x1) << 3); TTCvi_Write(start_addr, TTCvi_CSR1, value, verbosity); return 0; } int FFv1Object::TTCvi_Select_Counter(unsigned int start_addr, int ctr, int verbosity) { unsigned long saved = 0; unsigned long value = 0; TTCvi_Read(start_addr, TTCvi_CSR1, &saved, verbosity); value = (saved & 0x7fff) | ((ctr & 0x1) << 15); TTCvi_Write(start_addr, TTCvi_CSR1, value, verbosity); return 0; } int FFv1Object::TTCvi_SW_Trigger(unsigned int start_addr, int verbosity) { unsigned long value = 1; TTCvi_Write(start_addr, TTCvi_SW_L1A, value, verbosity); if (verbosity > 1) printf("Sent a Software L1A Trigger \n"); return 0; } int FFv1Object::TTCvi_Reset_Module(unsigned int start_addr, int verbosity) { unsigned long value = 1; TTCvi_Write(start_addr, TTCvi_Module_Reset, value, verbosity); if (verbosity > 1) printf("Reset TTCvi Module \n"); return 0; } int FFv1Object::TTCvi_Reset_Counters(unsigned int start_addr, int verbosity) { unsigned long value = 1; TTCvi_Write(start_addr, TTCvi_Ctr_Reset, value, verbosity); if (verbosity > 1) printf("Reset TTCvi counters \n"); return 0; } int FFv1Object::TTCvi_BGO_Reset_FIFO(unsigned int start_addr, int ttcvi_bgo_nr, int verbosity) { unsigned long saved = 0; unsigned long value = 0; TTCvi_Read(start_addr, TTCvi_CSR1, &saved, verbosity); value = (saved & 0xfff) | (1 << ttcvi_bgo_nr + 12); TTCvi_Write(start_addr, TTCvi_CSR2, value, verbosity); if (verbosity > 1) printf("Reset TTCvi FIFOs \n"); return 0; } int FFv1Object::TTCvi_BGO_Inhibit(unsigned int start_addr, int ttcvi_bgo_nr, unsigned long ttcvi_bgo_delay, unsigned long ttcvi_bgo_duration, int verbosity) { // unsigned long value = 1; TTCvi_Write(start_addr, TTCvi_Inhibit0_Delay + ttcvi_bgo_nr*8, ttcvi_bgo_delay, verbosity); TTCvi_Write(start_addr, TTCvi_Inhibit0_Duration + ttcvi_bgo_nr*8, ttcvi_bgo_duration, verbosity); return 0; } int FFv1Object::TTCvi_BGO_Mode(unsigned int start_addr, int ttcvi_bgo_nr, int ttcvi_bgo_enable, int ttcvi_bgo_sync, int ttcvi_bgo_single, int ttcvi_bgo_fifo, int verbosity) { unsigned long value = 1; value = (ttcvi_bgo_fifo & 0x1) << 3 | (ttcvi_bgo_single & 0x1) << 2 | (ttcvi_bgo_sync & 0x1) << 1 | (ttcvi_bgo_enable & 0x1); if (verbosity > 1) printf("BGO mode = $%01x \n", (unsigned int) value); TTCvi_Write(start_addr, TTCvi_BGO0_Mode + ttcvi_bgo_nr*8, value, verbosity); return 0; } int FFv1Object::TTCvi_BGO_Write(unsigned int start_addr, int ttcvi_bgo_nr, int verbosity) { unsigned long value = 1; TTCvi_Write(start_addr, TTCvi_BGO0_Write + ttcvi_bgo_nr*8, value, verbosity); return 0; } int FFv1Object::TTCvi_BGO_Retransmit(unsigned int start_addr, int ttcvi_bgo_nr, int verbosity) { unsigned long value = 0 << (ttcvi_bgo_nr + 8); TTCvi_Write(start_addr, TTCvi_CSR2, value, verbosity); return 0; } int FFv1Object::TTCvi_BGO_Data(unsigned int start_addr, int ttcvi_bgo_nr, int ttcvi_format, int verbosity) { unsigned long value = 0; unsigned long ttcrx_addr = 0; unsigned long subaddr = 1; unsigned long external = 0xfed; unsigned long data = 0; unsigned long command = 0x01; // reset bx ctr // unsigned long command = 0x03; // reset bx & evt ctrs // unsigned long command = 0xff; // reset bx & evt ctrs long fifo_depth; fifo_depth = 1; // if retransmit enabled one word is enough? // fifo_depth = 256; if (ttcvi_format == 1 ) { // long commands for (int i=0; i Couldn't open Input Event File = 'eventinput.txt'\n"); return 1; } if (verbosity > 1) printf("Opened Event Input File... \n"); while (!feof(readout_file)) { // for (int i=0; i<10; i++) { fscanf(readout_file, "%08x\n", (unsigned int *) bufp); // printf("read %08x\n", *bufp); bufp++; nwords++; } if (endian_swap == 1) { bufp = readout_buffer; for (int i=0; i> 8 ) || ((data & 0xff000000) >> 24); *bufp = swapped; bufp++; } } // printf("read %d (32 bit) words from file\n", nwords); int crc_check = CheckCRC(readout_buffer, nwords, 0); if (event_format == 3) { // test patterns CheckEvent(readout_buffer, nwords, evt_nr, &error, 1, event_format, 0, crc_check, &error_crc); } else { CheckEventNew(readout_buffer, nwords, evt_nr, &error, 1, 0, crc_check, &error_crc, verbosity); } if (error != 0) { printf("\n*** ERROR : The format of event in file was BAD. \n"); } else { printf("\nThe format of event in File was GOOD. \n"); if (error_crc != 0) { printf("*** ERROR : BUT the CRC in the Event did not agree with the Recomputed Value. \n"); } } return 0; } int FFv1Object::ReadDelayFPGAID(int fe_chip, int delay_chip, unsigned long* fpga_id) { // Uses CDC dial thru command. Same mechanism as SPY FIRE // CDC cmd part goes in new spy cmd LSB // FED cmd part goes in new spy cmd MSB (this triggers action) // cout << dec << "FE Chip # " << 8-fe_chip << " Delay chip # " << delay_chip << '\n'; unsigned long fed_data, fed_data2; unsigned int cdc_len; unsigned int extra = 3; // was 5 unsigned int shift = 1; cdc_len = 32 + extra; // some extra bits come from serial stream unsigned int tot_len = cdc_len + 27; // printf("total cmd len = %d; cdc len = %d \n", tot_len, cdc_len ); unsigned int fed_cmd = fedCmd(fe_chip, 0x15, tot_len, 0); // nb "write" cmd type unsigned int cdc_cmd = cdcCmd(delay_chip, 0x6, cdc_len); unsigned int dummy = 0; ffv1SingleWrite(dummy, FED_Serial_BRAM/4); // clear memory for test ffv1SingleWrite(dummy, FED_Serial_BRAM/4 + 1); // clear memory for test CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(cdc_cmd, FED_Spy_Cmd_LSB/4); // printf("wrote cdc LSB command = $ %08x at addr = $ %08x \n", cdc_cmd, FED_Spy_Cmd_LSB); ffv1SingleWrite(fed_cmd, FED_Spy_Cmd_MSB/4); // act of writing sends SpyArm command // printf("wrote fed MSB command = $ %08x at addr = $ %08x \n", fed_cmd, FED_Spy_Cmd_MSB); CheckSerialStatus(fed_cmd, 0); ffv1SingleRead(&fed_data, FED_Serial_BRAM/4); // readback memory fed_data <<= shift; ffv1SingleRead(&fed_data2, FED_Serial_BRAM/4 + 1); // fed_data |= (fed_data2 >> (32-extra)); fed_data |= (fed_data2 >> (32-shift)); *fpga_id = fed_data; return 0; } int FFv1Object::ReadDelayFPGAClockSkewDone(int fe_chip, int delay_chip, int* skew_done) { // AND of 4 DCM FPGA PSDONE signals ; 1 = DONE // Uses CDC dial thru command. Same mechanism as SPY FIRE // CDC cmd part goes in new spy cmd LSB // FED cmd part goes in new spy cmd MSB (this triggers action) // cout << dec << "FE Chip # " << 8-fe_chip << " Delay chip # " << delay_chip << '\n'; unsigned long fed_data; unsigned int cdc_len; unsigned int extra = 3; // was 5 unsigned int shift = 1; cdc_len = 1 + extra; // some extra bits come from serial stream unsigned int tot_len = cdc_len + 27; // printf("total cmd len = %d; cdc len = %d \n", tot_len, cdc_len ); unsigned int fed_cmd = fedCmd(fe_chip, 0x15, tot_len, 0); // nb "write" cmd type unsigned int cdc_cmd = cdcCmd(delay_chip, 0x2, cdc_len); CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(cdc_cmd, FED_Spy_Cmd_LSB/4); // printf("wrote cdc LSB command = $ %08x at addr = $ %08x \n", cdc_cmd, FED_Spy_Cmd_LSB); ffv1SingleWrite(fed_cmd, FED_Spy_Cmd_MSB/4); // act of writing sends SpyArm command // printf("wrote fed MSB command = $ %08x at addr = $ %08x \n", fed_cmd, FED_Spy_Cmd_MSB); CheckSerialStatus(fed_cmd, 0); ffv1SingleRead(&fed_data, FED_Serial_BRAM/4); // readback memory fed_data <<= shift; *skew_done = fed_data; return 0; } int FFv1Object::DumpEventToFile(unsigned long* event_buffer, unsigned long event_length, int verbosity) { unsigned long msw, lsw; verbosity = 0; FILE *eventdump_file = fopen( "eventdump.txt", "w" ); if (event_length%2 != 0) printf("ERROR: This event has an odd number = %d of 32 bit words ??\n", (unsigned int) event_length); for (unsigned long i=0; icm_width = 16; p_cm->cm_poly = 0x8005L; p_cm->cm_init = 0xFFFFL; // see DAQ/FE guide p_cm->cm_refin = FALSE; p_cm->cm_refot = FALSE; p_cm->cm_xorot = 0L; // initialise cm_ini(p_cm); for (unsigned long i=0; i=0; j--) { ch = (word >> j*8) & 0xff; // printf("char= %02x\n", ch); cm_nxt(p_cm, (ulong) ch); } } // extract crc crc = (unsigned long) cm_crc(p_cm); if (verbosity > 2) printf("crc value = $%08x \n", (unsigned int) crc); return (int) crc; } int FFv1Object::DisplayTrackerHeaderMonitor(int verbosity) { // Displays formatted contents of Serial Memory from response to Tracker Header Monitor command const int num_hdr_words = 21; unsigned long int hdr_data[num_hdr_words]; unsigned int dummy; unsigned int l1a; unsigned int fe_pipeaddr[8]; unsigned int fe_status[8][12]; BECommand(28, 1, &dummy, verbosity); // trigger monitor readout, ignore value // get full results from serial memory for (int i=0 ; i> 7 & 0xfffff; fe_pipeaddr[0] = hdr_data[18] >> 15 & 0xff; fe_pipeaddr[1] = (hdr_data[15] << 1 & 0xfe) | (hdr_data[16] >> 31 & 0x1); fe_pipeaddr[2] = hdr_data[13] >> 15 & 0xff; fe_pipeaddr[3] = (hdr_data[10] << 1 & 0xfe) | (hdr_data[11] >> 31 & 0x1); fe_pipeaddr[4] = hdr_data[8] >> 15 & 0xff; fe_pipeaddr[5] = (hdr_data[5] << 1 & 0xfe) | (hdr_data[6] >> 31 & 0x1); fe_pipeaddr[6] = hdr_data[3] >> 15 & 0xff; fe_pipeaddr[7] = (hdr_data[0] << 1 & 0xfe) | (hdr_data[1] >> 31 & 0x1); for (int fe=0; fe<8; fe++) { for (int fib=0; fib<12; fib++) { fe_status[fe][fib] = 0; } } fe_status[0][0] = hdr_data[18] >> 9 & 0x3f; fe_status[0][1] = hdr_data[18] >> 3 & 0x3f; fe_status[0][2] = (hdr_data[18] << 3 & 0x38) | (hdr_data[19] >> 29 & 0x7); fe_status[0][3] = hdr_data[19] >> 23 & 0x3f; fe_status[0][4] = hdr_data[19] >> 17 & 0x3f; fe_status[0][5] = hdr_data[19] >> 11 & 0x3f; fe_status[0][6] = hdr_data[19] >> 5 & 0x3f; fe_status[0][7] = (hdr_data[19] << 1 & 0x3e) | (hdr_data[20] >> 31 & 0x1); fe_status[0][8] = hdr_data[20] >> 25 & 0x3f; fe_status[0][9] = hdr_data[20] >> 19 & 0x3f; fe_status[0][10] = hdr_data[20] >> 13 & 0x3f; fe_status[0][11] = hdr_data[20] >> 7 & 0x3f; fe_status[1][0] = hdr_data[16] >> 25 & 0x3f; fe_status[1][1] = hdr_data[16] >> 19 & 0x3f; fe_status[1][2] = hdr_data[16] >> 13 & 0x3f; fe_status[1][3] = hdr_data[16] >> 7 & 0x3f; fe_status[1][4] = hdr_data[16] >> 1 & 0x3f; fe_status[1][5] = (hdr_data[16] << 5 & 0x20) | (hdr_data[17] >> 27 & 0x1f); fe_status[1][6] = hdr_data[17] >> 21 & 0x3f; fe_status[1][7] = hdr_data[17] >> 15 & 0x3f; fe_status[1][8] = hdr_data[17] >> 9 & 0x3f; fe_status[1][9] = hdr_data[17] >> 3 & 0x3f; fe_status[1][10] = (hdr_data[17] << 3 & 0x38) | (hdr_data[18] >> 29 & 0x07); fe_status[1][11] = hdr_data[18] >> 23 & 0x3f; fe_status[2][0] = hdr_data[13] >> 9 & 0x3f; fe_status[2][1] = hdr_data[13] >> 3 & 0x3f; fe_status[2][2] = (hdr_data[13] << 3 & 0x38) | (hdr_data[14] >> 29 & 0x7); fe_status[2][3] = hdr_data[14] >> 23 & 0x3f; fe_status[2][4] = hdr_data[14] >> 17 & 0x3f; fe_status[2][5] = hdr_data[14] >> 11 & 0x3f; fe_status[2][6] = hdr_data[14] >> 5 & 0x3f; fe_status[2][7] = (hdr_data[14] << 1 & 0x3e) | (hdr_data[15] >> 31 & 0x1); fe_status[2][8] = hdr_data[15] >> 25 & 0x3f; fe_status[2][9] = hdr_data[15] >> 19 & 0x3f; fe_status[2][10] = hdr_data[15] >> 13 & 0x3f; fe_status[2][11] = hdr_data[15] >> 7 & 0x3f; fe_status[3][0] = hdr_data[11] >> 25 & 0x3f; fe_status[3][1] = hdr_data[11] >> 19 & 0x3f; fe_status[3][2] = hdr_data[11] >> 13 & 0x3f; fe_status[3][3] = hdr_data[11] >> 7 & 0x3f; fe_status[3][4] = hdr_data[11] >> 1 & 0x3f; fe_status[3][5] = (hdr_data[11] << 5 & 0x20) | (hdr_data[12] >> 27 & 0x1f); fe_status[3][6] = hdr_data[12] >> 21 & 0x3f; fe_status[3][7] = hdr_data[12] >> 15 & 0x3f; fe_status[3][8] = hdr_data[12] >> 9 & 0x3f; fe_status[3][9] = hdr_data[12] >> 3 & 0x3f; fe_status[3][10] = (hdr_data[12] << 3 & 0x38) | (hdr_data[13] >> 29 & 0x07); fe_status[3][11] = hdr_data[13] >> 23 & 0x3f; fe_status[4][0] = hdr_data[8] >> 9 & 0x3f; fe_status[4][1] = hdr_data[8] >> 3 & 0x3f; fe_status[4][2] = (hdr_data[8] << 3 & 0x38) | (hdr_data[9] >> 29 & 0x7); fe_status[4][3] = hdr_data[9] >> 23 & 0x3f; fe_status[4][4] = hdr_data[9] >> 17 & 0x3f; fe_status[4][5] = hdr_data[9] >> 11 & 0x3f; fe_status[4][6] = hdr_data[9] >> 5 & 0x3f; fe_status[4][7] = (hdr_data[9] << 1 & 0x3e) | (hdr_data[10] >> 31 & 0x1); fe_status[4][8] = hdr_data[10] >> 25 & 0x3f; fe_status[4][9] = hdr_data[10] >> 19 & 0x3f; fe_status[4][10] = hdr_data[10] >> 13 & 0x3f; fe_status[4][11] = hdr_data[10] >> 7 & 0x3f; fe_status[5][0] = hdr_data[6] >> 25 & 0x3f; fe_status[5][1] = hdr_data[6] >> 19 & 0x3f; fe_status[5][2] = hdr_data[6] >> 13 & 0x3f; fe_status[5][3] = hdr_data[6] >> 7 & 0x3f; fe_status[5][4] = hdr_data[6] >> 1 & 0x3f; fe_status[5][5] = (hdr_data[6] << 5 & 0x20) | (hdr_data[7] >> 27 & 0x1f); fe_status[5][6] = hdr_data[7] >> 21 & 0x3f; fe_status[5][7] = hdr_data[7] >> 15 & 0x3f; fe_status[5][8] = hdr_data[7] >> 9 & 0x3f; fe_status[5][9] = hdr_data[7] >> 3 & 0x3f; fe_status[5][10] = (hdr_data[7] << 3 & 0x38) | (hdr_data[8] >> 29 & 0x07); fe_status[5][11] = hdr_data[8] >> 23 & 0x3f; fe_status[6][0] = hdr_data[3] >> 9 & 0x3f; fe_status[6][1] = hdr_data[3] >> 3 & 0x3f; fe_status[6][2] = (hdr_data[3] << 3 & 0x38) | (hdr_data[4] >> 29 & 0x7); fe_status[6][3] = hdr_data[4] >> 23 & 0x3f; fe_status[6][4] = hdr_data[4] >> 17 & 0x3f; fe_status[6][5] = hdr_data[4] >> 11 & 0x3f; fe_status[6][6] = hdr_data[4] >> 5 & 0x3f; fe_status[6][7] = (hdr_data[4] << 1 & 0x3e) | (hdr_data[5] >> 31 & 0x1); fe_status[6][8] = hdr_data[5] >> 25 & 0x3f; fe_status[6][9] = hdr_data[5] >> 19 & 0x3f; fe_status[6][10] = hdr_data[5] >> 13 & 0x3f; fe_status[6][11] = hdr_data[5] >> 7 & 0x3f; fe_status[7][0] = hdr_data[1] >> 25 & 0x3f; fe_status[7][1] = hdr_data[1] >> 19 & 0x3f; fe_status[7][2] = hdr_data[1] >> 13 & 0x3f; fe_status[7][3] = hdr_data[1] >> 7 & 0x3f; fe_status[7][4] = hdr_data[1] >> 1 & 0x3f; fe_status[7][5] = (hdr_data[1] << 5 & 0x20) | (hdr_data[2] >> 27 & 0x1f); fe_status[7][6] = hdr_data[2] >> 21 & 0x3f; fe_status[7][7] = hdr_data[2] >> 15 & 0x3f; fe_status[7][8] = hdr_data[2] >> 9 & 0x3f; fe_status[7][9] = hdr_data[2] >> 3 & 0x3f; fe_status[7][10] = (hdr_data[2] << 3 & 0x38) | (hdr_data[3] >> 29 & 0x07); fe_status[7][11] = hdr_data[3] >> 23 & 0x3f; printf("L1A nr = %6d ($%05x) \n", l1a, l1a); printf("FE Nr \tAddr $ \tFibre APV Status $\n"); printf("\t\t12 11 10 9 8 7 6 5 4 3 2 1\n"); for (int i=0; i<8; i++) { // fe fpgas printf("%d \t%02x \t", 8-i, fe_pipeaddr[i]); for (int j=0; j<12; j++) { // fibres printf("%02x ", fe_status[i][j]); } printf("\n"); } return 0; } const char* tts_status[16] = { "Disconnected", "WARNING OVERFLOW", "OUT OF SYNC", "Undefined", "BUSY", "Undefined", "Undefined", "Undefined", "READY", "Undefined", "Undefined", "Undefined", "Error", "Undefined", "Undefined", "Disconnected" }; int FFv1Object::DisplayBEStatusTWO(int verbosity) { // TTS status and BX Ctr Terminal value (at new Orbit) plus additional Buffer Flags are stored in 2nd BE Status register const int num_words = 3; unsigned long int data[num_words]; unsigned int dummy; unsigned int tts, bx_term; BECommand(29, 1, &dummy, verbosity); // get all bits from serial memory for (int i=0 ; i> 11 & 0xf; bx_term = (data[1] << 1 & 0xfff) | (data[2] >> 31); printf(" TTS bits = $%1x ; ", tts); printf("TTS status = %s \n", tts_status[tts]); printf(" Bx Ctr Value at New Orbit = $%03x (%d)\n", bx_term, bx_term); return 0; } /********************************************************************************/ //adapted from James Leaver's code void FFv1Object::ReadEPROMData() { unsigned int ReadDataArray[2048]; // Get data // Read FED Industry Test results from EPROM unsigned long int offset = INDUSTRY_RESULTS_OFFSET; for(unsigned long byte_num = 0; byte_num < (unsigned long) INDUSTRY_NUM_RESULT_BYTES; byte_num++) { ReadSerialEPROM(offset, &ReadDataArray[byte_num], 1); offset++; } // Form results string stringstream read_results_ss; string read_results(""); unsigned long int serial_number(0); unsigned long int enter_fed_parameters_status(0); unsigned long int digital_tests_status(0); unsigned long int analog_tests_status(0); string test_status(""); unsigned long int year(0); unsigned long int month(0); unsigned long int day(0); unsigned long int hour(0); unsigned long int minute(0); unsigned long int second(0); serial_number = ((ReadDataArray[0] & 0xFF) * 10 ) + ((ReadDataArray[1] & 0xFF) / 10); enter_fed_parameters_status = (ReadDataArray[1] & 0xFF) % 10 ; digital_tests_status = (ReadDataArray[2] & 0xFF) / 10 ; analog_tests_status = (ReadDataArray[2] & 0xFF) % 10 ; year = ((ReadDataArray[3] & 0xFF) * 100) + (ReadDataArray[4] & 0xFF) ; month = ReadDataArray[5] & 0xFF ; day = ReadDataArray[6] & 0xFF ; hour = ReadDataArray[7] & 0xFF ; minute = ReadDataArray[8] & 0xFF ; second = ReadDataArray[9] & 0xFF ; // read_results_ss << "\n" << " FED Industry Test results read from EPROM:" << "\n" << "\n"; read_results_ss << " FED serial number : " << setw(3) << setfill('0') << serial_number << "\n\n"; // if(enter_fed_parameters_status == 1) { test_status = "FAIL"; } else if(enter_fed_parameters_status == 2) { test_status = "PASS"; } else { test_status = "UNATTEMPTED"; } read_results_ss << " Enter FED Parameters: " << test_status << "\n"; // if(digital_tests_status == 1) { test_status = "FAIL"; } else if(digital_tests_status == 2) { test_status = "PASS"; } else { test_status = "UNATTEMPTED"; } read_results_ss << " Digital Tests : " << test_status << "\n"; // if(analog_tests_status == 1) { test_status = "FAIL"; } else if(analog_tests_status == 2) { test_status = "PASS"; } else { test_status = "UNATTEMPTED"; } read_results_ss << " Analog Tests : " << test_status << "\n"; // read_results_ss << " Date of Results : " << setw(4) << setfill('0') << year << "/" << setw(2) << setfill('0') << month << "/" << setw(2) << setfill('0') << day << " - " << setw(2) << setfill('0') << hour << ":" << setw(2) << setfill('0') << minute << ":" << setw(2) << setfill('0') << second << "\n\n"; read_results = read_results_ss.str(); cout << read_results; return; } // Test Fake Frame Data from Oz int FFv1Object::EnableFakeEventData(int fe_nr, int verbosity) { unsigned int data = 0x1; // bit 1 enables fake frames (NB SIDE EFFECT disables other super modes) FECommand(fe_nr, 30, 0, &data, verbosity); return 0; } int FFv1Object::LoadFakeEventData(int fe_nr, int fibre_nr, int apv_reorder, int tick_only, int verbosity) { // if (fibre_nr == 0) { // for (int fibre_nr = 1; fibre_nr <= fibre_max; fibre_nr++) { // printf("Loading Fake Data for Fibre nr = %d \n", fibre_nr); if (fibre_nr == 12) { for (int fibre_nr = 0; fibre_nr < 12; fibre_nr++) { printf("Loading Fake Data for Ram nr = %d \n", fibre_nr); LoadFakeData(fe_nr, fibre_nr, apv_reorder, tick_only, verbosity); } } else { // printf("Loading Fake Data for Fibre nr = %d \n", fibre_nr); printf("Loading Fake Data for RAM nr = %d \n", fibre_nr); LoadFakeData(fe_nr, fibre_nr, apv_reorder, tick_only, verbosity); } return 0; } int FFv1Object::DumpFakeEventData(int fe_nr, int fibre_nr, int verbosity) { DumpFakeData(fe_nr, fibre_nr, verbosity); return 0; } const unsigned int fakemax = 284; unsigned int fakedata[fakemax]; int FFv1Object::LoadFakeData(int fe_nr, int fibre_nr, int apv_reorder, int tick_only, int verbosity) { unsigned int addr; unsigned int data; // unsigned int data_high = 1023; // unsigned int data_low = 0; // unsigned int data_hit = 150; // unsigned int data_baseline = 0; unsigned int ram_nr; unsigned int* fakep; unsigned char mystr[512]; // single apv output order indexed by strip nr ; this is what the FED FE does ! /* unsigned int apv_to_strip_order[128] = { 0, 16, 32, 48, 64, 80, 96, 112, 4, 20, 36, 52, 68, 84, 100, 116, 8, 24, 40, 56, 72, 88, 104, 120, 12, 28, 44, 60, 76, 92, 108, 124, 1, 17, 33, 49, 65, 81, 97, 113, 5, 21, 37, 51, 69, 85, 101, 117, 9, 25, 41, 55, 73, 89, 105, 121, 13, 29, 45, 59, 77, 93, 109, 125, 2, 18, 34, 50, 66, 82, 98, 114, 6, 22, 38, 54, 70, 86, 102, 118, 10, 26, 42, 58, 74, 90, 106, 122, 14, 30, 46, 62, 78, 94, 110, 126, 3, 19, 35, 51, 67, 83, 99, 115, 7, 23, 39, 55, 71, 87, 103, 119, 11, 27, 43, 59, 75, 91, 107, 123, 15, 31, 47, 63, 79, 95, 111, 127}; */ fakep = fakedata; for (unsigned int i=0; i Couldn't open Fake Data File = 'fakedata.txt'\n"); return 1; } if (verbosity > 1) printf("Opened Fake Data File... \n"); while (!feof(fakedata_file)) { // fscanf(fakedata_file, "%d\n", (unsigned int *) fakep); fscanf(fakedata_file, "%d # %s\n", (unsigned int *) fakep, mystr); // printf("read %08x\n", *fakep); fakep++; } /* for (unsigned int i=0; i 1) printf("fe = %d, ram_nr = %d, addr = %04x , data = %d\n", fe_nr, ram_nr, addr, data); WriteFakeAddr(fe_nr, &addr, verbosity); WriteFakeData(fe_nr, &data, verbosity); addr = (((ram_nr/2) & 0x7) << 13) | FakeTickLevel; data = fakedata[1]; printf("FAKE TICK : fe = %d, ram_nr = %d, addr = %04x , data = %d\n", fe_nr, ram_nr, addr, data); WriteFakeAddr(fe_nr, &addr, verbosity); WriteFakeData(fe_nr, &data, verbosity); addr = (((ram_nr/2) & 0x7) << 13) | FakeLowerPhase; data = fakedata[2]; if (verbosity > 1) printf("fe = %d, ram_nr = %d, addr = %04x , data = %d\n", fe_nr, ram_nr, addr, data); WriteFakeAddr(fe_nr, &addr, verbosity); WriteFakeData(fe_nr, &data, verbosity); addr = (((ram_nr/2) & 0x7) << 13) | FakeUpperPhase; data = fakedata[3]; if (verbosity > 1) printf("fe = %d, ram_nr = %d, addr = %04x , data = %d\n", fe_nr, ram_nr, addr, data); WriteFakeAddr(fe_nr, &addr, verbosity); WriteFakeData(fe_nr, &data, verbosity); addr = (((ram_nr/2) & 0x7) << 13) | FakeFrameInterval; data = fakedata[4]; if (verbosity > 1) printf("fe = %d, ram_nr = %d, addr = %04x , data = %d\n", fe_nr, ram_nr, addr, data); WriteFakeAddr(fe_nr, &addr, verbosity); WriteFakeData(fe_nr, &data, verbosity); addr = (((ram_nr/2) & 0x7) << 13) | FakeFrameRepetition; data = fakedata[5]; if (verbosity > 1) printf("fe = %d, ram_nr = %d, addr = %04x , data = %d\n", fe_nr, ram_nr, addr, data); WriteFakeAddr(fe_nr, &addr, verbosity); WriteFakeData(fe_nr, &data, verbosity); } if (tick_only) { // optional skip loading of RAMs (as they don't get cleared on VME reset, other registers like tick level do get reset) } else { // Frame Data for each fibre... // base address for auto incrementing in RAM for a given fibre addr = (((ram_nr/2) & 0x7) << 13) | (((ram_nr%2) & 0x1) << 9); printf("FAKE : ram_nr = %d ; base addr = $%04x \n", ram_nr, addr); WriteFakeAddr(fe_nr, &addr, verbosity); // digital headers (skipping ticks) WriteFakeData(fe_nr, &fakedata[6], verbosity); WriteFakeData(fe_nr, &fakedata[7], verbosity); WriteFakeData(fe_nr, &fakedata[8], verbosity); WriteFakeData(fe_nr, &fakedata[9], verbosity); // pipe addr = 8 WriteFakeData(fe_nr, &fakedata[10], verbosity); WriteFakeData(fe_nr, &fakedata[11], verbosity); WriteFakeData(fe_nr, &fakedata[12], verbosity); WriteFakeData(fe_nr, &fakedata[13], verbosity); WriteFakeData(fe_nr, &fakedata[14], verbosity); WriteFakeData(fe_nr, &fakedata[15], verbosity); WriteFakeData(fe_nr, &fakedata[16], verbosity); WriteFakeData(fe_nr, &fakedata[17], verbosity); WriteFakeData(fe_nr, &fakedata[18], verbosity); WriteFakeData(fe_nr, &fakedata[19], verbosity); WriteFakeData(fe_nr, &fakedata[20], verbosity); WriteFakeData(fe_nr, &fakedata[21], verbosity); WriteFakeData(fe_nr, &fakedata[22], verbosity); WriteFakeData(fe_nr, &fakedata[23], verbosity); // Added by James (pipeline addr is 16 long) WriteFakeData(fe_nr, &fakedata[24], verbosity); WriteFakeData(fe_nr, &fakedata[25], verbosity); // WriteFakeDataMultiple(fe_nr, &fakedata[10], 16, 0); // test multiple string commands WriteFakeData(fe_nr, &fakedata[26], verbosity); WriteFakeData(fe_nr, &fakedata[27], verbosity); // strip data (NB need to put in apv order or strip order according to FE mode) // same value on each strip for now... // Ramp data test /* // data = fibre_nr * 10; data = ram_nr * 10; for (int strip=0; strip 1) printf("fe = %d, fibre = %d, addr = %04x \n", fe_nr, fibre_nr, addr); printf("Offset (addr = $%04x ) = %d\n", addr, data); addr = (((ram_nr/2) & 0x7) << 13) | FakeTickLevel; WriteFakeAddr(fe_nr, &addr, verbosity); ReadFakeData(fe_nr, &data, verbosity); if (verbosity > 1) printf("fe = %d, ram_nr = %d, addr = %04x \n", fe_nr, ram_nr, addr); printf("Tick Level (addr = $%04x ) = %d\n", addr, data); addr = (((ram_nr/2) & 0x7) << 13) | FakeLowerPhase; WriteFakeAddr(fe_nr, &addr, verbosity); ReadFakeData(fe_nr, &data, verbosity); if (verbosity > 1) printf("fe = %d, ram_nr = %d, addr = %04x \n", fe_nr, ram_nr, addr); printf("Lower Phase (addr = $%04x ) = %d\n", addr, data); addr = (((ram_nr/2) & 0x7) << 13) | FakeUpperPhase; WriteFakeAddr(fe_nr, &addr, verbosity); ReadFakeData(fe_nr, &data, verbosity); if (verbosity > 1) printf("fe = %d, ram_nr = %d, addr = %04x \n", fe_nr, ram_nr, addr); printf("Upper Phase (addr = $%04x ) = %d\n", addr, data); addr = (((ram_nr/2) & 0x7) << 13) | FakeFrameInterval; WriteFakeAddr(fe_nr, &addr, verbosity); ReadFakeData(fe_nr, &data, verbosity); if (verbosity > 1) printf("fe = %d, ram_nr = %d, addr = %04x \n", fe_nr, ram_nr, addr); printf("Frame Interval (addr = $%04x ) = %d\n", addr, data); addr = (((ram_nr/2) & 0x7) << 13) | FakeFrameRepetition; WriteFakeAddr(fe_nr, &addr, verbosity); ReadFakeData(fe_nr, &data, verbosity); if (verbosity > 1) printf("fe = %d, ram_nr = %d, addr = %04x \n", fe_nr, ram_nr, addr); printf("Frame Repetition (addr = $%04x ) = %d\n", addr, data); } // Frame Data... // base address for auto incrementing in RAM for a given fibre addr = (((ram_nr/2) & 0x7) << 13) | (((ram_nr%2) & 0x1) << 9); if (verbosity > 1) printf("ram_nr = %d ; base addr = $%04x \n", ram_nr, addr); WriteFakeAddr(fe_nr, &addr, verbosity); // digital headers (skipping ticks) /****************************************************************/ /* Additions by James: we have to increment the address counter */ /* each time that we read fake data from the FED */ /****************************************************************/ for (int i=0; i<22; i++) { ReadFakeData(fe_nr, &data, verbosity); printf("Header sample = %d ; addr = $%04x ; value = %d \n", i, addr, data); /*****/ addr++; WriteFakeAddr(fe_nr, &addr, verbosity); /*****/ } // strip data has interleaved APV frames (NB need to put frames in apv order or strip order according to FE mode) int maxdump = 256; printf("Only dumping first %d Data samples... \n", maxdump); for (int strip=0; strip 3) printf("i = %d, data = %d, \n", i, *data); ram_data = *data++<<(32-10); if (verbosity > 3) printf("ram_data = $%08x \n", ram_data); // usleep(0); // added 03.08.05 ; this cured loading and readback of RAM data; needed at RAL 01.02.2006 fed_cmd = fedCmd(fe_nr, 28, 10, 0); CheckSerialStatus(fed_cmd, 0); ffv1SingleWrite(fed_cmd, FED_Serial_BRAM/4 + i*(ngaps+2) + 0); // fill cmd string in buffer ffv1SingleWrite(ram_data, FED_Serial_BRAM/4 + i*(ngaps+2) + 1); for (int j=0; j 1 ) printf("fe nr = %d ; set super mode = %d \n", fe_nr, mode); FECommand(fe_nr, 30, 0, &mode, verbosity); // usleep(1); // debugging return 0; } int FFv1Object::VMEWriteLoop(unsigned int offset, unsigned int data, unsigned int loops) { { // char choice=-1; // string temp; // do { // cin>>temp; // choice=temp[0]; // temp.erase(); // choice=tolower(choice); // if(choice == 'q') break; for (unsigned int i=0; i>temp; // choice=temp[0]; // temp.erase(); // choice=tolower(choice); // if(choice == 'q') break; for (unsigned int i=0; i max_tries) break; } while (fed_status != 0xffffffff); if (tries > max_tries) { printf("ERROR : Serial Command Line was BUSY for %d attempts for fed_cmd = $%08x\n", tries, fed_cmd); // exit(1); return 1; } return 0; } #endif // _FFv1Object_hh_