mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-05-10 06:40:02 +02:00
latest update from Ian in eiger server
This commit is contained in:
parent
5fcec01a31
commit
de319249cd
462
slsDetectorSoftware/eigerDetectorServer/Beb.cxx
Normal file
462
slsDetectorSoftware/eigerDetectorServer/Beb.cxx
Normal file
@ -0,0 +1,462 @@
|
||||
|
||||
/**
|
||||
* @author Ian Johnson
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
|
||||
//return reversed 1 means good, 0 means failed
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
#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"<<beb_number<<") Beb Info.:"<<endl;
|
||||
cout<<"\t\tSerial Add: 0x"<<hex<<serial_address<<dec<<endl;
|
||||
cout<<"\t\tMAC 1GbE: "<<src_mac_1GbE.c_str()<<endl;
|
||||
cout<<"\t\tIP 1GbE: "<<src_ip_1GbE.c_str()<<endl;
|
||||
cout<<"\t\tport 1GbE: "<<src_port_1GbE<<endl;
|
||||
cout<<"\t\tMAC 10GbE: "<<src_mac_10GbE.c_str()<<endl;
|
||||
cout<<"\t\tIP 10GbE: "<<src_ip_10GbE.c_str()<<endl;
|
||||
cout<<"\t\tport 10GbE: "<<src_port_10GbE<<endl;
|
||||
}
|
||||
|
||||
|
||||
Beb::Beb(){
|
||||
|
||||
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];
|
||||
|
||||
if(!InitBebInfos()) exit(1);
|
||||
|
||||
cout<<"Printing Beb infos:"<<endl;
|
||||
for(unsigned int i=1;i<beb_infos.size();i++) beb_infos[i]->Print();
|
||||
cout<<endl<<endl;
|
||||
|
||||
bit_mode = 4;
|
||||
|
||||
ll = new LocalLinkInterface(XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_LEFT_BASEADDR);
|
||||
|
||||
SetByteOrder();
|
||||
}
|
||||
|
||||
Beb::~Beb(){
|
||||
delete ll;
|
||||
delete [] send_data_raw;
|
||||
delete [] recv_data_raw;
|
||||
}
|
||||
|
||||
void Beb::ClearBebInfos(){
|
||||
for(unsigned int i=0;i<beb_infos.size();i++) delete beb_infos[i];
|
||||
beb_infos.clear();
|
||||
}
|
||||
|
||||
bool Beb::InitBebInfos(){//file name at some point
|
||||
ClearBebInfos();
|
||||
|
||||
BebInfo* b0 = new BebInfo(0);
|
||||
if(b0->SetSerialAddress(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 ("<<i<<") :"<<endl;
|
||||
beb_infos[i]->Print();
|
||||
cout<<endl<<endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bool Beb::ReadSetUpFromFile(string file_name){
|
||||
|
||||
static ifstream infile;
|
||||
static string line;
|
||||
static char cmd_st[2000],str_mac1[200],str_ip1[200],str_mac10[200],str_ip10[200];
|
||||
static int value_i[2];
|
||||
|
||||
infile.open(file_name.c_str(),ios::in);
|
||||
if(!infile.is_open()){
|
||||
cout<<"Error could not open setup file: "<<file_name<<"."<<endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cout<<endl;
|
||||
cout<<"Setting up detector:"<<endl;
|
||||
while(std::getline(infile,line)){
|
||||
if(line.length()<1) continue;
|
||||
istringstream iss(line);
|
||||
iss>>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 "<<file_name<<"."<<endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if(GetBebInfoIndex(value_i[0])){
|
||||
cout<<"Error adding beb from "<<file_name<<", beb number "<<value_i[0]<<" already added."<<endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
BebInfo* b = new BebInfo(value_i[0]);
|
||||
b->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;i<beb_infos.size();i++){ //header stuff always starts from 1
|
||||
if(!SetHeaderData(beb_infos[i]->GetBebNumber(),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 "<<beb_infos[i]->GetBebNumber()<<"."<<endl;
|
||||
beb_infos[i]->Print();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int Beb::GetBebInfoIndex(unsigned int beb_numb){
|
||||
if(!beb_numb) return 0;
|
||||
|
||||
for(unsigned int i=1;i<beb_infos.size();i++) if(beb_numb==beb_infos[i]->GetBebNumber()) return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Beb::WriteTo(unsigned int index){
|
||||
if(index>=beb_infos.size()){
|
||||
cout<<"WriteTo index error."<<endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
send_data_raw[0] = 0x90000000 | beb_infos[index]->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<n;i++) d[i] = (((d[i]&0xff)<<24) | ((d[i]&0xff00)<<8) | ((d[i]&0xff0000)>>8) | ((d[i]&0xff000000)>>24)); //little_endian
|
||||
else for(unsigned int i=0;i<n;i++) d[i] = (((d[i]&0xffff)<<16) | ((d[i]&0xffff0000)>>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 ..."<<endl;
|
||||
|
||||
if(beb_infos.size()<2) return 0;
|
||||
|
||||
send_ndata = 3;
|
||||
send_data[0] = 0x000c0000;
|
||||
send_data[1] = 0;
|
||||
send_data[2] = 0;
|
||||
WriteTo(0);
|
||||
|
||||
//using little endian for data, big endian not fully tested, swap on 16 bit boundary.
|
||||
send_ndata = 3;
|
||||
send_data[0] = 0x000c0000;
|
||||
send_data[1] = 1;
|
||||
send_data[2] = 0;
|
||||
SwapDataFun(0,2,&(send_data[1]));
|
||||
WriteTo(0);
|
||||
|
||||
cout<<"\tSetting Byte Order .............. ok"<<endl<<endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool Beb::SetUpUDPHeader(unsigned int beb_number, bool ten_gig, unsigned int header_number, string dst_mac, string dst_ip, unsigned int dst_port){
|
||||
unsigned int i = GetBebInfoIndex(beb_number);
|
||||
if(!i) return 0; //i must be greater than 0, zero is the global send
|
||||
|
||||
send_ndata = 14;
|
||||
send_data[0] = ten_gig ? 0x00020000 : 0x00010000; //write to fanout numbers 1 or 2
|
||||
send_data[1] = ((header_number*8)<<16);
|
||||
if(!SetHeaderData(beb_number,ten_gig,dst_mac,dst_ip,dst_port)) return 0;
|
||||
|
||||
SwapDataFun(1,12,&(send_data[2]));
|
||||
|
||||
if(!WriteTo(i)) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bool Beb::SetHeaderData(unsigned int beb_number, bool ten_gig, string dst_mac, string dst_ip, unsigned int dst_port){
|
||||
unsigned int i = GetBebInfoIndex(beb_number);
|
||||
if(!i) return 0; //i must be greater than 0, zero is the global send
|
||||
return SetHeaderData(beb_infos[i]->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<num_words; i++) word_ptr[i] = base_ptr[i];
|
||||
// for(unsigned int i=num_words; i<16; i++) word_ptr[i] = 0;
|
||||
// return word_ptr;
|
||||
|
||||
for(unsigned int i=0; i<num_words; i++) send_data[i+2] = base_ptr[i];
|
||||
for(unsigned int i=num_words; i<16; i++) send_data[i+2] = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bool Beb::SetMAC(string mac, unsigned char* dst_ptr){
|
||||
for(int i=0;i<6;i++){
|
||||
size_t p0=mac.find(':');
|
||||
if((i!=5&&p0!=2)||(i==5&&mac.length()!=2)){
|
||||
cout<<"Error: in mac address -> "<<mac<<endl;
|
||||
return 0;
|
||||
}
|
||||
dst_ptr[i] = (unsigned char) strtoul(mac.substr(0,p0).c_str(),NULL,16);
|
||||
mac=mac.substr(p0+1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Beb::SetIP(string ip, unsigned char* dst_ptr){
|
||||
for(int i=0;i<4;i++){
|
||||
size_t p0=ip.find('.');
|
||||
if((i!=3&&(p0<1||p0>3))||(i==3&&(ip.length()<1||ip.length()>3))){
|
||||
cout<<"Error: in ip address -> "<<ip<<endl;
|
||||
return 0;
|
||||
}
|
||||
dst_ptr[i] = atoi(ip.substr(0,p0).c_str());
|
||||
ip=ip.substr(p0+1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Beb::SetPortNumber(unsigned int port_number, unsigned char* dst_ptr){
|
||||
dst_ptr[0] = (port_number >> 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: "<<beb_number<<","<<left_right<<","<<ten_gig<<","<<dst_number<<","<<1<<","<<header_size<<","<<test_just_send_out_packets_no_wait<<endl;
|
||||
|
||||
for(unsigned int i=0;i<nimages;i++){
|
||||
//header then data request
|
||||
if(!SendMultiReadRequest(beb_number,left_right,ten_gig,dst_number,1,header_size,test_just_send_out_packets_no_wait) ||
|
||||
!SendMultiReadRequest(beb_number,left_right,ten_gig,dst_number,npackets,packet_size,test_just_send_out_packets_no_wait) ||
|
||||
(in_two_requests&&!SendMultiReadRequest(beb_number,left_right,ten_gig,dst_number,npackets,packet_size,test_just_send_out_packets_no_wait))) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bool Beb::Test(unsigned int beb_number){
|
||||
cout<<"Testing module number: "<<beb_number<<endl;
|
||||
|
||||
|
||||
//bool Beb::SetUpUDPHeader(unsigned int beb_number, bool ten_gig, unsigned int header_number, string dst_mac, string dst_ip, unsigned int dst_port){
|
||||
//SetUpUDPHeader(26,0,0,"60:fb:42:f4:e3:d2","129.129.205.186",22000);
|
||||
|
||||
unsigned int index = GetBebInfoIndex(beb_number);
|
||||
if(!index){
|
||||
cout<<"Error beb number ("<<beb_number<<")not in list????"<<endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
for(unsigned int i=0;i<64;i++){
|
||||
if(!SetUpUDPHeader(beb_number,0,i,"60:fb:42:f4:e3:d2","129.129.205.186",22000+i)){
|
||||
cout<<"Error setting up header table...."<<endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 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=1);
|
||||
for(unsigned int i=0;i<64;i++){
|
||||
if(!SendMultiReadRequest(beb_number,i%3+1,0,i,1,0)){
|
||||
cout<<"Error requesting data...."<<endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
104
slsDetectorSoftware/eigerDetectorServer/Beb.h
Normal file
104
slsDetectorSoftware/eigerDetectorServer/Beb.h
Normal file
@ -0,0 +1,104 @@
|
||||
|
||||
/**
|
||||
* @author Ian Johnson
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BEB_H
|
||||
#define BEB_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "LocalLinkInterface.h"
|
||||
|
||||
|
||||
class BebInfo{
|
||||
|
||||
private:
|
||||
unsigned int beb_number;
|
||||
unsigned int serial_address;
|
||||
std::string src_mac_1GbE;
|
||||
std::string src_mac_10GbE;
|
||||
std::string src_ip_1GbE;
|
||||
std::string src_ip_10GbE;
|
||||
unsigned int src_port_1GbE;
|
||||
unsigned int src_port_10GbE;
|
||||
|
||||
public:
|
||||
BebInfo(unsigned int beb_num);
|
||||
~BebInfo(){};
|
||||
|
||||
bool SetSerialAddress(unsigned int add);
|
||||
bool SetHeaderInfo(bool ten_gig, std::string src_mac, std::string src_ip, unsigned int src_port);//src_port fixed 42000+beb_number or 52000 + beb_number);
|
||||
unsigned int GetBebNumber() {return beb_number;}
|
||||
unsigned int GetSerialAddress() {return serial_address;}
|
||||
std::string GetSrcMAC(bool ten_gig) {return ten_gig ? src_mac_10GbE : src_mac_1GbE;}
|
||||
std::string GetSrcIP(bool ten_gig) {return ten_gig ? src_ip_10GbE : src_ip_1GbE;}
|
||||
unsigned int GetSrcPort(bool ten_gig) {return ten_gig ? src_port_10GbE : src_port_1GbE;}
|
||||
|
||||
void Print();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Beb{ //
|
||||
|
||||
private:
|
||||
std::vector<BebInfo*> beb_infos;
|
||||
void ClearBebInfos();
|
||||
bool InitBebInfos();
|
||||
bool ReadSetUpFromFile(std::string file_name);
|
||||
bool CheckSourceStuffBebInfo();
|
||||
unsigned int GetBebInfoIndex(unsigned int beb_numb);
|
||||
|
||||
LocalLinkInterface* ll;
|
||||
|
||||
int send_ndata;
|
||||
unsigned int send_buffer_size;
|
||||
unsigned int* send_data_raw;
|
||||
unsigned int* send_data;
|
||||
|
||||
int recv_ndata;
|
||||
unsigned int recv_buffer_size;
|
||||
unsigned int* recv_data_raw;
|
||||
unsigned int* recv_data;
|
||||
|
||||
bool WriteTo(unsigned int index);
|
||||
|
||||
bool SetMAC(std::string mac, unsigned char* dst_ptr);
|
||||
bool SetIP(std::string ip, unsigned char* dst_ptr);
|
||||
bool SetPortNumber(unsigned int port_number, unsigned char* dst_ptr);
|
||||
void AdjustIPChecksum(udp_header_type *ip);
|
||||
|
||||
bool SetHeaderData(unsigned int beb_number, bool ten_gig, std::string dst_mac, std::string dst_ip, unsigned int dst_port);
|
||||
bool SetHeaderData(std::string src_mac, std::string src_ip, unsigned int src_port, std::string dst_mac, std::string dst_ip, unsigned int dst_port);
|
||||
|
||||
void SwapDataFun(bool little_endian, unsigned int n, unsigned int *d);
|
||||
bool SetByteOrder();
|
||||
|
||||
short bit_mode;
|
||||
|
||||
public:
|
||||
Beb();
|
||||
virtual ~Beb();
|
||||
|
||||
bool SetBebSrcHeaderInfos(unsigned int beb_number, bool ten_gig, std::string src_mac, std::string src_ip, unsigned int src_port);
|
||||
bool SetUpUDPHeader(unsigned int beb_number, bool ten_gig, unsigned int header_number, std::string dst_mac, std::string dst_ip, unsigned int dst_port);
|
||||
|
||||
bool 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=1);
|
||||
|
||||
|
||||
bool SetUpTransferParameters(short the_bit_mode);
|
||||
bool 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=0); //all images go to the same destination!
|
||||
|
||||
|
||||
bool Test(unsigned int beb_number);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
380
slsDetectorSoftware/eigerDetectorServer/BebServer.cxx
Executable file
380
slsDetectorSoftware/eigerDetectorServer/BebServer.cxx
Executable file
@ -0,0 +1,380 @@
|
||||
|
||||
/**
|
||||
* @author Ian Johnson
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <algorithm> // std::remove_if
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Beb.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
enum cmd_string {evNotFound,
|
||||
evRequestImages,evTestRequest,
|
||||
evSetBitMode,
|
||||
evSetupTableEntry,evSetDstParameters,
|
||||
evTest,evTestSend,
|
||||
evExitServer};
|
||||
|
||||
map<string, cmd_string> enum_map;
|
||||
|
||||
void init(){
|
||||
|
||||
enum_map["requestimages"] = evRequestImages; //<dst>
|
||||
enum_map["testrequest"] = evTestRequest; //<dst>
|
||||
|
||||
enum_map["setbitmode"] = evSetBitMode; // (resets on_dst and dst_requested)
|
||||
|
||||
enum_map["setuptableentry"] = evSetupTableEntry;
|
||||
enum_map["setdstparameters"] = evSetDstParameters; //<one_ten> <ndsts> <nimages_per_request> (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<<endl<<endl;
|
||||
|
||||
/*
|
||||
if(argc<2){
|
||||
cout<<"Usage: eiger_beb_server port_number"<<endl<<endl;
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
init();
|
||||
|
||||
Beb *bebs = new Beb();
|
||||
|
||||
// unsigned short int port_number = atoi(argv[1]);
|
||||
|
||||
unsigned short int port_number = 43212;
|
||||
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<<endl<<"\n\n\n\nWaiting for command -> "<<flush;
|
||||
int nread = AccpetConnectionAndWaitForData(data,length);
|
||||
if(nread<=0) return 0;
|
||||
|
||||
time(&rawtime); timeinfo=localtime(&rawtime);
|
||||
cout<<asctime(timeinfo);
|
||||
cout<<" Command received: "<<data<<endl<<endl;
|
||||
|
||||
|
||||
|
||||
string tmp_str[5];
|
||||
//float v1,v2,v3,v4,v5;
|
||||
int n[5];
|
||||
|
||||
string cmd = GetNextString(data,1);
|
||||
//static char retval_st[100];
|
||||
int ret_val = 1;
|
||||
string return_message = " Command recieved: ";
|
||||
return_message.append(data);
|
||||
return_message.append("\n");
|
||||
|
||||
int return_start_pos;
|
||||
while(cmd.length()>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 <dst_number> (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 <dst_number>");
|
||||
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 <dst_number> (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 <dst_number>\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 <bit_mode 4,8,16,32>\n");
|
||||
else{ return_message.append("\tExecuted: SetBitMode ");AddNumber(return_message,n[0]);return_message.append("\n");}
|
||||
break;
|
||||
|
||||
case evSetDstParameters : //move below //<one_ten_gigabit> <ndsts> <nimages_per_request>
|
||||
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()); //<ndsts (1 to 32)>
|
||||
n[2] = atoi(GetNextString(data).data()); // <nimages_per_request (>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)> <ndsts> <nimages_per_request>\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 <beb_number> <1GbE(0) or 10GbE(1)> <dst_number> <src_mac> <src_ip> <src_port> <dst_mac> <dst_ip> <dst_port>\n");
|
||||
ret_val = 1;
|
||||
}else{
|
||||
ret_val = !bebs->SetBebSrcHeaderInfos(n[0],n[1],tmp_str[0],tmp_str[1],n[3])||!bebs->SetUpUDPHeader(n[0],n[1],n[2],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 <beb_number>\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 <beb_number> <1GbE(0) or 10GbE(1)> <dst_number>\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<string, cmd_string>::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<<return_message.c_str()<<endl;
|
||||
cout<<"\treturn: "<<ret_val<<endl;
|
||||
|
||||
if(!WriteNClose(return_message.c_str(),return_message.length())) return 0;
|
||||
}
|
||||
|
||||
|
||||
delete bebs;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
string LowerCase(string str){
|
||||
string s = str;
|
||||
string::iterator i = s.begin();
|
||||
while(i!=s.end()) *i=tolower(*(i++));
|
||||
return s;
|
||||
}
|
||||
|
||||
string GetNextString(string str,bool start_from_beginning){
|
||||
static string::size_type start_pos = 0;
|
||||
if(start_from_beginning) start_pos = 0;
|
||||
|
||||
while(start_pos != string::npos){
|
||||
string::size_type found = str.find_first_of(" ",start_pos);
|
||||
string sub = str.substr(start_pos,found-start_pos);
|
||||
|
||||
start_pos = found;
|
||||
if(start_pos != string::npos) start_pos+=1;
|
||||
|
||||
sub.erase(remove_if(sub.begin(),sub.end(), ::isspace ),sub.end());
|
||||
|
||||
if(sub.length()>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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -24,4 +24,5 @@ Acquisition:
|
||||
stop acquisition
|
||||
acquisition in progress
|
||||
wait until daq is finished
|
||||
status (needs to be implemented)
|
||||
|
||||
|
@ -18,7 +18,7 @@ char eiger_message[1024];
|
||||
int eiger_message_length = 0;
|
||||
int eiger_ret_val=0;
|
||||
|
||||
const int ndacs = 16;
|
||||
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"};
|
||||
|
||||
|
||||
@ -47,6 +47,7 @@ int EigerInit(){
|
||||
if(!passed){
|
||||
struct hostent *dst_host;
|
||||
if((dst_host = gethostbyname("localhost")) == NULL){ //or look into getaddrinfo(3)
|
||||
/*if((dst_host = gethostbyname("beb026")) == NULL){ //or look into getaddrinfo(3)*/
|
||||
fprintf(stderr,"ERROR, no such host\n");
|
||||
return 0;
|
||||
}else{
|
||||
@ -127,10 +128,10 @@ int EigerGetDAC(const char* iname){
|
||||
return eiger_ret_val;
|
||||
}
|
||||
|
||||
int EigerSetNumberOfExposures(int n){
|
||||
int EigerSetNumberOfExposures(unsigned int n){
|
||||
eiger_nexposures = n;
|
||||
eiger_ret_val=0;
|
||||
eiger_message_length = sprintf(eiger_message,"setnumberofexposures %d",n);
|
||||
eiger_message_length = sprintf(eiger_message,"setnumberofexposures %u",n);
|
||||
return EigerSendCMD();
|
||||
}
|
||||
|
||||
@ -188,10 +189,10 @@ int EigerGetDynamicRange(){
|
||||
*/
|
||||
|
||||
|
||||
int EigerSetPhotonEnergy(unsigned int in_eV){
|
||||
int EigerSetPhotonEnergy(int in_eV){
|
||||
eigergetphotonenergy = in_eV;
|
||||
eiger_ret_val=0;
|
||||
eiger_message_length = sprintf(eiger_message,"setphotonenergy %u",in_eV);
|
||||
eiger_message_length = sprintf(eiger_message,"setphotonenergy %d",in_eV);
|
||||
return EigerSendCMD();
|
||||
}
|
||||
|
||||
|
1189
slsDetectorSoftware/eigerDetectorServer/FebControl.cxx
Normal file
1189
slsDetectorSoftware/eigerDetectorServer/FebControl.cxx
Normal file
File diff suppressed because it is too large
Load Diff
188
slsDetectorSoftware/eigerDetectorServer/FebControl.h
Normal file
188
slsDetectorSoftware/eigerDetectorServer/FebControl.h
Normal file
@ -0,0 +1,188 @@
|
||||
|
||||
/**
|
||||
* @author Ian Johnson
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FEBCONTROL_H
|
||||
#define FEBCONTROL_H
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "FebInterface.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;
|
||||
int* top_dac;
|
||||
int* 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;}
|
||||
|
||||
int SetTopDACValue(unsigned int i, int value) { return (i<ndacs && TopAddressIsValid()) ? (top_dac[i]=value) : -1;}
|
||||
int GetTopDACValue(unsigned int i) { return (i<ndacs) ? top_dac[i]:-1;}
|
||||
int SetBottomDACValue(unsigned int i, int value) { return (i<ndacs && BottomAddressIsValid()) ? (bottom_dac[i]=value) : -1;}
|
||||
int GetBottomDACValue(unsigned int i) { return (i<ndacs) ? bottom_dac[i]:-1;}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class FebControl:private FebInterface{
|
||||
|
||||
private:
|
||||
|
||||
std::vector<Module*> 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(Module* m);
|
||||
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, unsigned int& 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);
|
||||
|
||||
bool SendBitModeToBebServer();
|
||||
|
||||
unsigned int ConvertTimeToRegister(float time_in_sec);
|
||||
|
||||
unsigned int AddressToAll();
|
||||
bool SetCommandRegister(unsigned int cmd);
|
||||
bool GetDAQStatusRegister(unsigned int dst_address, unsigned int &ret_status);
|
||||
bool StartDAQOnlyNWaitForFinish(int sleep_time_us=5000);
|
||||
|
||||
bool ResetChipCompletely();
|
||||
|
||||
struct sockaddr_in serv_addr;
|
||||
bool SetupSendToSocket(const char* ip_address_hostname, unsigned short int port);
|
||||
int WriteNRead(char* message, int length, int max_length);
|
||||
|
||||
|
||||
public:
|
||||
FebControl();
|
||||
virtual ~FebControl();
|
||||
|
||||
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 DecodeDACString(std::string dac_str, unsigned int& module_index, bool& top, bool& bottom, unsigned int& dac_ch);
|
||||
bool SetDAC(std::string s, int value, bool is_a_voltage_mv=0);
|
||||
bool GetDAC(std::string s, int& ret_value, bool voltage_mv=0);
|
||||
bool GetDACName(unsigned int dac_num, std::string &s);
|
||||
|
||||
bool SetTrimbits(unsigned int module_num, 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 SetNExposures(unsigned int n_images);
|
||||
unsigned int GetNExposures();
|
||||
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();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
172
slsDetectorSoftware/eigerDetectorServer/FebInterface.cxx
Normal file
172
slsDetectorSoftware/eigerDetectorServer/FebInterface.cxx
Normal file
@ -0,0 +1,172 @@
|
||||
|
||||
/**
|
||||
* @author Ian Johnson
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
//#include <unistd.h>
|
||||
//#include <string.h>
|
||||
//#include <sys/mman.h>
|
||||
//#include <fcntl.h>
|
||||
|
||||
#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;i<n;i++) feb_numb[i] = list[i];
|
||||
}
|
||||
|
||||
bool FebInterface::WriteTo(unsigned int ch){
|
||||
if(ch>0xfff) 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;t<ntrys;t++){
|
||||
if((recv_ndata=ll->Read(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;i<nfebs;i++) dst = (dst | feb_numb[i]);
|
||||
bool passed = WriteTo(dst);
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
|
||||
bool FebInterface::ReadRegister(unsigned int sub_num, unsigned int reg_num,unsigned int& value_read){
|
||||
return ReadRegisters(sub_num,1,®_num,&value_read);
|
||||
}
|
||||
|
||||
|
||||
bool FebInterface::ReadRegisters(unsigned int sub_num, unsigned int nreads, unsigned int* reg_nums,unsigned int* values_read){
|
||||
//here cout<<"Reading Register ...."<<endl;
|
||||
|
||||
nreads &= 0x3ff;
|
||||
if(!nreads||nreads>send_buffer_size-2) return 0;
|
||||
|
||||
send_ndata = nreads+2;
|
||||
send_data[0] = 0x20000000 | nreads << 14;
|
||||
|
||||
for(unsigned int i=0;i<nreads;i++) send_data[i+1]=reg_nums[i];
|
||||
send_data[nreads+1] = 0;
|
||||
|
||||
if(!WriteTo(sub_num)||!ReadFrom(sub_num)||recv_ndata!=int(nreads+2)) return 0;
|
||||
|
||||
for(unsigned int i=0;i<nreads;i++) values_read[i] = recv_data[i+1];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool FebInterface::WriteRegister(unsigned int sub_num, unsigned int reg_num,unsigned int value, bool wait_on, unsigned int wait_on_address){
|
||||
return WriteRegisters(sub_num,1,®_num,&value,&wait_on,&wait_on_address);
|
||||
}
|
||||
|
||||
bool FebInterface::WriteRegisters(unsigned int sub_num, unsigned int nwrites, unsigned int* reg_nums, unsigned int* values, bool* wait_ons, unsigned int* wait_on_addresses){
|
||||
|
||||
nwrites &= 0x3ff; //10 bits
|
||||
if(!nwrites||2*nwrites>send_buffer_size-2) return 0;
|
||||
|
||||
//cout<<"Write register : "<<this<<" "<<s_num<<" "<<nwrites<<" "<<reg_nums<<" "<<values<<" "<<wait_ons<<" "<<wait_on_addresses<<endl;
|
||||
send_ndata = 2*nwrites+2;
|
||||
send_data[0] = 0x80000000 | nwrites << 14;
|
||||
send_data[2*nwrites+1] = 0;
|
||||
|
||||
for(unsigned int i=0;i<nwrites;i++) send_data[2*i+1] = 0x3fff®_nums[i];
|
||||
for(unsigned int i=0;i<nwrites;i++) send_data[2*i+2] = values[i];
|
||||
// wait on busy data(28), address of busy flag data(27 downto 14)
|
||||
if(wait_ons&&wait_on_addresses) for(unsigned int i=0;i<nwrites;i++) send_data[2*i+1] |= (wait_ons[i]<<28 | (0x3fff&wait_on_addresses[i])<<14);
|
||||
|
||||
if(!WriteTo(sub_num)) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bool FebInterface::WriteMemory(unsigned int sub_num, unsigned int mem_num, unsigned int start_address, unsigned int nwrites, unsigned int *values){
|
||||
// -1 means write to all
|
||||
|
||||
mem_num &= 0x3f;
|
||||
start_address &= 0x3fff;
|
||||
nwrites &= 0x3ff;
|
||||
if(!nwrites||nwrites>send_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;
|
||||
for(unsigned int i=0;i<nwrites;i++) send_data[i+1] = values[i];
|
||||
|
||||
|
||||
if(!WriteTo(sub_num)) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
53
slsDetectorSoftware/eigerDetectorServer/FebInterface.h
Normal file
53
slsDetectorSoftware/eigerDetectorServer/FebInterface.h
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
/**
|
||||
* @author Ian Johnson
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FEBINTERFACE_H
|
||||
#define FEBINTERFACE_H
|
||||
|
||||
#include "LocalLinkInterface.h"
|
||||
|
||||
class FebInterface{ //
|
||||
|
||||
private:
|
||||
LocalLinkInterface* ll;
|
||||
|
||||
unsigned int nfebs;
|
||||
unsigned int* feb_numb;
|
||||
|
||||
int send_ndata;
|
||||
unsigned int send_buffer_size;
|
||||
unsigned int* send_data_raw;
|
||||
unsigned int* send_data;
|
||||
|
||||
int recv_ndata;
|
||||
unsigned int recv_buffer_size;
|
||||
unsigned int* recv_data_raw;
|
||||
unsigned int* recv_data;
|
||||
|
||||
bool WriteTo(unsigned int ch);
|
||||
bool ReadFrom(unsigned int ch, unsigned int ntrys=20);
|
||||
|
||||
|
||||
public:
|
||||
FebInterface();
|
||||
virtual ~FebInterface();
|
||||
|
||||
void SendCompleteList(unsigned int n,unsigned int* list);
|
||||
bool SetByteOrder();
|
||||
|
||||
bool ReadRegister(unsigned int sub_num, unsigned int reg_num,unsigned int& value_read);
|
||||
bool ReadRegisters(unsigned int sub_num, unsigned int nreads, unsigned int* reg_nums,unsigned int* values_read);
|
||||
|
||||
bool WriteRegister(unsigned int sub_num, unsigned int reg_num,unsigned int value, bool wait_on=0, unsigned int wait_on_address=0);
|
||||
bool WriteRegisters(unsigned int sub_num, unsigned int nwrites, unsigned int* reg_nums, unsigned int* values, bool* wait_ons=0, unsigned int* wait_on_addresses=0);
|
||||
|
||||
bool WriteMemory(unsigned int sub_num, unsigned int mem_num, unsigned int start_address, unsigned int nwrites, unsigned int *values);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
111
slsDetectorSoftware/eigerDetectorServer/FebRegisterDefs.h
Normal file
111
slsDetectorSoftware/eigerDetectorServer/FebRegisterDefs.h
Normal file
@ -0,0 +1,111 @@
|
||||
|
||||
/**
|
||||
* @author Ian Johnson
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
|
||||
//daq register definitions
|
||||
#define DAQ_REG_CTRL 1
|
||||
#define DAQ_REG_CHIP_CMDS 2
|
||||
#define DAQ_REG_STATIC_BITS 3
|
||||
#define DAQ_REG_CLK_ROW_CLK_NTIMES 3
|
||||
#define DAQ_REG_SHIFT_IN_32 3
|
||||
#define DAQ_REG_READOUT_NROWS 3
|
||||
#define DAQ_REG_SEND_N_TESTPULSES 3
|
||||
|
||||
#define DAQ_REG_NEXPOSURES 3
|
||||
#define DAQ_REG_EXPOSURE_TIMER 4 // == (31 downto 3) * 10^(2 downto 0)
|
||||
#define DAQ_REG_EXPOSURE_REPEAT_TIMER 5 // == (31 downto 3) * 10^(2 downto 0)
|
||||
#define DAQ_REG_STATUS 6 //also pg and fifo status register
|
||||
|
||||
#define DAQ_CTRL_RESET 0x80000000
|
||||
#define DAQ_CTRL_START 0x40000000
|
||||
#define ACQ_CTRL_START 0x50000000 //this is 0x10000000 (acq) | 0x40000000 (daq)
|
||||
#define DAQ_CTRL_STOP 0x00000000
|
||||
|
||||
//direct chip commands to the DAQ_REG_CHIP_CMDS register
|
||||
#define DAQ_SET_STATIC_BIT 0x00000001
|
||||
#define DAQ_RESET_COMPLETELY 0x0000000E
|
||||
#define DAQ_RESET_PERIPHERY 0x00000002
|
||||
#define DAQ_RESET_PIXEL_COUNTERS 0x00000004
|
||||
#define DAQ_RESET_COLUMN_SELECT 0x00000008
|
||||
|
||||
#define DAQ_STORE_IMAGE 0x00000010
|
||||
#define DAQ_RELEASE_IMAGE_STORE 0x00000020
|
||||
|
||||
#define DAQ_SEND_A_TOKEN_IN 0x00000040
|
||||
#define DAQ_CLK_ROW_CLK_NTIMES 0x00000080
|
||||
#define DAQ_SERIALIN_SHIFT_IN_32 0x00000100
|
||||
#define DAQ_LOAD_16ROWS_OF_TRIMBITS 0x00000200
|
||||
|
||||
#define DAQ_IGNORE_INITIAL_CRAP 0x00000400 //crap before readout
|
||||
#define DAQ_READOUT_NROWS 0x00000800
|
||||
#define DAQ_CLKOUT_LAST_4_BITS_AND_RETURN_TO_START 0x00001000 //last 4 bit of data in the last frame
|
||||
|
||||
#define DAQ_RELEASE_IMAGE_STORE_AFTER_READOUT 0x00002000
|
||||
#define DAQ_RESET_PIXEL_COUNTERS_AFTER_READOUT 0x00004000
|
||||
|
||||
#define DAQ_CLK_ROW_CLK_TO_SELECT_NEXT_ROW 0x00008000
|
||||
#define DAQ_CLK_MAIN_CLK_TO_SELECT_NEXT_PIXEL 0x00010000
|
||||
#define DAQ_SEND_N_TEST_PULSES 0x00020000
|
||||
|
||||
#define DAQ_CHIP_CONTROLLER_HALF_SPEED 0x00040000 //everything at 100 MHz (50MHz ddr readout)
|
||||
#define DAQ_CHIP_CONTROLLER_QUARTER_SPEED 0x00080000 //everything at 50 MHz (25MHz ddr readout)
|
||||
#define DAQ_CHIP_CONTROLLER_SUPER_SLOW_SPEED 0x000c0000 //everything at ~200 kHz (200 kHz MHz ddr readout)
|
||||
|
||||
#define DAQ_FIFO_ENABLE 0x00100000
|
||||
|
||||
//direct chip commands to the DAQ_REG_CHIP_CMDS register
|
||||
#define DAQ_NEXPOSURERS_SAFEST_MODE_ROW_CLK_BEFORE_MODE 0x00200000 //row clk is before main clk readout sequence
|
||||
#define DAQ_NEXPOSURERS_NORMAL_NONPARALLEL_MODE 0x00400000 //expose ->readout ->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
|
||||
|
||||
|
||||
//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
|
533
slsDetectorSoftware/eigerDetectorServer/FebServer.cxx
Executable file
533
slsDetectorSoftware/eigerDetectorServer/FebServer.cxx
Executable file
@ -0,0 +1,533 @@
|
||||
|
||||
/**
|
||||
* @author Ian Johnson
|
||||
* @version 1.0
|
||||
* @developed for running Eiger at cSAXS
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <algorithm> // std::remove_if
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "FebControl.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
enum cmd_string {evNotFound,
|
||||
evReinitialize,evReset,
|
||||
|
||||
// evSetInputDelays,
|
||||
evSetDACValue,evGetDACValue,evSetDACVoltage,evGetDACVoltage,evSetHighVoltage,//evGetHighVoltage,
|
||||
|
||||
// evSetTrimBits,evLoadTrimBitFile,
|
||||
|
||||
evSetBitMode,
|
||||
evSetPhotonEnergy,
|
||||
// evSetPhotonEnergyCalibrationParameters,evActivateRateCorrection,evDeactivateRateCorrection,evSetRateCorrectionTau,
|
||||
|
||||
evSetReadoutSpeed,evSetReadoutMode,
|
||||
|
||||
//temp solution
|
||||
// evNotFound1,evNotFound2,evNotFound3,
|
||||
|
||||
evSetNumberOfExposures,evSetExposureTime,evSetExposurePeriod,
|
||||
// evSetTriggerPolarityToPositive,evSetTriggerPolarityToNegative,evSetTriggerMode,
|
||||
// evEnableExternalGatingWhenSignalsPositive,evEnableExternalGatingWhenSignalsNegative,evDisableExternalGating,
|
||||
evStartAcquisition,evStopAcquisition,evIsDaqStillRunning};
|
||||
// evWaitUntilDaqFinished,evExitServer
|
||||
|
||||
|
||||
map<string, cmd_string> 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["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["enableexternalgatingwhensignalspositive"] = evEnableExternalGatingWhenSignalsPositive;
|
||||
enum_map["enableexternalgatingwhensignalsnegative"] = evEnableExternalGatingWhenSignalsNegative;
|
||||
enum_map["disableexternalgating"] = evDisableExternalGating;
|
||||
*/
|
||||
|
||||
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<<endl<<endl;
|
||||
|
||||
/*
|
||||
if(argc<2){
|
||||
cout<<"Usage: feb_server port_number"<<endl<<endl;
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
init();
|
||||
|
||||
FebControl *feb_controler = new FebControl();
|
||||
|
||||
unsigned short int port_number = 43210;
|
||||
if(!SetupListenSocket(port_number)) return 1;
|
||||
|
||||
|
||||
int length=1000;
|
||||
char data[1000];
|
||||
|
||||
int stop = 0;
|
||||
time_t rawtime;
|
||||
struct tm *timeinfo;
|
||||
|
||||
|
||||
while(!stop){
|
||||
|
||||
cout<<endl<<"\n\n\n\nWaiting for command -> "<<flush;
|
||||
int nread = AccpetConnectionAndWaitForData(data,length);
|
||||
if(nread<=0) return 0;
|
||||
|
||||
time(&rawtime); timeinfo=localtime(&rawtime);
|
||||
cout<<asctime(timeinfo);
|
||||
cout<<" Command received: "<<data<<endl<<endl;
|
||||
|
||||
|
||||
|
||||
string tmp_str[5];
|
||||
float v[4];//,v2,v3,v4,v5;
|
||||
int n[5];
|
||||
|
||||
string cmd = GetNextString(data,1);
|
||||
int ret_val = 1;
|
||||
|
||||
string return_message = "\n\n\tCommand recieved: ";
|
||||
return_message.append(data);
|
||||
return_message.append("\n");
|
||||
|
||||
int return_start_pos;
|
||||
while(cmd.length()>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 :
|
||||
|
||||
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 <dac_name> <value>\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(" mV\n");
|
||||
ret_val = 0;
|
||||
}else{
|
||||
return_message.append("\tError executing: GetDACValue <dac_name>\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 <dac_name> <voltage_mV>\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 <dac_name>\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 <voltage>\n");
|
||||
ret_val = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
// case evSetTrimBits :
|
||||
// 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 <mode 4,8,16,32>\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 <energy eV>\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 <speed 0-full 1-half 2-quarter 3-super_slow>\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 <mode 0->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>\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 <t_seconds>\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 <t_seconds>\n");
|
||||
ret_val = 1;
|
||||
}
|
||||
break;
|
||||
// case evSetTriggerPolarityToPositive :
|
||||
// case evSetTriggerPolarityToNegative :
|
||||
// case evSetTriggerMode :
|
||||
|
||||
// case evEnableExternalGatingWhenSignalsPositive :
|
||||
// case evEnableExternalGatingWhenSignalsNegative :
|
||||
// case evDisableExternalGating :
|
||||
|
||||
|
||||
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<string, cmd_string>::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<<return_message.c_str()<<endl;
|
||||
cout<<"\treturn: "<<ret_val<<endl;
|
||||
|
||||
if(!WriteNClose(return_message.c_str(),return_message.length())) return 0;
|
||||
}
|
||||
|
||||
|
||||
delete feb_controler;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
string LowerCase(string str){
|
||||
string s = str;
|
||||
string::iterator i = s.begin();
|
||||
while(i!=s.end()) *i=tolower(*(i++));
|
||||
return s;
|
||||
}
|
||||
|
||||
string GetNextString(string str,bool start_from_beginning){
|
||||
static string::size_type start_pos = 0;
|
||||
if(start_from_beginning) start_pos = 0;
|
||||
|
||||
while(start_pos != string::npos){
|
||||
string::size_type found = str.find_first_of(" ",start_pos);
|
||||
string sub = str.substr(start_pos,found-start_pos);
|
||||
|
||||
start_pos = found;
|
||||
if(start_pos != string::npos) start_pos+=1;
|
||||
|
||||
sub.erase(remove_if(sub.begin(),sub.end(), ::isspace ),sub.end());
|
||||
|
||||
if(sub.length()>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);
|
||||
}
|
||||
|
||||
|
||||
|
28
slsDetectorSoftware/eigerDetectorServer/Makefile.virtual
Normal file
28
slsDetectorSoftware/eigerDetectorServer/Makefile.virtual
Normal file
@ -0,0 +1,28 @@
|
||||
CC = gcc
|
||||
CFLAGS += -Wall -DDACS_INT -DEIGERD -DDACS_INT -DSTOP_SERVER -DPCCOMPILE#-DVERBOSE #-DVIRTUAL -DPCCOMPILE
|
||||
LDLIBS += -lm -lstdc++
|
||||
|
||||
PROGS = eigerDetectorServerVirtual
|
||||
DESTDIR ?= bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRC_CLNT = communication_funcs.c slsDetectorServer.c slsDetectorServer_funcs.c slsDetectorFunctionList.c
|
||||
#SRC_CLNT2 = Eiger.cxx HardwareIO.cxx LocalLinkInterface.cxx Feb.cxx
|
||||
OBJS = $(SRC_CLNT:.c=.o)
|
||||
OBJS2 = $(SRC_CLNT2:.cpp=.o)
|
||||
|
||||
|
||||
all: clean $(PROGS)
|
||||
|
||||
|
||||
boot: $(OBJS) $(OBJS2)
|
||||
|
||||
$(PROGS):
|
||||
echo $(OBJS) $(OBJS2)
|
||||
mkdir -p $(DESTDIR)
|
||||
$(CC) -o $@ $(SRC_CLNT) $(CFLAGS) $(LDLIBS)
|
||||
mv $(PROGS) $(DESTDIR)
|
||||
|
||||
clean:
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o
|
||||
|
Binary file not shown.
BIN
slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServerVirtual
Executable file
BIN
slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServerVirtual
Executable file
Binary file not shown.
@ -4,11 +4,16 @@ echo -e "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
|
||||
. /opt/eldk-5.1/powerpc-4xx-softfloat/environment-setup-ppc440-linux
|
||||
|
||||
#powerpc-4xx-softfloat-g++ -Wall -o test Test.cxx HardwareIO.cxx LocalLinkInterface.cxx Feb.cxx -I .
|
||||
|
||||
powerpc-4xx-softfloat-g++ -Wall -o eiger_test EigerTest.cxx Eiger.cxx HardwareIO.cxx LocalLinkInterface.cxx Feb.cxx -I .
|
||||
|
||||
#powerpc-4xx-softfloat-g++ -Wall -o hardware_interface_test HardwareInterfaceTest.cxx HardwareInterface.cxx HardwareMMapping.cxx -I .
|
||||
|
||||
|
||||
#powerpc-4xx-softfloat-g++ -Wall -o eiger_test EigerTest.cxx Eiger.cxx HardwareIO.cxx LocalLinkInterface.cxx Feb.cxx -I .
|
||||
|
||||
powerpc-4xx-softfloat-g++ -Wall -o feb_debug FebServer.cxx FebControl.cxx FebInterface.cxx LocalLinkInterface.cxx HardwareIO.cxx -I .
|
||||
|
||||
powerpc-4xx-softfloat-g++ -Wall -o beb_debug BebServer.cxx Beb.cxx LocalLinkInterface.cxx HardwareIO.cxx -I .
|
||||
|
||||
|
||||
cp eiger_test rootfs_executables/.
|
||||
|
||||
|
||||
|
@ -19,21 +19,21 @@ readout_mode 0 #(0-parallel,1-non_parallel,2-safe_mode)
|
||||
|
||||
#default dacs
|
||||
SvP 0
|
||||
Vtr 1.28
|
||||
Vrf 1.55
|
||||
Vrs 0.7
|
||||
SvN 2
|
||||
Vtgstv 1.278
|
||||
Vcmp_ll 0.5
|
||||
Vcmp_lr 0.5
|
||||
cal 2
|
||||
Vcmp_rl 0.5
|
||||
rxb_rb 0.6
|
||||
rxb_lb 0.6
|
||||
Vcmp_rr 0.5
|
||||
Vcp 0.1
|
||||
Vcn 1
|
||||
Vis 0.775
|
||||
Vtr 1280
|
||||
Vrf 1550
|
||||
Vrs 700
|
||||
SvN 2000
|
||||
Vtgstv 1278
|
||||
Vcmp_ll 750
|
||||
Vcmp_lr 750
|
||||
cal 2000
|
||||
Vcmp_rl 750
|
||||
rxb_rb 600
|
||||
rxb_lb 600
|
||||
Vcmp_rr 750
|
||||
Vcp 100
|
||||
Vcn 1000
|
||||
Vis 775
|
||||
|
||||
#default high_voltage
|
||||
high_voltage 152
|
||||
|
12
slsDetectorSoftware/eigerDetectorServer/setup_beb.txt
Normal file
12
slsDetectorSoftware/eigerDetectorServer/setup_beb.txt
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
|
||||
#detector setup
|
||||
#add_beb base_address mac_1GBE ip_1GBE mac_10GBE ip_10GBE
|
||||
|
||||
add_beb 26 0 00:50:c2:46:d9:34 129.129.205.78 00:50:c2:46:d9:35 10.0.26.1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -359,7 +359,7 @@ int executeTrimming(enum trimMode mode, int par1, int par2, int imod){
|
||||
}
|
||||
|
||||
|
||||
int configureMAC(int ipad, long long int imacadd, long long int iservermacadd, int dtb){
|
||||
int configureMAC(int ipad, long long int macad, long long int detectormacadd, int detipad, int udpport, int ival){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4128,7 +4128,7 @@ int slsDetector::setDynamicRange(int n){
|
||||
ret=thisReceiver->sendInt(fnum2,retval1,retval);
|
||||
if((retval1 != retval)|| (ret==FAIL)){
|
||||
ret = FAIL;
|
||||
cout << "ERROR:Acquisition Period in receiver set incorrectly to " << retval1 << " instead of " << retval << endl;
|
||||
cout << "ERROR:Dynamic range in receiver set incorrectly to " << retval1 << " instead of " << retval << endl;
|
||||
setErrorMask((getErrorMask())|(RECEIVER_DYNAMIC_RANGE));
|
||||
}
|
||||
if(ret==FORCE_UPDATE)
|
||||
|
@ -85,7 +85,7 @@ int executeTrimming(enum trimMode mode, int par1, int par2, int imod);
|
||||
|
||||
|
||||
#ifndef MYTHEND
|
||||
int configureMAC(int ipad, long long int imacadd, long long int iservermacadd, int dtb);
|
||||
int configureMAC(int ipad, long long int macad, long long int detectormacadd, int detipad, int udpport, int ival);
|
||||
#endif
|
||||
|
||||
#ifdef GOTTHARDD
|
||||
|
@ -370,33 +370,53 @@ int send_update(int file_des) {
|
||||
int64_t retval = 0;
|
||||
|
||||
n += sendData(file_des,lastClientIP,sizeof(lastClientIP),OTHER);
|
||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||
nm=setNMod(GET_FLAG,X);
|
||||
#endif
|
||||
n += sendData(file_des,&nm,sizeof(nm),INT32);
|
||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||
nm=setNMod(GET_FLAG,Y);
|
||||
#endif
|
||||
n += sendData(file_des,&nm,sizeof(nm),INT32);
|
||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||
nm=setDynamicRange(GET_FLAG);
|
||||
#endif
|
||||
n += sendData(file_des,&nm,sizeof(nm),INT32);
|
||||
nm = dataBytes;
|
||||
n += sendData(file_des,&nm,sizeof(nm),INT32);
|
||||
|
||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||
t=setSettings(GET_SETTINGS, GET_FLAG);
|
||||
#endif
|
||||
n += sendData(file_des,&t,sizeof(t),INT32);
|
||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||
nm=getThresholdEnergy(GET_FLAG);
|
||||
#endif
|
||||
n += sendData(file_des,&nm,sizeof(nm),INT32);
|
||||
|
||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||
retval=setTimer(FRAME_NUMBER,GET_FLAG);
|
||||
#endif
|
||||
n += sendData(file_des,&retval,sizeof(int64_t),INT64);
|
||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||
retval=setTimer(ACQUISITION_TIME,GET_FLAG);
|
||||
#endif
|
||||
n += sendData(file_des,&retval,sizeof(int64_t),INT64);
|
||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||
retval=setTimer(FRAME_PERIOD,GET_FLAG);
|
||||
#endif
|
||||
n += sendData(file_des,&retval,sizeof(int64_t),INT64);
|
||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||
retval=setTimer(DELAY_AFTER_TRIGGER,GET_FLAG);
|
||||
#endif
|
||||
n += sendData(file_des,&retval,sizeof(int64_t),INT64);
|
||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||
retval=setTimer(GATES_NUMBER,GET_FLAG);
|
||||
#endif
|
||||
n += sendData(file_des,&retval,sizeof(int64_t),INT64);
|
||||
/* retval=setTimer(PROBES_NUMBER,GET_FLAG);
|
||||
n += sendData(file_des,&retval,sizeof(int64_t),INT64);*/
|
||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||
retval=setTimer(CYCLES_NUMBER,GET_FLAG);
|
||||
#endif
|
||||
n += sendData(file_des,&retval,sizeof(int64_t),INT64);
|
||||
|
||||
if (lockStatus==0) {
|
||||
@ -2885,16 +2905,18 @@ int execute_trimming(int file_des) {
|
||||
|
||||
int configure_mac(int file_des) {
|
||||
|
||||
int retval=-1;
|
||||
int retval=-100;
|
||||
int ret=OK,ret1=OK;
|
||||
char arg[3][50];
|
||||
char arg[5][50];
|
||||
int n;
|
||||
|
||||
#ifndef MYTHEND
|
||||
int imod=0;//should be in future sent from client as -1, arg[2]
|
||||
int ipad;
|
||||
long long int imacadd;
|
||||
long long int iservermacadd;
|
||||
long long int idetectormacadd;
|
||||
int udpport;
|
||||
int detipad;
|
||||
#endif
|
||||
|
||||
sprintf(mess,"Can't configure MAC\n");
|
||||
@ -2909,9 +2931,13 @@ int configure_mac(int file_des) {
|
||||
ret = FAIL;
|
||||
strcpy(mess,"Not applicable/implemented for this detector\n");
|
||||
#else
|
||||
sscanf(arg[0], "%x", &ipad);
|
||||
sscanf(arg[1], "%llx", &imacadd);
|
||||
sscanf(arg[2], "%llx", &iservermacadd);
|
||||
sscanf(arg[0], "%x", &ipad);
|
||||
sscanf(arg[1], "%llx", &imacadd);
|
||||
sscanf(arg[2], "%x", &udpport);
|
||||
sscanf(arg[3], "%llx", &idetectormacadd);
|
||||
sscanf(arg[4], "%x", &detipad);
|
||||
|
||||
|
||||
|
||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||
if (imod>=getTotalNumberOfModules()) {
|
||||
@ -2927,17 +2953,20 @@ int configure_mac(int file_des) {
|
||||
printf("macad:%llx\n",imacadd);
|
||||
for (i=0;i<6;i++)
|
||||
printf("mac adress %d is 0x%x \n",6-i,(unsigned int)(((imacadd>>(8*i))&0xFF)));
|
||||
printf("server macad:%llx\n",iservermacadd);
|
||||
printf("udp port:0x%x\n",udpport);
|
||||
printf("detector macad:%llx\n",idetectormacadd);
|
||||
for (i=0;i<6;i++)
|
||||
printf("server mac adress %d is 0x%x \n",6-i,(unsigned int)(((iservermacadd>>(8*i))&0xFF)));
|
||||
printf("detector mac adress %d is 0x%x \n",6-i,(unsigned int)(((idetectormacadd>>(8*i))&0xFF)));
|
||||
printf("detipad %x\n",detipad);
|
||||
printf("\n");
|
||||
printf("Configuring MAC of module %d\n", imod);
|
||||
printf("Configuring MAC of module %d at port %x\n", imod, udpport);
|
||||
#endif
|
||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||
if (ret==OK) {
|
||||
/*retval=configureMAC(ipad,imacadd,iservermacadd,digitalTestBit);*/
|
||||
retval=configureMAC(ipad,imacadd,iservermacadd,0);
|
||||
/*if(retval==-1) ret=FAIL;*/
|
||||
if(getRunStatus() == RUNNING)
|
||||
stopStateMachine();
|
||||
retval=configureMAC(ipad,imacadd,idetectormacadd,detipad,udpport,0); /*digitalTestBit);*/
|
||||
if(retval==-1) ret=FAIL;
|
||||
}
|
||||
#endif
|
||||
#ifdef VERBOSE
|
||||
|
Loading…
x
Reference in New Issue
Block a user