///////////////////////////////////////////////////////////////// // // // FF1 VME interface debugging tool // // // // Author: Matt Noy // // date: 21/03/2003 // // notes: // // // // // ///////////////////////////////////////////////////////////////// // added fed specific methods by jac starting 06.05.2003 #ifndef _FFv1Object_hh_ #define _FFv1Object_hh_ #include "StopWatch.hh" //#include "VMEDummyBusAdapter.hh" #include "VMEBusAdapterInterface.hh" #ifdef BUILD_NIVXI #include "MXI2x86LinuxBusAdapter_test.hh" #else #include "SBS620x86LinuxBusAdapter.hh" #endif #include "VMEAddressTableASCIIReader.hh" #include "VMEDevice.hh" #include "VMEAddressTable.hh" #include #include #include #include // 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_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 = 0x1EE0000; // assumes FED in slot 18 so offset from 12'0000 // 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 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 FILE *output_file; FILE *cf_image_file; FILE *readout_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; const int eprom_max = 2*1024; //const unsigned int eprom_max = 1024; //unsigned int data[eprom_max]; const unsigned int header_len = 34; // in 32 bit words const unsigned int trailer_len = 2; // ignoring dummy tracker trailer unsigned int fibre_thresh_calc[chan_max]; // calculated threshold from 1st event ; 0-15 (* 32 adc counts) unsigned int fibre_ped_calc[chan_max]; // for present will assume pedestal is SAME for all strips on fibre 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 coarse, int fine); 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); 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); 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 ClearReadoutCSR(int verbosity); int CheckEvent(unsigned long* event_buffer, unsigned long event_length, unsigned int event_nr, int* error, unsigned int trig_nr, int event_format, int stop_flag); 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 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 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 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 verbosity); int WriteFibrePedestals(int chip, unsigned int* data, int mode, int verbosity); int ReadFibrePedestals(int chip, unsigned int* data, 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, int verbosity); int TestReadoutFromFile(int verbosity, int event_format, int event_nr, int endian_swap); int ReadDelayFPGAID(int fe_chip, int delay_chip, unsigned long* fpga_id); 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 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=0) { 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" << '\n'; 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, 0x0); // fill cmd string in buffer ffv1SingleWrite(fed_data, 0x1); // data is irrelevant ffv1SingleWrite(2, 0x200); // send cmd string 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; ffv1SingleWrite(fed_cmd, 0x201); // sends read cmd usleep(100); unsigned long fed_data = *data; ffv1SingleRead(&fed_data, 0x0); // 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; ffv1SingleWrite(fed_cmd, 0x201); // sends read cmd usleep(100); unsigned long fed_data = *data; ffv1SingleRead(&fed_data, 0x0); // 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 coarse, int fine) { // // CDC dial thru command cout << dec << "FE Chip # " << fe_chip << " Delay chip # " << delay_chip << " Coarse = " << coarse << " Fine = " << fine << '\n'; 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 // printf("enter cdc cmd length => " ); // cin >> cdc_len; // printf("enter total cmd length => " ); // cin >> tot_len; 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); unsigned int cdc_cmd = cdcCmd(delay_chip, 0x01, cdc_len); unsigned int fed_data1 = cdc_cmd | coarse << 1 | fine >> 4; unsigned int fed_data2 = fine << 28 | coarse << 24 | fine << 19 | coarse << 15 | fine << 10 | coarse << 6 | fine << 1; cout << "fed_cmd = $ " << hex << fed_cmd << " ; fed_data1 = $ " << fed_data1 << " ; fed_data2 = $ " << fed_data2 << '\n'; ffv1SingleWrite(fed_cmd, 0x0); // fill cmd string in buffer ffv1SingleWrite(fed_data1, 0x1); // cdc cmd and data ffv1SingleWrite(fed_data2, 0x2); ffv1SingleWrite(0, 0x3); // 26.09.03 ; clear next word to avoid hangup in serial decoder (this stops every second command being ignored!) ffv1SingleWrite(3, 0x200); // send cmd string return 0; } int FFv1Object::SpyArm(int fe_chip, int delay_chip) { // // CDC dial thru command cout << dec << "FE Chip # " << 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'; ffv1SingleWrite(fed_cmd, 0x0); // fill cmd string in buffer ffv1SingleWrite(fed_data, 0x1); // cdc cmd ffv1SingleWrite(0, 0x2); // clear next word to avoid hangup in serial decoder (this stops every second command being ignored!) ffv1SingleWrite(2, 0x200); // 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 # " << 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); 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); // 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 int max_spy_words = 16; 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) { // Displays formatted contents of Serial Memory from response to Spy Fire command for (int i=0; i> j & 0x1; } } printf("Spy Bit Data : \n"); for (int i=0; i 1) cout << dec << "BE Chip cmd code # " << be_code << " R/W = " << be_rw << '\n'; if (be_rw == 0) { fed_cmd = fedCmd(10, be_code, 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'; 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) // readonly regs { fed_cmd = fedCmd(10, be_code, be_cmd_len[be_code], 2); // r_w =2 must add 2 to length command } else { fed_cmd = fedCmd(10, be_code, be_cmd_len[be_code], 1); } ffv1SingleWrite(fed_cmd, FED_Serial_Read/4); // sends read cmd usleep(100); // should check Ser Status register here ffv1SingleRead(&fed_data, FED_Serial_BRAM/4); // readback memory if (be_code >=16 ) // 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); } *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 } return 0; } int FFv1Object::DisplayBEStatus(int flag) { unsigned int l1a_cnt, bx_cnt, unread_frame_cnt, unread_word_cnt, total_frame_cnt; unsigned int be_status, ttc_ready, ttc_chanb_short, ttc_chanb_long; unsigned int fpga_code; 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); cout << "BE 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 << '\n'; } // BECommand(24, 1, &ttc_status, verbosity); BECommand(16, 1, &be_status, 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); 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); printf("16) BE Status = $ %08x\n", (unsigned int) be_status); cout << "17) L1A ctr = " << dec << l1a_cnt << '\n'; cout << "18) BX ctr = " << dec << bx_cnt << '\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 (64) ctr = " << dec << unread_word_cnt << " $ " << hex << unread_word_cnt << '\n'; cout << "20) TTC Ready = $ " << hex << ttc_ready << '\n'; cout << "26) TTC ChanB Long = $ " << hex << ttc_chanb_long << '\n'; cout << "27) TTC ChanB Short = $ " << hex << ttc_chanb_short << '\n'; 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 be_mode, ttc_ctrl, test_reg, fe_enable, be_link, be_enable; unsigned int fed_id; unsigned int dummy = 1; unsigned int verbosity = 0; 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 ttc_ctrl = 0x0; // to avoid compilation warning messages fed_id = 0xfed; if (run_type == 1) { be_mode = 0x01; // scope } else if (run_type == 2 || run_type == 3) { be_mode = 0x02; // ff } else { cout << "Sorry Illegal Run Type " << '\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(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) { 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'; ffv1SingleWrite(fed_cmd, 0x0); // fill cmd string in buffer ffv1SingleWrite(fed_data, 0x1); ffv1SingleWrite(2, 0x200); // 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); } ffv1SingleWrite(fed_cmd, 0x201); // sends read cmd usleep(100); ffv1SingleRead(&fed_data, 0x0); // readback memory if (fe_code == 3 || 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, 0x1); // 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 } 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(2000000); // safe wait for DCMs to lock 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) { 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; // 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 if (first_trigger == 1) printf("=====================================================================================\n"); if (num_secs == 0) num_secs = 10; // 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); } // 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 > 1) cout << "Event Pending: Status = " << dec << readout_status << '\n'; if (verbosity > 1) cout << "Event Number = " << dec << event_number << '\n'; if (verbosity > 1) cout << "Fragment Number = " << dec << fragment_number << '\n'; if (verbosity > 1) cout << "Buffer Size (32 bit words) = " << dec << buffer_length << " $ " << hex << buffer_length << '\n'; if (verbosity > 1) cout << "Total Transferred (32 bit words) = " << dec << total_length << " $ " << hex << total_length << '\n'; event_length += buffer_length; 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; } for (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, unsigned int event_nr, int* error, unsigned int trig_nr, int event_format, int stop_flag) { // FE nr : FE modules 0 - 7 // Fibre nr : Fibres 0 - 11 on each FE // Chan nr : Chans 0 -95 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 fe_data[12][1024]; // code below relies on length of first fibre being zero for (int i=0; i> 24 & 0xf; unsigned int l1a_nr = event_buffer[0] & 0xffffff; unsigned int bx_nr = event_buffer[1] >> 20 & 0xfff; unsigned int 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", (unsigned int) event_nr, (unsigned int) event_length ); if (trig_nr == 1) printf("DAQ Header : L1A Nr = %6d ; Bx Nr = %6d ; Evt Type = %02x ; Fed ID = %4x \n", l1a_nr, bx_nr, (unsigned int) 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 if (l1a_nr != event_nr) { 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; } // tracker header for (int i=0; i<8; i++) { // loop over fe fpgas fe_len[i] = event_buffer[i*4 + 4] >> 16 & 0xffff; // nr of bytes fe_pipeaddr[i] = event_buffer[i*4 + 5] >> 8 & 0xff; fe_status[i][0] = event_buffer[i*4 + 5] >> 2 & 0x3f; fe_status[i][1] = ((event_buffer[i*4 + 4] & 0x3) << 4) | (event_buffer[i*4 + 2] >> 28 & 0xf); fe_status[i][2] = event_buffer[i*4 + 2] >> 22 & 0x3f; fe_status[i][3] = event_buffer[i*4 + 2] >> 16 & 0x3f; fe_status[i][4] = event_buffer[i*4 + 2] >> 10 & 0x3f; fe_status[i][5] = event_buffer[i*4 + 2] >> 4 & 0x3f; fe_status[i][6] = ((event_buffer[i*4 + 2] & 0xf) << 2) | (event_buffer[i*4 + 3] >> 30 & 0x3); fe_status[i][7] = event_buffer[i*4 + 3] >> 24 & 0x3f; fe_status[i][8] = event_buffer[i*4 + 3] >> 18 & 0x3f; fe_status[i][9] = event_buffer[i*4 + 3] >> 12 & 0x3f; fe_status[i][10] = event_buffer[i*4 + 3] >> 6 & 0x3f; fe_status[i][11] = event_buffer[i*4 + 3] & 0x3f; } if (trig_nr == 1) { printf("FE Nr \tLength\tPipe $ \tFE Status Bits $ (0-11) \n"); printf("\t\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\t%d \t\t%02x \t\t", 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", 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", 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 = abs( *it - *(it-1) ); if (diff > ped_diff[chan_nr]) { ped_diff[chan_nr] = diff; } } } if (j<20) printf("%4d ", *it); if (j<20) fprintf(output_file, "%4d ", *it); j++; } printf("\n"); fprintf(output_file, "\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; nwords++; if (nwords%2 != 0) { printf("*** ERROR => Total number of words (32 bit) = %d should be EVEN \n", nwords ); *error = 1; } if (trig_nr == 1) printf("DAQ Trailer : Evt Length = %8d (64 bit words) ; CRC = $ %04x \n", daq_len, daq_crc ); 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("The 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 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); 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 // 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); ffv1SingleWrite(fed_cmd, 0x0); // fill cmd string in buffer ffv1SingleWrite(fed_data, 0x1); ffv1SingleWrite(2, 0x200); // 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); ffv1SingleWrite(fed_cmd, 0x201); // sends read cmd // usleep(100); unsigned long fed_data = *data; ffv1SingleRead(&fed_data, 0x0); // readback memory //cout << "fed_data = $ " << hex << fed_data << '\n'; *data = fed_data >> (32-1); return 0; } int FFv1Object::DisplayFirmwareVersions(FILE* file, int verbosity) { 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); ReadDelayFPGAID(0, 0, &fpga_code_delay); fprintf(file, " DELAY FPGA Fe 0 Delay 0 : vers = $ %08x \n", (unsigned int) fpga_code_delay); 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]; 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 } printf("FE Status \n"); printf("FE nr \tFPGA \t\tMode $ \tScope \tOptoRx \tADC \tFibre\n"); printf("\tCode $ \t\t\tLen \tCtrl $ \tCtrl $ \tEnables $ \n"); for (int fe_nr = 0; fe_nr < fe_max; fe_nr++) { printf("%d \t%08x \t%02x \t%d \t%02x \t%06x \t%06x \n", 8-fe_nr, fpga_code[fe_nr], mode[fe_nr], scope_len[fe_nr], optorx_ctrl[fe_nr],adc_ctrl[fe_nr], fibre_enable[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; // // 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 = fopen( "cf_image.txt", "r" ); if ( cf_image_file == NULL ) { printf( "*** ERROR => Couldn't open Compact Image File = 'cf_image.txt'\n"); return 1; } if (verbosity > 1) printf("Opened CF Image 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) { DisplayFirmwareVersions(output_file, 1); } } if (nr_sectors > 256) nr_sectors = 256; // h/w limit // if (file_flag) fprintf(output_file, "Compact Flash Dump \n"); // if (file_flag) fprintf(output_file, "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(50000); // 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(50000); // 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, "Compact Flash Dump \n"); // fscanf(cf_image_file, "Logical Block Address = $%*04x ; Nr Sectors = %*03d \n"); if (ace_loop == 0) { unsigned int fpga_code_fe[fe_max], fpga_code_be; unsigned long fpga_code_vme; fscanf(cf_image_file, " Firmware Versions \n"); for (int fe_nr = 0; fe_nr < fe_max; fe_nr++) { fscanf(cf_image_file, " FE FPGA nr = %d : vers = $ %08x \n", &fe_nr, &fpga_code_fe[fe_nr]); } fscanf(cf_image_file, " BE FPGA : vers = $ %08x \n", &fpga_code_be); fscanf(cf_image_file, " VME FPGA : vers = $ %08x \n", (unsigned int *) &fpga_code_vme); // fprintf(output_file, " Firmware Versions in Image\n"); // for (unsigned int fe_nr = 0; fe_nr < fe_max; fe_nr++) { // fprintf(output_file, " FE FPGA nr = %d : vers = $ %08x \n", 8-fe_nr, fpga_code_fe[fe_nr]); // } // fprintf(output_file, " BE FPGA : vers = $ %08x \n", fpga_code_be); // fprintf(output_file, " 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(50000); // 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, "LBA = $ %04x \n", (unsigned int *) &dummy); // if (verbosity > 1) fprintf(output_file, "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, "%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(output_file, "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, "\n"); } else { // Hopefully can read some data from the CFlash card! if (file_flag) { // if ((buf > 0) && (buf % 16) == 0) fprintf(output_file, "%03d \n", buf/16); if ((buf % 16) == 0) fprintf(output_file, "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(output_file, "%04x ", (unsigned int) data); // save to file } if (file_flag) fprintf(output_file, "\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 ); // if ( fclose(cf_image_file) != 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::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 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 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 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 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(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(5); 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]; 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); 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 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 (int i=0; i 1) printf("WriteTrimDAC: fe fpga = %02d ; chan = %02d ; value = %02d \n", chip_id, i, value); FECommand(chip_id, 6, 0, &value, verbosity); } } else { value = chan << 8 | (*data & 0xff); if (verbosity > 1) printf("WriteTrimDAC: fe fpga = %02d ; chan = %02d ; value = %02d \n", chip_id, chan, value); FECommand(chip_id, 6, 0, &value, verbosity); } 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(" 0 1 2 3 4 5 6 7 8 9 10 11\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("fibre %d ; thresh = %d \n", 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; ffv1SingleWrite(fed_cmd, 0x0); // fill cmd string in buffer ffv1SingleWrite(fed_data1, 0x1); ffv1SingleWrite(fed_data2, 0x2); ffv1SingleWrite(3, 0x200); // 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); ffv1SingleWrite(fed_cmd, 0x201); // sends read cmd usleep(100); ffv1SingleRead(&fed_data1, 0x0); ffv1SingleRead(&fed_data2, 0x1); // 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", 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("\t0 \t 1\t 2\t 3\t 4\t 5\t 6\t 7\t 8\t 9\t 10\t 11\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", fibre_nr, data[fibre_nr]); } } 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(" \t 0\t 1\t 2\t 3\t 4\t 5\t 6\t 7\t 8\t 9\t 10\t 11\n"); for (int fe_nr=0; fe_nr 1) printf("fibre %d ; start addr = $%08x \n", fibre_nr, (unsigned int) start_addr); fed_cmd = fedCmd(chip, 0xe, 12, 0); ffv1SingleWrite(fed_cmd, 0x0); // fill cmd string in buffer ffv1SingleWrite(start_addr, 0x1); ffv1SingleWrite(2, 0x200); // send cmd string // load same pedestal data for each strip, address autoincrements for pair of fibres // 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 ; start addr = $%08x ; even fibre = %d ; odd fibre = %d \n", fibre_nr, strip_nr, (unsigned int) start_addr, data[fibre_nr], data[fibre_nr+1]); } } return 0; } int FFv1Object::WriteFibrePedestals(int chip, unsigned int* data, int mode, int verbosity) { unsigned int fed_cmd; unsigned long start_addr; unsigned long word1, word2; for (int fibre_nr=0; fibre_nr> 4; // ignore cluster data and valid strip word2 = data[fibre_nr] << 28; if (verbosity > 1) printf("fibre %d ; start addr = $%08x ; word1 = $%08x ; word2 = $%08x \n", fibre_nr, (unsigned int) start_addr, (unsigned int) word1, (unsigned int) word2); fed_cmd = fedCmd(chip, 0xe, 12, 0); // ped address ffv1SingleWrite(fed_cmd, 0x0); // fill cmd string in buffer ffv1SingleWrite(start_addr, 0x1); ffv1SingleWrite(2, 0x200); // send cmd string // load same pedestal data for each strip, address autoincrements for pair of fibres if (mode == 0 || mode == 1 || mode == 5) { for (int strip_nr=0; strip_nr> 4; word2 = strip_nr << 28; } ffv1SingleWrite(word1, 0x1); ffv1SingleWrite(word2, 0x2); // 2 words needed for 36 bits of pedestal data ffv1SingleWrite(3, 0x200); // send cmd string } } // 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; word2 = strip_nr << 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, 0x200); // send stream of command/data packets usleep(10000); } } 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", fibre_nr, data[fibre_nr]); } } 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 Readout File = 'readout_file.txt'\n"); return 1; } if (verbosity > 1) printf("Opened Readout 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); CheckEvent(readout_buffer, nwords, evt_nr, &error, 1, event_format, 0); if (error != 0) { printf("*** ERROR : The format of event in file was BAD. \n"); } else { printf("The format of event in File was GOOD. \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); 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); ffv1SingleRead(&fed_data, 0x0); // readback memory fed_data <<= shift; ffv1SingleRead(&fed_data2, 0x1); // fed_data |= (fed_data2 >> (32-extra)); fed_data |= (fed_data2 >> (32-shift)); *fpga_id = fed_data; return 0; } #endif // _FFv1Object_hh_