From 87ce1ed7363339ad1486f6c46d2d8b45eea0e5cf Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 3 Feb 2017 12:29:44 +0100 Subject: [PATCH 1/2] moved tau to settings file, removed gain and offset, setting threshold loads settings file, setting threshold only sets client variable --- slsDetectorSoftware/Makefile | 4 +- slsDetectorSoftware/commonFiles/error_defs.h | 12 +- .../commonFiles/sls_detector_defs.h | 2 +- .../eigerDetectorServer/Beb.cxx | 470 ------ .../eigerDetectorServer/BebServer.cxx | 388 ----- .../eigerDetectorServer/Commands.txt | 28 - .../eigerDetectorServer/Eiger.cxx | 1027 ------------- .../eigerDetectorServer/Eiger.h | 179 --- .../EigerBackEndFunctions.c | 200 --- .../EigerHighLevelFunctions.c | 363 ----- .../eigerDetectorServer/EigerRegisterDefs.h | 116 -- .../eigerDetectorServer/EigerTest.cxx | 38 - .../eigerDetectorServer/Feb.cxx | 326 ----- .../eigerDetectorServer/FebControl.c | 22 +- .../eigerDetectorServer/FebControl.cxx | 1297 ----------------- .../eigerDetectorServer/FebInterface.cxx | 175 --- .../eigerDetectorServer/FebServer.cxx | 604 -------- .../eigerDetectorServer/HardwareIO.cxx | 87 -- .../LocalLinkInterface.cxx | 277 ---- .../eigerDetectorServer/LocalLinkTest.cxx | 28 - .../eigerDetectorServer/Makefile | 15 +- .../eigerDetectorServer/Test.cxx | 38 - .../bin/hv9m_blackfin_server | Bin 30184 -> 0 bytes .../eigerDetectorServer/build.sh | 19 - .../eigerDetectorServer/doxy_eiger.config | 94 -- .../eigerDetectorServer/renameServer.sh | 1 + .../eigerDetectorServer/setup.txt | 53 - .../eigerDetectorServer/setup_beb.txt | 12 - .../slsDetectorFunctionList.c | 82 +- .../slsDetectorServer_defs.h | 4 +- .../multiSlsDetector/multiSlsDetector.cpp | 75 +- .../slsDetector/slsDetector.cpp | 384 +++-- slsDetectorSoftware/slsDetector/slsDetector.h | 18 +- .../slsDetector/slsDetectorBase.h | 4 - .../slsDetector/slsDetectorCommand.cpp | 27 +- .../slsDetector/slsDetectorUsers.cpp | 8 - .../slsDetector/slsDetectorUsers.h | 13 - .../slsDetectorAnalysis/energyConversion.cpp | 155 +- .../slsDetectorAnalysis/energyConversion.h | 52 +- .../slsDetectorFunctionList.h | 6 +- .../slsDetectorServer_funcs.c | 145 +- slsDetectorSoftware/threadFiles/Task.h | 37 +- 42 files changed, 583 insertions(+), 6302 deletions(-) delete mode 100644 slsDetectorSoftware/eigerDetectorServer/Beb.cxx delete mode 100755 slsDetectorSoftware/eigerDetectorServer/BebServer.cxx delete mode 100644 slsDetectorSoftware/eigerDetectorServer/Commands.txt delete mode 100644 slsDetectorSoftware/eigerDetectorServer/Eiger.cxx delete mode 100644 slsDetectorSoftware/eigerDetectorServer/Eiger.h delete mode 100644 slsDetectorSoftware/eigerDetectorServer/EigerBackEndFunctions.c delete mode 100644 slsDetectorSoftware/eigerDetectorServer/EigerHighLevelFunctions.c delete mode 100644 slsDetectorSoftware/eigerDetectorServer/EigerRegisterDefs.h delete mode 100644 slsDetectorSoftware/eigerDetectorServer/EigerTest.cxx delete mode 100644 slsDetectorSoftware/eigerDetectorServer/Feb.cxx delete mode 100644 slsDetectorSoftware/eigerDetectorServer/FebControl.cxx delete mode 100644 slsDetectorSoftware/eigerDetectorServer/FebInterface.cxx delete mode 100755 slsDetectorSoftware/eigerDetectorServer/FebServer.cxx delete mode 100644 slsDetectorSoftware/eigerDetectorServer/HardwareIO.cxx delete mode 100644 slsDetectorSoftware/eigerDetectorServer/LocalLinkInterface.cxx delete mode 100644 slsDetectorSoftware/eigerDetectorServer/LocalLinkTest.cxx delete mode 100644 slsDetectorSoftware/eigerDetectorServer/Test.cxx delete mode 100755 slsDetectorSoftware/eigerDetectorServer/bin/hv9m_blackfin_server delete mode 100755 slsDetectorSoftware/eigerDetectorServer/build.sh delete mode 100644 slsDetectorSoftware/eigerDetectorServer/doxy_eiger.config delete mode 100644 slsDetectorSoftware/eigerDetectorServer/setup.txt delete mode 100644 slsDetectorSoftware/eigerDetectorServer/setup_beb.txt diff --git a/slsDetectorSoftware/Makefile b/slsDetectorSoftware/Makefile index eb3708d50..36eda6c4c 100644 --- a/slsDetectorSoftware/Makefile +++ b/slsDetectorSoftware/Makefile @@ -69,14 +69,14 @@ gotthardVirtualServer: $(SRC_MYTHEN_SVC) %.o : %.cpp %.h Makefile - $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) -lpthread -lrt $(LIBZMQ) #$(FLAGS) + $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) -lpthread -lrt $(LIBZMQ) #$(FLAGS) package: $(OBJS) $(DESTDIR)/libSlsDetector.so $(DESTDIR)/libSlsDetector.a $(DESTDIR)/libSlsDetector.so: $(OBJS) - $(CXX) -shared -Wl,-soname,libSlsDetector.so -o libSlsDetector.so $(OBJS) -lc $(INCLUDES) $(DFLAGS) $(FLAGS) $(EPICSFLAGS) -L/usr/lib64 -lpthread -lrt $(LIBZMQ) + $(CXX) -shared -Wl,-soname,libSlsDetector.so -o libSlsDetector.so $(OBJS) -lc $(INCLUDES) $(DFLAGS) $(FLAGS) $(EPICSFLAGS) -L/usr/lib64 -lpthread -lrt $(LIBZMQ) $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) mv libSlsDetector.so $(DESTDIR) diff --git a/slsDetectorSoftware/commonFiles/error_defs.h b/slsDetectorSoftware/commonFiles/error_defs.h index fed6af415..5aa6f9a1b 100644 --- a/slsDetectorSoftware/commonFiles/error_defs.h +++ b/slsDetectorSoftware/commonFiles/error_defs.h @@ -19,11 +19,12 @@ using namespace std; /** Error flags */ /*Assumption: Only upto 63 detectors */ -#define CRITICAL_ERROR_MASK 0xFFFFFFFF #define MULTI_DETECTORS_NOT_ADDED 0x8000000000000000ULL +#define CRITICAL_ERROR_MASK 0xFFFFFFFF +// 0xFFFFFFFF00000000ULL #define CANNOT_CONNECT_TO_DETECTOR 0x4000000000000000ULL #define CANNOT_CONNECT_TO_RECEIVER 0x2000000000000000ULL #define COULDNOT_SET_CONTROL_PORT 0x1000000000000000ULL @@ -40,10 +41,9 @@ using namespace std; #define COULD_NOT_CONFIGURE_MAC 0x0002000000000000ULL #define COULDNOT_START_RECEIVER 0x0001000000000000ULL // default error like starting threads #define COULDNOT_STOP_RECEIVER 0x0000800000000000ULL - // 0xFFFFFFFF00000000ULL - +// 0x00000000FFFFFFFFULL #define COULDNOT_SET_NETWORK_PARAMETER 0x0000000000000001ULL #define COULDNOT_SET_ROI 0x0000000000000002ULL #define RECEIVER_READ_FREQUENCY 0x0000000000000004ULL @@ -74,8 +74,9 @@ using namespace std; #define RECEIVER_READ_TIMER 0x0000000008000000ULL #define RECEIVER_ACQ_TIME_NOT_SET 0x0000000010000000ULL #define RECEIVER_FLIPPED_DATA_NOT_SET 0x0000000020000000ULL - +#define THRESHOLD_NOT_SET 0x0000000040000000ULL // 0x00000000FFFFFFFFULL + /** @short class returning all error messages for error mask */ class errorDefs { @@ -234,6 +235,9 @@ public: if(slsErrorMask&RECEIVER_FLIPPED_DATA_NOT_SET) retval.append("Could not set receiver flipped data/bottom\n"); + if(slsErrorMask&THRESHOLD_NOT_SET) + retval.append("Could not set threshold\n"); + //------------------------------------------------------ length of message diff --git a/slsDetectorSoftware/commonFiles/sls_detector_defs.h b/slsDetectorSoftware/commonFiles/sls_detector_defs.h index 8e3a82689..df7e34c53 100755 --- a/slsDetectorSoftware/commonFiles/sls_detector_defs.h +++ b/slsDetectorSoftware/commonFiles/sls_detector_defs.h @@ -126,7 +126,7 @@ class slsDetectorDefs: public virtual slsReceiverDefs{ typedef struct { int module; /**< is the module number */ int serialnumber; /**< is the module serial number */ - int nchan; /**< is the number of channels per chip */ + int nchan; /**< is the number of channels on the module*/ int nchip; /**< is the number of chips on the module */ int ndac; /**< is the number of dacs on the module */ int nadc; /**< is the number of adcs on the module */ diff --git a/slsDetectorSoftware/eigerDetectorServer/Beb.cxx b/slsDetectorSoftware/eigerDetectorServer/Beb.cxx deleted file mode 100644 index 80746bbe6..000000000 --- a/slsDetectorSoftware/eigerDetectorServer/Beb.cxx +++ /dev/null @@ -1,470 +0,0 @@ - -/** - * @author Ian Johnson - * @version 1.0 - */ - - -//return reversed 1 means good, 0 means failed - - - -#include -#include -#include -#include -#include -#include -#include - - -#include "xfs_types.h" -#include "xparameters.h" - -#include "Beb.h" - -using namespace std; - -BebInfo::BebInfo(unsigned int beb_num){beb_number=beb_num;serial_address=0;src_mac_1GbE="";src_mac_10GbE="";src_ip_1GbE="";src_ip_10GbE=""; src_port_1GbE=src_port_10GbE=0;} -bool BebInfo::SetHeaderInfo(bool ten_gig, string src_mac, string src_ip, unsigned int src_port){ - if(ten_gig){ src_mac_10GbE = src_mac; src_ip_10GbE = src_ip; src_port_10GbE = src_port;} - else { src_mac_1GbE = src_mac; src_ip_1GbE = src_ip; src_port_1GbE = src_port;} - return 1; -} - -bool BebInfo::SetSerialAddress(unsigned int a){ - //address pre shifted - if(a>0xff) return 0; - serial_address = 0x04000000 | ((a&0xff)<<16); - return 1; -} - -void BebInfo::Print(){ - cout<<"\t"<Print(); - cout<InitNewMemory(XPAR_PLB_LL_NEW_MEMORY, arg1)) - printf("New Memory FAIL\n"); - else - printf("New Memory OK\n"); - -} - -Beb::~Beb(){ - delete ll; - delete [] send_data_raw; - delete [] recv_data_raw; -} - -void Beb::ClearBebInfos(){ - for(unsigned int i=0;iSetSerialAddress(0xff)) beb_infos.push_back(b0); //all bebs for reset and possibly get request data? - - if(!ReadSetUpFromFile("/home/root/executables/setup_beb.txt")) return 0; -/* - //loop through file to fill vector. - BebInfo* b = new BebInfo(26); - b->SetSerialAddress(0); //0xc4000000 - b->SetHeaderInfo(0,"00:50:c2:46:d9:34","129.129.205.78",42000 + 26); // 1 GbE, ip address can be acquire from the network "arp" - b->SetHeaderInfo(1,"00:50:c2:46:d9:35","10.0.26.1",52000 + 26); //10 GbE, everything calculable/setable - beb_infos.push_back(b); -*/ - - return CheckSourceStuffBebInfo(); -} - - - -bool Beb::SetBebSrcHeaderInfos(unsigned int beb_number, bool ten_gig, string src_mac, string src_ip,unsigned int src_port){ - //so that the values can be reset externally for now.... - - unsigned int i = GetBebInfoIndex(beb_number); - if(!i) return 0; //i must be greater than 0, zero is the global send - beb_infos[i]->SetHeaderInfo(ten_gig,src_mac,src_ip,src_port); - - cout<<"Printing Beb info number ("<Print(); - cout<>cmd_st; - if(!strcmp("add_beb",cmd_st)){ - if(!(iss>>value_i[0]>>value_i[1]>>str_mac1>>str_ip1>>str_mac10>>str_ip10)){ - cout<<"Error adding beb from "<SetSerialAddress(value_i[1]); - b->SetHeaderInfo(0,str_mac1,str_ip1,42000+value_i[0]); - b->SetHeaderInfo(1,str_mac10,str_ip10,52000+value_i[0]); - beb_infos.push_back(b); - } - } - - infile.close(); - - return 1; -} - - - -bool Beb::CheckSourceStuffBebInfo(){ - for(unsigned int i=1;iGetBebNumber(),0,"00:00:00:00:00:00","10.0.0.1",20000)||!SetHeaderData(beb_infos[i]->GetBebNumber(),1,"00:00:00:00:00:00","10.0.0.1",20000)){ - cout<<"Error in BebInfo for module number "<GetBebNumber()<<"."<Print(); - return 0; - } - } - return 1; -} - -unsigned int Beb::GetBebInfoIndex(unsigned int beb_numb){ - if(!beb_numb) return 0; - - for(unsigned int i=1;iGetBebNumber()) return i; - return 0; -} - - - -bool Beb::WriteTo(unsigned int index){ - if(index>=beb_infos.size()){ - cout<<"WriteTo index error."<GetSerialAddress(); - if(ll->Write(4,send_data_raw)!=4) return 0; - - send_data_raw[0] = 0xc0000000; - if((send_ndata+1)*4!=ll->Write((send_ndata+1)*4,send_data_raw)) return 0; - - return 1; -} - - -void Beb::SwapDataFun(bool little_endian, unsigned int n, unsigned int *d){ - if(little_endian) for(unsigned int i=0;i>8) | ((d[i]&0xff000000)>>24)); //little_endian - else for(unsigned int i=0;i>16)); -} - - -bool Beb::SetByteOrder(){ - send_data_raw[0] = 0x8fff0000; - if(ll->Write(4,send_data_raw)!=4) return 0; - - while((ll->Read(recv_buffer_size*4,recv_data_raw)/4)>0) cout<<"\t) Cleanning buffer ..."<GetSrcMAC(ten_gig),beb_infos[i]->GetSrcIP(ten_gig),beb_infos[i]->GetSrcPort(ten_gig),dst_mac,dst_ip,dst_port); -} - -bool Beb::SetHeaderData(string src_mac, string src_ip, unsigned int src_port, string dst_mac, string dst_ip, unsigned int dst_port){ - /* example header*/ - //static unsigned int* word_ptr = new unsigned int [16]; - static udp_header_type udp_header = { - {0x00, 0x50, 0xc5, 0xb2, 0xcb, 0x46}, // DST MAC - {0x00, 0x50, 0xc2, 0x46, 0xd9, 0x02}, // SRC MAC - {0x08, 0x00}, - {0x45}, - {0x00}, - {0x00, 0x00}, - {0x00, 0x00}, - {0x40}, - {0x00}, - {0xff}, - {0x11}, - {0x00, 0x00}, - {129, 205, 205, 128}, // Src IP - {129, 205, 205, 122}, // Dst IP - {0x0f, 0xa1}, - {0x13, 0x89}, - {0x00, 0x00}, //{0x00, 0x11}, - {0x00, 0x00} - }; - - if(!SetMAC(src_mac,&(udp_header.src_mac[0]))) return 0; - if(!SetIP(src_ip,&(udp_header.src_ip[0]))) return 0; - if(!SetPortNumber(src_port,&(udp_header.src_port[0]))) return 0; - - if(!SetMAC(dst_mac,&(udp_header.dst_mac[0]))) return 0; - if(!SetIP(dst_ip,&(udp_header.dst_ip[0]))) return 0; - if(!SetPortNumber(dst_port,&(udp_header.dst_port[0]))) return 0; - - - AdjustIPChecksum(&udp_header); - - unsigned int* base_ptr = (unsigned int *) &udp_header; - unsigned int num_words = ( sizeof(udp_header_type) + 3 ) / 4; - // for(unsigned int i=0; i "<3))||(i==3&&(ip.length()<1||ip.length()>3))){ - cout<<"Error: in ip address -> "<> 8) & 0xff ; - dst_ptr[1] = port_number & 0xff; - return 1; -} - - -void Beb::AdjustIPChecksum(udp_header_type *ip){ - unsigned char *cptr = (unsigned char *) ip->ver_headerlen; - - ip->ip_header_checksum[0] = 0; - ip->ip_header_checksum[1] = 0; - ip->total_length[0] = 0; - ip->total_length[1] = 28; // IP + UDP Header Length - - // calc ip checksum - unsigned int ip_checksum = 0; - for(unsigned int i=0; i<10; i++){ - ip_checksum += ( (cptr[2*i] << 8) + (cptr[2*i + 1]) ); - if (ip_checksum & 0x00010000) ip_checksum = (ip_checksum + 1) & 0x0000ffff; - } - - ip->ip_header_checksum[0] = (ip_checksum >> 8) & 0xff ; - ip->ip_header_checksum[1] = ip_checksum & 0xff ; -} - - - -bool Beb::SendMultiReadRequest(unsigned int beb_number, unsigned int left_right, bool ten_gig, unsigned int dst_number, unsigned int npackets, unsigned int packet_size, bool stop_read_when_fifo_empty){ - - unsigned int i = GetBebInfoIndex(beb_number); //zero is the global send - - send_ndata = 3; - if(left_right == 1) send_data[0] = 0x00040000; - else if(left_right == 2) send_data[0] = 0x00080000; - else if(left_right == 3) send_data[0] = 0x000c0000; - else return 0; - - //packet_size/=2; - if(dst_number>0x3f) return 0; - if(packet_size>0x3ff) return 0; - if(npackets==0||npackets>0x100) return 0; - npackets--; - - - send_data[1] = 0x62000000 | (!stop_read_when_fifo_empty) << 27 | (ten_gig==1) << 24 | packet_size << 14 | dst_number << 8 | npackets; - send_data[2] = 0; - - SwapDataFun(0,2,&(send_data[1])); - - if(!WriteTo(i)) return 0; - - return 1; -} - - -bool Beb::SetUpTransferParameters(short the_bit_mode){ - if(the_bit_mode!=4&&the_bit_mode!=8&&the_bit_mode!=16&&the_bit_mode!=32) return 0; - bit_mode = the_bit_mode; - - //nimages = the_number_of_images; - // on_dst = 0; - - return 1; -} - -bool Beb::RequestNImages(unsigned int beb_number, unsigned int left_right, bool ten_gig, unsigned int dst_number, unsigned int nimages, bool test_just_send_out_packets_no_wait){ - if(dst_number>64) return 0; - - unsigned int header_size = 4; //4*64 bits - unsigned int packet_size = ten_gig ? 0x200 : 0x80; // 4k or 1k packets - unsigned int npackets = ten_gig ? bit_mode*4 : bit_mode*16; - bool in_two_requests = (!ten_gig&&bit_mode==32); - if(in_two_requests) npackets/=2; - - //cout<<"here: "< -#include -#include -#include -#include // std::remove_if - -#include -#include -#include -#include -#include - -#include "Beb.h" -#include "slsDetectorServer_defs.h" //include port number - -using namespace std; - -enum cmd_string {evNotFound, - evRequestImages,evTestRequest, - evSetBitMode, - evSetupTableEntry,evSetDstParameters, - evTest,evTestSend, - evExitServer}; - -map enum_map; - -void init(){ - - enum_map["requestimages"] = evRequestImages; // - enum_map["testrequest"] = evTestRequest; // - - enum_map["setbitmode"] = evSetBitMode; // (resets on_dst and dst_requested) - - enum_map["setuptableentry"] = evSetupTableEntry; - enum_map["setdstparameters"] = evSetDstParameters; // (resets on_dst and dst_requested) - - enum_map["test"] = evTest; - enum_map["testsend"] = evTestSend; - enum_map["exitserver"] = evExitServer; - -} - -int server_list_s; -int server_conn_s; -int AccpetConnectionAndWaitForData(char* buffer, int maxlength); -bool WriteNClose(const char* buffer, int length); -bool SetupListenSocket(unsigned short int port); - - -string LowerCase(string str); -string GetNextString(string str,bool start_from_beginning=0); -void AddNumber(string& str, int n, int location=-1);//-1 means append - -int main(int argc, char* argv[]){ - cout<1) - bebs = new Beb(atoi(argv[1])); - else - bebs = new Beb(-1); - - // unsigned short int port_number = atoi(argv[1]); - - unsigned short int port_number = BEB_PORT; - if(!SetupListenSocket(port_number)) return 1; - - - int length=1000; - char data[1000]; - - int stop = 0; - time_t rawtime; - struct tm *timeinfo; - - bool send_to_ten_gig = 0; - int ndsts_in_use=32; - unsigned int nimages_per_request=1; - - int on_dst=0; - bool dst_requested[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - - while(!stop){ - - cout< "<0){ - return_start_pos = return_message.length(); - - switch(enum_map.find(LowerCase(cmd))->second){ - - case evRequestImages : - tmp_str[0] = GetNextString(data); - n[0] = atoi(tmp_str[0].data()); //dst number - if(tmp_str[0].length()<1||n[0]<0||n[0]>=ndsts_in_use){ - return_message.append("\tError executing: RequestImages (note dst_number must be less than ndsts_in_use that is set with SetDstParameters\n"); - ret_val = 1; - }else{ - dst_requested[n[0]] = 1; - ret_val=0; - tmp_str[1] = " ( "; - while(dst_requested[on_dst]){ - //waits on data - if((ret_val = (!bebs->RequestNImages(0,1,send_to_ten_gig,on_dst,nimages_per_request)||!bebs->RequestNImages(0,2,send_to_ten_gig,0x20|on_dst,nimages_per_request)))) break; - AddNumber(tmp_str[1],on_dst);tmp_str[1].append(" "); - dst_requested[on_dst++]=0; - on_dst%=ndsts_in_use; - } - if(ret_val) return_message.append("\tError executing: RequestImages "); - else{ return_message.append("\tExecuted: RequestImages "); AddNumber(return_message,n[0]);} - return_message.append(tmp_str[1]); - return_message.append(" )\n"); - } - break; - - case evTestRequest : - tmp_str[0] = GetNextString(data); - n[0] = atoi(tmp_str[0].data()); //dst number - if(tmp_str[0].length()<1||n[0]<0||n[0]>=ndsts_in_use){ - return_message.append("\tError executing: TestRequest (note dst_number must be less than 2xndsts_in_use that is set with SetDstParameters\n"); - ret_val = 1; - }else{ - ret_val = (!bebs->RequestNImages(0,1,send_to_ten_gig,n[0],nimages_per_request,1)||!bebs->RequestNImages(0,2,send_to_ten_gig,0x20|n[0],nimages_per_request,1)); - if(ret_val) return_message.append("\tError executing: TestRequest \n"); - else{ return_message.append("\tExecuted: TestRequest "); AddNumber(return_message,n[0]); return_message.append("\n");} - } - break; - - case evSetBitMode : - on_dst = 0; - for(n[0]=0;n[0]<32;n[0]++) dst_requested[n[0]] = 0; //clear dst requested - n[0] = atoi(GetNextString(data).data()); - if((ret_val = !bebs->SetUpTransferParameters(n[0]))) return_message.append("\tError executing: SetBitMode \n"); - else{ return_message.append("\tExecuted: SetBitMode ");AddNumber(return_message,n[0]);return_message.append("\n");} - break; - - case evSetDstParameters : //move below // - on_dst = 0; - for(n[0]=0;n[0]<32;n[0]++) dst_requested[n[0]] = 0; //clear dst requested - n[0] = atoi(GetNextString(data).data()); //<1GbE(0) or 10GbE(1)> - n[1] = atoi(GetNextString(data).data()); // - n[2] = atoi(GetNextString(data).data()); // 0)> - - if((n[0]!=0&&n[0]!=1)||(n[1]<1||n[1]>32)||n[2]<1){ - return_message.append("\tError executing: SetDstParameters <1GbE(0) or 10GbE(1)> \n"); - ret_val=1; - } - else{ - send_to_ten_gig = n[0]; - ndsts_in_use=n[1]; - nimages_per_request=n[2]; - return_message.append("\tExecuted: SetDstParameters "); - AddNumber(return_message,n[0]);return_message.append(" "); - AddNumber(return_message,n[1]);return_message.append(" "); - AddNumber(return_message,n[2]);return_message.append(" "); - ret_val=0; - } - break; - - case evSetupTableEntry : - n[0] = atoi(GetNextString(data).data()); //beb_number; - n[1] = atoi(GetNextString(data).data()); //<1GbE(0) or 10GbE(1)> - n[2] = atoi(GetNextString(data).data()); //header_number - tmp_str[0] = GetNextString(data); //src_mac - tmp_str[1] = GetNextString(data); //src_ip - n[3] = atoi(GetNextString(data).data()); //src_port - tmp_str[2] = GetNextString(data); //dst_mac - tmp_str[3] = GetNextString(data); //dst_ip - n[4] = atoi((tmp_str[4]=GetNextString(data)).data()); //dst_port - - if(n[0]<1||(n[1]!=0&&n[1]!=1)||(n[2]<0||n[2]>63)||tmp_str[0].length()<1||tmp_str[1].length()<1||n[3]<0||tmp_str[2].length()<1||tmp_str[3].length()<1||n[4]<0||tmp_str[4].length()<1){ - return_message.append("\tError executing: SetupTableEntry <1GbE(0) or 10GbE(1)> \n"); - ret_val = 1; - }else{ - for(int i=0;i<32;i++)/** modified for Aldo*/ - ret_val = !bebs->SetBebSrcHeaderInfos(n[0],n[1],tmp_str[0],tmp_str[1],n[3])||!bebs->SetUpUDPHeader(n[0],n[1],n[2]+i,tmp_str[2],tmp_str[3],n[4]); - - if(ret_val) return_message.append("\tError Executing: SetupTableEntry "); - else return_message.append("\tExecuted: SetupTableEntry "); - AddNumber(return_message,n[0]);return_message.append(" "); - AddNumber(return_message,n[1]);return_message.append(" "); - AddNumber(return_message,n[2]);return_message.append(" "); - return_message.append(tmp_str[0]);return_message.append(" "); - return_message.append(tmp_str[1]);return_message.append(" "); - AddNumber(return_message,n[3]);return_message.append(" "); - return_message.append(tmp_str[2]);return_message.append(" "); - return_message.append(tmp_str[3]);return_message.append(" "); - AddNumber(return_message,n[4]); - } - break; - - case evTest : - n[0] = atoi(GetNextString(data).data()); - if(n[0]<1){ - return_message.append("\tError executing: Test \n"); - ret_val = 1; - }else{ - ret_val = !bebs->Test(n[0]); - if(ret_val) return_message.append("\tError Executing: Test "); - else return_message.append("\tExecuted: Test "); - AddNumber(return_message,n[0]); - } - break; - - - case evTestSend : - n[0] = atoi(GetNextString(data).data()); //beb_number; - n[1] = atoi(GetNextString(data).data()); //giga bit, ten giga bit - n[2] = atoi((tmp_str[0]=GetNextString(data)).data()); //header_number - - if(n[0]<1||(n[1]!=0&&n[1]!=1)||(n[2]<0||n[2]>63)||tmp_str[0].length()<1){ - return_message.append("\tError executing: TestSend <1GbE(0) or 10GbE(1)> \n"); - ret_val = 1; - }else{ - ret_val = !bebs->SendMultiReadRequest(n[0],1,n[1],n[2],1,0); - - if(ret_val) return_message.append("\tError Executing: TestSend "); - else return_message.append("\tExecuted: TestSend "); - AddNumber(return_message,n[0]);return_message.append(" "); - AddNumber(return_message,n[1]);return_message.append(" "); - AddNumber(return_message,n[2]);return_message.append(" "); - } - break; - - case evExitServer : - return_message.append("\tExiting Server ....\n"); - stop = 1; - ret_val = -200; - break; - - default : - return_message.append("\tWarning command \""); - return_message.append(cmd); - return_message.append("\" not found.\n"); - return_message.append("\t\tValid commands: "); - map::iterator it = enum_map.begin(); - while(it!=enum_map.end()){ - return_message.append((it++)->first); - return_message.append(" "); - } - - ret_val=-100; - break; - } - - return_message.append("\n"); - AddNumber(return_message,ret_val,return_start_pos); - if(ret_val!=0) break; - - cmd = GetNextString(data); - } - return_message.append("\n\n\n"); - - AddNumber(return_message,ret_val,0); - cout<0) return sub; - } - - return ""; -} - - - -void AddNumber(string& str, int n, int location){ - static char retval_st[100]; - sprintf(retval_st,"%d",n); - - if(location<0) str.append(retval_st); - else str.insert(location,retval_st); -} - - -bool SetupListenSocket(unsigned short int port){ - server_list_s=0; - server_conn_s=0; - - if((server_list_s = socket(AF_INET, SOCK_STREAM, 0))<0) return 0; - - struct sockaddr_in servaddr; /* socket address structure */ - memset(&servaddr, 0, sizeof(servaddr)); - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = htonl(INADDR_ANY); - servaddr.sin_port = htons(port); - - if(bind(server_list_s,(struct sockaddr *) &servaddr,sizeof(servaddr))<0) return 0; - - if(listen(server_list_s,32) < 0){ // 1024 /* Backlog for listen() */ - return 0; - } - - return 1; -} - - -int AccpetConnectionAndWaitForData(char* buffer, int maxlength){ - if(server_list_s==0||maxlength<=0) return 0; - - if((server_conn_s = accept(server_list_s,NULL,NULL))< 0) return 0; - - int nread = read(server_conn_s,buffer,maxlength-1); - - if(nread<0) return 0; - - buffer[nread]='\0'; - return nread; -} - -bool WriteNClose(const char* buffer, int length){ - if(server_conn_s==0||length<=0) return 0; - - int nsent = write(server_conn_s,buffer,length); - if(close(server_conn_s)<0) return 0; - - server_conn_s=0; - return (nsent==length); -} - - - - diff --git a/slsDetectorSoftware/eigerDetectorServer/Commands.txt b/slsDetectorSoftware/eigerDetectorServer/Commands.txt deleted file mode 100644 index e03e20865..000000000 --- a/slsDetectorSoftware/eigerDetectorServer/Commands.txt +++ /dev/null @@ -1,28 +0,0 @@ - -Internal setup: - setdac - trimbits - rate correction tau - high voltage - - -Setup: - photon energy - dynamic range (4,8,16,32) - number of images - exposure time - exposure period - readout speed(full speed, 1/2 speed, 1/4 or super slow) - readout mode (parallel, non-parallel or super safe) - trigger mode (internal,external start of series, external start of acquisitions, external window) - trigger polarity (pos/neg) - external gating (on, pos/neg) - - -Acquisition: - start acquisition - stop acquisition - acquisition in progress - wait until daq is finished - status (needs to be implemented) - diff --git a/slsDetectorSoftware/eigerDetectorServer/Eiger.cxx b/slsDetectorSoftware/eigerDetectorServer/Eiger.cxx deleted file mode 100644 index 43ac6c5fc..000000000 --- a/slsDetectorSoftware/eigerDetectorServer/Eiger.cxx +++ /dev/null @@ -1,1027 +0,0 @@ - -/** - * @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 ...."< -#include - -#include "Feb.h" - - -class Module{ - - private: - unsigned int module_number; - bool top_address_valid; - unsigned int top_left_address; - unsigned int top_right_address; - bool bottom_address_valid; - unsigned int bottom_left_address; - unsigned int bottom_right_address; - - unsigned int idelay_top[4]; //ll,lr,rl,ll - unsigned int idelay_bottom[4]; //ll,lr,rl,ll - float high_voltage; - float* top_dac; - float* bottom_dac; - - public: - Module(unsigned int number, unsigned int address_top); //for half module() - Module(unsigned int number, unsigned int address_top, unsigned int address_bottom); - ~Module(); - - static const unsigned int ndacs; - static const std::string dac_names[16]; - - unsigned int GetModuleNumber() {return module_number;} - bool TopAddressIsValid() {return top_address_valid;} - unsigned int GetTopBaseAddress() {return (top_left_address&0xff);} - unsigned int GetTopLeftAddress() {return top_left_address;} - unsigned int GetTopRightAddress() {return top_right_address;} - unsigned int GetBottomBaseAddress() {return (bottom_left_address&0xff);} - bool BottomAddressIsValid() {return bottom_address_valid;} - unsigned int GetBottomLeftAddress() {return bottom_left_address;} - unsigned int GetBottomRightAddress() {return bottom_right_address;} - - unsigned int SetTopIDelay(unsigned int chip,unsigned int value) { return TopAddressIsValid() &&chip<4 ? (idelay_top[chip]=value) : 0;} //chip 0=ll,1=lr,0=rl,1=rr - unsigned int GetTopIDelay(unsigned int chip) { return chip<4 ? idelay_top[chip] : 0;} //chip 0=ll,1=lr,0=rl,1=rr - unsigned int SetBottomIDelay(unsigned int chip,unsigned int value) { return BottomAddressIsValid() &&chip<4 ? (idelay_bottom[chip]=value) : 0;} //chip 0=ll,1=lr,0=rl,1=rr - unsigned int GetBottomIDelay(unsigned int chip) { return chip<4 ? idelay_bottom[chip] : 0;} //chip 0=ll,1=lr,0=rl,1=rr - - float SetHighVoltage(float value) { return TopAddressIsValid() ? (high_voltage=value) : -1;} - float GetHighVoltage() { return high_voltage;} - - float SetTopDACVoltage(unsigned int i, float value) { return (i modules; - void ClearModules(); - - unsigned int staticBits; //program=1,m4=2,m8=4,test=8,rotest=16,cs_bar_left=32,cs_bar_right=64 - unsigned int acquireNReadoutMode; //safe or parallel, half or full speed - unsigned int triggerMode; //internal timer, external start, external window, signal polarity (external trigger and enable) - unsigned int externalEnableMode; //external enabling engaged and it's polarity - unsigned int subFrameMode; - - unsigned int photon_energy_eV; - - unsigned int nimages; - float exposure_time_in_sec; - float exposure_period_in_sec; - - unsigned int trimbit_size; - unsigned char* last_downloaded_trimbits; - - void PrintModuleList(); - bool GetModuleIndex(unsigned int module_number, unsigned int& module_index); - bool CheckModuleAddresses(unsigned int top_address, unsigned int bottom_address); - bool AddModule(unsigned int module_number, unsigned int top_address); - bool AddModule(unsigned int module_number, unsigned int top_address, unsigned int bottom_address, bool half_module=0); - - bool GetDACNumber(std::string s, unsigned int& n); - bool SendDACValue(unsigned int dst_num, unsigned int ch, float& value); - bool VoltageToDAC(float value, unsigned int& digital, unsigned int nsteps, float vmin, float vmax); - float DACToVoltage(unsigned int digital,unsigned int nsteps,float vmin,float vmax); - - bool SendHighVoltage(unsigned int module_index, float& value); - - bool SendIDelays(unsigned int dst_num, bool chip_lr, unsigned int channels, unsigned int ndelay_units); - - bool SetStaticBits(); - bool SetStaticBits(unsigned int the_static_bits); - - unsigned int ConvertTimeToRegister(float time_in_sec); - - bool SetCommandRegister(unsigned int cmd); - bool GetDAQStatusRegister(int socket_num, unsigned int &ret_status); - bool StartDAQOnlyNWaitForFinish(int sleep_time_us=5000); - bool ResetDataStream(); - - bool ResetChipCompletely(); - - public: - Eiger(); - virtual ~Eiger(); - - bool Init(); - bool ReadSetUpFileToAddModules(std::string file_name); - bool ReadSetUpFile(unsigned int module_num, std::string file_name); - bool CheckSetup(); - - unsigned int GetNModules(); - unsigned int GetNHalfModules(); - - //bool SetHighVoltage(float value); - bool SetHighVoltage(unsigned int module_num,float value); - - bool SetPhotonEnergy(unsigned int full_energy_eV); - unsigned int GetPhotonEnergy(){return photon_energy_eV;} - - bool SetIDelays(unsigned int module_num, unsigned int ndelay_units); - bool SetIDelays(unsigned int module_num, unsigned int chip_pos, unsigned int ndelay_units); - - bool SetDAC(std::string s, float value); - bool GetDAC(std::string s, float& ret_value); - bool GetDACName(unsigned int dac_num, std::string &s); - - bool SetTrimbits(unsigned char* trimbits); - unsigned char* GetTrimbits(); - - - - bool Reset(); - bool StartAcquisition(); - bool StopAcquisition(); - bool AcquisitionInProgress(); - bool WaitForFinishedFlag(int sleep_time_us=5000); - - //functions for setting up exposure - void PrintAcquisitionSetup(); - bool SetNImages(unsigned int n_images); - unsigned int GetNImages(); - bool SetExposureTime(float the_exposure_time_in_sec); - float GetExposureTime(); - bool SetExposurePeriod(float the_exposure_period_in_sec); - float GetExposurePeriod(); - bool SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo); - unsigned int GetDynamicRange(); - bool SetReadoutSpeed(unsigned int readout_speed=0); //0->full,1->half,2->quarter or 3->super_slow - bool SetReadoutMode(unsigned int readout_mode=0); //0->parallel,1->non-parallel,2-> safe_mode - bool SetTriggerMode(unsigned int trigger_mode=0, bool polarity=1); - bool SetExternalEnableMode(bool use_external_enable=0, bool polarity=1); - - - //functions for testing - bool SetTestModeVariable(bool on=1); - bool GetTestModeVariable(); - - bool FebTest(){return Feb::Test();} - -}; - - -#endif diff --git a/slsDetectorSoftware/eigerDetectorServer/EigerBackEndFunctions.c b/slsDetectorSoftware/eigerDetectorServer/EigerBackEndFunctions.c deleted file mode 100644 index 1378160f5..000000000 --- a/slsDetectorSoftware/eigerDetectorServer/EigerBackEndFunctions.c +++ /dev/null @@ -1,200 +0,0 @@ - -/** - * @author Ian Johnson - * @version 1.0 - */ - - -#include -#include -#include -#include - - - -#include "slsDetectorServer_defs.h" //include port number - -struct sockaddr_in eiger_back_socket_addr; -int eiger_back_max_message_length = 1024; -char eiger_back_message[1024]; -int eiger_back_message_length = 0; -int eiger_back_ret_val=0; - - -int bit_mode=0; -int ten_giga=0; - -int EigerBackInit(){ - static int passed = 0; - - if(!passed){ - struct hostent *dst_host; - if((dst_host = gethostbyname("localhost")) == NULL){ //or look into getaddrinfo(3) - fprintf(stderr,"ERROR, no such host\n"); - return 0; - }else{ - //struct sockaddr_in eiger_back_socket_addr; - int port = BEB_PORT; - bzero((char *) &eiger_back_socket_addr, sizeof(eiger_back_socket_addr)); - eiger_back_socket_addr.sin_family = AF_INET; - bcopy((char *)dst_host->h_addr,(char *)&eiger_back_socket_addr.sin_addr.s_addr,dst_host->h_length); - eiger_back_socket_addr.sin_port = htons(port); - passed = 1; - } - } - - return passed; -} - - -int EigerBackSendCMD(){ - if(!EigerBackInit()||eiger_back_message_length<=0) return 0; - - int sockfd = socket(AF_INET,SOCK_STREAM,0); - if(sockfd<0){ - fprintf(stderr,"ERROR opening socket\n"); - return 0; - } - - if(connect(sockfd,(struct sockaddr *) &eiger_back_socket_addr,sizeof(eiger_back_socket_addr))<0){ - fprintf(stderr,"ERROR connecting\n"); - return 0; - } - - int n = write(sockfd,eiger_back_message,eiger_back_message_length); - int ret_length = read(sockfd,eiger_back_message,eiger_back_max_message_length); - - close(sockfd); - - if(n<0||ret_length<0) return 0; - - - //fprintf(stdout,"%s\n",eiger_back_message); - if(eiger_back_ret_val>0){ - int i=0; - eiger_back_message[1]='\0'; - if(atoi(eiger_back_message)!=0) return 0; - - for(i=2;i <1GbE(0) or 10GbE(1)> -int EigerSetupTableEntryLeft(int ipad, long long int macad, long long int detectormacadd, int detipad, int udpport){ - char src_mac[50], src_ip[50],dst_mac[50], dst_ip[50]; - - int src_port = 0xE185; - int dst_port = udpport; - sprintf(src_ip,"%d.%d.%d.%d",(detipad>>24)&0xff,(detipad>>16)&0xff,(detipad>>8)&0xff,(detipad)&0xff); - sprintf(dst_ip,"%d.%d.%d.%d",(ipad>>24)&0xff,(ipad>>16)&0xff,(ipad>>8)&0xff,(ipad)&0xff); - sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x",(unsigned int)((detectormacadd>>40)&0xFF), - (unsigned int)((detectormacadd>>32)&0xFF), - (unsigned int)((detectormacadd>>24)&0xFF), - (unsigned int)((detectormacadd>>16)&0xFF), - (unsigned int)((detectormacadd>>8)&0xFF), - (unsigned int)((detectormacadd>>0)&0xFF)); - sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x",(unsigned int)((macad>>40)&0xFF), - (unsigned int)((macad>>32)&0xFF), - (unsigned int)((macad>>24)&0xFF), - (unsigned int)((macad>>16)&0xFF), - (unsigned int)((macad>>8)&0xFF), - (unsigned int)((macad>>0)&0xFF)); - - printf("Seting up Table Entry Left:\n"); - printf("src_port:%d\n",src_port); - printf("dst_port:%d\n",dst_port); - printf("src_ip:%s\n",src_ip); - printf("dst_ip:%s\n",dst_ip); - printf("src_mac:%s\n",src_mac); - printf("dst_mac:%s\n\n",dst_mac); - - - - eiger_back_ret_val=0; - eiger_back_message_length = sprintf(eiger_back_message,"setuptableentry %d %d %d %s %s %d %s %s %d",34,ten_giga,0,src_mac,src_ip,src_port,dst_mac,dst_ip,dst_port); - return EigerBackSendCMD(); -} - - -int EigerSetupTableEntryRight(int ipad, long long int macad, long long int detectormacadd, int detipad, int udpport){ - char src_mac[50], src_ip[50],dst_mac[50], dst_ip[50]; - - int src_port = 0xE185; - int dst_port = udpport+1; - sprintf(src_ip,"%d.%d.%d.%d",(detipad>>24)&0xff,(detipad>>16)&0xff,(detipad>>8)&0xff,(detipad)&0xff); - sprintf(dst_ip,"%d.%d.%d.%d",(ipad>>24)&0xff,(ipad>>16)&0xff,(ipad>>8)&0xff,(ipad)&0xff); - sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x",(unsigned int)((detectormacadd>>40)&0xFF), - (unsigned int)((detectormacadd>>32)&0xFF), - (unsigned int)((detectormacadd>>24)&0xFF), - (unsigned int)((detectormacadd>>16)&0xFF), - (unsigned int)((detectormacadd>>8)&0xFF), - (unsigned int)((detectormacadd>>0)&0xFF)); - sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x",(unsigned int)((macad>>40)&0xFF), - (unsigned int)((macad>>32)&0xFF), - (unsigned int)((macad>>24)&0xFF), - (unsigned int)((macad>>16)&0xFF), - (unsigned int)((macad>>8)&0xFF), - (unsigned int)((macad>>0)&0xFF)); - - printf("Seting up Table Entry Right:\n"); - printf("src_port:%d\n",src_port); - printf("dst_port:%d\n",dst_port); - printf("src_ip:%s\n",src_ip); - printf("dst_ip:%s\n",dst_ip); - printf("src_mac:%s\n",src_mac); - printf("dst_mac:%s\n\n",dst_mac); - - eiger_back_ret_val=0; - eiger_back_message_length = sprintf(eiger_back_message,"setuptableentry %d %d %d %s %s %d %s %s %d",34,ten_giga,32,src_mac,src_ip,src_port,dst_mac,dst_ip,dst_port); - return EigerBackSendCMD(); -} - - - - -int RequestImages(){ - printf("Going to request images\n"); - eiger_back_ret_val=0; - eiger_back_message_length = sprintf(eiger_back_message,"requestimages %d",0); // dst_number - return EigerBackSendCMD(); -} - -int SetDestinationParameters(int i){ - eiger_back_ret_val=0; - eiger_back_message_length = sprintf(eiger_back_message,"setdstparameters %d %d %d",ten_giga,1,i);// number of dsts - return EigerBackSendCMD(); -} - - -void SetTenGigbaBitEthernet(int val){ - ten_giga = val; -} - - -int GetTenGigbaBitEthernet(){ - return ten_giga; -} diff --git a/slsDetectorSoftware/eigerDetectorServer/EigerHighLevelFunctions.c b/slsDetectorSoftware/eigerDetectorServer/EigerHighLevelFunctions.c deleted file mode 100644 index 445a9a2cb..000000000 --- a/slsDetectorSoftware/eigerDetectorServer/EigerHighLevelFunctions.c +++ /dev/null @@ -1,363 +0,0 @@ - -/** - * @author Ian Johnson - * @version 1.0 - */ - -#include -#include -#include -#include - -#include "slsDetectorServer_defs.h" //include port number - - - -int eiger_nexposures = 1; -float eiger_exposuretime = 0; -float eiger_exposureperiod = 0; -int eiger_ncycles = 1; -int eiger_ngates = 0; -int eiger_getphotonenergy = 0; -int eiger_dynamicrange = 0; -int eiger_readoutspeed = 0; -int eiger_readoutmode = 0; -int eiger_highvoltage = 0; -int eiger_iodelay = 0; -int eiger_triggermode = 0; -int eiger_extgating = 0; -int eiger_extgatingpolarity = 0; - -const unsigned int ndacs = 16; -const char* 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"}; - -int saved_trimbits[256*256*4]; - - -int EigerGetNumberOfExposures(){return eiger_nexposures;} -float EigerGetExposureTime(){return eiger_exposuretime;} -float EigerGetExposurePeriod(){return eiger_exposureperiod;} -int EigerGetNumberOfCycles(){return eiger_ncycles;} -/*int EigerGetNumberOfGates(){return eiger_ngates;}*/ -unsigned int EigerGetDynamicRange(){return eiger_dynamicrange;} -int EigerGetPhotonEnergy(){return eiger_getphotonenergy;} -int EigerGetReadoutSpeed(){return eiger_readoutspeed;} -int EigerGetReadoutMode(){return eiger_readoutmode;} -int EigerGetHighVoltage(){return eiger_highvoltage;} -int EigerGetIODelay(){return eiger_iodelay;} -int EigerGetTriggerMode(){return eiger_triggermode;} -int EigerGetExternalGating(){return eiger_extgating;} -int EigerGetExternalGatingPolarity(){return eiger_extgatingpolarity;} - -int EigerInit(){ - saved_trimbits[0] = -1; - - -} - - -int EigerSendCMD(){ - if(!EigerInit()||eiger_message_length<=0) return 0; - - int sockfd = socket(AF_INET,SOCK_STREAM,0); - if(sockfd<0){ - fprintf(stderr,"ERROR opening socket\n"); - return 0; - } - - if(connect(sockfd,(struct sockaddr *) &eiger_socket_addr,sizeof(eiger_socket_addr))<0){ - fprintf(stderr,"ERROR connecting\n"); - return 0; - } - - int n = write(sockfd,eiger_message,eiger_message_length); - - int ret_length = read(sockfd,eiger_message,eiger_max_message_length); - - close(sockfd); - - if(n<0||ret_length<0) return 0; - - - //fprintf(stdout,"%s\n",eiger_message); - if(eiger_ret_val>0){ - int i=0; - eiger_message[1]='\0'; - if(atoi(eiger_message)!=0) return 0; - - for(i=2;i0&&ireadout ->expose -> ..., with store is always closed -#define DAQ_NEXPOSURERS_PARALLEL_MODE 0x00600000 //parallel acquire/read mode - -//DAQ_NEXPOSURERS_READOUT_COMPLETE_IMAGES is old now hard-wired in the firmware that every image comes with a header -//#define DAQ_NEXPOSURERS_READOUT_COMPLETE_IMAGES 0x00800000 //DAQ_IGNORE_INITIAL_CRAP and DAQ_CLKOUT_LAST_4_BITS_AND_RETURN_TO_START - -#define DAQ_NEXPOSURERS_EXTERNAL_ENABLING 0x01000000 -#define DAQ_NEXPOSURERS_EXTERNAL_ENABLING_POLARITY 0x02000000 -#define DAQ_NEXPOSURERS_EXTERNAL_TRIGGER_POLARITY 0x04000000 - -#define DAQ_NEXPOSURERS_INTERNAL_ACQUISITION 0x00000000 //internally controlled -#define DAQ_NEXPOSURERS_EXTERNAL_ACQUISITION_START 0x08000000 //external acquisition start -#define DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START 0x10000000 //external image start -#define DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START_AND_STOP 0x18000000 //externally controlly, external image start and stop - -#define DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING 0x20000000 -#define DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION 0x40000000 - -//#define DAQ_MASTER_HALF_MODULE 0x80000000 currently not used - - -//chips static bits -#define DAQ_STATIC_BIT_PROGRAM 0x00000001 -#define DAQ_STATIC_BIT_M4 0x00000002 //these are the status bits, not bit mode -#define DAQ_STATIC_BIT_M8 0x00000004 //these are the status bits, not bit mode -#define DAQ_STATIC_BIT_M12 0x00000000 //these are the status bits, not bit mode, ie. "00" is 12 bit mode -#define DAQ_STATIC_BIT_CHIP_TEST 0x00000008 -#define DAQ_STATIC_BIT_ROTEST 0x00000010 -#define DAQ_CS_BAR_LEFT 0x00000020 -#define DAQ_CS_BAR_RIGHT 0x00000040 - - -//status flags -#define DAQ_STATUS_DAQ_RUNNING 0x01 -#define DAQ_DATA_COLLISION_ERROR 0x02 - -#define DAQ_STATUS_CURRENT_M4 0x04 -#define DAQ_STATUS_CURRENT_M8 0x08 -#define DAQ_STATUS_CURRENT_M12 0x00 //in 12 bit mode both are cleared -#define DAQ_STATUS_CURRENT_TESTMODE 0x10 -#define DAQ_STATUS_TOKEN_OUT 0x20 -#define DAQ_STATUS_SERIAL_OUT 0x40 -#define DAQ_STATUS_PIXELS_ARE_ENABLED 0x80 -#define DAQ_STATUS_DAQ_RUN_TOGGLE 0x200 - -//data delay registers -#define CHIP_DATA_OUT_DELAY_REG_CTRL 1 -#define CHIP_DATA_OUT_DELAY_REG2 2 -#define CHIP_DATA_OUT_DELAY_REG3 3 -#define CHIP_DATA_OUT_DELAY_REG4 4 -#define CHIP_DATA_OUT_DELAY_SET 0x20000000 - - -//module configuration -#define TOP_BIT_MASK 0x00f -#define MASTER_BIT_MASK 0x200 diff --git a/slsDetectorSoftware/eigerDetectorServer/EigerTest.cxx b/slsDetectorSoftware/eigerDetectorServer/EigerTest.cxx deleted file mode 100644 index 4e95bd560..000000000 --- a/slsDetectorSoftware/eigerDetectorServer/EigerTest.cxx +++ /dev/null @@ -1,38 +0,0 @@ - -/** - * @author Ian Johnson - * @version 1.0 - */ - - -#include -#include - -#include - -#include "Eiger.h" - - -using namespace std; - -int main(int argc, char* argv[]){ - - cout<<"\n\n\n\n\n\n\n\n\n\n"<1) ? atoi(argv[1]):5; - - //Feb *f = new Feb(); - // f->Test(); - //delete f; - //return 0; - - Eiger* e = new Eiger(); - e->SetNImages(n); - e->SetDynamicRange(32); - e->SetExposureTime(0.02); - e->SetExposurePeriod(0.050); - e->StartAcquisition(); - - delete e; - - return 0; -} diff --git a/slsDetectorSoftware/eigerDetectorServer/Feb.cxx b/slsDetectorSoftware/eigerDetectorServer/Feb.cxx deleted file mode 100644 index 8bb6bbebc..000000000 --- a/slsDetectorSoftware/eigerDetectorServer/Feb.cxx +++ /dev/null @@ -1,326 +0,0 @@ - -/** - * @author Ian Johnson - * @version 1.0 - */ - - -//return reversed 1 means good, 0 means failed - - -#include -#include -//#include -//#include -//#include -//#include - -#include "xparameters.h" - -#include "Feb.h" - -using namespace std; - -Feb::Feb(){ - - nfebs = 0; - feb_numb = 0; - - send_ndata = 0; - send_buffer_size = 1026; - send_data_raw = new unsigned int [send_buffer_size+1]; - send_data = &send_data_raw[1]; - - recv_ndata = 0; - recv_buffer_size = 1026; - recv_data_raw = new unsigned int [recv_buffer_size+1]; - recv_data = &recv_data_raw[1]; - - ll = new LocalLinkInterface(XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR); - -} - -Feb::~Feb(){ - delete ll; - if(feb_numb) delete [] feb_numb; - delete [] send_data_raw; - delete [] recv_data_raw; -} - -void Feb::SendCompleteFebList(unsigned int n,unsigned int* list){ - if(feb_numb) delete [] feb_numb; - nfebs = n; - feb_numb = new unsigned int [n]; - for(unsigned int i=0;i0xfff) return 0; - - send_data_raw[0] = 0x90000000 | (ch<<16); //we - if(ll->Write(4,send_data_raw)!=4) return 0; - - send_data_raw[0] = 0xc0000000; //data - return ((send_ndata+1)*4==ll->Write((send_ndata+1)*4,send_data_raw)); -} - -bool Feb::ReadFrom(unsigned int ch, unsigned int ntrys){ - if(ch>=0xfff) return 0; - - recv_data_raw[0] = 0xa0000000 | (ch<<16); //read data - ll->Write(4,recv_data_raw); - usleep(20); - - recv_ndata=-1; - for(unsigned int t=0;tRead(recv_buffer_size*4,recv_data_raw)/4)>0){ - recv_ndata--; - break; - } - cout<<"\t Read try number: "<=0); -} - -void Feb::PrintData(){ - cout<<"Sent data: "<1&&recv_ndata>1){ - cout<<"\t\t Tail sent: "<Write(4,send_data_raw)!=4) return 0; - - cout<<"Feb::CheckingCommunication ...."<Read(recv_buffer_size*4,recv_data_raw)/4)>0) cout<<"\t) Cleanning buffer ..."<=nfebs){ - cout<<"Error invalid sub number "<send_buffer_size-2) return 0; - - send_ndata = nreads+2; - send_data[0] = 0x20000000 | nreads << 14; //cmd -> read "00" , nreads - - for(unsigned int i=0;isend_buffer_size-2) return 0; - - //cout<<"Write register : "< write nwrites and how many - send_data[2*nwrites+1] = 0; //tail - - for(unsigned int i=0;isend_buffer_size-2) return 0; - - send_ndata = nwrites+2; - send_data[0] = 0xc0000000 | mem_num << 24 | nwrites << 14 | start_address; //cmd -> write to memory, nwrites, mem number, start address - send_data[nwrites+1] = 0; //tail - for(unsigned int i=0;i -#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[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 -/* - 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(!WriteMemory(modules[0]->GetTopLeftAddress(),0,0,1024,trimbits_to_load_r)||!WriteMemory(modules[0]->GetTopRightAddress(),0,0,1024,trimbits_to_load_l)||!StartDAQOnlyNWaitForFinish()){ - cout <<" some errror!"<< endl; - return 0; - } -*/ - if(!WriteMemory(modules[0]->GetTopLeftAddress(),0,0,1023,trimbits_to_load_r)||!WriteMemory(modules[0]->GetTopRightAddress(),0,0,1023,trimbits_to_load_l)||!StartDAQOnlyNWaitForFinish()){ - cout <<" some errror!"<< endl; - return 0; - } - - } //end row_set loop (groups of 16 rows) - } // end l_r loop - memcpy(last_downloaded_trimbits,trimbits,trimbit_size*sizeof(unsigned char)); - return SetStaticBits(); //send the static bits -} - - -unsigned int* 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."<GetTopRightAddress(),status_reg_r))) - return 0; - if(status_reg_r&DAQ_STATUS_DAQ_RUNNING) return 1; - - /* - 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..."< -#include -//#include -//#include -//#include -//#include - -#include "xparameters.h" - -#include "FebInterface.h" - -using namespace std; - -FebInterface::FebInterface(){ - - nfebs = 0; - feb_numb = 0; - - send_ndata = 0; - send_buffer_size = 1026; - send_data_raw = new unsigned int [send_buffer_size+1]; - send_data = &send_data_raw[1]; - - recv_ndata = 0; - recv_buffer_size = 1026; - recv_data_raw = new unsigned int [recv_buffer_size+1]; - recv_data = &recv_data_raw[1]; - - ll = new LocalLinkInterface(XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR); - -} - -FebInterface::~FebInterface(){ - delete ll; - if(feb_numb) delete [] feb_numb; - delete [] send_data_raw; - delete [] recv_data_raw; -} - -void FebInterface::SendCompleteList(unsigned int n,unsigned int* list){ - if(feb_numb) delete [] feb_numb; - nfebs = n; - feb_numb = new unsigned int [n]; - for(unsigned int i=0;i0xfff) return 0; - - send_data_raw[0] = 0x8fff0000; - if(ll->Write(4,send_data_raw)!=4) return 0; - - send_data_raw[0] = 0x90000000 | (ch<<16); - if(ll->Write(4,send_data_raw)!=4) return 0; - - send_data_raw[0] = 0xc0000000; - return ((send_ndata+1)*4==ll->Write((send_ndata+1)*4,send_data_raw)); -} - -bool FebInterface::ReadFrom(unsigned int ch, unsigned int ntrys){ - if(ch>=0xfff) return 0; - - recv_data_raw[0] = 0xa0000000 | (ch<<16); - ll->Write(4,recv_data_raw); - usleep(20); - - recv_ndata=-1; - for(unsigned int t=0;tRead(recv_buffer_size*4,recv_data_raw)/4)>0){ - recv_ndata--; - break; - } - usleep(1000); - } - - return (recv_ndata>=0); -} - - - -bool FebInterface::SetByteOrder(){ - - send_data_raw[0] = 0x8fff0000; - if(ll->Write(4,send_data_raw)!=4) return 0; - - send_ndata = 2; - send_data[0] = 0; - send_data[1] = 0; - - unsigned int dst = 0xff; - for(unsigned int i=0;isend_buffer_size-2) return 0; - - send_ndata = nreads+2; - send_data[0] = 0x20000000 | nreads << 14; - - for(unsigned int i=0;isend_buffer_size-2) return 0; - - //cout<<"Write register : "<send_buffer_size-2) {cout<<"error herer: nwrites:"< write to memory, nwrites, mem number, start address - send_data[nwrites+1] = 0; - for(unsigned int i=0;i -#include -#include -#include -#include // std::remove_if - -#include -#include -#include -#include -#include - -#include "FebControl.h" -#include "slsDetectorServer_defs.h" //include port number - -using namespace std; - -enum cmd_string {evNotFound, - evReinitialize,evReset, - - evSetInputDelays, - evSetDACValue,evGetDACValue,evSetDACVoltage,evGetDACVoltage,evSetHighVoltage,//evGetHighVoltage, - - evSetTrimBits, - evSetAllTrimBits, - evGetTrimBits, - //evLoadTrimBitFile, - - evSetBitMode, - evSetPhotonEnergy, - // evSetPhotonEnergyCalibrationParameters,evActivateRateCorrection,evDeactivateRateCorrection,evSetRateCorrectionTau, - - evSetReadoutSpeed,evSetReadoutMode, - - //temp solution - // evNotFound1,evNotFound2,evNotFound3, - - evSetNumberOfExposures,evSetExposureTime,evSetExposurePeriod, - // evSetTriggerPolarityToPositive,evSetTriggerPolarityToNegative, - evSetTriggerMode, - evSetExternalGating, - evStartAcquisition,evStopAcquisition,evIsDaqStillRunning, - evWaitUntilDaqFinished, - evExitServer -}; - -map enum_map; - -void init(){ - - enum_map["reinitialize"] = evReinitialize; - enum_map["reset"] = evReset; - enum_map["setinputdelays"] = evSetInputDelays; - enum_map["setdacvalue"] = evSetDACValue; - enum_map["getdacvalue"] = evGetDACValue; - enum_map["setdacvoltage"] = evSetDACVoltage; - enum_map["getdacvoltage"] = evGetDACVoltage; - enum_map["sethighvoltage"] = evSetHighVoltage; - enum_map["settrimbits"] = evSetTrimBits; - enum_map["setalltrimbits"] = evSetAllTrimBits; - enum_map["gettrimbits"] = evGetTrimBits; - // enum_map["loadtrimbitfile"] = evLoadTrimBitFile; - enum_map["setbitmode"] = evSetBitMode; - enum_map["setphotonenergy"] = evSetPhotonEnergy; - // enum_map["setphotonenergycalibrationparameters"] = evSetPhotonEnergyCalibrationParameters; - // enum_map["activateratecorrection"] = evActivateRateCorrection; - // enum_map["deactivateratecorrection"] = evDeactivateRateCorrection; - // enum_map["setratecorrectiontau"] = evSetRateCorrectionTau; - enum_map["setreadoutspeed"] = evSetReadoutSpeed; - enum_map["setreadoutmode"] = evSetReadoutMode; - enum_map["setnumberofexposures"] = evSetNumberOfExposures; - enum_map["setexposuretime"] = evSetExposureTime; - enum_map["setexposureperiod"] = evSetExposurePeriod; - // enum_map["settriggerpolaritytopositive"] = evSetTriggerPolarityToPositive; - // enum_map["settriggerpolaritytonegative"] = evSetTriggerPolarityToNegative; - enum_map["settriggermode"] = evSetTriggerMode; - enum_map["setexternalgating"] = evSetExternalGating; - enum_map["startacquisition"] = evStartAcquisition; - enum_map["stopacquisition"] = evStopAcquisition; - enum_map["isdaqstillrunning"] = evIsDaqStillRunning; - enum_map["waituntildaqfinished"] = evWaitUntilDaqFinished; - enum_map["exitserver"] = evExitServer; -} - -int server_list_s; -int server_conn_s; -int AccpetConnectionAndWaitForData(char* buffer, int maxlength); -bool WriteNClose(const char* buffer, int length); -bool SetupListenSocket(unsigned short int port); - - -string LowerCase(string str); -string GetNextString(string str,bool start_from_beginning=0); -void AddNumber(string& str, int n, int location=-1, bool space_after=0);//-1 means append -void AddNumber(string& str, float v, int location=-1, bool space_after=0);//-1 means append - -int main(int argc, char* argv[]){ - cout< "<0){ - int ret_parameter = 0; - return_start_pos = return_message.length(); - - switch(enum_map.find(LowerCase(cmd))->second){ - - case evReinitialize : - if(feb_controler->Init()){ - return_message.append("\tExecuted: Reinitialize\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: Reinitialize\n"); - ret_val = 1; - } - break; - - case evReset : - if(feb_controler->Reset()){ - return_message.append("\tExecuted: Reset\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: Reset\n"); - ret_val = 1; - } - break; - - - - case evSetInputDelays : - tmp_str[0] = GetNextString(data); - n[0] = atoi(tmp_str[0].data()); - - if(tmp_str[0].length()>0&&feb_controler->SetIDelays(0,n[0])){ - return_message.append("\tExecuted: SetInputDelays "); AddNumber(return_message,n[0]); return_message.append("\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetInputDelays \n"); - ret_val = 1; - } - break; - - - - case evSetDACValue : - tmp_str[0] = GetNextString(data); - tmp_str[1] = GetNextString(data); - n[0] = atoi(tmp_str[1].data()); - - if(tmp_str[0].length()>0&&tmp_str[1].length()>0&&feb_controler->SetDAC(tmp_str[0],n[0])){ - return_message.append("\tExecuted: SetDACValue "); return_message.append(tmp_str[0]+" "); AddNumber(return_message,n[0]); return_message.append("\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetDACValue \n"); - ret_val = 1; - } - break; - - case evGetDACValue : - tmp_str[0] = GetNextString(data); - - if(tmp_str[0].length()>0&&feb_controler->GetDAC(tmp_str[0],ret_parameter)){ - return_message.append("\tExecuted: GetDACValue "); return_message.append(tmp_str[0]+" -> ");AddNumber(return_message,ret_parameter); return_message.append("\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: GetDACValue \n"); - ret_val = 1; - } - break; - - case evSetDACVoltage : - tmp_str[0] = GetNextString(data); - tmp_str[1] = GetNextString(data); - n[0] = atoi(tmp_str[1].data()); - - if(tmp_str[0].length()>0&&tmp_str[1].length()>0&&feb_controler->SetDAC(tmp_str[0],n[0],1)){ - return_message.append("\tExecuted: SetDACVoltage "); return_message.append(tmp_str[0]+" "); AddNumber(return_message,n[0]); return_message.append("\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetDACVoltage \n"); - ret_val = 1; - } - break; - - case evGetDACVoltage : - tmp_str[0] = GetNextString(data); - - if(tmp_str[0].length()>0&&feb_controler->GetDAC(tmp_str[0],ret_parameter,1)){ - return_message.append("\tExecuted: GetDACVoltage "); return_message.append(tmp_str[0]+" -> ");AddNumber(return_message,ret_parameter); return_message.append(" mV\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: GetDACVoltage \n"); - ret_val = 1; - } - break; - - case evSetHighVoltage : - tmp_str[0] = GetNextString(data); - v[0] = atof(tmp_str[0].data()); - - if(tmp_str[0].length()>0&&feb_controler->SetHighVoltage(v[0])){ - return_message.append("\tExecuted: SetHighVoltage "); AddNumber(return_message,v[0]); return_message.append("\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetHighVoltage \n"); - ret_val = 1; - } - break; - - case evSetTrimBits : - tmp_str[0] = GetNextString(data); - if(feb_controler->LoadTrimbitFile()){ - /* if(1){*/ - /*tmp_str[0] = GetNextString(data); - feb_controler->SetTrimbits(0,(unsigned char*)(tmp_str[0].c_str()));*/ - return_message.append("\tExecuted: SetTrimBits\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetTrimBits \n"); - ret_val = 1; - } - break; - - case evSetAllTrimBits : - tmp_str[0] = GetNextString(data); - n[0] = atoi(tmp_str[0].data()); - if(feb_controler->SaveAllTrimbitsTo(n[0])){ - /*feb_controler->SetTrimbits(0,(unsigned char*)(tmp_str[0].c_str()));*/ - /*if(1){*/ - return_message.append("\tExecuted: SetAllTrimBits\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetAllTrimBits \n"); - ret_val = 1; - } - break; - - - case evGetTrimBits : - if(feb_controler->SaveTrimbitFile()){ - /*if(1){*/ - /*tmp_str[0] = GetNextString(data); - feb_controler->GetTrimbits();*/ - return_message.append("\tExecuted: GetTrimBits\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: GetTrimBits \n"); - ret_val = 1; - } - break; - - - // case evLoadTrimBitFile : - - case evSetBitMode : - tmp_str[0] = GetNextString(data); - n[0] = atoi(tmp_str[0].data()); - - if(tmp_str[0].length()>0&&feb_controler->SetDynamicRange(n[0])){ - return_message.append("\tExecuted: SetBitMode "); AddNumber(return_message,n[0]); return_message.append("\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetBitMode \n"); - ret_val = 1; - } - break; - - case evSetPhotonEnergy : - tmp_str[0] = GetNextString(data); - n[0] = atoi(tmp_str[0].data()); - if(tmp_str[0].length()>0&&feb_controler->SetPhotonEnergy(n[0])){ - return_message.append("\tExecuted: SetPhotonEnergy "); AddNumber(return_message,n[0]); return_message.append("\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetPhotonEnergy \n"); - ret_val = 1; - } - break; - - // case evSetPhotonEnergyCalibrationParameters : - // case evActivateRateCorrection : - // case evDeactivateRateCorrection : - // case evSetRateCorrectionTau : - - - case evSetReadoutSpeed : - tmp_str[0] = GetNextString(data); - n[0] = atoi(tmp_str[0].data()); - if(tmp_str[0].length()>0&&feb_controler->SetReadoutSpeed(n[0])){ - return_message.append("\tExecuted: SetReadoutSpeed "); AddNumber(return_message,n[0]); return_message.append("\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetReadoutSpeed \n"); - ret_val = 1; - } - break; - - case evSetReadoutMode : - tmp_str[0] = GetNextString(data); - n[0] = atoi(tmp_str[0].data()); - if(tmp_str[0].length()>0&&feb_controler->SetReadoutMode(n[0])){ - return_message.append("\tExecuted: SetReadoutMode "); AddNumber(return_message,n[0]); return_message.append("\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetReadoutMode parallel,1->non-parallel,2-> safe_mode>\n"); - ret_val = 1; - } - break; - - case evSetNumberOfExposures : - tmp_str[0] = GetNextString(data); - n[0] = atoi(tmp_str[0].data()); - if(tmp_str[0].length()>0&&feb_controler->SetNExposures(n[0])){ - return_message.append("\tExecuted: SetNumberOfExposures "); AddNumber(return_message,n[0]); return_message.append("\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetNumberOfExposures \n"); - ret_val = 1; - } - break; - - case evSetExposureTime : - tmp_str[0] = GetNextString(data); - v[0] = atof(tmp_str[0].data()); - if(tmp_str[0].length()>0&&feb_controler->SetExposureTime(v[0])){ - return_message.append("\tExecuted: SetExposureTime "); AddNumber(return_message,v[0]); return_message.append("\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetExposureTime \n"); - ret_val = 1; - } - break; - - case evSetExposurePeriod : - tmp_str[0] = GetNextString(data); - v[0] = atof(tmp_str[0].data()); - if(tmp_str[0].length()>0&&feb_controler->SetExposurePeriod(v[0])){ - return_message.append("\tExecuted: SetExposurePeriod "); AddNumber(return_message,v[0]); return_message.append("\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetExposurePeriod \n"); - ret_val = 1; - } - break; - // case evSetTriggerPolarityToPositive : - // case evSetTriggerPolarityToNegative : - case evSetTriggerMode : - tmp_str[0] = GetNextString(data); - n[0] = atoi(tmp_str[0].data()); - if(tmp_str[0].length()>0&&feb_controler->SetTriggerMode(n[0])){ - return_message.append("\tExecuted: SetTriggerMode "); AddNumber(return_message,n[0]); return_message.append("\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: SetTriggerMode \n"); - ret_val = 1; - } - break; - - case evSetExternalGating : - tmp_str[0] = GetNextString(data); - tmp_str[1] = GetNextString(data); - n[0] = atoi(tmp_str[0].data()); - n[1] = atoi(tmp_str[1].data()); - if(tmp_str[0].length()<1 || tmp_str[1].length()<1 || (n[0]!=0&&n[0]!=1) || (n[1]!=0&&n[1]!=1)){ - return_message.append("\tError executing: setexternalgating \n"); - ret_val = 1; - } - feb_controler->SetExternalEnableMode(n[0],n[1]); - ret_val = 0; - break; - - case evStartAcquisition : - if(feb_controler->StartAcquisition()){ - return_message.append("\tExecuted: StartAcquisition\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: StartAcquisition\n"); - ret_val = 1; - } - break; - - case evStopAcquisition : - if(feb_controler->StopAcquisition()){ - return_message.append("\tExecuted: StopAcquisition\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: StopAcquisition\n"); - ret_val = 1; - } - break; - - - case evIsDaqStillRunning : - return_message.append("\tExecuted: evIsDaqStillRunning\n"); - ret_parameter = feb_controler->AcquisitionInProgress(); - ret_val = 0; - break; - - - case evWaitUntilDaqFinished : - if(feb_controler->WaitForFinishedFlag()){ - return_message.append("\tExecuted: WaitUntilDaqFinished\n"); - ret_val = 0; - }else{ - return_message.append("\tError executing: WaitUntilDaqFinished\n"); - ret_val = 1; - } - break; - - - case evExitServer : - return_message.append("\tExiting Server ....\n"); - stop = 1; - ret_val = -200; - break; - - - default : - return_message.append("\tWarning command \""); - return_message.append(cmd); - return_message.append("\" not found.\n"); - return_message.append("\t\tValid commands: "); - map::iterator it = enum_map.begin(); - while(it!=enum_map.end()){ - return_message.append((it++)->first); - return_message.append(" "); - } - - ret_val=-100; - break; - } - - // return_message.append("\n"); - //AddNumber(return_message,ret_parameter,return_start_pos); - AddNumber(return_message,ret_val,return_start_pos,1); - AddNumber(return_message,ret_parameter,0,1); - if(ret_val!=0) break; - - cmd = GetNextString(data); - } - /*return_message.append("\n\n\n");*/ - - AddNumber(return_message,ret_val,0,1); - cout<0) return sub; - } - - return ""; -} - - -void AddNumber(string& str, int n, int location, bool space_after){ - static char retval_st[100]; - if(space_after) sprintf(retval_st,"%d ",n); - else sprintf(retval_st,"%d",n); - - if(location<0) str.append(retval_st); - else str.insert(location,retval_st); -} - -void AddNumber(string& str, float v, int location, bool space_after){ - static char retval_st[100]; - if(space_after) sprintf(retval_st,"%f ",v); - else sprintf(retval_st,"%f",v); - - if(location<0) str.append(retval_st); - else str.insert(location,retval_st); -} - - -bool SetupListenSocket(unsigned short int port){ - server_list_s=0; - server_conn_s=0; - - if((server_list_s = socket(AF_INET, SOCK_STREAM, 0))<0) return 0; - - struct sockaddr_in servaddr; /* socket address structure */ - memset(&servaddr, 0, sizeof(servaddr)); - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = htonl(INADDR_ANY); - servaddr.sin_port = htons(port); - - if(bind(server_list_s,(struct sockaddr *) &servaddr,sizeof(servaddr))<0) return 0; - - if(listen(server_list_s,32) < 0){ // 1024 /* Backlog for listen() */ - return 0; - } - - return 1; -} - - -int AccpetConnectionAndWaitForData(char* buffer, int maxlength){ - if(server_list_s==0||maxlength<=0) return 0; - - if((server_conn_s = accept(server_list_s,NULL,NULL))< 0) return 0; - - int nread = read(server_conn_s,buffer,maxlength-1); - - if(nread<0) return 0; - - buffer[nread]='\0'; - return nread; -} - -bool WriteNClose(const char* buffer, int length){ - if(server_conn_s==0||length<=0) return 0; - - int nsent = write(server_conn_s,buffer,length); - if(close(server_conn_s)<0) return 0; - - server_conn_s=0; - return (nsent==length); -} - - - diff --git a/slsDetectorSoftware/eigerDetectorServer/HardwareIO.cxx b/slsDetectorSoftware/eigerDetectorServer/HardwareIO.cxx deleted file mode 100644 index 3c6cff40b..000000000 --- a/slsDetectorSoftware/eigerDetectorServer/HardwareIO.cxx +++ /dev/null @@ -1,87 +0,0 @@ - -//Class initially from Gerd and was called mmap_test.c -//return reversed 1 means good, 0 means failed - - -//#include -//#include -//#include -//#include -//#include - -#include "HardwareIO.h" - -xfs_u8 HardwareIO::xfs_in8(xfs_u32 InAddress) -{ - /* read the contents of the I/O location and then synchronize the I/O - * such that the I/O operation completes before proceeding on - */ - - xfs_u8 IoContents; - __asm__ volatile ("eieio; lbz %0,0(%1)":"=r" (IoContents):"b" - (InAddress)); - return IoContents; -} - -/*****************************************************************************/ - -xfs_u16 HardwareIO::xfs_in16(xfs_u32 InAddress) -{ - /* read the contents of the I/O location and then synchronize the I/O - * such that the I/O operation completes before proceeding on - */ - - xfs_u16 IoContents; - __asm__ volatile ("eieio; lhz %0,0(%1)":"=r" (IoContents):"b" - (InAddress)); - return IoContents; -} - -/*****************************************************************************/ - -xfs_u32 HardwareIO::xfs_in32(xfs_u32 InAddress) -{ - /* read the contents of the I/O location and then synchronize the I/O - * such that the I/O operation completes before proceeding on - */ - - xfs_u32 IoContents; - __asm__ volatile ("eieio; lwz %0,0(%1)":"=r" (IoContents):"b" - (InAddress)); - return IoContents; -} - -/*****************************************************************************/ - -void HardwareIO::xfs_out8(xfs_u32 OutAddress, xfs_u8 Value) -{ - /* write the contents of the I/O location and then synchronize the I/O - * such that the I/O operation completes before proceeding on - */ - - __asm__ volatile ("stb %0,0(%1); eieio"::"r" (Value), "b"(OutAddress)); -} - -/*****************************************************************************/ -void HardwareIO::xfs_out16(xfs_u32 OutAddress, xfs_u16 Value) -{ - /* write the contents of the I/O location and then synchronize the I/O - * such that the I/O operation completes before proceeding on - */ - - __asm__ volatile ("sth %0,0(%1); eieio"::"r" (Value), "b"(OutAddress)); -} - -/*****************************************************************************/ - -void HardwareIO::xfs_out32(xfs_u32 OutAddress, xfs_u32 Value) -{ - /* write the contents of the I/O location and then synchronize the I/O - * such that the I/O operation completes before proceeding on - */ - - __asm__ volatile ("stw %0,0(%1); eieio"::"r" (Value), "b"(OutAddress)); -} - - - diff --git a/slsDetectorSoftware/eigerDetectorServer/LocalLinkInterface.cxx b/slsDetectorSoftware/eigerDetectorServer/LocalLinkInterface.cxx deleted file mode 100644 index a8b3311ac..000000000 --- a/slsDetectorSoftware/eigerDetectorServer/LocalLinkInterface.cxx +++ /dev/null @@ -1,277 +0,0 @@ - -//Class initially from Gerd and was called mmap_test.c -//return reversed 1 means good, 0 means failed - - -#include -#include -//#include - - -#include "HardwareMMappingDefs.h" - -#include "LocalLinkInterface.h" - - - -LocalLinkInterface::LocalLinkInterface(unsigned int ll_fifo_badr){ - // printf("\n v 1 \n"); - printf("Initialize PLB LL FIFOs\n"); - ll_fifo_base=0; - ll_fifo_ctrl_reg=0; - if(Init(ll_fifo_badr)){ - Reset(); - printf("\tFIFO Status : 0x%08x\n",StatusVector()); - }else printf("\tError LocalLink Mappping : 0x%08x\n",ll_fifo_badr); - - printf("\n\n"); -} - -LocalLinkInterface::~LocalLinkInterface(){}; - -LocalLinkInterface::LocalLinkInterface(){ - printf("Initialize new memory\n"); - } - -int LocalLinkInterface::InitNewMemory (unsigned int addr, int ifg){ - unsigned int CSP0BASE; - int fd; - - /*fd = open("/dev/mem", O_RDWR | O_SYNC, 0); - if (fd == -1) { - printf("\nCan't find /dev/mem!\n"); - return 0; - } - printf("/dev/mem opened\n"); - - - CSP0BASE = (u_int32_t)mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, addr); - if (CSP0BASE == (u_int32_t)MAP_FAILED) { - printf("\nCan't map memmory area!!\n"); - return 0; - } - printf("CSP0 mapped\n"); - - - volatile u_int8_t *ptr1; - - ptr1=(u_int8_t*)(CSP0BASE); - - printf("pointer val=%x\n",(void*)ptr1); - - printf("ifg_control=%02x\n",*ptr1); - - *ptr1=ifg; - - printf("ifg_control new=%02x\n",*ptr1); - - close(fd); -*/ - return 1; -} - - - -bool LocalLinkInterface::Init(unsigned int ll_fifo_badr){ - int fd; - void *plb_ll_fifo_ptr; - - if ((fd=open("/dev/mem", O_RDWR)) < 0){ - fprintf(stderr, "Could not open /dev/mem\n"); - return 0; - } - - plb_ll_fifo_ptr = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, ll_fifo_badr); - close(fd); - - if (plb_ll_fifo_ptr == MAP_FAILED){ - perror ("mmap"); - return 0; - } - - ll_fifo_base = (xfs_u32) plb_ll_fifo_ptr; - ll_fifo_ctrl_reg = 0; - - return 1; -} - - - -bool LocalLinkInterface::Reset(){ - return Reset(PLB_LL_FIFO_CTRL_RESET_STD); -} - -bool LocalLinkInterface::Reset(unsigned int rst_mask){ - ll_fifo_ctrl_reg |= rst_mask; - printf("\tCTRL Register bits: 0x%08x\n",ll_fifo_ctrl_reg); - - xfs_out32(ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll_fifo_ctrl_reg); - xfs_out32(ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll_fifo_ctrl_reg); - xfs_out32(ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll_fifo_ctrl_reg); - xfs_out32(ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll_fifo_ctrl_reg); - - ll_fifo_ctrl_reg &= (~rst_mask); - - xfs_out32(ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll_fifo_ctrl_reg); - // printf("FIFO CTRL Address: 0x%08x\n FIFO CTRL Register: 0x%08x\n",PLB_LL_FIFO_REG_CTRL,plb_ll_fifo[PLB_LL_FIFO_REG_CTRL]); - return 1; -} - - - -unsigned int LocalLinkInterface::StatusVector(){ - return xfs_in32(ll_fifo_base+4*PLB_LL_FIFO_REG_STATUS); -} - -int LocalLinkInterface::Write(unsigned int buffer_len, void *buffer){ - // note: buffer must be word (4 byte) aligned - // frame_len in byte - int vacancy=0; - int i; - int words_send = 0; - int last_word; - unsigned int *word_ptr; - unsigned int fifo_ctrl; - xfs_u32 status; - - if (buffer_len < 1) return -1; - - last_word = (buffer_len-1)/4; - word_ptr = (unsigned int *)buffer; - - while (words_send <= last_word) - { - while (!vacancy)//wait for Fifo to be empty again - { - status = xfs_in32(ll_fifo_base+4*PLB_LL_FIFO_REG_STATUS); - if((status & PLB_LL_FIFO_STATUS_ALMOSTFULL) == 0) vacancy = 1; - } - - //Just to know: #define PLB_LL_FIFO_ALMOST_FULL_THRESHOLD_WORDS 100 - for (i=0; ((i>>> SOF\n\r"); - buffer_ptr = 0; - sof = 1; - } - - fifo_val = xfs_in32(ll_fifo_base+4*PLB_LL_FIFO_REG_FIFO); //read from fifo - - if ((buffer_ptr > 0) || sof) - { - if ( (buffer_len >> 2) > buffer_ptr) - { - word_ptr[buffer_ptr++] = fifo_val; //write to buffer - } - else - { - buffer_ptr = 0; - return -2; // buffer overflow - } - - if (status & PLB_LL_FIFO_STATUS_LL_EOF) - { - len = (buffer_ptr << 2) -3 + ( (status & PLB_LL_FIFO_STATUS_LL_REM)>>PLB_LL_FIFO_STATUS_LL_REM_SHIFT ); -// printf(">>>>status=0x%08x EOF len = %d \n\r\n\r",status, len); - buffer_ptr = 0; - return len; - } - - } - } - } - while(!(status & PLB_LL_FIFO_STATUS_EMPTY)); - - return 0; -} - -bool LocalLinkInterface::ctrl_reg_write_mask(unsigned int mask, unsigned int val){ - // printf("Fifo CTRL Reg(1): 0x%08x\n",plb_ll_fifo_ctrl_reg); - ll_fifo_ctrl_reg &= (~mask); - //printf("Fifo CTRL Reg(2): 0x%08x\n",plb_ll_fifo_ctrl_reg); - ll_fifo_ctrl_reg |= ( mask & val); -// printf("Fifo CTRL Reg: 0x%08x\n",plb_ll_fifo_ctrl_reg); - xfs_out32(ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll_fifo_ctrl_reg); -// printf("Fifo STAT Reg: 0x%08x\n", plb_ll_fifo[PLB_LL_FIFO_REG_STATUS]); - return 1; -} - - -int LocalLinkInterface::Test(unsigned int buffer_len, void *buffer){ - - int len; - unsigned int rec_buff_len = 4096; - unsigned int rec_buffer[4097]; - - - Write(buffer_len,buffer); - usleep(10000); - - do{ - len = Read(rec_buff_len,rec_buffer); - printf("receive length: %i\n",len); - - if (len > 0){ - rec_buffer[len]=0; - printf((char*) rec_buffer); - printf("\n"); - } - } while(len > 0); - - printf("\n\n\n\n"); - return 1; -} - -void LocalLinkInterface::llfifo_print_frame(unsigned char* fbuff, int len){ - printf("\n\r----Frame of len : %d Byte\n\r",len); - for(int i=0;i - -#include "xparameters.h" - -#include "LocalLinkInterface.h" - -int main(){ - - char s[2000]; - sprintf(s,"papamama"); - - LocalLinkInterface* l0 = new LocalLinkInterface(XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_LEFT_BASEADDR); - l0->Test(8,s); - LocalLinkInterface* l1 = new LocalLinkInterface(XPAR_PLB_LL_FIFO_AURORA_RX4_TX1_LEFT_BASEADDR); - l1->Test(8,s); - LocalLinkInterface* l2 = new LocalLinkInterface(XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR); - l2->Test(8,s); - LocalLinkInterface* l3 = new LocalLinkInterface(XPAR_PLB_LL_FIFO_AURORA_RX4_TX1_RIGHT_BASEADDR); - l3->Test(8,s); - - delete l0; - delete l1; - delete l2; - delete l3; - - return 1; -} diff --git a/slsDetectorSoftware/eigerDetectorServer/Makefile b/slsDetectorSoftware/eigerDetectorServer/Makefile index 3a9cc6c59..ccf582d27 100755 --- a/slsDetectorSoftware/eigerDetectorServer/Makefile +++ b/slsDetectorSoftware/eigerDetectorServer/Makefile @@ -1,5 +1,4 @@ CC = powerpc-4xx-softfloat-gcc -CCX = powerpc-4xx-softfloat-g++ BLACKFIN_CC = bfin-uclinux-gcc CFLAGS += -Wall -DDACS_INT -DEIGERD -DSLS_DETECTOR_FUNCTION_LIST -DDACS_INT -DSTOP_SERVER #-DVERBOSEI #-DVERBOSE #-DVIRTUAL -DPCCOMPILE -DMARTIN LDLIBS += -lm -lstdc++ @@ -10,13 +9,10 @@ INSTMODE = 0777 SRC_CLNT = communication_funcs.c slsDetectorServer.c slsDetectorServer_funcs.c slsDetectorFunctionList.c FebControl.c Beb.c HardwareIO.c LocalLinkInterface.c Feb.c FebInterface.c -#SRC_CLNT2 = FebServer.cxx FebControl.cxx FebInterface.cxx LocalLinkInterface.cxx HardwareIO.cxx -#SRC_CLNT3 = BebServer.cxx Beb.cxx LocalLinkInterface.cxx HardwareIO.cxx - OBJS = $(SRC_CLNT:.c=.o) -all: clean $(PROGS) hv9m_blackfin_server #feb_debug beb_debug +all: clean $(PROGS) #hv9m_blackfin_server boot: $(OBJS) @@ -27,14 +23,7 @@ $(PROGS): $(CC) -o $@ $(SRC_CLNT) $(CFLAGS) $(LDLIBS) mv $(PROGS) $(DESTDIR) -feb_debug:$(SRC_CLNT2) - $(CCX) -o feb_debug $(SRC_CLNT2) -I. - mv feb_debug $(DESTDIR) - -beb_debug:$(SRC_CLNT3) - $(CCX) -o beb_debug $(SRC_CLNT3) -I. - mv beb_debug $(DESTDIR) - + hv9m_blackfin_server:9mhvserial_bf.c $(BLACKFIN_CC) -o hv9m_blackfin_server 9mhvserial_bf.c -Wall #-DVERBOSE mv hv9m_blackfin_server $(DESTDIR) diff --git a/slsDetectorSoftware/eigerDetectorServer/Test.cxx b/slsDetectorSoftware/eigerDetectorServer/Test.cxx deleted file mode 100644 index 8e07d609b..000000000 --- a/slsDetectorSoftware/eigerDetectorServer/Test.cxx +++ /dev/null @@ -1,38 +0,0 @@ - -/** - * @author Ian Johnson - * @version 1.0 - */ - - -#include -#include - -#include "xparameters.h" - -#include "Feb.h" - - -using namespace std; - -int main(){ - - cout<<"\n\n\n\n\n\n\n\n\n\n"<ReadRegister(0,0,v); - feb->ReadRegister(0,0xffffffff,v); - cout<ReadRegister(1,0,v); - feb->ReadRegister(1,0xffffffff,v); - - delete feb; - - return 1; -} diff --git a/slsDetectorSoftware/eigerDetectorServer/bin/hv9m_blackfin_server b/slsDetectorSoftware/eigerDetectorServer/bin/hv9m_blackfin_server deleted file mode 100755 index a23826d2f465e87c9ecc0323391a07019082f074..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30184 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