/** * @author Ian Johnson * @version 1.0 */ #include #include #include #include #include #include #include #include "EigerRegisterDefs.h" #include "Eiger.h" using namespace std; //GetDAQStatusRegister(512,current_mode_bits_from_fpga)){ const unsigned int Module::ndacs = 16; const string Module::dac_names[16] = {"SvP","Vtr","Vrf","Vrs","SvN","Vtgstv","Vcmp_ll","Vcmp_lr","cal","Vcmp_rl","rxb_rb","rxb_lb","Vcmp_rr","Vcp","Vcn","Vis"}; Module::Module(unsigned int number, unsigned int address_top){ module_number = number; top_address_valid = 1; top_left_address = 0x100 | (0xff & address_top); top_right_address = 0x200 | (0xff & address_top); bottom_address_valid = 0; bottom_left_address = 0; bottom_right_address = 0; high_voltage = -1; top_dac = new float [ndacs]; bottom_dac = new float [ndacs]; for(unsigned int i=0;iGetModuleNumber()); ReadSetUpFile(modules[i]->GetModuleNumber(),st); } return CheckSetup(); } bool Eiger::ReadSetUpFileToAddModules(string file_name){ static ifstream infile; static string line; static char cmd_st[2000]; static int value_i[3]; infile.open(file_name.c_str(),ios::in); if(!infile.is_open()) return 0; cout<>cmd_st; if(!strcmp("add_module",cmd_st)){ if(!(iss>>value_i[0]>>value_i[1]>>value_i[2])){ cout<<"Error adding module from "<>value_i[0]>>value_i[1])){ cout<<"Error adding half module from "<TopAddressIsValid()){ feb_list[nfebs++] = modules[i]->GetTopRightAddress(); feb_list[nfebs++] = modules[i]->GetTopLeftAddress(); } if(modules[i]->BottomAddressIsValid()){ feb_list[nfebs++] = modules[i]->GetBottomRightAddress(); feb_list[nfebs++] = modules[i]->GetBottomLeftAddress(); } } SendCompleteFebList(nfebs,feb_list); delete [] feb_list; cout<GetModuleNumber()<<" "; if(modules[i]->TopAddressIsValid()) cout<GetTopBaseAddress()<<" (top) "<BottomAddressIsValid()) cout<GetBottomBaseAddress()<<" (bottom)"<GetModuleNumber()==module_number){ module_index=i; return 1; } } return 0; } bool Eiger::CheckModuleAddresses(unsigned int top_address, unsigned int bottom_address){ bool found_t = 0; bool found_b = 0; for(unsigned int i=0;iGetTopBaseAddress() || top_address==modules[i]->GetBottomBaseAddress())) found_t=1; if(bottom_address!=0 && (bottom_address==modules[i]->GetTopBaseAddress() || bottom_address==modules[i]->GetBottomBaseAddress())) found_b=1; } if(top_address==bottom_address) cout<<"\tWarning: top and bottom address are the same "<>cmd_st; if(cmd_st[0]=='#'||!strcmp("add_module",cmd_st)||!strcmp("add_half_module",cmd_st)){ ;// cout<<"do nothing "<>value_i[0])) cout<<"Error reading iodelay from "<>value_f; SetHighVoltage(module_num,value_f); }else if(!strcmp("photon_energy",cmd_st)){ iss>>value_f; SetPhotonEnergy(value_f); }else if(!strcmp("dynamic_range",cmd_st)){ iss>>value_i[0]; SetDynamicRange(value_i[0]); }else if(!strcmp("readout_speed",cmd_st)){ iss>>value_i[0]; SetReadoutSpeed(value_i[0]); }else if(!strcmp("readout_mode",cmd_st)){ iss>>value_i[0]; SetReadoutMode(value_i[0]); }else{ iss>>value_f; if(module_num>0) sprintf(cmd_st,"mod%d::%s",module_num,cmd_st); if(!SetDAC(cmd_st,value_f)) cout<<"error in string: "<GetTopIDelay(j)<0){ cout<<"Warning: module "<GetModuleNumber()<<"'s idelay top number "<GetBottomIDelay(j)<0){ cout<<"Warning: module "<GetModuleNumber()<<"'s idelay bottom number "<GetHighVoltage()<0){ cout<<"Warning: module "<GetModuleNumber()<<"'s high voltage not set."<GetTopDACVoltage(j)<0){ cout<<"Warning: module "<GetModuleNumber()<<"'s top \""<GetBottomDACVoltage(j)<0){ cout<<"Warning: module "<GetModuleNumber()<<"'s bottom \""<TopAddressIsValid()) n_half_modules++; if(modules[i]->BottomAddressIsValid()) n_half_modules++; } return n_half_modules; } bool Eiger::SetPhotonEnergy(unsigned int full_energy_eV){ photon_energy_eV = full_energy_eV; cout<<"Setting photon energy to: "<3){ cout<<"Error SetIDelay chip_pos "<TopAddressIsValid()){ if(SendIDelays(modules[module_index]->GetTopLeftAddress(),chip_pos%2==0,0xffffffff,ndelay_units)){ if(module_index!=0) modules[module_index]->SetTopIDelay(chip_pos,ndelay_units); else for(unsigned int i=0;iSetTopIDelay(chip_pos,ndelay_units); }else{ cout<<"Error could not set idelay module number "<BottomAddressIsValid()){ if(SendIDelays(modules[module_index]->GetBottomLeftAddress(),chip_pos%2==0,0xffffffff,ndelay_units)){ if(module_index!=0) modules[module_index]->SetBottomIDelay(chip_pos,ndelay_units); else for(unsigned int i=0;iSetBottomIDelay(chip_pos,ndelay_units); }else{ cout<<"Error could not set idelay module number "<TopAddressIsValid()){ if(SendIDelays(modules[module_index]->GetTopRightAddress(),chip_pos%2==0,0xffffffff,ndelay_units)){ if(module_index!=0) modules[module_index]->SetTopIDelay(chip_pos,ndelay_units); else for(unsigned int i=0;iSetTopIDelay(chip_pos,ndelay_units); }else{ cout<<"Error could not set idelay module number "<BottomAddressIsValid()){ if(SendIDelays(modules[module_index]->GetBottomRightAddress(),chip_pos%2==0,0xffffffff,ndelay_units)){ if(module_index!=0) modules[module_index]->SetBottomIDelay(chip_pos,ndelay_units); else for(unsigned int i=0;iSetBottomIDelay(chip_pos,ndelay_units); }else{ cout<<"Error could not set idelay module number "<0x3ff) ndelay_units=0x3ff; // this is global unsigned int delay_data_valid_nclks = 15 - ((ndelay_units&0x3c0)>>6); //data valid delay upto 15 clks ndelay_units &= 0x3f; //up to 64 delay units // ndelay_unit |= 0x40; //and one bit for a full clock delay for the enabled pixels is zero for now unsigned int set_left_delay_channels = chip_lr ? channels:0; unsigned int set_right_delay_channels = chip_lr ? 0:channels; cout<<"\tSetting delays of "; if(set_left_delay_channels!=0) cout<<"left chips of dst_num "<vmax) return 0; digital = int(((value-vmin)/(vmax-vmin))*(nsteps-1) + 0.5); return 1; } float Eiger::DACToVoltage(unsigned int digital,unsigned int nsteps,float vmin,float vmax){ return vmin+(vmax-vmin)*digital/(nsteps-1); } bool Eiger::SetHighVoltage(unsigned int module_num,float value){ unsigned int module_index=0; if(!GetModuleIndex(module_num,module_index)||!modules[module_index]->TopAddressIsValid()){ cout<<"Error could not set high voltage module number "<GetTopRightAddress(),value)) return 0; if(module_index!=0) modules[module_index]->SetHighVoltage(value); else for(unsigned int i=0;iSetHighVoltage(value); cout<<"\tHigh voltage of dst "<GetTopRightAddress()<<" set to "<GetHighVoltage()<<"."<TopAddressIsValid()){ float v = value; if(!SendDACValue(modules[module_index]->GetTopRightAddress(),dac_ch,v)) return 0; if(module_index!=0) modules[module_index]->SetTopDACVoltage(dac_ch,v); else for(unsigned int i=0;iSetTopDACVoltage(dac_ch,v); } if(bottom&&modules[module_index]->BottomAddressIsValid()){ float v = value; if(!SendDACValue(modules[module_index]->GetBottomRightAddress(),dac_ch,v)) return 0; if(module_index!=0) modules[module_index]->SetBottomDACVoltage(dac_ch,v); else for(unsigned int i=0;iSetBottomDACVoltage(dac_ch,v); } return 1; } bool Eiger::GetDAC(std::string s, float& ret_value){ cout<<"Function Eiger::GetDAC need to be finished....."<=Module::ndacs){ cout<<"Warning: Eiger::GetDACName index out of range, "<15){ cout<<"Warning invalid ch for SetDAC."<>3)<<((7-i)*4);//upper trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[263679 - (row_set*16480+super_column_start_position_r+i)])<<((7-i)*4);//low trimbits_to_load_r[offset+chip_sc+32] |= ((0x38 & trimbits[263679 - (row_set*16480+super_column_start_position_r+i)])>>3)<<((7-i)*4);//upper } } } if(!WriteMemory(0,0,0,1024,trimbits_to_load_r)||!WriteMemory(1,0,0,1024,trimbits_to_load_l)||!StartDAQOnlyNWaitForFinish()) return 0; } } memcpy(last_downloaded_trimbits,trimbits,trimbit_size*sizeof(unsigned char)); return SetStaticBits(); //send the static bits } unsigned char* Eiger::GetTrimbits(){ return last_downloaded_trimbits; } bool Eiger::SetCommandRegister(unsigned int cmd){ // if(fifo_enabled){ // return WriteRegister(-1,DAQ_REG_CHIP_CMDS,cmd | DAQ_FIFO_ENABLE); // } return WriteRegister(0xfff,DAQ_REG_CHIP_CMDS,cmd); } bool Eiger::GetDAQStatusRegister(int socket_num, unsigned int &ret_status){ if(!ReadRegister(socket_num,DAQ_REG_STATUS,ret_status)){ cout<<"Error: reading status register."<> 16; return 1; } bool Eiger::StartDAQOnlyNWaitForFinish(int sleep_time_us){ if(!WriteRegister(0xfff,DAQ_REG_CTRL,0)||!WriteRegister(0xfff,DAQ_REG_CTRL,DAQ_CTRL_START)){ cout<<"Warning: could not start."<full,1->half,2->quarter or 3->super_slow acquireNReadoutMode &= (~DAQ_CHIP_CONTROLLER_SUPER_SLOW_SPEED); if(readout_speed==1){ acquireNReadoutMode |= DAQ_CHIP_CONTROLLER_HALF_SPEED; cout<<"Everything at half speed, ie. reading with 50 MHz main clk (half speed) ...."<parallel,1->non-parallel,2-> safe_mode acquireNReadoutMode &= (~DAQ_NEXPOSURERS_PARALLEL_MODE); if(readout_mode==1){ acquireNReadoutMode |= DAQ_NEXPOSURERS_NORMAL_NONPARALLEL_MODE; cout<<"Readout mode set to normal non-parallel readout mode ... "< internal exposure time and period, //"01"-> external acquistion start and internal exposure time and period, //"10"-> external start trigger and internal exposure time, //"11"-> external triggered start and stop of exposures triggerMode = (~DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START_AND_STOP); if(trigger_mode == 1){ triggerMode = DAQ_NEXPOSURERS_EXTERNAL_ACQUISITION_START; cout<<"Trigger mode: external start of acquisition sequence, internal exposure length and period."<(pow(2,29)-1)*pow(10,7)){ float max_time = 10e-9*(pow(2,28)-1)*pow(10,7); cout<<"Warning: time exceeds ("<pow(2,29)-1){ power_of_ten++; n_clk_cycles = round(n_clk_cycles/10.0);} decoded_time = int(n_clk_cycles)<<3 | int(power_of_ten); } return decoded_time; } bool Eiger::ResetDataStream(){ //for(int i=0;i<10;i++) cout<<"Warning need to think about reseting data stream ...."<