diff --git a/slsDetectorSoftware/eigerDetectorServer/Beb.c b/slsDetectorSoftware/eigerDetectorServer/Beb.c new file mode 100644 index 000000000..f95f4b81b --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/Beb.c @@ -0,0 +1,557 @@ + +/** + * @author Ian Johnson + * @version 1.0 + */ + + +//return reversed 1 means good, 0 means failed + + + +#include +#include + + + +#include "xfs_types.h" +#include "xparameters.h" + +#include "Beb.h" + + + + struct BebInfo beb_infos[10]; + int bebInfoSize = 0; + + struct LocalLinkInterface ll_beb_local,* ll_beb; + struct LocalLinkInterface ll_beb_new_memory_local,* ll_beb_new_memory; + + struct udp_header_type udp_header; + + int Beb_send_ndata; + unsigned int Beb_send_buffer_size; + unsigned int* Beb_send_data_raw; + unsigned int* Beb_send_data; + + int Beb_recv_ndata; + unsigned int Beb_recv_buffer_size; + unsigned int* Beb_recv_data_raw; + unsigned int* Beb_recv_data; + + short Beb_bit_mode; + + +void BebInfo_BebInfo(struct BebInfo* bebInfo, unsigned int beb_num){ + bebInfo->beb_number=beb_num; + bebInfo->serial_address=0; + strcpy(bebInfo->src_mac_1GbE,""); + strcpy(bebInfo->src_mac_10GbE,""); + strcpy(bebInfo->src_ip_1GbE,""); + strcpy(bebInfo->src_ip_10GbE,""); + bebInfo->src_port_1GbE=bebInfo->src_port_10GbE=0; +} + +int BebInfo_SetSerialAddress(struct BebInfo* bebInfo, unsigned int a){ + //address pre shifted + if(a>0xff) return 0; + bebInfo->serial_address = 0x04000000 | ((a&0xff)<<16); + return 1; +} + + +int BebInfo_SetHeaderInfo(struct BebInfo* bebInfo, int ten_gig, char* src_mac, char* src_ip, unsigned int src_port){ + if(ten_gig){ strcpy(bebInfo->src_mac_10GbE,src_mac); strcpy(bebInfo->src_ip_10GbE,src_ip); bebInfo->src_port_10GbE = src_port;} + else { strcpy(bebInfo->src_mac_1GbE,src_mac); strcpy(bebInfo->src_ip_1GbE,src_ip); bebInfo->src_port_1GbE = src_port;} + return 1; +} + + + +unsigned int BebInfo_GetBebNumber(struct BebInfo* bebInfo) {return bebInfo->beb_number;} +unsigned int BebInfo_GetSerialAddress(struct BebInfo* bebInfo) {return bebInfo->serial_address;} +char* BebInfo_GetSrcMAC(struct BebInfo* bebInfo, int ten_gig) {return ten_gig ? bebInfo->src_mac_10GbE : bebInfo->src_mac_1GbE;} +char* BebInfo_GetSrcIP(struct BebInfo* bebInfo, int ten_gig) {return ten_gig ? bebInfo->src_ip_10GbE : bebInfo->src_ip_1GbE;} +unsigned int BebInfo_GetSrcPort(struct BebInfo* bebInfo, int ten_gig) {return ten_gig ? bebInfo->src_port_10GbE : bebInfo->src_port_1GbE;} + + +void BebInfo_Print(struct BebInfo* bebInfo){ + printf("\t%d) Beb Info.:\n",bebInfo->beb_number); + printf("\t\tSerial Add: 0x%x\n",bebInfo->serial_address); + printf("\t\tMAC 1GbE: %s\n",bebInfo->src_mac_1GbE); + printf("\t\tIP 1GbE: %s\n",bebInfo->src_ip_1GbE); + printf("\t\tport 1GbE: %d\n",bebInfo->src_port_1GbE); + printf("\t\tMAC 10GbE: %s\n",bebInfo->src_mac_10GbE); + printf("\t\tIP 10GbE: %s\n",bebInfo->src_ip_10GbE); + printf("\t\tport 10GbE: %d\n",bebInfo->src_port_10GbE); +} + + +void Beb_Beb(int arg1){ + + Beb_send_ndata = 0; + Beb_send_buffer_size = 1026; + Beb_send_data_raw = malloc((Beb_send_buffer_size+1) * sizeof(unsigned int)); + Beb_send_data = &Beb_send_data_raw[1]; + + Beb_recv_ndata = 0; + Beb_recv_buffer_size = 1026; + Beb_recv_data_raw = malloc((Beb_recv_buffer_size+1) * sizeof(unsigned int)); + Beb_recv_data = &Beb_recv_data_raw[1]; + + udp_header= (struct udp_header_type){ + {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(!Beb_InitBebInfos()) exit(1); + + printf("Printing Beb infos:\n"); + unsigned int i; + for(i=1;iSetSerialAddress(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 Beb_CheckSourceStuffBebInfo(); +} + + + +int Beb_SetBebSrcHeaderInfos(unsigned int beb_number, int ten_gig, char* src_mac, char* src_ip,unsigned int src_port){ + //so that the values can be reset externally for now.... + + unsigned int i = Beb_GetBebInfoIndex(beb_number); + if(!i){ printf("returning 000\n");return 0;} //i must be greater than 0, zero is the global send + BebInfo_SetHeaderInfo(&beb_infos[i],ten_gig,src_mac,src_ip,src_port); + + printf("Printing Beb info number (%d) :\n",i); + BebInfo_Print(&beb_infos[i]); + printf("\n"); + + return 1; +} + + +int Beb_ReadSetUpFromFile(char* file_name){ + char line[100]; + char str[100]; + + int i0,i1; + char mac0[50],mac1[50],ip0[50],ip1[0]; + FILE* fp = fopen(file_name, "r"); + if( fp == NULL ){ + perror("Error while opening the beb setup file.\n"); + return 0; + } + + printf("Setting up beb side of detector:\n"); + while ( fgets (line , 255 , fp) != NULL ){ + if(strlen(line)<=1) + continue; + sscanf (line, "%s", str); + if (str[0]=='#') + continue; + + if(!strcmp(str,"add_beb")){ + if( sscanf (line,"%s %d %d %s %s %s %s",str,&i0,&i1,mac0,ip0,mac1,ip1) < 7){ + printf("Error adding beb from %s.\n",file_name); + exit(0); + } + + printf ("Read: %s %d %d %s %s %s %s\n", str,i0,i1,mac0,ip0,mac1,ip1); + + if(Beb_GetBebInfoIndex(i0)){ + printf("Error adding beb from %s, beb number %d already added.\n",file_name,i0); + exit(0); + } + + struct BebInfo b0; + BebInfo_BebInfo(&b0,i0); + BebInfo_SetSerialAddress(&b0,i1); + BebInfo_SetHeaderInfo(&b0,0,mac0,ip0,42000+i0); + BebInfo_SetHeaderInfo(&b0,1,mac1,ip1,52000+i0); + beb_infos[bebInfoSize] = b0; + bebInfoSize++; + } + } + fclose(fp); + return 1; +} + + + +int Beb_CheckSourceStuffBebInfo(){ + unsigned int i; + for(i=1;i=bebInfoSize){ + printf("WriteTo index error.\n"); + return 0; + } + + Beb_send_data_raw[0] = 0x90000000 | BebInfo_GetSerialAddress(&beb_infos[index]); + if(Local_Write(ll_beb,4,Beb_send_data_raw)!=4) return 0; + + Beb_send_data_raw[0] = 0xc0000000; + if((Beb_send_ndata+1)*4!=Local_Write(ll_beb,(Beb_send_ndata+1)*4,Beb_send_data_raw)) return 0; + + return 1; +} + + +void Beb_SwapDataFun(int little_endian, unsigned int n, unsigned int *d){ + unsigned int i; + if(little_endian) for(i=0;i>8) | ((d[i]&0xff000000)>>24)); //little_endian + else for(i=0;i>16)); +} + + +int Beb_SetByteOrder(){ + Beb_send_data_raw[0] = 0x8fff0000; + if(Local_Write(ll_beb,4,Beb_send_data_raw)!=4) return 0; + + while((Local_Read(ll_beb,Beb_recv_buffer_size*4,Beb_recv_data_raw)/4)>0) printf("\t) Cleanning buffer ...\n"); + + if(bebInfoSize<2) return 0; + + Beb_send_ndata = 3; + Beb_send_data[0] = 0x000c0000; + Beb_send_data[1] = 0; + Beb_send_data[2] = 0; + Beb_WriteTo(0); + + //using little endian for data, big endian not fully tested, swap on 16 bit boundary. + Beb_send_ndata = 3; + Beb_send_data[0] = 0x000c0000; + Beb_send_data[1] = 1; + Beb_send_data[2] = 0; + Beb_SwapDataFun(0,2,&(Beb_send_data[1])); + Beb_WriteTo(0); + + printf("\tSetting Byte Order .............. ok\n"); + + return 1; +} + + + + +int Beb_SetUpUDPHeader(unsigned int beb_number, int ten_gig, unsigned int header_number, char* dst_mac, char* dst_ip, unsigned int dst_port){ + unsigned int i = Beb_GetBebInfoIndex(beb_number); + if(!i) return 0; //i must be greater than 0, zero is the global send + + Beb_send_ndata = 14; + Beb_send_data[0] = ten_gig ? 0x00020000 : 0x00010000; //write to fanout numbers 1 or 2 + Beb_send_data[1] = ((header_number*8)<<16); + if(!Beb_SetHeaderData(beb_number,ten_gig,dst_mac,dst_ip,dst_port)) return 0; + + Beb_SwapDataFun(1,12,&(Beb_send_data[2])); + + if(!Beb_WriteTo(i)) return 0; + + return 1; +} + + +int Beb_SetHeaderData(unsigned int beb_number, int ten_gig, char* dst_mac, char* dst_ip, unsigned int dst_port){ + unsigned int i = Beb_GetBebInfoIndex(beb_number); + if(!i) return 0; //i must be greater than 0, zero is the global send + return Beb_SetHeaderData1(BebInfo_GetSrcMAC(&beb_infos[i],ten_gig),BebInfo_GetSrcIP(&beb_infos[i],ten_gig),BebInfo_GetSrcPort(&beb_infos[i],ten_gig),dst_mac,dst_ip,dst_port); +} + +int Beb_SetHeaderData1(char* src_mac, char* src_ip, unsigned int src_port, char* dst_mac, char* 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(!Beb_SetMAC(src_mac,&(udp_header.src_mac[0]))) return 0; + if(!Beb_SetIP(src_ip,&(udp_header.src_ip[0]))) return 0; + if(!Beb_SetPortNumber(src_port,&(udp_header.src_port[0]))) return 0; + + if(!Beb_SetMAC(dst_mac,&(udp_header.dst_mac[0]))) return 0; + if(!Beb_SetIP(dst_ip,&(udp_header.dst_ip[0]))) return 0; + if(!Beb_SetPortNumber(dst_port,&(udp_header.dst_port[0]))) return 0; + + + Beb_AdjustIPChecksum(&udp_header); + + unsigned int* base_ptr = (unsigned int *) &udp_header; + unsigned int num_words = ( sizeof(struct udp_header_type) + 3 ) / 4; + // for(unsigned int i=0; i %s\n",macVal); + return 0; + } + + int itemp; + sscanf(pch,"%x",&itemp); + dst_ptr[i] = (u_int8_t)itemp; + pch = strtok (NULL, ":"); + i++; + } + return 1; +} + +int Beb_SetIP(char* ip, uint8_t* dst_ptr){ + char ipVal[50];strcpy(ipVal,ip); + int i = 0; + char *pch = strtok (ipVal,"."); + while (pch != NULL){ + if(((i!=3) && ((strlen(pch)>3) || (strlen(pch)<1))) || ((i==3)&&((strlen(pch)<1) || (strlen(pch) > 3)))){ + printf("Error: in ip address -> %s\n",ipVal); + return 0; + } + + int itemp; + sscanf(pch,"%d",&itemp); + dst_ptr[i] = (u_int8_t)itemp; + pch = strtok (NULL, "."); + i++; + } + return 1; +} + +int Beb_SetPortNumber(unsigned int port_number, uint8_t* dst_ptr){ + dst_ptr[0] = (port_number >> 8) & 0xff ; + dst_ptr[1] = port_number & 0xff; + return 1; +} + + +void Beb_AdjustIPChecksum(struct 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; + unsigned int i; + for(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 ; +} + + + +int Beb_SendMultiReadRequest(unsigned int beb_number, unsigned int left_right, int ten_gig, unsigned int dst_number, unsigned int npackets, unsigned int packet_size, int stop_read_when_fifo_empty){ + + unsigned int i = Beb_GetBebInfoIndex(beb_number); //zero is the global send + + Beb_send_ndata = 3; + if(left_right == 1) Beb_send_data[0] = 0x00040000; + else if(left_right == 2) Beb_send_data[0] = 0x00080000; + else if(left_right == 3) Beb_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--; + + + Beb_send_data[1] = 0x62000000 | (!stop_read_when_fifo_empty) << 27 | (ten_gig==1) << 24 | packet_size << 14 | dst_number << 8 | npackets; + Beb_send_data[2] = 0; + + Beb_SwapDataFun(0,2,&(Beb_send_data[1])); + + if(!Beb_WriteTo(i)) return 0; + + return 1; +} + + +int 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; + Beb_bit_mode = the_bit_mode; + + //nimages = the_number_of_images; + // on_dst = 0; + + return 1; +} + +int Beb_RequestNImages(unsigned int beb_number, unsigned int left_right, int ten_gig, unsigned int dst_number, unsigned int nimages, int 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 ? Beb_bit_mode*4 : Beb_bit_mode*16; + int in_two_requests = (!ten_gig&&Beb_bit_mode==32); + if(in_two_requests) npackets/=2; + + printf("here: %d %d %d %d %d %d %d\n",beb_number,left_right,ten_gig,dst_number,nimages, header_size,test_just_send_out_packets_no_wait); + //printf("here: "< +#include */ + +#include + + + +#include "xparameters.h" +#include "Feb.h" + + + +Feb_Feb(){ + + Feb_nfebs = 0; + Feb_feb_numb = 0; + + Feb_send_ndata = 0; + Feb_send_buffer_size = 1026; + Feb_send_data_raw = malloc((Feb_send_buffer_size+1)*sizeof(int)); + Feb_send_data = &Feb_send_data_raw[1]; + + Feb_recv_ndata = 0; + Feb_recv_buffer_size = 1026; + Feb_recv_data_raw = malloc((Feb_recv_buffer_size+1)*sizeof(int)); + Feb_recv_data = &Feb_recv_data_raw[1]; + + Local_LocalLinkInterface1(ll,XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR); + +} +/* +~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){ + unsigned int i; + if(Feb_feb_numb) free(Feb_feb_numb); + Feb_nfebs = n; + Feb_feb_numb = malloc(n*sizeof(unsigned int)); + for(i=0;i0xfff) return 0; + + Feb_send_data_raw[0] = 0x90000000 | (ch<<16); //we + if(Local_Write(ll,4,Feb_send_data_raw)!=4) return 0; + + Feb_send_data_raw[0] = 0xc0000000; //data + return 1;((Feb_send_ndata+1)*4==Local_Write(ll,(Feb_send_ndata+1)*4,Feb_send_data_raw)); +} + +int Feb_ReadFrom(unsigned int ch, unsigned int ntrys){ + unsigned int t; + if(ch>=0xfff) return 0; + + Feb_recv_data_raw[0] = 0xa0000000 | (ch<<16); //read data + Local_Write(ll,4,Feb_recv_data_raw); + usleep(20); + + Feb_recv_ndata=-1; + for(t=0;t0){ + Feb_recv_ndata--; + break; + } + printf("\t Read try number: %d\n",t); + usleep(1000); + } + + + return (Feb_recv_ndata>=0); +} + +void Feb_PrintData(){ + int i; + printf("Sent data: %d\n",Feb_send_ndata); + for(i=0;i1&&Feb_recv_ndata>1){ + printf("\t\t Tail sent: %d (0x%x) receiver: %d (0x%x)\n",Feb_send_data[Feb_send_ndata-1],Feb_send_data[Feb_send_ndata-1],Feb_recv_data[Feb_recv_ndata-1],Feb_recv_data[Feb_recv_ndata-1]); + }else{ + printf("Error printing tail, too little data nsent = 0x%x, nrecv = 0x%x.\n",Feb_send_ndata, Feb_recv_ndata); + } + Feb_PrintData(); + } + return header_returned_is_ok; +} + + +int Feb_CheckTail(unsigned int valid_bit_mask){ + if(Feb_send_ndata<=1&&Feb_recv_ndata<=1){ + printf("Error checking tail, too little data nsent = %d, nrecv = %d.\n",Feb_send_ndata, Feb_recv_ndata); + return 0; + } + + unsigned int the_tail = Feb_recv_data[Feb_recv_ndata-1]&valid_bit_mask; + if(the_tail!=0){ + printf("Error returned in tail: 0x%x (%d)\n",the_tail,the_tail); + if(the_tail&0x10000000) printf("\t\tBusy flag address error.\n"); + if(the_tail&0x20000000) printf("\t\tRead register address error.\n"); + if(the_tail&0x40000000) printf("\t\tWrite register address error.\n"); + if(the_tail&0x80000000) printf("\t\tBram number error.\n"); + if(the_tail&0x08000000) printf("\t\tFifo to read from error.\n"); + if(the_tail&0x3ff) printf("\t\tNumber of data send error.\n"); + return 0; //error + } + + return 1; +} + + +int Feb_CheckCommunication(){ + Feb_send_data_raw[0] = 0x8fff0000; //rst-all serial coms and lls + if(Local_Write(ll,4,Feb_send_data_raw)!=4) return 0; + + printf("CheckingCommunication ....\n"); + while((Local_Read(ll,Feb_recv_buffer_size*4,Feb_recv_data_raw)/4)>0) printf("\t) Cleanning buffer ...\n"); + + return Feb_SetByteOrder(); +} + + +int Feb_SetByteOrder(){ + + unsigned int i; + Feb_send_ndata = 2; + Feb_send_data[0] = 0; //header + Feb_send_data[1] = 0; //tail + + unsigned int dst = 0xff; + for( i=0;i=nfebs){ + cout<<"Error invalid sub number "<Feb_send_buffer_size-2) return 0; + + Feb_send_ndata = nreads+2; + Feb_send_data[0] = 0x20000000 | nreads << 14; //cmd -> read "00" , nreads + + for(i=0;iFeb_send_buffer_size-2) return 0; + + //cout<<"Write register : "< write nwrites and how many + Feb_send_data[2*nwrites+1] = 0; //tail + + for(i=0;iFeb_send_buffer_size-2) return 0; + + Feb_send_ndata = nwrites+2; + Feb_send_data[0] = 0xc0000000 | mem_num << 24 | nwrites << 14 | start_address; //cmd -> write to memory, nwrites, mem number, start address + Feb_send_data[nwrites+1] = 0; //tail + for(i=0;i +#include +#include +#include +#include + + +//#include +//#include +//#include +//#include + + + +#include "FebRegisterDefs.h" +#include "FebControl.h" +#include "Beb.h" + + + +//GetDAQStatusRegister(512,current_mode_bits_from_fpga)){ + +unsigned int Module_ndacs = 16; +char Module_dac_names[16][10]= {"SvP","Vtr","Vrf","Vrs","SvN","Vtgstv","Vcmp_ll","Vcmp_lr","cal","Vcmp_rl","rxb_rb","rxb_lb","Vcmp_rr","Vcp","Vcn","Vis"};; + + + + +struct Module modules[10]; +int moduleSize = 0; + +unsigned int Feb_Control_staticBits; //program=1,m4=2,m8=4,test=8,rotest=16,cs_bar_left=32,cs_bar_right=64 +unsigned int Feb_Control_acquireNReadoutMode; //safe or parallel, half or full speed +unsigned int Feb_Control_triggerMode; //internal timer, external start, external window, signal polarity (external trigger and enable) +unsigned int Feb_Control_externalEnableMode; //external enabling engaged and it's polarity +unsigned int Feb_Control_subFrameMode; + +unsigned int Feb_Control_photon_energy_eV; + +unsigned int Feb_Control_nimages; +double Feb_Control_exposure_time_in_sec; +double Feb_Control_exposure_period_in_sec; + +unsigned int Feb_Control_trimbit_size; +unsigned int* Feb_Control_last_downloaded_trimbits; + + + + +void Module_Module(struct Module* mod,unsigned int number, unsigned int address_top){ + unsigned int i; + mod->module_number = number; + mod->top_address_valid = 1; + mod->top_left_address = 0x100 | (0xff & address_top); + mod->top_right_address = (0x200 | (0xff & address_top)); + mod-> bottom_address_valid = 0; + mod-> bottom_left_address = 0; + mod-> bottom_right_address = 0; + + mod->high_voltage = -1; + mod->top_dac = malloc(Module_ndacs * sizeof(int)); + mod->bottom_dac = malloc(Module_ndacs * sizeof(int)); + for(i=0;itop_dac[i] = mod->top_address_valid ? -1:0; + for(i=0;ibottom_dac[i] = mod->bottom_address_valid ? -1:0; +} + +void Module_Module1(struct Module* mod,unsigned int number, unsigned int address_top, unsigned int address_bottom){ + unsigned int i; + mod->module_number = number; + mod->top_address_valid = 1; + mod->top_left_address = 0x100 | (0xff & address_top); + mod->top_right_address = 0x200 | (0xff & address_top); + mod->bottom_address_valid = 1; + mod->bottom_left_address = 0x100 | (0xff & address_bottom); + mod->bottom_right_address = 0x200 | (0xff & address_bottom); + + mod->high_voltage = -1; + + for(i=0;i<4;i++) mod->idelay_top[i]=mod->idelay_bottom[i]=0; + + mod->top_dac = malloc(Module_ndacs * sizeof(int)); + mod->bottom_dac = malloc(Module_ndacs * sizeof(int)); + for(i=0;itop_dac[i] = mod->top_address_valid ? -1:0; + for(i=0;ibottom_dac[i] = mod->bottom_address_valid ? -1:0; +} + + +unsigned int Module_GetModuleNumber(struct Module* mod) {return mod->module_number;} +int Module_TopAddressIsValid(struct Module* mod) {return mod->top_address_valid;} +unsigned int Module_GetTopBaseAddress(struct Module* mod) {return (mod->top_left_address&0xff);} +unsigned int Module_GetTopLeftAddress(struct Module* mod) {return mod->top_left_address;} +unsigned int Module_GetTopRightAddress(struct Module* mod) {return mod->top_right_address;} +unsigned int Module_GetBottomBaseAddress(struct Module* mod) {return (mod->bottom_left_address&0xff);} +int Module_BottomAddressIsValid(struct Module* mod) {return mod->bottom_address_valid;} +unsigned int Module_GetBottomLeftAddress(struct Module* mod) {return mod->bottom_left_address;} +unsigned int Module_GetBottomRightAddress(struct Module* mod) {return mod->bottom_right_address;} + +unsigned int Module_SetTopIDelay(struct Module* mod,unsigned int chip,unsigned int value) { return Module_TopAddressIsValid(mod) &&chip<4 ? (mod->idelay_top[chip]=value) : 0;} //chip 0=ll,1=lr,0=rl,1=rr +unsigned int Module_GetTopIDelay(struct Module* mod,unsigned int chip) { return chip<4 ? mod->idelay_top[chip] : 0;} //chip 0=ll,1=lr,0=rl,1=rr +unsigned int Module_SetBottomIDelay(struct Module* mod,unsigned int chip,unsigned int value) { return Module_BottomAddressIsValid(mod) &&chip<4 ? (mod->idelay_bottom[chip]=value) : 0;} //chip 0=ll,1=lr,0=rl,1=rr +unsigned int Module_GetBottomIDelay(struct Module* mod,unsigned int chip) { return chip<4 ? mod->idelay_bottom[chip] : 0;} //chip 0=ll,1=lr,0=rl,1=rr + +float Module_SetHighVoltage(struct Module* mod,float value) { return Module_TopAddressIsValid(mod) ? (mod->high_voltage=value) : -1;} +float Module_GetHighVoltage(struct Module* mod) { return mod->high_voltage;} + +int Module_SetTopDACValue(struct Module* mod,unsigned int i, int value) { return (itop_dac[i]=value) : -1;} +int Module_GetTopDACValue(struct Module* mod,unsigned int i) { return (itop_dac[i]:-1;} +int Module_SetBottomDACValue(struct Module* mod,unsigned int i, int value) { return (ibottom_dac[i]=value) : -1;} +int Module_GetBottomDACValue(struct Module* mod,unsigned int i) { return (ibottom_dac[i]:-1;} + + + + + + + + +void Feb_Control_FebControl(){ + + Feb_Control_staticBits=Feb_Control_acquireNReadoutMode=Feb_Control_triggerMode=Feb_Control_externalEnableMode=Feb_Control_subFrameMode=0; + + Feb_Control_trimbit_size=263680; + Feb_Control_last_downloaded_trimbits = malloc(Feb_Control_trimbit_size * sizeof(int)); + + printf("\nDefault Settings:\n"); + Feb_Control_nimages = 1; + Feb_Control_exposure_time_in_sec = 1; + Feb_Control_exposure_period_in_sec = 0; + Feb_Control_SetTestModeVariable(0); + //SetPhotonEnergyCalibrationParameters(-5.8381e-5,1.838515,5.09948e-7,-4.32390e-11,1.32527e-15); + //SetRateCorrection(0); //deactivate rate correction + Feb_Control_SetDynamicRange(16); + Feb_Control_SetPhotonEnergy(8000); + Feb_Control_SetReadoutMode(0); + Feb_Control_SetReadoutSpeed(0); + Feb_Control_SetTriggerMode(0,1); + Feb_Control_SetExternalEnableMode(0,1); + printf("\n\n"); + + Feb_Control_Init(); +} + + + +void Feb_Control_ClearModules(){ + unsigned int i; + //for(i=0;i0) + sprintf(str,"mod%d::%s",module_num,str); + if(!Feb_Control_SetDAC(str,f0,1)) + printf("error in string: %s",str); + + } + } + fclose(fp); + + return 1; +} + + +int Feb_Control_CheckSetup(){ + unsigned int i,j; + int ok = 1; + + for(i=0;i3){ + printf("Error SetIDelay chip_pos %d doesn't exist.\n",chip_pos);; + return 0; + } + + unsigned int module_index=0; + if(!Feb_Control_GetModuleIndex(module_num,&module_index)){ + printf("Error could not set i delay module number %d invalid.\n",module_num); + return 0; + } + + int ok = 1; + if(chip_pos/2==0){ //left fpga + if(Module_TopAddressIsValid(&modules[module_index])){ + if(Feb_Control_SendIDelays(Module_GetTopLeftAddress(&modules[module_index]),chip_pos%2==0,0xffffffff,ndelay_units)){ + if(module_index!=0) Module_SetTopIDelay(&modules[module_index],chip_pos,ndelay_units); + else{ + for(i=0;i0x3ff) ndelay_units=0x3ff; + // this is global + unsigned int delay_data_valid_nclks = 15 - ((ndelay_units&0x3c0)>>6); //data valid delay upto 15 clks + ndelay_units &= 0x3f; + + unsigned int set_left_delay_channels = chip_lr ? channels:0; + unsigned int set_right_delay_channels = chip_lr ? 0:channels; + + printf("\tSetting delays of "); + if(set_left_delay_channels!=0) printf("left chips of dst_num %d",dst_num); + else if(set_right_delay_channels!=0) printf("right chips of dst_num %d",dst_num); + + printf(", tracks 0x%x to: %d, %d clks and %d units.\n",channels,(((15-delay_data_valid_nclks)<<6)|ndelay_units),delay_data_valid_nclks,ndelay_units); + + if(!Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG2, 1<<31 | delay_data_valid_nclks<<16 | ndelay_units,0,0) || //the 1<<31 time enables the setting of the data valid delays + !Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG3,set_left_delay_channels,0,0) || + !Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG4,set_right_delay_channels,0,0) || + !Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG_CTRL,CHIP_DATA_OUT_DELAY_SET,1,1)){ + printf("Warning: could not SetChipDataInputDelays(...).\n"); + return 0; + } + + return 1; +} + + +int Feb_Control_VoltageToDAC(float value, unsigned int* digital,unsigned int nsteps,float vmin,float vmax){ + if(valuevmax) return 0; + *digital = (int)(((value-vmin)/(vmax-vmin))*(nsteps-1) + 0.5); + return 1; +} + +float Feb_Control_DACToVoltage(unsigned int digital,unsigned int nsteps,float vmin,float vmax){ + return vmin+(vmax-vmin)*digital/(nsteps-1); +} + + +int Feb_Control_SetHighVoltage(float value){ + return Feb_Control_SetHighVoltage1(0,value); +} + +int Feb_Control_SetHighVoltage1(unsigned int module_num,float value){ + unsigned int module_index=0; + unsigned int i; + if(!Feb_Control_GetModuleIndex(module_num,&module_index)||!Module_TopAddressIsValid(&modules[module_index])){ + printf("Error could not set high voltage module number %d invalid.\n",module_num); + return 0; + } + + if(!Feb_Control_SendHighVoltage(Module_GetTopRightAddress(&modules[module_index]),&value)) return 0; + + if(module_index!=0) Module_SetHighVoltage(&modules[module_index],value); + else for(i=0;i4095){ + printf("Waring: SetDac bad value, %d. The range is 0 to 4095.\n",v); + return 0; + } + + if(top&&Module_TopAddressIsValid(&modules[module_index])){ + + if(!Feb_Control_SendDACValue(Module_GetTopRightAddress(&modules[module_index]),dac_ch,&v)) return 0; + + + if(module_index!=0) Module_SetTopDACValue(&modules[module_index],dac_ch,v); + else for(i=0;i=Module_ndacs){ + printf("Warning: GetDACName index out of range, %d invalid.\n",dac_num); + return 0; + } + strcpy(s,Module_dac_names[dac_num]); + return 1; +} + +int Feb_Control_GetDACNumber(char* s, unsigned int* n){ + unsigned int i; + for(i=0;i15){ + printf("Warning invalid ch for SetDAC.\n"); + return 0; + } + + //if(voltage<0) return PowerDownDAC(socket_num,ch); + + *value&=0xfff; + unsigned int dac_ic = (ch<8) ? 1:2; + unsigned int dac_ch = ch%8; + unsigned int r = dac_ic<<30 | 3<<16 | dac_ch<<12 | *value; //3 write and power up + + + if(!Feb_Interface_WriteRegister(dst_num,0,r,1,0)){ + printf("Warning: trouble setting dac %d voltage.\n",ch); + return 0; + } + + float voltage=Feb_Control_DACToVoltage(*value,4096,0,2048); + + printf("\tDac number %d (%s) of dst %d set to %d (%f mV).\n",ch,Module_dac_names[ch],dst_num,*value,voltage); + return 1; +} + +/* +float GetDAC(string s){ + static unsigned int n; + if(!GetDACNumber(s,n)) return 0; + + return dac[n]; +} +*/ + +int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits){ + printf("Setting Trimbits\n"); + + //for (int iy=10000;iy<20020;++iy)//263681 + //for (int iy=263670;iy<263680;++iy)//263681 + // printf("%d:%c\t\t",iy,trimbits[iy]); + + + + unsigned int module_index=0; + if(!Feb_Control_GetModuleIndex(module_num,&module_index)){ + printf("Warning could not set trimbits, bad module number.\n"); + return 0; + } + + if(!Feb_Control_Reset()) printf("Warning could not reset DAQ.\n"); + int l_r; + for(l_r=0;l_r<2;l_r++){ // l_r loop + unsigned int disable_chip_mask = l_r ? DAQ_CS_BAR_LEFT : DAQ_CS_BAR_RIGHT; + if(!(Feb_Interface_WriteRegister(0xfff,DAQ_REG_STATIC_BITS,disable_chip_mask|DAQ_STATIC_BIT_PROGRAM|DAQ_STATIC_BIT_M8,0,0)&&Feb_Control_SetCommandRegister(DAQ_SET_STATIC_BIT)&&Feb_Control_StartDAQOnlyNWaitForFinish(5000))){ + printf("Could not select chips\n"); + return 0; + } + int row_set; + for(row_set=0;row_set<16;row_set++){ //16 rows at a time + if(row_set==0){ + if(!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY|DAQ_SEND_A_TOKEN_IN|DAQ_LOAD_16ROWS_OF_TRIMBITS)){ + printf("Warning: Could not Feb_Control_SetCommandRegister for loading trim bits.\n"); + return 0; + } + }else{ + if(!Feb_Control_SetCommandRegister(DAQ_LOAD_16ROWS_OF_TRIMBITS)){ + printf("Warning: Could not Feb_Control_SetCommandRegister for loading trim bits.\n"); + return 0; + } + } + + static unsigned int trimbits_to_load_l[1024]; + static unsigned int trimbits_to_load_r[1024]; + int row; + for(row=0;row<16;row++){ //row loop + int offset = 2*32*row; + int sc; + for(sc=0;sc<32;sc++){ //supercolumn loop sc + + int super_column_start_position_l = 1030*row + l_r *258 + sc*8; + int super_column_start_position_r = 1030*row + 516 + l_r *258 + sc*8; + + /* + int super_column_start_position_l = 1024*row + l_r *256 + sc*8; //256 per row, 8 per super column + int super_column_start_position_r = 1024*row + 512 + l_r *256 + sc*8; //256 per row, 8 per super column +*/ + int chip_sc = 31 - sc; + trimbits_to_load_l[offset+chip_sc] = 0; + trimbits_to_load_r[offset+chip_sc] = 0; + int i; + for(i=0;i<8;i++){ // column loop i + + trimbits_to_load_l[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_l+i])<<((7-i)*4);//low + trimbits_to_load_l[offset+chip_sc+32] |= ((0x38 & trimbits[row_set*16480+super_column_start_position_l+i])>>3)<<((7-i)*4);//upper + trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_r+i])<<((7-i)*4);//low + trimbits_to_load_r[offset+chip_sc+32] |= ((0x38 & trimbits[row_set*16480+super_column_start_position_r+i])>>3)<<((7-i)*4);//upper +/* + 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]->Module_GetTopLeftAddress(),0,0,1024,trimbits_to_load_r)||!WriteMemory(modules[0]->Module_GetTopRightAddress(),0,0,1024,trimbits_to_load_l)||!Feb_Control_StartDAQOnlyNWaitForFinish()){ + cout <<" some errror!"<< endl; + return 0; + } +*/ + if(!Feb_Interface_WriteMemory(Module_GetTopLeftAddress(&modules[0]),0,0,1023,trimbits_to_load_r)||!Feb_Interface_WriteMemory(Module_GetTopRightAddress(&modules[0]),0,0,1023,trimbits_to_load_l)||!Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ + printf(" some errror!\n"); + return 0; + } + + } //end row_set loop (groups of 16 rows) + } // end l_r loop + memcpy(Feb_Control_last_downloaded_trimbits,trimbits,Feb_Control_trimbit_size*sizeof(unsigned char)); + return Feb_Control_SetStaticBits(); //send the static bits +} + + +unsigned int* Feb_Control_GetTrimbits(){ + return Feb_Control_last_downloaded_trimbits; +} + + + + +unsigned int Feb_Control_AddressToAll(){ + if(moduleSize==0) return 0; + return Module_GetTopLeftAddress(&modules[0])|Module_GetTopRightAddress(&modules[0]); +} + +int Feb_Control_SetCommandRegister(unsigned int cmd){ + return Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CHIP_CMDS,cmd,0,0); +} + + +int Feb_Control_GetDAQStatusRegister(unsigned int dst_address, unsigned int* ret_status){ + if(!Feb_Interface_ReadRegister(dst_address,DAQ_REG_STATUS,ret_status)){ + printf("Error: reading status register.\n"); + return 0; + } + + *ret_status = (0x00FF0000 & *ret_status) >> 16; + return 1; +} + + +int Feb_Control_StartDAQOnlyNWaitForFinish(int sleep_time_us){ + if(!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0)||!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_START,0,0)){ + printf("Warning: could not start.\n"); + return 0; + } + + return Feb_Control_WaitForFinishedFlag(sleep_time_us); +} + +int Feb_Control_WaitForFinishedFlag(int sleep_time_us){ + int is_running = Feb_Control_AcquisitionInProgress(); + while(is_running){ + usleep(sleep_time_us); + is_running = Feb_Control_AcquisitionInProgress(); + } + if(is_running!=0){ + printf("\n\nWarning WaitForFinishedFlag comunication problem..\n\n"); + return 0; //communication problem + } + + return 1; +} + +int Feb_Control_AcquisitionInProgress(){ + unsigned int status_reg_r=0; + + if(!(Feb_Control_GetDAQStatusRegister(Module_GetTopRightAddress(&modules[1]),&status_reg_r))) + return 0; + if(status_reg_r&DAQ_STATUS_DAQ_RUNNING) return 1; + + /* + if(!(GetDAQStatusRegister(modules[i]->Module_GetTopLeftAddress(),status_reg_r)&&GetDAQStatusRegister(modules[i]->Module_GetTopRightAddress(),status_reg_l))){ + for(int i=0;i<2;i++) printf("Waring trouble reading status register. Returning zero to avoid inifite loops, this could cause trouble!"\n");; + return 0; //to avoid inifite loops + } + if((status_reg_r|status_reg_l)&DAQ_STATUS_DAQ_RUNNING) return 1; + } + */ + + return 0; //i.e. not running (status_reg_r|status_reg_l)&DAQ_STATUS_DAQ_RUNNING; +} + +int Feb_Control_Reset(){ + if(!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_RESET,0,0) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0)){ + printf("Warning: Could not reset daq, no response.\n"); + return 0; + } + + return Feb_Control_WaitForFinishedFlag(5000); +} + + + + +int Feb_Control_SetStaticBits(){ + //program=1,m4=2,m8=4,test=8,rotest=16,cs_bar_left=32,cs_bar_right=64 + if(!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_STATIC_BITS,Feb_Control_staticBits,0,0) || !Feb_Control_SetCommandRegister(DAQ_SET_STATIC_BIT) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ + printf("Warning: Could not set static bits\n"); + return 0; + } + + return 1; +} +int Feb_Control_SetStaticBits1(unsigned int the_static_bits){ + Feb_Control_staticBits = the_static_bits; + return Feb_Control_SetStaticBits(); +} + +int Feb_Control_SetTestModeVariable(int on){ + if(on) Feb_Control_staticBits |= DAQ_STATIC_BIT_CHIP_TEST; //setting test bit to high + else Feb_Control_staticBits &= (~DAQ_STATIC_BIT_CHIP_TEST); //setting test bit to low + return 1; +} + +int Feb_Control_GetTestModeVariable(){ + return Feb_Control_staticBits&DAQ_STATIC_BIT_CHIP_TEST; +} + +int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo){ + static unsigned int everything_but_bit_mode = DAQ_STATIC_BIT_PROGRAM|DAQ_STATIC_BIT_CHIP_TEST|DAQ_STATIC_BIT_ROTEST; + if(four_eight_sixteen_or_thirtytwo==4){ + Feb_Control_staticBits = DAQ_STATIC_BIT_M4 | (Feb_Control_staticBits&everything_but_bit_mode); //leave test bits in currernt state + Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; + }else if(four_eight_sixteen_or_thirtytwo==8){ + Feb_Control_staticBits = DAQ_STATIC_BIT_M8 | (Feb_Control_staticBits&everything_but_bit_mode); + Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; + }else if(four_eight_sixteen_or_thirtytwo==16){ + Feb_Control_staticBits = DAQ_STATIC_BIT_M12 | (Feb_Control_staticBits&everything_but_bit_mode); + Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; + }else if(four_eight_sixteen_or_thirtytwo==32){ + Feb_Control_staticBits = DAQ_STATIC_BIT_M12 | (Feb_Control_staticBits&everything_but_bit_mode); + Feb_Control_subFrameMode |= DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; + }else{ + printf("Warning: dynamic range (%d) not valid, not setting bit mode.\n",four_eight_sixteen_or_thirtytwo); + printf("Set dynamic range int must equal 4,8 16, or 32.\n"); + return 0; + } + + printf("Dynamic range set to: %d\n",four_eight_sixteen_or_thirtytwo); + return 1; +} + +unsigned int Feb_Control_GetDynamicRange(){ + if(Feb_Control_subFrameMode&DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING) return 32; + else if(DAQ_STATIC_BIT_M4&Feb_Control_staticBits) return 4; + else if(DAQ_STATIC_BIT_M8&Feb_Control_staticBits) return 8; + + return 16; +} + +int Feb_Control_SetReadoutSpeed(unsigned int readout_speed){ //0->full,1->half,2->quarter or 3->super_slow + Feb_Control_acquireNReadoutMode &= (~DAQ_CHIP_CONTROLLER_SUPER_SLOW_SPEED); + if(readout_speed==1){ + Feb_Control_acquireNReadoutMode |= DAQ_CHIP_CONTROLLER_HALF_SPEED; + printf("Everything at half speed, ie. reading with 50 MHz main clk (half speed) ....\n"); + }else if(readout_speed==2){ + Feb_Control_acquireNReadoutMode |= DAQ_CHIP_CONTROLLER_QUARTER_SPEED; + printf("Everything at quarter speed, ie. reading with 25 MHz main clk (quarter speed) ....\n"); + }else if(readout_speed==3){ + Feb_Control_acquireNReadoutMode |= DAQ_CHIP_CONTROLLER_SUPER_SLOW_SPEED; + printf("Everything at super slow speed, ie. reading with ~0.200 MHz main clk (super slow speed) ....\n"); + }else{ + if(readout_speed){ + printf("Warning readout speed %d unknown, defaulting to full speed.\n",readout_speed); + printf("Everything at full speed, ie. reading with 100 MHz main clk (full speed) ....\n"); + return 0; + } + printf("Everything at full speed, ie. reading with 100 MHz main clk (full speed) ....\n"); + } + + return 1; +} + +int Feb_Control_SetReadoutMode(unsigned int readout_mode){ //0->parallel,1->non-parallel,2-> safe_mode + Feb_Control_acquireNReadoutMode &= (~DAQ_NEXPOSURERS_PARALLEL_MODE); + if(readout_mode==1){ + Feb_Control_acquireNReadoutMode |= DAQ_NEXPOSURERS_NORMAL_NONPARALLEL_MODE; + printf("Readout mode set to normal non-parallel readout mode ... \n");; + }else if(readout_mode==2){ + Feb_Control_acquireNReadoutMode |= DAQ_NEXPOSURERS_SAFEST_MODE_ROW_CLK_BEFORE_MODE; + printf("Readout mode set to safest mode, row clk before main clk readout sequence .... \n");; + }else{ + Feb_Control_acquireNReadoutMode |= DAQ_NEXPOSURERS_PARALLEL_MODE; + if(readout_mode){ + printf("Warning readout mode %d) unknown, defaulting to full speed.\n",readout_mode); + printf("Readout mode set to parrallel acquire/read mode .... \n");; + return 0; + } + printf("Readout mode set to parrallel acquire/read mode .... \n");; + } + + return 1; +} + +int Feb_Control_SetTriggerMode(unsigned int trigger_mode,int polarity){ + //"00"-> internal exposure time and period, + //"01"-> external acquistion start and internal exposure time and period, + //"10"-> external start trigger and internal exposure time, + //"11"-> external triggered start and stop of exposures + Feb_Control_triggerMode = (~DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START_AND_STOP); + + if(trigger_mode == 1){ + Feb_Control_triggerMode = DAQ_NEXPOSURERS_EXTERNAL_ACQUISITION_START; + printf("Trigger mode: external start of acquisition sequence, internal exposure length and period.\n");; + }else if(trigger_mode == 2){ + Feb_Control_triggerMode = DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START; + printf("Trigger mode: external image start, internal exposure time.\n");; + }else if(trigger_mode == 3){ + Feb_Control_triggerMode = DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START_AND_STOP; + printf("Trigger mode: externally controlled, external image window (start and stop).\n");; + }else{ + Feb_Control_triggerMode = DAQ_NEXPOSURERS_INTERNAL_ACQUISITION; + if(trigger_mode) printf("Warning trigger %d) unknown, defaulting to internal triggering.\n",trigger_mode);; + + printf("Trigger mode: acquisition internally controlled exposure length and period.\n");; + return trigger_mode==0; + } + + if(polarity){ + Feb_Control_triggerMode |= DAQ_NEXPOSURERS_EXTERNAL_TRIGGER_POLARITY; + printf("External trigger polarity set to positive.\n");; + }else{ + Feb_Control_triggerMode &= (~DAQ_NEXPOSURERS_EXTERNAL_TRIGGER_POLARITY); + printf("External trigger polarity set to negitive.\n");; + } + + return 1; +} + + +int Feb_Control_SetExternalEnableMode(int use_external_enable, int polarity){ + if(use_external_enable){ + Feb_Control_externalEnableMode |= DAQ_NEXPOSURERS_EXTERNAL_ENABLING; + printf("External enabling enabled, "); + if(polarity){ + Feb_Control_externalEnableMode |= DAQ_NEXPOSURERS_EXTERNAL_ENABLING_POLARITY; + printf(", polarity set to positive.\n");; + }else{ + Feb_Control_externalEnableMode &= (~DAQ_NEXPOSURERS_EXTERNAL_ENABLING_POLARITY); + printf(", polarity set to negative.\n");; + } + }else{ + Feb_Control_externalEnableMode &= (~DAQ_NEXPOSURERS_EXTERNAL_ENABLING); + printf("External enabling disabled.\n");; + } + + return 1; +} + +int Feb_Control_SetNExposures(unsigned int n_images){ + if(!Feb_Control_nimages){ + printf("Warning nimages must be greater than zero.%d\n",Feb_Control_nimages); + return 0; + } + + Feb_Control_nimages = n_images; + printf("Number of images set to: %d\n",Feb_Control_nimages); + return 1; +} +unsigned int Feb_Control_GetNExposures(){return Feb_Control_nimages;} + +int Feb_Control_SetExposureTime(double the_exposure_time_in_sec){ + Feb_Control_exposure_time_in_sec = the_exposure_time_in_sec; + printf("Exposure time set to: %f\n",Feb_Control_exposure_time_in_sec); + return 1; +} +double Feb_Control_GetExposureTime(){return Feb_Control_exposure_time_in_sec;} + +int Feb_Control_SetExposurePeriod(double the_exposure_period_in_sec){ + Feb_Control_exposure_period_in_sec = the_exposure_period_in_sec; + printf("Exposure period set to: %f\n",Feb_Control_exposure_period_in_sec); + return 1; +} +double Feb_Control_GetExposurePeriod(){return Feb_Control_exposure_period_in_sec;} + +unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec){ + float n_clk_cycles = round(time_in_sec/10e-9); //200 MHz ctb clk or 100 MHz feb clk + + unsigned int decoded_time; + if(n_clk_cycles>(pow(2,29)-1)*pow(10,7)){ + float max_time = 10e-9*(pow(2,28)-1)*pow(10,7); + printf("Warning: time exceeds (%f) maximum exposure time of %f sec.\n",time_in_sec,max_time); + printf("\t Setting to maximum %f us.\n",max_time); + decoded_time = 0xffffffff; + }else{ + int power_of_ten = 0; + while(n_clk_cycles>pow(2,29)-1){ power_of_ten++; n_clk_cycles = round(n_clk_cycles/10.0);} + decoded_time = (int)(n_clk_cycles)<<3 | (int)(power_of_ten); + } + + return decoded_time; +} + +int Feb_Control_ResetChipCompletely(){ + if(!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ + printf("Warning: could not ResetChipCompletely().\n");; + return 0; + } + + return 1; +} + + +void Feb_Control_PrintAcquisitionSetup(){ + + time_t rawtime; + time(&rawtime); + struct tm *timeinfo = localtime(&rawtime); + + printf("\nStarting an exposure: %s",asctime(timeinfo)); + printf("\t Dynamic range nbits: %d\n",Feb_Control_GetDynamicRange()); + printf("\t Trigger mode: 0x%x\n",Feb_Control_triggerMode); + printf("\t Number of exposures: %d\n",Feb_Control_GetNExposures()); + printf("\t Exsposure time (if used): %f seconds.\n",Feb_Control_exposure_time_in_sec); + printf("\t Exsposure period (if used): %f seconds.\n\n\n",Feb_Control_exposure_period_in_sec); +} + +int Feb_Control_SendBitModeToBebServer(){ +/* + static int first_pass = 1; + static char buffer[1024]; + + if(first_pass&&!Feb_Control_SetupSendToSocket("localhost",43212)) return 0; + else first_pass=0; +*/ + unsigned int just_bit_mode = (DAQ_STATIC_BIT_M4|DAQ_STATIC_BIT_M8) & Feb_Control_staticBits; + unsigned int bit_mode = 16; //default + if(just_bit_mode == DAQ_STATIC_BIT_M4) bit_mode = 4; + else if(just_bit_mode == DAQ_STATIC_BIT_M8) bit_mode = 8; + else if(Feb_Control_subFrameMode&DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING) bit_mode = 32; + + + if(!Beb_SetUpTransferParameters(bit_mode)){ + printf("Error: sending bit mode ...\n"); + return 0; + } + + /* + bzero(buffer,1024); + sprintf(buffer,"setbitmode %d",bit_mode); + + if(Feb_Control_WriteNRead(buffer,strlen(buffer),1024)<1||strncmp(buffer,"0",1)){ + printf("Error: sending bit mode ...\n"); + return 0; + } +*/ + return 1; +} + +/* +int Feb_Control_SetupSendToSocket(const char* ip_address_hostname, unsigned short int port){ + + struct hostent *server; + if((server = gethostbyname(ip_address_hostname)) == NULL){ //or look into getaddrinfo(3) + fprintf(stderr,"ERROR, no such host\n"); + return 0; + } + + //struct sockaddr_in serv_addr; + bzero((char *) &Feb_Control_serv_addr, sizeof(Feb_Control_serv_addr)); + Feb_Control_serv_addr.sin_family = AF_INET; + bcopy((char *)server->h_addr,(char *)&Feb_Control_serv_addr.sin_addr.s_addr,server->h_length); + Feb_Control_serv_addr.sin_port = htons(port); + + return 1; +} + +int Feb_Control_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 *) &Feb_Control_serv_addr,sizeof(Feb_Control_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; +} +*/ + +int Feb_Control_StartAcquisition(){ + + static unsigned int reg_nums[20]; + static unsigned int reg_vals[20]; + + Feb_Control_PrintAcquisitionSetup(); + + // if(!Reset()||!ResetDataStream()){ + if(!Feb_Control_Reset()){ + printf("Trouble reseting daq or data stream...\n");; + return 0; + } + + if(!Feb_Control_SetStaticBits(Feb_Control_staticBits&(DAQ_STATIC_BIT_M4|DAQ_STATIC_BIT_M8))){ + printf("Trouble setting static bits ...\n");; + return 0; + } + + if(!Feb_Control_SendBitModeToBebServer()){ + printf("Trouble sending static bits to server ...\n");; + return 0; + } + + if(!Feb_Control_ResetChipCompletely()){ + printf("Trouble resetting chips ...\n");; + return 0; + } + + reg_nums[0]=DAQ_REG_CTRL; + reg_vals[0]=0; + reg_nums[1]=DAQ_REG_NEXPOSURES; + reg_vals[1]=Feb_Control_nimages; + reg_nums[2]=DAQ_REG_EXPOSURE_TIMER; + reg_vals[2]=Feb_Control_ConvertTimeToRegister(Feb_Control_exposure_time_in_sec); + reg_nums[3]=DAQ_REG_EXPOSURE_REPEAT_TIMER; + reg_vals[3]=Feb_Control_ConvertTimeToRegister(Feb_Control_exposure_period_in_sec); + reg_nums[4]=DAQ_REG_CHIP_CMDS; + reg_vals[4]=(Feb_Control_acquireNReadoutMode|Feb_Control_triggerMode|Feb_Control_externalEnableMode|Feb_Control_subFrameMode); + int i; + for(i=5;i<19;i++){ + reg_nums[i]=DAQ_REG_CTRL; + reg_vals[i]=0; + } + reg_nums[19]=DAQ_REG_CTRL; + reg_vals[19]=ACQ_CTRL_START; + + if(!Feb_Interface_WriteRegisters(Feb_Control_AddressToAll(),20,reg_nums,reg_vals,0,0)){ + printf("Trouble starting acquisition....\n");; + return 0; + } + + return 1; +} + +int Feb_Control_StopAcquisition(){ + return Feb_Control_Reset(); +} + + + + +int Feb_Control_LoadTrimbitFile(){/* + string filename = "/home/root/noise.snbeb040"; + ifstream input_file; + + int Module_ndacs =16; + int dacs[Module_ndacs]; + unsigned int chanregs[trimbit_size]; + + + input_file.open(filename.c_str() ,ifstream::binary); + if(!input_file.is_open()){ + printf("Warning, could not open trimbit file: %s\n",filename); + exit(-1); + } + + //dacs + int i; + for(i=0;i +//#include +//#include +//#include +//#include +//#include + +#include +#include + +#include "xparameters.h" + +#include "FebInterface.h" + + + + struct LocalLinkInterface ll_local,* ll; + + unsigned int Feb_Interface_nfebs; + unsigned int* Feb_Interface_feb_numb; + + int Feb_Interface_send_ndata; + unsigned int Feb_Interface_send_buffer_size; + unsigned int* Feb_Interface_send_data_raw; + unsigned int* Feb_Interface_send_data; + + int Feb_Interface_recv_ndata; + unsigned int Feb_Interface_recv_buffer_size; + unsigned int* Feb_Interface_recv_data_raw; + unsigned int* Feb_Interface_recv_data; + + +void Feb_Interface_FebInterface(){ + ll = &ll_local; + Feb_Interface_nfebs = 0; + Feb_Interface_feb_numb = 0; + + Feb_Interface_send_ndata = 0; + Feb_Interface_send_buffer_size = 1026; + Feb_Interface_send_data_raw = malloc((Feb_Interface_send_buffer_size+1) * sizeof(unsigned int)); + Feb_Interface_send_data = &Feb_Interface_send_data_raw[1]; + + Feb_Interface_recv_ndata = 0; + Feb_Interface_recv_buffer_size = 1026; + Feb_Interface_recv_data_raw = malloc((Feb_Interface_recv_buffer_size+1) * sizeof(unsigned int)); + Feb_Interface_recv_data = &Feb_Interface_recv_data_raw[1]; + + Local_LocalLinkInterface1(ll,XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR); + +} + + + +void Feb_Interface_SendCompleteList(unsigned int n,unsigned int* list){ + unsigned int i; + if(Feb_Interface_feb_numb) free(Feb_Interface_feb_numb); + Feb_Interface_nfebs = n; + Feb_Interface_feb_numb = malloc(n * sizeof(unsigned int)); + for(i=0;i0xfff) return 0; + + Feb_Interface_send_data_raw[0] = 0x8fff0000; + if(Local_Write(ll,4,Feb_Interface_send_data_raw)!=4) return 0; + + Feb_Interface_send_data_raw[0] = 0x90000000 | (ch<<16); + if(Local_Write(ll,4,Feb_Interface_send_data_raw)!=4) return 0; + + Feb_Interface_send_data_raw[0] = 0xc0000000; + return ((Feb_Interface_send_ndata+1)*4==Local_Write(ll,(Feb_Interface_send_ndata+1)*4,Feb_Interface_send_data_raw)); +} + +int Feb_Interface_ReadFrom(unsigned int ch, unsigned int ntrys){ + unsigned int t; + if(ch>=0xfff) return 0; + + Feb_Interface_recv_data_raw[0] = 0xa0000000 | (ch<<16); + Local_Write(ll,4,Feb_Interface_recv_data_raw); + usleep(20); + + Feb_Interface_recv_ndata=-1; + for(t=0;t0){ + Feb_Interface_recv_ndata--; + break; + } + usleep(1000); + } + + return (Feb_Interface_recv_ndata>=0); +} + + + +int Feb_Interface_SetByteOrder(){ + Feb_Interface_send_data_raw[0] = 0x8fff0000; + if(Local_Write(ll,4,Feb_Interface_send_data_raw)!=4) return 0; + Feb_Interface_send_ndata = 2; + Feb_Interface_send_data[0] = 0; + Feb_Interface_send_data[1] = 0; + unsigned int i; + unsigned int dst = 0xff; + for(i=0;iFeb_Interface_send_buffer_size-2) return 0; + + Feb_Interface_send_ndata = nreads+2; + Feb_Interface_send_data[0] = 0x20000000 | nreads << 14; + + for(i=0;iFeb_Interface_send_buffer_size-2) return 0; + + //cout<<"Write register : "<Feb_Interface_send_buffer_size-2) {printf("error herer: nwrites:%d\n",nwrites);return 0;}//*d-1026 + + Feb_Interface_send_ndata = nwrites+2;//*d-1025 + Feb_Interface_send_data[0] = 0xc0000000 | mem_num << 24 | nwrites << 14 | start_address; //cmd -> write to memory, nwrites, mem number, start address + Feb_Interface_send_data[nwrites+1] = 0; + for(i=0;i +//#include +//#include +//#include +//#include + +#include "HardwareIO.h" + +xfs_u8 HWIO_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 HWIO_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 HWIO_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 HWIO_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 HWIO_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 HWIO_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.c b/slsDetectorSoftware/eigerDetectorServer/LocalLinkInterface.c new file mode 100644 index 000000000..e36293b93 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/LocalLinkInterface.c @@ -0,0 +1,280 @@ + +//Class initially from Gerd and was called mmap_test.c +//return reversed 1 means good, 0 means failed + + +#include +#include +//#include +#include +#include + + +#include "HardwareMMappingDefs.h" + +#include "LocalLinkInterface.h" + + + +Local_LocalLinkInterface1(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr){ + // printf("\n v 1 \n"); + printf("Initialize PLB LL FIFOs\n"); + ll->ll_fifo_base=0; + ll->ll_fifo_ctrl_reg=0; + if(Local_Init(ll,ll_fifo_badr)){ + Local_Reset(ll); + printf("\tFIFO Status : 0x%08x\n",Local_StatusVector(ll)); + }else printf("\tError LocalLink Mappping : 0x%08x\n",ll_fifo_badr); + + printf("\n\n"); +} + +/*~LocalLinkInterface(){};*/ + +Local_LocalLinkInterface(struct LocalLinkInterface* ll){ + printf("Initialize new memory\n"); + } + +int Local_InitNewMemory (struct LocalLinkInterface* ll,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; +} + + + +int Local_Init(struct LocalLinkInterface* ll,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->ll_fifo_base = (xfs_u32) plb_ll_fifo_ptr; + ll->ll_fifo_ctrl_reg = 0; + + return 1; +} + + + +int Local_Reset(struct LocalLinkInterface* ll){ + return Local_Reset1(ll,PLB_LL_FIFO_CTRL_RESET_STD); +} + +int Local_Reset1(struct LocalLinkInterface* ll,unsigned int rst_mask){ + ll->ll_fifo_ctrl_reg |= rst_mask; + printf("\tCTRL Register bits: 0x%08x\n",ll->ll_fifo_ctrl_reg); + + HWIO_xfs_out32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll->ll_fifo_ctrl_reg); + HWIO_xfs_out32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll->ll_fifo_ctrl_reg); + HWIO_xfs_out32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll->ll_fifo_ctrl_reg); + HWIO_xfs_out32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll->ll_fifo_ctrl_reg); + + ll->ll_fifo_ctrl_reg &= (~rst_mask); + + HWIO_xfs_out32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll->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 Local_StatusVector(struct LocalLinkInterface* ll){ + return HWIO_xfs_in32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_STATUS); +} + +int Local_Write(struct LocalLinkInterface* ll,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 = HWIO_xfs_in32(ll->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; ((ill_fifo_base+4*PLB_LL_FIFO_REG_FIFO,word_ptr[words_send++]); + } + } + return buffer_len; +} + + +int Local_Read(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer){ + static unsigned int buffer_ptr = 0; + // note: buffer must be word (4 byte) aligned + // frame_len in byte + int len; + unsigned int *word_ptr; + unsigned int status; + volatile unsigned int fifo_val; + int sof = 0; + + word_ptr = (unsigned int *)buffer; + do + { + status = HWIO_xfs_in32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_STATUS); + + if (!(status & PLB_LL_FIFO_STATUS_EMPTY)) + { + if (status & PLB_LL_FIFO_STATUS_LL_SOF) + { + if (buffer_ptr) + { + buffer_ptr = 0; + return -1; // buffer overflow + } +// printf(">>>> SOF\n\r"); + buffer_ptr = 0; + sof = 1; + } + + fifo_val = HWIO_xfs_in32(ll->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; +} + +int Local_ctrl_reg_write_mask(struct LocalLinkInterface* ll,unsigned int mask, unsigned int val){ + // printf("Fifo CTRL Reg(1): 0x%08x\n",plb_ll_fifo_ctrl_reg); + ll->ll_fifo_ctrl_reg &= (~mask); + //printf("Fifo CTRL Reg(2): 0x%08x\n",plb_ll_fifo_ctrl_reg); + ll->ll_fifo_ctrl_reg |= ( mask & val); +// printf("Fifo CTRL Reg: 0x%08x\n",plb_ll_fifo_ctrl_reg); + HWIO_xfs_out32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll->ll_fifo_ctrl_reg); +// printf("Fifo STAT Reg: 0x%08x\n", plb_ll_fifo[PLB_LL_FIFO_REG_STATUS]); + return 1; +} + + +int Local_Test(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer){ + + int len; + unsigned int rec_buff_len = 4096; + unsigned int rec_buffer[4097]; + + + Local_Write(ll,buffer_len,buffer); + usleep(10000); + + do{ + len = Local_Read(ll,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 Local_llfifo_print_frame(struct LocalLinkInterface* ll,unsigned char* fbuff, int len){ + int i; + printf("\n\r----Frame of len : %d Byte\n\r",len); + for(i=0;i