#include "FebControl.h" #include "FebRegisterDefs.h" #include "slsDetectorServer_defs.h" #include "logger.h" #include "Beb.h" #include #include #include #include #include // POSIX terminal control definitions(CS8, CREAD, CLOCAL..) #include #include //GetDAQStatusRegister(512,current_mode_bits_from_fpga)) { unsigned int Module_ndacs = 16; char Module_dac_names[16][10]={"SvP","Vtr","Vrf","Vrs","SvN","Vtgstv","Vcmp_ll","Vcmp_lr","cal","Vcmp_rl","rxb_rb","rxb_lb","Vcmp_rr","Vcp","Vcn","Vis"}; struct Module modules[10]; int moduleSize = 0; unsigned int Feb_Control_staticBits; //program=1,m4=2,m8=4,test=8,rotest=16,cs_bar_left=32,cs_bar_right=64 unsigned int Feb_Control_acquireNReadoutMode; //safe or parallel, half or full speed unsigned int Feb_Control_triggerMode; //internal timer, external start, external window, signal polarity (external trigger and enable) unsigned int Feb_Control_externalEnableMode; //external enabling engaged and it's polarity unsigned int Feb_Control_subFrameMode; unsigned int Feb_Control_softwareTrigger; unsigned int Feb_Control_nimages; double Feb_Control_exposure_time_in_sec; int64_t Feb_Control_subframe_exposure_time_in_10nsec; int64_t Feb_Control_subframe_period_in_10nsec; double Feb_Control_exposure_period_in_sec; int64_t Feb_Control_RateTable_Tau_in_nsec = -1; int64_t Feb_Control_RateTable_Period_in_nsec = -1; unsigned int Feb_Control_trimbit_size; unsigned int* Feb_Control_last_downloaded_trimbits; int Feb_Control_module_number; int Feb_Control_current_index; int Feb_Control_counter_bit = 1; int Feb_control_master = 0; int Feb_control_normal = 0; unsigned int Feb_Control_rate_correction_table[1024]; double Feb_Control_rate_meas[16384]; double ratemax=-1; int Feb_Control_activated = 1; int Feb_Control_hv_fd = -1; void Module_Module(struct Module* mod,unsigned int number, unsigned int address_top) { unsigned int i; mod->module_number = number; mod->top_address_valid = 1; mod->top_left_address = 0x100 | (0xff & address_top); mod->top_right_address = (0x200 | (0xff & address_top)); mod-> bottom_address_valid = 0; mod-> bottom_left_address = 0; mod-> bottom_right_address = 0; mod->high_voltage = -1; mod->top_dac = malloc(Module_ndacs * sizeof(int)); mod->bottom_dac = malloc(Module_ndacs * sizeof(int)); for(i=0;itop_dac[i] = mod->top_address_valid ? -1:0; for(i=0;ibottom_dac[i] = mod->bottom_address_valid ? -1:0; } void Module_ModuleBottom(struct Module* mod,unsigned int number, unsigned int address_bottom) { unsigned int i; mod->module_number = number; mod->top_address_valid = 0; mod->top_left_address = 0; mod->top_right_address = 0; mod-> bottom_address_valid = 1; mod-> bottom_left_address = 0x100 | (0xff & address_bottom); mod-> bottom_right_address = (0x200 | (0xff & address_bottom)); mod->high_voltage = -1; for(i=0;i<4;i++) mod->idelay_top[i]=mod->idelay_bottom[i]=0; mod->top_dac = malloc(Module_ndacs * sizeof(int)); mod->bottom_dac = malloc(Module_ndacs * sizeof(int)); for(i=0;itop_dac[i] = mod->top_address_valid ? -1:0; for(i=0;ibottom_dac[i] = mod->bottom_address_valid ? -1:0; } void Module_Module1(struct Module* mod,unsigned int number, unsigned int address_top, unsigned int address_bottom) { unsigned int i; mod->module_number = number; mod->top_address_valid = 1; mod->top_left_address = 0x100 | (0xff & address_top); mod->top_right_address = 0x200 | (0xff & address_top); mod->bottom_address_valid = 1; mod->bottom_left_address = 0x100 | (0xff & address_bottom); mod->bottom_right_address = 0x200 | (0xff & address_bottom); mod->high_voltage = -1; for(i=0;i<4;i++) mod->idelay_top[i]=mod->idelay_bottom[i]=0; mod->top_dac = malloc(Module_ndacs * sizeof(int)); mod->bottom_dac = malloc(Module_ndacs * sizeof(int)); for(i=0;itop_dac[i] = mod->top_address_valid ? -1:0; for(i=0;ibottom_dac[i] = mod->bottom_address_valid ? -1:0; } unsigned int Module_GetModuleNumber(struct Module* mod) {return mod->module_number;} int Module_TopAddressIsValid(struct Module* mod) {return mod->top_address_valid;} unsigned int Module_GetTopBaseAddress(struct Module* mod) {return (mod->top_left_address&0xff);} unsigned int Module_GetTopLeftAddress(struct Module* mod) {return mod->top_left_address;} unsigned int Module_GetTopRightAddress(struct Module* mod) {return mod->top_right_address;} unsigned int Module_GetBottomBaseAddress(struct Module* mod) {return (mod->bottom_left_address&0xff);} int Module_BottomAddressIsValid(struct Module* mod) {return mod->bottom_address_valid;} unsigned int Module_GetBottomLeftAddress(struct Module* mod) {return mod->bottom_left_address;} unsigned int Module_GetBottomRightAddress(struct Module* mod) {return mod->bottom_right_address;} unsigned int Module_SetTopIDelay(struct Module* mod,unsigned int chip,unsigned int value) { return Module_TopAddressIsValid(mod) &&chip<4 ? (mod->idelay_top[chip]=value) : 0;} //chip 0=ll,1=lr,0=rl,1=rr unsigned int Module_GetTopIDelay(struct Module* mod,unsigned int chip) { return chip<4 ? mod->idelay_top[chip] : 0;} //chip 0=ll,1=lr,0=rl,1=rr unsigned int Module_SetBottomIDelay(struct Module* mod,unsigned int chip,unsigned int value) { return Module_BottomAddressIsValid(mod) &&chip<4 ? (mod->idelay_bottom[chip]=value) : 0;} //chip 0=ll,1=lr,0=rl,1=rr unsigned int Module_GetBottomIDelay(struct Module* mod,unsigned int chip) { return chip<4 ? mod->idelay_bottom[chip] : 0;} //chip 0=ll,1=lr,0=rl,1=rr float Module_SetHighVoltage(struct Module* mod,float value) { return Feb_control_master ? (mod->high_voltage=value) : -1;}// Module_TopAddressIsValid(mod) ? (mod->high_voltage=value) : -1;} float Module_GetHighVoltage(struct Module* mod) { return mod->high_voltage;} int Module_SetTopDACValue(struct Module* mod,unsigned int i, int value) { return (itop_dac[i]=value) : -1;} int Module_GetTopDACValue(struct Module* mod,unsigned int i) { return (itop_dac[i] : -1;} int Module_SetBottomDACValue(struct Module* mod,unsigned int i, int value) { return (ibottom_dac[i]=value): -1;} int Module_GetBottomDACValue(struct Module* mod,unsigned int i) { return (ibottom_dac[i] : -1;} void Feb_Control_activate(int activate) { Feb_Control_activated = activate; } int Feb_Control_IsBottomModule() { if (Module_BottomAddressIsValid(&modules[Feb_Control_current_index])) return 1; return 0; } int Feb_Control_GetModuleNumber() { return Feb_Control_module_number; } void Feb_Control_FebControl() { Feb_Control_staticBits=Feb_Control_acquireNReadoutMode=Feb_Control_triggerMode=Feb_Control_externalEnableMode=Feb_Control_subFrameMode=0; Feb_Control_trimbit_size=263680; Feb_Control_last_downloaded_trimbits = malloc(Feb_Control_trimbit_size * sizeof(int)); moduleSize = 0; } int Feb_Control_Init(int master, int top, int normal, int module_num) { unsigned int i; Feb_Control_module_number = 0; Feb_Control_current_index = 0; Feb_control_master = master; Feb_control_normal = normal; //global send Feb_Control_AddModule1(0,1,0xff,0,1); Feb_Control_PrintModuleList(); Feb_Control_module_number = (module_num & 0xFF); int serial = !top; FILE_LOG(logDEBUG1, ("serial: %d\n",serial)); Feb_Control_current_index = 1; //Add the half module Feb_Control_AddModule1(Feb_Control_module_number,top,serial,serial,1); Feb_Control_PrintModuleList(); unsigned int nfebs = 0; unsigned int* feb_list = malloc(moduleSize*4 * sizeof(unsigned int)); for(i=1;i3) { FILE_LOG(logERROR, ("SetIDelay chip_pos %d doesn't exist.\n",chip_pos)); return 0; } unsigned int module_index=0; if (!Feb_Control_GetModuleIndex(module_num,&module_index)) { FILE_LOG(logERROR, ("could not set i delay module number %d invalid.\n",module_num)); return 0; } int ok = 1; if (chip_pos/2==0) { //left fpga if (Module_TopAddressIsValid(&modules[module_index])) { if (Feb_Control_SendIDelays(Module_GetTopLeftAddress(&modules[module_index]),chip_pos%2==0,0xffffffff,ndelay_units)) { if (module_index!=0) Module_SetTopIDelay(&modules[module_index],chip_pos,ndelay_units); else { for(i=0;i0x3ff) 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; FILE_LOG(logDEBUG1, ("\tSetting delays of %s chips of dst_num %d, " "tracks 0x%x to %d, %d clks and %d units.\n", ((set_left_delay_channels != 0) ? "left" : "right"), dst_num, channels, (((15-delay_data_valid_nclks)<<6)|ndelay_units), delay_data_valid_nclks, ndelay_units)); if (Feb_Control_activated) { if (!Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG2, 1<<31 | delay_data_valid_nclks<<16 | ndelay_units,0,0) || //the 1<<31 time enables the setting of the data valid delays !Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG3,set_left_delay_channels,0,0) || !Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG4,set_right_delay_channels,0,0) || !Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG_CTRL,CHIP_DATA_OUT_DELAY_SET,1,1)) { FILE_LOG(logERROR, ("could not SetChipDataInputDelays(...).\n")); return 0; } } return 1; } int Feb_Control_VoltageToDAC(float value, unsigned int* digital,unsigned int nsteps,float vmin,float vmax) { if (valuevmax) return 0; *digital = (int)(((value-vmin)/(vmax-vmin))*(nsteps-1) + 0.5); return 1; } float Feb_Control_DACToVoltage(unsigned int digital,unsigned int nsteps,float vmin,float vmax) { return vmin+(vmax-vmin)*digital/(nsteps-1); } //only master gets to call this function int Feb_Control_SetHighVoltage(int value) { FILE_LOG(logDEBUG1, (" Setting High Voltage:\t")); /* * maximum voltage of the hv dc/dc converter: * 300 for single module power distribution board * 200 for 9M power distribution board * but limit is 200V for both */ const float vmin=0; float vmax=200; if (Feb_control_normal) vmax=300; const float vlimit=200; const unsigned int ntotalsteps = 256; unsigned int nsteps = ntotalsteps*vlimit/vmax; unsigned int dacval = 0; //calculate dac value if (!Feb_Control_VoltageToDAC(value,&dacval,nsteps,vmin,vlimit)) { FILE_LOG(logERROR, ("SetHighVoltage bad value, %d. The range is 0 to %d V.\n",value, (int)vlimit)); return -1; } FILE_LOG(logINFO, ("High Voltage set to %dV\n", value)); FILE_LOG(logDEBUG1, ("High Voltage set to (%d dac):\t%dV\n", dacval, value)); return Feb_Control_SendHighVoltage(dacval); } int Feb_Control_GetHighVoltage(int* value) { FILE_LOG(logDEBUG1, (" Getting High Voltage:\t")); unsigned int dacval = 0; if (!Feb_Control_ReceiveHighVoltage(&dacval)) return 0; //ok, convert dac to v /* * maximum voltage of the hv dc/dc converter: * 300 for single module power distribution board * 200 for 9M power distribution board * but limit is 200V for both */ const float vmin=0; float vmax=200; if (Feb_control_normal) vmax=300; const float vlimit=200; const unsigned int ntotalsteps = 256; unsigned int nsteps = ntotalsteps*vlimit/vmax; *value = (int)(Feb_Control_DACToVoltage(dacval,nsteps,vmin,vlimit)+0.5); FILE_LOG(logINFO, ("High Voltage read %dV\n", *value)); FILE_LOG(logDEBUG1, ("High Voltage read (%d dac)\t%dV\n", dacval, *value)); return 1; } int Feb_Control_SendHighVoltage(int dacvalue) { //normal if (Feb_control_normal) { //open file FILE* fd=fopen(NORMAL_HIGHVOLTAGE_OUTPUTPORT,"w"); if (fd==NULL) { FILE_LOG(logERROR, ("Could not open file for writing to set high voltage\n")); return 0; } //convert to string, add 0 and write to file fprintf(fd, "%d0\n", dacvalue); fclose(fd); } //9m else { /*Feb_Control_OpenSerialCommunication();*/ if (Feb_Control_hv_fd == -1) { FILE_LOG(logERROR, ("High voltage serial communication not set up for 9m\n")); return 0; } char buffer[SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE]; memset(buffer,0,SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); buffer[SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE-1]='\n'; int n; sprintf(buffer,"p%d",dacvalue); FILE_LOG(logINFO, ("Sending HV: '%s'\n",buffer)); n = write(Feb_Control_hv_fd, buffer, SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); if (n < 0) { FILE_LOG(logERROR, ("writing to i2c bus\n")); return 0; } #ifdef VERBOSEI FILE_LOG(logINFO, ("Sent %d Bytes\n", n)); #endif //ok/fail memset(buffer,0,SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); buffer[SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE-1] = '\n'; n = read(Feb_Control_hv_fd, buffer, SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); if (n < 0) { FILE_LOG(logERROR, ("reading from i2c bus\n")); return 0; } #ifdef VERBOSEI FILE_LOG(logINFO, ("Received %d Bytes\n", n)); #endif FILE_LOG(logINFO, ("Received HV: '%s'\n",buffer)); fflush(stdout); /*Feb_Control_CloseSerialCommunication();*/ if (buffer[0] != 's') { FILE_LOG(logERROR, ("\nError: Failed to set high voltage\n")); return 0; } FILE_LOG(logINFO, ("%s\n",buffer)); } return 1; } int Feb_Control_ReceiveHighVoltage(unsigned int* value) { //normal if (Feb_control_normal) { //open file FILE* fd=fopen(NORMAL_HIGHVOLTAGE_INPUTPORT,"r"); if (fd==NULL) { FILE_LOG(logERROR, ("Could not open file for writing to get high voltage\n")); return 0; } //read, assigning line to null and readbytes to 0 then getline allocates initial buffer size_t readbytes=0; char* line=NULL; if (getline(&line, &readbytes, fd) == -1) { FILE_LOG(logERROR, ("could not read file to get high voltage\n")); return 0; } //read again to read the updated value rewind(fd); free(line); readbytes=0; readbytes = getline(&line, &readbytes, fd); if (readbytes == -1) { FILE_LOG(logERROR, ("could not read file to get high voltage\n")); return 0; } // Remove the trailing 0 *value = atoi(line)/10; free(line); fclose(fd); } //9m else { /*Feb_Control_OpenSerialCommunication();*/ if (Feb_Control_hv_fd == -1) { FILE_LOG(logERROR, ("High voltage serial communication not set up for 9m\n")); return 0; } char buffer[SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE]; buffer[SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE-1]='\n'; int n = 0; //request strcpy(buffer,"g "); FILE_LOG(logINFO, ("\nSending HV: '%s'\n",buffer)); n = write(Feb_Control_hv_fd, buffer, SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); if (n < 0) { FILE_LOG(logERROR, ("writing to i2c bus\n")); return 0; } #ifdef VERBOSEI FILE_LOG(logINFO, ("Sent %d Bytes\n", n)); #endif //ok/fail memset(buffer,0,SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); buffer[SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE-1] = '\n'; n = read(Feb_Control_hv_fd, buffer, SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); if (n < 0) { FILE_LOG(logERROR, ("reading from i2c bus\n")); return 0; } #ifdef VERBOSEI FILE_LOG(logINFO, ("Received %d Bytes\n", n)); #endif FILE_LOG(logINFO, ("Received HV: '%s'\n",buffer)); if (buffer[0] != 's') { FILE_LOG(logERROR, ("failed to read high voltage\n")); return 0; } memset(buffer,0,SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); buffer[SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE-1] = '\n'; n = read(Feb_Control_hv_fd, buffer, SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); if (n < 0) { FILE_LOG(logERROR, ("reading from i2c bus\n")); return 0; } #ifdef VERBOSEI FILE_LOG(logINFO, ("Received %d Bytes\n", n)); #endif FILE_LOG(logINFO, ("Received HV: '%s'\n",buffer)); /*Feb_Control_OpenSerialCommunication();*/ if (!sscanf(buffer,"%d",value)) { FILE_LOG(logERROR, ("failed to scan high voltage read\n")); return 0; } } return 1; } int Feb_Control_DecodeDACString(char* dac_str, unsigned int* module_index, int* top, int* bottom, unsigned int* dac_ch) { char* local_s = dac_str; *module_index = Feb_Control_current_index; *top = 1;//make them both 1 instead of this *bottom = 1; if (Module_BottomAddressIsValid(&modules[*module_index])) *top=0; else *bottom=0; *dac_ch = 0; if (!Feb_Control_GetDACNumber(local_s,dac_ch)) { FILE_LOG(logERROR, ("invalid dac_name: %s (%s)\n",dac_str,local_s)); return 0; } return 1; } int Feb_Control_SetDAC(char* dac_str, int value, int is_a_voltage_mv) { unsigned int i; unsigned int module_index, dac_ch; int top, bottom; if (!Feb_Control_DecodeDACString(dac_str,&module_index,&top,&bottom,&dac_ch)) return 0; unsigned int v = value; if (is_a_voltage_mv&&!Feb_Control_VoltageToDAC(value,&v,4096,0,2048)) { FILE_LOG(logERROR, ("SetDac bad value, %d. The range is 0 to 2048 mV.\n",value)); return 0; } if (v<0||v>4095) { FILE_LOG(logERROR, ("SetDac bad value, %d. The range is 0 to 4095.\n",v)); return 0; } if (top&&Module_TopAddressIsValid(&modules[module_index])) { if (!Feb_Control_SendDACValue(Module_GetTopRightAddress(&modules[module_index]),dac_ch,&v)) return 0; if (module_index!=0) Module_SetTopDACValue(&modules[module_index],dac_ch,v); else for(i=0;i=Module_ndacs) { FILE_LOG(logERROR, ("GetDACName index out of range, %d invalid.\n",dac_num)); return 0; } strcpy(s,Module_dac_names[dac_num]); return 1; } int Feb_Control_GetDACNumber(char* s, unsigned int* n) { unsigned int i; for(i=0;i15) { FILE_LOG(logERROR, ("invalid ch for SetDAC.\n")); return 0; } //if (voltage<0) return PowerDownDAC(socket_num,ch); *value&=0xfff; unsigned int dac_ic = (ch<8) ? 1:2; unsigned int dac_ch = ch%8; unsigned int r = dac_ic<<30 | 3<<16 | dac_ch<<12 | *value; //3 write and power up if (Feb_Control_activated) { if (!Feb_Interface_WriteRegister(dst_num,0,r,1,0)) { FILE_LOG(logERROR, ("trouble setting dac %d voltage.\n",ch)); return 0; } } float voltage=Feb_Control_DACToVoltage(*value,4096,0,2048); FILE_LOG(logINFO, ("%s set to %d (%.2fmV)\n", Module_dac_names[ch],*value,voltage)); FILE_LOG(logDEBUG1, ("Dac number %d (%s) of dst %d set to %d (%f mV)\n",ch,Module_dac_names[ch],dst_num,*value,voltage)); return 1; } int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits) { FILE_LOG(logINFO, ("Setting Trimbits\n")); //for (int iy=10000;iy<20020;++iy)//263681 //for (int iy=263670;iy<263680;++iy)//263681 // FILE_LOG(logINFO, ("%d:%c\t\t",iy,trimbits[iy])); unsigned int trimbits_to_load_l[1024]; unsigned int trimbits_to_load_r[1024]; unsigned int module_index=0; if (!Feb_Control_GetModuleIndex(module_num,&module_index)) { FILE_LOG(logERROR, ("could not set trimbits, bad module number.\n")); return 0; } if (Feb_Control_Reset() == STATUS_ERROR) { FILE_LOG(logERROR, ("could not reset DAQ.\n")); } int l_r; for(l_r=0;l_r<2;l_r++) { // l_r loop unsigned int disable_chip_mask = l_r ? DAQ_CS_BAR_LEFT : DAQ_CS_BAR_RIGHT; if (Feb_Control_activated) { if (!(Feb_Interface_WriteRegister(0xfff,DAQ_REG_STATIC_BITS,disable_chip_mask|DAQ_STATIC_BIT_PROGRAM|DAQ_STATIC_BIT_M8,0,0) &&Feb_Control_SetCommandRegister(DAQ_SET_STATIC_BIT) &&(Feb_Control_StartDAQOnlyNWaitForFinish(5000) == STATUS_IDLE))) { FILE_LOG(logERROR, ("Could not select chips\n")); return 0; } } int row_set; for(row_set=0;row_set<16;row_set++) { //16 rows at a time if (row_set==0) { if (!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY|DAQ_SEND_A_TOKEN_IN|DAQ_LOAD_16ROWS_OF_TRIMBITS)) { FILE_LOG(logERROR, ("Could not Feb_Control_SetCommandRegister for loading trim bits.\n")); return 0; } } else { if (!Feb_Control_SetCommandRegister(DAQ_LOAD_16ROWS_OF_TRIMBITS)) { FILE_LOG(logERROR, ("Could not Feb_Control_SetCommandRegister for loading trim bits.\n")); return 0; } } int row; for(row=0;row<16;row++) { //row loop int offset = 2*32*row; int sc; for(sc=0;sc<32;sc++) { //supercolumn loop sc int super_column_start_position_l = 1030*row + l_r *258 + sc*8; int super_column_start_position_r = 1030*row + 516 + l_r *258 + sc*8; /* int super_column_start_position_l = 1024*row + l_r *256 + sc*8; //256 per row, 8 per super column int super_column_start_position_r = 1024*row + 512 + l_r *256 + sc*8; //256 per row, 8 per super column */ int chip_sc = 31 - sc; trimbits_to_load_l[offset+chip_sc] = 0; trimbits_to_load_r[offset+chip_sc] = 0; trimbits_to_load_l[offset+chip_sc+32] = 0; trimbits_to_load_r[offset+chip_sc+32] = 0; int i; for(i=0;i<8;i++) { // column loop i if (Module_TopAddressIsValid(&modules[1])) { trimbits_to_load_l[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_l+i])<<((7-i)*4);//low trimbits_to_load_l[offset+chip_sc+32] |= ((0x38 & trimbits[row_set*16480+super_column_start_position_l+i])>>3)<<((7-i)*4);//upper trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_r+i])<<((7-i)*4);//low trimbits_to_load_r[offset+chip_sc+32] |= ((0x38 & trimbits[row_set*16480+super_column_start_position_r+i])>>3)<<((7-i)*4);//upper } else { trimbits_to_load_l[offset+chip_sc] |= ( 0x7 & trimbits[263679 - (row_set*16480+super_column_start_position_l+i)])<<((7-i)*4);//low trimbits_to_load_l[offset+chip_sc+32] |= ((0x38 & trimbits[263679 - (row_set*16480+super_column_start_position_l+i)])>>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 } } // end column loop i } //end supercolumn loop sc } //end row loop if (Module_TopAddressIsValid(&modules[1])) { if (Feb_Control_activated) { if (!Feb_Interface_WriteMemoryInLoops(Module_GetTopLeftAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_l)|| !Feb_Interface_WriteMemoryInLoops(Module_GetTopRightAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_r)|| //if (!Feb_Interface_WriteMemory(Module_GetTopLeftAddress(&modules[0]),0,0,1023,trimbits_to_load_r)|| // !Feb_Interface_WriteMemory(Module_GetTopRightAddress(&modules[0]),0,0,1023,trimbits_to_load_l)|| (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { FILE_LOG(logERROR, (" some errror!\n")); return 0; } } } else { if (Feb_Control_activated) { if (!Feb_Interface_WriteMemoryInLoops(Module_GetBottomLeftAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_l)|| !Feb_Interface_WriteMemoryInLoops(Module_GetBottomRightAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_r)|| //if (!Feb_Interface_WriteMemory(Module_GetTopLeftAddress(&modules[0]),0,0,1023,trimbits_to_load_r)|| // !Feb_Interface_WriteMemory(Module_GetTopRightAddress(&modules[0]),0,0,1023,trimbits_to_load_l)|| (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { FILE_LOG(logERROR, (" some errror!\n")); return 0; } } } } //end row_set loop (groups of 16 rows) } // end l_r loop memcpy(Feb_Control_last_downloaded_trimbits,trimbits,Feb_Control_trimbit_size*sizeof(unsigned int)); return Feb_Control_SetStaticBits(); //send the static bits } unsigned int* Feb_Control_GetTrimbits() { return Feb_Control_last_downloaded_trimbits; } unsigned int Feb_Control_AddressToAll() { FILE_LOG(logDEBUG1, ("in Feb_Control_AddressToAll()\n")); if (moduleSize==0) return 0; if (Module_BottomAddressIsValid(&modules[1])) { //if (Feb_Control_am_i_master) return Module_GetBottomLeftAddress(&modules[1])|Module_GetBottomRightAddress(&modules[1]); // else return 0; } return Module_GetTopLeftAddress(&modules[1])|Module_GetTopRightAddress(&modules[1]); //return Module_GetTopLeftAddress(&modules[0])|Module_GetTopRightAddress(&modules[0]); } int Feb_Control_SetCommandRegister(unsigned int cmd) { if (Feb_Control_activated) return Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CHIP_CMDS,cmd,0,0); else return 1; } int Feb_Control_GetDAQStatusRegister(unsigned int dst_address, unsigned int* ret_status) { //if deactivated, should be handled earlier and should not get into this function if (Feb_Control_activated) { if (!Feb_Interface_ReadRegister(dst_address,DAQ_REG_STATUS,ret_status)) { FILE_LOG(logERROR, ("Error: reading status register.\n")); return 0; } } *ret_status = (0x02FF0000 & *ret_status) >> 16; return 1; } int Feb_Control_StartDAQOnlyNWaitForFinish(int sleep_time_us) { if (Feb_Control_activated) { if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0)||!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_START,0,0)) { FILE_LOG(logERROR, ("could not start.\n")); return 0; } } return Feb_Control_WaitForFinishedFlag(sleep_time_us); } int Feb_Control_AcquisitionInProgress() { unsigned int status_reg_r=0,status_reg_l=0; //deactivated should return end of acquisition if (!Feb_Control_activated) return STATUS_IDLE; int ind = Feb_Control_current_index; if (Module_BottomAddressIsValid(&modules[ind])) { if (!(Feb_Control_GetDAQStatusRegister(Module_GetBottomRightAddress(&modules[ind]),&status_reg_r))) {FILE_LOG(logERROR, ("Error: Trouble reading Status register. bottom right address\n"));return STATUS_ERROR;} if (!(Feb_Control_GetDAQStatusRegister(Module_GetBottomLeftAddress(&modules[ind]),&status_reg_l))) {FILE_LOG(logERROR, ("Error: Trouble reading Status register. bottom left address\n"));return STATUS_ERROR;} } else { if (!(Feb_Control_GetDAQStatusRegister(Module_GetTopRightAddress(&modules[ind]),&status_reg_r))) {FILE_LOG(logERROR, ("Error: Trouble reading Status register. top right address\n"));return STATUS_ERROR;} if (!(Feb_Control_GetDAQStatusRegister(Module_GetTopLeftAddress(&modules[ind]),&status_reg_l))) {FILE_LOG(logERROR, ("Error: Trouble reading Status register. top left address\n"));return STATUS_ERROR;} } //running if ((status_reg_r|status_reg_l)&DAQ_STATUS_DAQ_RUNNING) { FILE_LOG(logDEBUG1, ("**runningggg\n")); return STATUS_RUNNING; } //idle return STATUS_IDLE; } int Feb_Control_AcquisitionStartedBit() { unsigned int status_reg_r=0,status_reg_l=0; //deactivated should return acquisition started/ready if (!Feb_Control_activated) return 1; int ind = Feb_Control_current_index; if (Module_BottomAddressIsValid(&modules[ind])) { if (!(Feb_Control_GetDAQStatusRegister(Module_GetBottomRightAddress(&modules[ind]),&status_reg_r))) {FILE_LOG(logERROR, ("Error: Trouble reading Status register. bottom right address\n"));return -1;} if (!(Feb_Control_GetDAQStatusRegister(Module_GetBottomLeftAddress(&modules[ind]),&status_reg_l))) {FILE_LOG(logERROR, ("Error: Trouble reading Status register. bottom left address\n"));return -1;} } else { if (!(Feb_Control_GetDAQStatusRegister(Module_GetTopRightAddress(&modules[ind]),&status_reg_r))) {FILE_LOG(logERROR, ("Error: Trouble reading Status register. top right address\n")); return -1;} if (!(Feb_Control_GetDAQStatusRegister(Module_GetTopLeftAddress(&modules[ind]),&status_reg_l))) {FILE_LOG(logERROR, ("Error: Trouble reading Status register. top left address\n"));return -1;} } //doesnt mean it started, just the bit if ((status_reg_r|status_reg_l)&DAQ_STATUS_DAQ_RUN_TOGGLE) return 1; return 0; } int Feb_Control_WaitForFinishedFlag(int sleep_time_us) { int is_running = Feb_Control_AcquisitionInProgress(); int check_error = 0; // it will break out if it is idle or if check_error is more than 5 times while(is_running != STATUS_IDLE) { usleep(sleep_time_us); is_running = Feb_Control_AcquisitionInProgress(); // check error only 5 times (ensuring it is not something that happens sometimes) if (is_running == STATUS_ERROR) { if (check_error == 5) break; check_error++; }// reset check_error for next time else check_error = 0; } return is_running; } int Feb_Control_WaitForStartedFlag(int sleep_time_us, int prev_flag) { //deactivated dont wait (otherwise give a toggle value back) if (!Feb_Control_activated) return 1; //did not start if (prev_flag == -1) return 0; int value = prev_flag; while(value == prev_flag) { usleep(sleep_time_us); value = Feb_Control_AcquisitionStartedBit(); } //did not start if (value == -1) return 0; return 1; } int Feb_Control_Reset() { FILE_LOG(logINFO, ("Reset daq\n")); if (Feb_Control_activated) { if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_RESET,0,0) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0)) { FILE_LOG(logERROR, ("Could not reset daq, no response.\n")); return 0; } } return Feb_Control_WaitForFinishedFlag(5000); } int Feb_Control_SetStaticBits() { if (Feb_Control_activated) { //program=1,m4=2,m8=4,test=8,rotest=16,cs_bar_left=32,cs_bar_right=64 if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_STATIC_BITS,Feb_Control_staticBits,0,0) || !Feb_Control_SetCommandRegister(DAQ_SET_STATIC_BIT) || (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { FILE_LOG(logERROR, ("Could not set static bits\n")); return 0; } } return 1; } int Feb_Control_SetStaticBits1(unsigned int the_static_bits) { Feb_Control_staticBits = the_static_bits; return Feb_Control_SetStaticBits(); } int Feb_Control_SetInTestModeVariable(int on) { if (on) Feb_Control_staticBits |= DAQ_STATIC_BIT_CHIP_TEST; //setting test bit to high else Feb_Control_staticBits &= (~DAQ_STATIC_BIT_CHIP_TEST); //setting test bit to low return 1; } int Feb_Control_GetTestModeVariable() { return Feb_Control_staticBits&DAQ_STATIC_BIT_CHIP_TEST; } int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo) { static unsigned int everything_but_bit_mode = DAQ_STATIC_BIT_PROGRAM|DAQ_STATIC_BIT_CHIP_TEST|DAQ_STATIC_BIT_ROTEST; if (four_eight_sixteen_or_thirtytwo==4) { Feb_Control_staticBits = DAQ_STATIC_BIT_M4 | (Feb_Control_staticBits&everything_but_bit_mode); //leave test bits in currernt state Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; } else if (four_eight_sixteen_or_thirtytwo==8) { Feb_Control_staticBits = DAQ_STATIC_BIT_M8 | (Feb_Control_staticBits&everything_but_bit_mode); Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; } else if (four_eight_sixteen_or_thirtytwo==16) { Feb_Control_staticBits = DAQ_STATIC_BIT_M12 | (Feb_Control_staticBits&everything_but_bit_mode); Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; } else if (four_eight_sixteen_or_thirtytwo==32) { Feb_Control_staticBits = DAQ_STATIC_BIT_M12 | (Feb_Control_staticBits&everything_but_bit_mode); Feb_Control_subFrameMode |= DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; } else { FILE_LOG(logERROR, ("dynamic range (%d) not valid, not setting bit mode.\n",four_eight_sixteen_or_thirtytwo)); FILE_LOG(logINFO, ("Set dynamic range int must equal 4,8 16, or 32.\n")); return 0; } FILE_LOG(logINFO, ("Dynamic range set to %d\n",four_eight_sixteen_or_thirtytwo)); return 1; } unsigned int Feb_Control_GetDynamicRange() { if (Feb_Control_subFrameMode&DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING) return 32; else if (DAQ_STATIC_BIT_M4&Feb_Control_staticBits) return 4; else if (DAQ_STATIC_BIT_M8&Feb_Control_staticBits) return 8; return 16; } int Feb_Control_SetReadoutSpeed(unsigned int readout_speed) { //0->full,1->half,2->quarter or 3->super_slow Feb_Control_acquireNReadoutMode &= (~DAQ_CHIP_CONTROLLER_SUPER_SLOW_SPEED); if (readout_speed==1) { Feb_Control_acquireNReadoutMode |= DAQ_CHIP_CONTROLLER_HALF_SPEED; FILE_LOG(logINFO, ("Speed set to half speed (50 MHz)\n")); } else if (readout_speed==2) { Feb_Control_acquireNReadoutMode |= DAQ_CHIP_CONTROLLER_QUARTER_SPEED; FILE_LOG(logINFO, ("Speed set to quarter speed (25 MHz)\n")); } else { if (readout_speed) { FILE_LOG(logERROR, ("readout speed %d unknown, defaulting to full speed.\n",readout_speed)); FILE_LOG(logINFO, ("full speed, (100 MHz)\n")); return 0; } FILE_LOG(logINFO, ("Speed set to full speed (100 MHz)\n")); } return 1; } int Feb_Control_SetReadoutMode(unsigned int readout_mode) { //0->parallel,1->non-parallel,2-> safe_mode Feb_Control_acquireNReadoutMode &= (~DAQ_NEXPOSURERS_PARALLEL_MODE); if (readout_mode==1) { Feb_Control_acquireNReadoutMode |= DAQ_NEXPOSURERS_NORMAL_NONPARALLEL_MODE; FILE_LOG(logINFO, ("Readout mode set to Non Parallel\n")); } else if (readout_mode==2) { Feb_Control_acquireNReadoutMode |= DAQ_NEXPOSURERS_SAFEST_MODE_ROW_CLK_BEFORE_MODE; FILE_LOG(logINFO, ("Readout mode set to Safe (row clk before main clk readout sequence)\n")); } else { Feb_Control_acquireNReadoutMode |= DAQ_NEXPOSURERS_PARALLEL_MODE; if (readout_mode) { FILE_LOG(logERROR, ("readout mode %d) unknown, defaulting to parallel readout.\n",readout_mode)); FILE_LOG(logINFO, ("Readout mode set to Parallel\n")); return 0; } FILE_LOG(logINFO, ("Readout mode set to Parallel\n")); } return 1; } int Feb_Control_SetTriggerMode(unsigned int trigger_mode,int polarity) { //"00"-> 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 Feb_Control_triggerMode = (~DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START_AND_STOP); if (trigger_mode == 1) { Feb_Control_triggerMode = DAQ_NEXPOSURERS_EXTERNAL_ACQUISITION_START; FILE_LOG(logINFO, ("Trigger mode set to Burst Trigger\n")); } else if (trigger_mode == 2) { Feb_Control_triggerMode = DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START; FILE_LOG(logINFO, ("Trigger mode set to Trigger Exposure\n")); } else if (trigger_mode == 3) { Feb_Control_triggerMode = DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START_AND_STOP; FILE_LOG(logINFO, ("Trigger mode set to Gated\n")); } else { Feb_Control_triggerMode = DAQ_NEXPOSURERS_INTERNAL_ACQUISITION; if (trigger_mode) { FILE_LOG(logERROR, ("trigger %d) unknown, defaulting to Auto\n",trigger_mode)); } FILE_LOG(logINFO, ("Trigger mode set to Auto\n")); return trigger_mode==0; } if (polarity) { Feb_Control_triggerMode |= DAQ_NEXPOSURERS_EXTERNAL_TRIGGER_POLARITY; FILE_LOG(logINFO, ("External trigger polarity set to positive\n")); } else { Feb_Control_triggerMode &= (~DAQ_NEXPOSURERS_EXTERNAL_TRIGGER_POLARITY); FILE_LOG(logINFO, ("External trigger polarity set to negitive\n")); } return 1; } int Feb_Control_SetExternalEnableMode(int use_external_enable, int polarity) { if (use_external_enable) { Feb_Control_externalEnableMode |= DAQ_NEXPOSURERS_EXTERNAL_ENABLING; if (polarity) { Feb_Control_externalEnableMode |= DAQ_NEXPOSURERS_EXTERNAL_ENABLING_POLARITY; } else { Feb_Control_externalEnableMode &= (~DAQ_NEXPOSURERS_EXTERNAL_ENABLING_POLARITY); } FILE_LOG(logINFO, ("External enabling enabled, polarity set to %s\n", (polarity ? "positive" : "negative"))); } else { Feb_Control_externalEnableMode = 0; /* changed by Dhanya according to old code &= (~DAQ_NEXPOSURERS_EXTERNAL_ENABLING);*/ FILE_LOG(logINFO, ("External enabling disabled\n")); } return 1; } int Feb_Control_SetNExposures(unsigned int n_images) { if (!n_images) { FILE_LOG(logERROR, ("nimages must be greater than zero.%d\n",n_images)); return 0; } Feb_Control_nimages = n_images; FILE_LOG(logINFO, ("Number of images set to %d\n",Feb_Control_nimages)); return 1; } unsigned int Feb_Control_GetNExposures() {return Feb_Control_nimages;} int Feb_Control_SetExposureTime(double the_exposure_time_in_sec) { Feb_Control_exposure_time_in_sec = the_exposure_time_in_sec; FILE_LOG(logINFO, ("Exposure time set to %fs\n",Feb_Control_exposure_time_in_sec)); return 1; } double Feb_Control_GetExposureTime() {return Feb_Control_exposure_time_in_sec;} int64_t Feb_Control_GetExposureTime_in_nsec() {return (int64_t)(Feb_Control_exposure_time_in_sec*(1E9));} int Feb_Control_SetSubFrameExposureTime(int64_t the_subframe_exposure_time_in_10nsec) { Feb_Control_subframe_exposure_time_in_10nsec = the_subframe_exposure_time_in_10nsec; FILE_LOG(logINFO, ("Sub Frame Exposure time set to %lldns\n",(long long int)Feb_Control_subframe_exposure_time_in_10nsec * 10)); return 1; } int64_t Feb_Control_GetSubFrameExposureTime() {return Feb_Control_subframe_exposure_time_in_10nsec*10;} int Feb_Control_SetSubFramePeriod(int64_t the_subframe_period_in_10nsec) { Feb_Control_subframe_period_in_10nsec = the_subframe_period_in_10nsec; FILE_LOG(logINFO, ("Sub Frame Period set to %lldns\n",(long long int)Feb_Control_subframe_period_in_10nsec * 10)); return 1; } int64_t Feb_Control_GetSubFramePeriod() {return Feb_Control_subframe_period_in_10nsec*10;} int Feb_Control_SetExposurePeriod(double the_exposure_period_in_sec) { Feb_Control_exposure_period_in_sec = the_exposure_period_in_sec; FILE_LOG(logINFO, ("Exposure period set to %fs\n",Feb_Control_exposure_period_in_sec)); return 1; } double Feb_Control_GetExposurePeriod() {return Feb_Control_exposure_period_in_sec;} unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec) { float n_clk_cycles = round(time_in_sec/10e-9); //200 MHz ctb clk or 100 MHz feb clk unsigned int decoded_time; if (n_clk_cycles>(pow(2,29)-1)*pow(10,7)) { float max_time = 10e-9*(pow(2,28)-1)*pow(10,7); FILE_LOG(logERROR, ("time exceeds (%f) maximum exposure time of %f sec.\n",time_in_sec,max_time)); FILE_LOG(logINFO, ("\t Setting to maximum %f us.\n",max_time)); decoded_time = 0xffffffff; } else { int power_of_ten = 0; while(n_clk_cycles>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; } int Feb_Control_ResetChipCompletely() { if (!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY) || (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { FILE_LOG(logERROR, ("could not ResetChipCompletely() with 0x%x.\n",DAQ_RESET_COMPLETELY)); return 0; } FILE_LOG(logINFO, ("Chip reset completely\n")); return 1; } int Feb_Control_ResetChipPartially() { if (!Feb_Control_SetCommandRegister(DAQ_RESET_PERIPHERY) || (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { FILE_LOG(logERROR, ("could not ResetChipPartially with periphery\n")); return 0; } FILE_LOG(logINFO, ("Chip reset periphery 0x%x\n",DAQ_RESET_PERIPHERY)); if (!Feb_Control_SetCommandRegister(DAQ_RESET_COLUMN_SELECT) || (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { FILE_LOG(logERROR, ("could not ResetChipPartially with column select\n")); return 0; } FILE_LOG(logINFO, ("Chip reset column select 0x%x\n",DAQ_RESET_COLUMN_SELECT)); return 1; } void Feb_Control_PrintAcquisitionSetup() { time_t rawtime; time(&rawtime); struct tm *timeinfo = localtime(&rawtime); FILE_LOG(logINFO, ("Starting an exposure: (%s)" "\t Dynamic range nbits: %d\n" "\t Trigger mode: 0x%x\n" "\t Number of exposures: %d\n" "\t Exsposure time (if used): %f seconds.\n" "\t Exsposure period (if used): %f seconds.\n\n", asctime(timeinfo), Feb_Control_GetDynamicRange(), Feb_Control_triggerMode, Feb_Control_GetNExposures(), Feb_Control_exposure_time_in_sec, Feb_Control_exposure_period_in_sec)); } int Feb_Control_SendBitModeToBebServer() { unsigned int just_bit_mode = (DAQ_STATIC_BIT_M4|DAQ_STATIC_BIT_M8) & Feb_Control_staticBits; unsigned int bit_mode = 16; //default if (just_bit_mode == DAQ_STATIC_BIT_M4) bit_mode = 4; else if (just_bit_mode == DAQ_STATIC_BIT_M8) bit_mode = 8; else if (Feb_Control_subFrameMode&DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING) bit_mode = 32; if (!Beb_SetUpTransferParameters(bit_mode)) { FILE_LOG(logERROR, ("Error: sending bit mode ...\n")); return 0; } return 1; } int Feb_Control_PrepareForAcquisition() {//return 1; FILE_LOG(logINFO, ("Going to Prepare for Acquisition\n\n\n")); static unsigned int reg_nums[20]; static unsigned int reg_vals[20]; Feb_Control_PrintAcquisitionSetup(); // if (!Reset()||!ResetDataStream()) { if (Feb_Control_Reset() == STATUS_ERROR) { FILE_LOG(logERROR, ("Trouble reseting daq or data stream...\n")); return 0; } if (!Feb_Control_SetStaticBits1(Feb_Control_staticBits&(DAQ_STATIC_BIT_M4|DAQ_STATIC_BIT_M8))) { FILE_LOG(logERROR, ("Trouble setting static bits ...\n")); return 0; } if (!Feb_Control_SendBitModeToBebServer()) { FILE_LOG(logERROR, ("Trouble sending static bits to server ...\n")); return 0; } int ret=0; if (Feb_Control_counter_bit) ret = Feb_Control_ResetChipCompletely(); else ret = Feb_Control_ResetChipPartially(); if (!ret) { FILE_LOG(logERROR, ("Trouble resetting chips ...\n")); return 0; } reg_nums[0]=DAQ_REG_CTRL; reg_vals[0]=0; reg_nums[1]=DAQ_REG_NEXPOSURES; reg_vals[1]=Feb_Control_nimages; reg_nums[2]=DAQ_REG_EXPOSURE_TIMER; reg_vals[2]=Feb_Control_ConvertTimeToRegister(Feb_Control_exposure_time_in_sec); reg_nums[3]=DAQ_REG_EXPOSURE_REPEAT_TIMER; reg_vals[3]=Feb_Control_ConvertTimeToRegister(Feb_Control_exposure_period_in_sec); reg_nums[4]=DAQ_REG_CHIP_CMDS; reg_vals[4]=(Feb_Control_acquireNReadoutMode|Feb_Control_triggerMode|Feb_Control_externalEnableMode|Feb_Control_subFrameMode); reg_nums[5]=DAQ_REG_SUBFRAME_EXPOSURES; reg_vals[5]= Feb_Control_subframe_exposure_time_in_10nsec; //(1 means 10ns, 100 means 1000ns) reg_nums[6]=DAQ_REG_SUBFRAME_PERIOD; reg_vals[6]= Feb_Control_subframe_period_in_10nsec; //(1 means 10ns, 100 means 1000ns) // if (!Feb_Interface_WriteRegisters((Module_GetTopLeftAddress(&modules[1])|Module_GetTopRightAddress(&modules[1])),20,reg_nums,reg_vals,0,0)) { if (Feb_Control_activated) { if (!Feb_Interface_WriteRegisters(Feb_Control_AddressToAll(),7,reg_nums,reg_vals,0,0)) { FILE_LOG(logERROR, ("Trouble starting acquisition....\n")); return 0; } } return 1; } int Feb_Control_StartAcquisition() { FILE_LOG(logINFOBLUE, ("Starting Acquisition\n")); static unsigned int reg_nums[20]; static unsigned int reg_vals[20]; int i; for(i=0;i<14;i++) { reg_nums[i]=DAQ_REG_CTRL; reg_vals[i]=0; } reg_nums[14]=DAQ_REG_CTRL; reg_vals[14]=ACQ_CTRL_START; if (Feb_Control_activated) { if (!Feb_Interface_WriteRegisters(Feb_Control_AddressToAll(),15,reg_nums,reg_vals,0,0)) { FILE_LOG(logERROR, ("Trouble starting acquisition....\n")); return 0; } } return 1; } int Feb_Control_StopAcquisition() { return Feb_Control_Reset(); } int Feb_Control_SaveAllTrimbitsTo(int value) { unsigned int chanregs[Feb_Control_trimbit_size]; int i; for(i=0;i255||y<0||y>255) { FILE_LOG(logERROR, ("Pixel out of range.\n")); return 0; } // y = 255 - y; int nrowclocks = 0; nrowclocks += (Feb_Control_staticBits&DAQ_STATIC_BIT_M4) ? 0 : 2*y; nrowclocks += (Feb_Control_staticBits&DAQ_STATIC_BIT_M8) ? 0 : y; Feb_Control_SetInTestModeVariable(1); //on Feb_Control_SetStaticBits(); Feb_Control_SetCommandRegister(DAQ_RESET_PERIPHERY|DAQ_RESET_COLUMN_SELECT); if (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE) { FILE_LOG(logERROR, ("could not pulse pixel as status not idle\n")); return 0; } unsigned int serial_in = 8<<(4*(7-x%8)); if (!Feb_Control_Shift32InSerialIn(serial_in)) { FILE_LOG(logERROR, ("ChipController::PulsePixel: could shift in the initail 32.\n")); return 0; } if (!pulse_multiple) serial_in=0; for(i=0;i1023) { FILE_LOG(logERROR, ("Clock row clock ntimes (%d) exceeds the maximum value of 1023.\n\t Setting ntimes to 1023.\n",ntimes)); ntimes=1023; } if (Feb_Control_activated) { if (!Feb_Control_SetCommandRegister(DAQ_CLK_ROW_CLK_NTIMES) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CLK_ROW_CLK_NTIMES,ntimes,0,0) || (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { FILE_LOG(logERROR, ("could not clock row clock.\n")); return 0; } } return 1; } int Feb_Control_PulseChip(int npulses) { int i; int on = 1; if (npulses == -1) { on = 0; FILE_LOG(logINFO, ("\nResetting to normal mode\n")); } else { FILE_LOG(logINFO, ("\n\nPulsing Chip.\n"));//really just toggles the enable FILE_LOG(logINFO, ("Vcmp should be set to 2.0 and Vtrim should be 2.\n")); } Feb_Control_SetInTestModeVariable(on); Feb_Control_SetStaticBits(); //toggle the enable 2x times Feb_Control_ResetChipCompletely(); for(i=0;i ratemax) ratemax= Feb_Control_rate_meas[i]; } /* b : index/address of block ram/rate correction table b0 : base in vhdl m : slope in vhdl Firmware: data_in(11..2) -> memory address --> memory data_in( 1..0) -> lsb mem_data_out(13.. 0) -> base mem_data_out(17..14) -> slope delta = slope*lsb corr = base+delta */ int next_i=0; double beforemax; b0[0] = 0; m[0] = 1; Feb_Control_rate_correction_table[0] = (((int)(m[0]+0.5)&0xf)<<14) | ((int)(b0[0]+0.5)&0x3fff); int b=0; for(b=1;b<1024;b++) { if (m[b-1]<15) { double s=0,sx=0,sy=0,sxx=0,sxy=0; for(;;next_i++) { if (next_i>=np) { for(; b<1024; b++) { if (beforemax>ratemax) b0[b] = beforemax; else b0[b] = ratemax; m[b] = 15; Feb_Control_rate_correction_table[b] = (((int)(m[b]+0.5)&0xf)<<14) | ((int)(b0[b]+0.5)&0x3fff); } b=1024; break; } double x = Feb_Control_rate_meas[next_i] - b*4; double y = next_i; /*FILE_LOG(logDEBUG1, ("Start Loop x: %f,\t y: %f,\t s: %f,\t sx: %f,\t sy: %f,\t sxx: %f,\t sxy: %f,\t " "next_i: %d,\t b: %d,\t Feb_Control_rate_meas[next_i]: %f\n", x, y, s, sx, sy, sxx, sxy, next_i, b, Feb_Control_rate_meas[next_i]));*/ if (x < -0.5) continue; if (x > 3.5) break; s += 1; sx += x; sy += y; sxx += x*x; sxy += x*y; /*FILE_LOG(logDEBUG1, ("End Loop x: %f,\t y: %f,\t s: %f,\t sx: %f,\t sy: %f,\t sxx: %f,\t sxy: %f,\t " "next_i: %d,\t b: %d,\t Feb_Control_rate_meas[next_i]: %f\n", x, y, s, sx, sy, sxx, sxy, next_i, b, Feb_Control_rate_meas[next_i]));*/ } double delta = s*sxx - sx*sx; b0[b] = (sxx*sy - sx*sxy)/delta; m[b] = (s*sxy - sx*sy) /delta; beforemax= b0[b]; if (m[b]<0||m[b]>15) { m[b]=15; if (beforemax>ratemax) b0[b] = beforemax; else b0[b] = ratemax; } /*FILE_LOG(logDEBUG1, ("After Loop s: %f,\t sx: %f,\t sy: %f,\t sxx: %f,\t sxy: %f,\t " "next_i: %d,\t b: %d,\t Feb_Control_rate_meas[next_i]: %f\n", s, sx, sy, sxx, sxy, next_i, b, Feb_Control_rate_meas[next_i]));*/ // cout<ratemax) b0[b] = beforemax; else b0[b] = ratemax; m[b] = 15; } Feb_Control_rate_correction_table[b] = (((int)(m[b]+0.5)&0xf)<<14) | ((int)(b0[b]+0.5)&0x3fff); /*FILE_LOG(logDEBUG1, ("After Loop 4*b: %d\tbase:%d\tslope:%d\n",4*b, (int)(b0[b]+0.5), (int)(m[b]+0.5) ));*/ } if (Feb_Control_SetRateCorrectionTable(Feb_Control_rate_correction_table)) { Feb_Control_RateTable_Tau_in_nsec = tau_in_Nsec; Feb_Control_RateTable_Period_in_nsec = period_in_sec*1e9; return 1; } else { Feb_Control_RateTable_Tau_in_nsec = -1; Feb_Control_RateTable_Period_in_nsec = -1; return 0; } } int Feb_Control_SetRateCorrectionTable(unsigned int *table) { if (!table) { FILE_LOG(logERROR, ("Error: could not set rate correction table, point is zero.\n")); Feb_Control_SetRateCorrectionVariable(0); return 0; } FILE_LOG(logINFO, ("Setting rate correction table. %d %d %d %d ....\n", table[0],table[1],table[2],table[3])); //was added otherwise after an acquire, startdaqonlywatiforfinish waits forever if (!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY)) { FILE_LOG(logERROR, ("Could not Feb_Control_SetCommandRegister for loading trim bits.\n")); return 0; } FILE_LOG(logINFO, ("daq reset completely\n")); if (Module_TopAddressIsValid(&modules[1])) { if (Feb_Control_activated) { if (!Feb_Interface_WriteMemoryInLoops(Module_GetTopLeftAddress(&modules[Feb_Control_current_index]),1,0,1024,Feb_Control_rate_correction_table)|| !Feb_Interface_WriteMemoryInLoops(Module_GetTopRightAddress(&modules[Feb_Control_current_index]),1,0,1024,Feb_Control_rate_correction_table)|| (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { FILE_LOG(logERROR, ("could not write to memory (top) ::Feb_Control_SetRateCorrectionTable\n")); return 0; } } } else { if (Feb_Control_activated) { if (!Feb_Interface_WriteMemoryInLoops(Module_GetBottomLeftAddress(&modules[Feb_Control_current_index]),1,0,1024,Feb_Control_rate_correction_table)|| !Feb_Interface_WriteMemoryInLoops(Module_GetBottomRightAddress(&modules[Feb_Control_current_index]),1,0,1024,Feb_Control_rate_correction_table)|| (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { FILE_LOG(logERROR, ("could not write to memory (bottom) ::Feb_Control_SetRateCorrectionTable\n")); return 0; } } } return 1; } int Feb_Control_GetRateCorrectionVariable() { return (Feb_Control_subFrameMode&DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION);} void Feb_Control_SetRateCorrectionVariable(int activate_rate_correction) { if (activate_rate_correction) { Feb_Control_subFrameMode |= DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION; FILE_LOG(logINFO, ("Rate correction activated\n")); } else { Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION; FILE_LOG(logINFO, ("Rate correction deactivated\n")); } } int Feb_Control_PrintCorrectedValues() { int i; int delta, slope, base, lsb, corr; for (i=0; i < 4096; i++) { lsb = i&3; base = Feb_Control_rate_correction_table[i>>2] & 0x3fff; slope = ((Feb_Control_rate_correction_table[i>>2] & 0x3c000) >> 14); delta = slope*lsb; corr = delta+base; if (slope==15) corr= 3*slope+base; FILE_LOG(logDEBUG1, ("Readout Input: %d,\tBase:%d,\tSlope:%d,\tLSB:%d,\tDelta:%d\tResult:%d\tReal:%lf\n", i, base, slope, lsb, delta, corr, Feb_Control_rate_meas[i])); } return 1; } //So if software says now 40.00 you neeed to convert to mdegrees 40000(call it A1) and then //A1/65536/0.00198421639-273.15 int Feb_Control_GetLeftFPGATemp() { unsigned int temperature=0; if (Module_TopAddressIsValid(&modules[1])) Feb_Interface_ReadRegister(Module_GetTopLeftAddress (&modules[1]),FEB_REG_STATUS, &temperature); else Feb_Interface_ReadRegister(Module_GetBottomLeftAddress (&modules[1]),FEB_REG_STATUS, &temperature); temperature = temperature >> 16; temperature = ((((float)(temperature)/65536.0f)/0.00198421639f ) - 273.15f)*1000; // Static conversation, copied from xps sysmon standalone driver //division done in client to send int over network return (int)temperature; } int Feb_Control_GetRightFPGATemp() { unsigned int temperature=0; if (Module_TopAddressIsValid(&modules[1])) Feb_Interface_ReadRegister(Module_GetTopRightAddress (&modules[1]),FEB_REG_STATUS, &temperature); else Feb_Interface_ReadRegister(Module_GetBottomRightAddress (&modules[1]),FEB_REG_STATUS, &temperature); temperature = temperature >> 16; temperature = ((((float)(temperature)/65536.0f)/0.00198421639f ) - 273.15f)*1000; // Static conversation, copied from xps sysmon standalone driver //division done in client to send int over network return (int)temperature; } int64_t Feb_Control_GetMeasuredPeriod() { unsigned int sub_num = (Module_TopAddressIsValid(&modules[1])) ? Module_GetTopLeftAddress (&modules[1]): Module_GetBottomLeftAddress (&modules[1]); unsigned int value = 0; Feb_Interface_ReadRegister(sub_num,MEAS_PERIOD_REG, &value); return (int64_t)value*10; } int64_t Feb_Control_GetSubMeasuredPeriod() { unsigned int sub_num = (Module_TopAddressIsValid(&modules[1])) ? Module_GetTopLeftAddress (&modules[1]): Module_GetBottomLeftAddress (&modules[1]); unsigned int value = 0; Feb_Interface_ReadRegister(sub_num,MEAS_SUBPERIOD_REG, &value); return (int64_t)value*10; } int Feb_Control_SoftwareTrigger() { unsigned int orig_value = 0; Feb_Interface_ReadRegister(Feb_Control_AddressToAll(),DAQ_REG_CHIP_CMDS, &orig_value); unsigned int cmd = orig_value | DAQ_REG_CHIP_CMDS_INT_TRIGGER; if (Feb_Control_activated) { // set trigger bit FILE_LOG(logDEBUG1, ("Setting Trigger, Register:0x%x\n",cmd)); if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CHIP_CMDS,cmd,0,0)) { FILE_LOG(logERROR, ("Could not give software trigger\n")); return 0; } // unset trigger bit FILE_LOG(logDEBUG1, ("Unsetting Trigger, Register:0x%x\n",orig_value)); if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CHIP_CMDS,orig_value,0,0)) { FILE_LOG(logERROR, ("Could not give software trigger\n")); return 0; } FILE_LOG(logINFO, ("Software Internal Trigger Sent!\n")); } return 1; } uint32_t Feb_Control_WriteRegister(uint32_t offset, uint32_t data) { uint32_t value=0; if (Module_TopAddressIsValid(&modules[1])) { if (!Feb_Interface_WriteRegister(Module_GetTopRightAddress (&modules[1]),offset, data,0, 0)) { FILE_LOG(logERROR, ("Could not read tr value. Value read:%d\n", value)); value = 0; } if(!Feb_Interface_WriteRegister(Module_GetTopLeftAddress (&modules[1]),offset, data,0, 0)) { cprintf(RED,"Could not read tl value. Value read:%d\n", value); value = 0; } } else { if (!Feb_Interface_WriteRegister(Module_GetBottomRightAddress (&modules[1]),offset, data,0, 0)) { FILE_LOG(logERROR, ("Could not read br value. Value read:%d\n", value)); value = 0; } if(!Feb_Interface_WriteRegister(Module_GetBottomLeftAddress (&modules[1]),offset, data,0, 0)) { cprintf(RED,"Could not read bl value. Value read:%d\n", value); value = 0; } } return Feb_Control_ReadRegister(offset); } uint32_t Feb_Control_ReadRegister(uint32_t offset) { uint32_t value=0; uint32_t value1=0; if (Module_TopAddressIsValid(&modules[1])) { if (!Feb_Interface_ReadRegister(Module_GetTopRightAddress (&modules[1]),offset, &value)) { FILE_LOG(logERROR, ("Could not read value. Value read:%d\n", value)); value = 0; } printf("Read top right addr: 0x%08x\n", value); if(!Feb_Interface_ReadRegister(Module_GetTopLeftAddress (&modules[1]),offset, &value1)) { cprintf(RED,"Could not read value. Value read:%d\n", value1); value1 = 0; } printf("Read top left addr: 0x%08x\n", value1); if (value != value1) value = -1; } else { if (!Feb_Interface_ReadRegister(Module_GetBottomRightAddress (&modules[1]),offset, &value)) { FILE_LOG(logERROR, ("Could not read value. Value read:%d\n", value)); value = 0; } printf("Read bottom right addr: 0x%08x\n", value); if(!Feb_Interface_ReadRegister(Module_GetBottomLeftAddress (&modules[1]),offset, &value1)) { cprintf(RED,"Could not read value. Value read:%d\n", value1); value1 = 0; } printf("Read bottom left addr: 0x%08x\n", value1); if (value != value1) value = -1; } return value; }