/** * @author Ian Johnson * @version 1.0 */ #include #include #include #include #include #include #include #include #include #include #include #include "FebRegisterDefs.h" #include "FebControl.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 int [ndacs]; bottom_dac = new int [ndacs]; for(unsigned int i=0;iGetModuleNumber()); ReadSetUpFile(modules[i]->GetModuleNumber(),st); } return CheckSetup(); } bool FebControl::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(); } } FebInterface::SendCompleteList(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 FebControl::CheckModuleAddresses(Module* m){ bool found_t = 0; bool found_b = 0; for(unsigned int i=0;iTopAddressIsValid() && modules[i]->GetTopBaseAddress() && m->GetTopBaseAddress()==modules[i]->GetTopBaseAddress()) || (m->TopAddressIsValid() && modules[i]->GetBottomBaseAddress() && m->GetTopBaseAddress()==modules[i]->GetBottomBaseAddress())) found_t=1; if((m->BottomAddressIsValid() && modules[i]->GetTopBaseAddress() && m->GetBottomBaseAddress()==modules[i]->GetTopBaseAddress()) || (m->BottomAddressIsValid() && modules[i]->GetBottomBaseAddress() && m->GetBottomBaseAddress()==modules[i]->GetBottomBaseAddress())) found_b=1; } if(found_t) cout<<"\tWarning: top address "<< m->GetTopBaseAddress()<<" already used."<GetBottomBaseAddress()<<" already used."<TopAddressIsValid()&&m->BottomAddressIsValid()&&m->GetTopBaseAddress()==m->GetBottomBaseAddress(); if(top_bottom_same) cout<<"\tWarning: top and bottom address are the same "<GetTopBaseAddress()<<"."<TopAddressIsValid()&&m->BottomAddressIsValid()){ cout<<"\tAdding full module number "<GetModuleNumber()<<" with top and bottom base addresses: "<GetTopBaseAddress()<<" "<GetBottomBaseAddress()<TopAddressIsValid()){ cout<<"\tAdding half module number "<GetModuleNumber()<<" with top base address: "<GetTopBaseAddress()<BottomAddressIsValid()){ cout<<"\tAdding half module number "<GetModuleNumber()<<" with bottom base address: "<GetBottomBaseAddress()<>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,1)) 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."<GetTopDACValue(j)<0){ cout<<"Warning: module "<GetModuleNumber()<<"'s top \""<GetBottomDACValue(j)<0){ cout<<"Warning: module "<GetModuleNumber()<<"'s bottom \""<TopAddressIsValid()) n_half_modules++; if(modules[i]->BottomAddressIsValid()) n_half_modules++; } return n_half_modules; } bool FebControl::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); for(unsigned int i=0;iSetBottomIDelay(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;iSetTopIDelay(chip_pos,ndelay_units); 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; 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 FebControl::DACToVoltage(unsigned int digital,unsigned int nsteps,float vmin,float vmax){ return vmin+(vmax-vmin)*digital/(nsteps-1); } bool FebControl::SetHighVoltage(float value){ return SetHighVoltage(0,value); } bool FebControl::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()<<"."<4095){ cout<<"Waring: SetDac bad value, "<TopAddressIsValid()){ if(!SendDACValue(modules[module_index]->GetTopRightAddress(),dac_ch,v)) return 0; if(module_index!=0) modules[module_index]->SetTopDACValue(dac_ch,v); else for(unsigned int i=0;iSetTopDACValue(dac_ch,v); } if(bottom&&modules[module_index]->BottomAddressIsValid()){ if(!SendDACValue(modules[module_index]->GetBottomRightAddress(),dac_ch,v)) return 0; if(module_index!=0) modules[module_index]->SetBottomDACValue(dac_ch,v); else for(unsigned int i=0;iSetBottomDACValue(dac_ch,v); } return 1; } bool FebControl::GetDAC(std::string s, int& ret_value, bool voltage_mv){ unsigned int module_index, dac_ch; bool top, bottom; if(!DecodeDACString(s,module_index,top,bottom,dac_ch)) return 0; ret_value = top ? modules[module_index]->GetTopDACValue(dac_ch) : modules[module_index]->GetBottomDACValue(dac_ch); if(voltage_mv) ret_value = DACToVoltage(ret_value,4096,0,2048); return 1; } bool FebControl::GetDACName(unsigned int dac_num, std::string &s){ if(dac_num>=Module::ndacs){ cout<<"Warning: FebControl::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(modules[0]->GetTopLeftAddress(),0,0,1024,trimbits_to_load_r)||!WriteMemory(modules[0]->GetTopRightAddress(),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* FebControl::GetTrimbits(){ return last_downloaded_trimbits; } unsigned int FebControl::AddressToAll(){ if(modules.size()==0) return 0; return modules[0]->GetTopLeftAddress()|modules[0]->GetTopRightAddress(); } bool FebControl::SetCommandRegister(unsigned int cmd){ return WriteRegister(AddressToAll(),DAQ_REG_CHIP_CMDS,cmd); } bool FebControl::GetDAQStatusRegister(unsigned int dst_address, unsigned int &ret_status){ if(!ReadRegister(dst_address,DAQ_REG_STATUS,ret_status)){ cout<<"Error: reading status register."<> 16; return 1; } bool FebControl::StartDAQOnlyNWaitForFinish(int sleep_time_us){ if(!WriteRegister(AddressToAll(),DAQ_REG_CTRL,0)||!WriteRegister(AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_START)){ cout<<"Warning: could not start."<GetTopLeftAddress(),status_reg_r)&&GetDAQStatusRegister(modules[i]->GetTopRightAddress(),status_reg_l))){*/ if(!(GetDAQStatusRegister(modules[i]->GetTopLeftAddress(),status_reg_r)||GetDAQStatusRegister(modules[i]->GetTopRightAddress(),status_reg_l))){ for(int i=0;i<2;i++) cout<<"Waring trouble reading status register. Returning zero to avoid inifite loops, this could cause trouble!"<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 FebControl::ResetChipCompletely(){ if(!SetCommandRegister(DAQ_RESET_COMPLETELY) || !StartDAQOnlyNWaitForFinish()){ cout<<"Warning: could not ResetChipCompletely()."<h_addr,(char *)&serv_addr.sin_addr.s_addr,server->h_length); serv_addr.sin_port = htons(port); return 1; } int FebControl::WriteNRead(char* message, int length, int max_length){ int sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd <0){ fprintf(stderr,"ERROR opening socket\n"); return 0; } if(connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0){ fprintf(stderr,"ERROR connecting\n"); return 0; } int n = write(sockfd,message,length); if(n<0) printf("ERROR writing to socket"); length = read(sockfd,message,max_length); if(length<0) printf("ERROR reading to socket"); close(sockfd); return length; } bool FebControl::StartAcquisition(){ static unsigned int reg_nums[20]; static unsigned int reg_vals[20]; PrintAcquisitionSetup(); // if(!Reset()||!ResetDataStream()){ if(!Reset()){ cout<<"Trouble reseting daq or data stream..."<