From 261849d69c50b5618a45acedeefbcb0624979088 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Tue, 23 Oct 2018 16:20:40 +0200 Subject: [PATCH] eiger server compiles, client side of interface to do --- slsDetectorServers/eigerDetectorServer/Beb.c | 978 +++-- slsDetectorServers/eigerDetectorServer/Beb.h | 159 +- .../eigerDetectorServer/FebControl.c | 1325 +++--- .../eigerDetectorServer/FebControl.h | 279 +- .../eigerDetectorServer/FebInterface.c | 239 +- .../eigerDetectorServer/FebInterface.h | 53 +- .../eigerDetectorServer/HardwareIO.c | 11 - .../eigerDetectorServer/LocalLinkInterface.c | 110 +- .../eigerDetectorServer/LocalLinkInterface.h | 59 +- .../eigerDetectorServer/gitInfo.txt | 8 +- .../eigerDetectorServer/gitInfoEiger.h | 6 +- .../slsDetectorFunctionList.c | 918 +++-- .../slsDetectorServer_defs.h | 2 +- .../slsDetectorFunctionList.c | 11 +- .../mythen3DetectorServer/AD9257.h | 1 - .../mythen3DetectorServer/Makefile | 33 - .../mythen3DetectorServer/Makefile.virtual | 25 - .../mythen3DetectorServer/RegisterDefs.h | 101 - .../mythen3DetectorServer/ansi.h | 1 - .../mythen3DetectorServer/blackfin.h | 1 - .../commonServerFunctions.h | 1 - .../communication_funcs.c | 1 - .../communication_funcs.h | 1 - .../mythen3DetectorServer/gitInfo.txt | 9 - .../mythen3DetectorServer/gitInfoMythen3.h | 6 - .../mythen3DetectorServer/gitInfoMythen3Tmp.h | 6 - .../mythen3DetectorServer/mythen3Server | Bin 92440 -> 0 bytes .../mythen3DetectorServer/mythen3Server.gdb | Bin 435662 -> 0 bytes .../mythen3DetectorServer/programfpga.h | 1 - .../slsDetectorFunctionList.c | 1304 ------ .../slsDetectorFunctionList.h | 1 - .../mythen3DetectorServer/slsDetectorServer.c | 1 - .../slsDetectorServer_defs.h | 167 - .../slsDetectorServer_funcs.c | 1 - .../slsDetectorServer_funcs.h | 1 - .../mythen3DetectorServer/sls_detector_defs.h | 1 - .../sls_detector_funcs.h | 1 - .../mythen3DetectorServer/sls_receiver_defs.h | 1 - .../sls_receiver_funcs.h | 1 - .../mythen3DetectorServer/updateGitVersion.sh | 31 - .../slsDetectorServer/communication_funcs.c | 108 +- .../slsDetectorServer/communication_funcs.h | 3 +- slsDetectorServers/slsDetectorServer/logger.h | 3 +- .../slsDetectorFunctionList.h | 39 +- .../slsDetectorServer/slsDetectorServer.c | 17 +- .../slsDetectorServer_funcs.c | 3626 ++++++----------- .../slsDetectorServer_funcs.h | 6 +- .../slsDetector/slsDetector.cpp | 41 +- .../src/slsReceiverTCPIPInterface.cpp | 174 +- slsSupportLib/include/ClientInterface.cpp | 4 +- slsSupportLib/include/ClientInterface.h | 3 +- slsSupportLib/include/sls_detector_defs.h | 4 +- 52 files changed, 3442 insertions(+), 6441 deletions(-) delete mode 120000 slsDetectorServers/mythen3DetectorServer/AD9257.h delete mode 100644 slsDetectorServers/mythen3DetectorServer/Makefile delete mode 100644 slsDetectorServers/mythen3DetectorServer/Makefile.virtual delete mode 100644 slsDetectorServers/mythen3DetectorServer/RegisterDefs.h delete mode 120000 slsDetectorServers/mythen3DetectorServer/ansi.h delete mode 120000 slsDetectorServers/mythen3DetectorServer/blackfin.h delete mode 120000 slsDetectorServers/mythen3DetectorServer/commonServerFunctions.h delete mode 120000 slsDetectorServers/mythen3DetectorServer/communication_funcs.c delete mode 120000 slsDetectorServers/mythen3DetectorServer/communication_funcs.h delete mode 100644 slsDetectorServers/mythen3DetectorServer/gitInfo.txt delete mode 100644 slsDetectorServers/mythen3DetectorServer/gitInfoMythen3.h delete mode 100644 slsDetectorServers/mythen3DetectorServer/gitInfoMythen3Tmp.h delete mode 100755 slsDetectorServers/mythen3DetectorServer/mythen3Server delete mode 100755 slsDetectorServers/mythen3DetectorServer/mythen3Server.gdb delete mode 120000 slsDetectorServers/mythen3DetectorServer/programfpga.h delete mode 100644 slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c delete mode 120000 slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.h delete mode 120000 slsDetectorServers/mythen3DetectorServer/slsDetectorServer.c delete mode 100644 slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h delete mode 120000 slsDetectorServers/mythen3DetectorServer/slsDetectorServer_funcs.c delete mode 120000 slsDetectorServers/mythen3DetectorServer/slsDetectorServer_funcs.h delete mode 120000 slsDetectorServers/mythen3DetectorServer/sls_detector_defs.h delete mode 120000 slsDetectorServers/mythen3DetectorServer/sls_detector_funcs.h delete mode 120000 slsDetectorServers/mythen3DetectorServer/sls_receiver_defs.h delete mode 120000 slsDetectorServers/mythen3DetectorServer/sls_receiver_funcs.h delete mode 100755 slsDetectorServers/mythen3DetectorServer/updateGitVersion.sh diff --git a/slsDetectorServers/eigerDetectorServer/Beb.c b/slsDetectorServers/eigerDetectorServer/Beb.c index dc4e139fa..7c20c2b40 100644 --- a/slsDetectorServers/eigerDetectorServer/Beb.c +++ b/slsDetectorServers/eigerDetectorServer/Beb.c @@ -1,12 +1,8 @@ - -/** - * @author Ian Johnson - * @version 1.0 - */ - - -//return reversed 1 means good, 0 means failed - +#include "xfs_types.h" +#include "xparameters.h" +#include "FebRegisterDefs.h" +#include "logger.h" +#include "Beb.h" #include @@ -14,46 +10,40 @@ #include #include #include - - - -#include "xfs_types.h" -#include "xparameters.h" -#include "FebRegisterDefs.h" - -#include "Beb.h" +#include +#include #define MAX(x, y) (((x) > (y)) ? (x) : (y)) - struct BebInfo beb_infos[10]; - int bebInfoSize = 0; +struct BebInfo beb_infos[10]; +int bebInfoSize = 0; - struct LocalLinkInterface ll_beb_local,* ll_beb; +struct LocalLinkInterface ll_beb_local,* ll_beb; - struct udp_header_type udp_header; +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_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; +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; - int BEB_MMAP_SIZE = 0x1000; +short Beb_bit_mode; +int BEB_MMAP_SIZE = 0x1000; - int Beb_activated = 1; +int Beb_activated = 1; - uint32_t Beb_detid = 0; - int Beb_top =0; +uint32_t Beb_detid = 0; +int Beb_top =0; -void BebInfo_BebInfo(struct BebInfo* bebInfo, unsigned int beb_num){ +void BebInfo_BebInfo(struct BebInfo* bebInfo, unsigned int beb_num) { bebInfo->beb_number=beb_num; bebInfo->serial_address=0; strcpy(bebInfo->src_mac_1GbE,""); @@ -64,18 +54,18 @@ void BebInfo_BebInfo(struct BebInfo* bebInfo, unsigned int beb_num){ } -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_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; +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; } @@ -87,20 +77,29 @@ char* BebInfo_GetSrcIP(struct BebInfo* bebInfo, int ten_gig) {return ten_gig 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 BebInfo_Print(struct BebInfo* bebInfo) { + FILE_LOG(logINFO, ( + "%d) Beb Info:\n" + "\tSerial Add: 0x%x\n" + "\tMAC 1GbE: %s\n" + "\tIP 1GbE: %s\n" + "\tPort 1GbE: %d\n" + "\tMAC 10GbE: %s\n" + "\tIP 10GbE: %s\n" + "\tPort 10GbE: %d\n", + bebInfo->beb_number, + bebInfo->serial_address, + bebInfo->src_mac_1GbE, + bebInfo->src_ip_1GbE, + bebInfo->src_port_1GbE, + bebInfo->src_mac_10GbE, + bebInfo->src_ip_10GbE, + bebInfo->src_port_10GbE)); } -void Beb_Beb(){ - +void Beb_Beb(int id) { + Beb_detid = id; Beb_send_ndata = 0; Beb_send_buffer_size = 1026; Beb_send_data_raw = malloc((Beb_send_buffer_size+1) * sizeof(unsigned int)); @@ -111,76 +110,76 @@ void Beb_Beb(){ 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} - }; + 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); + if (!Beb_InitBebInfos()) exit(1); - printf("Printing Beb infos:\n"); - unsigned int i; - for(i=1;i 0) + if (fd > 0) Beb_close(fd,csp0base); return ret; } /* do not work at the moment */ -int Beb_SetSlaveViaSoftware(){ +int Beb_SetSlaveViaSoftware() { - if(!Beb_activated) + if (!Beb_activated) return 0; //mapping new memory @@ -347,66 +343,69 @@ int Beb_SetSlaveViaSoftware(){ //open file pointer int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_SYS_BASEADDR); - if(fd < 0) - cprintf(BG_RED,"Set Slave FAIL\n"); - else{ + if (fd < 0) { + FILE_LOG(logERROR, ("Set Slave FAIL\n")); + } else { value = Beb_Read32(csp0base, MASTERCONFIG_OFFSET); value&=~MASTER_BIT; value|=OVERWRITE_HARDWARE_BIT; int newval = Beb_Write32(csp0base, MASTERCONFIG_OFFSET,value); - if(newval!=value) - cprintf(BG_RED,"Could not set Slave via Software\n"); - else + if (newval!=value) { + FILE_LOG(logERROR, ("Could not set Slave via Software\n")); + } else { ret = 0; + } } //close file pointer - if(fd > 0) + if (fd > 0) Beb_close(fd,csp0base); return ret; } -int Beb_Activate(int enable){ +int Beb_Activate(int enable) { //mapping new memory u_int32_t* csp0base=0; u_int32_t value = 0, ret = -1; //open file pointer int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_SYS_BASEADDR); - if(fd < 0) - cprintf(BG_RED,"Deactivate FAIL\n"); - else{ - if(enable > -1){ + if (fd < 0) { + FILE_LOG(logERROR, ("Deactivate FAIL\n")); + } else { + if (enable > -1) { value = Beb_Read32(csp0base, MASTERCONFIG_OFFSET); - printf("Deactivate register value before:%d\n",value); - if(enable) + FILE_LOG(logINFO, ("Deactivate register value before:%d\n",value)); + if (enable) value&=~DEACTIVATE_BIT; else value|=DEACTIVATE_BIT; int newval = Beb_Write32(csp0base, MASTERCONFIG_OFFSET,value); - if(newval!=value){ - if(enable) - cprintf(BG_RED,"Could not activate via Software\n"); - else - cprintf(BG_RED,"Could not deactivate via Software\n"); + if (newval!=value) { + if (enable) { + FILE_LOG(logERROR, ("Could not activate via Software\n")); + } else { + FILE_LOG(logERROR, ("Could not deactivate via Software\n")); + } } } value = Beb_Read32(csp0base, MASTERCONFIG_OFFSET); - if(value&DEACTIVATE_BIT) ret = 0; + if (value&DEACTIVATE_BIT) ret = 0; else ret = 1; - if(enable == -1){ - if(ret) - cprintf(BLUE,"Detector is active. Register value:%d\n", value); - else - cprintf(BG_RED,"Detector is deactivated! Register value:%d\n", value); + if (enable == -1) { + if (ret) { + FILE_LOG(logINFOBLUE, ("Detector is active. Register value:%d\n", value)); + } else { + FILE_LOG(logERROR, ("Detector is deactivated! Register value:%d\n", value)); + } } } //close file pointer - if(fd > 0) + if (fd > 0) Beb_close(fd,csp0base); Beb_activated = ret; @@ -416,23 +415,23 @@ int Beb_Activate(int enable){ int Beb_Set32bitOverflow(int val) { - if(!Beb_activated) + if (!Beb_activated) return val; //mapping new memory u_int32_t* csp0base=0; u_int32_t valueread = 0; u_int32_t offset = FLOW_REG_OFFSET; - if(val>0) val = 1; + if (val>0) val = 1; //open file pointer int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_SYS_BASEADDR); - if(fd < 0){ - cprintf(BG_RED,"Could not read register to set overflow flag in 32 bit mode. FAIL\n"); + if (fd < 0) { + FILE_LOG(logERROR, ("Could not read register to set overflow flag in 32 bit mode. FAIL\n")); return -1; } - else{ - if(val > -1){ + else { + if (val > -1) { // reset bit valueread = Beb_Read32(csp0base, offset); Beb_Write32(csp0base, offset,valueread & ~FLOW_REG_OVERFLOW_32_BIT_MSK); @@ -446,15 +445,15 @@ int Beb_Set32bitOverflow(int val) { valueread = (Beb_Read32(csp0base, offset) & FLOW_REG_OVERFLOW_32_BIT_MSK) >> FLOW_REG_OVERFLOW_32_BIT_OFST; } //close file pointer - if(fd > 0) + if (fd > 0) Beb_close(fd,csp0base); return valueread; } -int Beb_SetNetworkParameter(enum NETWORKINDEX mode, int val){ +int Beb_SetNetworkParameter(enum NETWORKINDEX mode, int val) { - if(!Beb_activated) + if (!Beb_activated) return val; @@ -464,7 +463,7 @@ int Beb_SetNetworkParameter(enum NETWORKINDEX mode, int val){ u_int32_t offset = TXM_DELAY_LEFT_OFFSET; char modename[100] = ""; - switch(mode){ + switch(mode) { case TXN_LEFT: offset = TXM_DELAY_LEFT_OFFSET; strcpy(modename,"Transmission Delay Left"); @@ -480,18 +479,18 @@ int Beb_SetNetworkParameter(enum NETWORKINDEX mode, int val){ case FLOWCTRL_10G: offset = FLOW_REG_OFFSET; strcpy(modename,"Flow Control for 10G"); - if(val>0) val = 1; + if (val>0) val = 1; break; - default: cprintf(BG_RED,"Unrecognized mode in network parameter: %d\n",mode); return -1; + default: FILE_LOG(logERROR, ("Unrecognized mode in network parameter: %d\n",mode)); return -1; } //open file pointer int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_SYS_BASEADDR); - if(fd < 0){ - cprintf(BG_RED,"Could not read register to set network parameter. FAIL\n"); + if (fd < 0) { + FILE_LOG(logERROR, ("Could not read register to set network parameter. FAIL\n")); return -1; } - else{ - if(val > -1){ + else { + if (val > -1) { if (mode != FLOWCTRL_10G) { valueread = Beb_Read32(csp0base, offset); Beb_Write32(csp0base, offset,val); @@ -517,16 +516,16 @@ int Beb_SetNetworkParameter(enum NETWORKINDEX mode, int val){ } //close file pointer - if(fd > 0) + if (fd > 0) Beb_close(fd,csp0base); return valueread; } -int Beb_ResetToHardwareSettings(){ +int Beb_ResetToHardwareSettings() { - if(!Beb_activated) + if (!Beb_activated) return 1; //mapping new memory @@ -535,18 +534,19 @@ int Beb_ResetToHardwareSettings(){ //open file pointer int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_SYS_BASEADDR); - if(fd < 0) - cprintf(BG_RED,"Reset to Hardware Settings FAIL\n"); - else{ + if (fd < 0) { + FILE_LOG(logERROR, ("Reset to Hardware Settings FAIL\n")); + } else { value = Beb_Write32(csp0base, MASTERCONFIG_OFFSET,0); - if(value) - cprintf(BG_RED,"Could not reset to hardware settings\n"); - else + if (value) { + FILE_LOG(logERROR, ("Could not reset to hardware settings\n")); + } else { ret = 0; + } } //close file pointer - if(fd > 0) + if (fd > 0) Beb_close(fd,csp0base); return ret; @@ -554,95 +554,97 @@ int Beb_ResetToHardwareSettings(){ -u_int32_t Beb_GetFirmwareRevision(){ +u_int32_t Beb_GetFirmwareRevision() { //mapping new memory u_int32_t* csp0base=0; u_int32_t value = 0; //open file pointer int fd = Beb_open(&csp0base,XPAR_VERSION); - if(fd < 0) - cprintf(BG_RED,"Firmware Revision Read FAIL\n"); - else{ + if (fd < 0) { + FILE_LOG(logERROR, ("Firmware Revision Read FAIL\n")); + } else { value = Beb_Read32(csp0base, FIRMWARE_VERSION_OFFSET); - if(!value) - cprintf(BG_RED,"Firmware Revision Number does not exist in this version\n"); + if (!value) { + FILE_LOG(logERROR, ("Firmware Revision Number does not exist in this version\n")); + } } //close file pointer - if(fd > 0) + if (fd > 0) Beb_close(fd,csp0base); return value; } -u_int32_t Beb_GetFirmwareSoftwareAPIVersion(){ +u_int32_t Beb_GetFirmwareSoftwareAPIVersion() { //mapping new memory u_int32_t* csp0base=0; u_int32_t value = 0; //open file pointer int fd = Beb_open(&csp0base,XPAR_VERSION); - if(fd < 0) - cprintf(BG_RED,"Firmware Software API Version Read FAIL\n"); - else{ + if (fd < 0) { + FILE_LOG(logERROR, ("Firmware Software API Version Read FAIL\n")); + } else { value = Beb_Read32(csp0base, FIRMWARESOFTWARE_API_OFFSET); - if(!value) - cprintf(BG_RED,"Firmware Software API Version does not exist in this version\n"); + if (!value) { + FILE_LOG(logERROR, ("Firmware Software API Version does not exist in this version\n")); + } } //close file pointer - if(fd > 0) + if (fd > 0) Beb_close(fd,csp0base); return value; } -void Beb_ResetFrameNumber(){ +void Beb_ResetFrameNumber() { - if(!Beb_activated) + if (!Beb_activated) return; //mapping new memory to read master top module configuration u_int32_t* csp0base=0; //open file pointer int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_SYS_BASEADDR); - if(fd < 0){ - cprintf(BG_RED,"Reset Frame Number FAIL\n"); - }else{ + if (fd < 0) { + FILE_LOG(logERROR, ("Reset Frame Number FAIL\n")); + } else { //write a 1 Beb_Write32(csp0base, FRAME_NUM_RESET_OFFSET, 1); usleep(100000); //100ms //write a 0 Beb_Write32(csp0base, FRAME_NUM_RESET_OFFSET, 0); - printf("Frame Number Reset OK\n"); + FILE_LOG(logINFO, ("Frame Number Reset OK\n")); //close file pointer Beb_close(fd,csp0base); } } -void Beb_ClearBebInfos(){ +void Beb_ClearBebInfos() { //unsigned int i; - //for(i=0;i=bebInfoSize){ - printf("WriteTo index error.\n"); - return 0; - } + if (index>=bebInfoSize) { + FILE_LOG(logERROR, ("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] = 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; + 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; + return 1; } -void Beb_SwapDataFun(int little_endian, unsigned int n, unsigned int *d){ +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)); + if (little_endian) for(i=0;i>8) | ((d[i]&0xff000000)>>24)); //little_endian + else for(i=0;i>16)); } -int Beb_SetByteOrder(){ - return 1; +int Beb_SetByteOrder() { + 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){ +int Beb_SetUpUDPHeader(unsigned int beb_number, int ten_gig, unsigned int header_number, char* dst_mac, char* dst_ip, unsigned int dst_port) { - if(!Beb_activated) + if (!Beb_activated) return 1; u_int32_t bram_phy_addr; @@ -757,14 +760,14 @@ int Beb_SetUpUDPHeader(unsigned int beb_number, int ten_gig, unsigned int header else bram_phy_addr = 0xC6001000; - if(!Beb_SetHeaderData(beb_number,ten_gig,dst_mac,dst_ip,dst_port)) return 0; + if (!Beb_SetHeaderData(beb_number,ten_gig,dst_mac,dst_ip,dst_port)) return 0; int fd = Beb_open(&csp0base,bram_phy_addr); - if(fd < 0){ - cprintf(BG_RED,"Set up UDP Header FAIL\n"); - }else{ + if (fd < 0) { + FILE_LOG(logERROR, ("Set up UDP Header FAIL\n")); + } else { //read data memcpy(csp0base+header_number*16, &udp_header, sizeof(udp_header)); //close file pointer @@ -774,34 +777,17 @@ int Beb_SetUpUDPHeader(unsigned int beb_number, int ten_gig, unsigned int header } -//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 = 1;/*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; -// printf("beb dst_port:%d\n",dst_port); -// 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 = 1;/*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_SetHeaderData(unsigned int beb_number, int ten_gig, char* dst_mac, char* dst_ip, unsigned int dst_port) { + unsigned int i = 1;/*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*/ +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 @@ -823,46 +809,46 @@ int Beb_SetHeaderData1(char* src_mac, char* src_ip, unsigned int src_port, char* {0x00, 0x00}, //{0x00, 0x11}, {0x00, 0x00} }; -*/ + */ - if(!Beb_SetMAC(src_mac,&(udp_header.src_mac[0]))) return 0; - printf("Setting Source MAC to %s\n",src_mac); - if(!Beb_SetIP(src_ip,&(udp_header.src_ip[0]))) return 0; - printf("Setting Source IP to %s\n",src_ip); - if(!Beb_SetPortNumber(src_port,&(udp_header.src_port[0]))) return 0; - printf("Setting Source port to %d\n",src_port); + if (!Beb_SetMAC(src_mac,&(udp_header.src_mac[0]))) return 0; + FILE_LOG(logINFO, ("Setting Source MAC to %s\n",src_mac)); + if (!Beb_SetIP(src_ip,&(udp_header.src_ip[0]))) return 0; + FILE_LOG(logINFO, ("Setting Source IP to %s\n",src_ip)); + if (!Beb_SetPortNumber(src_port,&(udp_header.src_port[0]))) return 0; + FILE_LOG(logINFO, ("Setting Source port to %d\n",src_port)); - if(!Beb_SetMAC(dst_mac,&(udp_header.dst_mac[0]))) return 0; - printf("Setting Destination MAC to %s\n",dst_mac); - if(!Beb_SetIP(dst_ip,&(udp_header.dst_ip[0]))) return 0; - printf("Setting Destination IP to %s\n",dst_ip); - if(!Beb_SetPortNumber(dst_port,&(udp_header.dst_port[0]))) return 0; - printf("Setting Destination port to %d\n",dst_port); + if (!Beb_SetMAC(dst_mac,&(udp_header.dst_mac[0]))) return 0; + FILE_LOG(logINFO, ("Setting Destination MAC to %s\n",dst_mac)); + if (!Beb_SetIP(dst_ip,&(udp_header.dst_ip[0]))) return 0; + FILE_LOG(logINFO, ("Setting Destination IP to %s\n",dst_ip)); + if (!Beb_SetPortNumber(dst_port,&(udp_header.dst_port[0]))) return 0; + FILE_LOG(logINFO, ("Setting Destination port to %d\n",dst_port)); - Beb_AdjustIPChecksum(&udp_header); + 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); + while (pch != NULL) { + if (strlen(pch)!=2) { + FILE_LOG(logERROR, ("Error: in mac address -> %s\n",macVal)); return 0; } @@ -875,15 +861,15 @@ int Beb_SetMAC(char* mac, uint8_t* dst_ptr){ return 1; } -int Beb_SetIP(char* ip, uint8_t* dst_ptr){ +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; - } + while (pch != NULL) { + if (((i!=3) && ((strlen(pch)>3) || (strlen(pch)<1))) || ((i==3)&&((strlen(pch)<1) || (strlen(pch) > 3)))) { + FILE_LOG(logERROR, ("Error: in ip address -> %s\n",ipVal)); + return 0; + } int itemp; sscanf(pch,"%d",&itemp); @@ -894,98 +880,94 @@ int Beb_SetIP(char* ip, uint8_t* dst_ptr){ 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; +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; +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 ; -} + 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 - - -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){ - -// This is a dead function, will be removed in future -// ================================================== - - unsigned int i = 1;/*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; -#ifdef MARTIN - cprintf(GREEN, "Beb_send_data[1]:%X\n",Beb_send_data[1]); -#endif - Beb_send_data[2] = 0; - - Beb_SwapDataFun(0,2,&(Beb_send_data[1])); -#ifdef MARTIN - cprintf(GREEN, "Beb_send_data[1] Swapped:%X\n",Beb_send_data[1]); -#endif - - if(Beb_activated){ - if(!Beb_WriteTo(i)) return 0; + // 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; } - return 1; + ip->ip_header_checksum[0] = (ip_checksum >> 8) & 0xff ; + ip->ip_header_checksum[1] = ip_checksum & 0xff ; } -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_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) { + + // This is a dead function, will be removed in future + // ================================================== + + unsigned int i = 1;/*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; + FILE_LOG(logDEBUG5, ("Beb_send_data[1]:%X\n",Beb_send_data[1])); + Beb_send_data[2] = 0; + + Beb_SwapDataFun(0,2,&(Beb_send_data[1])); + FILE_LOG(logDEBUG5, ("Beb_send_data[1] Swapped:%X\n",Beb_send_data[1])); + + if (Beb_activated) { + 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_StopAcquisition() { - if(!Beb_activated) + if (!Beb_activated) return 1; u_int32_t* csp0base=0; volatile u_int32_t valuel,valuer; //open file pointer int fd = Beb_open(&csp0base,XPAR_CMD_GENERATOR); - if(fd < 0){ - cprintf(BG_RED,"Beb Stop Acquisition FAIL\n"); + if (fd < 0) { + FILE_LOG(logERROR, ("Beb Stop Acquisition FAIL\n")); return 0; - }else{ + } else { //find value valuel = Beb_Read32(csp0base, (LEFT_OFFSET+STOP_ACQ_OFFSET)); valuer = Beb_Read32(csp0base, (RIGHT_OFFSET+STOP_ACQ_OFFSET)); @@ -996,19 +978,19 @@ int Beb_StopAcquisition() Beb_Write32(csp0base, (LEFT_OFFSET + STOP_ACQ_OFFSET),(valuel&(~STOP_ACQ_BIT))); Beb_Write32(csp0base, (RIGHT_OFFSET + STOP_ACQ_OFFSET),(valuer&(~STOP_ACQ_BIT))); - printf("Beb Stop Acquisition OK\n"); + FILE_LOG(logINFO, ("Beb Stop Acquisition OK\n")); //close file pointer Beb_close(fd,csp0base); } return 1; } -int Beb_RequestNImages(unsigned int beb_number, int ten_gig, unsigned int dst_number, unsigned int nimages, int test_just_send_out_packets_no_wait){ +int Beb_RequestNImages(unsigned int beb_number, int ten_gig, unsigned int dst_number, unsigned int nimages, int test_just_send_out_packets_no_wait) { - if(!Beb_activated) + if (!Beb_activated) return 1; - if(dst_number>64) return 0; + 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 @@ -1020,12 +1002,13 @@ int Beb_RequestNImages(unsigned int beb_number, int ten_gig, unsigned int dst_nu u_int32_t send_header_command; u_int32_t send_frame_command; - if(in_two_requests) npackets/=2; + if (in_two_requests) npackets/=2; -#ifdef MARTIN - cprintf(RED, "----Beb_RequestNImages Start----\n"); - cprintf(RED, "beb_number:%X, ten_gig:%X,dst_number:%X,npackets:%X,Beb_bit_mode:%X,header_size:%X,nimages:%d,test_just_send_out_packets_no_wait:%X\n",beb_number,ten_gig,dst_number,npackets,Beb_bit_mode,header_size,nimages,test_just_send_out_packets_no_wait); -#endif + FILE_LOG(logDEBUG5, ("----Beb_RequestNImages Start----\n")); + FILE_LOG(logDEBUG5, ("beb_number:%X, ten_gig:%X,dst_number:%X, npackets:%X, " + "Beb_bit_mode:%X, header_size:%X, nimages:%d, test_just_send_out_packets_no_wait:%X\n", + beb_number, ten_gig, dst_number, npackets, Beb_bit_mode, header_size, + nimages, test_just_send_out_packets_no_wait)); // CMD_GEN core registers // @@ -1061,26 +1044,24 @@ int Beb_RequestNImages(unsigned int beb_number, int ten_gig, unsigned int dst_nu volatile u_int32_t value; //open file pointer int fd = Beb_open(&csp0base,XPAR_CMD_GENERATOR); - if(fd < 0){ - cprintf(BG_RED,"Beb Request N Images FAIL\n"); + if (fd < 0) { + FILE_LOG(logERROR, ("Beb Request N Images FAIL\n")); return 0; - }else{ - -#ifdef MARTIN - int i; - for (i=0; i < 10; i++) - printf("%X\n",Beb_Read32(baseaddr, (LEFT_OFFSET + i*4))); -#endif + } else { + { + int i; + for (i=0; i < 10; i++) + FILE_LOG(logDEBUG5, ("%X\n",Beb_Read32(csp0base, (LEFT_OFFSET + i*4)))); + } // Generating commands send_header_command = 0x62000000 | (!test_just_send_out_packets_no_wait) << 27 | (ten_gig==1) << 24 | header_size << 14 | 0; send_frame_command = 0x62000000 | (!test_just_send_out_packets_no_wait) << 27 | (ten_gig==1) << 24 | packet_size << 14 | (npackets-1); - -#ifdef MARTIN - for (i=0; i < 10; i++) - printf("%X\n",Beb_Read32(baseaddr, (LEFT_OFFSET + i*4))); - printf("%d\n",in_two_requests); -#endif - + { + int i; + for (i=0; i < 10; i++) + FILE_LOG(logDEBUG5, ("%X\n",Beb_Read32(csp0base, (LEFT_OFFSET + i*4)))); + FILE_LOG(logDEBUG5, ("%d\n",in_two_requests)); + } //"0x20 << 8" is dst_number (0x00 for left, 0x20 for right) //Left Beb_Write32(csp0base, (LEFT_OFFSET + FIRST_CMD_PART1_OFFSET),0); @@ -1088,7 +1069,7 @@ int Beb_RequestNImages(unsigned int beb_number, int ten_gig, unsigned int dst_nu Beb_Write32(csp0base, (LEFT_OFFSET + SECOND_CMD_PART1_OFFSET),0); Beb_Write32(csp0base, (LEFT_OFFSET + SECOND_CMD_PART2_OFFSET),send_frame_command); value = Beb_Read32(csp0base,(LEFT_OFFSET + TWO_REQUESTS_OFFSET)); - if(in_two_requests) Beb_Write32(csp0base, (LEFT_OFFSET + TWO_REQUESTS_OFFSET),(value | TWO_REQUESTS_BIT)); + if (in_two_requests) Beb_Write32(csp0base, (LEFT_OFFSET + TWO_REQUESTS_OFFSET),(value | TWO_REQUESTS_BIT)); else Beb_Write32(csp0base, (LEFT_OFFSET + TWO_REQUESTS_OFFSET),(value &~(TWO_REQUESTS_BIT))); // Right @@ -1097,62 +1078,59 @@ int Beb_RequestNImages(unsigned int beb_number, int ten_gig, unsigned int dst_nu Beb_Write32(csp0base, (RIGHT_OFFSET + SECOND_CMD_PART1_OFFSET),0); Beb_Write32(csp0base, (RIGHT_OFFSET + SECOND_CMD_PART2_OFFSET),send_frame_command | right_port_value); value = Beb_Read32(csp0base,(RIGHT_OFFSET + TWO_REQUESTS_OFFSET)); - if(in_two_requests) Beb_Write32(csp0base, (RIGHT_OFFSET + TWO_REQUESTS_OFFSET),(value | TWO_REQUESTS_BIT)); + if (in_two_requests) Beb_Write32(csp0base, (RIGHT_OFFSET + TWO_REQUESTS_OFFSET),(value | TWO_REQUESTS_BIT)); else Beb_Write32(csp0base, (RIGHT_OFFSET + TWO_REQUESTS_OFFSET),(value &~(TWO_REQUESTS_BIT))); // Set number of frames Beb_Write32(csp0base, (LEFT_OFFSET + COMMAND_COUNTER_OFFSET), nimages*(2+in_two_requests)); Beb_Write32(csp0base, (RIGHT_OFFSET + COMMAND_COUNTER_OFFSET), nimages*(2+in_two_requests)); - -#ifdef MARTIN - for (i=0; i < 10; i++) - printf("%X\n",Beb_Read32(baseaddr, (LEFT_OFFSET + i*4))); //*(ptrl+i)); - printf("%d\n",in_two_requests); -#endif - + { + int i; + for (i=0; i < 10; i++) + FILE_LOG(logDEBUG5, ("%X\n",Beb_Read32(csp0base, (LEFT_OFFSET + i*4)))); //*(ptrl+i)); + FILE_LOG(logDEBUG5, ("%d\n",in_two_requests)); + } Beb_close(fd,csp0base); -#ifdef MARTIN - printf("----Beb_RequestNImages----\n"); -#endif + FILE_LOG(logDEBUG5, ("----Beb_RequestNImages----\n")); } return 1; } -int Beb_Test(unsigned int beb_number){ - printf("Testing module number: %d\n",beb_number); - +int Beb_Test(unsigned int beb_number) { + FILE_LOG(logINFO, ("Testing module number: %d\n",beb_number)); - //int SetUpUDPHeader(unsigned int beb_number, int 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 = Beb_GetBebInfoIndex(beb_number); - if(!index){ - printf("Error beb number (%d)not in list????\n",beb_number); - return 0; - } + //int SetUpUDPHeader(unsigned int beb_number, int 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 i; - for(i=0;i<64;i++){ - if(!Beb_SetUpUDPHeader(beb_number,0,i,"60:fb:42:f4:e3:d2","129.129.205.186",22000+i)){ - printf("Error setting up header table....\n"); - return 0; - } - } + unsigned int index = Beb_GetBebInfoIndex(beb_number); + if (!index) { + FILE_LOG(logERROR, ("Error beb number (%d)not in list????\n",beb_number)); + return 0; + } - // 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=1); - for(i=0;i<64;i++){ - if(!Beb_SendMultiReadRequest(beb_number,i%3+1,0,i,1,0,1)){ - printf("Error requesting data....\n"); - return 0; - } - } - + unsigned int i; + for(i=0;i<64;i++) { + if (!Beb_SetUpUDPHeader(beb_number,0,i,"60:fb:42:f4:e3:d2","129.129.205.186",22000+i)) { + FILE_LOG(logERROR, ("Error setting up header table....\n")); + return 0; + } + } - return 1; + // 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=1); + for(i=0;i<64;i++) { + if (!Beb_SendMultiReadRequest(beb_number,i%3+1,0,i,1,0,1)) { + FILE_LOG(logERROR, ("Error requesting data....\n")); + return 0; + } + } + + + return 1; } // Returns the FPGA temperature from the xps sysmon ip core @@ -1165,9 +1143,9 @@ int Beb_GetBebFPGATemp() int ret; //open file pointer int fd = Beb_open(&csp0base,XPAR_SYSMON_0_BASEADDR); - if(fd < 0){ - cprintf(BG_RED,"Module Configuration FAIL\n"); - }else{ + if (fd < 0) { + FILE_LOG(logERROR, ("Module Configuration FAIL\n")); + } else { //read data ret = Beb_Read32(csp0base, FPGA_TEMP_OFFSET); temperature = ((((float)(ret)/65536.0f)/0.00198421639f ) - 273.15f)*1000; // Static conversation, copied from xps sysmon standalone driver @@ -1180,42 +1158,42 @@ int Beb_GetBebFPGATemp() void Beb_SetDetectorNumber(uint32_t detid) { - if(!Beb_activated) + if (!Beb_activated) return; uint32_t swapid = Beb_swap_uint16(detid); - //cprintf(GREEN, "detector id %d swapped %d\n", detid, swapid); + //FILE_LOG(logINFO, "detector id %d swapped %d\n", detid, swapid)); u_int32_t* csp0base=0; int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_TEST_BASEADDR); - if(fd < 0){ - cprintf(BG_RED,"Set Detector ID FAIL\n"); + if (fd < 0) { + FILE_LOG(logERROR, ("Set Detector ID FAIL\n")); return; - }else{ + } else { uint32_t value = Beb_Read32(csp0base, UDP_HEADER_A_LEFT_OFST); value &= UDP_HEADER_X_MSK; // to keep previous x value Beb_Write32(csp0base, UDP_HEADER_A_LEFT_OFST, value | ((swapid << UDP_HEADER_ID_OFST) & UDP_HEADER_ID_MSK)); value = Beb_Read32(csp0base, UDP_HEADER_A_LEFT_OFST); - if((value & UDP_HEADER_ID_MSK) != ((swapid << UDP_HEADER_ID_OFST) & UDP_HEADER_ID_MSK)) - cprintf(BG_RED,"Set Detector ID FAIL\n"); - + if ((value & UDP_HEADER_ID_MSK) != ((swapid << UDP_HEADER_ID_OFST) & UDP_HEADER_ID_MSK)) { + FILE_LOG(logERROR, ("Set Detector ID FAIL\n")); + } value = Beb_Read32(csp0base, UDP_HEADER_A_RIGHT_OFST); value &= UDP_HEADER_X_MSK; // to keep previous x value Beb_Write32(csp0base, UDP_HEADER_A_RIGHT_OFST, value | ((swapid << UDP_HEADER_ID_OFST) & UDP_HEADER_ID_MSK)); value = Beb_Read32(csp0base, UDP_HEADER_A_RIGHT_OFST); - if((value & UDP_HEADER_ID_MSK) != ((swapid << UDP_HEADER_ID_OFST) & UDP_HEADER_ID_MSK)) - cprintf(BG_RED,"Set Detector ID FAIL\n"); - + if ((value & UDP_HEADER_ID_MSK) != ((swapid << UDP_HEADER_ID_OFST) & UDP_HEADER_ID_MSK)) { + FILE_LOG(logERROR, ("Set Detector ID FAIL\n")); + } Beb_close(fd,csp0base); } - printf("detector id %d has been set in udp header\n", detid); + FILE_LOG(logINFO, ("Detector id %d set in UDP Header\n\n", detid)); } int Beb_SetDetectorPosition(int pos[]) { - if(!Beb_activated) + if (!Beb_activated) return OK; - cprintf(BLUE,"Got Position values %d %d %d...\n", pos[0],pos[1], pos[2]); + FILE_LOG(logINFO, ("Got Position values %d %d %d...\n", pos[0],pos[1], pos[2])); pos[0] = Beb_swap_uint16(pos[0]); //pos[1] = Beb_swap_uint16(pos[1]); @@ -1226,10 +1204,10 @@ int Beb_SetDetectorPosition(int pos[]) { u_int32_t* csp0base=0; //open file pointer int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_TEST_BASEADDR); - if(fd < 0){ - cprintf(BG_RED,"Set Detector Position FAIL\n"); + if (fd < 0) { + FILE_LOG(logERROR, ("Set Detector Position FAIL\n")); return FAIL; - }else{ + } else { uint32_t value = 0; ret = OK; // x left @@ -1237,7 +1215,7 @@ int Beb_SetDetectorPosition(int pos[]) { value &= UDP_HEADER_ID_MSK; // to keep previous id value Beb_Write32(csp0base, UDP_HEADER_A_LEFT_OFST, value | ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)); value = Beb_Read32(csp0base, UDP_HEADER_A_LEFT_OFST); - if((value & UDP_HEADER_X_MSK) != ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)) + if ((value & UDP_HEADER_X_MSK) != ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)) ret = FAIL; // x right @@ -1245,7 +1223,7 @@ int Beb_SetDetectorPosition(int pos[]) { value &= UDP_HEADER_ID_MSK; // to keep previous id value Beb_Write32(csp0base, UDP_HEADER_A_RIGHT_OFST, value | ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)); value = Beb_Read32(csp0base, UDP_HEADER_A_RIGHT_OFST); - if((value & UDP_HEADER_X_MSK) != ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)) + if ((value & UDP_HEADER_X_MSK) != ((pos[0] << UDP_HEADER_X_OFST) & UDP_HEADER_X_MSK)) ret = FAIL; @@ -1255,7 +1233,7 @@ int Beb_SetDetectorPosition(int pos[]) { int posval = Beb_swap_uint16(Beb_top ? pos[1] : (pos[1]+1)); Beb_Write32(csp0base, UDP_HEADER_B_LEFT_OFST, ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)); value = Beb_Read32(csp0base, UDP_HEADER_B_LEFT_OFST); - if(value != ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)) + if (value != ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)) ret = FAIL; // y right @@ -1263,7 +1241,7 @@ int Beb_SetDetectorPosition(int pos[]) { posval = Beb_swap_uint16(Beb_top ? (pos[1]+1) : pos[1]); Beb_Write32(csp0base, UDP_HEADER_B_RIGHT_OFST, ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)); value = Beb_Read32(csp0base, UDP_HEADER_B_RIGHT_OFST); - if(value != ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)) + if (value != ((posval << UDP_HEADER_Y_OFST) & UDP_HEADER_Y_MSK)) ret = FAIL; @@ -1273,7 +1251,7 @@ int Beb_SetDetectorPosition(int pos[]) { value &= UDP_HEADER_Y_MSK; // to keep previous y value Beb_Write32(csp0base, UDP_HEADER_B_LEFT_OFST, value | ((pos[2] << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK)); value = Beb_Read32(csp0base, UDP_HEADER_B_LEFT_OFST); - if((value & UDP_HEADER_Z_MSK) != ((pos[2] << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK)) + if ((value & UDP_HEADER_Z_MSK) != ((pos[2] << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK)) ret = FAIL; // z right @@ -1281,7 +1259,7 @@ int Beb_SetDetectorPosition(int pos[]) { value &= UDP_HEADER_Y_MSK; // to keep previous y value Beb_Write32(csp0base, UDP_HEADER_B_RIGHT_OFST, value | ((pos[2] << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK)); value = Beb_Read32(csp0base, UDP_HEADER_B_RIGHT_OFST); - if((value & UDP_HEADER_Z_MSK) != ((pos[2] << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK)) + if ((value & UDP_HEADER_Z_MSK) != ((pos[2] << UDP_HEADER_Z_OFST) & UDP_HEADER_Z_MSK)) ret = FAIL; @@ -1289,11 +1267,11 @@ int Beb_SetDetectorPosition(int pos[]) { Beb_close(fd,csp0base); } if (ret == OK) { - cprintf(BLUE, "Position set to...\n" + FILE_LOG(logINFO, ("Position set to...\n" "Left: [%d, %d, %d]\n" "Right:[%d, %d, %d]\n", - Beb_swap_uint16(pos[0]), Beb_top ? pos[1] : (pos[1]+1), Beb_swap_uint16(pos[2]), - Beb_swap_uint16(pos[0]), Beb_top ? (pos[1]+1) : pos[1], Beb_swap_uint16(pos[2])); + Beb_swap_uint16(pos[0]), Beb_top ? pos[1] : (pos[1]+1), Beb_swap_uint16(pos[2]), + Beb_swap_uint16(pos[0]), Beb_top ? (pos[1]+1) : pos[1], Beb_swap_uint16(pos[2]))); } return ret; @@ -1301,46 +1279,42 @@ int Beb_SetDetectorPosition(int pos[]) { uint16_t Beb_swap_uint16( uint16_t val) { - return (val << 8) | (val >> 8 ); + return (val << 8) | (val >> 8 ); } -int Beb_open(u_int32_t** csp0base, u_int32_t offset){ +int Beb_open(u_int32_t** csp0base, u_int32_t offset) { int fd = open("/dev/mem", O_RDWR | O_SYNC, 0); - if (fd == -1) - cprintf(BG_RED,"\nCan't find /dev/mem!\n"); - else{ -#ifdef VERBOSE - printf("/dev/mem opened\n"); -#endif + if (fd == -1) { + FILE_LOG(logERROR, ("\nCan't find /dev/mem!\n")); + } else { + FILE_LOG(logDEBUG5, ("/dev/mem opened\n")); *csp0base = (u_int32_t*)mmap(0, BEB_MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, offset); if (*csp0base == MAP_FAILED) { - cprintf(BG_RED,"\nCan't map memmory area!!\n"); + FILE_LOG(logERROR, ("\nCan't map memmory area!!\n")); fd = -1; } -#ifdef VERBOSE - else printf("CSP0 mapped %p\n",(void*)*csp0base); -#endif + else FILE_LOG(logDEBUG5, ("CSP0 mapped %p\n",(void*)*csp0base)); } return fd; } -u_int32_t Beb_Read32 (u_int32_t* baseaddr, u_int32_t offset){ +u_int32_t Beb_Read32 (u_int32_t* baseaddr, u_int32_t offset) { volatile u_int32_t value; value=* (u_int32_t*)(baseaddr + offset/(sizeof(u_int32_t))); return value; } -u_int32_t Beb_Write32 (u_int32_t* baseaddr, u_int32_t offset, u_int32_t data){ +u_int32_t Beb_Write32 (u_int32_t* baseaddr, u_int32_t offset, u_int32_t data) { volatile u_int32_t *ptr1; ptr1=(u_int32_t*)(baseaddr + offset/(sizeof(u_int32_t))); *ptr1 = data; return *ptr1; } -void Beb_close(int fd,u_int32_t* csp0base){ - if(fd >= 0) +void Beb_close(int fd,u_int32_t* csp0base) { + if (fd >= 0) close(fd); munmap(csp0base,BEB_MMAP_SIZE); } diff --git a/slsDetectorServers/eigerDetectorServer/Beb.h b/slsDetectorServers/eigerDetectorServer/Beb.h index 73718db03..6ab1338e8 100644 --- a/slsDetectorServers/eigerDetectorServer/Beb.h +++ b/slsDetectorServers/eigerDetectorServer/Beb.h @@ -1,103 +1,84 @@ - -/** - * @author Ian Johnson - * @version 1.0 - */ - - -#ifndef BEB_H -#define BEB_H - +#pragma once #include "LocalLinkInterface.h" #include "slsDetectorServer_defs.h" - + struct BebInfo{ - unsigned int beb_number; - unsigned int serial_address; - char src_mac_1GbE[50]; - char src_mac_10GbE[50]; - char src_ip_1GbE[50]; - char src_ip_10GbE[50]; - unsigned int src_port_1GbE; - unsigned int src_port_10GbE; + unsigned int beb_number; + unsigned int serial_address; + char src_mac_1GbE[50]; + char src_mac_10GbE[50]; + char src_ip_1GbE[50]; + char src_ip_10GbE[50]; + unsigned int src_port_1GbE; + unsigned int src_port_10GbE; }; - void BebInfo_BebInfo(struct BebInfo* bebInfo, unsigned int beb_num); - void BebInfo_BebDstInfo(struct BebInfo* bebInfo, unsigned int beb_num); - int BebInfo_SetSerialAddress(struct BebInfo* bebInfo, unsigned int add); - int BebInfo_SetHeaderInfo(struct BebInfo* bebInfo, int ten_gig, char* src_mac, char* src_ip, unsigned int src_port);//src_port fixed 42000+beb_number or 52000 + beb_number); - unsigned int BebInfo_GetBebNumber(struct BebInfo* bebInfo); - unsigned int BebInfo_GetSerialAddress(struct BebInfo* bebInfo); - char* BebInfo_GetSrcMAC(struct BebInfo* bebInfo, int ten_gig); - char* BebInfo_GetSrcIP(struct BebInfo* bebInfo, int ten_gig); - unsigned int BebInfo_GetSrcPort(struct BebInfo* bebInfo, int ten_gig); - void BebInfo_Print(struct BebInfo* bebInfo); +void BebInfo_BebInfo(struct BebInfo* bebInfo, unsigned int beb_num); +void BebInfo_BebDstInfo(struct BebInfo* bebInfo, unsigned int beb_num); +int BebInfo_SetSerialAddress(struct BebInfo* bebInfo, unsigned int add); +int BebInfo_SetHeaderInfo(struct BebInfo* bebInfo, int ten_gig, char* src_mac, char* src_ip, unsigned int src_port);//src_port fixed 42000+beb_number or 52000 + beb_number); +unsigned int BebInfo_GetBebNumber(struct BebInfo* bebInfo); +unsigned int BebInfo_GetSerialAddress(struct BebInfo* bebInfo); +char* BebInfo_GetSrcMAC(struct BebInfo* bebInfo, int ten_gig); +char* BebInfo_GetSrcIP(struct BebInfo* bebInfo, int ten_gig); +unsigned int BebInfo_GetSrcPort(struct BebInfo* bebInfo, int ten_gig); +void BebInfo_Print(struct BebInfo* bebInfo); +void Beb_ClearBebInfos(); +int Beb_InitBebInfos(); +int Beb_CheckSourceStuffBebInfo(); +unsigned int Beb_GetBebInfoIndex(unsigned int beb_numb); +void Beb_GetModuleConfiguration(int* master, int* top, int* normal); +void Beb_EndofDataSend(int tengiga); - void Beb_ClearBebInfos(); - int Beb_InitBebInfos(); - int Beb_CheckSourceStuffBebInfo(); - unsigned int Beb_GetBebInfoIndex(unsigned int beb_numb); +int Beb_SetMasterViaSoftware(); +int Beb_SetSlaveViaSoftware(); +int Beb_Activate(int enable); +int Beb_Set32bitOverflow(int val); +int Beb_SetNetworkParameter(enum NETWORKINDEX mode, int val); +int Beb_ResetToHardwareSettings(); +u_int32_t Beb_GetFirmwareRevision(); +u_int32_t Beb_GetFirmwareSoftwareAPIVersion(); +void Beb_ResetFrameNumber(); +int Beb_WriteTo(unsigned int index); +int Beb_SetMAC(char* mac, uint8_t* dst_ptr); +int Beb_SetIP(char* ip, uint8_t* dst_ptr); +int Beb_SetPortNumber(unsigned int port_number, uint8_t* dst_ptr); +void Beb_AdjustIPChecksum(struct udp_header_type *ip); + +int Beb_SetHeaderData(unsigned int beb_number, int ten_gig, char* dst_mac, char* dst_ip, unsigned int 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); + +void Beb_SwapDataFun(int little_endian, unsigned int n, unsigned int *d); +int Beb_SetByteOrder(); +void Beb_Beb(); +int Beb_SetBebSrcHeaderInfos(unsigned int beb_number, int ten_gig, char* src_mac, char* src_ip, unsigned int src_port); +int Beb_SetUpUDPHeader(unsigned int beb_number, int ten_gig, unsigned int header_number, char* dst_mac, char* dst_ip, unsigned int dst_port); + +/*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=1);*/ +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); + +int Beb_StopAcquisition(); +int Beb_SetUpTransferParameters(short the_bit_mode); +/*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=0); //all images go to the same destination!*/ +int Beb_RequestNImages(unsigned int beb_number, int ten_gig, unsigned int dst_number, unsigned int nimages, int test_just_send_out_packets_no_wait); + +int Beb_Test(unsigned int beb_number); + +int Beb_GetBebFPGATemp(); + +void Beb_SetDetectorNumber(uint32_t detid); +int Beb_SetDetectorPosition(int pos[]); + +uint16_t Beb_swap_uint16( uint16_t val); +int Beb_open(u_int32_t** csp0base, u_int32_t offset); +u_int32_t Beb_Read32 (u_int32_t* baseaddr, u_int32_t offset); +u_int32_t Beb_Write32 (u_int32_t* baseaddr, u_int32_t offset, u_int32_t data); +void Beb_close(int fd,u_int32_t* csp0base); - void Beb_GetModuleConfiguration(int* master, int* top, int* normal); - void Beb_EndofDataSend(int tengiga); - - int Beb_SetMasterViaSoftware(); - int Beb_SetSlaveViaSoftware(); - int Beb_Activate(int enable); - int Beb_Set32bitOverflow(int val); - int Beb_SetNetworkParameter(enum NETWORKINDEX mode, int val); - int Beb_ResetToHardwareSettings(); - u_int32_t Beb_GetFirmwareRevision(); - u_int32_t Beb_GetFirmwareSoftwareAPIVersion(); - void Beb_ResetFrameNumber(); - - int Beb_WriteTo(unsigned int index); - - int Beb_SetMAC(char* mac, uint8_t* dst_ptr); - int Beb_SetIP(char* ip, uint8_t* dst_ptr); - int Beb_SetPortNumber(unsigned int port_number, uint8_t* dst_ptr); - void Beb_AdjustIPChecksum(struct udp_header_type *ip); - - int Beb_SetHeaderData(unsigned int beb_number, int ten_gig, char* dst_mac, char* dst_ip, unsigned int 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); - - void Beb_SwapDataFun(int little_endian, unsigned int n, unsigned int *d); - int Beb_SetByteOrder(); - - - void Beb_Beb(); - - - int Beb_SetBebSrcHeaderInfos(unsigned int beb_number, int ten_gig, char* src_mac, char* src_ip, unsigned int src_port); - int Beb_SetUpUDPHeader(unsigned int beb_number, int ten_gig, unsigned int header_number, char* dst_mac, char* dst_ip, unsigned int dst_port); - - /*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=1);*/ - 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); - - int Beb_StopAcquisition(); - int Beb_SetUpTransferParameters(short the_bit_mode); - /*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=0); //all images go to the same destination!*/ - int Beb_RequestNImages(unsigned int beb_number, int ten_gig, unsigned int dst_number, unsigned int nimages, int test_just_send_out_packets_no_wait); - - int Beb_Test(unsigned int beb_number); - - int Beb_GetBebFPGATemp(); - - void Beb_SetDetectorNumber(uint32_t detid); - int Beb_SetDetectorPosition(int pos[]); - - uint16_t Beb_swap_uint16( uint16_t val); - int Beb_open(u_int32_t** csp0base, u_int32_t offset); - u_int32_t Beb_Read32 (u_int32_t* baseaddr, u_int32_t offset); - u_int32_t Beb_Write32 (u_int32_t* baseaddr, u_int32_t offset, u_int32_t data); - void Beb_close(int fd,u_int32_t* csp0base); - -#endif - diff --git a/slsDetectorServers/eigerDetectorServer/FebControl.c b/slsDetectorServers/eigerDetectorServer/FebControl.c index aa63dbab7..7ee4fb6bc 100644 --- a/slsDetectorServers/eigerDetectorServer/FebControl.c +++ b/slsDetectorServers/eigerDetectorServer/FebControl.c @@ -1,10 +1,8 @@ - -/** - * @author Ian Johnson - * @version 1.0 - */ - - +#include "FebRegisterDefs.h" +#include "FebControl.h" +#include "Beb.h" +#include "slsDetectorServer_defs.h" +#include "logger.h" #include #include @@ -14,18 +12,14 @@ #include #include // POSIX terminal control definitions(CS8, CREAD, CLOCAL..) #include - -#include "FebRegisterDefs.h" -#include "FebControl.h" -#include "Beb.h" -#include "slsDetectorServer_defs.h" +#include +#include - -//GetDAQStatusRegister(512,current_mode_bits_from_fpga)){ +//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"};; +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"}; @@ -68,7 +62,7 @@ int Feb_Control_activated = 1; int Feb_Control_hv_fd = -1; -void Module_Module(struct Module* mod,unsigned int number, unsigned int address_top){ +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; @@ -86,7 +80,7 @@ void Module_Module(struct Module* mod,unsigned int number, unsigned int address_ } -void Module_ModuleBottom(struct Module* mod,unsigned int number, unsigned int address_bottom){ +void Module_ModuleBottom(struct Module* mod,unsigned int number, unsigned int address_bottom) { unsigned int i; mod->module_number = number; mod->top_address_valid = 0; @@ -108,7 +102,7 @@ void Module_ModuleBottom(struct Module* mod,unsigned int number, unsigned int ad -void Module_Module1(struct Module* mod,unsigned int number, unsigned int address_top, unsigned int address_bottom){ +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; @@ -154,23 +148,23 @@ int Module_GetBottomDACValue(struct Module* mod,unsigned int i) -void Feb_Control_activate(int activate){ +void Feb_Control_activate(int activate) { Feb_Control_activated = activate; } -int Feb_Control_IsBottomModule(){ - if(Module_BottomAddressIsValid(&modules[Feb_Control_current_index])) +int Feb_Control_IsBottomModule() { + if (Module_BottomAddressIsValid(&modules[Feb_Control_current_index])) return 1; return 0; } -int Feb_Control_GetModuleNumber(){ +int Feb_Control_GetModuleNumber() { return Feb_Control_module_number; } -void Feb_Control_FebControl(){ +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)); @@ -180,7 +174,7 @@ void Feb_Control_FebControl(){ -int Feb_Control_Init(int master, int top, int normal, int module_num){ +int Feb_Control_Init(int master, int top, int normal, int module_num) { unsigned int i; Feb_Control_module_number = 0; Feb_Control_current_index = 0; @@ -193,7 +187,7 @@ int Feb_Control_Init(int master, int top, int normal, int module_num){ Feb_Control_module_number = (module_num & 0xFF); int serial = !top; - printf("serial: %d\n",serial); + FILE_LOG(logDEBUG5, ("serial: %d\n",serial)); Feb_Control_current_index = 1; @@ -205,12 +199,12 @@ int Feb_Control_Init(int master, int top, int normal, int module_num){ unsigned int nfebs = 0; unsigned int* feb_list = malloc(moduleSize*4 * sizeof(unsigned int)); - for(i=1;i3){ - cprintf(RED,"Error SetIDelay chip_pos %d doesn't exist.\n",chip_pos);; + if (chip_pos>3) { + FILE_LOG(logERROR, ("SetIDelay chip_pos %d doesn't exist.\n",chip_pos)); return 0; } unsigned int module_index=0; - if(!Feb_Control_GetModuleIndex(module_num,&module_index)){ - cprintf(RED,"Error could not set i delay module number %d invalid.\n",module_num); + if (!Feb_Control_GetModuleIndex(module_num,&module_index)) { + FILE_LOG(logERROR, ("could not set i delay module number %d invalid.\n",module_num)); return 0; } int ok = 1; - if(chip_pos/2==0){ //left fpga - if(Module_TopAddressIsValid(&modules[module_index])){ - if(Feb_Control_SendIDelays(Module_GetTopLeftAddress(&modules[module_index]),chip_pos%2==0,0xffffffff,ndelay_units)){ - if(module_index!=0) Module_SetTopIDelay(&modules[module_index],chip_pos,ndelay_units); - else{ + 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; +int Feb_Control_SendIDelays(unsigned int dst_num, int chip_lr, unsigned int channels, unsigned int ndelay_units) { + if (ndelay_units>0x3ff) ndelay_units=0x3ff; // this is global unsigned int delay_data_valid_nclks = 15 - ((ndelay_units&0x3c0)>>6); //data valid delay upto 15 clks ndelay_units &= 0x3f; @@ -520,18 +525,19 @@ int Feb_Control_SendIDelays(unsigned int dst_num, int chip_lr, unsigned int chan 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); + FILE_LOG(logDEBUG5, ("\tSetting delays of %s chips of dst_num %d, " + "tracks 0x%x to %d, %d clks and %d units.\n", + ((set_left_delay_channels != 0) ? "left" : "right"), + dst_num, channels, (((15-delay_data_valid_nclks)<<6)|ndelay_units), + delay_data_valid_nclks, ndelay_units)); - if(Feb_Control_activated){ - if(!Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG2, 1<<31 | delay_data_valid_nclks<<16 | ndelay_units,0,0) || //the 1<<31 time enables the setting of the data valid delays + if (Feb_Control_activated) { + if (!Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG2, 1<<31 | delay_data_valid_nclks<<16 | ndelay_units,0,0) || //the 1<<31 time enables the setting of the data valid delays !Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG3,set_left_delay_channels,0,0) || !Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG4,set_right_delay_channels,0,0) || - !Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG_CTRL,CHIP_DATA_OUT_DELAY_SET,1,1)){ - cprintf(RED,"Warning: could not SetChipDataInputDelays(...).\n"); + !Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG_CTRL,CHIP_DATA_OUT_DELAY_SET,1,1)) { + FILE_LOG(logERROR, ("could not SetChipDataInputDelays(...).\n")); return 0; } } @@ -540,20 +546,20 @@ int Feb_Control_SendIDelays(unsigned int dst_num, int chip_lr, unsigned int chan } -int Feb_Control_VoltageToDAC(float value, unsigned int* digital,unsigned int nsteps,float vmin,float vmax){ - if(valuevmax) return 0; +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){ +float Feb_Control_DACToVoltage(unsigned int digital,unsigned int nsteps,float vmin,float vmax) { return vmin+(vmax-vmin)*digital/(nsteps-1); } //only master gets to call this function -int Feb_Control_SetHighVoltage(int value){ - printf(" Setting High Voltage:\t"); +int Feb_Control_SetHighVoltage(int value) { + FILE_LOG(logDEBUG5, (" Setting High Voltage:\t")); /* * maximum voltage of the hv dc/dc converter: * 300 for single module power distribution board @@ -562,7 +568,7 @@ int Feb_Control_SetHighVoltage(int value){ */ const float vmin=0; float vmax=200; - if(Feb_control_normal) + if (Feb_control_normal) vmax=300; const float vlimit=200; const unsigned int ntotalsteps = 256; @@ -570,21 +576,22 @@ int Feb_Control_SetHighVoltage(int value){ unsigned int dacval = 0; //calculate dac value - if(!Feb_Control_VoltageToDAC(value,&dacval,nsteps,vmin,vlimit)){ - cprintf(RED,"\nWarning: SetHighVoltage bad value, %d. The range is 0 to %d V.\n",value, (int)vlimit); + if (!Feb_Control_VoltageToDAC(value,&dacval,nsteps,vmin,vlimit)) { + FILE_LOG(logERROR, ("SetHighVoltage bad value, %d. The range is 0 to %d V.\n",value, (int)vlimit)); return -1; } - printf("(%d dac):\t%dV\n", dacval, value); + FILE_LOG(logINFO, ("High Voltage set to %dV\n", value)); + FILE_LOG(logDEBUG5, ("High Voltage set to (%d dac):\t%dV\n", dacval, value)); return Feb_Control_SendHighVoltage(dacval); } -int Feb_Control_GetHighVoltage(int* value){ - printf(" Getting High Voltage:\t"); +int Feb_Control_GetHighVoltage(int* value) { + FILE_LOG(logDEBUG5, (" Getting High Voltage:\t")); unsigned int dacval = 0; - if(!Feb_Control_ReceiveHighVoltage(&dacval)) + if (!Feb_Control_ReceiveHighVoltage(&dacval)) return 0; //ok, convert dac to v @@ -596,25 +603,25 @@ int Feb_Control_GetHighVoltage(int* value){ */ const float vmin=0; float vmax=200; - if(Feb_control_normal) + if (Feb_control_normal) vmax=300; const float vlimit=200; const unsigned int ntotalsteps = 256; unsigned int nsteps = ntotalsteps*vlimit/vmax; *value = (int)(Feb_Control_DACToVoltage(dacval,nsteps,vmin,vlimit)+0.5); - printf("(%d dac)\t%dV\n", dacval, *value); - + FILE_LOG(logINFO, ("High Voltage read %dV\n", *value)); + FILE_LOG(logDEBUG5, ("High Voltage read (%d dac)\t%dV\n", dacval, *value)); return 1; } -int Feb_Control_SendHighVoltage(int dacvalue){ +int Feb_Control_SendHighVoltage(int dacvalue) { //normal - if(Feb_control_normal){ + if (Feb_control_normal) { //open file FILE* fd=fopen(NORMAL_HIGHVOLTAGE_OUTPUTPORT,"w"); - if(fd==NULL){ - cprintf(RED,"\nWarning: Could not open file for writing to set high voltage\n"); + if (fd==NULL) { + FILE_LOG(logERROR, ("Could not open file for writing to set high voltage\n")); return 0; } //convert to string, add 0 and write to file @@ -623,10 +630,10 @@ int Feb_Control_SendHighVoltage(int dacvalue){ } //9m - else{ + else { /*Feb_Control_OpenSerialCommunication();*/ - if (Feb_Control_hv_fd == -1){ - cprintf(RED,"\nWarning: High voltage serial communication not set up for 9m\n"); + if (Feb_Control_hv_fd == -1) { + FILE_LOG(logERROR, ("High voltage serial communication not set up for 9m\n")); return 0; } @@ -635,34 +642,34 @@ int Feb_Control_SendHighVoltage(int dacvalue){ buffer[SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE-1]='\n'; int n; sprintf(buffer,"p%d",dacvalue); - cprintf(GREEN,"Sending HV: '%s'\n",buffer); + FILE_LOG(logINFO, ("Sending HV: '%s'\n",buffer)); n = write(Feb_Control_hv_fd, buffer, SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); if (n < 0) { - cprintf(RED,"\nWarning: Error writing to i2c bus\n"); + FILE_LOG(logERROR, ("writing to i2c bus\n")); return 0; } #ifdef VERBOSEI - cprintf(GREEN,"Sent %d Bytes\n", n); + FILE_LOG(logINFO, ("Sent %d Bytes\n", n)); #endif //ok/fail memset(buffer,0,SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); buffer[SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE-1] = '\n'; n = read(Feb_Control_hv_fd, buffer, SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); if (n < 0) { - cprintf(RED,"\nWarning: Error reading from i2c bus\n"); + FILE_LOG(logERROR, ("reading from i2c bus\n")); return 0; } #ifdef VERBOSEI - cprintf(GREEN,"Received %d Bytes\n", n); + FILE_LOG(logINFO, ("Received %d Bytes\n", n)); #endif - cprintf(GREEN,"Received HV: '%s'\n",buffer); + FILE_LOG(logINFO, ("Received HV: '%s'\n",buffer)); fflush(stdout); /*Feb_Control_CloseSerialCommunication();*/ - if(buffer[0] != 's'){ - cprintf(RED,"\nError: Failed to set high voltage\n"); + if (buffer[0] != 's') { + FILE_LOG(logERROR, ("\nError: Failed to set high voltage\n")); return 0; } - cprintf(GREEN,"%s\n",buffer); + FILE_LOG(logINFO, ("%s\n",buffer)); } @@ -675,22 +682,22 @@ int Feb_Control_SendHighVoltage(int dacvalue){ -int Feb_Control_ReceiveHighVoltage(unsigned int* value){ +int Feb_Control_ReceiveHighVoltage(unsigned int* value) { //normal - if(Feb_control_normal){ + if (Feb_control_normal) { //open file FILE* fd=fopen(NORMAL_HIGHVOLTAGE_INPUTPORT,"r"); - if(fd==NULL){ - cprintf(RED,"\nWarning: Could not open file for writing to get high voltage\n"); + if (fd==NULL) { + FILE_LOG(logERROR, ("Could not open file for writing to get high voltage\n")); return 0; } //read, assigning line to null and readbytes to 0 then getline allocates initial buffer size_t readbytes=0; char* line=NULL; - if(getline(&line, &readbytes, fd) == -1){ - cprintf(RED,"\nWarning: could not read file to get high voltage\n"); + if (getline(&line, &readbytes, fd) == -1) { + FILE_LOG(logERROR, ("could not read file to get high voltage\n")); return 0; } //read again to read the updated value @@ -698,8 +705,8 @@ int Feb_Control_ReceiveHighVoltage(unsigned int* value){ free(line); readbytes=0; readbytes = getline(&line, &readbytes, fd); - if(readbytes == -1){ - cprintf(RED,"\nWarning: could not read file to get high voltage\n"); + if (readbytes == -1) { + FILE_LOG(logERROR, ("could not read file to get high voltage\n")); return 0; } // Remove the trailing 0 @@ -710,11 +717,11 @@ int Feb_Control_ReceiveHighVoltage(unsigned int* value){ //9m - else{ + else { /*Feb_Control_OpenSerialCommunication();*/ - if (Feb_Control_hv_fd == -1){ - cprintf(RED,"\nWarning: High voltage serial communication not set up for 9m\n"); + if (Feb_Control_hv_fd == -1) { + FILE_LOG(logERROR, ("High voltage serial communication not set up for 9m\n")); return 0; } char buffer[SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE]; @@ -723,14 +730,14 @@ int Feb_Control_ReceiveHighVoltage(unsigned int* value){ //request strcpy(buffer,"g "); - cprintf(GREEN,"\nSending HV: '%s'\n",buffer); + FILE_LOG(logINFO, ("\nSending HV: '%s'\n",buffer)); n = write(Feb_Control_hv_fd, buffer, SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); if (n < 0) { - cprintf(RED,"\nWarning: Error writing to i2c bus\n"); + FILE_LOG(logERROR, ("writing to i2c bus\n")); return 0; } #ifdef VERBOSEI - cprintf(GREEN,"Sent %d Bytes\n", n); + FILE_LOG(logINFO, ("Sent %d Bytes\n", n)); #endif //ok/fail @@ -738,15 +745,15 @@ int Feb_Control_ReceiveHighVoltage(unsigned int* value){ buffer[SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE-1] = '\n'; n = read(Feb_Control_hv_fd, buffer, SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); if (n < 0) { - cprintf(RED,"\nWarning: Error reading from i2c bus\n"); + FILE_LOG(logERROR, ("reading from i2c bus\n")); return 0; } #ifdef VERBOSEI - cprintf(GREEN,"Received %d Bytes\n", n); + FILE_LOG(logINFO, ("Received %d Bytes\n", n)); #endif - cprintf(GREEN,"Received HV: '%s'\n",buffer); - if(buffer[0] != 's'){ - cprintf(RED,"\nWarning: failed to read high voltage\n"); + FILE_LOG(logINFO, ("Received HV: '%s'\n",buffer)); + if (buffer[0] != 's') { + FILE_LOG(logERROR, ("failed to read high voltage\n")); return 0; } @@ -754,16 +761,16 @@ int Feb_Control_ReceiveHighVoltage(unsigned int* value){ buffer[SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE-1] = '\n'; n = read(Feb_Control_hv_fd, buffer, SPECIAL9M_HIGHVOLTAGE_BUFFERSIZE); if (n < 0) { - cprintf(RED,"\nWarning: Error reading from i2c bus\n"); + FILE_LOG(logERROR, ("reading from i2c bus\n")); return 0; } #ifdef VERBOSEI - cprintf(GREEN,"Received %d Bytes\n", n); + FILE_LOG(logINFO, ("Received %d Bytes\n", n)); #endif - cprintf(GREEN,"Received HV: '%s'\n",buffer); + FILE_LOG(logINFO, ("Received HV: '%s'\n",buffer)); /*Feb_Control_OpenSerialCommunication();*/ - if (!sscanf(buffer,"%d",value)){ - cprintf(RED,"\nWarning: failed to scan high voltage read\n"); + if (!sscanf(buffer,"%d",value)) { + FILE_LOG(logERROR, ("failed to scan high voltage read\n")); return 0; } } @@ -773,87 +780,87 @@ int Feb_Control_ReceiveHighVoltage(unsigned int* value){ -int Feb_Control_DecodeDACString(char* dac_str, unsigned int* module_index, int* top, int* bottom, unsigned int* dac_ch){ +int Feb_Control_DecodeDACString(char* dac_str, unsigned int* module_index, int* top, int* bottom, unsigned int* dac_ch) { char* local_s = dac_str; *module_index = Feb_Control_current_index; *top = 1;//make them both 1 instead of this *bottom = 1; - if(Module_BottomAddressIsValid(&modules[*module_index])) + if (Module_BottomAddressIsValid(&modules[*module_index])) *top=0; else *bottom=0; *dac_ch = 0; - if(!Feb_Control_GetDACNumber(local_s,dac_ch)){ - cprintf(RED,"Error in dac_name: %s (%s)\n",dac_str,local_s); + if (!Feb_Control_GetDACNumber(local_s,dac_ch)) { + FILE_LOG(logERROR, ("invalid dac_name: %s (%s)\n",dac_str,local_s)); return 0; } return 1; } -int Feb_Control_SetDAC(char* dac_str, int value, int is_a_voltage_mv){ +int Feb_Control_SetDAC(char* dac_str, int value, int is_a_voltage_mv) { unsigned int i; unsigned int module_index, dac_ch; int top, bottom; - if(!Feb_Control_DecodeDACString(dac_str,&module_index,&top,&bottom,&dac_ch)) return 0; + if (!Feb_Control_DecodeDACString(dac_str,&module_index,&top,&bottom,&dac_ch)) return 0; unsigned int v = value; - if(is_a_voltage_mv&&!Feb_Control_VoltageToDAC(value,&v,4096,0,2048)){ - cprintf(RED,"Warning: SetDac bad value, %d. The range is 0 to 2048 mV.\n",value); + if (is_a_voltage_mv&&!Feb_Control_VoltageToDAC(value,&v,4096,0,2048)) { + FILE_LOG(logERROR, ("SetDac bad value, %d. The range is 0 to 2048 mV.\n",value)); return 0; } - if(v<0||v>4095){ - cprintf(RED,"Warning: SetDac bad value, %d. The range is 0 to 4095.\n",v); + if (v<0||v>4095) { + FILE_LOG(logERROR, ("SetDac bad value, %d. The range is 0 to 4095.\n",v)); return 0; } - if(top&&Module_TopAddressIsValid(&modules[module_index])){ + if (top&&Module_TopAddressIsValid(&modules[module_index])) { - if(!Feb_Control_SendDACValue(Module_GetTopRightAddress(&modules[module_index]),dac_ch,&v)) return 0; + 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); + if (module_index!=0) Module_SetTopDACValue(&modules[module_index],dac_ch,v); else for(i=0;i=Module_ndacs){ - cprintf(RED,"Warning: GetDACName index out of range, %d invalid.\n",dac_num); +int Feb_Control_GetDACName(unsigned int dac_num, char* s) { + if (dac_num>=Module_ndacs) { + FILE_LOG(logERROR, ("GetDACName index out of range, %d invalid.\n",dac_num)); return 0; } strcpy(s,Module_dac_names[dac_num]); return 1; } -int Feb_Control_GetDACNumber(char* s, unsigned int* n){ +int Feb_Control_GetDACNumber(char* s, unsigned int* n) { unsigned int i; - for(i=0;i15){ - cprintf(RED,"Warning invalid ch for SetDAC.\n"); + if (ch<0||ch>15) { + FILE_LOG(logERROR, ("invalid ch for SetDAC.\n")); return 0; } - //if(voltage<0) return PowerDownDAC(socket_num,ch); + //if (voltage<0) return PowerDownDAC(socket_num,ch); *value&=0xfff; unsigned int dac_ic = (ch<8) ? 1:2; @@ -878,73 +885,72 @@ int Feb_Control_SendDACValue(unsigned int dst_num, unsigned int ch, unsigned int unsigned int r = dac_ic<<30 | 3<<16 | dac_ch<<12 | *value; //3 write and power up - if(Feb_Control_activated){ - if(!Feb_Interface_WriteRegister(dst_num,0,r,1,0)){ - cprintf(RED,"Warning: trouble setting dac %d voltage.\n",ch); + if (Feb_Control_activated) { + if (!Feb_Interface_WriteRegister(dst_num,0,r,1,0)) { + FILE_LOG(logERROR, ("trouble setting dac %d voltage.\n",ch)); return 0; } } float voltage=Feb_Control_DACToVoltage(*value,4096,0,2048); - printf("\tDac number %d (%s) of dst %d set to %d (%f mV).\n",ch,Module_dac_names[ch],dst_num,*value,voltage); + FILE_LOG(logINFO, ("%s set to %d (%.2fmV)\n", Module_dac_names[ch],*value,voltage)); + FILE_LOG(logDEBUG5, ("Dac number %d (%s) of dst %d set to %d (%f mV)\n",ch,Module_dac_names[ch],dst_num,*value,voltage)); return 1; } -int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits){ - printf("Setting Trimbits\n"); +int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits) { + FILE_LOG(logINFO, ("Setting Trimbits\n")); //for (int iy=10000;iy<20020;++iy)//263681 //for (int iy=263670;iy<263680;++iy)//263681 - // printf("%d:%c\t\t",iy,trimbits[iy]); + // FILE_LOG(logINFO, ("%d:%c\t\t",iy,trimbits[iy])); unsigned int trimbits_to_load_l[1024]; unsigned int trimbits_to_load_r[1024]; unsigned int module_index=0; - if(!Feb_Control_GetModuleIndex(module_num,&module_index)){ - cprintf(RED,"Warning could not set trimbits, bad module number.\n"); + if (!Feb_Control_GetModuleIndex(module_num,&module_index)) { + FILE_LOG(logERROR, ("could not set trimbits, bad module number.\n")); return 0; } - if(Feb_Control_Reset() == STATUS_ERROR) cprintf(RED,"Warning could not reset DAQ.\n"); - int l_r; //printf("222\n"); - for(l_r=0;l_r<2;l_r++){ // l_r loop - //printf("\nl_r:%d\t\t",l_r); + if (Feb_Control_Reset() == STATUS_ERROR) { + FILE_LOG(logERROR, ("could not reset DAQ.\n")); + } + int l_r; + for(l_r=0;l_r<2;l_r++) { // l_r loop unsigned int disable_chip_mask = l_r ? DAQ_CS_BAR_LEFT : DAQ_CS_BAR_RIGHT; - if(Feb_Control_activated){ - if(!(Feb_Interface_WriteRegister(0xfff,DAQ_REG_STATIC_BITS,disable_chip_mask|DAQ_STATIC_BIT_PROGRAM|DAQ_STATIC_BIT_M8,0,0) + if (Feb_Control_activated) { + if (!(Feb_Interface_WriteRegister(0xfff,DAQ_REG_STATIC_BITS,disable_chip_mask|DAQ_STATIC_BIT_PROGRAM|DAQ_STATIC_BIT_M8,0,0) &&Feb_Control_SetCommandRegister(DAQ_SET_STATIC_BIT) - &&(Feb_Control_StartDAQOnlyNWaitForFinish(5000) == STATUS_IDLE))){ - printf("Could not select chips\n"); + &&(Feb_Control_StartDAQOnlyNWaitForFinish(5000) == STATUS_IDLE))) { + FILE_LOG(logERROR, ("Could not select chips\n")); return 0; } } int row_set; - for(row_set=0;row_set<16;row_set++){ //16 rows at a time - //printf("row_set:%d\t\t",row_set); - if(row_set==0){ - if(!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY|DAQ_SEND_A_TOKEN_IN|DAQ_LOAD_16ROWS_OF_TRIMBITS)){ - cprintf(RED,"Warning: Could not Feb_Control_SetCommandRegister for loading trim bits.\n"); + for(row_set=0;row_set<16;row_set++) { //16 rows at a time + if (row_set==0) { + if (!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY|DAQ_SEND_A_TOKEN_IN|DAQ_LOAD_16ROWS_OF_TRIMBITS)) { + FILE_LOG(logERROR, ("Could not Feb_Control_SetCommandRegister for loading trim bits.\n")); return 0; } - }else{ - if(!Feb_Control_SetCommandRegister(DAQ_LOAD_16ROWS_OF_TRIMBITS)){ - cprintf(RED,"Warning: Could not Feb_Control_SetCommandRegister for loading trim bits.\n"); + } else { + if (!Feb_Control_SetCommandRegister(DAQ_LOAD_16ROWS_OF_TRIMBITS)) { + FILE_LOG(logERROR, ("Could not Feb_Control_SetCommandRegister for loading trim bits.\n")); return 0; } } int row; - for(row=0;row<16;row++){ //row loop - //printf("row:%d\t\t",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 - //printf("sc:%d\t\t",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; @@ -958,15 +964,14 @@ int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits){ trimbits_to_load_l[offset+chip_sc+32] = 0; trimbits_to_load_r[offset+chip_sc+32] = 0; int i; - for(i=0;i<8;i++){ // column loop i - //printf("i:%d\t\t",i); + for(i=0;i<8;i++) { // column loop i - if(Module_TopAddressIsValid(&modules[1])){ + if (Module_TopAddressIsValid(&modules[1])) { trimbits_to_load_l[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_l+i])<<((7-i)*4);//low trimbits_to_load_l[offset+chip_sc+32] |= ((0x38 & trimbits[row_set*16480+super_column_start_position_l+i])>>3)<<((7-i)*4);//upper trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_r+i])<<((7-i)*4);//low trimbits_to_load_r[offset+chip_sc+32] |= ((0x38 & trimbits[row_set*16480+super_column_start_position_r+i])>>3)<<((7-i)*4);//upper - }else{ + } else { trimbits_to_load_l[offset+chip_sc] |= ( 0x7 & trimbits[263679 - (row_set*16480+super_column_start_position_l+i)])<<((7-i)*4);//low trimbits_to_load_l[offset+chip_sc+32] |= ((0x38 & trimbits[263679 - (row_set*16480+super_column_start_position_l+i)])>>3)<<((7-i)*4);//upper trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[263679 - (row_set*16480+super_column_start_position_r+i)])<<((7-i)*4);//low @@ -977,25 +982,25 @@ int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits){ } //end supercolumn loop sc } //end row loop - if(Module_TopAddressIsValid(&modules[1])){ - if(Feb_Control_activated){ - if(!Feb_Interface_WriteMemoryInLoops(Module_GetTopLeftAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_l)|| + if (Module_TopAddressIsValid(&modules[1])) { + if (Feb_Control_activated) { + if (!Feb_Interface_WriteMemoryInLoops(Module_GetTopLeftAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_l)|| !Feb_Interface_WriteMemoryInLoops(Module_GetTopRightAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_r)|| - //if(!Feb_Interface_WriteMemory(Module_GetTopLeftAddress(&modules[0]),0,0,1023,trimbits_to_load_r)|| + //if (!Feb_Interface_WriteMemory(Module_GetTopLeftAddress(&modules[0]),0,0,1023,trimbits_to_load_r)|| // !Feb_Interface_WriteMemory(Module_GetTopRightAddress(&modules[0]),0,0,1023,trimbits_to_load_l)|| - (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)){ - printf(" some errror!\n"); + (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { + FILE_LOG(logERROR, (" some errror!\n")); return 0; } } - }else{ - if(Feb_Control_activated){ - if(!Feb_Interface_WriteMemoryInLoops(Module_GetBottomLeftAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_l)|| + } else { + if (Feb_Control_activated) { + if (!Feb_Interface_WriteMemoryInLoops(Module_GetBottomLeftAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_l)|| !Feb_Interface_WriteMemoryInLoops(Module_GetBottomRightAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_r)|| - //if(!Feb_Interface_WriteMemory(Module_GetTopLeftAddress(&modules[0]),0,0,1023,trimbits_to_load_r)|| + //if (!Feb_Interface_WriteMemory(Module_GetTopLeftAddress(&modules[0]),0,0,1023,trimbits_to_load_r)|| // !Feb_Interface_WriteMemory(Module_GetTopRightAddress(&modules[0]),0,0,1023,trimbits_to_load_l)|| - (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)){ - printf(" some errror!\n"); + (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { + FILE_LOG(logERROR, (" some errror!\n")); return 0; } } @@ -1010,47 +1015,46 @@ int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits){ } -unsigned int* Feb_Control_GetTrimbits(){ +unsigned int* Feb_Control_GetTrimbits() { return Feb_Control_last_downloaded_trimbits; } -unsigned int Feb_Control_AddressToAll(){printf("in Feb_Control_AddressToAll()\n"); +unsigned int Feb_Control_AddressToAll() { + FILE_LOG(logINFO, ("in Feb_Control_AddressToAll()\n")); -if(moduleSize==0) return 0; + if (moduleSize==0) return 0; -if(Module_BottomAddressIsValid(&modules[1])){ - //printf("************* bottom\n"); - //if(Feb_Control_am_i_master) - return Module_GetBottomLeftAddress(&modules[1])|Module_GetBottomRightAddress(&modules[1]); - // else return 0; -} -// printf("************* top\n"); + if (Module_BottomAddressIsValid(&modules[1])) { + //if (Feb_Control_am_i_master) + return Module_GetBottomLeftAddress(&modules[1])|Module_GetBottomRightAddress(&modules[1]); + // else return 0; + } -return Module_GetTopLeftAddress(&modules[1])|Module_GetTopRightAddress(&modules[1]); -//return Module_GetTopLeftAddress(&modules[0])|Module_GetTopRightAddress(&modules[0]); + return Module_GetTopLeftAddress(&modules[1])|Module_GetTopRightAddress(&modules[1]); + //return Module_GetTopLeftAddress(&modules[0])|Module_GetTopRightAddress(&modules[0]); } -int Feb_Control_SetCommandRegister(unsigned int cmd){ - if(Feb_Control_activated) +int Feb_Control_SetCommandRegister(unsigned int cmd) { + if (Feb_Control_activated) return Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CHIP_CMDS,cmd,0,0); else return 1; } -int Feb_Control_GetDAQStatusRegister(unsigned int dst_address, unsigned int* ret_status){ +int Feb_Control_GetDAQStatusRegister(unsigned int dst_address, unsigned int* ret_status) { //if deactivated, should be handled earlier and should not get into this function - if(Feb_Control_activated){ - if(!Feb_Interface_ReadRegister(dst_address,DAQ_REG_STATUS,ret_status)){ - cprintf(RED,"Error: reading status register.\n"); + if (Feb_Control_activated) { + if (!Feb_Interface_ReadRegister(dst_address,DAQ_REG_STATUS,ret_status)) { + FILE_LOG(logERROR, ("Error: reading status register.\n")); return 0; } } @@ -1060,10 +1064,10 @@ int Feb_Control_GetDAQStatusRegister(unsigned int dst_address, unsigned int* ret } -int Feb_Control_StartDAQOnlyNWaitForFinish(int sleep_time_us){ - if(Feb_Control_activated){ - if(!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0)||!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_START,0,0)){ - cprintf(RED,"Warning: could not start.\n"); +int Feb_Control_StartDAQOnlyNWaitForFinish(int sleep_time_us) { + if (Feb_Control_activated) { + if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0)||!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_START,0,0)) { + FILE_LOG(logERROR, ("could not start.\n")); return 0; } } @@ -1071,30 +1075,31 @@ int Feb_Control_StartDAQOnlyNWaitForFinish(int sleep_time_us){ } -int Feb_Control_AcquisitionInProgress(){ +int Feb_Control_AcquisitionInProgress() { unsigned int status_reg_r=0,status_reg_l=0; //deactivated should return end of acquisition - if(!Feb_Control_activated) + if (!Feb_Control_activated) return STATUS_IDLE; int ind = Feb_Control_current_index; - if(Module_BottomAddressIsValid(&modules[ind])){ + if (Module_BottomAddressIsValid(&modules[ind])) { - if(!(Feb_Control_GetDAQStatusRegister(Module_GetBottomRightAddress(&modules[ind]),&status_reg_r))) - {cprintf(RED,"Error: Trouble reading Status register. bottom right address\n");return STATUS_ERROR;} - if(!(Feb_Control_GetDAQStatusRegister(Module_GetBottomLeftAddress(&modules[ind]),&status_reg_l))) - {cprintf(RED,"Error: Trouble reading Status register. bottom left address\n");return STATUS_ERROR;} + if (!(Feb_Control_GetDAQStatusRegister(Module_GetBottomRightAddress(&modules[ind]),&status_reg_r))) + {FILE_LOG(logERROR, ("Error: Trouble reading Status register. bottom right address\n"));return STATUS_ERROR;} + if (!(Feb_Control_GetDAQStatusRegister(Module_GetBottomLeftAddress(&modules[ind]),&status_reg_l))) + {FILE_LOG(logERROR, ("Error: Trouble reading Status register. bottom left address\n"));return STATUS_ERROR;} - }else{ - if(!(Feb_Control_GetDAQStatusRegister(Module_GetTopRightAddress(&modules[ind]),&status_reg_r))) - {cprintf(RED,"Error: Trouble reading Status register. top right address\n");return STATUS_ERROR;} - if(!(Feb_Control_GetDAQStatusRegister(Module_GetTopLeftAddress(&modules[ind]),&status_reg_l))) - {cprintf(RED,"Error: Trouble reading Status register. top left address\n");return STATUS_ERROR;} + } else { + if (!(Feb_Control_GetDAQStatusRegister(Module_GetTopRightAddress(&modules[ind]),&status_reg_r))) + {FILE_LOG(logERROR, ("Error: Trouble reading Status register. top right address\n"));return STATUS_ERROR;} + if (!(Feb_Control_GetDAQStatusRegister(Module_GetTopLeftAddress(&modules[ind]),&status_reg_l))) + {FILE_LOG(logERROR, ("Error: Trouble reading Status register. top left address\n"));return STATUS_ERROR;} } //running - if((status_reg_r|status_reg_l)&DAQ_STATUS_DAQ_RUNNING) {/*printf("**runningggg\n");*/ + if ((status_reg_r|status_reg_l)&DAQ_STATUS_DAQ_RUNNING) { + FILE_LOG(logDEBUG5, ("**runningggg\n")); return STATUS_RUNNING; } //idle @@ -1102,30 +1107,30 @@ int Feb_Control_AcquisitionInProgress(){ } -int Feb_Control_AcquisitionStartedBit(){ +int Feb_Control_AcquisitionStartedBit() { unsigned int status_reg_r=0,status_reg_l=0; //deactivated should return acquisition started/ready - if(!Feb_Control_activated) + if (!Feb_Control_activated) return 1; int ind = Feb_Control_current_index; - if(Module_BottomAddressIsValid(&modules[ind])){ + if (Module_BottomAddressIsValid(&modules[ind])) { - if(!(Feb_Control_GetDAQStatusRegister(Module_GetBottomRightAddress(&modules[ind]),&status_reg_r))) - {cprintf(RED,"Error: Trouble reading Status register. bottom right address\n");return -1;} - if(!(Feb_Control_GetDAQStatusRegister(Module_GetBottomLeftAddress(&modules[ind]),&status_reg_l))) - {cprintf(RED,"Error: Trouble reading Status register. bottom left address\n");return -1;} + if (!(Feb_Control_GetDAQStatusRegister(Module_GetBottomRightAddress(&modules[ind]),&status_reg_r))) + {FILE_LOG(logERROR, ("Error: Trouble reading Status register. bottom right address\n"));return -1;} + if (!(Feb_Control_GetDAQStatusRegister(Module_GetBottomLeftAddress(&modules[ind]),&status_reg_l))) + {FILE_LOG(logERROR, ("Error: Trouble reading Status register. bottom left address\n"));return -1;} - }else{ - if(!(Feb_Control_GetDAQStatusRegister(Module_GetTopRightAddress(&modules[ind]),&status_reg_r))) - {cprintf(RED,"Error: Trouble reading Status register. top right address\n"); return -1;} - if(!(Feb_Control_GetDAQStatusRegister(Module_GetTopLeftAddress(&modules[ind]),&status_reg_l))) - {cprintf(RED,"Error: Trouble reading Status register. top left address\n");return -1;} + } else { + if (!(Feb_Control_GetDAQStatusRegister(Module_GetTopRightAddress(&modules[ind]),&status_reg_r))) + {FILE_LOG(logERROR, ("Error: Trouble reading Status register. top right address\n")); return -1;} + if (!(Feb_Control_GetDAQStatusRegister(Module_GetTopLeftAddress(&modules[ind]),&status_reg_l))) + {FILE_LOG(logERROR, ("Error: Trouble reading Status register. top left address\n"));return -1;} } //doesnt mean it started, just the bit - if((status_reg_r|status_reg_l)&DAQ_STATUS_DAQ_RUN_TOGGLE) + if ((status_reg_r|status_reg_l)&DAQ_STATUS_DAQ_RUN_TOGGLE) return 1; return 0; @@ -1133,13 +1138,13 @@ int Feb_Control_AcquisitionStartedBit(){ -int Feb_Control_WaitForFinishedFlag(int sleep_time_us){ +int Feb_Control_WaitForFinishedFlag(int sleep_time_us) { int is_running = Feb_Control_AcquisitionInProgress(); int check_error = 0; // it will break out if it is idle or if check_error is more than 5 times - while(is_running != STATUS_IDLE){ + while(is_running != STATUS_IDLE) { usleep(sleep_time_us); is_running = Feb_Control_AcquisitionInProgress(); @@ -1157,35 +1162,35 @@ int Feb_Control_WaitForFinishedFlag(int sleep_time_us){ } -int Feb_Control_WaitForStartedFlag(int sleep_time_us, int prev_flag){ +int Feb_Control_WaitForStartedFlag(int sleep_time_us, int prev_flag) { //deactivated dont wait (otherwise give a toggle value back) - if(!Feb_Control_activated) + if (!Feb_Control_activated) return 1; //did not start - if(prev_flag == -1) + if (prev_flag == -1) return 0; int value = prev_flag; - while(value == prev_flag){ + while(value == prev_flag) { usleep(sleep_time_us); value = Feb_Control_AcquisitionStartedBit(); } //did not start - if(value == -1) + if (value == -1) return 0; return 1; } -int Feb_Control_Reset(){ - printf("Reset daq\n"); - if(Feb_Control_activated){ - if(!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_RESET,0,0) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0)){ - cprintf(RED,"Warning: Could not reset daq, no response.\n"); +int Feb_Control_Reset() { + FILE_LOG(logINFO, ("Reset daq\n")); + if (Feb_Control_activated) { + if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_RESET,0,0) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0)) { + FILE_LOG(logERROR, ("Could not reset daq, no response.\n")); return 0; } } @@ -1196,278 +1201,280 @@ int Feb_Control_Reset(){ -int Feb_Control_SetStaticBits(){ - if(Feb_Control_activated){ +int Feb_Control_SetStaticBits() { + if (Feb_Control_activated) { //program=1,m4=2,m8=4,test=8,rotest=16,cs_bar_left=32,cs_bar_right=64 - if(!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_STATIC_BITS,Feb_Control_staticBits,0,0) || + if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_STATIC_BITS,Feb_Control_staticBits,0,0) || !Feb_Control_SetCommandRegister(DAQ_SET_STATIC_BIT) || - (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)){ - cprintf(RED,"Warning: Could not set static bits\n"); + (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { + FILE_LOG(logERROR, ("Could not set static bits\n")); return 0; } } return 1; } -int Feb_Control_SetStaticBits1(unsigned int the_static_bits){ +int Feb_Control_SetStaticBits1(unsigned int the_static_bits) { Feb_Control_staticBits = the_static_bits; return Feb_Control_SetStaticBits(); } -int Feb_Control_SetInTestModeVariable(int on){ - if(on) Feb_Control_staticBits |= DAQ_STATIC_BIT_CHIP_TEST; //setting test bit to high +int Feb_Control_SetInTestModeVariable(int on) { + if (on) Feb_Control_staticBits |= DAQ_STATIC_BIT_CHIP_TEST; //setting test bit to high else Feb_Control_staticBits &= (~DAQ_STATIC_BIT_CHIP_TEST); //setting test bit to low return 1; } -int Feb_Control_GetTestModeVariable(){ +int Feb_Control_GetTestModeVariable() { return Feb_Control_staticBits&DAQ_STATIC_BIT_CHIP_TEST; } -int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo){ +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){ + 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){ + } 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){ + } 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){ + } 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{ - cprintf(RED,"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"); + } else { + FILE_LOG(logERROR, ("dynamic range (%d) not valid, not setting bit mode.\n",four_eight_sixteen_or_thirtytwo)); + FILE_LOG(logINFO, ("Set dynamic range int must equal 4,8 16, or 32.\n")); return 0; } - printf("Dynamic range set to: %d\n",four_eight_sixteen_or_thirtytwo); + FILE_LOG(logINFO, ("Dynamic range set to %d\n",four_eight_sixteen_or_thirtytwo)); return 1; } -unsigned int Feb_Control_GetDynamicRange(){ - if(Feb_Control_subFrameMode&DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING) return 32; - else if(DAQ_STATIC_BIT_M4&Feb_Control_staticBits) return 4; - else if(DAQ_STATIC_BIT_M8&Feb_Control_staticBits) return 8; +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 +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){ + 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){ + FILE_LOG(logINFO, ("Speed set to half speed (50 MHz)\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){ + FILE_LOG(logINFO, ("Speed set to quarter speed (25 MHz)\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){ - cprintf(RED,"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"); + FILE_LOG(logINFO, ("Speed set to super slow speed (~0.200 MHz)\n")); + } else { + if (readout_speed) { + FILE_LOG(logERROR, ("readout speed %d unknown, defaulting to full speed.\n",readout_speed)); + FILE_LOG(logINFO, ("full speed, (100 MHz)\n")); return 0; } - printf("Everything at full speed, ie. reading with 100 MHz main clk (full speed) ....\n"); + FILE_LOG(logINFO, ("Speed set to full speed (100 MHz)\n")); } return 1; } -int Feb_Control_SetReadoutMode(unsigned int readout_mode){ //0->parallel,1->non-parallel,2-> safe_mode +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){ + 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){ + FILE_LOG(logINFO, ("Readout mode set to Non Parallel\n")); + } else if (readout_mode==2) { Feb_Control_acquireNReadoutMode |= DAQ_NEXPOSURERS_SAFEST_MODE_ROW_CLK_BEFORE_MODE; - printf("Readout mode set to safest mode, row clk before main clk readout sequence .... \n");; - }else{ + FILE_LOG(logINFO, ("Readout mode set to Safe (row clk before main clk readout sequence)\n")); + } else { Feb_Control_acquireNReadoutMode |= DAQ_NEXPOSURERS_PARALLEL_MODE; - if(readout_mode){ - cprintf(RED,"Warning readout mode %d) unknown, defaulting to full speed.\n",readout_mode); - printf("Readout mode set to parrallel acquire/read mode .... \n");; + if (readout_mode) { + FILE_LOG(logERROR, ("readout mode %d) unknown, defaulting to parallel readout.\n",readout_mode)); + FILE_LOG(logINFO, ("Readout mode set to Parallel\n")); return 0; } - printf("Readout mode set to parrallel acquire/read mode .... \n");; + FILE_LOG(logINFO, ("Readout mode set to Parallel\n")); } return 1; } -int Feb_Control_SetTriggerMode(unsigned int trigger_mode,int polarity){ +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){ + 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){ + FILE_LOG(logINFO, ("Trigger mode set to Burst Trigger\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){ + FILE_LOG(logINFO, ("Trigger mode set to Trigger Exposure\n")); + } else if (trigger_mode == 3) { Feb_Control_triggerMode = DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START_AND_STOP; - printf("Trigger mode: externally controlled, external image window (start and stop).\n");; - }else{ + FILE_LOG(logINFO, ("Trigger mode set to Gated\n")); + } else { Feb_Control_triggerMode = DAQ_NEXPOSURERS_INTERNAL_ACQUISITION; - if(trigger_mode) cprintf(RED,"Warning trigger %d) unknown, defaulting to internal triggering.\n",trigger_mode);; + if (trigger_mode) { + FILE_LOG(logERROR, ("trigger %d) unknown, defaulting to Auto\n",trigger_mode)); + } - printf("Trigger mode: acquisition internally controlled exposure length and period.\n");; + FILE_LOG(logINFO, ("Trigger mode set to Auto\n")); return trigger_mode==0; } - if(polarity){ + if (polarity) { Feb_Control_triggerMode |= DAQ_NEXPOSURERS_EXTERNAL_TRIGGER_POLARITY; - printf("External trigger polarity set to positive.\n");; - }else{ + FILE_LOG(logINFO, ("External trigger polarity set to positive\n")); + } else { Feb_Control_triggerMode &= (~DAQ_NEXPOSURERS_EXTERNAL_TRIGGER_POLARITY); - printf("External trigger polarity set to negitive.\n");; + FILE_LOG(logINFO, ("External trigger polarity set to negitive\n")); } return 1; } -int Feb_Control_SetExternalEnableMode(int use_external_enable, int polarity){ - if(use_external_enable){ +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){ + if (polarity) { Feb_Control_externalEnableMode |= DAQ_NEXPOSURERS_EXTERNAL_ENABLING_POLARITY; - printf(", polarity set to positive.\n");; - }else{ + } else { Feb_Control_externalEnableMode &= (~DAQ_NEXPOSURERS_EXTERNAL_ENABLING_POLARITY); - printf(", polarity set to negative.\n");; } - }else{ + FILE_LOG(logINFO, ("External enabling enabled, polarity set to %s\n", + (polarity ? "positive" : "negative"))); + + } else { Feb_Control_externalEnableMode = 0; /* changed by Dhanya according to old code &= (~DAQ_NEXPOSURERS_EXTERNAL_ENABLING);*/ - printf("External enabling disabled.\n");; + FILE_LOG(logINFO, ("External enabling disabled\n")); } return 1; } -int Feb_Control_SetNExposures(unsigned int n_images){ - if(!n_images){ - cprintf(RED,"Warning nimages must be greater than zero.%d\n",n_images); +int Feb_Control_SetNExposures(unsigned int n_images) { + if (!n_images) { + FILE_LOG(logERROR, ("nimages must be greater than zero.%d\n",n_images)); return 0; } Feb_Control_nimages = n_images; - printf("Number of images set to: %d\n",Feb_Control_nimages); + FILE_LOG(logINFO, ("Number of images set to %d\n",Feb_Control_nimages)); return 1; } -unsigned int Feb_Control_GetNExposures(){return Feb_Control_nimages;} +unsigned int Feb_Control_GetNExposures() {return Feb_Control_nimages;} -int Feb_Control_SetExposureTime(double the_exposure_time_in_sec){ +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: %fs\n",Feb_Control_exposure_time_in_sec); + FILE_LOG(logINFO, ("Exposure time set to %fs\n",Feb_Control_exposure_time_in_sec)); return 1; } -double Feb_Control_GetExposureTime(){return Feb_Control_exposure_time_in_sec;} -int64_t Feb_Control_GetExposureTime_in_nsec(){return (int64_t)(Feb_Control_exposure_time_in_sec*(1E9));} +double Feb_Control_GetExposureTime() {return Feb_Control_exposure_time_in_sec;} +int64_t Feb_Control_GetExposureTime_in_nsec() {return (int64_t)(Feb_Control_exposure_time_in_sec*(1E9));} -int Feb_Control_SetSubFrameExposureTime(int64_t the_subframe_exposure_time_in_10nsec){ +int Feb_Control_SetSubFrameExposureTime(int64_t the_subframe_exposure_time_in_10nsec) { Feb_Control_subframe_exposure_time_in_10nsec = the_subframe_exposure_time_in_10nsec; - printf("Sub Frame Exposure time set to: %lld\n",(long long int)Feb_Control_subframe_exposure_time_in_10nsec); + FILE_LOG(logINFO, ("Sub Frame Exposure time set to %lldns\n",(long long int)Feb_Control_subframe_exposure_time_in_10nsec * 10)); return 1; } -int64_t Feb_Control_GetSubFrameExposureTime(){return Feb_Control_subframe_exposure_time_in_10nsec*10;} +int64_t Feb_Control_GetSubFrameExposureTime() {return Feb_Control_subframe_exposure_time_in_10nsec*10;} -int Feb_Control_SetSubFramePeriod(int64_t the_subframe_period_in_10nsec){ +int Feb_Control_SetSubFramePeriod(int64_t the_subframe_period_in_10nsec) { Feb_Control_subframe_period_in_10nsec = the_subframe_period_in_10nsec; - printf("Sub Frame Period set to: %lld\n",(long long int)Feb_Control_subframe_period_in_10nsec); + FILE_LOG(logINFO, ("Sub Frame Period set to %lldns\n",(long long int)Feb_Control_subframe_period_in_10nsec * 10)); return 1; } -int64_t Feb_Control_GetSubFramePeriod(){return Feb_Control_subframe_period_in_10nsec*10;} +int64_t Feb_Control_GetSubFramePeriod() {return Feb_Control_subframe_period_in_10nsec*10;} -int Feb_Control_SetExposurePeriod(double the_exposure_period_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); + FILE_LOG(logINFO, ("Exposure period set to %fs\n",Feb_Control_exposure_period_in_sec)); return 1; } -double Feb_Control_GetExposurePeriod(){return Feb_Control_exposure_period_in_sec;} +double Feb_Control_GetExposurePeriod() {return Feb_Control_exposure_period_in_sec;} -unsigned int Feb_Control_ConvertTimeToRegister(float time_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)){ + if (n_clk_cycles>(pow(2,29)-1)*pow(10,7)) { float max_time = 10e-9*(pow(2,28)-1)*pow(10,7); - cprintf(RED,"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); + FILE_LOG(logERROR, ("time exceeds (%f) maximum exposure time of %f sec.\n",time_in_sec,max_time)); + FILE_LOG(logINFO, ("\t Setting to maximum %f us.\n",max_time)); decoded_time = 0xffffffff; - }else{ + } 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);} + while(n_clk_cycles>pow(2,29)-1) { power_of_ten++; n_clk_cycles = round(n_clk_cycles/10.0);} decoded_time = (int)(n_clk_cycles)<<3 | (int)(power_of_ten); } return decoded_time; } -int Feb_Control_ResetChipCompletely(){ - if(!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY) || (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)){ - cprintf(RED,"Warning: could not ResetChipCompletely() with 0x%x.\n",DAQ_RESET_COMPLETELY); +int Feb_Control_ResetChipCompletely() { + if (!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY) || (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { + FILE_LOG(logERROR, ("could not ResetChipCompletely() with 0x%x.\n",DAQ_RESET_COMPLETELY)); return 0; } - printf("Chip reset completely\n"); + FILE_LOG(logINFO, ("Chip reset completely\n")); return 1; } -int Feb_Control_ResetChipPartially(){ - if(!Feb_Control_SetCommandRegister(DAQ_RESET_PERIPHERY) || (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)){ - cprintf(RED,"Warning: could not ResetChipPartially with periphery\n"); +int Feb_Control_ResetChipPartially() { + if (!Feb_Control_SetCommandRegister(DAQ_RESET_PERIPHERY) || (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { + FILE_LOG(logERROR, ("could not ResetChipPartially with periphery\n")); return 0; } - printf("Chip reset periphery 0x%x\n",DAQ_RESET_PERIPHERY); + FILE_LOG(logINFO, ("Chip reset periphery 0x%x\n",DAQ_RESET_PERIPHERY)); - if(!Feb_Control_SetCommandRegister(DAQ_RESET_COLUMN_SELECT) || (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)){ - cprintf(RED,"Warning: could not ResetChipPartially with column select\n"); + if (!Feb_Control_SetCommandRegister(DAQ_RESET_COLUMN_SELECT) || (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { + FILE_LOG(logERROR, ("could not ResetChipPartially with column select\n")); return 0; } - printf("Chip reset column select 0x%x\n",DAQ_RESET_COLUMN_SELECT); + FILE_LOG(logINFO, ("Chip reset column select 0x%x\n",DAQ_RESET_COLUMN_SELECT)); return 1; } -void Feb_Control_PrintAcquisitionSetup(){ +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); + FILE_LOG(logINFO, ("\nStarting an exposure: %s",asctime(timeinfo))); + FILE_LOG(logINFO, ("\t Dynamic range nbits: %d\n",Feb_Control_GetDynamicRange())); + FILE_LOG(logINFO, ("\t Trigger mode: 0x%x\n",Feb_Control_triggerMode)); + FILE_LOG(logINFO, ("\t Number of exposures: %d\n",Feb_Control_GetNExposures())); + FILE_LOG(logINFO, ("\t Exsposure time (if used): %f seconds.\n",Feb_Control_exposure_time_in_sec)); + FILE_LOG(logINFO, ("\t Exsposure period (if used): %f seconds.\n\n\n",Feb_Control_exposure_period_in_sec)); } -int Feb_Control_SendBitModeToBebServer(){ +int Feb_Control_SendBitModeToBebServer() { unsigned int just_bit_mode = (DAQ_STATIC_BIT_M4|DAQ_STATIC_BIT_M8) & Feb_Control_staticBits; unsigned int bit_mode = 16; //default - if(just_bit_mode == DAQ_STATIC_BIT_M4) bit_mode = 4; - else if(just_bit_mode == DAQ_STATIC_BIT_M8) bit_mode = 8; - else if(Feb_Control_subFrameMode&DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING) bit_mode = 32; + if (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)){ - cprintf(RED,"Error: sending bit mode ...\n"); + if (!Beb_SetUpTransferParameters(bit_mode)) { + FILE_LOG(logERROR, ("Error: sending bit mode ...\n")); return 0; } @@ -1475,35 +1482,35 @@ int Feb_Control_SendBitModeToBebServer(){ } -int Feb_Control_PrepareForAcquisition(){//return 1; +int Feb_Control_PrepareForAcquisition() {//return 1; static unsigned int reg_nums[20]; static unsigned int reg_vals[20]; Feb_Control_PrintAcquisitionSetup(); - // if(!Reset()||!ResetDataStream()){ - if(Feb_Control_Reset() == STATUS_ERROR){ - printf("Trouble reseting daq or data stream...\n");; + // if (!Reset()||!ResetDataStream()) { + if (Feb_Control_Reset() == STATUS_ERROR) { + FILE_LOG(logERROR, ("Trouble reseting daq or data stream...\n")); return 0; } - if(!Feb_Control_SetStaticBits1(Feb_Control_staticBits&(DAQ_STATIC_BIT_M4|DAQ_STATIC_BIT_M8))){ - printf("Trouble setting static bits ...\n");; + if (!Feb_Control_SetStaticBits1(Feb_Control_staticBits&(DAQ_STATIC_BIT_M4|DAQ_STATIC_BIT_M8))) { + FILE_LOG(logERROR, ("Trouble setting static bits ...\n")); return 0; } - if(!Feb_Control_SendBitModeToBebServer()){ - printf("Trouble sending static bits to server ...\n");; + if (!Feb_Control_SendBitModeToBebServer()) { + FILE_LOG(logERROR, ("Trouble sending static bits to server ...\n")); return 0; } int ret=0; - if(Feb_Control_counter_bit) + if (Feb_Control_counter_bit) ret = Feb_Control_ResetChipCompletely(); else ret = Feb_Control_ResetChipPartially(); - if(!ret){ - printf("Trouble resetting chips ...\n");; + if (!ret) { + FILE_LOG(logERROR, ("Trouble resetting chips ...\n")); return 0; } @@ -1522,10 +1529,10 @@ int Feb_Control_PrepareForAcquisition(){//return 1; reg_vals[5]= Feb_Control_subframe_exposure_time_in_10nsec; //(1 means 10ns, 100 means 1000ns) reg_nums[6]=DAQ_REG_SUBFRAME_PERIOD; reg_vals[6]= Feb_Control_subframe_period_in_10nsec; //(1 means 10ns, 100 means 1000ns) - // if(!Feb_Interface_WriteRegisters((Module_GetTopLeftAddress(&modules[1])|Module_GetTopRightAddress(&modules[1])),20,reg_nums,reg_vals,0,0)){ - if(Feb_Control_activated){ - if(!Feb_Interface_WriteRegisters(Feb_Control_AddressToAll(),7,reg_nums,reg_vals,0,0)){ - printf("Trouble starting acquisition....\n");; + // if (!Feb_Interface_WriteRegisters((Module_GetTopLeftAddress(&modules[1])|Module_GetTopRightAddress(&modules[1])),20,reg_nums,reg_vals,0,0)) { + if (Feb_Control_activated) { + if (!Feb_Interface_WriteRegisters(Feb_Control_AddressToAll(),7,reg_nums,reg_vals,0,0)) { + FILE_LOG(logERROR, ("Trouble starting acquisition....\n")); return 0; } } @@ -1535,24 +1542,24 @@ int Feb_Control_PrepareForAcquisition(){//return 1; -int Feb_Control_StartAcquisition(){ - printf("****** starting acquisition********* \n"); +int Feb_Control_StartAcquisition() { + FILE_LOG(logINFO, ("****** starting acquisition********* \n")); static unsigned int reg_nums[20]; static unsigned int reg_vals[20]; int i; - for(i=0;i<14;i++){ + for(i=0;i<14;i++) { reg_nums[i]=DAQ_REG_CTRL; reg_vals[i]=0; } reg_nums[14]=DAQ_REG_CTRL; reg_vals[14]=ACQ_CTRL_START; - if(Feb_Control_activated){ - if(!Feb_Interface_WriteRegisters(Feb_Control_AddressToAll(),15,reg_nums,reg_vals,0,0)){ - cprintf(RED,"Trouble starting acquisition....\n");; + if (Feb_Control_activated) { + if (!Feb_Interface_WriteRegisters(Feb_Control_AddressToAll(),15,reg_nums,reg_vals,0,0)) { + FILE_LOG(logERROR, ("Trouble starting acquisition....\n")); return 0; } } @@ -1561,13 +1568,13 @@ int Feb_Control_StartAcquisition(){ return 1; } -int Feb_Control_StopAcquisition(){ +int Feb_Control_StopAcquisition() { return Feb_Control_Reset(); } -int Feb_Control_SaveAllTrimbitsTo(int value){ +int Feb_Control_SaveAllTrimbitsTo(int value) { unsigned int chanregs[Feb_Control_trimbit_size]; int i; for(i=0;i255||y<0||y>255){ - cprintf(RED,"Warning: Pixel out of range.\n"); + if (x<0||x>255||y<0||y>255) { + FILE_LOG(logERROR, ("Pixel out of range.\n")); return 0; } @@ -1609,17 +1616,17 @@ int Feb_Control_Pulse_Pixel(int npulses, int x, int y){ Feb_Control_SetStaticBits(); Feb_Control_SetCommandRegister(DAQ_RESET_PERIPHERY|DAQ_RESET_COLUMN_SELECT); if (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE) { - cprintf(RED,"Warning: could not pulse pixel as status not idle\n"); + FILE_LOG(logERROR, ("could not pulse pixel as status not idle\n")); return 0; } unsigned int serial_in = 8<<(4*(7-x%8)); - if(!Feb_Control_Shift32InSerialIn(serial_in)){ - cprintf(RED,"Warning ChipController::PulsePixel: could shift in the initail 32.\n"); + if (!Feb_Control_Shift32InSerialIn(serial_in)) { + FILE_LOG(logERROR, ("ChipController::PulsePixel: could shift in the initail 32.\n")); return 0; } - if(!pulse_multiple) + if (!pulse_multiple) serial_in=0; for(i=0;i1023){ - cprintf(RED,"Warning: Clock row clock ntimes (%d) exceeds the maximum value of 1023.\n\t Setting ntimes to 1023.\n",ntimes); +int Feb_Control_ClockRowClock(unsigned int ntimes) { + if (ntimes>1023) { + FILE_LOG(logERROR, ("Clock row clock ntimes (%d) exceeds the maximum value of 1023.\n\t Setting ntimes to 1023.\n",ntimes)); ntimes=1023; } - if(Feb_Control_activated){ - if(!Feb_Control_SetCommandRegister(DAQ_CLK_ROW_CLK_NTIMES) || + if (Feb_Control_activated) { + if (!Feb_Control_SetCommandRegister(DAQ_CLK_ROW_CLK_NTIMES) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CLK_ROW_CLK_NTIMES,ntimes,0,0) || - (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)){ - cprintf(RED,"Warning: could not clock row clock.\n"); + (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { + FILE_LOG(logERROR, ("could not clock row clock.\n")); return 0; } } @@ -1691,16 +1698,16 @@ int Feb_Control_ClockRowClock(unsigned int ntimes){ } -int Feb_Control_PulseChip(int npulses){ +int Feb_Control_PulseChip(int npulses) { int i; int on = 1; - if(npulses == -1){ + if (npulses == -1) { on = 0; - printf("\nResetting to normal mode\n"); - }else{ - printf("\n\nPulsing Chip.\n");//really just toggles the enable - printf("Vcmp should be set to 2.0 and Vtrim should be 2.\n"); + FILE_LOG(logINFO, ("\nResetting to normal mode\n")); + } else { + FILE_LOG(logINFO, ("\n\nPulsing Chip.\n"));//really just toggles the enable + FILE_LOG(logINFO, ("Vcmp should be set to 2.0 and Vtrim should be 2.\n")); } @@ -1708,145 +1715,149 @@ int Feb_Control_PulseChip(int npulses){ Feb_Control_SetStaticBits(); //toggle the enable 2x times Feb_Control_ResetChipCompletely(); - for(i=0;i ratemax) ratemax= Feb_Control_rate_meas[i]; + for(i=0;i ratemax) ratemax= Feb_Control_rate_meas[i]; } /* b : index/address of block ram/rate correction table b0 : base in vhdl m : slope in vhdl - + Firmware: data_in(11..2) -> memory address --> memory data_in( 1..0) -> lsb - + mem_data_out(13.. 0) -> base mem_data_out(17..14) -> slope - + delta = slope*lsb corr = base+delta - */ - + */ + int next_i=0; double beforemax; b0[0] = 0; m[0] = 1; - + Feb_Control_rate_correction_table[0] = (((int)(m[0]+0.5)&0xf)<<14) | ((int)(b0[0]+0.5)&0x3fff); int b=0; - for(b=1;b<1024;b++){ - if(m[b-1]<15){ + for(b=1;b<1024;b++) { + if (m[b-1]<15) { double s=0,sx=0,sy=0,sxx=0,sxy=0; - for(;;next_i++){ - if(next_i>=np){ - for(; b<1024; b++){ - if(beforemax>ratemax) b0[b] = beforemax; - else b0[b] = ratemax; - m[b] = 15; - Feb_Control_rate_correction_table[b] = (((int)(m[b]+0.5)&0xf)<<14) | ((int)(b0[b]+0.5)&0x3fff); - } - b=1024; - break; - } - - double x = Feb_Control_rate_meas[next_i] - b*4; - double y = next_i; - /*printf("Start Loop x: %f,\t y: %f,\t s: %f,\t sx: %f,\t sy: %f,\t sxx: %f,\t sxy: %f,\t " + for(;;next_i++) { + if (next_i>=np) { + for(; b<1024; b++) { + if (beforemax>ratemax) b0[b] = beforemax; + else b0[b] = ratemax; + m[b] = 15; + Feb_Control_rate_correction_table[b] = (((int)(m[b]+0.5)&0xf)<<14) | ((int)(b0[b]+0.5)&0x3fff); + } + b=1024; + break; + } + + double x = Feb_Control_rate_meas[next_i] - b*4; + double y = next_i; + /*FILE_LOG(logDEBUG5, ("Start Loop x: %f,\t y: %f,\t s: %f,\t sx: %f,\t sy: %f,\t sxx: %f,\t sxy: %f,\t " "next_i: %d,\t b: %d,\t Feb_Control_rate_meas[next_i]: %f\n", - x, y, s, sx, sy, sxx, sxy, next_i, b, Feb_Control_rate_meas[next_i]);*/ - - if(x < -0.5) continue; - if(x > 3.5) break; - s += 1; - sx += x; - sy += y; - sxx += x*x; - sxy += x*y; - /*printf("End Loop x: %f,\t y: %f,\t s: %f,\t sx: %f,\t sy: %f,\t sxx: %f,\t sxy: %f,\t " + x, y, s, sx, sy, sxx, sxy, next_i, b, Feb_Control_rate_meas[next_i]));*/ + + if (x < -0.5) continue; + if (x > 3.5) break; + s += 1; + sx += x; + sy += y; + sxx += x*x; + sxy += x*y; + /*FILE_LOG(logDEBUG5, ("End Loop x: %f,\t y: %f,\t s: %f,\t sx: %f,\t sy: %f,\t sxx: %f,\t sxy: %f,\t " "next_i: %d,\t b: %d,\t Feb_Control_rate_meas[next_i]: %f\n", - x, y, s, sx, sy, sxx, sxy, next_i, b, Feb_Control_rate_meas[next_i]);*/ + x, y, s, sx, sy, sxx, sxy, next_i, b, Feb_Control_rate_meas[next_i]));*/ } double delta = s*sxx - sx*sx; b0[b] = (sxx*sy - sx*sxy)/delta; m[b] = (s*sxy - sx*sy) /delta; beforemax= b0[b]; - if(m[b]<0||m[b]>15){ - m[b]=15; - if(beforemax>ratemax) b0[b] = beforemax; - else b0[b] = ratemax; + if (m[b]<0||m[b]>15) { + m[b]=15; + if (beforemax>ratemax) b0[b] = beforemax; + else b0[b] = ratemax; } - /*printf("After Loop s: %f,\t sx: %f,\t sy: %f,\t sxx: %f,\t sxy: %f,\t " + /*FILE_LOG(logDEBUG5, ("After Loop s: %f,\t sx: %f,\t sy: %f,\t sxx: %f,\t sxy: %f,\t " "next_i: %d,\t b: %d,\t Feb_Control_rate_meas[next_i]: %f\n", - s, sx, sy, sxx, sxy, next_i, b, Feb_Control_rate_meas[next_i]);*/ + s, sx, sy, sxx, sxy, next_i, b, Feb_Control_rate_meas[next_i]));*/ // cout<ratemax) b0[b] = beforemax; - else b0[b] = ratemax; - m[b] = 15; + } else { + if (beforemax>ratemax) b0[b] = beforemax; + else b0[b] = ratemax; + m[b] = 15; } Feb_Control_rate_correction_table[b] = (((int)(m[b]+0.5)&0xf)<<14) | ((int)(b0[b]+0.5)&0x3fff); - /*printf("After Loop 4*b: %d\tbase:%d\tslope:%d\n",4*b, (int)(b0[b]+0.5), (int)(m[b]+0.5) );*/ + /*FILE_LOG(logDEBUG5, ("After Loop 4*b: %d\tbase:%d\tslope:%d\n",4*b, (int)(b0[b]+0.5), (int)(m[b]+0.5) ));*/ } - if(Feb_Control_SetRateCorrectionTable(Feb_Control_rate_correction_table)){ + if (Feb_Control_SetRateCorrectionTable(Feb_Control_rate_correction_table)) { Feb_Control_RateTable_Tau_in_nsec = tau_in_Nsec; Feb_Control_RateTable_Period_in_nsec = period_in_sec*1e9; return 1; - }else{ + } else { Feb_Control_RateTable_Tau_in_nsec = -1; Feb_Control_RateTable_Period_in_nsec = -1; return 0; @@ -1858,75 +1869,75 @@ int Feb_Control_SetRateCorrectionTau(int64_t tau_in_Nsec){ -int Feb_Control_SetRateCorrectionTable(unsigned int *table){ - if(!table){ - printf("Error: could not set rate correction table, point is zero.\n"); - Feb_Control_SetRateCorrectionVariable(0); - return 0; - } +int Feb_Control_SetRateCorrectionTable(unsigned int *table) { + if (!table) { + FILE_LOG(logERROR, ("Error: could not set rate correction table, point is zero.\n")); + Feb_Control_SetRateCorrectionVariable(0); + return 0; + } - printf("Setting rate correction table. %d %d %d %d ....\n", - table[0],table[1],table[2],table[3]); + FILE_LOG(logINFO, ("Setting rate correction table. %d %d %d %d ....\n", + table[0],table[1],table[2],table[3])); - //was added otherwise after an acquire, startdaqonlywatiforfinish waits forever - if(!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY)){ - cprintf(RED,"Warning: Could not Feb_Control_SetCommandRegister for loading trim bits.\n"); - return 0; - } - printf("daq reset completely\n"); + //was added otherwise after an acquire, startdaqonlywatiforfinish waits forever + if (!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY)) { + FILE_LOG(logERROR, ("Could not Feb_Control_SetCommandRegister for loading trim bits.\n")); + return 0; + } + FILE_LOG(logINFO, ("daq reset completely\n")); - if(Module_TopAddressIsValid(&modules[1])){ - if(Feb_Control_activated){ - if(!Feb_Interface_WriteMemoryInLoops(Module_GetTopLeftAddress(&modules[Feb_Control_current_index]),1,0,1024,Feb_Control_rate_correction_table)|| - !Feb_Interface_WriteMemoryInLoops(Module_GetTopRightAddress(&modules[Feb_Control_current_index]),1,0,1024,Feb_Control_rate_correction_table)|| - (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)){ - cprintf(BG_RED,"Error in Top Writing to Memory ::Feb_Control_SetRateCorrectionTable\n"); - return 0; - } - } - }else{ - if(Feb_Control_activated){ - if(!Feb_Interface_WriteMemoryInLoops(Module_GetBottomLeftAddress(&modules[Feb_Control_current_index]),1,0,1024,Feb_Control_rate_correction_table)|| - !Feb_Interface_WriteMemoryInLoops(Module_GetBottomRightAddress(&modules[Feb_Control_current_index]),1,0,1024,Feb_Control_rate_correction_table)|| - (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)){ - cprintf(BG_RED,"Error in Bottom Writing to Memory ::Feb_Control_SetRateCorrectionTable\n"); - return 0; - } - } - } - return 1; + if (Module_TopAddressIsValid(&modules[1])) { + if (Feb_Control_activated) { + if (!Feb_Interface_WriteMemoryInLoops(Module_GetTopLeftAddress(&modules[Feb_Control_current_index]),1,0,1024,Feb_Control_rate_correction_table)|| + !Feb_Interface_WriteMemoryInLoops(Module_GetTopRightAddress(&modules[Feb_Control_current_index]),1,0,1024,Feb_Control_rate_correction_table)|| + (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { + FILE_LOG(logERROR, ("could not write to memory (top) ::Feb_Control_SetRateCorrectionTable\n")); + return 0; + } + } + } else { + if (Feb_Control_activated) { + if (!Feb_Interface_WriteMemoryInLoops(Module_GetBottomLeftAddress(&modules[Feb_Control_current_index]),1,0,1024,Feb_Control_rate_correction_table)|| + !Feb_Interface_WriteMemoryInLoops(Module_GetBottomRightAddress(&modules[Feb_Control_current_index]),1,0,1024,Feb_Control_rate_correction_table)|| + (Feb_Control_StartDAQOnlyNWaitForFinish(5000) != STATUS_IDLE)) { + FILE_LOG(logERROR, ("could not write to memory (bottom) ::Feb_Control_SetRateCorrectionTable\n")); + return 0; + } + } + } + return 1; } -int Feb_Control_GetRateCorrectionVariable(){ return (Feb_Control_subFrameMode&DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION);} +int Feb_Control_GetRateCorrectionVariable() { return (Feb_Control_subFrameMode&DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION);} -void Feb_Control_SetRateCorrectionVariable(int activate_rate_correction){ - if(activate_rate_correction){ - Feb_Control_subFrameMode |= DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION; - printf("Rate correction activated.\n"); - }else{ - Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION; - printf("Rate correction deactivated.\n"); - } +void Feb_Control_SetRateCorrectionVariable(int activate_rate_correction) { + if (activate_rate_correction) { + Feb_Control_subFrameMode |= DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION; + FILE_LOG(logINFO, ("Rate correction activated\n")); + } else { + Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION; + FILE_LOG(logINFO, ("Rate correction deactivated\n")); + } } -int Feb_Control_PrintCorrectedValues(){ +int Feb_Control_PrintCorrectedValues() { int i; int delta, slope, base, lsb, corr; - for (i=0; i < 4096; i++){ + for (i=0; i < 4096; i++) { lsb = i&3; base = Feb_Control_rate_correction_table[i>>2] & 0x3fff; slope = ((Feb_Control_rate_correction_table[i>>2] & 0x3c000) >> 14); - + delta = slope*lsb; corr = delta+base; - if(slope==15) corr= 3*slope+base; + if (slope==15) corr= 3*slope+base; - printf("Readout Input: %d,\tBase:%d,\tSlope:%d,\tLSB:%d,\tDelta:%d\tResult:%d\tReal:%lf\n", - i, base, slope, lsb, delta, corr, Feb_Control_rate_meas[i]); + FILE_LOG(logDEBUG5, ("Readout Input: %d,\tBase:%d,\tSlope:%d,\tLSB:%d,\tDelta:%d\tResult:%d\tReal:%lf\n", + i, base, slope, lsb, delta, corr, Feb_Control_rate_meas[i])); } return 1; } @@ -1935,9 +1946,9 @@ int Feb_Control_PrintCorrectedValues(){ //So if software says now 40.00 you neeed to convert to mdegrees 40000(call it A1) and then //A1/65536/0.00198421639-273.15 -int Feb_Control_GetLeftFPGATemp(){ +int Feb_Control_GetLeftFPGATemp() { unsigned int temperature=0; - if(Module_TopAddressIsValid(&modules[1])) + if (Module_TopAddressIsValid(&modules[1])) Feb_Interface_ReadRegister(Module_GetTopLeftAddress (&modules[1]),FEB_REG_STATUS, &temperature); else Feb_Interface_ReadRegister(Module_GetBottomLeftAddress (&modules[1]),FEB_REG_STATUS, &temperature); @@ -1947,9 +1958,9 @@ int Feb_Control_GetLeftFPGATemp(){ return (int)temperature; } -int Feb_Control_GetRightFPGATemp(){ +int Feb_Control_GetRightFPGATemp() { unsigned int temperature=0; - if(Module_TopAddressIsValid(&modules[1])) + if (Module_TopAddressIsValid(&modules[1])) Feb_Interface_ReadRegister(Module_GetTopRightAddress (&modules[1]),FEB_REG_STATUS, &temperature); else Feb_Interface_ReadRegister(Module_GetBottomRightAddress (&modules[1]),FEB_REG_STATUS, &temperature); @@ -1986,24 +1997,20 @@ int Feb_Control_SoftwareTrigger() { unsigned int cmd = orig_value | DAQ_REG_CHIP_CMDS_INT_TRIGGER; - if(Feb_Control_activated) { + if (Feb_Control_activated) { // set trigger bit -#ifdef VERBOSE - cprintf(BLUE,"Setting Trigger, Register:0x%x\n",cmd); -#endif + FILE_LOG(logDEBUG5, ("Setting Trigger, Register:0x%x\n",cmd)); if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CHIP_CMDS,cmd,0,0)) { - cprintf(RED,"Warning: Could not give software trigger\n"); + FILE_LOG(logERROR, ("Could not give software trigger\n")); return 0; } // unset trigger bit -#ifdef VERBOSE - cprintf(BLUE,"Unsetting Trigger, Register:0x%x\n",orig_value); -#endif + FILE_LOG(logDEBUG5, ("Unsetting Trigger, Register:0x%x\n",orig_value)); if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CHIP_CMDS,orig_value,0,0)) { - cprintf(RED,"Warning: Could not give software trigger\n"); + FILE_LOG(logERROR, ("Could not give software trigger\n")); return 0; } - cprintf(BLUE,"Software Internal Trigger Sent!\n"); + FILE_LOG(logINFO, ("Software Internal Trigger Sent!\n")); } return 1; @@ -2012,14 +2019,14 @@ int Feb_Control_SoftwareTrigger() { uint32_t Feb_Control_WriteRegister(uint32_t offset, uint32_t data) { uint32_t value=0; - if(Module_TopAddressIsValid(&modules[1])){ - if(!Feb_Interface_WriteRegister(Module_GetTopRightAddress (&modules[1]),offset, data,0, 0)) { - cprintf(RED,"Could not read value. Value read:%d\n", value); + if (Module_TopAddressIsValid(&modules[1])) { + if (!Feb_Interface_WriteRegister(Module_GetTopRightAddress (&modules[1]),offset, data,0, 0)) { + FILE_LOG(logERROR, ("Could not read value. Value read:%d\n", value)); value = 0; } } else { - if(!Feb_Interface_WriteRegister(Module_GetBottomRightAddress (&modules[1]),offset, data,0, 0)) { - cprintf(RED,"Could not read value. Value read:%d\n", value); + if (!Feb_Interface_WriteRegister(Module_GetBottomRightAddress (&modules[1]),offset, data,0, 0)) { + FILE_LOG(logERROR, ("Could not read value. Value read:%d\n", value)); value = 0; } } @@ -2029,14 +2036,14 @@ uint32_t Feb_Control_WriteRegister(uint32_t offset, uint32_t data) { uint32_t Feb_Control_ReadRegister(uint32_t offset) { uint32_t value=0; - if(Module_TopAddressIsValid(&modules[1])){ - if(!Feb_Interface_ReadRegister(Module_GetTopRightAddress (&modules[1]),offset, &value)) { - cprintf(RED,"Could not read value. Value read:%d\n", value); + if (Module_TopAddressIsValid(&modules[1])) { + if (!Feb_Interface_ReadRegister(Module_GetTopRightAddress (&modules[1]),offset, &value)) { + FILE_LOG(logERROR, ("Could not read value. Value read:%d\n", value)); value = 0; } } else { - if(!Feb_Interface_ReadRegister(Module_GetBottomRightAddress (&modules[1]),offset, &value)) { - cprintf(RED,"Could not read value. Value read:%d\n", value); + if (!Feb_Interface_ReadRegister(Module_GetBottomRightAddress (&modules[1]),offset, &value)) { + FILE_LOG(logERROR, ("Could not read value. Value read:%d\n", value)); value = 0; } } diff --git a/slsDetectorServers/eigerDetectorServer/FebControl.h b/slsDetectorServers/eigerDetectorServer/FebControl.h index b20da4fab..ba3cc4a55 100644 --- a/slsDetectorServers/eigerDetectorServer/FebControl.h +++ b/slsDetectorServers/eigerDetectorServer/FebControl.h @@ -1,36 +1,24 @@ - -/** - * @author Ian Johnson - * @version 1.0 - */ - - -#ifndef FEBCONTROL_H -#define FEBCONTROL_H - -#include -#include -//#include -//#include - - +#pragma once #include "FebInterface.h" +#include +#include + struct Module{ - unsigned int module_number; - int top_address_valid; - unsigned int top_left_address; - unsigned int top_right_address; - int bottom_address_valid; - unsigned int bottom_left_address; - unsigned int bottom_right_address; + unsigned int module_number; + int top_address_valid; + unsigned int top_left_address; + unsigned int top_right_address; + int 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; + 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; }; @@ -38,12 +26,12 @@ void Module_Module(struct Module* mod,unsigned int number, unsigned int address_ void Module_ModuleBottom(struct Module* mod,unsigned int number, unsigned int address_bottom); void Module_Module1(struct Module* mod,unsigned int number, unsigned int address_top, unsigned int address_bottom); unsigned int Module_GetModuleNumber(struct Module* mod); -int Module_TopAddressIsValid(struct Module* mod); +int Module_TopAddressIsValid(struct Module* mod); unsigned int Module_GetTopBaseAddress(struct Module* mod); unsigned int Module_GetTopLeftAddress(struct Module* mod) ; unsigned int Module_GetTopRightAddress(struct Module* mod); unsigned int Module_GetBottomBaseAddress(struct Module* mod); -int Module_BottomAddressIsValid(struct Module* mod); +int Module_BottomAddressIsValid(struct Module* mod); unsigned int Module_GetBottomLeftAddress(struct Module* mod); unsigned int Module_GetBottomRightAddress(struct Module* mod); unsigned int Module_SetTopIDelay(struct Module* mod,unsigned int chip,unsigned int value); @@ -51,17 +39,13 @@ unsigned int Module_GetTopIDelay(struct Module* mod,unsigned int chip) ; unsigned int Module_SetBottomIDelay(struct Module* mod,unsigned int chip,unsigned int value); unsigned int Module_GetBottomIDelay(struct Module* mod,unsigned int chip); -float Module_SetHighVoltage(struct Module* mod,float value); -float Module_GetHighVoltage(struct Module* mod); - -int Module_SetTopDACValue(struct Module* mod,unsigned int i, int value); -int Module_GetTopDACValue(struct Module* mod,unsigned int i); -int Module_SetBottomDACValue(struct Module* mod,unsigned int i, int value); -int Module_GetBottomDACValue(struct Module* mod,unsigned int i); - - - +float Module_SetHighVoltage(struct Module* mod,float value); +float Module_GetHighVoltage(struct Module* mod); +int Module_SetTopDACValue(struct Module* mod,unsigned int i, int value); +int Module_GetTopDACValue(struct Module* mod,unsigned int i); +int Module_SetBottomDACValue(struct Module* mod,unsigned int i, int value); +int Module_GetBottomDACValue(struct Module* mod,unsigned int i); void Feb_Control_activate(int activate); @@ -69,142 +53,107 @@ void Feb_Control_activate(int activate); int Feb_Control_IsBottomModule(); int Feb_Control_GetModuleNumber(); +void Feb_Control_PrintModuleList(); +int Feb_Control_GetModuleIndex(unsigned int module_number, unsigned int* module_index); +int Feb_Control_CheckModuleAddresses(struct Module* m); +int Feb_Control_AddModule(unsigned int module_number, unsigned int top_address); +int Feb_Control_AddModule1(unsigned int module_number, int top_enable, unsigned int top_address, unsigned int bottom_address, int half_module); +int Feb_Control_GetDACNumber(char* s, unsigned int* n); +int Feb_Control_SendDACValue(unsigned int dst_num, unsigned int ch, unsigned int* value); +int Feb_Control_VoltageToDAC(float value, unsigned int* digital, unsigned int nsteps, float vmin, float vmax); +float Feb_Control_DACToVoltage(unsigned int digital,unsigned int nsteps,float vmin,float vmax); +int Feb_Control_SendIDelays(unsigned int dst_num, int chip_lr, unsigned int channels, unsigned int ndelay_units); +int Feb_Control_SetStaticBits(); +int Feb_Control_SetStaticBits1(unsigned int the_static_bits); +int Feb_Control_SendBitModeToBebServer(); +unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec); +unsigned int Feb_Control_AddressToAll(); +int Feb_Control_SetCommandRegister(unsigned int cmd); +int Feb_Control_GetDAQStatusRegister(unsigned int dst_address, unsigned int* ret_status); +int Feb_Control_StartDAQOnlyNWaitForFinish(int sleep_time_us); +int Feb_Control_ResetChipCompletely(); +int Feb_Control_ResetChipPartially(); +void Feb_Control_FebControl(); +int Feb_Control_Init(int master, int top, int normal, int module_num); +int Feb_Control_OpenSerialCommunication(); +void Feb_Control_CloseSerialCommunication(); +int Feb_Control_CheckSetup(); +unsigned int Feb_Control_GetNModules(); +unsigned int Feb_Control_GetNHalfModules(); +int Feb_Control_SetHighVoltage(int value); +int Feb_Control_GetHighVoltage(int* value); +int Feb_Control_SendHighVoltage(int dacvalue); +int Feb_Control_ReceiveHighVoltage(unsigned int* value); - void Feb_Control_PrintModuleList(); - int Feb_Control_GetModuleIndex(unsigned int module_number, unsigned int* module_index); - int Feb_Control_CheckModuleAddresses(struct Module* m); - int Feb_Control_AddModule(unsigned int module_number, unsigned int top_address); - /*int Feb_Control_AddModule(unsigned int module_number, unsigned int top_address, unsigned int bottom_address, int half_module=0);*/ - int Feb_Control_AddModule1(unsigned int module_number, int top_enable, unsigned int top_address, unsigned int bottom_address, int half_module); +int Feb_Control_SetIDelays(unsigned int module_num, unsigned int ndelay_units); +int Feb_Control_SetIDelays1(unsigned int module_num, unsigned int chip_pos, unsigned int ndelay_units); - int Feb_Control_GetDACNumber(char* s, unsigned int* n); - int Feb_Control_SendDACValue(unsigned int dst_num, unsigned int ch, unsigned int* value); - int Feb_Control_VoltageToDAC(float value, unsigned int* digital, unsigned int nsteps, float vmin, float vmax); - float Feb_Control_DACToVoltage(unsigned int digital,unsigned int nsteps,float vmin,float vmax); +int Feb_Control_DecodeDACString(char* dac_str, unsigned int* module_index, int* top, int* bottom, unsigned int* dac_ch); +int Feb_Control_SetDAC(char* s, int value, int is_a_voltage_mv); +int Feb_Control_GetDAC(char* s, int* ret_value, int voltage_mv); +int Feb_Control_GetDACName(unsigned int dac_num,char* s); +int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int* trimbits); +unsigned int* Feb_Control_GetTrimbits(); +int Feb_Control_SaveAllTrimbitsTo(int value); +int Feb_Control_Reset(); +int Feb_Control_PrepareForAcquisition(); - int Feb_Control_SendIDelays(unsigned int dst_num, int chip_lr, unsigned int channels, unsigned int ndelay_units); +int Feb_Control_StartAcquisition(); +int Feb_Control_StopAcquisition(); +int Feb_Control_AcquisitionInProgress(); +int Feb_Control_AcquisitionStartedBit(); +int Feb_Control_WaitForFinishedFlag(int sleep_time_us); +int Feb_Control_WaitForStartedFlag(int sleep_time_us, int prev_flag); +void Feb_Control_PrintAcquisitionSetup(); +int Feb_Control_SetNExposures(unsigned int n_images); +unsigned int Feb_Control_GetNExposures(); +int Feb_Control_SetExposureTime(double the_exposure_time_in_sec); +double Feb_Control_GetExposureTime(); +int64_t Feb_Control_GetExposureTime_in_nsec(); +int Feb_Control_SetSubFrameExposureTime(int64_t the_subframe_exposure_time_in_10nsec); +int64_t Feb_Control_GetSubFrameExposureTime(); +int Feb_Control_SetSubFramePeriod(int64_t the_subframe_period_in_10nsec); +int64_t Feb_Control_GetSubFramePeriod(); +int Feb_Control_SetExposurePeriod(double the_exposure_period_in_sec); +double Feb_Control_GetExposurePeriod(); +int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo); +unsigned int Feb_Control_GetDynamicRange(); +int Feb_Control_SetReadoutSpeed(unsigned int readout_speed); //0 was default, 0->full,1->half,2->quarter or 3->super_slow +int Feb_Control_SetReadoutMode(unsigned int readout_mode); ///0 was default,0->parallel,1->non-parallel,2-> safe_mode +int Feb_Control_SetTriggerMode(unsigned int trigger_mode, int polarity);//0 and 1 was default, +int Feb_Control_SetExternalEnableMode(int use_external_enable, int polarity);//0 and 1 was default, - int Feb_Control_SetStaticBits(); - int Feb_Control_SetStaticBits1(unsigned int the_static_bits); +int Feb_Control_SetInTestModeVariable(int on); +int Feb_Control_GetTestModeVariable(); - int Feb_Control_SendBitModeToBebServer(); +void Feb_Control_Set_Counter_Bit(int value); +int Feb_Control_Get_Counter_Bit(); +int Feb_Control_Pulse_Pixel(int npulses,int x, int y); +int Feb_Control_PulsePixelNMove(int npulses, int inc_x_pos, int inc_y_pos); +int Feb_Control_Shift32InSerialIn(unsigned int value_to_shift_in); +int Feb_Control_SendTokenIn(); +int Feb_Control_ClockRowClock(unsigned int ntimes); +int Feb_Control_PulseChip(int npulses); - unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec); +int64_t Feb_Control_Get_RateTable_Tau_in_nsec(); +int64_t Feb_Control_Get_RateTable_Period_in_nsec(); +int Feb_Control_SetRateCorrectionTau(int64_t tau_in_Nsec); +int Feb_Control_SetRateCorrectionTable(unsigned int *table); +int Feb_Control_GetRateCorrectionVariable(); +void Feb_Control_SetRateCorrectionVariable(int activate_rate_correction); +int Feb_Control_PrintCorrectedValues(); - unsigned int Feb_Control_AddressToAll(); - int Feb_Control_SetCommandRegister(unsigned int cmd); - int Feb_Control_GetDAQStatusRegister(unsigned int dst_address, unsigned int* ret_status); - /*int Feb_Control_StartDAQOnlyNWaitForFinish(int sleep_time_us=5000);*/ - int Feb_Control_StartDAQOnlyNWaitForFinish(int sleep_time_us); +int Feb_Control_GetLeftFPGATemp(); +int Feb_Control_GetRightFPGATemp(); - int Feb_Control_ResetChipCompletely(); - int Feb_Control_ResetChipPartially(); +int64_t Feb_Control_GetMeasuredPeriod(); +int64_t Feb_Control_GetSubMeasuredPeriod(); - //struct sockaddr_in Feb_Control_serv_addr; - /* - int Feb_Control_SetupSendToSocket(const char* ip_address_hostname, unsigned short int port); - int Feb_Control_WriteNRead(char* message, int length, int max_length); -*/ +int Feb_Control_SoftwareTrigger(); +uint32_t Feb_Control_WriteRegister(uint32_t offset, uint32_t data); +uint32_t Feb_Control_ReadRegister(uint32_t offset); - void Feb_Control_FebControl(); - int Feb_Control_Init(int master, int top, int normal, int module_num); - int Feb_Control_OpenSerialCommunication(); - void Feb_Control_CloseSerialCommunication(); - int Feb_Control_CheckSetup(); - - unsigned int Feb_Control_GetNModules(); - unsigned int Feb_Control_GetNHalfModules(); - - int Feb_Control_SetHighVoltage(int value); - int Feb_Control_GetHighVoltage(int* value); - - int Feb_Control_SendHighVoltage(int dacvalue); - int Feb_Control_ReceiveHighVoltage(unsigned int* value); - - int Feb_Control_SetIDelays(unsigned int module_num, unsigned int ndelay_units); - int Feb_Control_SetIDelays1(unsigned int module_num, unsigned int chip_pos, unsigned int ndelay_units); - - int Feb_Control_DecodeDACString(char* dac_str, unsigned int* module_index, int* top, int* bottom, unsigned int* dac_ch); - /*int Feb_Control_SetDAC(string s, int value, int is_a_voltage_mv=0);*/ - int Feb_Control_SetDAC(char* s, int value, int is_a_voltage_mv); - /* int Feb_Control_GetDAC(string s, int* ret_value, int voltage_mv=0);*/ - int Feb_Control_GetDAC(char* s, int* ret_value, int voltage_mv); - int Feb_Control_GetDACName(unsigned int dac_num,char* s); - - int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int* trimbits); - unsigned int* Feb_Control_GetTrimbits(); - - - /**Added by Dhanya */ - int Feb_Control_SaveAllTrimbitsTo(int value); - - - - int Feb_Control_Reset(); - int Feb_Control_PrepareForAcquisition(); - - int Feb_Control_StartAcquisition(); - int Feb_Control_StopAcquisition(); - int Feb_Control_AcquisitionInProgress(); - int Feb_Control_AcquisitionStartedBit(); - /*int Feb_Control_WaitForFinishedFlag(int sleep_time_us=5000);*/ - int Feb_Control_WaitForFinishedFlag(int sleep_time_us); - int Feb_Control_WaitForStartedFlag(int sleep_time_us, int prev_flag); - - //functions for setting up exposure - void Feb_Control_PrintAcquisitionSetup(); - int Feb_Control_SetNExposures(unsigned int n_images); - unsigned int Feb_Control_GetNExposures(); - int Feb_Control_SetExposureTime(double the_exposure_time_in_sec); - double Feb_Control_GetExposureTime(); - int64_t Feb_Control_GetExposureTime_in_nsec(); - int Feb_Control_SetSubFrameExposureTime(int64_t the_subframe_exposure_time_in_10nsec); - int64_t Feb_Control_GetSubFrameExposureTime(); - int Feb_Control_SetSubFramePeriod(int64_t the_subframe_period_in_10nsec); - int64_t Feb_Control_GetSubFramePeriod(); - int Feb_Control_SetExposurePeriod(double the_exposure_period_in_sec); - double Feb_Control_GetExposurePeriod(); - int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo); - unsigned int Feb_Control_GetDynamicRange(); - int Feb_Control_SetReadoutSpeed(unsigned int readout_speed); //0 was default, 0->full,1->half,2->quarter or 3->super_slow - int Feb_Control_SetReadoutMode(unsigned int readout_mode); ///0 was default,0->parallel,1->non-parallel,2-> safe_mode - int Feb_Control_SetTriggerMode(unsigned int trigger_mode, int polarity);//0 and 1 was default, - int Feb_Control_SetExternalEnableMode(int use_external_enable, int polarity);//0 and 1 was default, - - //functions for testing - /*int Feb_Control_SetTestModeVariable(int on=1);*/ - int Feb_Control_SetInTestModeVariable(int on); - int Feb_Control_GetTestModeVariable(); - - void Feb_Control_Set_Counter_Bit(int value); - int Feb_Control_Get_Counter_Bit(); - int Feb_Control_Pulse_Pixel(int npulses,int x, int y); - int Feb_Control_PulsePixelNMove(int npulses, int inc_x_pos, int inc_y_pos); - int Feb_Control_Shift32InSerialIn(unsigned int value_to_shift_in); - int Feb_Control_SendTokenIn(); - int Feb_Control_ClockRowClock(unsigned int ntimes); - int Feb_Control_PulseChip(int npulses); - - int64_t Feb_Control_Get_RateTable_Tau_in_nsec(); - int64_t Feb_Control_Get_RateTable_Period_in_nsec(); - int Feb_Control_SetRateCorrectionTau(int64_t tau_in_Nsec); - int Feb_Control_SetRateCorrectionTable(unsigned int *table); - int Feb_Control_GetRateCorrectionVariable(); - void Feb_Control_SetRateCorrectionVariable(int activate_rate_correction); - int Feb_Control_PrintCorrectedValues(); - - int Feb_Control_GetLeftFPGATemp(); - int Feb_Control_GetRightFPGATemp(); - - int64_t Feb_Control_GetMeasuredPeriod(); - int64_t Feb_Control_GetSubMeasuredPeriod(); - - int Feb_Control_SoftwareTrigger(); - - uint32_t Feb_Control_WriteRegister(uint32_t offset, uint32_t data); - uint32_t Feb_Control_ReadRegister(uint32_t offset); -#endif diff --git a/slsDetectorServers/eigerDetectorServer/FebInterface.c b/slsDetectorServers/eigerDetectorServer/FebInterface.c index a094bda44..5ca087d42 100644 --- a/slsDetectorServers/eigerDetectorServer/FebInterface.c +++ b/slsDetectorServers/eigerDetectorServer/FebInterface.c @@ -1,45 +1,31 @@ - -/** - * @author Ian Johnson - * @version 1.0 - */ - - - -//#include -//#include -//#include -//#include -//#include -//#include +#include "FebInterface.h" +#include "LocalLinkInterface.h" +#include "xparameters.h" +#include "logger.h" #include #include #include -#include "xparameters.h" - -#include "FebInterface.h" +struct LocalLinkInterface ll_local,* ll; - struct LocalLinkInterface ll_local,* ll; +unsigned int Feb_Interface_nfebs; +unsigned int* Feb_Interface_feb_numb; - 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_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; +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(){ +void Feb_Interface_FebInterface() { ll = &ll_local; Feb_Interface_nfebs = 0; Feb_Interface_feb_numb = 0; @@ -54,131 +40,129 @@ void Feb_Interface_FebInterface(){ 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); + Local_LocalLinkInterface1(ll,XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR); } -void Feb_Interface_SendCompleteList(unsigned int n,unsigned int* list){ +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; +int Feb_Interface_WriteTo(unsigned int ch) { + if (ch>0xfff) return 0; -#ifdef MARTIN - cprintf(YELLOW, "FIW ch %d\n", ch); -#endif + FILE_LOG(logDEBUG5, ("FIW ch %d\n", ch)); - 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] = 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] = 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)); +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){ +int Feb_Interface_ReadFrom(unsigned int ch, unsigned int ntrys) { unsigned int t; - if(ch>=0xfff) return 0; + 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); - } + Feb_Interface_recv_data_raw[0] = 0xa0000000 | (ch<<16); + Local_Write(ll,4,Feb_Interface_recv_data_raw); + usleep(20); - return (Feb_Interface_recv_ndata>=0); + 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(){ +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; + unsigned int dst = 0xff; + for(i=0;iFeb_Interface_send_buffer_size-2) return 0; + nreads &= 0x3ff; + if (!nreads||nreads>Feb_Interface_send_buffer_size-2) return 0; - //cout<<"Write register : "<Feb_Interface_send_buffer_size-2) return 0; + + //cout<<"Write register : "<0){ + while(ndata_countdown>0) { n_to_send = ndata_countdownFeb_Interface_send_buffer_size-2) {printf("error herer: nwrites:%d\n",nwrites);return 0;}//*d-1026 + mem_num &= 0x3f; + start_address &= 0x3fff; + nwrites &= 0x3ff; + if (!nwrites||nwrites>Feb_Interface_send_buffer_size-2) { + FILE_LOG(logERROR, ("invalid nwrites:%d\n",nwrites)); + return 0; + }//*d-1026 - Feb_Interface_send_ndata = nwrites+2;//*d-1026 - 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 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) diff --git a/slsDetectorServers/eigerDetectorServer/LocalLinkInterface.c b/slsDetectorServers/eigerDetectorServer/LocalLinkInterface.c index 8d1b9db1f..7679ad432 100644 --- a/slsDetectorServers/eigerDetectorServer/LocalLinkInterface.c +++ b/slsDetectorServers/eigerDetectorServer/LocalLinkInterface.c @@ -1,44 +1,36 @@ - -//Class initially from Gerd and was called mmap_test.c -//return reversed 1 means good, 0 means failed - +#include "LocalLinkInterface.h" +#include "HardwareMMappingDefs.h" +#include "logger.h" +#include "ansi.h" #include #include -//#include +#include +#include -#include "HardwareMMappingDefs.h" - -#include "LocalLinkInterface.h" - - - -void Local_LocalLinkInterface1(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr){ - // printf("\n v 1 \n"); - printf("Initialize PLB LL FIFOs\n"); +void Local_LocalLinkInterface1(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr) { + FILE_LOG(logDEBUG5, ("Initialize PLB LL FIFOs\n")); ll->ll_fifo_base=0; ll->ll_fifo_ctrl_reg=0; - if(Local_Init(ll,ll_fifo_badr)){ + 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"); + FILE_LOG(logDEBUG5, ("\tFIFO Status : 0x%08x\n\n\n", Local_StatusVector(ll))); + } else FILE_LOG(logERROR, ("\tCould not map LocalLink : 0x%08x\n\n\n", ll_fifo_badr)); } -/*~LocalLinkInterface(){};*/ -void Local_LocalLinkInterface(struct LocalLinkInterface* ll){ - printf("Initializing new memory\n"); +void Local_LocalLinkInterface(struct LocalLinkInterface* ll) { + FILE_LOG(logDEBUG5, ("Initializing new memory\n")); } -int Local_Init(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr){ +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){ + if ((fd=open("/dev/mem", O_RDWR)) < 0) { fprintf(stderr, "Could not open /dev/mem\n"); return 0; } @@ -46,7 +38,7 @@ int Local_Init(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr){ 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){ + if (plb_ll_fifo_ptr == MAP_FAILED) { perror ("mmap"); return 0; } @@ -59,13 +51,13 @@ int Local_Init(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr){ -int Local_Reset(struct LocalLinkInterface* ll){ +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){ +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); + FILE_LOG(logDEBUG5, ("\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); @@ -75,17 +67,16 @@ int Local_Reset1(struct LocalLinkInterface* ll,unsigned int rst_mask){ 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){ +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){ +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; @@ -101,22 +92,19 @@ int Local_Write(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buf last_word = (buffer_len-1)/4; word_ptr = (unsigned int *)buffer; -#ifdef MARTIN - cprintf(BLUE, "LL Write - Len: %2d - If: %X - Data: ",buffer_len, ll->ll_fifo_base); + FILE_LOG(logDEBUG5, ("LL Write - Len: %2d - If: %X - Data: ",buffer_len, ll->ll_fifo_base)); for (i=0; i < buffer_len/4; i++) - cprintf(BLUE, "%.8X ",*(((unsigned *) buffer)+i)); - printf("\n"); -#endif + FILE_LOG(logDEBUG5, ("%.8X ",*(((unsigned *) buffer)+i))); 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; -#ifdef MARTIN - if (vacancy == 0) cprintf(RED, "Fifo full!\n"); -#endif + if ((status & PLB_LL_FIFO_STATUS_ALMOSTFULL) == 0) vacancy = 1; + if (vacancy == 0) { + FILE_LOG(logERROR, ("Fifo full!\n")); + } } //Just to know: #define PLB_LL_FIFO_ALMOST_FULL_THRESHOLD_WORDS 100 @@ -140,7 +128,7 @@ int Local_Write(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buf } -int Local_Read(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer){ +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 @@ -150,9 +138,7 @@ int Local_Read(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buff volatile unsigned int fifo_val; int sof = 0; -#ifdef MARTIN - cprintf(CYAN, "LL Read - If: %X - Data: ",ll->ll_fifo_base); -#endif + FILE_LOG(logDEBUG5, ("LL Read - If: %X - Data: ",ll->ll_fifo_base)); word_ptr = (unsigned int *)buffer; do @@ -168,7 +154,6 @@ int Local_Read(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buff buffer_ptr = 0; return -1; // buffer overflow } - // printf(">>>> SOF\n\r"); buffer_ptr = 0; sof = 1; } @@ -179,9 +164,7 @@ int Local_Read(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buff { if ( (buffer_len >> 2) > buffer_ptr) { -#ifdef MARTIN - cprintf(CYAN, "%.8X ", fifo_val); -#endif + FILE_LOG(logDEBUG5, ("%.8X ", fifo_val)); word_ptr[buffer_ptr++] = fifo_val; //write to buffer } else @@ -193,10 +176,7 @@ int Local_Read(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buff 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 ); -#ifdef MARTIN - cprintf(CYAN, "Len: %d\n",len); -#endif - // printf(">>>>status=0x%08x EOF len = %d \n\r\n\r",status, len); + FILE_LOG(logDEBUG5, ("Len: %d\n",len)); buffer_ptr = 0; return len; } @@ -209,19 +189,15 @@ int Local_Read(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buff 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); +int Local_ctrl_reg_write_mask(struct LocalLinkInterface* ll,unsigned int mask, unsigned int val) { 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 Local_Test(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer) { int len; unsigned int rec_buff_len = 4096; @@ -233,28 +209,14 @@ int Local_Test(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buff do{ len = Local_Read(ll,rec_buff_len,rec_buffer); - printf("receive length: %i\n",len); + FILE_LOG(logDEBUG5, ("receive length: %i\n",len)); - if (len > 0){ + if (len > 0) { rec_buffer[len]=0; - printf((char*) rec_buffer); - printf("\n"); + FILE_LOG(logINFO, ("%s\n", (char*) rec_buffer)); } } 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 - -#include "ansi.h" -#include -#include - -/*class LocalLinkInterface: public HardwareIO{ //*/ struct LocalLinkInterface{ - xfs_u32 ll_fifo_base; - unsigned int ll_fifo_ctrl_reg; + xfs_u32 ll_fifo_base; + unsigned int ll_fifo_ctrl_reg; }; +int Local_Init(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr); +int Local_Reset1(struct LocalLinkInterface* ll,unsigned int rst_mask); +int Local_ctrl_reg_write_mask(struct LocalLinkInterface* ll,unsigned int mask, unsigned int val); +void Local_LocalLinkInterface1(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr); +unsigned int Local_StatusVector(struct LocalLinkInterface* ll); +int Local_Reset(struct LocalLinkInterface* ll); +int Local_Write(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer); +int Local_Read(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer); +int Local_Test(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer); +void Local_LocalLinkInterface(struct LocalLinkInterface* ll); - - int Local_Init(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr); - int Local_Reset1(struct LocalLinkInterface* ll,unsigned int rst_mask); - - int Local_ctrl_reg_write_mask(struct LocalLinkInterface* ll,unsigned int mask, unsigned int val); - void Local_llfifo_print_frame(struct LocalLinkInterface* ll,unsigned char* fbuff, int len); - - - void Local_LocalLinkInterface1(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr); - /* virtual ~LocalLinkInterface();*/ - - unsigned int Local_StatusVector(struct LocalLinkInterface* ll); - int Local_Reset(struct LocalLinkInterface* ll); - int Local_Write(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer); - int Local_Read(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer); - - int Local_Test(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer); - - void Local_LocalLinkInterface(struct LocalLinkInterface* ll); - - /* - int FiFoReset(unsigned int numb); - int FifoSend(unsigned int numb, unsigned int frame_len, void *buffer); - int FifoReceive(unsigned int numb, unsigned int frame_len, void *buffer); - int FifoTest(unsigned int numb,unsigned int send_len, char *send_str); - */ - - - - -#endif diff --git a/slsDetectorServers/eigerDetectorServer/gitInfo.txt b/slsDetectorServers/eigerDetectorServer/gitInfo.txt index 8aa8ce29d..136474476 100644 --- a/slsDetectorServers/eigerDetectorServer/gitInfo.txt +++ b/slsDetectorServers/eigerDetectorServer/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorPackage/slsDetectorServers/eigerDetectorServer URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git -Repsitory UUID: 178b83222380f7b7294cde66e66719c5d1c1363c -Revision: 2 +Repsitory UUID: dfad145e1492e961c95063aa5b2f54e5e1b418a0 +Revision: 3 Branch: refactor Last Changed Author: Dhanya_Thattil -Last Changed Rev: 4125 -Last Changed Date: 2018-10-16 09:02:45.000000002 +0200 ./Makefile +Last Changed Rev: 4127 +Last Changed Date: 2018-10-23 12:30:26.000000002 +0200 ./Beb.c diff --git a/slsDetectorServers/eigerDetectorServer/gitInfoEiger.h b/slsDetectorServers/eigerDetectorServer/gitInfoEiger.h index 6ae33d32f..2254b38c9 100644 --- a/slsDetectorServers/eigerDetectorServer/gitInfoEiger.h +++ b/slsDetectorServers/eigerDetectorServer/gitInfoEiger.h @@ -1,6 +1,6 @@ #define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git" -#define GITREPUUID "178b83222380f7b7294cde66e66719c5d1c1363c" +#define GITREPUUID "dfad145e1492e961c95063aa5b2f54e5e1b418a0" #define GITAUTH "Dhanya_Thattil" -#define GITREV 0x4125 -#define GITDATE 0x20181016 +#define GITREV 0x4127 +#define GITDATE 0x20181023 #define GITBRANCH "refactor" diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c index 2231ae283..0de061582 100644 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c @@ -1,3 +1,12 @@ +#include "slsDetectorFunctionList.h" +#ifndef VIRTUAL +#include "gitInfoEiger.h" +#include "FebControl.h" +#include "Beb.h" +#include "versionAPI.h" +#endif +#include "logger.h" + #include #include //to gethostname @@ -7,32 +16,39 @@ #include #endif -#include "slsDetectorFunctionList.h" -#ifndef VIRTUAL -#include "gitInfoEiger.h" -#include "FebControl.h" -#include "Beb.h" -#include "versionAPI.h" -#endif - // Global variable from slsDetectorServer extern int debugflag; +extern int isControlServer; -int default_tau_from_file= -1; - -#define BEB_NUM 34 - -enum detectorSettings thisSettings; 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"}; - -enum{E_PARALLEL, E_NON_PARALLEL, E_SAFE}; - +int default_tau_from_file= -1; +enum detectorSettings thisSettings; sls_detector_module *detectorModules=NULL; int *detectorChips=NULL; int *detectorChans=NULL; int *detectorDacs=NULL; int *detectorAdcs=NULL; +int send_to_ten_gig = 0; +int ndsts_in_use=32; +unsigned int nimages_per_request=1; +int on_dst=0; +int 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}; + +enum masterFlags masterMode=IS_SLAVE; +int top = 0; +int master = 0; +int normal = 0; +#ifndef VIRTUAL +uint32_t detid = 0; +#endif + + +int firmware_compatibility = OK; +int firmware_check_done = 0; +char firmware_message[MAX_STR_LENGTH]; + + int eiger_highvoltage = 0; int eiger_theo_highvoltage = 0; int eiger_iodelay = 0; @@ -72,30 +88,6 @@ int eiger_virtual_stop = 0; #endif -int send_to_ten_gig = 0; -int ndsts_in_use=32; -unsigned int nimages_per_request=1; -int on_dst=0; -int 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}; - - -int default_gain_values[3] = {517000,517000,517000}; -int default_offset_values[3] = {3851000,3851000,3851000}; - - -enum masterFlags masterMode=IS_SLAVE; -int top = 0; -int master = 0; -int normal = 0; -#ifndef VIRTUAL -uint32_t detid = 0; -#endif - -/* basic tests */ - -int firmware_compatibility = OK; -int firmware_check_done = 0; -char firmware_message[MAX_STR_LENGTH]; int isFirmwareCheckDone() { @@ -107,15 +99,12 @@ int getFirmwareCheckResult(char** mess) { return firmware_compatibility; } -void checkFirmwareCompatibility(){ +void checkFirmwareCompatibility() { firmware_compatibility = OK; firmware_check_done = 0; memset(firmware_message, 0, MAX_STR_LENGTH); #ifdef VIRTUAL - cprintf(BLUE,"\n\n" - "********************************************************\n" - "***************** EIGER Virtual Server *****************\n" - "********************************************************\n"); + FILE_LOG(logINFOBLUE, ("************ EIGER Virtual Server *****************\n\n")); firmware_check_done = 1; return; #endif @@ -126,11 +115,7 @@ void checkFirmwareCompatibility(){ int64_t sw_fw_apiversion = getDetectorId(SOFTWARE_FIRMWARE_API_VERSION); int64_t client_sw_apiversion = getDetectorId(CLIENT_SOFTWARE_API_VERSION); - cprintf(BLUE,"\n\n" - "********************************************************\n" - "**********************EIGER Server**********************\n" - "********************************************************\n"); - cprintf(BLUE,"\n" + FILE_LOG(logINFOBLUE, ("**************** EIGER Server *********************\n\n" "Detector IP Addr:\t\t 0x%x\n" "Detector MAC Addr:\t\t 0x%llx\n" @@ -147,50 +132,47 @@ void checkFirmwareCompatibility(){ (long long int)swversion, (long long int)sw_fw_apiversion, REQUIRED_FIRMWARE_VERSION, - (long long int)client_sw_apiversion); + (long long int)client_sw_apiversion)); // return if debugflag is not zero, debug mode if (debugflag) { firmware_check_done = 1; - return; + return; } //cant read versions - if(!fwversion || !sw_fw_apiversion){ - strcpy(firmware_message, - "FATAL ERROR: Cant read versions from FPGA. Please update firmware.\n"); - cprintf(RED,"%s\n\n", firmware_message); + if (!fwversion || !sw_fw_apiversion) { + strcpy(firmware_message, "Cant read versions from FPGA. Please update firmware.\n"); + FILE_LOG(logERROR, (firmware_message)); firmware_compatibility = FAIL; firmware_check_done = 1; return; } //check for API compatibility - old server - if(sw_fw_apiversion > REQUIRED_FIRMWARE_VERSION){ - sprintf(firmware_message, - "FATAL ERROR: This detector software software version (%lld) is incompatible.\n" + if (sw_fw_apiversion > REQUIRED_FIRMWARE_VERSION) { + sprintf(firmware_message, "This detector software software version (%lld) is incompatible.\n" "Please update detector software (min. %lld) to be compatible with this firmware.\n", (long long int)sw_fw_apiversion, (long long int)REQUIRED_FIRMWARE_VERSION); - cprintf(RED,"%s\n\n", firmware_message); + FILE_LOG(logERROR, (firmware_message)); firmware_compatibility = FAIL; firmware_check_done = 1; return; } //check for firmware compatibility - old firmware - if( REQUIRED_FIRMWARE_VERSION > fwversion){ - sprintf(firmware_message, - "FATAL ERROR: This firmware version (%lld) is incompatible.\n" + if ( REQUIRED_FIRMWARE_VERSION > fwversion) { + sprintf(firmware_message, "This firmware version (%lld) is incompatible.\n" "Please update firmware (min. %lld) to be compatible with this server.\n", (long long int)fwversion, (long long int)REQUIRED_FIRMWARE_VERSION); - cprintf(RED,"%s\n\n", firmware_message); + FILE_LOG(logERROR, (firmware_message)); firmware_compatibility = FAIL; firmware_check_done = 1; return; } - printf("Compatibility - success\n"); + FILE_LOG(logINFO, ("Compatibility - success\n")); firmware_check_done = 1; } @@ -200,13 +182,13 @@ void checkFirmwareCompatibility(){ /* Ids */ -int64_t getDetectorId(enum idMode arg){ +int64_t getDetectorId(enum idMode arg) { #ifdef VIRTUAL return 0; #else int64_t retval = -1; - switch(arg){ + switch(arg) { case DETECTOR_SERIAL_NUMBER: retval = getDetectorNumber();/** to be implemented with mac? */ break; @@ -215,7 +197,7 @@ int64_t getDetectorId(enum idMode arg){ case SOFTWARE_FIRMWARE_API_VERSION: return (int64_t)Beb_GetFirmwareSoftwareAPIVersion(); case DETECTOR_SOFTWARE_VERSION: - return (GITDATE & 0xFFFFFF); + return (GITDATE & 0xFFFFFF); case CLIENT_SOFTWARE_API_VERSION: return APIEIGER; default: @@ -236,7 +218,7 @@ u_int64_t getFirmwareVersion() { -u_int32_t getDetectorNumber(){ +u_int32_t getDetectorNumber() { #ifdef VIRTUAL return 0; #else @@ -262,22 +244,22 @@ u_int64_t getDetectorMAC() { //getting rid of ":" char * pch; pch = strtok (output,":"); - while (pch != NULL){ + while (pch != NULL) { strcat(mac,pch); pch = strtok (NULL, ":"); } sscanf(mac,"%llx",&res); //increment by 1 for 10g - if(send_to_ten_gig) + if (send_to_ten_gig) res++; - //printf("mac:%llx\n",res); + //FILE_LOG(logINFO, ("mac:%llx\n",res)); return res; #endif } -u_int32_t getDetectorIP(){ +u_int32_t getDetectorIP() { #ifdef VIRTUAL return 0; #endif @@ -298,7 +280,7 @@ u_int32_t getDetectorIP(){ } strcpy(output,temp); sscanf(output, "%x", &res); - //printf("ip:%x\n",res); + //FILE_LOG(logINFO, ("ip:%x\n",res)); return res; } @@ -309,11 +291,10 @@ u_int32_t getDetectorIP(){ /* initialization */ -void initControlServer(){ +void initControlServer() { #ifdef VIRTUAL getModuleConfiguration(); setupDetector(); - printf("\n"); return; #else //Feb and Beb Initializations @@ -322,38 +303,35 @@ void initControlServer(){ Feb_Control_FebControl(); Feb_Control_Init(master,top,normal, getDetectorNumber()); //master of 9M, check high voltage serial communication to blackfin - if(master && !normal){ - if(Feb_Control_OpenSerialCommunication()) - ;// Feb_Control_CloseSerialCommunication(); + if (master && !normal) { + if (Feb_Control_OpenSerialCommunication()) + ;// Feb_Control_CloseSerialCommunication(); } - printf("FEB Initialization done\n"); - Beb_Beb(); + FILE_LOG(logDEBUG5, ("Control server: FEB Initialization done\n")); + Beb_Beb(detid); Beb_SetDetectorNumber(getDetectorNumber()); - printf("BEB Initialization done\n"); + FILE_LOG(logDEBUG5, ("Control server: BEB Initialization done\n")); setupDetector(); #endif - printf("\n"); } -void initStopServer(){ +void initStopServer() { #ifdef VIRTUAL getModuleConfiguration(); - printf("\n"); return; #else getModuleConfiguration(); Feb_Interface_FebInterface(); Feb_Control_FebControl(); Feb_Control_Init(master,top,normal,getDetectorNumber()); - printf("FEB Initialization done\n"); + FILE_LOG(logDEBUG5, ("Stop server: FEB Initialization done\n")); #endif - printf("\n"); } -void getModuleConfiguration(){ +void getModuleConfiguration() { #ifdef VIRTUAL #ifdef VIRTUAL_MASTER master = 1; @@ -367,24 +345,22 @@ void getModuleConfiguration(){ #else normal = 1; #endif - if(top) printf("*************** TOP ***************\n"); - else printf("*************** BOTTOM ***************\n"); - if(master) printf("*************** MASTER ***************\n"); - else printf("*************** SLAVE ***************\n"); - if(normal) printf("*************** NORMAL ***************\n"); - else printf("*************** SPECIAL ***************\n"); + FILE_LOG(logINFOBLUE, ("Module: %s %s %s\n", + (top ? "TOP" : "BOTTOM"), + (master ? "MASTER" : "SLAVE"), + (normal ? "NORMAL" : "SPECIAL"))); return; #else int *m=&master; int *t=⊤ int *n=&normal; Beb_GetModuleConfiguration(m,t,n); - if(top) printf("*************** TOP ***************\n"); - else printf("*************** BOTTOM ***************\n"); - if(master) printf("*************** MASTER ***************\n"); - else printf("*************** SLAVE ***************\n"); - if(normal) printf("*************** NORMAL ***************\n"); - else printf("*************** SPECIAL ***************\n"); + if (isControlServer) { + FILE_LOG(logINFOBLUE, ("Module: %s %s %s\n", + (top ? "TOP" : "BOTTOM"), + (master ? "MASTER" : "SLAVE"), + (normal ? "NORMAL" : "SPECIAL"))); + } // read detector id char output[255]; @@ -392,7 +368,9 @@ void getModuleConfiguration(){ fgets(output, sizeof(output), sysFile); pclose(sysFile); sscanf(output,"%u",&detid); - printf("detector id: %u\n",detid); + if (isControlServer) { + FILE_LOG(logINFOBLUE, ("Detector ID: %u\n\n", detid)); + } #endif } @@ -400,8 +378,8 @@ void getModuleConfiguration(){ /* set up detector */ -void allocateDetectorStructureMemory(){ - printf("This Server is for 1 Eiger half module (250k)\n"); +void allocateDetectorStructureMemory() { + FILE_LOG(logINFO, ("This Server is for 1 Eiger half module (250k)\n\n")); //Allocation of memory detectorModules=malloc(sizeof(sls_detector_module)); @@ -409,13 +387,11 @@ void allocateDetectorStructureMemory(){ detectorChans=malloc(NCHIP*NCHAN*sizeof(int)); detectorDacs=malloc(NDAC*sizeof(int)); detectorAdcs=malloc(NADC*sizeof(int)); -#ifdef VERBOSE - printf("modules from 0x%x to 0x%x\n",detectorModules, detectorModules+n); - printf("chips from 0x%x to 0x%x\n",detectorChips, detectorChips+n*NCHIP); - printf("chans from 0x%x to 0x%x\n",detectorChans, detectorChans+n*NCHIP*NCHAN); - printf("dacs from 0x%x to 0x%x\n",detectorDacs, detectorDacs+n*NDAC); - printf("adcs from 0x%x to 0x%x\n",detectorAdcs, detectorAdcs+n*NADC); -#endif + FILE_LOG(logDEBUG5, ("modules from 0x%x to 0x%x\n",detectorModules, detectorModules)); + FILE_LOG(logDEBUG5, ("chips from 0x%x to 0x%x\n",detectorChips, detectorChips)); + FILE_LOG(logDEBUG5, ("chans from 0x%x to 0x%x\n",detectorChans, detectorChans)); + FILE_LOG(logDEBUG5, ("dacs from 0x%x to 0x%x\n",detectorDacs, detectorDacs)); + FILE_LOG(logDEBUG5, ("adcs from 0x%x to 0x%x\n",detectorAdcs, detectorAdcs)); (detectorModules)->dacs=detectorDacs; (detectorModules)->adcs=detectorAdcs; (detectorModules)->chipregs=detectorChips; @@ -442,18 +418,20 @@ void setupDetector() { allocateDetectorStructureMemory(); //set dacs - printf("Setting Default Dac values\n"); + FILE_LOG(logINFOBLUE, ("Setting Default Dac values\n")); { int i = 0; int retval[2]={-1,-1}; const int defaultvals[NDAC] = DEFAULT_DAC_VALS; for(i = 0; i < NDAC; ++i) { setDAC((enum DACINDEX)i,defaultvals[i],0,retval); - if (retval[0] != defaultvals[i]) - cprintf(RED, "Warning: Setting dac %d failed, wrote %d, read %d\n",i ,defaultvals[i], retval[0]); + if (retval[0] != defaultvals[i]) { + FILE_LOG(logERROR, ("Setting dac %d failed, wrote %d, read %d\n",i ,defaultvals[i], retval[0])); + } } } + FILE_LOG(logINFOBLUE, ("Setting Default Parameters\n")); //setting default measurement parameters setTimer(FRAME_NUMBER, DEFAULT_NUM_FRAMES); setTimer(ACQUISITION_TIME, DEFAULT_EXPTIME); @@ -466,7 +444,7 @@ void setupDetector() { setReadOutFlags(DEFAULT_READOUT_MODE); setReadOutFlags(DEFAULT_READOUT_STOREINRAM_MODE); setReadOutFlags(DEFAULT_READOUT_OVERFLOW32_MODE); - setSpeed(CLOCK_DIVIDER, DEFAULT_CLK_SPEED);//clk_devider,half speed + setSpeed(DEFAULT_CLK_SPEED);//clk_devider,half speed setIODelay(DEFAULT_IO_DELAY); setTiming(DEFAULT_TIMING_MODE); //SetPhotonEnergyCalibrationParameters(-5.8381e-5,1.838515,5.09948e-7,-4.32390e-11,1.32527e-15); @@ -480,6 +458,7 @@ void setupDetector() { #ifndef VIRTUAL Feb_Control_CheckSetup(); #endif + FILE_LOG(logDEBUG5, ("Setup detector done\n\n")); } @@ -506,25 +485,25 @@ uint32_t readRegister(uint32_t offset) { /* set parameters - dr, roi */ -int setDynamicRange(int dr){ +int setDynamicRange(int dr) { #ifdef VIRTUAL - if(dr > 0){ - printf(" Setting dynamic range: %d\n",dr); + if (dr > 0) { + FILE_LOG(logINFO, ("Setting dynamic range: %d\n", dr)); eiger_dynamicrange = dr; } return eiger_dynamicrange; #else - if(dr > 0){ - printf(" Setting dynamic range: %d\n",dr); - if(Feb_Control_SetDynamicRange(dr)){ + if (dr > 0) { + FILE_LOG(logDEBUG5, ("Setting dynamic range: %d\n", dr)); + if (Feb_Control_SetDynamicRange(dr)) { //EigerSetBitMode(dr); on_dst = 0; int i; for(i=0;i<32;i++) dst_requested[i] = 0; //clear dst requested - if(Beb_SetUpTransferParameters(dr)) + if (Beb_SetUpTransferParameters(dr)) eiger_dynamicrange = dr; - else printf("ERROR:Could not set bit mode in the back end\n"); + else FILE_LOG(logERROR, ("Could not set bit mode in the back end\n")); } } //make sure back end and front end have the same bit mode @@ -539,15 +518,12 @@ int setDynamicRange(int dr){ /* parameters - readout */ -int setSpeed(enum speedVariable arg, int val){ +enum speedVariable setSpeed(int val) { - if (arg != CLOCK_DIVIDER) - return -1; - - if(val != -1){ - printf(" Setting Read out Speed: %d\n",val); + if (val != -1) { + FILE_LOG(logDEBUG5, ("Setting Read out Speed: %d\n", val)); #ifndef VIRTUAL - if(Feb_Control_SetReadoutSpeed(val)) + if (Feb_Control_SetReadoutSpeed(val)) #endif eiger_readoutspeed = val; } @@ -555,25 +531,33 @@ int setSpeed(enum speedVariable arg, int val){ } -enum readOutFlags setReadOutFlags(enum readOutFlags val){ +enum readOutFlags setReadOutFlags(enum readOutFlags val) { enum readOutFlags retval = GET_READOUT_FLAGS; - if(val!=GET_READOUT_FLAGS){ + if (val!=GET_READOUT_FLAGS) { - if(val&0xF0000){ - switch(val){ - case PARALLEL: val=E_PARALLEL; printf(" Setting Read out Flag: Parallel\n"); break; - case NONPARALLEL: val=E_NON_PARALLEL; printf(" Setting Read out Flag: Non Parallel\n"); break; - case SAFE: val=E_SAFE; printf(" Setting Read out Flag: Safe\n"); break; + if (val&0xF0000) { + switch(val) { + case PARALLEL: + val=E_PARALLEL; + FILE_LOG(logDEBUG5, ("Setting Read out Flag: Parallel\n")); + break; + case NONPARALLEL: + val=E_NON_PARALLEL; + FILE_LOG(logDEBUG5, ("Setting Read out Flag: Non Parallel\n")); + break; + case SAFE: + val=E_SAFE; + FILE_LOG(logDEBUG5, ("Setting Read out Flag: Safe\n")); + break; default: - cprintf(RED,"Cannot set unknown readout flag. 0x%x\n", val); + FILE_LOG(logERROR, ("Cannot set unknown readout flag. 0x%x\n", val)); return -1; } - printf(" Setting Read out Flag: %d\n",val); #ifndef VIRTUAL - if(Feb_Control_SetReadoutMode(val)) + if (Feb_Control_SetReadoutMode(val)) #endif eiger_readoutmode = val; #ifndef VIRTUAL @@ -583,16 +567,21 @@ enum readOutFlags setReadOutFlags(enum readOutFlags val){ } else if (val&0xF00000) { - switch(val){ - case SHOW_OVERFLOW: val=1; printf(" Setting Read out Flag: Overflow in 32 bit mode\n"); break; - case NOOVERFLOW: val=0; printf(" Setting Read out Flag: No overflow in 32 bit mode\n"); break; + switch(val) { + case SHOW_OVERFLOW: + val=1; + FILE_LOG(logDEBUG5, ("Setting Read out Flag: Overflow in 32 bit mode\n")); + break; + case NOOVERFLOW: + val=0; + FILE_LOG(logDEBUG5, ("Setting Read out Flag: No overflow in 32 bit mode\n")); + break; default: - cprintf(RED,"Cannot set unknown readout flag. 0x%x\n", val); + FILE_LOG(logERROR, ("Cannot set unknown readout flag. 0x%x\n", val)); return -1; } - printf(" Setting Read out Flag: %d\n",val); #ifndef VIRTUAL - if(Beb_Set32bitOverflow(val) != -1) + if (Beb_Set32bitOverflow(val) != -1) #endif eiger_overflow32 = val; #ifndef VIRTUAL @@ -601,41 +590,58 @@ enum readOutFlags setReadOutFlags(enum readOutFlags val){ } - else{ - switch(val){ - case STORE_IN_RAM: val=1; printf(" Setting Read out Flag: Store in Ram\n"); break; - case CONTINOUS_RO: val=0; printf(" Setting Read out Flag: Continuous Readout\n"); break; + else { + switch(val) { + case STORE_IN_RAM: + val=1; + FILE_LOG(logDEBUG5, ("Setting Read out Flag: Store in Ram\n")); + break; + case CONTINOUS_RO: + val=0; + FILE_LOG(logDEBUG5, ("Setting Read out Flag: Continuous Readout\n")); + break; default: - cprintf(RED,"Cannot set unknown readout flag. 0x%x\n", val); + FILE_LOG(logERROR, ("Cannot set unknown readout flag. 0x%x\n", val)); return -1; } - printf(" Setting store in ram variable: %d\n",val); eiger_storeinmem = val; } } - switch(eiger_readoutmode){ - case E_PARALLEL: retval=PARALLEL; break; - case E_NON_PARALLEL: retval=NONPARALLEL; break; - case E_SAFE: retval=SAFE; break; + switch(eiger_readoutmode) { + case E_PARALLEL: + retval=PARALLEL; + break; + case E_NON_PARALLEL: + retval=NONPARALLEL; + break; + case E_SAFE: + retval=SAFE; + break; } - switch(eiger_overflow32){ - case 1: retval|=SHOW_OVERFLOW; break; - case 0: retval|=NOOVERFLOW; break; + switch(eiger_overflow32) { + case 1: + retval|=SHOW_OVERFLOW; + break; + case 0: + retval|=NOOVERFLOW; + break; } - switch(eiger_storeinmem){ - case 0: retval|=CONTINOUS_RO; break; - case 1: retval|=STORE_IN_RAM; break; + switch(eiger_storeinmem) { + case 0: + retval|=CONTINOUS_RO; + break; + case 1: + retval|=STORE_IN_RAM; + break; } - - - printf("Read out Flag: 0x%x\n",retval); + FILE_LOG(logDEBUG5, ("Read out Flag: 0x%x\n", retval)); return retval; } @@ -648,17 +654,17 @@ enum readOutFlags setReadOutFlags(enum readOutFlags val){ /* parameters - timer */ -int64_t setTimer(enum timerIndex ind, int64_t val){ +int64_t setTimer(enum timerIndex ind, int64_t val) { #ifndef VIRTUAL int64_t subdeadtime = 0; #endif int64_t subexptime = 0; - switch(ind){ + switch(ind) { case FRAME_NUMBER: - if(val >= 0){ - printf(" Setting number of frames: %d * %d\n",(unsigned int)val,eiger_ncycles); + if (val >= 0) { + FILE_LOG(logDEBUG5, ("Setting number of frames: %d * %d\n", (unsigned int)val, eiger_ncycles)); #ifndef VIRTUAL - if(Feb_Control_SetNExposures((unsigned int)val*eiger_ncycles)){ + if (Feb_Control_SetNExposures((unsigned int)val*eiger_ncycles)) { eiger_nexposures = val; //SetDestinationParameters(EigerGetNumberOfExposures()*EigerGetNumberOfCycles()); on_dst = 0; @@ -674,8 +680,8 @@ int64_t setTimer(enum timerIndex ind, int64_t val){ }return eiger_nexposures; case ACQUISITION_TIME: - if(val >= 0){ - printf(" Setting exp time: %fs\n",val/(1E9)); + if (val >= 0) { + FILE_LOG(logDEBUG5, ("Setting exp time: %fs\n", val/(1E9))); #ifndef VIRTUAL Feb_Control_SetExposureTime(val/(1E9)); #else @@ -689,8 +695,8 @@ int64_t setTimer(enum timerIndex ind, int64_t val){ #endif case SUBFRAME_ACQUISITION_TIME: - if(val >= 0){ - printf(" Setting sub exp time: %lldns\n",(long long int)val); + if (val >= 0) { + FILE_LOG(logDEBUG5, ("Setting sub exp time: %lldns\n", (long long int)val)); #ifndef VIRTUAL // calculate subdeadtime before settings subexptime subdeadtime = Feb_Control_GetSubFramePeriod() - @@ -714,16 +720,16 @@ int64_t setTimer(enum timerIndex ind, int64_t val){ case SUBFRAME_DEADTIME: #ifndef VIRTUAL - // get subexptime - subexptime = Feb_Control_GetSubFrameExposureTime(); + // get subexptime + subexptime = Feb_Control_GetSubFrameExposureTime(); #else - subexptime = eiger_virtual_subexptime*10; + subexptime = eiger_virtual_subexptime*10; #endif - if(val >= 0){ - printf(" Setting sub period: %lldns = subexptime(%lld) + subdeadtime(%lld)\n", - (long long int)(val + subexptime), + if (val >= 0) { + FILE_LOG(logINFO, ("Setting sub period (subdeadtime(%lld)): %lldns\n", (long long int)subexptime, - (long long int)val); + (long long int)val), + (long long int)(val + subexptime)); //calculate subperiod val += subexptime; #ifndef VIRTUAL @@ -739,8 +745,8 @@ int64_t setTimer(enum timerIndex ind, int64_t val){ #endif case FRAME_PERIOD: - if(val >= 0){ - printf(" Setting acq period: %fs\n",val/(1E9)); + if (val >= 0) { + FILE_LOG(logDEBUG5, ("Setting acq period: %fs\n", val/(1E9))); #ifndef VIRTUAL Feb_Control_SetExposurePeriod(val/(1E9)); #else @@ -754,10 +760,11 @@ int64_t setTimer(enum timerIndex ind, int64_t val){ #endif case CYCLES_NUMBER: - if(val >= 0){ - printf(" Setting number of triggers: %d * %d\n",(unsigned int)val,eiger_nexposures); + if (val >= 0) { + FILE_LOG(logDEBUG5, ("Setting number of triggers: %d * %d\n", + (unsigned int)val,eiger_nexposures)); #ifndef VIRTUAL - if(Feb_Control_SetNExposures((unsigned int)val*eiger_nexposures)){ + if (Feb_Control_SetNExposures((unsigned int)val*eiger_nexposures)) { eiger_ncycles = val; //SetDestinationParameters(EigerGetNumberOfExposures()*EigerGetNumberOfCycles()); on_dst = 0; @@ -772,7 +779,7 @@ int64_t setTimer(enum timerIndex ind, int64_t val){ } return eiger_ncycles; default: - cprintf(RED,"Warning: Timer Index not implemented for this detector: %d\n", ind); + FILE_LOG(logERROR, ("Timer Index not implemented for this detector: %d\n", ind)); break; } @@ -784,12 +791,12 @@ int64_t getTimeLeft(enum timerIndex ind) { #ifdef VIRTUAL return 0; #else - switch(ind){ + switch(ind) { case MEASURED_PERIOD: return Feb_Control_GetMeasuredPeriod(); case MEASURED_SUBPERIOD: return Feb_Control_GetSubMeasuredPeriod(); return 0; default: - cprintf(RED,"This timer left index (%d) not defined for Eiger\n",ind); + FILE_LOG(logERROR, ("This timer left index (%d) not defined for Eiger\n", ind)); return -1; } #endif @@ -801,13 +808,11 @@ int64_t getTimeLeft(enum timerIndex ind) { /* parameters - channel, chip, module, settings */ -int setModule(sls_detector_module myMod, int delay){ +int setModule(sls_detector_module myMod, int delay) { int retval[2]; int i; - //#ifdef VERBOSE - printf("Setting module with settings %d\n",myMod.reg); - //#endif + FILE_LOG(logINFO, ("Setting module with settings %d\n",myMod.reg)); //copy module locally (module number, serial number, gain offset, //dacs (pointless), trimbit values(if needed) @@ -819,8 +824,8 @@ int setModule(sls_detector_module myMod, int delay){ setSettings( (enum detectorSettings)myMod.reg); // iodelay - if(setIODelay(delay)!= delay){ - cprintf(RED,"could not set iodelay %d\n",delay); + if (setIODelay(delay)!= delay) { + FILE_LOG(logERROR, ("Could not set iodelay %d\n", delay)); return FAIL; } @@ -830,10 +835,10 @@ int setModule(sls_detector_module myMod, int delay){ // trimbits #ifndef VIRTUAL - if(myMod.nchan==0 && myMod.nchip == 0) - cprintf(BLUE,"Setting module without trimbits\n"); - else{ - printf("Setting module with trimbits\n"); + if (myMod.nchan==0 && myMod.nchip == 0) { + FILE_LOG(logINFO, ("Setting module without trimbits\n")); + } else { + FILE_LOG(logINFO, ("Setting module with trimbits\n")); //includ gap pixels unsigned int tt[263680]; int iy,ichip,ix,ip=0,ich=0; @@ -850,8 +855,8 @@ int setModule(sls_detector_module myMod, int delay){ } //set trimbits - if(!Feb_Control_SetTrimbits(Feb_Control_GetModuleNumber(),tt)){ - cprintf(BG_RED,"Could not set trimbits\n"); + if (!Feb_Control_SetTrimbits(Feb_Control_GetModuleNumber(),tt)) { + FILE_LOG(logERROR, ("Could not set trimbits\n")); return FAIL; } } @@ -860,7 +865,7 @@ int setModule(sls_detector_module myMod, int delay){ } -int getModule(sls_detector_module *myMod){ +int getModule(sls_detector_module *myMod) { #ifndef VIRTUAL int i; @@ -869,7 +874,7 @@ int getModule(sls_detector_module *myMod){ //dacs for(i=0;idacs)+i)); + //FILE_LOG(logINFO,"dac%d:%d\n",i, *((detectorModules->dacs)+i)); } //trimbits @@ -895,7 +900,7 @@ int getModule(sls_detector_module *myMod){ if (detectorModules) { if (copyModule(myMod, detectorModules) == FAIL) return FAIL; - } + } else return FAIL; return OK; @@ -903,16 +908,16 @@ int getModule(sls_detector_module *myMod){ -enum detectorSettings setSettings(enum detectorSettings sett){ - if(sett == UNINITIALIZED){ +enum detectorSettings setSettings(enum detectorSettings sett) { + if (sett == UNINITIALIZED) { return thisSettings; - }if(sett != GET_SETTINGS) + }if (sett != GET_SETTINGS) thisSettings = sett; - printf(" Settings: %d\n", thisSettings); + FILE_LOG(logINFO, ("Settings: %d\n", thisSettings)); return thisSettings; } -enum detectorSettings getSettings(){ +enum detectorSettings getSettings() { return thisSettings; } @@ -923,15 +928,15 @@ enum detectorSettings getSettings(){ /* parameters - threshold */ -int getThresholdEnergy(){ - printf(" Getting Threshold energy\n"); +int getThresholdEnergy() { + FILE_LOG(logINFO, ("Getting Threshold energy\n")); return eiger_photonenergy; } -int setThresholdEnergy(int ev){ - printf(" Setting threshold energy:%d\n",ev); - if(ev >= 0) +int setThresholdEnergy(int ev) { + FILE_LOG(logINFO, ("Setting threshold energy:%d\n",ev)); + if (ev >= 0) eiger_photonenergy = ev; return getThresholdEnergy(); } @@ -942,61 +947,55 @@ int setThresholdEnergy(int ev){ /* parameters - dac, adc, hv */ -void setDAC(enum DACINDEX ind, int val, int mV, int retval[]){ - printf("Going to set dac %d to %d with mv mode %d \n", (int)ind, val, mV); - if(ind == VTHRESHOLD){ +void setDAC(enum DACINDEX ind, int val, int mV, int retval[]) { + FILE_LOG(logDEBUG5, ("Going to set dac %d to %d with mv mode %d \n", (int)ind, val, mV)); + if (ind == VTHRESHOLD) { int ret[5]; setDAC(VCMP_LL,val,mV,retval); - ret[0] = retval[mV]; + ret[0] = retval[mV]; setDAC(VCMP_LR,val,mV,retval); - ret[1] = retval[mV]; + ret[1] = retval[mV]; setDAC(VCMP_RL,val,mV,retval); - ret[2] = retval[mV]; + ret[2] = retval[mV]; setDAC(VCMP_RR,val,mV,retval); - ret[3] = retval[mV]; + ret[3] = retval[mV]; setDAC(VCP,val,mV,retval); - ret[4] = retval[mV]; + ret[4] = retval[mV]; - if((ret[0]== ret[1])&& + if ((ret[0]== ret[1])&& (ret[1]==ret[2])&& (ret[2]==ret[3]) && - (ret[3]==ret[4])) - cprintf(GREEN,"vthreshold match\n"); - else{ - retval[0] = -1;retval[1] = -1; - cprintf(RED,"vthreshold mismatch 0:%d 1:%d 2:%d 3:%d\n", - ret[0],ret[1],ret[2],ret[3]); + (ret[3]==ret[4])) { + FILE_LOG(logINFO, ("vthreshold match\n")); + } else { + retval[0] = -1;retval[1] = -1; + FILE_LOG(logERROR, ("vthreshold mismatch 0:%d 1:%d 2:%d 3:%d\n", + ret[0],ret[1],ret[2],ret[3])); } return; } char iname[10]; - if(((int)ind>=0)&&((int)ind=0)&&((int)ind= 0) - printf("Setting dac %d: %s to %d ",ind, iname,val); - else - printf("Getting dac %d: %s ",ind, iname); - if(mV) - printf("in mV\n"); - else - printf("in dac units\n"); -#endif + FILE_LOG(logDEBUG5, ("%s dac %d: %s to %d %s\n", + (val >= 0) ? "Setting" : "Getting", + ind, iname, val, + mV ? "mV" : "dac units")); #ifdef VIRTUAL - if (mV){ + if (mV) { retval[0] = (int)(((val-0)/(2048-0))*(4096-1) + 0.5); retval[1] = val; - }else + } else retval[0] = val; #else - if(val >= 0) + if (val >= 0) Feb_Control_SetDAC(iname,val,mV); int k; Feb_Control_GetDAC(iname, &k,0); @@ -1010,7 +1009,7 @@ void setDAC(enum DACINDEX ind, int val, int mV, int retval[]){ -int getADC(enum ADCINDEX ind){ +int getADC(enum ADCINDEX ind) { #ifdef VIRTUAL return 0; #else @@ -1018,43 +1017,43 @@ int getADC(enum ADCINDEX ind){ char tempnames[6][20]={"FPGA EXT", "10GE","DCDC", "SODL", "SODR", "FPGA"}; char cstore[255]; - switch(ind){ - case TEMP_FPGA: - retval=getBebFPGATemp(); - break; - case TEMP_FPGAFEBL: - retval=Feb_Control_GetLeftFPGATemp(); - break; - case TEMP_FPGAFEBR: - retval=Feb_Control_GetRightFPGATemp(); - break; - case TEMP_FPGAEXT: - case TEMP_10GE: - case TEMP_DCDC: - case TEMP_SODL: - case TEMP_SODR: - sprintf(cstore,"more /sys/class/hwmon/hwmon%d/device/temp1_input",ind); - FILE* sysFile = popen(cstore, "r"); - fgets(cstore, sizeof(cstore), sysFile); - pclose(sysFile); - sscanf(cstore,"%d",&retval); - break; - default: - return -1; + switch(ind) { + case TEMP_FPGA: + retval=getBebFPGATemp(); + break; + case TEMP_FPGAFEBL: + retval=Feb_Control_GetLeftFPGATemp(); + break; + case TEMP_FPGAFEBR: + retval=Feb_Control_GetRightFPGATemp(); + break; + case TEMP_FPGAEXT: + case TEMP_10GE: + case TEMP_DCDC: + case TEMP_SODL: + case TEMP_SODR: + sprintf(cstore,"more /sys/class/hwmon/hwmon%d/device/temp1_input",ind); + FILE* sysFile = popen(cstore, "r"); + fgets(cstore, sizeof(cstore), sysFile); + pclose(sysFile); + sscanf(cstore,"%d",&retval); + break; + default: + return -1; } - printf("Temperature %s: %f°C\n",tempnames[ind],(double)retval/1000.00); + FILE_LOG(logINFO, ("Temperature %s: %f°C\n", tempnames[ind], (double)retval/1000.00)); return retval; #endif } -int setHighVoltage(int val){ +int setHighVoltage(int val) { #ifdef VIRTUAL if (master) { // set - if(val!=-1){ + if (val!=-1) { eiger_theo_highvoltage = val; } return eiger_theo_highvoltage; @@ -1066,10 +1065,10 @@ int setHighVoltage(int val){ if (master) { // set - if(val!=-1){ + if (val!=-1) { eiger_theo_highvoltage = val; int ret = Feb_Control_SetHighVoltage(val); - if(!ret) //could not set + if (!ret) //could not set return -2; else if (ret == -1) //outside range return -1; @@ -1077,13 +1076,13 @@ int setHighVoltage(int val){ // get if (!Feb_Control_GetHighVoltage(&eiger_highvoltage)) { - cprintf(RED,"Warning: Could not read high voltage\n"); + FILE_LOG(logERROR, ("Could not read high voltage\n")); return -3; } // tolerance of 5 if (abs(eiger_theo_highvoltage-eiger_highvoltage) > HIGH_VOLTAGE_TOLERANCE) { - cprintf(BLUE, "High voltage still ramping: %d\n", eiger_highvoltage); + FILE_LOG(logINFO, ("High voltage still ramping: %d\n", eiger_highvoltage)); return eiger_highvoltage; } return eiger_theo_highvoltage; @@ -1101,18 +1100,18 @@ int setHighVoltage(int val){ /* parameters - timing, extsig */ -void setTiming( enum externalCommunicationMode arg){ +void setTiming( enum externalCommunicationMode arg) { enum externalCommunicationMode ret=GET_EXTERNAL_COMMUNICATION_MODE; - if(arg != GET_EXTERNAL_COMMUNICATION_MODE){ - switch((int)arg){ + if (arg != GET_EXTERNAL_COMMUNICATION_MODE) { + switch((int)arg) { case AUTO_TIMING: ret = 0; break; case TRIGGER_EXPOSURE: ret = 2; break; case BURST_TRIGGER: ret = 1; break; case GATE_FIX_NUMBER: ret = 3; break; } - printf(" Setting Triggering Mode: %d\n",(int)ret); + FILE_LOG(logDEBUG5, ("Setting Triggering Mode: %d\n", (int)ret)); #ifndef VIRTUAL - if(Feb_Control_SetTriggerMode(ret,1)) + if (Feb_Control_SetTriggerMode(ret,1)) #endif eiger_triggermode = ret; } @@ -1122,13 +1121,13 @@ void setTiming( enum externalCommunicationMode arg){ enum externalCommunicationMode getTiming() { enum externalCommunicationMode ret = GET_EXTERNAL_COMMUNICATION_MODE; ret = eiger_triggermode; - switch((int)ret){ + switch((int)ret) { case 0: ret = AUTO_TIMING; break; case 2: ret = TRIGGER_EXPOSURE; break; case 1: ret = BURST_TRIGGER; break; case 3: ret = GATE_FIX_NUMBER; break; default: - printf("Unknown trigger mode found %d\n",ret); + FILE_LOG(logERROR, ("Unknown trigger mode found %d\n", ret)); ret = 0; } return ret; @@ -1138,7 +1137,7 @@ enum externalCommunicationMode getTiming() { /* configure mac */ -int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport, uint32_t udpport2, int ival) { +int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport, uint32_t udpport2) { #ifndef VIRTUAL char src_mac[50], src_ip[50],dst_mac[50], dst_ip[50]; int src_port = 0xE185; @@ -1157,40 +1156,47 @@ int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t (unsigned int)((destmac>>8)&0xFF), (unsigned int)((destmac>>0)&0xFF)); - printf("src_port:%d\n",src_port); - printf("src_ip:%s\n",src_ip); - printf("dst_ip:%s\n",dst_ip); - printf("src_mac:%s\n",src_mac); - printf("dst_mac:%s\n",dst_mac); - int beb_num = BEB_NUM;//Feb_Control_GetModuleNumber(); + FILE_LOG(logINFO, ("src_port:%d\n" + "src_ip:%s\n" + "dst_ip:%s\n" + "src_mac:%s\n" + "dst_mac:%s\n", + src_port, src_ip, dst_ip, src_mac, dst_mac)); + + + int beb_num = detid; int header_number = 0; int dst_port = udpport; - if(!top) + if (!top) dst_port = udpport2; - printf("dst_port:%d\n\n",dst_port); + FILE_LOG(logINFO, ("dst_port:%d\n", dst_port)); int i=0; - /* for(i=0;i<32;i++){ modified for Aldo*/ - if(Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,src_port) && - Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) - printf("set up left ok\n"); - else return -1; + /* for(i=0;i<32;i++) { modified for Aldo*/ + if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,src_port) && + Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) { + FILE_LOG(logINFO, ("set up left ok\n")); + } else { + return -1; + } /*}*/ header_number = 32; dst_port = udpport2; - if(!top) + if (!top) dst_port = udpport; - printf("dst_port:%d\n\n",dst_port); + FILE_LOG(logINFO, ("dst_port:%d\n",dst_port)); - /*for(i=0;i<32;i++){*//** modified for Aldo*/ - if(Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,src_port) && - Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) - printf("set up right ok\n\n"); - else return -1; + /*for(i=0;i<32;i++) {*//** modified for Aldo*/ + if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,src_port) && + Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) { + FILE_LOG(logINFO, ("set up right ok\n")); + } else { + return -1; + } /*}*/ on_dst = 0; @@ -1217,11 +1223,11 @@ int setDetectorPosition(int pos[]) { /* eiger specific - iodelay, 10g, pulse, rate, temp, activate, delay nw parameter */ -int setIODelay(int val){ - if(val!=-1){ - printf(" Setting IO Delay: %d\n",val); +int setIODelay(int val) { + if (val!=-1) { + FILE_LOG(logDEBUG5, ("Setting IO Delay: %d\n",val)); #ifndef VIRTUAL - if(Feb_Control_SetIDelays(Feb_Control_GetModuleNumber(),val)) + if (Feb_Control_SetIDelays(Feb_Control_GetModuleNumber(),val)) #endif eiger_iodelay = val; } @@ -1229,30 +1235,26 @@ int setIODelay(int val){ } -int enableTenGigabitEthernet(int val){ - if(val!=-1){ - if(val>0) +int enableTenGigabitEthernet(int val) { + if (val!=-1) { + FILE_LOG(logINFO, ("Setting 10Gbe: %d\n", (val > 0) ? 1 : 0)); + if (val>0) send_to_ten_gig = 1; else send_to_ten_gig = 0; //configuremac called from client } -#ifdef VERBOSE - printf("10Gbe:%d\n",send_to_ten_gig); -#endif return send_to_ten_gig; } -int setCounterBit(int val){ - if(val!=-1){ +int setCounterBit(int val) { + if (val!=-1) { + FILE_LOG(logINFO, ("Setting Counter Bit: %d\n",val)); #ifdef VIRTUAL eiger_virtual_counter_bit = val; #else Feb_Control_Set_Counter_Bit(val); -#endif -#ifdef VERBOSE - printf("Counter Bit:%d\n",val); #endif } #ifdef VIRTUAL @@ -1263,45 +1265,45 @@ int setCounterBit(int val){ } -int pulsePixel(int n, int x, int y){ +int pulsePixel(int n, int x, int y) { #ifndef VIRTUAL - if(!Feb_Control_Pulse_Pixel(n,x,y)) + if (!Feb_Control_Pulse_Pixel(n,x,y)) return FAIL; #endif return OK; } -int pulsePixelNMove(int n, int x, int y){ +int pulsePixelNMove(int n, int x, int y) { #ifndef VIRTUAL - if(!Feb_Control_PulsePixelNMove(n,x,y)) + if (!Feb_Control_PulsePixelNMove(n,x,y)) return FAIL; #endif return OK; } -int pulseChip(int n){ +int pulseChip(int n) { #ifndef VIRTUAL - if(!Feb_Control_PulseChip(n)) + if (!Feb_Control_PulseChip(n)) return FAIL; #endif return OK; } -int64_t setRateCorrection(int64_t custom_tau_in_nsec){//in nanosec (will never be -1) +int64_t setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never be -1) #ifdef VIRTUAL //deactivating rate correction - if(custom_tau_in_nsec==0){ + if (custom_tau_in_nsec==0) { eiger_virtual_ratecorrection_variable = 0; return 0; } //when dynamic range changes, use old tau - else if(custom_tau_in_nsec == -1) + else if (custom_tau_in_nsec == -1) custom_tau_in_nsec = eiger_virtual_ratetable_tau_in_ns; //get period = subexptime if 32bit , else period = exptime if 16 bit int64_t actual_period = eiger_virtual_subexptime*10; //already in nsec - if(eiger_dynamicrange == 16) + if (eiger_dynamicrange == 16) actual_period = eiger_virtual_exptime; int64_t ratetable_period_in_nsec = eiger_virtual_ratetable_period_in_ns; @@ -1310,44 +1312,44 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec){//in nanosec (will never b //same setting - if((tau_in_nsec == custom_tau_in_nsec) && (ratetable_period_in_nsec == actual_period)){ - if(eiger_dynamicrange == 32) - printf("Rate Table already created before: Same Tau %lldns, Same subexptime %lldns\n", - (long long int)tau_in_nsec,(long long int)ratetable_period_in_nsec); + if ((tau_in_nsec == custom_tau_in_nsec) && (ratetable_period_in_nsec == actual_period)) { + if (eiger_dynamicrange == 32) + FILE_LOG(logINFO, ("Rate Table already created before: Same Tau %lldns, Same subexptime %lldns\n", + (long long int)tau_in_nsec,(long long int)ratetable_period_in_nsec)); else - printf("Rate Table already created before: Same Tau %lldns, Same exptime %lldns\n", - (long long int)tau_in_nsec,(long long int)ratetable_period_in_nsec); + FILE_LOG(logINFO, ("Rate Table already created before: Same Tau %lldns, Same exptime %lldns\n", + (long long int)tau_in_nsec,(long long int)ratetable_period_in_nsec)); } //different setting, calculate table - else{ + else { eiger_virtual_ratetable_tau_in_ns = custom_tau_in_nsec; double period_in_sec = (double)(eiger_virtual_subexptime*10)/(double)1e9; - if(eiger_dynamicrange == 16) + if (eiger_dynamicrange == 16) period_in_sec = eiger_virtual_exptime; eiger_virtual_ratetable_period_in_ns = period_in_sec*1e9; } //activating rate correction eiger_virtual_ratecorrection_variable = 1; - printf("Rate Correction Value set to %lld ns\n",(long long int)eiger_virtual_ratetable_tau_in_ns); + FILE_LOG(logINFO, ("Rate Correction Value set to %lld ns\n",(long long int)eiger_virtual_ratetable_tau_in_ns)); return eiger_virtual_ratetable_tau_in_ns; #else //deactivating rate correction - if(custom_tau_in_nsec==0){ + if (custom_tau_in_nsec==0) { Feb_Control_SetRateCorrectionVariable(0); return 0; } //when dynamic range changes, use old tau - else if(custom_tau_in_nsec == -1) + else if (custom_tau_in_nsec == -1) custom_tau_in_nsec = Feb_Control_Get_RateTable_Tau_in_nsec(); int dr = Feb_Control_GetDynamicRange(); //get period = subexptime if 32bit , else period = exptime if 16 bit int64_t actual_period = Feb_Control_GetSubFrameExposureTime(); //already in nsec - if(dr == 16) + if (dr == 16) actual_period = Feb_Control_GetExposureTime_in_nsec(); int64_t ratetable_period_in_nsec = Feb_Control_Get_RateTable_Period_in_nsec(); @@ -1355,35 +1357,34 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec){//in nanosec (will never b //same setting - if((tau_in_nsec == custom_tau_in_nsec) && (ratetable_period_in_nsec == actual_period)){ - if(dr == 32) - printf("Rate Table already created before: Same Tau %lldns, Same subexptime %lldns\n", - tau_in_nsec,ratetable_period_in_nsec); - else - printf("Rate Table already created before: Same Tau %lldns, Same exptime %lldns\n", - tau_in_nsec,ratetable_period_in_nsec); + if ((tau_in_nsec == custom_tau_in_nsec) && (ratetable_period_in_nsec == actual_period)) { + if (dr == 32) { + FILE_LOG(logINFO, ("Rate Table already created before: Same Tau %lldns, Same subexptime %lldns\n", + tau_in_nsec,ratetable_period_in_nsec)); + } else { + FILE_LOG(logINFO, ("Rate Table already created before: Same Tau %lldns, Same exptime %lldns\n", + tau_in_nsec,ratetable_period_in_nsec)); + } } //different setting, calculate table - else{ + else { int ret = Feb_Control_SetRateCorrectionTau(custom_tau_in_nsec); - if(ret<=0){ - cprintf(RED,"Rate correction failed. Deactivating rate correction\n"); + if (ret<=0) { + FILE_LOG(logERROR, ("Rate correction failed. Deactivating rate correction\n")); Feb_Control_SetRateCorrectionVariable(0); return ret; } } //activating rate correction Feb_Control_SetRateCorrectionVariable(1); - printf("Rate Correction Value set to %lld ns\n",(long long int)Feb_Control_Get_RateTable_Tau_in_nsec()); -#ifdef VERBOSE + FILE_LOG(logINFO, ("Rate Correction Value set to %lld ns\n", (long long int)Feb_Control_Get_RateTable_Tau_in_nsec())); Feb_Control_PrintCorrectedValues(); -#endif return Feb_Control_Get_RateTable_Tau_in_nsec(); #endif } -int getRateCorrectionEnable(){ +int getRateCorrectionEnable() { #ifdef VIRTUAL return eiger_virtual_ratecorrection_variable; #else @@ -1391,28 +1392,28 @@ int getRateCorrectionEnable(){ #endif } -int getDefaultSettingsTau_in_nsec(){ +int getDefaultSettingsTau_in_nsec() { return default_tau_from_file; } -void setDefaultSettingsTau_in_nsec(int t){ +void setDefaultSettingsTau_in_nsec(int t) { default_tau_from_file = t; - printf("Default tau set to %d\n",default_tau_from_file); + FILE_LOG(logINFO, ("Default tau set to %d\n", default_tau_from_file)); } -int64_t getCurrentTau(){ - if(!getRateCorrectionEnable()) +int64_t getCurrentTau() { + if (!getRateCorrectionEnable()) return 0; else #ifndef VIRTUAL return Feb_Control_Get_RateTable_Tau_in_nsec(); #else - return eiger_virtual_ratetable_tau_in_ns; + return eiger_virtual_ratetable_tau_in_ns; #endif } -void setExternalGating(int enable[]){ - if(enable>=0){ +void setExternalGating(int enable[]) { + if (enable>=0) { #ifndef VIRTUAL Feb_Control_SetExternalEnableMode(enable[0], enable[1]);//enable = 0 or 1, polarity = 0 or 1 , where 1 is positive #endif @@ -1423,44 +1424,41 @@ void setExternalGating(int enable[]){ enable[1] = eiger_extgatingpolarity; } -int setAllTrimbits(int val){ +int setAllTrimbits(int val) { #ifndef VIRTUAL - if(!Feb_Control_SaveAllTrimbitsTo(val)){ - cprintf(RED,"error in setting all trimbits to value\n"); + if (!Feb_Control_SaveAllTrimbitsTo(val)) { + FILE_LOG(logERROR, ("Could not set all trimbits\n")); return FAIL; } #endif -#ifdef VERBOSE - printf("Copying register %x value %d\n",destMod->reg,val); -#endif - if (detectorModules){ + if (detectorModules) { int ichan; for (ichan=0; ichan<(detectorModules->nchan); ichan++) { *((detectorModules->chanregs)+ichan)=val; } } - cprintf(GREEN, "All trimbits have been set to %d\n", val); + FILE_LOG(logINFO, ("All trimbits have been set to %d\n", val)); return OK; } -int getAllTrimbits(){ +int getAllTrimbits() { int ichan=0; int value = *((detectorModules->chanregs)); - if (detectorModules){ + if (detectorModules) { for (ichan=0; ichan<(detectorModules->nchan); ichan++) { - if(*((detectorModules->chanregs)+ichan) != value) { + if (*((detectorModules->chanregs)+ichan) != value) { value= -1; break; } } } - printf("Value of all Trimbits: %d\n", value); + FILE_LOG(logINFO, ("Value of all Trimbits: %d\n", value)); return value; } -int getBebFPGATemp(){ +int getBebFPGATemp() { #ifdef VIRTUAL return 0; #else @@ -1468,7 +1466,7 @@ int getBebFPGATemp(){ #endif } -int activate(int enable){ +int activate(int enable) { #ifdef VIRTUAL if (enable >=0) eiger_virtual_activate = enable; @@ -1480,12 +1478,12 @@ int activate(int enable){ #endif } -int setNetworkParameter(enum NETWORKINDEX mode, int value){ +int setNetworkParameter(enum NETWORKINDEX mode, int value) { #ifndef VIRTUAL return Beb_SetNetworkParameter(mode, value); #else if (value>-1) { - switch(mode){ + switch(mode) { case TXN_LEFT: eiger_virtual_transmission_delay_left = value; break; @@ -1497,13 +1495,13 @@ int setNetworkParameter(enum NETWORKINDEX mode, int value){ break; case FLOWCTRL_10G: eiger_virtual_transmission_flowcontrol_10g = value; - if(value>0) value = 1; + if (value>0) value = 1; break; - default: cprintf(BG_RED,"Unrecognized mode in network parameter: %d\n",mode); - return -1; + default: FILE_LOG(logERROR, ("Unrecognized mode in network parameter: %d\n",mode)); + return -1; } } - switch(mode){ + switch(mode) { case TXN_LEFT: return eiger_virtual_transmission_delay_left; case TXN_RIGHT: @@ -1512,8 +1510,8 @@ int setNetworkParameter(enum NETWORKINDEX mode, int value){ return eiger_virtual_transmission_delay_frame; case FLOWCTRL_10G: return eiger_virtual_transmission_flowcontrol_10g; - default: cprintf(BG_RED,"Unrecognized mode in network parameter: %d\n",mode); - return -1; + default: FILE_LOG(logERROR, ("Unrecognized mode in network parameter: %d\n",mode)); + return -1; } #endif } @@ -1527,11 +1525,11 @@ int setNetworkParameter(enum NETWORKINDEX mode, int value){ /* aquisition */ -int prepareAcquisition(){ +int prepareAcquisition() { #ifndef VIRTUAL - printf("Going to prepare for acquisition with counter_bit:%d\n",Feb_Control_Get_Counter_Bit()); + FILE_LOG(logINFO, ("Going to prepare for acquisition with counter_bit:%d\n",Feb_Control_Get_Counter_Bit())); Feb_Control_PrepareForAcquisition(); - printf("Going to reset Frame Number\n"); + FILE_LOG(logINFO, ("Going to reset Frame Number\n")); Beb_ResetFrameNumber(); #endif return OK; @@ -1539,16 +1537,16 @@ int prepareAcquisition(){ } -int startStateMachine(){ +int startStateMachine() { #ifdef VIRTUAL eiger_virtual_status = 1; eiger_virtual_stop = 0; - if(pthread_create(&eiger_virtual_tid, NULL, &start_timer, NULL)) { - cprintf(RED,"Could not start Virtual acquisition thread\n"); + if (pthread_create(&eiger_virtual_tid, NULL, &start_timer, NULL)) { + FILE_LOG(logERROR, ("Could not start Virtual acquisition thread\n")); eiger_virtual_status = 0; return FAIL; } - cprintf(GREEN,"***Virtual Acquisition started\n"); + FILE_LOG(logINFO ,"***Virtual Acquisition started\n"); return OK; #else @@ -1556,24 +1554,24 @@ int startStateMachine(){ //get the DAQ toggle bit prev_flag = Feb_Control_AcquisitionStartedBit(); - printf("Going to start acquisition\n"); + FILE_LOG(logINFO, ("Going to start acquisition\n")); Feb_Control_StartAcquisition(); - if(!eiger_storeinmem){ - printf("requesting images right after start\n"); + if (!eiger_storeinmem) { + FILE_LOG(logINFO, ("requesting images right after start\n")); ret = startReadOut(); } //wait for acquisition start - if(ret == OK){ - if(!Feb_Control_WaitForStartedFlag(5000, prev_flag)){ - cprintf(RED,"Error: Acquisition did not start or trouble reading register\n"); + if (ret == OK) { + if (!Feb_Control_WaitForStartedFlag(5000, prev_flag)) { + FILE_LOG(logERROR, ("Acquisition did not FILE_LOG(logERROR ouble reading register\n")); return FAIL; } - cprintf(GREEN,"***Acquisition started\n"); + FILE_LOG(logINFO, ("***Acquisition started\n")); } - /*while(getRunStatus() == IDLE){printf("waiting for being not idle anymore\n");}*/ + /*while(getRunStatus() == IDLE) {FILE_LOG(logINFO, ("waiting for being not idle anymore\n"));}*/ return ret; #endif @@ -1583,12 +1581,12 @@ int startStateMachine(){ void* start_timer(void* arg) { eiger_virtual_status = 1; int wait_in_s = nimages_per_request * eiger_virtual_period; - cprintf(GREEN,"going to wait for %d s\n", wait_in_s); + FILE_LOG(logINFO, ("going to wait for %d s\n", wait_in_s)); while(!eiger_virtual_stop && (wait_in_s >= 0)) { usleep(1000 * 1000); wait_in_s--; } - cprintf(GREEN,"Virtual Timer Done***\n"); + FILE_LOG(logINFO, ("Virtual Timer Done***\n")); eiger_virtual_status = 0; return NULL; @@ -1597,16 +1595,16 @@ void* start_timer(void* arg) { -int stopStateMachine(){ - cprintf(BG_RED,"Going to stop acquisition\n"); +int stopStateMachine() { + FILE_LOG(logERROR, ("Going to stop acquisition\n")); #ifdef VIRTUAL eiger_virtual_stop = 0; return OK; #else - if((Feb_Control_StopAcquisition() == STATUS_IDLE) & Beb_StopAcquisition()) + if ((Feb_Control_StopAcquisition() == STATUS_IDLE) & Beb_StopAcquisition()) return OK; - cprintf(BG_RED,"failed to stop acquisition\n"); + FILE_LOG(logERROR, ("failed to stop acquisition\n")); return FAIL; #endif } @@ -1622,29 +1620,29 @@ int softwareTrigger() { } -int startReadOut(){ +int startReadOut() { - printf("Requesting images...\n"); + FILE_LOG(logINFO, ("Requesting images...\n")); #ifdef VIRTUAL return OK; #else //RequestImages(); int ret_val = 0; dst_requested[0] = 1; - while(dst_requested[on_dst]){ + while(dst_requested[on_dst]) { //waits on data - int beb_num = BEB_NUM;//Feb_Control_GetModuleNumber(); + int beb_num = detid; if ((ret_val = (!Beb_RequestNImages(beb_num,send_to_ten_gig,on_dst,nimages_per_request,0)))) break; -// for(i=0;iserialnumber>=0){ + if (srcMod->serialnumber>=0) { destMod->serialnumber=srcMod->serialnumber; } //no trimbit feature if (destMod->nchip && ((srcMod->nchip)>(destMod->nchip))) { - printf("Number of chip of source is larger than number of chips of destination\n"); + FILE_LOG(logINFO, ("Number of chip of source is larger than number of chips of destination\n")); return FAIL; } //no trimbit feature if (destMod->nchan && ((srcMod->nchan)>(destMod->nchan))) { - printf("Number of channels of source is larger than number of channels of destination\n"); + FILE_LOG(logINFO, ("Number of channels of source is larger than number of channels of destination\n")); return FAIL; } if ((srcMod->ndac)>(destMod->ndac)) { - printf("Number of dacs of source is larger than number of dacs of destination\n"); + FILE_LOG(logINFO, ("Number of dacs of source is larger than number of dacs of destination\n")); return FAIL; } if ((srcMod->nadc)>(destMod->nadc)) { - printf("Number of dacs of source is larger than number of dacs of destination\n"); + FILE_LOG(logINFO, ("Number of dacs of source is larger than number of dacs of destination\n")); return FAIL; } -#ifdef VERBOSE - printf("DACs: src %d, dest %d\n",srcMod->ndac,destMod->ndac); - printf("ADCs: src %d, dest %d\n",srcMod->nadc,destMod->nadc); - printf("Chips: src %d, dest %d\n",srcMod->nchip,destMod->nchip); - printf("Chans: src %d, dest %d\n",srcMod->nchan,destMod->nchan); - -#endif + FILE_LOG(logDEBUG5, ("DACs: src %d, dest %d\n",srcMod->ndac,destMod->ndac)); + FILE_LOG(logDEBUG5, ("ADCs: src %d, dest %d\n",srcMod->nadc,destMod->nadc)); + FILE_LOG(logDEBUG5, ("Chips: src %d, dest %d\n",srcMod->nchip,destMod->nchip)); + FILE_LOG(logDEBUG5, ("Chans: src %d, dest %d\n",srcMod->nchan,destMod->nchan)); destMod->ndac=srcMod->ndac; destMod->nadc=srcMod->nadc; destMod->nchip=srcMod->nchip; destMod->nchan=srcMod->nchan; if (srcMod->reg>=0) destMod->reg=srcMod->reg; -#ifdef VERBOSE - printf("Copying register %x (%x)\n",destMod->reg,srcMod->reg ); -#endif + FILE_LOG(logDEBUG5, ("Copying register %x (%x)\n",destMod->reg,srcMod->reg )); if (srcMod->gain>=0) destMod->gain=srcMod->gain; if (srcMod->offset>=0) destMod->offset=srcMod->offset; - if((destMod->nchip!=0) || (destMod->nchan!=0)) { + if ((destMod->nchip!=0) || (destMod->nchan!=0)) { for (ichip=0; ichip<(srcMod->nchip); ichip++) { if (*((srcMod->chipregs)+ichip)>=0) *((destMod->chipregs)+ichip)=*((srcMod->chipregs)+ichip); @@ -1792,9 +1786,7 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod){ *((destMod->chanregs)+ichan)=*((srcMod->chanregs)+ichan); } } -#ifdef VERBOSE - else printf("Not Copying trimbits\n"); -#endif + else FILE_LOG(logINFO, ("Not Copying trimbits\n")); for (idac=0; idac<(srcMod->ndac); idac++) { if (*((srcMod->dacs)+idac)>=0) { *((destMod->dacs)+idac)=*((srcMod->dacs)+idac); @@ -1808,8 +1800,8 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod){ } -int calculateDataBytes(){ - if(send_to_ten_gig) +int calculateDataBytes() { + if (send_to_ten_gig) return setDynamicRange(-1) * ONE_GIGA_CONSTANT * TEN_GIGA_BUFFER_SIZE; else return setDynamicRange(-1) * TEN_GIGA_CONSTANT * ONE_GIGA_BUFFER_SIZE; @@ -1818,13 +1810,13 @@ int calculateDataBytes(){ -int getTotalNumberOfChannels(){return ((int)getNumberOfChannelsPerChip() * (int)getNumberOfChips());} -int getNumberOfChips(){return NCHIP;} -int getNumberOfDACs(){return NDAC;} -int getNumberOfADCs(){return NADC;} -int getNumberOfChannelsPerChip(){return NCHAN;} -int getNumberOfGains(){return NGAIN;} -int getNumberOfOffsets(){return NOFFSET;} +int getTotalNumberOfChannels() {return ((int)getNumberOfChannelsPerChip() * (int)getNumberOfChips());} +int getNumberOfChips() {return NCHIP;} +int getNumberOfDACs() {return NDAC;} +int getNumberOfADCs() {return NADC;} +int getNumberOfChannelsPerChip() {return NCHAN;} +int getNumberOfGains() {return NGAIN;} +int getNumberOfOffsets() {return NOFFSET;} diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h index fec509799..dfc4d745b 100644 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h @@ -42,7 +42,7 @@ enum DACINDEX {SVP,VTR,VRF,VRS,SVN,VTGSTV,VCMP_LL,VCMP_LR,CAL,VCMP_RL,RX }; enum ADCINDEX {TEMP_FPGAEXT, TEMP_10GE, TEMP_DCDC, TEMP_SODL, TEMP_SODR, TEMP_FPGA, TEMP_FPGAFEBL, TEMP_FPGAFEBR}; enum NETWORKINDEX {TXN_LEFT, TXN_RIGHT, TXN_FRAME,FLOWCTRL_10G}; - +enum {E_PARALLEL, E_NON_PARALLEL, E_SAFE}; /* Hardware Definitions */ #define NCHAN (256 * 256) diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c index c922d0ddc..81a7e4912 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -448,7 +448,7 @@ void setupDetector() { bus_w(DAQ_REG, 0x0); /* Only once at server startup */ - setSpeed(CLOCK_DIVIDER, HALF_SPEED); + setSpeed(HALF_SPEED); cleanFifos(); resetCore(); @@ -465,7 +465,7 @@ void setupDetector() { setTimer(DELAY_AFTER_TRIGGER, DEFAULT_DELAY); setTimer(STORAGE_CELL_NUMBER, DEFAULT_NUM_STRG_CLLS); selectStoragecellStart(DEFAULT_STRG_CLL_STRT); - /*setSpeed(CLOCK_DIVIDER, HALF_SPEED); depends if all the previous stuff works*/ + /*setSpeed(HALF_SPEED); depends if all the previous stuff works*/ setTiming(DEFAULT_TIMING_MODE); setHighVoltage(DEFAULT_HIGH_VOLTAGE); @@ -611,10 +611,7 @@ int setDynamicRange(int dr){ /* parameters - readout */ -int setSpeed(enum speedVariable arg, int val) { - - if (arg != CLOCK_DIVIDER) - return -1; +enum speedVariable setSpeed(int val) { // setting if(val >= 0) { @@ -1620,7 +1617,7 @@ void readFrame(int *ret, char *mess){ } else { *ret = (int)FINISHED; sprintf(mess,"acquisition successfully finished\n"); - printf("%s",mess); + cprintf(GREEN, "%s",mess); } } diff --git a/slsDetectorServers/mythen3DetectorServer/AD9257.h b/slsDetectorServers/mythen3DetectorServer/AD9257.h deleted file mode 120000 index 87b70e097..000000000 --- a/slsDetectorServers/mythen3DetectorServer/AD9257.h +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServer/AD9257.h \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/Makefile b/slsDetectorServers/mythen3DetectorServer/Makefile deleted file mode 100644 index ba8ffe5f1..000000000 --- a/slsDetectorServers/mythen3DetectorServer/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -CROSS = bfin-uclinux- -CC = $(CROSS)gcc -#CC = gcc -CLAGS += -Wall -DMYTHEN3D -DSLS_DETECTOR_FUNCTION_LIST -DDACS_INT -DSTOP_SERVER #-DVERBOSEI #-DVERBOSE -LDLIBS += -lm -lstdc++ - - -PROGS = mythen3DetectorServer -DESTDIR ?= bin -INSTMODE = 0777 - -SRC_CLNT = communication_funcs.c slsDetectorServer.c slsDetectorServer_funcs.c slsDetectorFunctionList.c -OBJS = $(SRC_CLNT:.c=.o) - - - -all: clean versioning $(PROGS) - -boot: $(OBJS) - -versioning: - @echo `tput setaf 6; ./updateGitVersion.sh; tput sgr0;` - -$(PROGS): $(OBJS) -# echo $(OBJS) - mkdir -p $(DESTDIR) - $(CC) -o $@ $^ $(CFLAGS) $(LDLIBS) - mv $(PROGS) $(DESTDIR) - rm *.gdb - -clean: - rm -rf $(DESTDIR)/$(PROGS) *.o - diff --git a/slsDetectorServers/mythen3DetectorServer/Makefile.virtual b/slsDetectorServers/mythen3DetectorServer/Makefile.virtual deleted file mode 100644 index de7284bcc..000000000 --- a/slsDetectorServers/mythen3DetectorServer/Makefile.virtual +++ /dev/null @@ -1,25 +0,0 @@ -CC = gcc -CFLAGS += -Wall -DVIRTUAL -DMYTHEN3D -DSLS_DETECTOR_FUNCTION_LIST -DDACS_INT -DSTOP_SERVER #-DVERBOSEI #-DVERBOSE -LDLIBS += -lm -lstdc++ - -PROGS = virtualMythen3DetectorServer -DESTDIR ?= bin -INSTMODE = 0777 - -SRC_CLNT = communication_funcs.c slsDetectorServer.c slsDetectorServer_funcs.c slsDetectorFunctionList.c -OBJS = $(SRC_CLNT:.c=.o) - -all: clean $(PROGS) - -boot: $(OBJS) - -$(PROGS): $(OBJS) - echo $(OBJS) - mkdir -p $(DESTDIR) - $(CC) -o $@ $^ $(CFLAGS) $(LDLIBS) - mv $(PROGS) $(DESTDIR) - rm *.gdb - -clean: - rm -rf $(DESTDIR)/$(PROGS) *.o - diff --git a/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h b/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h deleted file mode 100644 index 1fa922d3b..000000000 --- a/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef REGISTERS_G_H -#define REGISTERS_G_H - -/* Definitions for FPGA*/ - -/* FPGA Version register */ -#define FPGA_VERSION_REG (0x00 << 11) - -#define BOARD_REVISION_OFST (0) -#define BOARD_REVISION_MSK (0x00FFFFFF << BOARD_REVISION_OFST) -#define DETECTOR_TYPE_OFST (24) -#define DETECTOR_TYPE_MSK (0x000000FF << DETECTOR_TYPE_OFST) - -/* Fix pattern register */ -#define FIX_PATT_REG (0x01 << 11) - - -/* Timer 64 bit Regiser */ -#define SET_DELAY_LSB_REG (0x60 << 11) //96<<11 //0x68<<11 -#define SET_DELAY_MSB_REG (0x61 << 11) //97<<11 //0x69<<11 -#define SET_CYCLES_LSB_REG (0x62 << 11) //98<<11//0x6c<<11 -#define SET_CYCLES_MSB_REG (0x63 << 11) //99<<11//0x6d<<11 -#define SET_FRAMES_LSB_REG (0x64 << 11) //(100<<11)/** to hex */ -#define SET_FRAMES_MSB_REG (0x65 << 11) //101<<11//0x71<<11 -#define SET_PERIOD_LSB_REG (0x66 << 11) //102<<11//0x74<<11 -#define SET_PERIOD_MSB_REG (0x67 << 11) //103<<11//0x75<<11 -#define SET_GATES_LSB_REG (0x6A << 11) /*check in firmware*///106<<11//0x7c<<11 -#define SET_GATES_MSB_REG (0x6B << 11) //107<<11//0x7d<<11 -#define SET_EXPTIME_LSB_REG (0x72 << 11) /** check in firmware *///114<<11//0x78<<11 -#define SET_EXPTIME_MSB_REG (0x73 << 11) //115<<11//0x79<<11 - -#define GET_ACTUAL_TIME_LSB_REG (0x10 << 11) //16<<11 -#define GET_ACTUAL_TIME_MSB_REG (0x11 << 11) //17<<11 -#define GET_DELAY_LSB_REG (0x12 << 11) //18<<11//0x6a<<11 -#define GET_DELAY_MSB_REG (0x13 << 11) //19<<11//0x6b<<11 -#define GET_CYCLES_LSB_REG (0x14 << 11) //20<<11//0x6e<<11 -#define GET_CYCLES_MSB_REG (0x15 << 11) //21<<11//0x6f<<11 -#define GET_FRAMES_LSB_REG (0x16 << 11) //22<<11//0x72<<11 -#define GET_FRAMES_MSB_REG (0x17 << 11) //23<<11//0x73<<11 -#define GET_PERIOD_LSB_REG (0x18 << 11) //24<<11//0x76<<11 -#define GET_PERIOD_MSB_REG (0x19 << 11) //25<<11//0x77<<11 -#define GET_EXPTIME_LSB_REG (0x1A << 11) //26<<11//0x7a<<11 -#define GET_EXPTIME_MSB_REG (0x1B << 11) //27<<11//0x7b<<11 -#define GET_GATES_LSB_REG (0x1C << 11) //28<<11//0x7e<<11 -#define GET_GATES_MSB_REG (0x1D << 11) //29<<11//0x7f<<11 - -#define FRAMES_FROM_START_LSB_REG (0x22 << 11) //34<<11 -#define FRAMES_FROM_START_MSB_REG (0x23 << 11) //35<<11 -#define FRAMES_FROM_START_PG_LSB_REG (0x24 << 11) //36<<11 -#define FRAMES_FROM_START_PG_MSB_REG (0x25 << 11) //37<<11 -#define GET_MEASUREMENT_TIME_LSB_REG (0x26 << 11) //38<<11 -#define GET_MEASUREMENT_TIME_MSB_REG (0x27 << 11) //39<<11 - - -/* SPI (Serial Peripheral Interface) Register */ -#define SPI_REG (0x40 << 11) - -#define DAC_SERIAL_DIGITAL_OUT_OFST (0) -#define DAC_SERIAL_DIGITAL_OUT_MSK (0x00000001 << DAC_SERIAL_DIGITAL_OUT_OFST) -#define DAC_SERIAL_CLK_OUT_OFST (1) -#define DAC_SERIAL_CLK_OUT_MSK (0x00000001 << DAC_SERIAL_CLK_OUT_OFST) -#define DAC_SERIAL_CS_OUT_OFST (2) -#define DAC_SERIAL_CS_OUT_MSK (0x00000001 << DAC_SERIAL_CS_OUT_OFST) -#define HV_SERIAL_DIGITAL_OUT_OFST (8) -#define HV_SERIAL_DIGITAL_OUT_MSK (0x00000001 << HV_SERIAL_DIGITAL_OUT_OFST) -#define HV_SERIAL_CLK_OUT_OFST (9) -#define HV_SERIAL_CLK_OUT_MSK (0x00000001 << HV_SERIAL_CLK_OUT_OFST) -#define HV_SERIAL_CS_OUT_OFST (10) -#define HV_SERIAL_CS_OUT_MSK (0x00000001 << HV_SERIAL_CS_OUT_OFST) - -/* Control Register */ -#define CONTROL_REG (0x4F << 11) //(79 << 11) /** to hex */ - - -/* Reconfiguratble PLL Control Regiser */ -#define PLL_CONTROL_REG (0x51 << 11) //(81 << 11)/** to hex */ - -//#define PLL_CTRL_RECONFIG_RST_OFST (0) //parameter reset -//#define PLL_CTRL_RECONFIG_RST_MSK (0x00000001 << PLL_CTRL_RECONFIG_RST_OFST) //parameter reset -//#define PLL_CTRL_WR_PARAMETER_OFST (2) -//#define PLL_CTRL_WR_PARAMETER_MSK (0x00000001 << PLL_CTRL_WR_PARAMETER_OFST) -#define PLL_CTRL_RST_OFST (3) -#define PLL_CTRL_RST_MSK (0x00000001 << PLL_CTRL_RST_OFST) -//#define PLL_CTRL_ADDR_OFST (16) -//#define PLL_CTRL_ADDR_MSK (0x0000003F << PLL_CTRL_ADDR_OFST) - -/* Samples Register */ -#define NSAMPLES_REG (0x5D << 11) //93<<11 - -/* Power On Register */ -#define POWER_ON_REG (0x5e<<11) - -#define POWER_ENABLE_OFST (16) - -/* Dac Registers */ -#define DAC_VAL_REG (0x79 << 11) //121<<11 -#define DAC_NUM_REG (0x80 << 11) //122<<11 -#define DAC_VAL_OUT_REG (0x2A << 11) //42<<11 - -#endif - diff --git a/slsDetectorServers/mythen3DetectorServer/ansi.h b/slsDetectorServers/mythen3DetectorServer/ansi.h deleted file mode 120000 index a122db0ad..000000000 --- a/slsDetectorServers/mythen3DetectorServer/ansi.h +++ /dev/null @@ -1 +0,0 @@ -../../slsReceiverSoftware/include/ansi.h \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/blackfin.h b/slsDetectorServers/mythen3DetectorServer/blackfin.h deleted file mode 120000 index 24f9c08f7..000000000 --- a/slsDetectorServers/mythen3DetectorServer/blackfin.h +++ /dev/null @@ -1 +0,0 @@ -/afs/psi.ch/project/mythen/marie_a/MythenServer/slsDetectorPackage/slsDetectorSoftware/slsDetectorServer/blackfin.h \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/commonServerFunctions.h b/slsDetectorServers/mythen3DetectorServer/commonServerFunctions.h deleted file mode 120000 index 33bdd8d53..000000000 --- a/slsDetectorServers/mythen3DetectorServer/commonServerFunctions.h +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServer/commonServerFunctions.h \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/communication_funcs.c b/slsDetectorServers/mythen3DetectorServer/communication_funcs.c deleted file mode 120000 index 87a4f95d1..000000000 --- a/slsDetectorServers/mythen3DetectorServer/communication_funcs.c +++ /dev/null @@ -1 +0,0 @@ -../commonFiles/communication_funcs.c \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/communication_funcs.h b/slsDetectorServers/mythen3DetectorServer/communication_funcs.h deleted file mode 120000 index f220903b2..000000000 --- a/slsDetectorServers/mythen3DetectorServer/communication_funcs.h +++ /dev/null @@ -1 +0,0 @@ -../commonFiles/communication_funcs.h \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/gitInfo.txt b/slsDetectorServers/mythen3DetectorServer/gitInfo.txt deleted file mode 100644 index 4df512cd8..000000000 --- a/slsDetectorServers/mythen3DetectorServer/gitInfo.txt +++ /dev/null @@ -1,9 +0,0 @@ -Path: slsDetectorsPackage/slsDetectorSoftware/jungfrauDetectorServer -URL: origin git@git.psi.ch:sls_detectors_software/slsDetectorPackage.git -Repository Root: origin git@git.psi.ch:sls_detectors_software/slsDetectorPackage.git -Repsitory UUID: 2f3dc8d109de8607f3217cf429619073dc9cc60e -Revision: 103 -Branch: developer -Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 3397 -Last Changed Date: 2017-12-04 18:23:05.000000002 +0100 ./RegisterDefs.h diff --git a/slsDetectorServers/mythen3DetectorServer/gitInfoMythen3.h b/slsDetectorServers/mythen3DetectorServer/gitInfoMythen3.h deleted file mode 100644 index 1acd1f071..000000000 --- a/slsDetectorServers/mythen3DetectorServer/gitInfoMythen3.h +++ /dev/null @@ -1,6 +0,0 @@ -#define GITURL "git@git.psi.ch:sls_detectors_software/slsDetectorPackage.git" -#define GITREPUUID "2f3dc8d109de8607f3217cf429619073dc9cc60e" -#define GITAUTH "Dhanya_Maliakal" -#define GITREV 0x3397 -#define GITDATE 0x20171204 -#define GITBRANCH "developer" diff --git a/slsDetectorServers/mythen3DetectorServer/gitInfoMythen3Tmp.h b/slsDetectorServers/mythen3DetectorServer/gitInfoMythen3Tmp.h deleted file mode 100644 index dfd9bb246..000000000 --- a/slsDetectorServers/mythen3DetectorServer/gitInfoMythen3Tmp.h +++ /dev/null @@ -1,6 +0,0 @@ -#define GITURL "" -#define GITREPUUID "" -#define GITAUTH "" -#define GITREV "" -#define GITDATE "" -#define GITBRANCH "" diff --git a/slsDetectorServers/mythen3DetectorServer/mythen3Server b/slsDetectorServers/mythen3DetectorServer/mythen3Server deleted file mode 100755 index 2f0fcf0df512e59de0500d8d3c73cc1d73a081d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92440 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

QEBJdSkHKXwK`{H*B25*o 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ℑHz-r&L3);Lt~-f?_y$o}J7@A>?FqJ_HVO3L6| zQuuvNaZbRdsmOClR*^0tZhkKpO^)1M`d*uUCQtJxnNLmc-8SPm=jW`a!S6jY!=on? zD&xIrGm^~^UnXWB&H6rvd+W~mUbbEuJl)*S?Zh^{BjV7OZSGf4f24!S7Bz4VExeqVhA$85`%02oABfoQbmz?R}dGwfpABO3>js^`?I8t_@ zu02PB#>8-+@;>BJ!vEb2k!oO z`ylGkkD6R}gpy?C1--kk*8Yw!AnR=fZwF0r3QG=P{ zXt>T#Zrsxo6PpFTreqA)8$zF4D|ueYKI*i?@-t+m9X;~?c5f{AA>=bGBllqy8qpn8 ziXPgca*zJW@CDWGoz%{SeA>HH3ww9xcXy2P?zHi5e%09Sl}7sRIrI9AoF0_^gguwP zuwly4*NiKV9zd7&nvvgqfBuPje!cCFxx9TpRxf^2p?`-*zWXYNWw==B?j7agD%V%e zt%84%6~H)@b!2+?Z}Q#Uk>6sDX`13J)4iio&6vv*V*Y1$ zDfy<7tHgZYjCmO`ld`4|^LKL{T3BDCOaAQDe3$sgqxn5xq?S*n)Ia3cIe(L{$W=Tt zSyp&`iQ6{|t0C_yJUYlbI~>u9Zb`jQbdG*cog+Bq=pU)|>qcMQ$t-lBKia870|wx$ z(+oeAG?_>KoJ_hOkuH1m!x|;{qfrtbqvsMgsiALlGS9R0&Y80NFN#SPB55LRs0t?g zPvl*%I|3aMwIT8QthD@wOa0}@<)$2Y-Ec<>^eKOS-EevK4wrV5)^w$MGIn#n6V1jD zP8B*L(ueoZM@O@%lTbPuxZESJ76ClQ({HqeGia9O=t18Xch(4Lgs%WXxdSH^)Du*@lMw?z!umHipoKrpk$^Q_X0Y zszjnH+OU&De;x9rev~=Qzp|--^RDxBSJbJ^)BA+0ObMDz-Qbs!NeTN#IVO~`*)!py zeBF_H*+5?)_vkCerIgPdE2Y!-IAOIB^6xjqcV%-&NNwojXXm?{Uwx?`*}Yv&p*MSX z=dBe<6$0j>o#_3_^(QVGEG&u|lmhT}24_LA0%$xEset1jzX4se^r5+=xhu7ux zO@U$seLZHL*{fZ_hVA&WB=uFJwrr0?XJEm<0!nL?H+%J}LiuXtEnjWe`$$={S2u3o zvNsa#ZM`H$?mqGxkToNad-xS&xhpM}#uT31fwR-eEgTK)5Mukj;n_={aQd#)zZ`OC z-!EJgs)zb}n|B`l*ccSFYr}#mtg7nJ`<{--r_I_1d19aPr?hacKFss}aK*XIYX1+B zcb;m#mw%;nr<$`@H*J52@{R58z+1AcO_L8Ze+CvtCo_+}lln0|^Mt|q4f`}!p)R$r zen#NRqi+~fkgMb#eao=*9hxQe@v)l5>mTu7Cbixkj;3joAO1!NoiJ;N!rQdk?bO^@ zA-risu<~s&Qi5~lEq!qfJ_jRpi+2Jj(MLb(p9R@fWb#jtrqE`kT|Aw=GZ4{qx<-9s@J3 zxWru98(t&-W+3Q4eoRqOW zDDNj~*;1pqSO579Baf22hyBvEgI)fehbe)leBOvGnGtnXc3)>MGug#aAG+Wve})3{ zJHG2>lsh%quN6+3%q%+P$ZL%D_XS}iO;^Xb&uU+__hZn9h>Wj&*t%F zSY>=SYvHaT*d65_e%+XS_$}ja+l@o(KIzu*S#+QawbPi|o0cH+&tQmok!r zui_odmih;ul}ZvJR~otV9NJaPm}`S*Zn31uhc|Y+`m#rF!E;!0aOaWd4Q+!N!|x<) zye`A3%lny9t23$ve^=kmdJr#U=n^xU^?t!fT`F@yJf7G}JLe@4)=8|EvnX(<*=p|$ zkD!mwUN@q9KC`XEmlAaF+z(6Cyfe9Tm%(2sTOMm+$p`e5fQ0)p;V#SAee}C$`bIBB z5^#gBkv1NjQSN{6u#KJlmsM)i=1R}nf?R7Q@+$citTBEoy)AS5Z*Z+!?)rGR*hDn? zv)6iKUsmx&($2T~21%g9h>?v@Z^odsxQiXKhoZ zL~$O^>rZ8_6JEG;`-|IG9UZ7#Yv9!2XW`V;$|DZ73OgF4D9p}pj9T@GcL)A6P5TqC z>|=@N-NiLN0z@!;0fjVsZkC!xXiu66%XXsr$z^y5@CV-m_WeG7S2tHW~#spswZC`b3)>T{s2n-_3_m=y7T(Uis|J!8-w@Jv9<4Sc z)T%RMyJs2Ag|P2t{$_B1nM?JV zrQ13}zSWb1`!>7iotzq4o~;*$omvXA$XUS^As_qObmmFnJFAS2U{hhTOUj_^_s@0W zJ7~(EUp6$YBcyGR{7T4Aaz8cP!>oEVr&^zU_+>aE(|(@xnXA{!8eC=c3)(eLSmI1L z6JM#W>n!M$d0H!RA#-rqyNBlME9>;sH-|6XW|i=AvkoVboWdQIjJSx>n=~9YxG}Wz zFqB~zZ40JoV;XXg{LU!h6pl;3d0T1W4TV+Exawzr+;rb&*8G6f;Q03Yu{08?!5q8n z8&c4N7>CB3IKg~$(Kc3pIKv`+9lq9o@;?WDy7NdC^I*ojepxwum)1?n8nSJc`;CkO zRuHMjbEl8yEQek$*RTwshgG}BPy0Gogz%{2I%(3xtCi_f4!?vQ#E9-Z_6kmuCjEkv z!h@&#XlGMc==+lKdGvWbMxQ?pPbry@(NMUY75!e$Ni|YFmp*2CI$MFU;dIxXqVb@I z=8aC`oI@dZg`>6gl4Hy1A)TB9n=UJa(>ro~-{{|SY@Xt*>D|Tj*y7Q%T+xhckWWO^ z;7-|vdtG157-6>bOzPF)`Lgf2kOx~vr`bD`GOSdKPg``5^>tuR-ZY37$1)>!@6tpkhCLXY?miJ|KY!;c! zliSjfrS#R7ZL2Ez%{FJ&nAJC+0TOS3*z9<+SKqwN>H$*g*FH@)d;cFkJ>H|w7VgxN zLy2Y67S@G}vjzvVv47*7h-uL@HA#6&Ss5-{bD+S@iin4=YL{Q;&Tr4{JZx9l_sa_5 zP&WOG^pG(d8#W4u!P!6#tmy1r9J&`-R<hCWtw0lx~;#17Awh!&1 z6f$6yM=8CkCCP7E*XBZlNB;V8%;w(G*9EaD8KPHJ$x1sccynQ@cCy~)$8tnQlpfGN zsdtd)M9TePrUQ#FZ@+XR%*u5mdMS1nq=+6#jdq-~5}coei+1@)|FZ}=kfS?uiPyDL19XD_8l^&P5L zYFVL6JJsx^w>tQmq7BgpU`OP@deV~TS++$jNfn$~ArDSBNFQ`-GN0RmIvTcTlJLaM ze#$Od&qMoY(-Ux)^4+4tC)l^CW7CoLjzl9h*q6#Kr``DD+>zZK%C$;3qC&J?rBKlO z*X+Y1klMUuWFH=BN^j6=G5grHYxN>zyrPZ1f397#H{_w`Nij9jFWQl}d3^B6gM4MA z{2?JkKkd2)eI{oCI~2b)@ow(nJ%)Caw6W~gj*g63-t3`=%6>`Yf~D~FK7H4Yk?cuQ zxtG%ojqF#Zcdjt`+>@C#>`7dVO5}<@M?;d%~+w5viweJ7M@xAEM z2+sT|nU!3sL2nQ8RhpMKYEGakvgR?pq+s`mNu^?aCLSqz=V z&szW0KQuiN?A(@z{?NYqTD=6zvy`mzZq?yz=-aK7oCq^+`SixVobsEp*^bram-S(I z3mb<0caffi-qtwuThjA}qWWSTt&W+3Sd$+!<+IxhZT4paIr`;2Cv0VgvD(jNwx8I| z9N(kG+Rqa$>3nuiXx(7{TC)XDm@Vk`HPDVupGbI9G*`nhk@hzHWsfInZxAnZ2lkx4 zajf<=`dw0kLn~&cLYq`5D=?O^(UlFwsY5bKyD!O0rA8u`6ImLv-q$B%Cn+I2>ab<% zj>{#H_d7+#=7|Q^*$Qp`|Jvm|jzu3U@>FFZ)$PpXf- z&#yYU!<0s6U1a84$m*sF&0pbVzgOh%I$~4sU94>`bH@iq9Zb?rv0k`?u4oC?b#s_k zwC-w~WyO91EB2bI)abSAhWdZA>$|j}ujKvAm-0?*%6GY{x|2`r5N&U~1%@0@p6OX9 zH!Wv=8sm3jFVs=UUIniIQly^Bo*cZt(#Ohy9}uKWh44bI43S-1?RWZ>6s`9u?|`%! zCt}LS_<4;DvshCoRjR zP48~tO@sMHY(1{$>H5h@+y%J{PEPNBF$G*uw=KgQbz3(Xe${KH3HX5fhwMpmMyZ376 zq&{L(@%2sF{_Z^=>=~3MbKeXovOOp#lc%#nTlGBqRAS!eo^zGbVkeGN%{X++A<=}S zVT~&M%@goLGIwWFK1ym_Xj^_>GedbC+9FZ>y%LXyz`ujjq4VvZAk{F z1y|rb+PKA=($Hlb`f@ktC;GZGlqY))`WCn|rzZMFThQbebm6MJeoMoh>h}fHO>WSU zVGlYqv0t8urm3^bLH%cJ^lr2Vme1(dc@wjLntpAU&wjGpZtoND2Kufp+3rKi;De*N z+HKEzwD305ZfbkC*acpzyfKSa%jP0p-Uqwh>AEvu9NK6+*fr*n{Hn%;vpDfE+3b`= zU-~UlI$K}bU(=E13Vnb3ws34)(0D>~+FNL^sH4R%S$yNuPA?j3>B}E%uj(4pc|#Ze zzHH0k_eA#H8}dW?K_AAioMbNG>};7ihOHT(%#b4gt5Ozw=%q=wtN^^S%9 zfp9IZHF|ZwO~SXxxgX)WF2%|sXNPM|19Gc;YW?K9{rvfy`?BU5W%fjwYb1BY$!YS( zCL>-hc;nUQo_LTR@N;H`L!1|jmqM)fX5l^Y68PIXRw%BCvgq*-=g1MAE%7n zJXtI!yJb!kN|o%96U9Q6a3V#p4=E>hU#=8RD@4>l>{o@llQ@}d(Zfo^qKL$`C^ECt z3ZEPt@6V$L`WR7DWR~L_n!*l4XNU1(;f^YAP5x}zX?!@mK<_;Ksd2D=uqz9>_F(KQj@5T^ zf@m;aE|CfGe4OVqJbQRf<@p592G8(Z9)2OwoC#!PE=?-JQZ@-2Ik&z*|5bf<_g(7K zjhP943uIQ@|0h`|#6m?RC`qh$E_h{!*6T4`?6=}RD4u@#Y#$UI&!!jstqXhcXMJUp zuzu+ClKpsgT^;+pzM&JpvA<)+@_pWl<@@Y44)aMurA~C>8Dr%0o)wci z*)J)jI`+AIR#?~6<@;oF+=GpFBy`Jq- zC!O3h-oN67&^LE(;#8&nkoXk+=J3jq{(hVUdaZgWUhW*T?UNL~?INxpn;z{(;D7Cv z4Dpcmf$7ig`vb4jAJkj$X}9)`3IitUXS^7d1BW3vpm^Zz9G-{Sahy0J2?w4 zzU*FsmSHrJ;=Sxt;ud1O}tVq2PZ*G?Nx*z4-q0cbA z*FBD>H1S^dwSmj@bv-`DrkK9VHkj1FtL@-BphoH>p~ja7N{c>aw&;to7QI7Xo@c|a zndQCiK}tL;ufg3sB_d1v9z3yqe*InV8j73e{7w7s}!`U;Y z1V>Y+Avsm1KR1i^*XiF1Jg653R^z*Fn^%0-wd!9;@Ladbm#?uD4= zx+i8O2j4x%bKQ?)-sQfK`5&M0T(@t6)cQfwXWF<}txL>WTdh<>oh?s;$0ytYCB$>x z9j3oGsdbHh&jhK>B-g8h%1zI8wfGeC;<@hX%y>Ht&$8OV$YQKjJwy$Zy{+nOzje)~ z-?~TiQq$MnQyCU*emZ=MzsB@-wxGuo-1+?0RVDbXtLX_T-p+dc*5&C{dF5u?=Vv@f zK4MK2_ghz^=TPcPsGrqyg7`(0o|BgGN$m}KqTjkP6U49E1lO@aQZl(8i5-?V=C`g9 zP3Ai0lbXQadP>nkDQ?4i-ZiGzH7P||%yV6{??L^S)B8@^7qX|`l5sNVPTgR(!jEHP z<@5U9F8V>D=eqGd<+l3LjtSPN{^l?|5XL;$EsuGwYl(TT%j@x6x8-v^*Zpw3MTLuL zw_gUv;)7FKZhqj2z@CzVtcL@6_-|~9`Lf#*^IP|=nBThlGJC1Be7p)Cm>^?N{MOwZ z^ILbF-azTTUsYVSp=ZQe5XPP&dR&Yq~LNWm``h6Vfw9mAm+F3^FrQ` zqk;=^*5kDb)_p2- zuKttM*M|$|gYKdyou3UqUi-ToNk{HpFwbKCJ9Xr@c4KuML>;rtIu4K3aYRoYzmS#h z8D`o>pQx2GNWOnD%j8Wclho}{LfyKl+W_izIH7J96%J)SZPxA&X6^c$DORe_d$s647#S`QEr%%-_t;MH4PfO_l3s$34uhuiib|ZE~w8%Y<(;4kaHr*GFMLGgnt2Q(uv1c_~~`ExqlD zS&rb#37!Ts^@4N0{|aA&qQ}sYWG-AT{xDyiWu;)R?icIm`UszwBv$80Z^Ow6$Bd4&V?!4E5Ci7VfHaRG+GJ%@!(pXG@34mCrimW^evEBsPfUZLdle5TDa+h_ND$v2qQQu6uP^k0$d(>Ztm${0u= z8<63^*Qz`CaE?6vcsMz%_^;_waw+$3avZ@EwcGf23}L>TQ(3zQ9ntY%P2g(%MDX$H zwp4yI8|mXn-vInDt%@&WtKgqFjexh0h@5n*Z62=2!-tBpA zR`_f4QfAkfq1G~=yq#m$9l@J&O1nEIrEE?y%omDq`PMcnu zVtN(6niOO3ntwbShvwfY{=s7J%{K$@JS$W@^jT=|ch-w@9>#|w3m2p57&`CrNsGq* zn}6<}cv^Eyq^Yr~UaM_xYHw|hYHg9$C6QLGxk+njZf(~_g|(irV|%0ZzPq41w|nS3 zeUTa!R;spnaWt$oHMg5NYi;e#EwMbOXp5U}Y-+yA%2}%Ye^DLBj_s*sLU!k`;{SFX zWAux(wl=qppbmA5n`+w|A!mDNVKkzJ+S(fHn<8ON>gNtbLg8f-CQNWEHLbZhyl`1W zqEPQi6BiXr3R){6ql!SueEO)=*o6MPe0RylBxfZBeAH zEmR*Nt)}KC0TU;J)eVhp8vlp1Ma$Y7B2AZT;YfR=w!OKP^0Y>3BaKTUS~%1mB5ZLW zP#HL15$G1&&P`G1HL%@=dD^MWbdd;>4(HTD<6LNkpP+ z(dODvJ2VNkYx>erOC^d$gITc-(L=-t@gz~RJ4yeD($Pxz~QifF}9 zYU+aGn&QF*g_Y&y`4vU-JgvBTfmzeoeNl0Babb03U_teDRmHrU$@hv`u6H=2w?iR!HK- z)ZHpmDW#M9qS9%l)x@tZo>?u=`6O03E%wNBaYcSXS#kVz<*aJn73Pq$THS-$6&mBqu%lr*e3rB(6r6qZ=`yd0jKJDb|a!&yB(PDh3-)T;~x zn0@4(*_Y0FCwW#BSI?;oTua%c?+E!wFHkv+rv+21q*6jJ328l<`Blz=aJ~8E7gm>I z_GXnOP)t%xAPK!);uMw@=U2=+r^~DOlsq*yl}kGWovbfhU*)=!Yc1E0xPH#{B-e{v zZ*jfLb&AWCq|_j;OSt@8d0Z7-*K^&#g`Q2_#&s{(Ca&#Vk8wTEb$|;otNMt`nT%wY zOXHfrbrsiit{Sd7u6C{!T&uXg$F-GfH`lXVuW%ja`hZKND3!*Q#Wj{Imuo6lHP=F} z7Ot;z-Nm(@YYW$-Tu*Vm%yp3KJ+4o=+%9D8T%)-raTRb?am{LCQEaYnVwntUapJL* zMW%$2p-^VeooWQEKMmTFE9Ni*s?$!dVzgvo6#aH9x6%F}3Vzk#@~wNX7{7AlzHy zqLyf6QKU)M?K&8hcHt}Htb|$q_}bi?b0E^b*epy>K&^dQOT^?7+Q@;$eWCE4b=sol z@ZxBsP3tYo%t(9B^8VRyjZIp(kaKwUHhSJy-81X@#5tvDWfrWJZBp)Z*97GD(W zG-u^4-DYu9BixqI2_nNP#flK8Z%;YT6E;rO>c&OFX_@h}M};rAV6Bn%C86jPA&J>8 zjdYzj1>$YMJM(*KkyhFijx2>kyxG6LccpJzt%|G;;31+9{#p>Y~|A(n(H;m=z=N9{1j)Uvx}R| zokc8}%EcF+N^cs4p=jg6R;yc7EsnNDF1RGpzu+o+NGkU?HAbV_LbfN;9`v)>G|33s z{5;=ywRnWpVt74dMl(5fdWm(zI5TI0`0!5Q@F}&QwsxmdZs)YBgjf;3u&6a{} zw1$w(eOgm!QAArN8!^7c$BooYN*ABI!xVb z`0DW!$C;ZgZ4`;jChhp%+KeTUB1>i7Zqt@DN88!nX;B7Zd)sHjwKbT#?6aDnv8k<{ z&7_o2h)(kAbMv1xK{rDsl>I#Qo1)#++T1SFx3-W*k*z94rvc*i6`JuektUxTN78Sj z-GpXl_A-|epXsWd-Kwm0LKSIVYhOA-t6&*2yFPIwswDAGqi@F{&&parm!BS2BQV8$wM@5qOi>qTE|1MzmIFeZBA^ znd|Q7r^$-{Z=`v4netg^V&y`Pbb+jCtgekMJr!k65gwto;p}(k%d4^F!ZVUIVJYBb zdvl7dXJ_*^=d5YHGE(Gbrff{6LX*``ke~K^3xz-bn^eh+c%C$+Y0PiEe0i+2)}-Cj zt3@RDSz1^%xo~PABZMAYGX4@-dnGMcFN3n@W8#uwEu*n@-HIzEuV)O&Y!5T}kK@OO zG?nTZ&=!v;?bF@>bJoy|OghpOX{}$@+fs=1=&d=nZce3rG;l!zz1ONc_8=9ZT8#*utvhLetao;+fo zBz-7nX4}>tYG2%zSPqu-_#{bJM#2qS)n?77=6!F%=029KZd``Tvwu-+e`5ueglI1_ z39YWNsj;nr?!mUyDxB0)+L|q5{FU^lSa*xPr+-L)ii&!|8f)xx2!Hlay^y`H*{{sF z(MVkafp~AyLdv0;pF}TU1|)O0vhpjFIRA2{68E!d%5I1XQCX>fcp0o~W39zI_mWo? z#oh;GRQ-$l97(sQC$LLR9N1^~>wv6FY)>@V%wF)cA?Y`@Ha8{|_nf&18Rvx$MUxI~ zEpX8Z3C8<@^?pgHwb5iNX_NR2L%%iS{L9UvESU`)3tI_u*W5c?66#?|VIo>}EYyWp zs4&{xCPQ?lskd`05dmp2B~&~s>zfveN<%F>S4w2{4O80}kHFZd6764wC6F<9zU|G; z#JnjsZhEwXu_;&;_UQE%HZrnf%0su64wQ^%4y`2#*0H9##`?vr5u`J<32iZIsZyh& zOO?B^B@~9~Uz*BZnyqnTleIf#g*LbN6Gnxt|Jf*-%o?eZQYbuy4$pcesfNPL?II75 zD6v3`!!2gvroA&w1)wo6K-r{mXe`AQJ=Q3IAI7S!K{nGH)%EEqG5$ zB=SWwp;SJhWZsfc7o0^x86}Ov>H@7Q)Gi{@3s0hVF9-)rhyToeu(wUEJr%keEf5QK zq1l|(V;bX&Ig2%az3H2Ehye9qoA_0q&jyO0gYg{CM}L&{M`N`vQc*P7v5j; zv8-7_Z^$W%gkrZnq=?g5GYK6JdBH_hNQ-Gc40g`5o9a!wDi$igH`Ik^kuZN0q6TbQ z+@k$^>BxbO!cdc`m#c-xV|-YaLG*c;pSU4c9h{161(a!=B=%2Hk)Sm(-$xm3*<;MT z2-~K`?IV#Wmlv9T)y2 z#-dsw#t9$PL>Xky+8U`_+!pC6>rKK~TFgKsR3B<=qWlX(;X0{@#0o8hQ;o3uvYY-hW22_dHirBk$FfI1&d*=z47-u)%U*UT8pM*<{ z^MCh!);aY&H~+E!m99 zHf0*SaodLen+`9+IoV}=_KW#VKAC$K85<(3`@FC+Gk)GjQ&@MNh}w8wlJMu2ua_}0 zE$dL(z%uq~&?Q}DzHJ1vZ1zUbuPFzXnXQX!8RU_kFAC$#*n_a0)G8jC{3Xt%Z9Q*# zBT?sg(xNXqCvz&C@ZC((5?KC&I97oZ(~T8H=BLk%CyjJYoVZZ+bK^*3of9W6Y&F|F z9+5CS3q^YNTxL5be7D-R_l4D-z0dKxxWJgS61r0lb8EIC#I3(#Que5&<3=qV!|v1k z-`w>o>=G=I-6B(eK)*1N?YAXJHs?u8Inc8uUqqA$!qEtJ9HJssmvGs*Fk4YG5c<5aV&m#O(M;N& z=e?=Vl!oXbm!)K(sK^pxvH<$X98+!i&jXIqbJ^Lmh9Z;bwVRc_N;U+D+0TyY{U)-( zknClMBRXSINHXvfrTZf+Gnx^~4gY5f18L=$Zq*c}n95nvd6IDx#u)NUa%%j)@>jSR z{<*1Lo4ue=hO#;N#FVGVAk`9+5mRc3Gz@7kG4;sSJYw-^5YUWe5nv`OHbEJ>&2@FK z6T+v-q!X_~{EfBMw=#-<>#bY7Er{2fo)~+_lT)*$Jep|%VkRQF`NCT)V7R%&MfPSz_Uyvc^8eNnqI!_1KPCl4(o&`A;R_q!G8!#s+UWHh^5= z75L2g26lU~YYTYuN~OAP#~B6K$|X2AhVm@m*wHev8x7* zKg+$mm*+bZt|ipZul#Z~oys=Ks+@nOEX}GT+DlE>q)`ru3ys zui`CITyU^%)rW()eN~$3ho~f7^;ZK_h8m~_ zsZ8ZlgVhiOOV9TC3Kn^=gB9Kz&zzPkmo?sf}ur+N^${ zeyDz=eyp~r2h~IBCu*zusoJIDhYKQun`nmc~^{D!V+NpM_-D;28tA42-Q;(~C z>IwCv`jvW0J+1buXVkOmztnT;*Xnuo8})+vt$IY#P_L*zs#n!(>VSG( zy`kPzZ>c}2gQ{D-tq!Tf>WDh3{>WAf2()ZU)6i+f7EgHzWPA@O?{~Tu0B#9 zs}t&^I;B2QpQ_X9j54qxty85HQ&m%_Nmb-m&}QRe^T8!~*3ESmuKbmWxBl_|eARLA zi_3nMUzpjH^q>E^bM@4}pZwBa9F@7{{)_aJB{!{@d)4D@x4c<7aPb5Z7|U7}TMK)Z zLRP}_tZz-VZS&}jEP?$845VjyX`Qd~?<)GX=FX+z!D*1WitJSYw_O4RPrW!QU$ zmSBD+3V4xenp>*45manXTO|bG1SGP;Fo#zmgk%^mrKu6*gIW642(~b-gedB%4ckB~ z*M*DQmZ_;iy2w)Gph6_JC~P-sTRC6JIa@OYG;BBakkfj{qwMo~sa-0^DH9%J>4akR zQq_=(;~LAXBdmXV~5GuRPBbAG&gbv#cBf6rn;v~(OD!2 zWbNq-Ju>%mwjUVk$2z?!{-!4}a(W0JjVuw_mPk^TEn3(d#rValnGh*aYhdgTUuat_tBqb1f&a!>t^}Z8eicGa9PJqDe|!II}cCHrGp_crjwR#XB=5E~r$w@CMNy5=GjtJz^1CtoIj2=+134n9K?JVX(as^{X{)&1_vHD%{wU9Ea*X zD`SQbl?fu>uP!uDqFTC9ZNjV=KbJk*H2&=wvazwv zyiXrA=_Kc(R0Y~Yvuc!sMw9I06*uRt-X@gk1f>YnX1-voNv-2EqA8QbTCzt)B)SUB zVnQS)hrqP9hLH4q({6#aBj5Zi(w>m1h>fipX9t=f78n>bmjI@P&wAaqxJ8tE zQg*9kW+D=y_siMLL+|^ZgzB&fWEnU+R(?!gdcKcxzOW@WOEHKn!D`&Ti&lnK@%FUb z9WV^dIfqUbU!~)kZ^mdCmk%o8c`+v?8T2Lx5PuzJEfg7bg2oNfTQlj*=DPNq=)rI_ zrrt0ijHw$G^Qd0kB6F`<{s^6eNonEYx;iG=Hgmn~olL8l+S^RMDZ{;`8GWM6ChYws)?aGg_@a+P+JQN7_{xJ zkBA;kg>B-?m;zOmG&9Zj5STL&3{mswL<1iZn96vyXgZp;9;&t_d=;fn;ulo^uuK)q zZzkiw;u3~cW9-DVMKYp@9cEu#!@GY z=oCfdejNX!zfYF*GDt7$?v%~R-|kJ3b6|wo$@SD)$_W;wxo)@LW+Nr<-OkMpvs|z8 zK5rem0k9y=Lpm9ECvA4#?zqkV&3M^A<=a8R^ydX-kJpTJ%sQB~kTLY(dVB}aQ9o1m zlC#TRM%ZT$Dz(EbyN^7zyIq@8zMXtmZ|ODiY$x1T|E!Qjvm-jhg zga&&FQ}P$+&;7YHkneBseIMUx9?I?{AJ5&6&Gy@Qtu(GrxhZ>xvVaNoZ;02QAPCtJ zT`6@9!uA!2^lt<21##ct`VsgLNK?4>g3p03fNy{Y!S}!qoThd-)d}`TQ#=TynNzdD zE5IpW30Ma5yMw9o!6?`QejQu^(j`*w1vh~|0v`o;gXEV=eyMMPZ-XCzA32p9>bu?G z5O5fXNXG343&5!$$7bDg!5hFPkbKgC=IJ_f!3z6{b_?xWyGATBEU zxbd!=1`Y#9f`0G{a4I+*q&|J9PoE~R6@-3$pkJT+!1drm;5P6v@JaAx@D=bV_zrjq zJj2hlq@nfd4~_&!gI9o4!0BKGI3HXHwt`E*+rT@)_2BowZQu^@NpL^-3U~l~2Ye4a zqf}qJQ}yi+4gyDmW5FrlHDCo802hLF;1cj=@J{eM;P=2y;12Lna6kAQcmRA0d=LD< zsnYCNH6=UM-Y$CX51eYx14`}ba;n#AlzQ!Yr~2XVmHOeUPStf4qjowN0Bf9T<6)&X zzT;GzzJsTa2f!bI4>{FV=(m-6ZQTb_uSaL&abqrcGq?hzzK_cLk3i`73+nR=>hlZA z{|mnFEMOKPpJ!Go^~`-B^>~JIy+)URtv^UVeT{y4fbtw5+yTmSfbzV~``7&->Ajxk zRBt9L^=1YL-QJu467Egv^OnYpHxA4NuL8qh6#O~3oBHKZzp3D@;9b<~9_qCgd=+H; zY^B|{5^gK)v=#b2!!Um49;f;>>HeB>z2>2OL%^w^l#lcdklq2t-+{xFkE!={%Jceq zkoI{qjdEpyJHVYF;oc6bl1)m3BbSgXTZBGV$AokF1_!juKQ}K(<%Bg`1!8(xePQp7W zuaojRp`&vZ2wj}t1Gj)%!AC*p?R*M+7JM0e1w05sC+B-0?cn@WI5?+Da)W6g^-H3D zNzf??Iweg4b3w|RM0t~{z-n+lxDbqj%x_6IgI@<%g0z3qec*Z!dL}{7q#fX+;6Csv z@CEQ?5PBs+uO#|K(tF?u@KdKsPDXp~1~Wh(2;GvQTe1#L0Y zxJbSkycJvt(mu(wPjVOd1CVw}rd^Wvg8RVdz!$(*!8gF8;5*=l;0dQnv7_fr2EAYg zI1C&KjstaY3V01z0+xZZ!MR`$@ervPde3f;!P)Bna=7yiSp3i{b=ugTfnW9>*thfr&DE+ZU*TNa^qk|x)w zE~T88QqFAJGn@7tbBf<4Ipb7gq3_rdkp4B6{x$X>c-W~fo51g)`Ju~P=rSK^#Ul~r7lg#eQ4Za1w4c&G?w?{$Z>%^bP^F*E}@;s4eKhJ)i{XF}5h7@>P0-pr; zL(i?yb363>0rcDg9tGclu6fY42wVZ)M*FtXzDt~n*DB8mz3GSf^uzpT!RMW-U=ZBX z5D+>PK!>R>(+;mVRY?cj*{$Gl@I%^#_|u7hE#1-72S=v5?;esdK8pbDVy9!Kr3$LhJJ*r>btpf^4Z%&4O;Tpxdlt;JZ#W zoA0yvK4(5wYzv*L<_e{1ra0AgE~T#XIMuvrrRLQ*)%9bQx_$yky|1U<{k~5BSOKmF zzvon5%H^e8-jU#Fr}Ev$?sdIW4bE0-@HlWMxYwyJvBSA1gZF^<(f&`-{?F3xAJFa} zIn_AmG7h@TV0;7^A71*MmwuN%j((_v3&A=kzrO${PJijY4}1!wANHpo4*05413EzH zG61>^*bhGER9_se)ECD(Rc;U~>abHynFOnv>r_{g-j$?x70*}kd>!dsM|yKfXD;bv z)X?v*2Umi3ft$b|fzUSt`VL&G)WENTFMuzDXBZ!L#>p^nB&dUQra`|4UuC>(XT1Cz zd>(ued=LBpdXc`5^auN(Qx>=d-0DoA(U^(aqvUN-5|!@5c)sy z#}j{O9?wOLL)t5g_8MBnb2Zoj-U>qZq0oIO{dg$-cqnul3Y~^N3qB7X0N(=N1&@Q& zCyV-IdBF^jdSy|stgFC0kp7!R|Gj7xzhQYV_&snFNV{D`yIph)eAlUlRr4!lHXYJ8~ZZ&3Uidk9CZmu zT`r?80VB{ljyUP=(As-USFVIUx2n> zfVN-Q0X_;6?+e7cB8@q(KgjbHJb!TrV`vyiANeAEB$w~Ge9xtAb7|Y$o58O$H%?-1 z%moQInQ&J^|0|*Yl>u-z2;HuPZdXC?tDyH)+rghRht6dVoewSnZ)PsdW-c8E(&pFD z=GVLd9)#yBgXgOPN#{$XldqUtognqgr+)bd!Nbh4ZsyoDFb^zps^Ysid9ezlT*Z`Y zD)paA{ig;&=rfgmF_nH%e2VX9c&1-XrC&`YpQ+?CZ3vc_!@w!vH6ZCtBfV)`!R_Ea z@G0i-{>N|%yU`_xe-#O%4Gn%z$EC?NIpkvJ` z@C&wm>52Jji84wZDtf7-j_aikzJALPDMiXPj8ZOoDP@*f zB+M{os6|RGWt3Xth#|%pV~8=<8m^(t7}hZ*mKfu;h8c9k5T^|i(ilUWF~%@sjFS8C z{_)Dw!}*-g=l$#adVk^TR`K1Mfti?#`6v%t<)H>^@VD&wEqm%81VQ~w82rw0zjNI0 z3a|)!u@5J3DhwK&#|??dp9cQ?UR-}KuD@@^cHDz|@hqMTgT|FX(6|cap-~3s8_hAnnLH;)Kw~@b%{B4{Kf)C@u;6rwO$gU5a{~tR4cjWm?(*it)7sB8p z>wILLrsN=KNgi5(X`Ge&f6zcVQcL<9-zP7IAMG#3AFO#%JR= z-U$81l+1t+E_M>xWN~nLiM~`J?|Fp-QxYFJbamgJ$MAw!Z`tyUJzYwdj2B*;Vvws9faS+YZ&#!)d^*c}dyYVm{#TjJ(H~jpD zpMPS{pV;%K0xS-LKUW69pErlWUs8hLFR5X0p~-KU?+SzO)z$av>U-;be>)5=$;%~q zxn%p2?eAR&zIPqCaLM?~q2Eypg8vQmTx#@O>cU`D{zm2RN@5UPS%lWTV%;lS(EcmU zXq_t^*og=55X$QndA*_@uEvGI)kU}jvoSXe#?;%GdK+lZ6zUU;xk!b%*+8+aS1)qSeEPeXbCOx}NT!?XK@XK(Sy6_2;r^%lF{V%J;j zdPn}>QK#>y=Xca|nK~*{N1ut;XSJR+?|asK=z6`u^}57$T77I$AAh*x{JDz{@lhCb zu)BjF9XXhXMJUh5*mEo$PvA+tvK@M5;{O$Uzhdv#6Y6kE9j2*6+4I#UA5o&c`F&&cWagX)|s@< zq`H_aKyjYz#Tk6;IP-q3E>G9#Np45+I(-ADkiBQvccubQp?IAc!ePD2xq6lHxEjU% zwEUdjf-TsN=kPL$*J=Ko$#$GPo@qk+hw>d~dpOX04UwJ0>>N%+dHaSR-z?W-oYZ5y z69yyVFftGZe`Ckr*ztFE|DD}q)*EXLgK_mTelQHK7yIi|_6{8P4a}$1=W_LF-kT9U zN%P*6pPLzB@K4u+e~MSInE~wf>#x3k86EfkUjuy|C)MYD;=|cT#E;=3_7!6(mZSBD ztv}q3yB%-+pcJ=b6RNx5N4-S$$FV<7{Nlv#H-7#b^KUVJi}713unHTnF$`+=FljFy zz(ej+mF`pg{m42WS?8l(>_dKh#E&Lydd_?J!2L(wcB-qL12~8Rz4N^LPM`bENxX*F z!{B2kejGu0{5Xm=Sch%cfjxKx2XP41$H(JnosX^467Rm3fEk!+9mnr<{LUXy-ge%{ zhsLKEpK80+cDwZ#SU(Y$;Bxyn*k59QxBdJ5ywK0pM>9W~`O$nHFWP^?{(jqywwus= z&Cln%i*j{Ko!`pAQ5;j}=AAU}E%V(n-!1dpx}-j))yF+O|8si&7vxwx&Wgu(6Sk-1 zQ#^;o^E7)-v*!%I&hYEZCA^IMJHx-B73z4U<2oGIiTwPIpTjwh&$lfu--*k2=KIck z-!&k+zdGf5@U41`s>f_Rj7L#kZ_4XUe%<8PP3zyZ{+xSWLm#Lg^Ty@jHf-?T!Jb0) z6po|w_Jw{u=ToR&Ur?_R^F+)OF;B!ik)wDV)kQ>IL@uCsL>wP+eB=(^#mD&6XIS%n zhP43sHIHBOR$~+kun0F{CDvg*Iv?gaALeyoH}Y#9zvl6G9)IUqZ=Ut$UB@5rF5bsk zpJB!MEGrQg;YwVExtNb-xCv`<8(L?+b>{EIeaNr*{F?tQop4nD#sKFgZ#v#bTU99Liz zvvC8K;AY%{jo5^{aStBC!`P3f@El&iYj_>+;9Y!zv+7NK#Ho)3tMr&xqwCfJ*R2KH zumL-i3X*{d9X1$lK_wo*GMsa>woEIhPtu4a6xDQ8hOmD4CZ>cne_cr9I^x0Q$)nCW>&zEk8oMLnhT>x~`P8#{sW`ET->s!mc%a2K}ei8=li z$G_5mjW~wmID?P%#^h;*Jgt!574o}c80F(clNJ})6biWt1*hDSdQYfN}N_5#-n%{ zui`Y`)Avi(_e;TS%*7EL)&Gm>|K*@OWyn)TEpEdDcnJBE!JpUE*=y?THTz$)|FsV6 z#G`l|@8d&#LhG!y&gv?x#z7oH@mwvQtBqT2+%FdBA0{Gue!-q!bmM;P#Xh`*m+=nX z)n7C|)A-C9tiwZi7|-H4b8W%M#YFyN~HO8$mZjJ3Vwqx=7l?j-EnYaU+(RmZ=M{$pdd+aXW*S}OZuP?wf zOvhZz$5w3D&z!5DIUo1qK@_iS@%m+=zNYKQFIQs}8?gzm;dTAZQvJTI)1M!!7^;X zMm&J(Vx4+irykcm)h`Y7O`T79&Zj){=9xFI4(qWGPwJ!c{|)}XQH-U?pEvmP#$Mcq zm+`8;YO20!8mj;NJlu?1P`vWRE8lsO@4U$$#~b(%AL+j?(0@(DA}mJsy~)0Uh|j*_ z(YgiJEqIJi^<|s%Wm{0**US5QabGX)>&I~1bCUC{(0NwKuR?wmvZs(eg%wzZ2eC(g zwo`w$OJ7#}Hi+MbA8=A%RlJJDtGElh(a(#Y|J?e;*8f$RzUn3%z(E|rQM`-y^;_9p z!tRnxjA1wK$7#H$?;5Y~nt0T=`uoTPj6n^VH_Ja4=OURCQ*zu0M zmC0LK3Z|mCm5EzfFZSUup2tc25oh&nJ(UF*F20B7{2ll7%j zkbRZxt7Km#`zqO2$-YYVRkE+rag~mHPaV9c4&Gzud+dB~1D4=6Y`}eZ0B_?oKGnw# z^s|@a3e3ksG``CCsv#W4F&xK-_(;DyLBBf*b1)BgU^8}MH?r&3?E3Wxj^YEH(HGC~ z>YRy1Sd7-$Y@N-W*o7x?K%YF+Cy!tXrXsuEXV?4HScAsDZ~Xf=a01Q$zWJ*Y_0bn$ z6ti(NZb9``t-h+wUv2*Ct9T9X<3sP&^79+{iM#80^}grK0?(O6o*Vl-H=gud*6q1$ zzvrO?o`(*3u9@;&bK8Bc%zaMrWu9=q>32WDER13l*F1Kgc-jO)^Iq58 z9@pI?u5&Thxg6Igd3jS_-gMlXj(hVmUPblurur#xz7{xN*Y9>c+M_Qej&F(Mf0nr3 zl)27aa-F&CdSJa0>y_p>&-3)#$MoCB_2Db@;j3(4v_0ZIkH0VQccHv5l=q)B@w0`W z4g756C#K*l=lFSnpDX#fil5@1DehUAg;9*+n(O@hfuG_W6X$HlXFGnax>(!H&vHE@=HAzsOR-H{Ho(m9)Ak>)61Ve{;&wZ(}$Uh?5Jf&t$AzBTPrTL z;LN~k9KmDiVTpQJj>oW9U5M9u@haTr{@S1}%(KBfzY@=1 ziDwCaOZfY?b>6m4X`DKliyhc0Z`1N7U%!2XPxPC1>o@H|^R$?!Z6l1K!Y?y!*rf5(g=;x z7>&~nnxHAVP1AIb9?%Rurl%2qiB2I!D4r51DH6uHB?9Sw4HWPGwq@_>Yy&_p(AvRdZ~|2(f|$8 z5Dn9Lx=155N@FxmH)w*U=r&E$J$gVh^q8JT{JlSg6rp%Zpd?DB6iTHuN~a9Up*$+4 zQYxnks-jGaQ2`ZEb!1LbDkVqeyu2SXD5O%VpmIOQmv>N)?KFDe-w7C@czXWtBub%l z%A^?OP#zUf5fxJvJzuki>ZqQ!(++B;UDQS$)Ja{`P5bE}J-6Wq9iv|Aqmwj1gEU0L zbe=BK2#wMhjnfU9peedd({zt!=rKLzTR*$!%s%!!#ZX0DjEV%Cb8JI0WN*iJLdI?$eiqu%$?1S I?CsS3f3U=Yj{pDw diff --git a/slsDetectorServers/mythen3DetectorServer/mythen3Server.gdb b/slsDetectorServers/mythen3DetectorServer/mythen3Server.gdb deleted file mode 100755 index 4d4b23a68f2b4622c59812d318f09c797cf3a8e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 435662 zcmeFadstN0)jxh_7-r540~}zK0Y^FD4X+$WV!(JAKn0D$h=`Y5ItU3Qu?UVH7e*WPEJ?<`%pOry~-%8!=0ouQNtzxntz3-m|TGbk4a>$_#3>3>7rEd4|!d_>_90wN0n!4zokfBztbye%7)Js!|=f4S05Q#^Cd$P9R?SEc+H zk$-!6h0tCPn0LUF13a$_l3d1efAx{P8yHq7hP1VTQ|||T1D<~GoDQv!AfyXuvz&!K zIe7`&!21D|Zz-4RtzLBCfcBm=`8Vll= z5mWEVsdHi~D5rG&gyl^+#fz!G$f+e_>Qy=A6jLYUluJx?$*D#$<&#s}#MB`Zg@)EP0gQ%-#>rkdrH?gH^}znrp&se9y9u9(^^ zr}D+rEpo~srf!x~PBFDkPPxRCQ%*ICspWENo0uw=Q@h2~b#m&Un97$^$HmkvIrWB^ znj)vpi>WL*by-YVbNMP8Eo$I61XMOkL(BEpUpdPvn$KOua9szAmQz zC8u_Zsa`p?TTJ~;PI<)CpXJnHG4)3|bzDpxms78csh8x`c`@~CIW-`rej%sWkBFmZ z<&;%SwackoF||)l6^N-vU|Y)HX5oZ8`OXn7UU^dBs$toH{P1Zj)1Q zh^b9->YSLmK~7y3Q&n=x{4r6zN={7@Q_JL3zL;7pr^>`sftJ?M{DmzbeHqAzjg_6BEkfhjj1u~HA^hTE1 z$+bp7bSXVikj<%FM`W!V)0|O|d`oK-WaXHiD9GWl+@VN3o2||$$YpD56l7OMPZY$K z$^9}C&w^}c6vUa`8U;C*(-Q@GV4WRtj9-glO0tt}iPZX6O3&XxLn?FFOi$5U`vm*p2yI-^3``v)6EalcHd60ya4c zcKBMZZ%P!5E#&&9M!^Q=bA7o{u%7F`lP(qG0EXxjrEZ*07Z8n-c}wvz+U*N5L9baD8*5VBYJwzWgXy|4Od! znkZOnIoCHY3bwL>>$^4zHp$8L6-2=X04t1w^{nRl=10L?m0aI-QLutFT;GBy7+1yh zEsTPl1Z+_hY};C{Z*dfCK{eOsh=TP4Rulz0wT|m6j)EOn&-Il=!EW5Z^(~2lSvGQg zOQT@t0b3RYJAMP#R~iL#-^lfqsn$IP_;#$T7i*Rtag~z@OHTgh?)g^ux1FAx09^85 z?F{l7nZys%B7JV_r}x(|!E+UoZ7=&&smlbd%M~9PIN&4a1A~&Q#+(ayuWG)C({y6R zMYPbWs~5ioecI6Ufcf&{8*>6@;)(?gu>A$=o__!I01K#uZG|9FnlyuaarnnvDER7N zL7yh{fb47E_^DKW1-#rplu5Sw@M5eh%oDLrq&ez|MU=8xNfwcOe*M#8l+XsYEMkHu z$|P=gskm(~o6Squi-Fy?R+JWe>_{vJKHUh~S65j1;VpPS{WJ1PWJ#)V-&58DkGw)? z7FQgSG`~N+H>Nb30q^k<*9B)ZA!SV!-N%tso%;0e=tI5SGW(g*OH6QHS!`{%ak`=n zk$qeYxKdl)$MXPJ_c05dlloTDxq;d)dCmIq9Ima)e^g%2*gnI0yHwp%aaJpIBC=J( zbXLHM#@Qbwqf65ixVr5`v2D^VFMg?gtiNmB_-&2q^McPlM33B$wVp=K`nU6LUoTd+{qp*7{bvE+hgj3?k?EFnYKp93lD=hG`+WtXo^?gFsn)Yc zONZ;(S4$K5ejlwFAF_M=Oz^=%Njd{_xJTQ4@Vi)@h&z#^@uQZU9+KHhx{pcbk-FFVSt@kz zZiuy$hOV&8D zX2C#C00(P=`Ku(2*fyYyGA3BJY&dt{9)Y{N!_>#-Zc{ivJYvqp>c@fFVf{Ez4BpPH zjI>f^B2Q93vgpSeUK!b)15D7cj5wtp)F3XUL~+g_XY8`!n%}>a`jh1pO|T6z!9EdY z;)eR29kItho;uXyYRx}4b@U#8Bb*=6L*drC0zN)Gh7u_1AMr2CfUEVy{4LXJC}~Vmwo1 zM=jejly6u%T(-qBY|9{7mg|YA0&U9VTUrE71-Q*SsQ?l(XwO(SsnXc}-Y~ zu{CdUI3IJj->n)~(Q>A_B9g1!gRh{4pI%SaWuTU0c~gB6>8dZG8KZ;l1&|5f!?tQG&^cet_xp-b%*y+MmIXF_AssO(l;>VQT1u$Yy7c$=7hw-{cEj4ucH zEGm4j17FU>9NB&?xYUOFf5yHDdkrgKzBXF1L(>>#L7bQNqtri&hmXZy6_Z_Wh5s$( zHC{UEdjw^llgn?m!W0wk{3AWQdkq%Idla++VvV@HDaxcV<0^F8gOT?mtqhE>kg;zsn8);1_>KWAQs%_;hNw#3Uy zk(URGHp}U+i|Koc>O@IE!`KXt_)H=xfTJa#;@2V-j7#GpDk~ytRu`3uRL|vjlx|;` zBCx{CJ`eiP>k~TS!1FV+s8+D^T1ZI zNi4_T?7+)L*0@}3xo)8(*=S6T5v26)T zRbrk<<<(@?I9;SNB}Pl>qsS*PFE&@-n@iO7c3$YrftB1}@gX#f34VJXV>VkEUy4r+ zy$8^VqD9K~NfCzK^QE2lp35i1o|@CqgY{lxM@M)Eafd^ayE;Zt;~>4zi}-u|0e?JC z?b8$W{DB22!iQekTO|MPlL97q(}KU%?qoUYt>9x3xd^TW%NI;@u|^$o3(PvKBpdw` z;ZZjFqiNJ#8HvVgV$hiEXe8a`NOPnSNZM0ysu`)fLr>+M3?Gc({J7UM$EqeoIJ-Pn0e0^<6;km*vv=1aQS> zA@0?M=SV&Dg#LwG^$vDv4E))Pl~W0ChL~XH;;xuI))f(XkoL}VApu(T3`HI!xDCA# zEAoI`F(PRW=MP05l)g$3*Jc#kp`PhQuXv;6)gL+p>F-)f(VxhO$NN0R3nbs z%LaQX*Jc@#*v}XBXqO!BeTs6N}iPrk>7F{W)tS4W1K|kCE3x#D`0h6DY%hb4RN^Y!I`<{`*-^9U=kQ@}R5zEs4J?RORo*O$E_UBmU| z`x8djmv4ph!(3rpj;=4AB2U^8c-r*2Je@5bt}kO^@RTR>G^8(|P8dmFGGg*Ey1ty! zT!i*MDO01?mRGNftt}sqSNbbbTmBAsEPMAV;A*)tm~RGZ6~BNvH(s27S~2&y@kz+J@BA$6 zyzszqX{Hza_RsX-@0FQd_^X}Oa|AtdWO~2@pOba~e=_|Ytd2DBZx3rb&yWl)2kA`PR|O#1RhU}Zymue*lwfP2J7@dD;cv+Je~REQsR+z zgRmEc7%@HLZ}5?&J>oO|!vAUYH6CdcJzbox{hWFG4Q)=Kh+%>kWZzyrva;vL9$BTf z*duEe;IT$lHsH$0itS%Z5h%%U4_HP*S^9VcqaI#8RX4rj5G$iR8&$d#d+x+$bWx~x?2hn`4KfI zKTh)0?v7RO{4FtB zUR+38GF(SvdF`vlNnU#jr|w0?H(xYP@!b=7MYoZMewh=_iSpXNz?^$9?pucg?Didn}xz=rHpI z__F9|pLy8`eEk%(U<}9fJ@a)EU%4^(S|5Y2yGP}#HcWjqU)AB9A--r1R`2gd&OKXn zWR>4sH2NyGH)>Rnd;GsMlpg=0{CjmYW8V0G!2j-Rhx7lnF#o5(|5Wh5ck0Oeulo=9zhzYZ ztN&yE&**4<{pP~|gZ_`f|NHZl{=ZE9KM!%oQTYGsy#Jv8t)uq8b)^1>M*)v)=rj)( z&jfD(UH_b-yoGUCJYhupZv7OiQdx_iW4+X_NM{n7w*L-7#;tMlGG!k9jbXuCG{QS-mPy*W+h-#ImN)8t(;$;$1xo#iE@f z%d4Cti?j!hc=B~$UoblLJ)_tIa}4VHuIU*@Jrk4qPtwIG3|}gE>J{#AhGYswVa%`{ zdd0XvnZ=|z`l~W+bi!#?pTpmYS*}Rj%a?qqn^gJZk^gMO{`ag1 zot$Fz_&R(}e~o{&uMiU1Bm<4uK@M09Y2rkX(BHGwAzca*s9X)jekX52Ttts#Mvq z>`1CLDm}e4Mv*t-xqkPMRL@Cg0BMwT;g?2?7r*@&CA3y=jgsshJ^3=J2+D2QH3(2D-^&XxXX?r^>T#@uYIRNVe%j2@fS?Q3?itW`XpN+)!v56RL~ zFC0cM+#dr&)!ZIlgcYTVd?A#Tm=UKDgPC6IjA9!CU1OmD+av&_3ML^a9t&Ym0V^qO;LH`0j8{ zZAYA?R)92t3_C3Qu*0S1A4~d*Eu0X2syBROTplKNrNHTiTx)nyKhamvnZ{ z6E*fc2AZKd3zQkE)02a=O{872Xm7sL>VHfe`Lx$3<(pOcr;s0cLMwV~dgZa%t7@Cp z=xX2Tzvc`do6pS2#!0+G@;E$fK+JItc|cvmEaV%=I~W7Q_Bp*@c!jb%Z8W`kFiovD zMXE8;6wc{|op1euy2G)wez|;Y?D23TXz3qeO*)g6qV;dZ@ZXcbZ}iG5SLQ3W_GGB2 zS9~4jTs+pEk-jcjz(%$OH1C(&RlkeyX8|!*l}z4GjpdUCQ+d3_toUHYsP!$)6_FO# z&F)8gw_h8no3Ex0%?m#Wc>OyOA9b6rkMN2ztg;t}ca(|pNsF1_6W224L=~Jguodqb zw*sDuvz?N)#;F>-r%ZOA-fvdwc3wM9JnFJ(WzMRo>=SS zwcu)GtFjJ7;*RRI z!0;XV9+kF4Ta%y4Z^o;8!<}~rW_p~fi(|zzYCZnw8U7^81iu@jW^G=FcwU#Z;ta~% zkmnI^0(d4-(!{y&>V{(*K*>!pur0{z_jT05%ZOQvGcv)_7`3wV$cKpK7Yv`>^B_%e z_d8~+g-32?l>Em6Mr+R9$&$=B7vepg;IG1|e(|0Im34z|k&PgqE^_2w;0TXi_5PD| zzFpEmIz`pxKP^Y5)tdGfZfI0L{kF$%%Eo>VH0eY}^y;rmRq_WY`3ZD|?u|G!tmMyC zCGSJYUX)~li}+}akE_bvf^w&L=z;8QlJ_RrfdR}t%KZ0jRgIOX@k?MH1n#>hMEhvB zsY+gpl27uCYq0hr%I=y#k|5hQbc(xDRhmcX9k4o5>2Jg+eVwYb5v3b(>QO3vbBxlH zRHZ+B%j4gG6OmHs(io)^Ri*!d(#1S4mlk4_{xo^0_l~3V44kBtaA(9Q{kE#~^C)eR zWi6d(q)215{T;}sRTunbaW(G3nr#!)iIcQLD-1sHM98bM2xNd{|8>Rkt7^eqb1fC+H68lfd za}}(uw@CR*kbfBYl*`DuJWf}x5H!vq4A06XKCnym`M?iVB?!ksxx`!H5+_w9hzgHf z;=jTrE=H9&AeVU2{=c`Ox>>_#w6|uC&n`Uki;&bqWw2F$nOT5zOSj`;`tL4ZRzm+B z(+3u7Up&Y6X0o)67G^MZ_R3$VQ~lPt;%evS+C&YJni zzYh8RIP+`$!L@?EK2B(KaCS{YOLs!cfUBT#n(&}wyICtVIpV7mg!>%D`t9cB`eN+; zlLqZH(y7yJGy8pP9qA{XxqEF~;hCSwEqc)6H$cVDLB&BC<^}AIC@OvqDh~dysW>T8 zQ8bK-XXO^pqeVNYcur0aAU%C1-3^m$XM(rcKsAdqg25_rhmAF-%i}{?m$IfqSWEoX zKD@UKGnerTApeDs<08nh0Gt+rllfJk?(FW4Uv_+k(Igzw35jCgyfL2q zhyrm3S3S?tsB)NSR6P}=y+6%RVruJ6OmOE6<@DCqkvcjLlqFrsz0oFe! zN;6l~x>P0Hk4Z)+=GRMrLN$;0twe-}HlAnfidev_genI)!65fUUrbNl_A<&{k{Z{<{BERcn z$Zv9#{Kkv&`>9PDpZ}@+az>S3T3AY|@#Ud$sSoF<SuKBqCanyWVtl5H?V;f?3ZK&Cdn$4*B2x`U&);en)SI*j3EE&6Gnc%J? z-+>@p1)aq`?LRHA_Tb&Mae_vC01b;T>>zBrlRfM0mt#dgdq`c7nsD4A#^!Rw}1*hmYGnlf+@{7{p&q3WsXj_W3rO zF;fq19D)8LXmg|sf= z_uidhP9yiG*8(oB5+e68my6seF|*Gf6Ppu1gq(Y3#co{)w?6y~&n|F7arQ$o{Qh^Q z443m|b~HJ^$BrcD-f+&4oIjtho?gBIOXCw z#gXaWmPBLu$r0$jY8bgM4kStEsoXIr_f8(JW3K=gjpf*V;WsEc_Qhp>K8bu`#|X50 zMxmWaCO>~-49eHUp!}<&QhxJr%0EZu3zA9y&&-IeD@#V9dwsHGrMhPf*OpHw4VO75 zQ=S+zdZ-a|6?+sN!;igl{)9;T_7Q0B(~qn#ouHlkjD{Gr?}bO>_CKvx^hNS- zhvIHO4CjP3=?l!$3`e#$a|FKbAB8WTlg7d27#{!37~q{rPj7Ero2-r_*A~ym}Pcg%q+$f14(aY&Gr17_?86 zX^-v2TEetPYmp(G6YdSnZJ*EA<`i0AJTwAd@9IYGlbtD~OJ9}wQt#sYIA^#n{RWsu z9`(=a6kUqu>qp@nHD9BTkCP%#{0Ka`N8#yAie$^QF}SkF;A*AJRqVNM;s2WUW4W>Q zEN2wjXQoQDAIKd(hrFIWyhq-T8*OyI9jEk&TJA|q!LJH`B1H*V+{%n|_nf!3(f=HF zHHsmD)m$xK6T!wkk;Bj0}X`aHV3 zPKmzeFYXs39tn5@=7LYUNt*7sh91^YDcIv1sO|N;abHQNhsx1SB@bjv@;V^z zkmoPX3Ah=&=RVaD*nbuB#Qr~rz zv{WfrhkB3BOZE8H3CC{5-R`(6kaoTIf`=1X!~^s#Otmfz_y6&TzaS^2O`_Tc*i68@ zVrdp(^-_8Po%UH^?I^4DJN=?`a{+Ya%wYD$Fi#A)E1=t zS*zsKHlz+`Et6Bbka|9Av7FkC)K9Yt_P8~pMPu6rfC%-6F*wyZO|7P+A_95m&> zVSlK{&!^En3y){@s`_YXd*LSS4--!i~>u+nb#oC%$tAzc}w!{<@P`H-&UFCNkr*^3^A&-lN@N3siBjJARL z@bjZX`=;2n?-=Zuf2gy)$KTnGUH^8nV_p8l?1KFiQ)bP%RM~SwYeSDz3zkZJm!4@fI4WoaGa&}Q z%~ga)mA8uWLg?!dP8kE=qeJ-;9YbYXy4~A`atX7$oN5fT_kw~SixgN}XkSIDDLup1 zwynWE`^68pbeFVLRO87__qQk%Y4Ak@iMHakggvs>%Rgx8KGtkNt(W5jp)gGA_9}(y z6IGV#n?S{K?@;Yn?YE%)tz!EvZg7&gy`rVNIeACLP%VYhtq-+yw=~D2&8>0AivL(V zw)!hy0Kc{cJA0r|jgM7l#N9Me_XoZ6I|e=T+e!P!s?K`oFkh(icqVc_QS#@v4|=HXl<}00H*Gm-Tt6`e z=lI5lXCQG+O!&x-)BH09^G}z*T;8erdTL5rLA&9&#?gz2{(z^<`HqjUeh2S3VlDvI z9{f!f>*Vu=?Z8`E&~cjH>BD`S1>oz=G?Yk8kWYotw<~DBY!~jJ{oN#qBK0Y-2PWZu z#PB_%EM|K{c+ZUH{>XO>=zI))+oaz==uu9Ngn~68#rGNTkcAt{sfx%cQstCJ()?kemG}HX0h9y94;B%t~DY@-EKlePK}D9t5+2+E*?y2AL8M|2>8W=tsV{*Ldp*X zgW=pTwX*FS^pZZ9Tud-t(I)X-da3U{{)-2DJYD$P>gmB>C+yb6gB&cETC#_M-GecX z6XsEpeI_DD&EdX?95sjEkH~3O@$QbuX;rX{X->|hf5@5OtxabJiC4W`D_uU6Hc7A|q|V4Dg)J`5*m)!ZWC zECx+nL{7UZCoY@=8fA~=jWKky+n>h~UpOVE>h1Gal>Qhh{jpfuKaS20rt(w=vrI*i zGX=I-8gJZKdYk)a<1iD|(fu#|c=!JNIN~lfEFHXau4<<<+zv^|4GC$&Cs9Me=fb%| zRPbYo<|YyAys*r0s#t~f`!VV*5bNCtUfcHfM3nxfs&rZ#>8WH%)}sd9=aztTC=S#U z^V+4nCRLt&oJa94#B+7S?Zz6kKr_Xm7EczePiTWrr*#C$R(%{h+ea{2kqvE;+=$fOlPruc~~Y9q4Geim*=sy~4G zvopJJK42Q|A)uQZuAS_Ko$2+pLMkckky`h?aBV8f2^~Jg%6&VW;{^@ho6M?Cu3>n~ z^XG7Tmm$xcnCp(f-nIAQFSoxRf1Udo(9yb|!`~i{K+hf*{&MZD`0H$^J@?3-S^ye) zI&rJ?k?5Yvi^x&;R8B;Wx~IlO#@GojuUf z{!Z@D#e$>))*JB*hDq7)jll4Wa5;%$dQ)qzl{97s_X5`ZH14mPNTaUH=R~ij z?C*-G|8TfImF0vBVG3HpIsKsEVUdEzcn5eJCrfYjem(-%ZQ&XcEmqL-UV5V_4XnaN zT0Y64u`l>~V1rig7b5B}AF40HHDMdHAe_TM-pfT=Djz?~16I5UxpOIUyz7_SHe9k2tiQAhw-?w$*cAf%VUw%Di|uy{FTA z#2daNgt-o_6{{Tgm|W@{l^OKL#)j_# z%4=grEEl^J+7{0p<4s|_1yRs(Uq?ZED0nW^>uG$^IUeGSzY5Bg%!gjjnb#6LAs0~3ruShXy@_jo!bU)+({-z<) z(2F%oz!wTW9vbj4t7sM;SVe92gN_S;e=k(fejg}$KKzc26sK5U5el|Nz(^kJD+WEG z;9Vhl^ZC4zE6z_tG9QX}x}h0Qjm2Ds@$vKQa0&TcnO5Ysj#VN#2ax*i*vNOM;~9#= zp3@XyHGq9g&48m{K27nam25)C*b6?5z*n%9Gy?CJTX=IG_h`SUi+9P8UJ=sL&9~qj z86u`Q6CmfD5p!};`vw_uPA(0zkIhl0jux$YnuOxa=9kYw0AjLirGWL98RlbwG8v&N&f(t_uH3 zv23PX7JP)uo|o|}+z#Qd6YDVOkzW7n@{09Mln#U?-r_XLC&j5nMAgvZN%=coBbB7~ zdc~NH)Dv1KD}S+Tq#7ixUQt?QpHq@#MYxA#wR40Tsdk4;`A%7MyQ%gvm-5B3;dyvx zM~;>a&*N*9@1qUR0|#NWSz>WhZja%geAw1Ub9S9686xpSrZ;4Vm zoPzC;@<|FqHkx26$WR$PVPX{1Lv7HR(m0$c9rT>5alvk7UwPI=|L0uUQ7l1bUQx!{ zmJIry=5C8rg1_P}rdEgE>nA*gh*L@RE?+Ke=L7dKWDP&PJm7J!UpcP}d? z1}_)LxgTFv+B+b&ccWzh7E`jZij8YU#GEQAXZhtG=o{^;X=+&GZ^qGk z2d`zQ`!tSeg4GWNf1sKpr1{C`DR2#}Ad0#W!%N_f`UdNd`nzh6`iiRYA9#t@3z(-U zQcmBAVfg`1Hr~`>**K0zy4UBa=z$;D1m4|<27{LB9+c-RjuuPLJ>Y7!+%nyupDOn0 z{g{F8Ye$?Q*(vWb(RYoOV~5Bn$LA=$(Z#Vzm_1v%&u!&gEPQH7W^X`dg=r?xVl7u- z9|M+`#^XL|PX*mfF5#~-;(iNY2nBz26?0Uw;4kve&31xYz12zY65?)ae5n|FViIOH z6ZdMTQTZRE{9dvAII;Y@D35!olR4vAIo6q*S?L>uR^+EKSRv9)CeoN5i4z^iA!?!{ z-wcrv(lQrLPKSaA;Ddv1MpI3Do%fyT4-xdiOGcMh)&%PDrnCJaO_jRD*HNNt)DpFq zMyDu^qllE54+Y=9D)GM({O?L_MbFcX7mdDVu0JgY&^zpjpsD~D?oYZ0~+Dr~pN z*reK*(W^Xe+@_t#Y+qqrHlD56DQLwm&6zafd;BHh@$)$Q^x}|oWZ6VWukRw^`V2nq zaLK-LQR1lQ3ib1ISD>$0J!DyX;Kg{7V&8DTg^hia`IPux{{_Du>kfRQIEkKVH<`3d z@D+(3VSX#eDCg`8JEVIq-8k>wD!zM5@AU6+g@U&t{-P0bMem7qS}RC1@!bTR5#R&6 zOe|J+u?r}AW zEl=dVc%u6-C-BeWiNjL{@4=H5PZquvPduKI`A$5Mj$o`|C!eT}#}m=s2w%1!yz}mX z-ZZAror5)eD|&ajyiPsjnrPYvFK^+Zl!Lsv@$-iyYJOWzg<1@F5euI)2%s)P?5H?o!FJ@J8)Op#NP?}Bmojt>{`c@XpP%9_7&TnDK8CcbuswVE-` zN^j0f(dIa=AI~1pv6%DVX#t|jUVO`)^e4+o@C<7^Jm=`qc3!KDHl>Xl$I&kJ5^fxH z-s`u9bw`PvZw6i0aEeB8Z60|Buwn<3_F}`{jO;Vb?`UfGwacEB2vg6~lJ7-jB7Lt| zWrqAM$^VKj6P=Fs`6xcEZbemI^yvPBw9K1=kLGy2Jjc^%QnHBy9wBK}3eDs6O>|mi zapM)6)YR_AE$>aRz;PT!aisi%;|kmFhkvj=nf~+mvdMbP>U7@Z71!|Gt_p?CbXS8fOi>2#V}6G1pk;YM4`?mQJ9r{nvYH4Oq;}Sl1$+|8UOB>6kY=g zf25+YK1|_0k;0>&;k!1YVt7S^HM)wzGMU0xliVXv=#nXXDM^yy*#t?3u_-)*+Xq*u zD69!nnCWVP3>!h=@li3{2MVXDDBL1b_^qTok;36Rvs0z>?SQo{$Lcx!em5LbC!)%85oZ4E6>rvDf!?Gft zXuc4El=DxnZz(Yx*D?>`uSwg|J@DW|#wFGSdrSA=j`;34y|z08(WU#gY0Wk+zMIi$ zyE%8<@l0K+on_6|@0M?m+uy6@*S$26B5HERqU!@8)Hk|Lb(-CEtmW$Lyv^k1o|F)`ZalC2_6Y@Fj;DHjjX{LNzqcLb7| z;(&Py zIu{?%Uba>mT)Fmp{c#Pc*lh_J*0R@Ff3l*bd%XL9%FEXA0nKF&@eW%>BTB5jVW4*Y z)70j%wJooj+=KfWP`Z8xwL3@P?Q!PGmSnVihs|K_8E-(lcZS=&n6U`0?r`YER^O=9 zxF+yKCFja;v4*?+4p)t9k72K#aq)&+!>K&@wuS_Dq4gQiGGXfkoR-OQpA_kN*{N|Y z5n6oQ`c{95psD8U%Q0IR12f0B-CWsL$;?E}m(HFE>0ONLQf&#SeWOb2(h8nco(gOA z7GWat->wSPmIjjDPgfLFS*!0T8CZF#Vo$YRAbl_iPa{5iZJ0Kkt1%Q9PUIO~dY8fV zGXCG?*SX?d6C3W!qjq!+)Y2dGeq0u3d#db*;}eCwD_%O=8_E~P^E-Skuj)?0OJg4Q zPZn77xp8dbp$yLa!Z@p0Ye~(KdQewIcz%{QSbMd$2=vCgB)F!EczH5UBRt`sDg^S< z?6=q#nk-AEjakS}&R|Y4T?hOObNS9$b}!zPEro_IYi6shc6WJ~e_6$+{_BN56raZ0 zd?|XO!1Pz&2}jGT%*msmh9KWEwfo!^&E;&h!DO&?}m0B+sc3I?D^2HV-KRn_GYcK%xN;|Y^=*& z@v;*qq?%uLHdpi)H?Mxm_@XU~{f$+3>bfOf;PG)-Rdh<$U`@iwq7EaY)vcZ*9EbKDUuoVv zJ#f`fW&HNomhShPTe{D;G_PyvUg>s~lZM?lTLWqQ#K_z-IE$WeGsZ2#?0nNdCX9jY zxV*Kc`-)preYs-HQjhoS<*~yOBy@N zx({o%!n`rU|G2v9X9^oCTO6w#Yu9aaoSu~~!WN0J3ddj9ZFgvAPiN1if96Xz1+vcM zC1a#)79N@%Z#p}H*Sn!DlgY-gu}Bh_>2{w_()y^e;E{NgkR>hbbo;UcvtL? z6>@**8oaZZ8m=-)Xm;3yYKKv~)uGYOt*&yMTxSt}o5#2g=b1%oawhcIEV>VeVdfud z>8^Q@Y*?sv-&)u(j2q*F_rV@BC+~wjF4%9fbLh>Q2lrJ$YYc;!9gI8l?0DXP*(8rEXfoBPveLMDv%y}Ze=g#VMS)P5(u zQb-4+H~pWW@2xxrhq(m7D$hllDw>6in2oG<`VKGn3W+FTb|IBF;=}*z2rI z1%Tu-f^WH|Cuovv(z?6yhuSOW~nS*qFS1#0^&T?YG}he zWi>pDS%Ky$6Psy0fO*R19xu|yit|(p=Bc}dj&)<@`Dyd`EjZglbJU3qhWtu~Xpyio zu3Q6eco#EEyi4cm%QLy&@yEI18*&;R&pTI){RI14#k-E_nFq_^IXs+g-?(w-vDy53 zp}BnLv8VVkb{5*V>sX#9G2d#31sAO+pI`H2m2kaiNi@!2@wRei-mYU4G`o&XfyO-8 zOf`#~t5NS6jbd?6tR{e7j}|EEr*l#!w~X+R27#fPXT>*moWKv1aG7DcLREJJ9lzyv2_50;_WrTJ8Hc z-XOFHTg%^YepmRT(`p(h#{ALps9@C=IrUn?-+~}zcFVdG zWeGN;s~q=LT*bWE(j96sZr-^rxm>cgt2Y)UJ{iN>o`AJI0c(3=rBSrDtBr13t9=^u zfcyjUG$gOXv+C_C@;Gi2J&sWAKdXj3j*Y@_k0Vqo1Q_Nj`6bLi?Nckr&pNSI!u*%K zRl;7h`9#?dZJ+w|`E!MD3Ge3}IeR(ui7(aO>x&m5EcTDt#7S1pJl<+Gzco(sB2KLR zH9Uwa`;z=?gazXp&r3&5!gK~t8i8`(&Qth!0ycC@*4ue4uj;!nQZdZG zt7mR`%{Of}jU1X)n~{FS_nL3hY-z6fK(uWY?v`%P!>#r$u-eOItL?B{aZNW~FWTK| z+3qI8=4n)Rx76Vi?XJFRqRXn9+ghA+V0W`2VWUX3Gmqw(wZeUsbFo`e?x?PwX5Z>K zH;bSa@NggIpK{08bq_kSW=kAz%xkspfc>TUP_e%fjhcpOd5ZnbQrX{ij-Bh$g(I+U zUf8#@;$GGLqTQW>UcOXYAlTQEUrClXql)ZN7VJ@0g(ly(ziGe0ULZ`j{|#DI^WeCO zbLEHD#zD7?qRqy7!Jbtyfel)V1?GCrzLx!&^>C#&F$Wg+pO)o9A#B2c?P9&w{IfCZ z1%IVixKH?YWv1xq9Ic!w%oqG+&hgZ*-(j|{)tjeU$UA#6p1EZ*uQgjz%ynds%vG1` z*~EWjNEnKQOw+PT@|Bv`{I+cC_@^r8o4mpXjG=of33j`k@aoO~$f92TA>IN!T7S`% zVywx?f-T(YFt`$pmNCy&n(D5)?8dGPrbf%Ymm$rb31Tl6RBP*5?HUK8ePdm`E6!yS z=g%oFfqlYC^JlV1|I5xX*!}v3V5-xvEd(ErTI|9YoK62X{MHYei!eg}y_M#*2~})j z0J|-u|IKUvzE(Y=-V#TYIKJG^R9LGDs%vH6JznEO4db>@O2HR}iAoy1# z*t=`&M)UZ)ghh}t?h?ehqe<{N_Xz8qM=)C-bxQK}*b?h#=8R`IV22D=VXFbR)Erq! z7UCjky|`nHaB`ig?gx1Vz>}3ePMibGY`LnHM=j)OEY8r^*x5_6#xIv;1y7@X1MJfp z$NFl(5&^B-I+y{XxUq>cEP_gsqVHsNk{s! zNJqLY>xHMBox(ojUBb6v8zl~&%G)V8g%r?sZ2Sh{I{g36m?q$z3`{uzhPCHCQlc~e z*e1%Fc&AA9dcjH_QvFWQz1mR*x*x9GAj~(F zhW3Xao=vjEW=Z;ed1FD{OiR2gThvyat8+H>*K=0t zuURtZvHR;^vv&&Xg$&ex$TAk366YI)oigq}jlDjPv}nU@27ar~d|kR%C=-%UnzyYM z=Hovzp8AY>tP`^Qw)3ddU)E>CxL%ovw;AhZ>&!(KrOwM1sm{Ty+wB{Kc#Nwm@WfS; z?VKyDgTJ^P{^GUOYv3lbqHy9D zIUznKf$ogit>7>dw0^}R^-z*!8s@YB*3#c$2sa`JvuR`{v1i8;Wr}9S&nB(>DBU6K zfOfcr{!wTsnJwvGqjgCCzGET%d%{W<<~e!PjHG`)=z%hBN%tm&sg_2zceXTAwoWJm zCFd$K%FC+Vg0*~4S(WWBVM6(nWll>G;IKVgcUIqS*TWK7F}gD`OJx4wWVOQ6k7h|@ zXp*f__-&P@~zg)e(nYF~VwC#eQ_79~Ysw=FUz-PyJ}Z z@y{vSfZ6P(yuYud(YJ2a#oEUBV%XQyRR!SNxDCI}KP%4;T#chOhRLY6NU<_HskW?y z4~*AojYb=dtuclmr%J<2OoIv zlGfSmNUr`UuR)wo3k1eoXhodsd+}y>Nr9f`vGv;Qzyw`UC1GVNFSDz zG_Fsqr7_&RHqMoRm0`4}CCv*h-9P;S%?wIZ2lsvvPeLvzi39iXu6OdXgsmb?8fR$~ z=GXIF@fT}JHU&Zo=5UhD#_#3Gk{K)?V>H5U0E>_$;-wYT@{$yLc3`0{(Kyyti8+p| z%(f86=fH8Aak0p8t|&!n=UJyY zPN&UZU2L9)6SstsX7ZnwY>&XDcU@g=j$^c%)j5Ixy7ZWHz?F%94Q=HrLw?`EuoekZT-*lOCd zDMY{hT0HyPZ2psViak#-m?v4tbGT1~{kmKDz#{ZlF77Oyt6OWFXeky}!3JM)S&b*G z-vY;Jx`N8>vdp)Oy?J8oOYmcLu7`Qjfofoh#PN34^uRpeT4>7&ymG14dD&&D#G0<9 z8L=IwLsQM$GX>)ECh(Xntakha9A?;W60!r|)NQC-xrV&^28XsGMaUDh^?%oY-!VaW z)X`#YST{pIMQAbaa%|Fn_@dTDw_@V#G{Zu~W@yP4;qtl?VXA#8R&(=otAvx4RYDxz zA|o!|y<~7E3R{G|j#5X(x_yo&*LXpTh=G44#br$JdD`GnybMYD%M7+etP?1*daKpH z5k>DU$8!_zr41R6wop#ug`qt^D}UXY^eI$75# zf(h@n(i~@WS+y7Z8f|CE$u)LC>aS^8*XK<^++&+O29}{ee!GtREvZM2ify0BGsCi^ zspjvSgzalz6Z3qCd{UoDGx;H`PEO0csK>g3qJI=YFT?nbj-OBB+;{^DF?4O*@eIVz zwcV^cGJei6|0qtgvz6a1KURXs@`D4*mFT**J98UF$2lh_w(y_D(>aDB=^TPQ4o#6J z6#PZV-a4oCm?Ncfsz%u($Q15xZ!;!aQ%pu~k1@e&HN|tv?g^*th06aq!5s*N$X;qq z=@`Kw{4au6X*Fc%kGhx|*09l`oVPqUo@~%V8@aujN_=04>?lgRT}Q>zMes!5&6Cc= z2@M`t9zMYI8%zcp?q6a!duK_g7H=VneXBnAW{oPlGiKQ(nx)unjbm~H`I>L-U$FmD zyNAgYTZk81_$q2WTXF?0NIvv6t@*U8#hihij%Viog11kz+l69toJHrFigy{38B5z4 z|5^_dSX>-$vf7FQ<4RC7u=Opx|IQZ(kC#uy`4cttMV=2B7YY?89N${QQHAl~{!c$`4*qm?3=Y%KO)7wJ9w?dp9@0#73L(xLK*}sGp zI_S-=PrU|VEx0~D2lEy~_jbWCQymlR6=@_HP?`B1>x33S|Dr(8=>SW? z_Z^z+E_erVZ~4&O?oIJ0N|vJFf+F2fZX-se&dtyy##b+Dt?Bkiq;(7jqGS3Vny=!-H!ZC4d zGVhe=8Q`bhrySx~6QEqYg=5E=B7Ha~u+lE)1gGhxGa7<@CFHxd&5Ry-uqMfs&QtFh zggOTA8rz=r%zFIUj&mKk9Sx!$eC-hAFX0Zd`dKe5MXXf8v$oB|GfeJdLYdA+J1!;& zpGth1PEsK1f3G8bjANejkc+KNG1$Zu@f{w(>z8hZqEvGcePH99g3Z zzMw`)?XwobTAqaS6Sh#TfnSQb&H~6P*qV`biq_JS9ndkny-=_VS6(PAGm5$k7T z74(TZiy$CQixK`E#!yu+boPZpi?BnW<3sfZyhp9WEiF}O=};nT{w(Y2nrm6JtB zgNLaH9Z3S^KAm`CwWP<=IH!Hia%Os<_iEFj^c$wZt6qXqA8OnfON-BRhR9R+2$2c~ zU*j66E$I7A=*?_{aQ}WL`0d2O+CrpX&rTNWn6z4qqWOSm`NYjM=5@9iHCDvDmkKPK zYCXBeAk(73jpc;lro;mFP)gyM--L>sgo)}rpRr1qUSq6#_N<2C*!J;6*^!NfeVrl1 zae`mhN@;pNr}3T9hcxzrGrtWni34})Ez<)+=m_qmH}cEts2rW6KeCbTi$@%efB0su z?`p_VXWTsh?C(OS*@3LWvt6Mga|&h@Cb{s;i=m>b0?_iV&njG6#R(sI$qM~7@rLaC zlJ;37P3xKP(8kBkhC-`diLA~#HL#9JLipGAvVs)_`rDF>mJP5c zzpK&n%gs8=JXak5e96tOf-}AlPT5)GZqxBc&VGC~(@wddL1*B1+?;aeScvG+RE-e= zI7M@tc!I1{_{4i{M`u0umlNlo>B2ako@BAP_TB;c7NC8DgCY^`zawX!LeT$kRs9ym>AgJmVgyE$-b&a4KUyatZ=h7x|QkYaM! zfMd-{{{Dv5rcCq+^E7*kyEIrJ^gf-^@#oC!R*w7hc-QDbuE zI!W8H6IZeoQjW9CTpf?Tdog4!8^bX*H2M|_T5;?dt);>MW(m^ij}ln(r&$XtbJ?Z9 zCe4b+C-h^?F~JIiM5M9Po8T5PEQo>O&mx8el{`DiLbK;8j4s05odExy&9sc%_OHTi z8!QXYc7|373uj|Q&%Rhoqmp!+Y@O(_GFM>du)-jFjVQ(*M4h+AJ=;D||7^!9d)}i( zUv;=vG#u*1NsC9)?G}C-w1KmjHaqv?6o&2gN6E&$z(9*F_*Muk@9k|`o^l!Uzti)? z8RI2bG-`ud_(l7)zBI;=Xu@jd*^UP9v)&Ix+iPHc(LoeZS=Ro09eH>=apr8NXRU=+ zb1a)+F`Z3gayFa(mBzetC+@Zf@OQSZwhaT3qd69xd`3 z_#qmYM;)6P=9TCF!uDik@)Dg!%g!^Cn6f%+1!HgC$h8rTL?6!2BWJQIr_2i;aem)u zahL4$vhCIt%u2R{sVNgBK{F7#BA$obj96EA{9f#XIWf|D{Js8X+H2aF23lF4t>psi z^Q)k(tL$ZaSJPOv-ex!Pdf}V{`+=_8?1`J7+Q{`?329s=%otabHO6@C@%B30w>q7P zoA=l^w%xur)4uOU?lEgwfBH_?G|oQbwvE8E+CHD>5f@70G>K;0D!XyB!CaVe)NeRm zn55+mz-{IYi9*UM)5WZ^y)88y`{}sVb_4eBjOOu{&@{gD)^tb(Oqa^(A+N3it)-23{Oc^lc%X5J>D`g4x zU0jf?4c{;+>#t|^Qdx6W_MyQ$jhj*0ctvjO@&v10l8+hnzPoYFM)H@+9@7NQPcYiK z>b8xmA7iVie!t%sux7>cRG%?-r#I~F^`@0I*Dy62y{m)f25nW^N^3Qb6Kl76Jumil zP`L)HA+g$eJ?bX}3bO7HeqTraHq#KFuMar0oY+{{adYe0bD?b;Tl*$4j*@u(72k(< zw!ktMfPTE`VJzkFE}`8jI9!+Ncip^t|Bjne&s+&<*~wN7cCu603D!h=tNp_}osW^W zZ8Tj<&sS9C)1*G>Myg+n?#U2CXyP_32m* z&}xC!4$5jH8jD`W!U0R{RR*nbuEbBn4i|$JgIwQ|Vs9!*2Nl=B=90Io7ro7Nyj3&D zg3k5`<{7sC@jUC%u;XpH?HZQyL&2>V8FM!Br$3**FZZ$OFFDGrwx*KRIN4$m^Y1}^ zGRhCs=XTJYj=#g)wiG9K=>C{hEREcz5~WATR#RLNGzkLaa26bV;?)c3@IJ}!E@0s$ z!Uqz)YLtCXTzh=$gDww!2-03BQcaC%I zt4g(Np1_$wF76~_)jXnkLi0$md5=Awy9aCUVspH8e{US0u}8Cy()a*3+{Q&wQK?qcD4O&gP?c9=p>G?K193-Lt4 zs-0|ip4C)0U!-XnXetFIsdhbRGT>SUX# zuJ!CyJekBN#Fd}}DFRMg7z0@*lh&ZoTPuks>D}?Bc*#p*f(zvJzeMYC-88IT!6iyE zc8$v%aOF3!i8f|0XRm3?-P?BK>c=>H+l|i0@TQHK#prW@dYu*C$ma8TgkK|U!))Ia zUkWUSfUc0NT(a;;4HGn|TCxi7#q)tJXeSjTZoUv_O5>z8{K_c_f}Y1ci|{>J17<#R z!`{Jk^Z|VTbl!{iS{S_7k_P*dAY5E^4r_<+8*=T^`u)bNyIsF_J$5HqhfP=G&5Y~+ zWA9zyqb#of;o03>Her)&U?B@cdAJ&`d01&psF!Rufdq3|HVGi8yPNDLS=eM_HsN9~ z2E2inN{kc`TLaVlt#>OifYhqRJ0S49-!t<(yPJy^`+G0H&--`b z$v!h@=FH5QnKN_FoH?75Nbm4N<;zLVNi=)qghbPjOwy8MAl`ZQhx3PHU$GvXApx?p z(wq2&**2m>*m3e%i2A{o5_qZ+Jq!IfT1aE>4Eof>CPO zFF+@bzpI}*xO(+d_BHkeaZe@XsX4wu`p-CT)7kX1%%)sO&gHf}M=`cT`g#Mj!!FNQ z3HN7e%RDoa(=Eo$&*$l!IDcZs68S`P^)idc3%sd;)qX#@5ZGU6p0K#+%|hFC~3TO7NaB3vG)-4=g5)Rvg;*>od9Ajj)4N zdY}5tY&+x`BAwV~Li`JAReXl(d#4qQ14(gEhwF8Z-0{`)Jos zyE4)Mvz}=eR&%X2{oW?)$+{4~9}W6xX$USf#fhfN)cKZ|d%QcNeGm4_InEPx-HvCf zjNa$x2|n9|%gm#|wXT5o${f>FPPc(&Wk3t3l|>~*%YN)D%1+44upRF0 zHQPMsJAFOTEngOEl+alkpljdQr`+trSlxI#kA$c+>|4>!4D{CTK}R8tsDW ztCLbJTH6V?*8cnAUCb`ed+?cxI-eKkdOjb{Coa81$-^>dacE+sSIq4YmYm&Z4`1FJK0J(zELJ40|I zlJ5V-WqXFx-S~QMd!l5QJ-$Tnvw*D_cu!{JOLkM9wbm1mUvVb2r@G={qnTrw=Opc0 zp-F~aF47yPSsr*WtDR^+f4^SxcG#V_>>r2HiXO}}rCS;3F~YWf@wM{zpvx#ks(PgI zAk~fgowhV-l&#RTd9icvezS?eJ$Je_Aw)D&VrGv1=(cs8BUaV&S?n{ceh{cthY zsIO@sL!N+G&zm!KJ%?xNdye6JXbL0kIO`4SL|vAj5jAN(10Pyl<YqI2wxZgxOJz+z!(3T~i+BH*tCz$A&hjX4Z-&h~XMd`Ma*=fEt zPi3^}fYqJGY~{9|pi*bHC3MW{iDULzjvl{j;BqwB|y)ZX1g60%{Ya^u3gOCf?OBIfIgFCO&xJH z9*(yX)<-dK#W!K6kuAm`52-N(r!eKFvXXmB=y!@uqi_E(*osi1vFGAkQ?UAKd&kmtn|#Uk z)1mp$(%g4-euvV#M@d!rQ_(DAySbyZz0hP)JyAGkRdpEKS7D$0_z=OTPj&Q-amFp|dCH)R=h8=@grn zoqG;JksbF!hC~n0-K|(EMdM6rOD@h$MXwjgUJ%Kgn$`1r)~U)}2DYfrIjhpU=%ax< z6H?~z{ezqeo0tS!bT4yqjM94<&tdNP1Tv=BH(a}`E6_<+WXE%4Gv8xO9|Ws*W^J~8 ze;ZEL(+rTEjM$H4AT8|@PSgyS);zU+$i>^TdJeEJx8~#YIC`e7^cs+EurqCK@3I7~ z?7KI5@AzPC)6zFH+8M>}rCuB~{rmA}z^^gV_?h`^xe)eJiKZFWn@t%B!xKwoPbc=& z$MFm4R$h*hi6CetQ1zu|uViPG^Z9#82URZPICEZ73=#wvgrpI+{+C<(Z00 zlP^uw;na`hrboWW+M45>CK+7`$y1?!rC)=Ej|;@g&a7QoDDOhZSo1yf`@Nq-i!%-U zUFrSRN6d7ARfZgPX~Lzh!ugbfR_&*eVzl*#PP^;J6${n4PaaKzwwcr+p$s1`0Ih(wmLXL#u5_&>>64cnj_&`98ue&Ka<2DlkpRERZS1wIAl-B!}KE_%JM= z&68~LJkWtUBs0%r-g}Ak8GHeW*fPY9ut0h? zjF7*8u3{_hq0f1T;N-)n4ceo6j&TxponJ277s&~m1wa!mW8`}8mzPtS--8@=#vuF* z3EaUWA9b14(nq13^DQ|KG4I$O4`UdiO)Tf=+ltl0_U=LJjL=V;_eehTUfNTb_vm`s zCfc1-de$oGdlxPlGH#xS#uMzhY>xWbM_*IEcl33frM;%udp6on)aiO|cqIq1AF1ua zZz>FJGZEZce!j)1u5@=zES1+Tc4GfRD}d6Qd1PMCbN1vO|8tT&Stgq}{B8yEjkDw& zd0jCSND@=;GEvUeF*$$JQ;c$xP%7p8i07P&obj2nk@Ihh4U$i8kg0sgYSsz1={Wg) zT}djFFJv=&4oE|%(H9drVNN}NiXRX0A`{*lZ z^&3ix90xA+`cRxs^$r^bU!6St9N+{Wc{c%gKL=jO=!YfL;1#9FH(Aa>-uU{IU@pQ{ za(e|y{{^aM!JkUn2B#;%b|UXe+2CsPvn{dks#JUZ1-4S?u%SxVU<;WAE9E{vyIQOf? zVP6`LcPu`MQ>3|aTkUG^EvUQhvy;odTxO7Rk%z|e^Gcg{P5qvuFDUaN_bs%I3h8jd ze#hdw8@GCK8k$5mqE3Zy!sH~4DxHR%9Q|jnHR5GoEN9^)aNC#?s&G$#-R_&C9k7 zu|e|Pi(h@I8`smtW@9v)_vURPO%)W(1$%JrS1KPgNzei`v1?>$Z_(Z#8%JcOx-Qwv zQsONqmrd!pOBo`0_KJPc^%GrtoAy#{Cv*Th*aFy1BGp>O2ni*3uW_;6C2}oXGW#L; z;VnwB=)fVV9plgrv(apw4T|Nbn0T349Y#-mm%zS$;*KtVa6T;f*MQOz>YLTE-l0LS z=TIH&eWWe4GF$uJT65D#c zX+Oq9ob`M1RbGR1ucN_R2kP$+?K%2|GQy*m&i5o@Rb{;&ncDoPL(&!sK~8x))t4im zZ~ABq!@bN(+kMb?o(kQCzf`+Zp{$O^t_M)RDLrlQmP~6??qTpxS9LHKeDuAfFEBDs zD7e3&pNmzflO3p=@A}@+H--~0 zAB_?6Epd8XJ@M&#W?X>&(bXTD!RTBWr%A1_ik#Auhx)vRHq4Yq+48a4j`QN2=#w~G z-p)KZ=iNKNJ%(E@K1a)^xw5C$1kUiJj(KL-sJ^M5bz_Z~JvZ<zcM zdlX^YP7(my3$Ir=$F{dm-mJ5&##wY$kr_5mMqepzHD*DR-p=E`$k^k-Nf<_Xp_Jv- z8H>PQ|XeinZyxgtnAkI z9B{JnK`YLJXTJ*yT;29lGiG_5MDm(rRxY^c>?5yXwja-c#n9pBl}#uaT*s5wGo9rg zep@l-v7*tI>*TsxI#;|AB@M9(d1le9-0uALc~=_Ij*l~lD$ob%a*(GRXKi0v^?RE4 z=}n5Y%R_i{#v@jp$!rmId_S|gdlc-Bat^T0U_L3uw8jML$qX=l-n)xt%ap9?Nbvxsgc$hZPYpw zZ`}rHLElsRGRzW-Bs23!TXGJ+rF3I#8Tsr?jZpAMY%)qo$RrwG2_Bx{vA}kLY%Jm| zStw`uh&Y>W!^k2d4;eEPiV`x@v3DZNy0@^3;V7XfEiqmmWQK`lj=pUNDS%;NA&ykb-{+J@iSd6Zu%)D)F zrahM9H3pnN8Mj2&YSd) zk*x^T-C1Thb<_7tB|8r`AdBSEg@R^VHM2HE91I9p(l0N*ydJ*Lw^}@o4M9qGNT| z1h&0Ye*9shYlvFUr!(Nc@|dPypb?~=?b%2=xsa{gO(h+8D7hzV(n#By#X0Z(O(Cnx zBGY8`>@#PQ1DxaOv$XG>yxEH1HXM>kG22wHm^qWGpeKHMEb$+P`MYZ8+QS7Hi3iRr z+HUj}J^akJb=&oxkGp;^QLgQ0t?g~#0Vis9jfLJBwt-8rkBhTT>A`OZNqde~DwJyd z*(p6$O2{Gg{2TVS8A~9eV>KZ=Ny$R+Hekt`H?C(Tc0)!UvjX*7GxA2yFkVXK*_Aun zyw;9f&w=emj85DdTAd{q`r@QS=pw5;YrIy-x9Q-MwC{8(ZJtI)f|2UL^cxq)!FSN? zcVAQ_sm&{Gq4J7Q9+iG-j0s%zXm+KXd-z4{h`9Yc@Pk+1O>3}IN%QC>laKPuIIFEx zSG4E16Q7ofjL8&vnTK z5T$qWi4)*Q=k3JmkDXzGycxdMfA#Ozf4%336MWFJBrP)=aO&Oo%uze5lHauCV+Emh z{OQcm?A4%`(RjXv=pkD7*cog48ZSKR7*BGVn57bV_Td*`2QjuM53)iWr%9TJFx-D; zh}4(DMBf*bucFTzDt%rVlUOvvQtw!e75y&UlM0}IMtSnQbcg~|eCftpv=fg>@#;MX z$0X@)DzWLzsCL`~n@1}|oO#^cDZ$UOb*92hF{=tERT+bpOQE0evyts2g`15RS;q37 zu0XrmOjlX2@S0%D7{^CvyhUIwJR|5p>+A5y*qF^JVOGaRl61F+tXrYA<~5lLsF8D( zd5B->pxy2aa4za8Y0JjN<*-=Kr&F=dN6xcpcPjKyWZAR>>%#cVk)ABr zzu}$;w`iIZ&rHQw8K!P{JwF*MB0PLm8g0ZoZ(rPgSkJOH(h6ZC#Wl5xsB3)LZy4#i^x&9@d;T8ba7GsL_er|_)CJw)blv%%Z$F3>A zHgB5pDA_=1_D>rD!>-srI|Iw+qiXY z4rs9JgD+H@dvRXpflbLM+3BQ}_I%H^jwI=1oz4c!5t>o5OZu|TfHG&I-k)X|VDSZg z*;9G2Xn@a<8*W)x&~x@jg+02}2Mgk0_Y#j?lvz#+K71(4JV_!O*@Q(09g@?&C;(2J znYsS30sJTqw*#%diJ;YbP)~%-zVmn(Iu8yv`i3KHMlF)8y>*POau}skAu~p+0l5>U zQSva@5gA}TDfD^5wx}t-40l#g25vXd7)+LkpX)p_PS~D~hbL~xQ+hh}>^*=!J%QaN z!37<@gnb)3HV@j~aX670X-$HZ)1thxcwA2#Gp?r{kprh)#h{@1gRH}2p|$ykl680- z*WTb%3*1L9T`m_u$4jTt8yD*(eSIFzc@p`F^z(Y?+e}vMlSf!ffcaCTpz~?tojA|L zUBEVm-Q!Q`yVT6*rM0!D52d#4V?s1Swk|3?n?S=s4m3i%J z_&)b!#v;fhM$Ag+6|IK)cxgzzUNS)E5hqI}*dJsLldaNf*r`^+w%A}DCZ_^J{bsRN zdKI#6XtCHV8g`GEg zWu&~)q4PNTP1XzL@lw6xP~M5|gYZi86mDiexmvfN61Q5Py8ifnoTVW>R`}Is+>d4Y zFKcv82ezr! zTc!7}z-RUb4zA1@%09& z5S$99Ne)_pVHq1-TVI$o%2M1jAukCnBE1~x(xB^oBNuj(l(MZBwoE;mUK0BLIMT71 zf}YJfhtBrLZY!67twn#$XhJ=b%&&ImVeEu)OT-j>bKeKqKQxtDUhB4-j#%j2ldQ({ zJv(N`*C)dAY?OSJjnxkcj+2sY#^CD3cP}PexzXIZ^Xwto=_tLMpfNnuJsCH7;xb3d zUtT^{J)_$(^8utjUdL>4i%;zPt#kuI8StJ`gmX@_E!l~>JLg>q-+vpNo7?hr#=njk zZTl7Bw-qko-=;rgY?0R0mnJ1-p4he$XP*x&KK1*zx%i*99Q;>!A@3E~I*;fW_FY)pj9lWwj@lD1ox*yN>@fz5U|qKmd`0T1)Cnv06R=`m zG)boL~i*iEOsS`UnRotfrkp4_$?{Asc+4)#KA z4#+Cl^!Q^y2(35nNGN z7E^E2Sz{Y?%|-k4J-%7OzL?}UaRy1&EWTOVDexkG3T%K3TFr!QF{P(ljMdi4Bd^iiPw&_f%nMO&()bkk4*5k_Dcs1UWo8G?E z)}54Y2Dh`~Oz`9E4x{&Y*NGY#XFtL+2EWtrk;LV={d{g}=Y2Z|ocF!{&S2+*(C)(K zI32gLPL<+!jrrL&&G8TT8j{FlxnWy8bXK|NsI$VZ;nxrR`UU7#E`|R4fd}WqGvj=D z9oG3K$Ei9x@tU%0qSSX+@+BmQG1!%0r$Ulm(MZbf47S2mbSvT)*bwkCcM**$tXN9`e-iXUyuvi0oyc;ARr;(hZ$kuDG2 zOrD1oTC}t8t;D>qyyr@_g`GIGYD({Qy>t?i3Tsr_-yFpLt_a$V;Z_l%GsxWtr{FFO z?)_muCeHQfRFCdq;;vIn?ehk?6|0>sqP0a9+!kB|@6pP2=EV9=rT3~H+@DBEwlGuH z2AsEGcNQnnd85w5_X{%Zs?0WV!kuKZdeZrB&|uL+Yee?TGjYD zPitQR?w=}O-f7jJEY<6WxXiAUj-oCrvLI(p%b8iVSQR!G zT7B>De6RBsm(sgcxxaJrF1s@ja~DTTlLbkM&P#6vroQK;LnRs7T%zw^-=Q7b4xD&` z=IC#tJwqGCeo5>bpNuo(#G1zP$6e0O$?Z!!;qObg8v8xceMeJ%ig7Rm^Vg1b_HhjkR#8|sl-N?h8~or0WCwB@zhY!G%~7R!b`fkkQZBdNbfcK4;)|sS>_doJDZr43+X{X* z9QLb%x`MOLvS~PoB3fSAR?#lfCwQjY@-PCem{GGeE(zcAX3UxINBEBDr3~2*-s)qJ zJayI$aSM!#@Ma(hCzZ?9-95B3Jc}E`jBV|%>Hy@Z1hft=>W7R zADH>VR?=fUiyg@l^l+-YQ7AD}J}mun zQMb=BXisNeKoUpW8d%s1Nn;^d*psBO!~tu#^|K*i$dE9eckFhW7ugq(r19yPe7XJb zY2{GeNMk1S+9P3KajdQ#H;6{U%O!L|2p>oIEW##)lMp_Eu!1o5T&9;)se)$a%J>3U z%ErS+E?IWVkJn}O+{R9C&4}?^KwR;uw`rXq3l-9!#ACfPVy|qFq8`J^eoON~@#Kqr zeNePLlV0#iC+x+av6jq&^}~=SSlif{*B>yj>kp(G+YXqmqi0_KRNMU32h3%w59k*e zc!*LZ&5VO*jB(GJ*34>$yu>gs4;ZZ?t#Quk1G+`@PAP9az;XzF7<1Xc_U1Z zu{^4ZeA}s>?QV^Fwo96Ia@%yb7TD3O@hsU(p&it=AQt6 zc0=ILZmB$td$W6f|O>feK?6E?`79oi{$QkIvaVzHJn#3Ujho_juWgxuaS2- zH^V2^?igQoni^-5shAyUVRsc*--_p7c&hT5lnLf4L*$;Vt)boS)_~v#UwI zDKA0J;lALCBEH~OORM_$u-h!l@Wkr}Wm?8it@TE~>c6g$`^@_%_g?n|^jSPZo+%rFS6Ik^SSrB$KWZAyx0A3_$qmG#K+id?z?OYrv|**j$8+7B+VjfTs53} z^aea%^6>wVC*gL|*r7x7+aRs+T8Q&k^x$eLWYW4lxXWBHi)kVD3qL&t- z&BD{*@fqtt3G!UGj{AF~Rxgt8oI$ObWqfr+Dfe7g1D|4Mc&@u7L+ghznW7(*Ow2Xs z184!$hx_@h3vs`7yX0c->+T7Qpv|wx?6583-pgHN#4$)e(UmN zXI?4qd%NX+ltb1;n%}xbayDu`0qqkb#{<8JG;&fcU)C&@WBt}mo~^Sr>uy#3*8L`r-DyQITP|%Lv`Y!idcaQ3~ z?yFKR&1N2V_TBJWm+0|M$Hon7R$m|3XPt=b070AHtauuh$<%98J{JXvPsmLbLqEF+R8T7F_o%)B^xtmR_k zcxF=YzA02%d+>9IyFXHsPVSzwo=5|4ke5Tf1r-N1%fymdo4X3@GK z#y@9_Ncv-jpyiVp7vmS8_a_}6W;Y!K7WfWlr&J$=?Nx*OAjH`j=$ZtNa_7h4_cU;J zWH61uIX6*|G_?lU?33TTR9W*tXu`}Jrg|X!fZt|>tdEp)^P>I-dsIJLxWSA&v=|8< zgDm_tzh0^Hq|4h%x0T<$K=Uwrcjev%$$YnZvV`_+N^ipJ{e2Xs@luVh40%nS@KU&@ zl1AIXDud_67*B&4a(+Mf7|~w(@#6$KYsYm;yWCKDs@%AMsAyh5W558vb8DXZZkth0-Y<1}(&(SpHVis){E8QTvGD>= zj`43}hQX&@vhT0iXc>;wvS8V3^u17$=b)0F&Cr<^SoNmMtRt~nQaKOLdmN=cnGFv> zmf;v2)T21ymlue;ujzI}){y2|nPW65++u%7-vlD+OBh62<%WL-GjOe&$k?Ruq zgy*q&x+MH&Hnfl9ti#}kX;a=OwPx%p1+R0W0@Pu|Ja%LdPiY;ls@HY*utxKF~%hk;#-bCZDW$xteK`n&^`vX{SW9MdQxtEjfAg z61jm*^f6WwY7P3N#!w3{Sqis=n$$99ORbH|8bd2Y$<*xso7y;KN~D!B#SPxX|8W~t z`uUriL(OB+hT7J~nw9{_+2XAZ`Xz5T9H?vb`y^^#vdi!Ft(q}oMlxe_Lm^-FDnDgG zyJyX8C?pJ0Gg46Z)Ha72q;RNanZIR*7!V>;_rG`~4_5Q{SC7-{=U(*t5Mtz$7HU7YIzvT0_c#*cyj{>rTK*}cljK5X?a0aNnwSW zw$#38P#EPYTvS=;DzlfkD~jjR*PIgjTq>^*jOtNUR_w4>7MGV1@mf6@)|NDRyf0aTJO7Xxd^Y(V4=6>Y{E`_t>zOUh5eRH{vUc%jWX3C{JaPtFWS| zyrcjWD|F4}?V!Aa##h>1sIg;yRdGczbq&>{vfSAxipNnpqK2S5mE)=^Lt1-f6-wrH z5xB~Tpr9(qAmVvwj>}$3T@GAPsAzL#aVfe(^cB6kOA6;u-%_0mt|+sY7CYQ7d)ZvA zZ`E4xai-DDRbDLWfIJn>!omXNr}1Bf9_9700H>q8Y)h4c2qc$ zw-h+FF-PsHxT4HaO6=EV}cf7+%7=twRB>{YjnhP1@+2ZE^r@;<725`9FlCg8E*$-`5I=Sn^pcs|C%5*bUylZj^vo*X=L@KoZd#?yr7M|f_-b2pwHcz%oL2|O?2IfUm! zJg4y_8=-5*GYQWuJo$K>c&Zw)D2D19u}u0Tjd)nfgMM!q3vP&SiJF>2HGaR3_5;y9 zz-(z^Sgc;rMXn~)(BN&v`WmLivOrzIX(3$(^wp~bfUl1Wz0I`2i(+A{qP2#K@zdg5 z7+E+SD$ZJOAjm;XtEQAS*WV)X4asEMJJ9Ye(9jh0H~1TA-LAz(rG@qt+E#+sUt61_ zCA<7Bt-Lakgi_0@CO_XLgi!((_iEaE)=CW_Uu)1GmZEj3@V7*k_krmGjgl{b+JtGR zHPI)vgg8>rrVe-;yeq#JH(D3LJ$Tyw_>)=bAULJ|$v_g?0a4rhD_i`{jb3c9vH!zY zZP1HdU4+yzv_?y%LM?TLNIeIs&zbaMU!)G2K4sIeX>AN(w?%XUk+D@$tDw<0QqMus zYE-QZG|*0q=g*qxJLifu`&*WKgR_Ywyk7zsIvNGEK0q9Y7Z*syjXwWM>=4hn0N|(L zDf0XHYcPoIB#i-Ipf1n?y0`elEzwdjcVgpti+J`(d?lqXB}#pRieTLJDX-ZdZVmFf zMfSJRxn;+22-Qhc&^c2Q{7KtNXB9Sb$wEa_-g@p>qBtDhV4%8L3=3y#Fzi3)n$Y;d zt};SWdS4L;2Bm6z!23sR`eLW9)hFs9Xm#ec)>j5oIsntnA)LM zh>o>Vv$wI%51av?w}wj+$c%3ZQ4C|5*9pl=xsW4W$d(s3HTwZu&|FJTMLoT@)RRa= z-!}F8LjLV6VGEo^h;I%wAfgf?1&WdCy~O*ZMsI^(T1A2wVA{N)wo&ag-bDdEUr-}0 zjTbWY3V$;gqNpeB*rf8Zk}GCQXz?Y}XHMh7mNXGa767*bAU;1K8pp5#od=lK2^o=m*||LM6_ZPOp{{Suy||BKt01=`c2(Z7FKi>Ggbt!NHl z$f28?{dED1=;jFL5iqU-h=CHr6-o)gdKV)9plQTPq>WFWEi$TAu3Z4Nh&D*oD8@(q zAa&6cH_>{E9AXdT_tA`R^+)v`QC>_n^h>4whEVgWb7sRa>w$~r;Wy3BXad#Ldm9`5 z*qf+}aZ0oPFzL$3mml3woq;+?uLw4Kzg>3Z6oHgqr%k zaf6i=Xgc?T2q(4_*vUpqQrEM-dz*f1T2x00y&2by5i8_d{TTge1m^X9HH@0XGY*22 zx`xA|`*O9mf@w!aHL2tV(n7T4+^GQ_A?SgJ=3ngAo>33h(WHz3W0wrEjH>Ip$V)Y^ z!yF=RkIm%Q=hvn*8Wow)Vvk4t(^8MkS$zmPX@8@?xo%aor(*Y5G*&AkDGPbZZ#Ldq z>Lb|)6x5ft|ATT`yinPDYp!Vxgu&&o#n)ys)?|Vajbp&HmU4}FOk7MBqc(LIYZ%b=9wjNm0H71Fn3=KE7RbjzT`Fj*Gmt!I7YC2qmZ4Ih? zBa#v#^cP1V)dm^^;d%@Yh^3-()K2Pah=^JgjVE=usqq*eG@gQVJR#;9=MDO6V+e$JP7A7s#6ff}z!ReIWG2chp*-KXP|7h$aguk&l6o{#AKVAeK=ebWs zPKR(4cF{2iwQ(TgmwTH7d|Qb=(KrmoEzk3fyM+mz4R$OLCAicaoh~u$5Ly_&RH>#q z_XatFp)gI+3Vv>v%t!?!sfSQnQ357;gVa&0`fG{A*x;vqS_aGwC!PM4355)od|N^x z&|hoHzeYrqOjUf*mCc&t~1)$0RqCw%~A zQ4_WLnt0`As~b2?WkuD9WJdjB;|E0~(oii?$z-PCg{cfb!iv&^bJz&FSXK+#^&tZh z#u1@QX&<`8#FL~%8oY40wl#<>(LC7q0k|U2Qja-Fx)#1XvXYQEL=3>8NX%9wX8chK zshGg$I`U{`UY;tSQk`p^U4E+d;046ur&Rw{0cZn`I=LprFEv5Kid8SVosOZmrf=~}PBqoJ zwt;JVFyXU(fiSofP5qhj-0H%ZDHKzVsvDXqOGt9AMMTy`T9%1#Rg(xF>515VQ3WVv zM=Ii5lBkgp#%YO0?0&R%Q3{7hfj#cIA_rY)7teEl zE&fQV|EdfcFOB||6`|&3Qj?c9qA%B67djl?Mt&|= zgFPPRhp-I7n8)TvGvunpPK87P#*LH6{wYWrv_|mzAZA&_S9thtJ zwK&qmH@2MOJJdo1;(5xQW#yF>Rq$-U3d_p#tL9YDH*8yYxPlB~3URz%SO&K(4GCB%?GPkwE;F^^0zdxMdxVY_MgFo}d$6=zPOS zCT#Y`VqBvhu*__3t-&PsM<5KwnQDNxooJPo8Rb)+3&N3@XeP8-Lrv#J{R&5eW8fU6 zP*{FV9#P>~ylPd5KYe9B>ZE>oG^OfS=Aq8&mq$~!@;=uxA`QYsk%-L2`#AGyhb*WnbP1|10Apk! zKeqhO2`9=qknFLBLMIWmnM8SYhX{?39TFb*h(JawC<7-yckXaRtG@%xb)Kvv(BoH=4 z5!*4LnHJj5|EK{64$VRvHh8OH1Bl1B20nAHhuxm~?7;W6YZ>dj88_eY-HeC67pvbC zCKx>wN8xEPj}`BYKgRj?dhtAh??0)}B7AFMdZ%~_-xBjI$2-&M^#*+6)K7fBPr`rr zB>oRS@E!C2>4*4=_91?+eWtSMOk(m%CNILzXqb)3$;qrfShDommTML>J$`KYrw<)wL2P5w%0;18U!Zo5zp!qu*Y2p`ODmJ6 z%G1YRP>i)E9vBD@vct5K0V{q}&d78+U7Q|&@X>5f`Tko%s&797DS#VIeg8=Y2~Ni7 zU*Gt_Lmu6MxUc*7s&U}IzUlvNjQ)Glcy9kUnsv+b}08N4=BG<9#np<>{K37x|ChYZslR+5#=|^Z-w9FUnt)=ams=TWlQ~s&Er~FHK zU->}!Q2DoVT=_`(SouWxRQXK#T=_ydp`27sDPJn5l`{(MQ)%a_=bR*-C4hq%v4c%! zLvRr{g{87Is7lh=P&SNN*l;$2WiTrn$wsl!ER&tb&Szu5_r|huY&`bB6WJto0n1{O z*%UUFO#@Gy!LpgmW-=SQkj-M>Vc%sJu^g7mX0z|Hi`gaYQg#{3gP>W>YM77t@ngMp zteyqfQnri*Sp#ciAqL;}teJ&b3u|S|*$TFjtzy@*CG1Le6}y_bndiUC|9$oY_Cxj~ zb{%VDtJxZMJ-dP3$Zldcv$bp;yM^7#ZezEzAG15yde+YFWF71-wt@YGZDgC+W_CB* z!tP-|Wj|y0vQD;@ZDZTn&)I$K7wng82fLp=z<$LZWWQ!R*+Z<0?P9yx!|W0E8}?iF zJGO^)v%PE|+s__lzh{rJ1MDFC1ACl3!JcGKv8UNH?2qhE?9c33_8j{Q`zw2%y}({% ze`7DPzq6OwE9_PF8hf3+!QNzVv460)*&)`$-eJA$FgwDIvUhR0^`GoL_AmB6`+$AO z{>_fFkJ!iT6ZR?ljD60&U?%)(@|O(yxKv$wPcoYfCl+6nsfSt)(IL`IiT3I9gS9V)o{` zR2kSw}w}-IYc`DO6Wm}NDxsVZqzj6ekJbNatt_OTNWXwh(nO% zyePGc={jXhP{rd_>BTBRDqPoCC9b>@WpD)(npNHrgF#Uh$mGqTCRidsnHvbzwBQ(# zdYD&=Rgz%HDI9GC?++B|=e2F}g07m0iJGf881&cSJTmO}F9Y$tzUiSxP@LoGUl(e2 znB_NzmiZx~1)6{recz0$13^h^mnPWyLJeN1Wupl|VlsD+m3yO|?L)!*XxFQE5IFQR2c zB=wRkK`~HinDFZ;tQe!JB~TlHl-msL$#T@uA+%%>y%}Z;a&a4URzhV+HeP)6gd3Rz z;6j*<2WhryK~M)WcnJtRC^{#U6QLU1#P&7gDsD4Ji<41r4J?|d){cte7~NcyKw34_ z(zL-0lX27?qe6?IDM5D{V&-O{ng;h~gF!08+lUJf19H^FMuvkSXxjNq$IWpuhy)YR z<{F>6R8_yXfsoRr;+PH zv&;*d20kcY;0`qxs8n9Plui$kh5E0>FNjUn`_+C7=P){qc!J%B@0I|LUj^H$Xl|e* zTs1`3p`v$XcnUf)fy&p%B7Gz>mSVIA>T!{sPOvcmf!j5wLV`I_4Te!o3|G|dWiQ~y zzmX}c&Ta60j6qH(x);UDaC*p_hI*jWsCcd6oNq;ixOWE4b~;z( z$(dbHg0Mi@Ky!|&NDbzUuuqWztOY8oCu=Db+XuW#Wv#(gkr4?_7-+-=C0s#6I~$1n z)vNG^_!ZzO)Z%8G2>P3mW6*^UC1^J!Fx1F267;FyLp99Vo!Vy+MuHQm<}j-OQ-aP3 zJ`>dSn0h4CI9)w$D~PdE(iD!76{u8P$&ap^kwGN1;`}BY@pu(k1kC4Agb((K4!1VZ z;U3jp)Qlsc3{gnm%|kRkf~XcYfmjCm=CZ5$(!qdqzpzQ=QkXE0B=c_MKWt&M64 zAp79yh?LPZ>d+>}A$e;t9AQ&40DHK;wS^NRGU9Ly3NF=%sX7}i;~SxH6BaPgHrgIi zJ@NzF*huvNl@*1+<|72god`@(es!WAfS66C)+}@#y0s2e4aY#~&?gpxqkn9f%D~_F z#sQ0q4_h_N9rd(`m!sK@C;?22E^ zSrk}cY!;QZ6=#>LGqfNOUM5}B8p7HlZbzY4fET#}a1~JthVCPMKlqRu#W^cu@gyK5 zLs}4f?Rb(K=rdb_zCTR=k|TTatVXPh*qmp>v@tte&+wm3ui?r0pCR~5=LF$n9n+pRbT)s+ z;~P)xCpJW5j$qoiNlmC@x*v=;r9zj%AbaAT{!QF>Hp@@VEHI@_xFc!1@%F^q5^jyZ zIqoLIjrto1r-UaD&&t~v^aR-HrJ9k}dPlx*ZxiXCa_Op#RX z$KikUr3Auf0lv&T61OMZ9>s`zU`VqE&l8(aPka}o8gJI$qyr}N9dX+Yyk4&&K5sM5 z2JoGqY62e19r4@aZZ_Pczfr6EX}}I4%}_+3?pn)$hqr;#g67btcf)r82I_#i7xk@s z3DQ1uh_T(g?pBm3-C^9GczeQa(b`KWvjypX@GgT6gO@viW|U?V(s+*HUfx%vAsXyQ znxcP#{&??C1A@N^_yNGtJ*aye$}!zx*si}B(M-Z~8ZRa9p)UB2X@9-eek8#`Rauqf zfV|rhm=QwA;g~ID*$axN+wdd7u9?$aj#-nXSu-x2@tv5Y*!Tr}|2g^B;`$c&pQ!yU zg}$Ybn0Mcfgl|W}w<96441GHtzMT%=PKR%&L+sY{Tb}SOPxyb7Cum|)BgsADLo%4q zZ^ZG4mu`e#I2A@;0{$l61YDE3wIl)_hBPVQnw;GiUTM_envC5S-jkxiHMzPk+%r^z zYw~no_z(tY78GBmg*NB4zaHBy65_$hQ?8W7*2{kfww_yNF2 z41f=Z=NeJJR{@s?z*~Vvz>Pn{o#g@W+VeH|BEY8%fM<=-;5Q5kpDJnaF2MgZApbSv zHTVzi9Sr{uCur~;fTJ@aAJP7ti5h%A;GPInqt7od(BPS!@Ig2Lz8Xyu?Y{@`aRcC= z!1zJH4**WOAMGQ`uglipFLg55!9+g-elF{{ntQ1=9BcPaaVJ>*4xSz)xUury3&J)%xFArNNC44o2StaN{NNX97NOeAZu~ z!GnO`6-BS&pLL}MhxrX`b)p|p|C_GX;F|y+*uFPC8vF^stE1Uf{B~%uMg6jN!guBX z_}&P-1#lD=`H1o_^lABD0=zi_)%y3r2)yVap##*Ci2Qf>wfsTA*Jwa|3wU>}20sq? zode*ydJTR<*I@kPo(TLNz>5at|5ZTCe;9CS0K9pr29Mh{7=J&3J7j`>4+1`re=TUx z;7hx;UW326U);CRP>A|1ZP(z30SB{>d;~m%DIwZ# zeiU~cB2caWW_M`t9KZ+ihgElJa3A0c2IRjOT_*7F2Ylf87_(7>zdtB^V_Fw-O4W9Qhd@k#w2n7B0 zXtl_H;?=>{pW~>tfCpcLjb=2vO8@gvs(`-<_`vZ!9ash2gw7i=ApbRp74QjoLuDf$ zQNJl~Y4A@0M`uPp0&Y8`!MolN=WSX70pI$L20sq?!1`w#(cqpp2iyNS-__tZ0A8jc z$G5=$L!2Oq`o9Et)&Te?|I*;60e23d|DJzq@RGOTUwc6QFOF;Q6M&ZtfRFiDgBKhc zjJ{t+;8y}ZZ$SQ6KGE{;0Q~#`@P|Lu;LiX~XLs61wBL48gKKAYec^My)Zp5AU0?X( zGa6hwtLqCtbykCGXLWtyT?{AgJW4yO)8M1=qK8#9V;jMBKs@Gl`vS{-wHNXfqd1tv zNBYH5jADTO*Z68}94a!C@OXP9GpwYv%mPfZ<8>%pWDd7hYhXbd5*>d9+_dPr-L-+0 zzS=N$OZX6(^^8QvgHd=ej*m+YcH>7_5N5E(rY4Yd_y@eT;&Hoi zuvr5fAy_ZbN3@azL<36L6iou_Bp**P3xD-&ssu+cV9X!zI&vgU!b!q+*?deG6|soo z`9$F)I+~CNE3B4=E~SgY0Rw819{1r*)DO0XjUhL`#tYMDj%g%MMnYr=C7lE|Sf=4; zV>l4h1rCxRUk7jz9vFFtWAc&k*o^4m1ZswjQ!NLIp+%BoiwdkA042Hc3#8tLCmaJ6 zbSJ5CGxAQtvpn1w1D8-mJtL_x10!!C;O=mXFA#E*6%K2oa7=`|0R~Ge*}c(Zu%2pQ zPEcD-MZaD|PApjUz&JN-&4^sfSj!+l+>sQ(n+5^Gj?B&7M6peSKq;$$J`jbHfgndn zMo;@Go>#Gv{Y86+^%XmW05!OgeJtK6G7h9bBzlh1e;oem8A;9;qv6!48ckM^Pj=9W zK4K1&{G1La`bTExr0dE)KnW5 z9YQI_@&qJE-vwYnB!O^{QYQwK#1oM;{T33eizI@z9jwJgnsGc0Nz`em&P8anC<$&> z!hW)q1)SkF4%LU`>KSNxH$ves%->>%CJEI$P=pQ7@&Qm1shpd z5x5tL7UF?=AZkdq|j^D%O1nSl9piyOC18ae0UA!HOym3V5B zmoG=kzaykFX5qO7Velk8dPXvH8Pfa%A@XHN5Or9Rxco9g#E@0rIRq4RCRuqZ@^L!* zxr3QdlbEc6LL@BzOU&?6=}HQl&13zI%LA|>WhDq{?^kn(I_+=` z!A%zf{)k9!L+fn-2VG9So3U2AVQt>r;^qk77(4}seZWytejZf%1l{~{1~GfLy9sw5 z$OjD@&x5!tgbfWR0lh~>CN@OKmxuf$$B|EkUYK8Ykm>lx{G0zgC~ z*WC&v_-UUOSiTD`Dwq=KcixQ0=ts5OwM~6eh((w*Jf9?hOC#0t+UQnfE-!=hI|ni8 zeoy)Np2~lcfcq2;DmH``MH?A3C z@HK?hE#Y{ckd#E_Xbllk5mh6_Q~z=!Ex(i_BHa^B2->cr zA4y8o#67nUB&Taee+R6#HrN`j?>n}|B1GCL;;ppkVIXLOcPvLwswvt9Y(+>Nb=V&H zm#GvK1Sb7aR7Zjhm8K&R(}UDU7E}S94IH>*r|Mq>l$1wNC@v3PGb$Qs3l=s0S$e`(d@y@PB7J|&IMd{%g-f+WzSAx5`6*t6rIfQaLZN?f~SE_|_Yjt~t zWScSbBBpEWh^Mw$c-uf|rkjU9)Ht%Fcnx;oHWGQjLZ}>ieWxxU4kHxeBkz znZuB<0yi7Nq08{aps?`A1Ifb?%x`|nMO|`pgm~IlK z#~zNQ+1+6^sK3qwpkEF30%#^ply1@;NLz+CGvmh`MgLlpMuSi;4%t66hXWW!IWot@N)c3Ddq|JYeqEo>BuV^dJ{^#6VC*c8bgJ9 zfQSv<1i(0usRO{2C?!&&REVL#QL0Lm0^dd7$55b{f>8=IBN#)0PY`57si>uRl4u-6 zDUhCyV3Yz*3Pvfgih@xJ+=k#cqrfc~13$(y4yC3?#{nBg?Eia+j3LXPft^{7<4;Uv zGW9bXdJAg)6FiNPEYoQe7ZY^&hbZ6_9+8a$>UcJNT>K(*5;!VutU>=r?_7e5({Z-E z4iUtXQ*Vd-Pr!3#%dxyzpGPx2!i)8DcOl4mvA#bq*7xVd`u@CFKadye3uz7KyjVZS zg;&mt^%Xw6f)}qw#lee-t!iyqkJghx2Is|;V;>?oFQ&lX5E#gdDLptZu{?SOOD1+l zub&{j%7kA-Fdb}5Wx^E9Mo?wK9ED)O9ED)M^jeBU>4N!E9^K*;!Fnl>M!b@0zYK|n z8WFP}kKmP)iIjIC9$YUHIfWwcp-A*>pAKG!A))6-focaEi5sGGKWvBh8oZx-2mkL} zcS&ec*IlhykAM)%(C)~(`!*sX>+Tl_4D4%4KNs5*b={?){<n?>h0;qO*GlB;w zNE1^xiGmHoBVA63w~8Q*913QP;7}Sp6bvG$uDg`?9SVxhr{E3Xoa(wuiC+^z4b==Q zhia&*5meV*%KIS&#kxzuE3mPSuDebQm+_IckgvH3wDlcY4*(rr5L3jOOQl{)fMIuI zob17KMI@J4b9t_{$VKN-BG**P^*jgc0AMsiDc1n1o3;wC=3|J{O`|$Z9F3r!LwFS_ z_+bQkI|Y9bfgVI~=re%MqP0=5Xv*~&B@--~f<`O@DvPGzTnY*nO~J(oelr$LmOsDf zTjGxiXSBqveM@|#Z;4NT;}Rt_*&1DlsoJmiEpg;|ecCvUg3&f!hTu1ABUuN~uYbo- z)kQd?ZS?mo@#lR@{M|P$k!I=xC^6k#GgBQ5c(tjoZ0LHx|Mb;x%K^YsNM)^?M!eDT zD#Gb*i2Ax|H26|Za}a-}y`YFqcL&tBRAS_O2>uCGr{R6#4oC&-VQ7Th>Ox6`KTF`D z$AN-x5XT~<<2%Pp(n1Zd1>ir+?HX=2r-;2#lGSuf=~H4Z_+dMVg2 zfiqWsuM0NfmCTiO(;m4Cub=TOKe`jIGz@jqB#K?bUtgwI15f)h5)3or zH3*0*N$vW-*!vDJsfw)aTQ~P~Pj^p;nSq&sVTKG61OXKg1QZYf!2lSDA}9h1h?#*k zpyG--EGp)Nu2~Ey=DcRbu;#p|EGoh-3;+9`y0?285M4j~_Fq5ydG76c>zqobPQ_aR zL3V0`SGpSrC+7%lNZ3ON(?PfpPm*&{x-5+cArpfVHpg=x93^zel&R_17A`Yu5k((F zet@b+>?=g~e0({?^IakFXdx~~EE!XN3#sRFi4boD;Q>7D3W?8{VGlL<85qLf*45O?)9Au7%6c*swP)OWYh|eL%sQ?x5wO%A93vmJR^-4V53W?_k zvDXDy&V^^6LgEu7W=}zyE-Fmd$0Tf8BN^8zRzHuykD&VLg;=uc;ck))ti$SON7$Qp zb%GD}mZoDYs+PHQxP(xDW+teVtUjPvy=IV}pN`=uFqn>^OS`(>bc|TkpNgk}AG$B(filC??Ug@4311=1zL_EtL_6YvxysfUifWg)fGCcm?L2dYapcCA%Ykh?^@>J zp0L^h?nTy~cp$jAP@-Nl$Q^rt=m&4L&hB(gQl1)rTWB^Z8Uw)3!^6$BN6Jd}%V1*2h53 zQM9_1F5GWn^v!G4y8s@RpcpXEqWfCIkB}{dwh{5oThzZmE1F@Le^$5CgzvNFt*Q=2 zBg)BL^EUA*rZ%$ho@1-)KnYV{+65CF5K%Fjv$O3wP?}i_Ym+TL z4#xAuXe1b}d{i~%qe#$Dh4Q6rxea&SuOZ(ItJMV~5q^D9OTY4*-mu-8s9m)lQc=&C ziqa0Fc@+}Mh36hVtUPUE>f3k(Ha>2?Gt{$Y9dP7DI4g1xvU*+^{L!N!HEo8hnMDoY zLu_9dHX6l6;IwvX4jZN7^crWSBWA|)MY)zDlojQ~=W?j&HrGYUN{OttDiub52_8>J z-)HpAd(DSnr5tMs=5->dRrR(b)94z_C1QUt*5F|R=HY3C^abAsHZ4iv)Utey{kIB~ z`U6vuP#oBW0lkk5awkrJHEp9^5%&{>i`^jqAVlS8JdsMVYX-YUV8L%A9@DrhpMr(p zU2%2gmj-{pA_<_tOVm zJ6QSyv}>EU!Ez_i>%UvNeo`mCn0Z!DLI9;$tcfE(YBy&NAi;psNd z#MTJJyqLM;^rP`lG`e+G)s^`7)>0;oXhcP4_)HM%vk3LEvEfXC3#;)N0M1kx?dDS1 zu_^YQWB(3oZ+}=j#|1T|w+a;Jc!t1l@I^g9^xc6Cky*m%?h!H$2gMy!7ce@V=y_Ki zGrMnh^8b-m{b`h#(T_oR!kAr7^5AB$ac0Blb?FViqUwD_KxIT@)$<_6rUFt^i(eE9 z?TVkw8^^(|%82a>v3-RM7m6+Wm~qM33}cpvOOBROM(DcOj7`$!r=JoE-!u6n4Z9u345h|y=8tu#2RPBdAo&e2gOc9Vc z9gk{X-5xyE+^|wz#TVD@R7d&ZmxU&4ogk%6l8~mP@=f}JU(%+kC2dB*@ZqUxd|8a_ z*Iz&HK&UK5JRag&JW&*|U$G+Dyc(%PtXy?16Q58lD`8AlBK}+z0tfh>3w#(jAHLRsjV zG;9_&={glG*(vON>54OK8g*rhKA5B4VNzqS@qG?r5C(P(;^x{^Id5e(!cBe!4nn28 zH)v5(>xUM`VaRjS*pQF<{-7}%A3(G#7ej}U!<$4sjNUJA(FPz8->iVr8g2)e%}UA> z6^z@Qy?`plmNl2xjj;9xK;Ql|-jPedt%}OcJ(+LrTDl#qxea$FnTG^!-3-xC24U9v z?hEAHOVeWRjzq(BC73k4(+P*)1y=857_D}!<(w5T_OjZ&%z*BN+5VD!CPuOmytY^W z6$G=^bRQ?}yD->;NL%xj(0q3vq8~Jhxwn#Ytwu@rIHGkLW!z~*>oqEOR}yX1s4_a4 zzBuYz@w7VX5N4&eF>9MfI}(;E3dF>Ok8iJlDb^oxEgp#%J&Cg&Q6SO6x0$?z8Vq+T zy*uAwW?zJC*aI4oL`{=o!XJf2$&7>Xov57f1HjaW(2UGtR;_G{YsqiU>4nf3wCFuVeV^9mKt z*9vzN_#!+9!zdDki$dXC#NR7WIIlqAJgsmH0t)99D4eGiZnn^phOZTl)rPMXt`eTR zfx^AYfC?1O(+bD$%uqP5K;b;CaNMuKV70<&6!WygX_WM|!fBN8w8Cjr?rDY7s4^BP z9M_|owbijgg^L9WM}bh`BKBJ_N$$I6B0H1LN!;$>t%TV*xr6v&c#jdCqKlmE-9vP$ zE;GLO4AJ~9!WqNH7`jQ26@JsJh|Sf|Nh&X6SfaH#BHA3WDZ7;V41TD%6pB!nHbPsU z0Dl_VTuiC9-Wi&EA{i63?+=(o^PFTn_9yKn(n<(V0xWH}7@x=Rl$}ibG$Ucona=o> zz*v5D6#6}%K4BF<7bcrV`;weym!Ts~&0Yi#9>g;Zb?omIX@Oq1-U(~qe(6(3c^h*4$algf;d+QpvyJ%dmP~$>ncoph( zI5ke{zc`KG!m6GEy4|;;fI<8HtwEjZoX+VSFJ!0AQQyAClSI@0Gio{89!#GKra>@s zu(f$b+nx(2F5QU$%r9ZH(tkWptvlrv6*QnfQFUHxZ zk?uA-4(`-tfV$i4WR(t4cblD3MS-vv zK@z&QH(A@elUZXY)wM9IhL`irU_$Mf4CN{j)hizk>+=9p9U6kEycytigrbQJD744P zEQ;8m0-mk_OrxJ&QO(fj^h#4PE9pB|4W%)yZ5nT9a^>-3^hsDAsgyj3@Tw9p6plQ9 z!^5{I3v4ikYYcgXV>o_h+u|6m6cYZiF&w8zICRuqYK_7%oJQdoPNQ%Pr%^bD(&f!N%{w~?S0 zGvH+5xQ`+!QRU!KH!H=NuoU(+ETJKdY3@cK`!?f{QGcNhuUAx~KjK*nEvy4uwjUjD zpqOiW;8nUkEEj^|T0C7~!xK!(df~MX$r)8g{(IH+AX6PD!Pdj1Rrz#mPF45QcrL6O z(3_S}TlL60Fg0X-YgEwkF*tk+k9wR7yELJagkI!+TU#L385Ja(CnQuc*&CJ7=vJm; zQZcL?i&q9E$i_)C5sYaxdWZ~%wHF57Pt@3Fd@o_VF!A4kHmxY+ODPrDbf(Szw7ER6 z8AO{lbhVfxT=1;NqG2hm6Ko6w-S{oq+!)wQpsRQ2>f|7-mbAH&HuD3UwzPSd zHg$nbC2iOfRC5EHYT9s|t>y(bO<`kngMduqkkVYWumDkJwZJ@>iRW1K8vnias<5T{ zsagJ@rMdy>560U;OBIZ_gK9r)sqO@yZ?nD1w^Wp7Fy7YOMljwE+y>)q29Y0cYg#NA zZ`TPe*HSGf)GZY!to3-?ZpV2X8E@xWDj9D(;RKJ2w{tC(jJKU|f=9;NPB_6M<83FL z;F0mR6Hf5Rc-sjlcx1fo6io1-rK&%{vw2HJfv}~DO+Y%n0>F1mWIO~%3*Tm%;_5~! zXG*bQ2{Zdzl&~G35eez~mC*PStddufHBHWM0O14Yg$$M!Y-=gY>CSzD?oe;O#xoe* zpl#ly{60m4y!}m2(fGROG#=WQl1{s?drmwh1xp>@hn58^9`*D}TD?L2yvBQxe{G?e zp#m18L#d~6uJpLDw;Qo^psw;b&9g6XR(eoZdy_$*30x}E``3E(=Nw|0>bXwvt-xh< zSK`!DJmoUibA$IDJd(*C<1%zcO=C=Xu0Y&`IZ9ThtH3_$IxJyE_v_#L((y|=|Mfqd z`cl8z6%Qaa5sn1x%AkIYa3o+?1$CsZU+vl_!ROe|;~mat+I!X@ff0@b?7^Dbh;Sre z4+-2xI1;djG6>YK5sn1xy)-Qr;Yh$9cCOHZ`qdu(3L!t~I#cJ<$Pa>Umq9cxgvi`F zam@+wU8I(m{Q94at*GE|7P=>uv~6yC8Z0LR`3HYGA{h)iZnotn!@@7-j`;C}^k zrl{+3*hf}E^NYG^nH!N*Q=lC+vLowA>!Fb!8B_)|p_@c7mY$Ad`-<0MK)v$E&%h>84T;QHP3q&J(Dc&l3JKkn?KfJB%1$f)p zoA7qBQ}A}P+$`&5kHy>1z5$OT*%>ewWe4CL&CbO;mVFoY#o2>kj%RnqJCWTL?__o; z-X+#%_WW6nEN{Vd>3@imFsLYl@-fs1Di)^ISED zW-Ns`NxPZ?Vp<+I%=LF-%@>q)SyZ~0l8j|^Zi5fL$6yXKpExygfUc|hBx=_D5d9clj6KfqccZT>>%8k#>Lb)iGWsF<$JZ2c?aO<;eHLvs~%N1gA`tr6!qqR0s% zfG^AI=;$e1yl3qt+FV5br?gqJ23#68?7Fs1r~0t zcPUJx6^|F#L`tpOP(p1e9WWU1aBB>$w?;JD&Sq+GRVM0T$9fTC$hKG0<{D>_*gVEj zrDIcV<3k`(rcU%ZP%kD=@EmYa!M9Vp)BT>FYQ<(N@M?Y$tXpy|9oAyB@c~+Jso8^Y)uI}Pf6>quhK{?!&<%zm zH1vhxk2DO0;UgLjfME>`EhoWX%~^Y5`_ExG04Z&8E)2c;;1D>f{5#iTu{<7?_U=c^ zwMmvV?*J)^+7E|=yxMpC^cr}N=ViEQaV0!F0(7I}-tg%pJYUe7E%r6EmVhpS^?i6$ z%xj8RY#LDiFrcLc0qJ6ieCmQn_3}1#HYRlTdVw>e`OzdCgBVozg@Fs*&VYeGseGta zq8+YL%a#S7>V8RR*5*?W}*?^ zR>H#DPJ9a)If+g%yNT|2dx^n#`-#87J`(oGlWdFs49`k*Tl{DESR!pPQ(dCl;%3?? zZSho^r7ad$x-DjGN~A58kGerOzbI&nM}eARTRhxECm?8x=fNKcAsw{E_Y1VsL0hbo zTAmKtVhtz8phmJxCduiCW@{mI>|2D>0P?FbFN1YESQ{0mL#>zMX)y6{RQBD(`5;oDi;S1C z5HAx0gIuAQgh;Vaut4w*7#BM9A1f3;Q5?9sY#SAaU~CzuCQpF339ZRDKtxz$fL>*9 zF-fnInw-E5=V{c6s3g$jmO>qBq^Zed&1g+dQ?*DG>>KIB5Ni%Y z0vu}cY*=U2NNVx{rV5qjP^j3MU@jFc-ruD8eAtyqB=#2teGs@DJ(dGSi{Al)PBH}J zO}tEF$Euu8o)hRK^>NMh=t%zG&`DO&ds3CQRTa%OszDV^#r~O9w7AlW&Di{S6}>m8 zQbq5H4E&KQI#BFiR7KO<7xSOtbXPB=8bt8gW&l0uX7YJ%i|2>-_8BveQ zJ*!bpxhG-p#|oDhYPn0W(F;>Z+pNNMe139n+X(>&8*f}&mS9^!hlGpp9OT9vkHx|v*YT{PO)@$ysonlVw{~FFYN5Z+1c^J z&Q6@29WU(c#M#;LCd`9pW^F9N&W@Ms>=fDF^81(oDM?Z3>_nxr6P3Fh+M zvlErhPEnL3He)JasPPNFh(5|ycws7#$iW$Gjp213={HF2fu0?Jd@1$7{Y zv$C{~z*Rg0hm}=4G!Xv<$Y`WS(B&T5uduF|iRz^>>W;?J z&JMI_z8rSd(%lPYPZT9JRPbBG&yjyG z!4?KD)u`Tv32F<}WG_;O3%-z8`YihhUQWD>^!)_CLf4q!86oIXpc)b4NUIrQZqAum zBYl`r0i0C35CunlWHmjTetc@JM8-B9O}p2v^I&ea60*A910HYR?m&V?6eEv@Xtoru z7fI=6@vuUXX7g3B2;|#>3`=f8_ZSbDgrQ|<(TbU{+W=;SQB%bL_qVuF8DD!FE2HLN zM&|%)l-QKh=49F&XiXEF7;Wxm?jB^FBsS|Yzfm)f{*1Ox6PuN^nN6E9)@5R|f^#6A zP5qN`#160(#Wam9BqbZA1$%~1npiRlVwo}gfuSX15va63nwE#aIU^D}p9!?%5dD z@0y>(6N?$5JUfDapDl`9_Fx*vRipaUOTCvuBy0|Oe`F<|0T{3Us?Fgkh=oV_N(*SU zxd2AJUQAj*Yw{VSv8l49sR~945p^3g?=Ls<%_<;_@Iq(}7ycIEgk9`?tOM!Ku+po@ z1U>>7tRj115y-NN>_z&4Rb&Yf*Ca}d^`la*-I9879mvMjsEACXPm`Rqo(rT!N%6+a zjoVyWRzc@s^Dp*0AzG-@H(4R?=(S}(@x`7=rdz$XOe1@XU+gt)(=YapUR$;t-Z)$R zVlVw41k@-3&efkop7>xCe6bIMJ&3e5YlWs)$U8r1q*us0Yc4*^(hU==2xT1XMwtg8#&T>JzWGk*Bf7n|5!C%##4Bi#x6BEJ>3}SDRq=r7br|PY_n1wZYlqbtPbc% z;r+-4j^08GH*jbaZs5=;TpgfMxPe2Xa07=%xz%R7i>E)f+AQ3_5$@V(0PbMdMl*3} z{ES^2ZG^_aH|U;k_9a!}E7Q2XDz_w8j0_DA-n1e{*G+1a+xw<#_Mh7OCd+r}vY2ySg&W@Dssh=oG8w+9Fkvnmdl<6mEdhm-$+0%D zNQ%Ox_kfBF04&)RcL}K7Qb$26PREm;1?HaYCLIDQyA`bKg)G)cfMit+RD1S!dAR1?<$xHdBa)kNb4NAgYWJy^~ z9p{d-@vth9y#;Y{&L!kxUwuf%jfA3c3A%d)FjO)&+&IgoIhE`i=u=DR)sc93?N@sY zcyOnUzWoAM=iug?cEf+c=}-C+vQ2Kc&;hrTfcL|IawYF>~B2_Fc=_$I;s&F z)yT-Si5ML;{wu*=MW~;uo55&AZSn@I!lU*IfEaCJtn!TJP({-)TjZ*&E@|DhV)DMm z^J?{$k{FyQ6Q(OTW=0<@6P`Vz_l*720(7;3X>I%i-;8et0v@pwx(YtbyA@B9Us+P4B<92Urli7fKSf$QB63<% zO=v6`3`reI#wO%!4;T@_)sng=V9_{I1wvUwicPzNrbb0Xip`kj!@w97DGH2=6tz*L zD8^V%q}y-6!LFEKb$Ej%ow@L0=m16RTEvB9~F`Qt&}Mj&RJ zPKb_^!~$ijH7ia|rW;}|=G;VB_%c%iiqc|uE z9=b3DBeMUYIBeAmo~q=Id|!(IL%$ay>cl!*6O8%&uySSXUCAA!SoV&HE2e7!f*q=y z0hD-082OI)+~XPZBv-d@olC~iK{A+xC3r4oGVVmW3TpANZrkK=EII!rJUB~daCp3y zKL5qBts!S4aCgUIzGW4!t5@;5dKIsy4w2N3;hVK^7?Hmqft?UrUsU-TlGee>7gfH7 zlAUM_mm^4OtrDTKBk)U}fo+Mu#jS|}vEAop~v5^`Mvsli6A&pZ<=wo>ufKqbx zf}G!n4aseCxlonW%ETOa1kW@K#zJKZ3r=u)nZ7M6xF4%vEAmerai|c8*?_}8=YB-V zY}lK|RWw%6=*_OL%^6XbPMc_Cds(6yjeKt%IcqhFd2!O3&JuS? z?@`j4(L=Mg#QTh>d7aQYd+!pp(5Rc?(@8BDgEP8{)C-{Fc68MK&r8=m0wQT@9e+}o)z%3* z19etgCu*d#+M1)0&T6YpBc0XO-1=E<&7+6NYMq_uh1r=hiqs(pQMDMuH#08G3uiAh z-r$ogZB9xD*u;8}uQ>^Q0E;^jwxoKPa}J10QEo-vu^?jFnOQH#$C}2?ZFAW^5004a z8D#lPJR?v`goUc$Age7lSawko?43u!=kVlZy>fC2Z3^zEbJVqrUsr|tNkVJM5D~Sf zfn6L=$yUiY7ZzS6C^dL+5+!y-ccbsu!agFW?+ZkcROivV?bTRN=~Z7m_kxQb#_3&0 z5>~*Xh`VUCSDhHGzrijlUI}Ce&QXi$*>(~)dNcyh1`rMoJZsCiRSiSj27xjRkM^(~ zTc-$6|;yUr2Yrszl;9 zU%dv_mxv{j^VK3?uG&w%55qk8u^NwBpwjDs(|^Y+6WV4yguf$rvnd$%qoE3hSum9H z(hXd&l;uv}%V1H)V|=qcfF1ziFY*{;+Fc@`CLn@ZVmm(rnwHqk9{A;$#boDp+PUao(ZbRBng?^L9Rp968^nL-aE9ieFC3Lp^+k!$s&{F-l0q; zE0Wp~i%cdf#$!+51`?Oa>LK7Mz$wbLA^hxcCjvNJrFR5Qx8ti8ud<_&=F+|}nRBLO zIem5?9A!trumT4B9J>-hH8ggow2af+I5 zdRt9r(Kr}JyQ&k6?kE_O);UbB*O46OhRsGRqVq_=47*;!^#Xvj=EdlGUH}kPJA+HL zl8NjvA$|5i1&7qe1_-S!_@=@tc2*f#>Bn5c@j@lz<$%R<(4jN|@xhSBp?DH<&|xd; z#WJu!XY4xuvB2O$wDvhsUIeeCqJg8uct&Cv``;wW*N~_vbK(LRVrl^;)8k~mDLg6% zQ}rUnbfVB`{ZGQP1yZK`kXtM=?NJBV7Eqs7+Jnt%;#hca0iLADl#{r|K(OHVG9J^Y z?vRt_L-3Q*WSD=!^V+W=O?4|mQ5WC9H&YV^b|50DN& zS9XEqM9_Xh`T2>h>2w;6^Xg}$d6|qTKgGZkl z+D}nNXM+ifX19U|#WLPDjlmsr3eXPTQ&bdFTRfc2*yhDaH9{!rFjdAs3MCBfYDCWM z%oH6a_Ae0k13kbW5;vnOO*ck_I&qk!*mn`-8a!Gl4wDo&0uz2wo4Wo&KB-T_A10N_ zd<4(yn~w8pGfBRn42+WtTogRW+H zZt9kXd0RVfD$=_g`EtfwdfJS}b1AFHO2pef|5zA{?8tBcYmfHI!xcWhhgsjl*A|Ij3YWgqojd; zv@9Z;9Hhla&UAKO0H#EO*4@Q8k;XpNh+yJ;8uy^sN^svidR7!p;%J6*AQPRaAj5bj zCb6EjhcY6DOYga|MKq|=NKFA-ozwXPM(02}*+EAD89`TFg6KGRlGaTl-*JczV;Zn3 z*@$dMIECIOZMRVrU5~`O%@J7jYX~hd6I8dR1#F=tP4Fj5QYx>ABcUK6zy^{%y@fry^lo)NNYPg2flByN8cTv@gA6{fkPHoeHG!@!5# z>x@ZQ-a3vz?F3?W#$+5g*o1x@0ISju5NFkdoC^WV#*Rntx^_EyIp@0*%fBQwfS;ex z;36L#tTps}J9=;nTvU82kX|!6lkl!Qk5&~l;w+q3cR_ai8INgfj}jYv(OgxotAoc- z6?DHFo#R$uDCm>fbt+#SsGqD3lvD@*!#bcyJ&Jg#SyCM`YG2}c4yjzn#7RnL(fBu5 zMg0b3r5qw7k;@N=OIB8~FLFlA{BML!oEcc8UZVX`;`vH=oI<)Q;dB&)qdh;0#+_lM zJwJ+`kIZ>~6g^Lf=VF`!3Id?tN%dFyJzM&CJ3H^M z7+;{j#w*l7BicEaW$6Yw%jk9Ud%(af;~=x(2)u3gMaK@0zq<*s+2ZkcJwaeS861Cy zcwr6F19*prUYL89AmPFBcbYpq{w{DE9Dm0k^2gt4T6p~3JfYP%SE{HKr^*P{i`cT+pjMG_P?acO{qq6|{NCkb4*-BO3 z!yv|jR~zYa56rHp$_FI~zj*XS+{;l(eybKM6oPXP1M59$&g@H$!DOb0E8%ZeO{3kz;$x^1ACAPF z47@3ovE6d=7o*iK6JH;x18f6WK5ZHTc{d3iYQQKCLdL}aaJtu*fEDlIh2d@`&-SSL z9-xxvhBQ*}cyBmw6ocUe82D@4i?OKW+`MD;?WBzAqhMi|F=(ZlEF`sx@kLG45@h2! zI5v&zcF3vqWnf{)q$Of7X({e4X$=OdwO#*Y$8E0GRz*&&t?(=tIn~jsDo|^yc5}71 z@@j1juCLbCkoszE4Xv-%)?W41+8Q%>uPH z3)DJ9IkkQp5;xCR)-}kEV(OlG9*uD*vUwg0M4)1^rOdsCN;N{B#YKl2)PX8)R0Fz6 zh@w?6x07(LD(So=@hly7#gN2E9y}HE-Q8$RJWku5VtgrQEJr*0#;deH`YQc)jv~@(*07rN~=+b%c#-G{b6_$hITNN4yEk z=9{9@+tK(ojRk6ok3t}*az%9v^Z65K5SMLdq&6?3r^y2VrG%7`(he}oQqq9os8OZu z=}SX;KL{jUOIOg(GXTq};(vq!EyaU7d0zrdJ;~Ptcr^$q4c`GOr{-P&zB}=l9~5eD zL=Jh8J7Z0wakreJUWCx8s8rI$_u?!K^h$nL)L&Ckcc405tE~HxTUz(7qEU43D$zZ5 zL(Hqi$o`3W4UJ)Sd_0}st1Q-F+WFl%=lA5DFBLb5L&*I!_TZyqG6LGCT|6N!Secqn zP}8)wKS3QVmcXABk0kJ?Xk@i+K0{MUild0s)qK^fv(svSgrrI(q)?Y`pyo?K$TGlJ zsrgcaXBp^fK;1>jGGH~VjHRNCfiy>Nx_mf26u1bmfixlIbf|_mEP|#Ujb{`FJmoB( zsx|%iGZ-r#h6i=5zdI{XQy(#=Yz0zm6O793;cO)mY&&Z=0p zZY6opmIYumVumnI7vNEQr`kf=sV01t@)hL^ZG=%7@-*%WB>q0d{C?p_{N<1ZWaG9S zb7l4(#GGZ8<@KcdFfPJ3s9@MuIP?m?3vOu^=BGZk+s8p#ZhyQyPPmwRoB^X_pN+S# zF2y^t6JChibChG1%teI}S_6Sb*U-Ll7I>N*gs$aBgpKG1y~^V0lhGj%v>%BZNNiju z#OblO>Y6X!0#!HVyyO?Nq6bds1~}BcNU#B2Q0?tqN50QB&{M2 z+UyI#ItUPxKFqE}Foj1LP^;}T{@EQNwB;f&w3DALNM{Ew7qve ze08irToaQ}SJA3esXM_(!BmVf3=VvfOGrp7Zrj=ocF9K>T3TW;fmpIAqqu`?9`SAD z&!{Tk#l*Yh@k7KH6K93~9&tJS%gQ>qqOquA-$#A$Is(?Gl^?43<&C1ybGxm4Ll8)?Bnn>G%9W;aV&4lP^#h&bUQ8pD@Yk1 z0E1vc0PZ8(!2#$`Fj0f@=Lx0+5gfz_PN2iX1Dm0=siDpE`aDn3=7{<{?8d7Tm}Vra z7n9Y4KL4E&hfQDFTu7Vm0-OG@F^&U2Hr94$Iobuo7i!4Ic=Sr`V`fY^c>0X?QzlQH zb+lfvebmHhM;^BARxhI@Blxo<_- zs}Nu^%{M2l!XSH$#j0XpuZhrUoCGUR%0qG;;Bka;p%PvU=*ySSBhv?g0y9`5oTT!D8Ga)&l)Kf$t_Jq{8)OG`oMLqx9cE|pP1j*m)8n9mT+t?X zP4)yzNDvu%uoqxb->gt7;iM30Rfc75MrsURy_TUHheuVVS&O7u&eBKVl}Umz%l<~D zB}}E4!ZZz@$?qW%-*u2hpb2jyQWPIWcORaYD89`W--OF;!lj|+dmW4?AvJ9XTJ5Lcgi?b7j;=e9zU1{7Cy(`s;#t3C7CjSnh zp9xEyFP#`tkT0E~1tdyTde(vW9>By!Fw9?u&M+R;H~Ai5@-@Dm;p-v3?&RwRyh?Ze~SjkPe)}O@K0t~if zt}EBoIs=)P`d(Y<@nfpn8xE(=pbJ3YY`R<87`-(2#z&yt-W7ryhgpecZgops4u>Av!aW93d^uE zG{W~4 zun2YIIOtG9!pYM5TEL`)m1S7>5=wY-w#gfW5@wcReh*mk6xdcTgZ+c>xh%z*&J+i! zDb9k*kT}h2r!$=SOwWfY%MZ2H2O}{4x`7K{3w!63_gut~Rcs~vzksg-T+W;JiUwFL%|i zV-2P4ceIVZhBp-)Nu{m(I&EY1Y@EN+rufS|AN_RyM%#G6M;qe?6FF|2o=ks5K8*eoU;c+2ec>RIwgZI{0lzVXBtM`LO`nV8ptw#E|5O1AE`nV8py+-=D z5O1SK`j7=&C>;?`^&tyh?)n3{VAw0gmp29(+&@E?#bc46{N{J2DXunF!>(4w|E!v+ z0-aEi{|Ws1{+T8;9t5kTY#ge&0`Pdi#Fa6)tZ4>6uK_HHHvw!)_!q#`kyzy4tQms% zfW%@F1r|+2n{g0AS%4>lO-lnAH8qlX+X3vpeI0NX%@8U>m`r0)pIq_m32#_D8Oyz) z59@aT1C_O44Z}9;tB2PRvq$>-wMf*a@Q@{5XJpofhb(E7J7h_hgWMrY>>uNRKv7Fv z;Fl1mKXolqd*n1`wx~{FW_N<-8~}|-T!tAem7?(=SS5y&ReDCJ63TY@%psuO3Ycs` zYAOAB6OhLwmeD2jY#jbl)U)6srB=YEadO|BwoQXmY8y4}Wjr5u0Ykwer^4RL7JJ!0 zHAnFK@iMjlq2pynQZw{fMqv&Yqld$L__PvL(%21F$;o6LI7PQWRAA#@cuZqNznrox z36$kkFtuBbQ)i&|+gw?$L?Gr_QxUdnpMtmNtCJbEVl@jW40>NgIdU=WrHe2NQ12&+ z)q(3yQqRp%Uj~eR$doNNjL-2G!*-_X-Z1y)B)MBWX9?)JzM~%fv;nlN2 zJ4h07uwo{jx?3(2%^IBs#((dJF-6<$XJz6qnHtsUn2ES}*eQHH{(adg?8{DJU+)z5 z^-f{;2PD+mn>ij)Rfr?j4)g~IqxlDW@xQ_4B9=LqG_lQPPo^JGA| z>ZI&?z|nxwHuSRrsb>)0k_2qn8}KGToP(z-3HbSKP+)$Qd=UqHLi!A_c*->F%o6wy z!1$5a$R!9{e86ZLyX~G6bpJrm6!PFFF)G{<4F6WI^G9~PZS7N%neTh*wTX7ceMpw9 zP0aN@Wf9kAeb2|i=g0{f`Mzhhf?F;k%Jn_vYTjJmQ`RQhLm5Q4HZj-tl&g8|VVt9^ z*Y|vhQ1?BV*Yz*tdJO_|j~GPT&F2TZZ5gT*I!KnI;V1tZ|-g` z|DXui*R&RzzQ))8K_h*QufJ9!eT}cbP9uGdufJX+eT}cbQ6t?8z};LO#8cf1$luK+ zy#UjPN5y^M1m4Irt4=_TZ!8@5iK`Jq1)bCHND<^?;>vh_FCw&WaPWj}gPJ*?)V~pKB=btb zZ$<-}b0(F^P+-+GK|@QIkoNaEf{rdvP(G{Cp*J!mG=58C)l{s+=taI(YS1GvPont` zYTlzT&!_n`^O7epw|NPO!(e%+jqj-VG}%SwSFJf8pIC8d9({gdWyn}{HC-PfY;eC2 zZW}&^N-%JLa^QaDiH+c1qsG%vmI=arBZPm4xIcn~ z>ZP!MH?aS^*k42YhTRcyM!qE^&w3nVlpqx=?Lm!26ebefnC49-CK5T-J&k%R4cVy#*&2dc~8i;!*}0En@VLnIX0bjhP*SGa8>2Vn^f4 zL!36spXJZ1*7qei^LiK>YuCIkFC{> z=uo7i+q3u{wKEvDRkvBDsR~cR-O@tyoe(juwbu8nw-sa?!CAO>18!xZx#kWRng?#T zxX@hFHeF~QoQ3-cLJ7{ol2QQTg8pm?ee8^!IlI>e@Oc_M~sdI@|>2eqi;mW=o=9-`bLCI{TmVd`sep%ZS|&_XCb7s z;)q#B?hMGtodFrSGaw^(24v*UfQ;N3kdZqBGID1?M(zyA$ejThxicUmcLrqS&VY>E z8IX}X12S@FKt}Ei$ov(BDU~@GA*M6DIUtjH1UA`BO;gm#nSn5u8Kqz2PmPvpq^u*% zO;N{mKs{AH9yR(@x&8u$A$AtorUlS0XInL0_@G*`&hStj5fEc?nUy*+fXUb^bb7Re zfJuPZB*NoNDur2_jXglP(CmUBF)0u$r&nhOZYyK=ka~VVtwxqsB1-#A0q&qy*v12vy0Dyqd9WWUbrjTAI&OY=Be zSolDnb$zX>&I6?5ero4I!ctQyI6dFR-y zHO>OAlF#nv*fXK=Hv>18WS?i#=?BE)AZnY%sP_?Quo!_WBxD@*(_{bxy%NA%8U7?9w*n6A!Z_Rn&_}WqQZ&#=3TK;!;7CZ$#?LqVV?yJwhTubwt?qf7Bq4`Dk zMwpu&iDsk&nvo`QMDR0GS>TM|=0#6qtd8egM6fYVx|-xrp8NBYMvEAdxC)LlaHl?T zTQ+1CFcUZeC}ts+>V|2PT-;UT*F(I~XvL2hN)CVj47N%|?62sSRgJL>9+-x=N3O{` z6=~<#m(5-3Ieb^>4u)T`$@@(l{$6;%r*196V`KG>C)%w+h}2Z z8!fDFqd|Rphj>*UEv#>&L4B*K)xqqhZ*xh3Xnl#A$fEkVsi>|q@tlQ1^8?5!))$YO zG~NO$8O=OqGRDubSot>BBA2LR=)B5Obb2G6FG1v1S#e%z(K${dLyM)ZB0kKLzwo7h;Y{R?0E7ryi_eBHl5%+{)5jM={+rlc!a0t`hgJ5jdhG2~a+p40sAw&%q`d(L3Z+789PUV9#|L!2uS#RNN^ zK8|~?g}Pj49*B@jRJ0jDSAEw{s2tBj4|zXPN*dHI7R_s6mqydw&0>t3U|uh?0o^sV zqu^bD(`asYlG}EM5n*81UC=V}N@Kc5;ovzYh~;8Rc?&PJ7FP@;lc1C@4jrgls%|N77$v zls}w={~fJ%!nT%dF&M?SJ|SC)Q7$*;Y;Wx&Y#)=YQ^0G|#Tb)}D##Y+WU6 zdFLf8HtYGb3h}=)d+YKRw}RoPXZt~Gd>bXt@7SiS)`Z4K3WuMrzKR7)SFud>5xn#J zoXemz5zZx=gLSiHL<+8AiDWQ{GKVqZ@3` zgXcc?;P$fHeZqh^Kj?hPEMO${@RJ104@Mp*?K|zY9nr&2F8OA#dibePEW-W0&RUI< zk>iNgX_SdfBU-Ofd1NKgMvZdA&wq-iKQ{cNKsY~GJQ}g2%lH8>C8Tut<=$DkCUs4bKl6vTu)I-0d9{MHq&@UMb{ajYfZgUhv!{v0L z*N_9x;Ig3-*3t>+U{Y%7q}0+$sil)rODCn4PD(AElv+9|wRBQy>7>-sNvWliQcEYL zmQG47os?QSDYbM`YU!lZ(n+bMlTu43rIt=UQi~cPDYbM`*V3u5CvqENmoDguY%=mo z>z)Yte)h_$&5ist>}M1+#JPx~=wg24_XyHcrcPuHw#JoFU04J4L3MnG zgMqlT6yLivPla6rcC@~C?*%*)upvfmKe*KLn~2bitaX{32Z1WO)8Bu}At>pi&{D}b z&Ga6ETWij%Csr&Y-SQa8j-Xe_mmZCW5Z^_*E%elE;C+Z4!JUDtb|-$(e+m_5qaL*| zzwB3CLc4?f3tj|$A_?h7y@4{9AJ8|n6O?ZN$`qte}*t(G|3S&*aIq3talx+{de}7_s{?Tsn7qbsUl^6kB37Q^b&wl z8dt+ASp*GeiDxHRl*~f$ZN|=8@@TwL$HM*`JYwI6_U&ko0Tb5>r2Qy#YP9+sW^Bem znTDS2G?aSwU@x3(1cwjc+2X|wlaAbW8-W%`z=I`V*#i@4t`(f2zm6x{8!_AbBdqES zK9$&x?^EDM$UYcpBz7!P;xrxuE2o9P`G6M!y0U>F4lx@yQYh#z*?+`;#MlG!Fpa14 z@fit+EO09jmn&bv!sRW-XImcSVKbI~MD<~mTXg5U4mM!~ohSq!@2;agY zx(C^sqi<H00{W;~%BsNbp&;9NpEQonTvFy9DREJx}Kj18rq zVq6AF9O~6(0@&ULNPLdEHpxTv|44r+!JhcXEwD5WppiZri}9GoWqal7uLbav;=CH7 zd>79#yMiI8ztl+#u;B@Op9F^?PqSkUgV;uj8=MWpP*~WAPJ=}N#{f99>866TD*;`^ zOTcmf#OHLpgKY+$eIbBPn@Di7{{EyIO@`&-cq2Sx9N$O$_`F#!j=jLlweL1xBclec zkO+Ks)@JjROHL8#t67GYx#o8HgJd;eWM?@xRc%~hYg2y~R}-%qXk{nWbOPpunJ zj-vcOI<+qKEXvvfuQR9CoOfXMc6bd%61{mj_Rj0VIug5prr6C;6o0`^SVtE zS`0_u#af_tX(KH%>jM_rcTuzKh?1?3zH7~r9>Kb%tekb%nv@oRrC%aU)w(}mKftmo zdL+9-#sijrL+W;%g^+{szNiO3KLH2d?E-fVc#hw8V2Rp%8*ig-HI18w=W44q@RPMw z9b(n}gCzb)n1?En0yOH=oK(`~`^6^x zK96{Ry8n~-x8MXcgHv&X$zpR~kY5LkwW$I53i-D99kDD%(|GR_(KfygwJL}3i{%9D zZ^YjlKtL|pcOy;-O47Cu!#gSc{e^Pj@hc#)!~Z5({z~@aOlI#N_ReMR$wBt^g70fq zV6Q~qeD>-+&|$s?m$w9)KlC;n+ujGB=CiPHd!4JVcR~Ll)R7>IWwfNP48i>~tv?6D zuanbr;Ipf5mN}e8PHor?BM?XK9_53XGw-SmAcr#e0FteSptKgeLt_j+X(f244Pa}+ z>*(^GPH;E?P-ppj^k)*`Vp88HTnJcvH{k~uXknN*Gk!nOM?{I~)6nhsgvJ$gHk*`B z>FLgOfT9?m5l$fF6-??2!q)(kM-mQFB{GElSiOtjto9I>4Iq zuZM_LqyPf#i zl`6)C6{XC`26C;=-Q4UnBcL5a+P9z?T=ZZXPr%P$y!k9rz}jUkqJHR`*t6ab3_onm-azSoqTI$@Mf?(dlGjumFY&Q7X+F>fey*!q#g?{RSHSAe#k090Fst(Z! zL;b^C6mLXLP61TIQF9x&z{-EI2CT!OfW~uxkx_Ixf{gDGb|)N(ZnyC-z@p)V`_Nm* znuH`5dG#zN&|(ZN_NDKRHHH?u*RwbP7HD$mK5CN(2M17CyY810))cU_XuJbK6}^R} z4qFsfuYjHKGwZgbh3}9E`{3t1&XhGkFlT)wm~cp`gR7oOF8}NO-GD zi}R;Xo7_5WpW79ln)OegHhCD5v&Z|eFF1XgjD|ja+RdLn?bgy>PM>!5>C+}ppLXT+ zX~%cv^l6u;PrKpi)9!Mj-09O!%$3upU7kMe_NR9cgUi#W-2oceE>E9!bEi+kiJU&I z{T;e2a3cPOr%!7qxzneej4P*4YbPTLoP?)OyF7i`9i_wcU7kMehNn-vJbl{Doj&c@ zuADyY^7LspcltCEET>PqJbl^?PoH*q`m{S)`)lL$X*YlRw3|PD+RdLn?dDIPcJrrC zyZO_n-Tdj(u0DO*qxXwYYm3^1r%$_b`n1c_r`;WN1dtJobC)1GE>E9!g9XdJ>k#Em zpEkE63{Ic+@~2OG`O~Mpg43tz=~hpl_T=eii}}-OU^Tlf1pd8T_!Y=c7|1{biqqV84Q@cTc{C~-YJA~bfKKh zaynp{>}D@H7H-QwL^(E4jvL7FEoqj_yTHPdVZe36O*-PeOx6c;N95{*#}E+fgBbj% z!Snv^VEBD%)`x(?&w4ID>)EScM%{|fdM-cf+2LnBm!I|QH6IG?|HF&F-=iKiSiv_( zdtoj=1r_N5RnSwjon3!we0m8 z=`E!8Mve5xVcSu9F|__TY!|Lgwo9e=#gD_f$LO5Y0MU~kqjPdIiK*@}It4vOCtQ#$ zJw|6f$1c1HpjgpOJm@jftB6fOB%mtN+fQ<6nqQDift4t)73``EzA5QYiFSs@-3~8O zm@=&-VInNjC!)BiO4?rnn30u{jYwSzm~98;`y5ZHbT+FQHr6+W9aqD)fQ>Pua*Ep> zfl_h5gPU95#uvH)VA$4`Unc}&cIT+aiPLxv<%5H7aW|0co3g^S4#DBqTJ3_R z_Ezn~;EUK#;vJ42tUW0}**9f{YaL|YlrM_5~2YCjA)5$=V`t#y#SP|lihLJODLYZNZE*CJM^>MO7^7-}kPC2sCd87{3qS=h$ zCYnvzm8jO>Qw?hQW`=}X_AFFYK^0S?%;hw$fmKRZzVtS85@5daodTGa5q-6k<~c`a zR+YeyCiL|}5Oq1IAzTiaErl*$i$|A(7BW7bGl{9-9suJo%FsA!|6Dm3hA6Teuneri z^X33BY&L@0W`_aP+dcUE$rVz+|A$YmIG8G0sW@T`Rp1rq5zCtHAvC0M1FZDP6%`g> z<;kF48H39TI@}4cgoFR8X3((_K<7z*P^QMXZ;=?VG^#{}v|RXgY%+@CQJ>h`}= z?FN+V}tZL;CO378aa!^XH(v?1hRd7&B zuF{o*QmouTDM6+CEc_2DT?$P1A?$Yi$}N3}+yXP{LpTMeqvR@G=|eaLr=vIpr=vIp zr=vIpr=vIpr=vIpr=wthQ-nEKn>&U=3n{nUJ3JkwUcD&W=%^%{to&y3;_4i#o9>E) zDlixNG8z0@-O@BJfmKp!z05Sg*8oe7q{~tYW&JhAP7{AQ#kBXbI{|gF5Fqb(JD$uplW)*z^}Wr zK!=!9wV!w5$)lncQk{jFy%74beNMkhX}lj+Nmf|p&5$fL6pBMlHd=||qz}p|&If_w zoCKwL8PC3hAcbvRUH!g#=|8o4=_P7QmGscU9DWn3kw3hof=2sPXv^d#VBL8UbRZlH z>$dIFyt3G>byweo<~Ee|PvZ`*LhrCvPErYC>Il1AYXOB&^lSlY&I+Yi*H zo}x{m3e-S#@@-oW8uz3&N!!+gZQEghda|Vl+t$+nOO8AkU+{KeQ?>{Y`c|)PPAJ_A;7ywVpX15s zITcD2b1LbFyKdN>$Xr7{MV+dthcqs*3%ICWNRB zoZAP>XHIZ_T?8~yQUmlB(WC$cr;j%o3p+iHdIA!_Q8?4Q7SB{{4G8)f`0D}@{qjW< zh2O4SbrgkFGmUS~Ooc%{4arp@AP;p<6B@pQg)hrAn^3Z;(~w)TGPAZNsLcS2WMyX4 zPJn7uMAl_CV~45_Xi-_0DKH}IGR3$rC^5|H@h%N~8ZDj#k;P?ICjFcVDnw$}!kpk2 zN89FBz66y&ybK<)y5FbU?_kF|odp+@Ovyc8;Y0`zlkm)l*nf4KCC_L?F%{a3Cj3dXl zpFVc{VPg+Dct-nO_Zcv#Z~JjmfG19#y4}oa)257{G!~}qJ9O+YtYiB_#*g2wbGuHs zU|}4L?c24ZP5bfFrcRuEh`w(Dl#UZ;O&vd@-Pjq2|FRH9kDE1l$^;2#9AhzSyuQyt z2Wsp-c%SOt!>hM%*Rd-W80)lMCTS}hiZcz7u4{i&X}ew0b|2DqJ<|2WZzOHU+0@A= zByImRP)OcINqGv1JN7ed8Q2TN;QpE|F8&K{Qqn8Ef^#G7KJdoubs*oq{RygM$2WK9 zS{qk}kb`@`XjgM&>(Xcr5sOTW!&#mQWeydKsDg$2Sq(V$5(~uvui=kHZR4B$uv!r} z1WcJ}n7d(VH15nugK_u-7>%fU4T(@q6$xQlPC+4@j>N`rt5z)ux4|NYJxT(e1}OI6 zvuf57w0Q5)tQE`2+4`n@j1D}6l(C+7%lNSG{y7eTlX9wdG7g;_8c zgv=9&#k+X!gQLXg(b$*OmZBbY5g0PJgYXERHwuY|3-K|;=`B3p6%wxy;vW%9#X z)${f>As!9F>3FzRxE}Fa64N7~&bxz2LP=fX1MqO7Lyd{7w1zJG#) zOqY*wPZOREg~aoPc+rR0wt=StQmq$>>xDS*BcusWw?g7eLi`83^bz%a3W?4lgqiJy zY#D~9o|m;Gpoj*mO!cIVkwo^G#t-9jU5B1+a1b++a?t1K(?D7OE32PNkqA^j)Q&JM z`yu%b5}T`j=D{LY{agaDdG$m7p!%WlJ}?E<58(>Hp!$gcs!=7n@*#*_nyY-o6J7bx z*b9`P@*zA3utZlrbayIXv95dw6Ra_qiu+-o>Q;>9n<`YvR#ZuM=(+Y@=h{YU1ZeMr zRwC*uMc%m#4C(nGlw3o3w4p~;uq?SP2lpb+mUSX}a84&42mcu8!){*~#z+6HI_ z%&@h3!sZp0=FC} zJr-*(v8dl;vHHCSU!=!k?RFrH(qplPPlFLXmib5zs*D~0VY1#^jMF5LZcz_$amAK2 zf-FHTL1PV=lDd;ZsD_p3F3Lp!y+8|U3Bt*MQp6eRIRL3Tzfmzxrraw#R)AvEQe5=v>xd+fP?!e(O3_($tCvk;PHO4p)>=*1*EI%UfI zQ{dpHL@zyr%c-~V&J`qX${Ex6SW9C4HIfiRtnX>8zg7}xIfyT=N0}+n-}_4x(pdiz z#;+RdU)c)Oli7y9>P4WzY{S2jBbu>YsjkSeT}g0lR}x&?4Jfd)4S(%gRA_9M#2DNC zze&N2NGGU_d|GB3RCfyRzo2729aY<1%n~oLb5BJrktOU4onV~DEUFuVs%{ASF7m5x zoVOgA&VK-xq8oDg*SOSK!BVM0W(9)kj6l%OJP2(|BvW2wDXW%#F%Ce6JuvY{KBx{v@j2PC9DPAQXKhQfi`zuLHS%#wrVQd!ZCWb+9*gp zZDr6jaOYJ)2T(5j?d zm9pq;I5F4wtSkcqoUaBsy1#Or)RfS9ecb(3PJvlp2E(JbvUUh7otPc|F3H3Z!fdNK znew3CVBusu$`b0wZ`I(IsVrt_v&v$IHb+hqQ;PMvEbp;I_6*l6jL^0^G2VkQFGBVKohJgaw8XCj=3ishy#mPrwQKgS(tY}ZK8Kf@AOFb)EZAIX|S zSemkJA)FJ?5{&Z_OR$|Z&34lCz;a~rku_5&l0;{gfH^|QlIp&x9&U67oWU%LhrK*| z30fvHM|*v4air9ldCWV-D;4uOeI*dAqqJOWgg0Hp6Pp$rSr1KVj(GGy_Kwc}1kp^Ulp4_$H||`FOGR43Uv|s*f|)II4>o zot4mxOu`GS#7|oS?ary*V`xvYXJ>~uuPV&2FI#nBS;#sleE z-l|8_=0YTF51Jb4^^8oHUZ6U5npN*YtKKt1!3%F3pLFUwD^rV{2`oDTW12=ja~=JG zI?W4ZKY1yTH8`(KVPspXD~xGY7}KpVX1KyA$P@)v%OH&9-PYQgakRi=zihQd(PT&tNC3Ma!VD4*Gx zW;$m9tie$fm6+p%C^2K!lh>Nx4N*+MYgnZ}#SU{*Rk2TXO+)+y`)gXB{(|Gk)aDtP zomarlV^C!JD-7u9lcC2sDRxQ76EIlv@iQh||3k=-*@HGJMKkn%$LQzAQd?D8tCRF_ znPPC%H!ss;3?rHB9gD4AC=M&ztxa+Kf8kPC)WXx?+^ko_;;nkM*`XqwSD*n5c@4T3 zoRY(NZnkh(a7>lHZhmIea)yms=-eD(p2^^$VJbrh`Uiw03?9yQLkgxZ46`8=5rVN~ z>;@tr?31pu$lDj=P(Z79V+=G_PsgW#R@_(?S8*4*a&*_0G3;2UM@eQah32%XF%*oH zek{gKYix*VP2_Y+#ux$ZGR$M{BSWT9Kyx|Ybg{WS!v-66$YlC)^*k!MSf+*Yd4V%G zm{4qC)nKMo1Bv_ThY|O~xft~XBN!Rcj{-4b3D9i%1e(lC{!y4GDi)_Dr zDziTqJ9ZEI{IHSobhPMLn30#KTXmgp)%A>g5?zql<7Z~}_*quOXWOp-7|YX@+{{oQ zaK*0VC{ssrbHa?2+*~WUc~)|#yOIkH2amUHH8c$jlw$MrWVp1$rMdhV3+*?igrO)$ zSHa21&b3^-ewEjNT?x#vW?0~w^=X-AU1&7On6*_kb9v$nSoJOR{EpnPNE8|_h6(ks z7#bLsEu^ExU_czhfE~dzJu3$SV-{54qOdw%av*T-E^;nmG@ml7Nqy928Gg|2^h3iUc3yM2b5ID6|>JlaEYQ%w9yX zNx-6AT=Ma%+|9GLh%7lh zyKA(078*{-JTI>;1P+sCoar;OmsB$);9A7TjoXnOy#)P{y?E@Z`{=x)D|0>L9BrI_O@4fL1vJKDrll$reV+aV*HCoJHH6?kg@+Jw_S8gl zeDuI{+;lRs$fh*YLbH1ao$2_=nbu8AfFW1jr-bs$9PG3AURXC}x1=DVqi#8)3H+Rz zZ??YWY9db$xTNK=70Yn=+=VH4wr*Cc%)*~+B+(^9XI`VmVC1JtVRQr!i8ya8v^^KD zdTq!0Z}m!XdzaHxog_aY#~$K{y+jvoo6k9 zs3y?4)=IPYjJOMR+0!V?b7)mo$XWYE!bJ@38FAFmQBugz>Pj#pR9*SaabfqWgnPa+ zquY#aFEaXuR)#py@^c)XaRkbgO+a=G=MpfXy-pKxVgWTHRof2KMh)$NV=irggG(`c zo&4Fr#$-AUJ6D3$n~V`qcZNAeV)w5IIU}TH$eDopxw|h;$z1-LYK5GGTW2z!b-J^d(=*3F zyNGLiH@0F0BP5)WeLBUvxI9yR(^;V+(lEIFDxi~_ugrz+06fVe4%FA#HE0J^Ll#wF zy?}K#1`Xk(XXth~?DDy@6V#p_tT-b8GH-l@8!W?yMv2Wo#)1lEYBksyfDwG<6PN1& z?Sp#b^4z^`P%dYAl8(Z4h*V}LoP&Jf5OtV?OJo=2bauaW;v8H1tT^EzGK0QRMi|EwWji*y#^xZ{_lT?{AG(vM?D;>1Xv;+28=faaXQB@$` zT#Lyg7mmlPIa#8#HcjPVr0;aKeXRqQDGPFHec4M&I@z9pGTTVVS#WSVHH_$uqdwJ| zeI_}MRzlnpXx{b9r%(y`yf0M3kwcC1rU%3jiYQ|>7q-tqNG3YeI6Ga*p4{Pao9hE+ zhSky5X3_qf4eAI2GTmFakRb0^tFzNZ1QgFH1()A(#-_PtU^GKz5DXTMI#?OxW!?#e z#It0{B9m1ZA3eDkodl^84B6Q5__3PjjR-rsg2G6W!;|(5KW*iG8Sru~_nQGIl403Yl>d;sw zo;mN#UjGYJ%)Wjy>bp3W>s(LG!#OiYmTW(lsc6}6X@hA;4Kcv#$YY0C>LZ8PQAVEM zK8b`KP1l$?28_b!7~Unbw~u9~zFCz*c*EU-1(WZ3_nA{pZ61Rqw`;>^mP=s#v2frC zwJ&4Hrf3~k$xHKcCY6+{Lyq3zDS+zTWT>Pe!F*j}ou_y<$Q=0|VCcH3;#ss#fDmiQ z;fx`J6!$S>%sysxUaWEDmpx_3)Kph!pg3!eV_%t;VKXQBE?Ieem*pi4(lXULd+}_N zz6%;|dY>9TGYsG{4l)AHc-_Peo3l4WIeiEPa~9L6Z|=GSF5PtpwCYZkap_DJFi|#^ za|&0~+-b5=TQluNlHuvyt|+JKQr6ywD8HD^p1UL%5=v(?ZDGr50mMcLWdHL($r16cfg3;9-d$>`Si~5CU%|4 z+_i@%@Dlp_3Ac~Vu@@LNW_TJBWegZr3miAZWsgx82*>amfhmilI7x9UXwH;q_N*oJ znNEC8<Bd1pZ&Re1|pB!m%RAghiWVVCEh?}U^dpUGzxiB zGG%s3COw>eo5tA7F4wXo8VYDE60Dz?V%G;kiH1$;da!v|{P^PTNz$&_Ns8-R&E>ajH( ze4GJ$mW|x)VwsVE^DOH4Zh{C1%TkE^3*+>W&f@^~Pq67Jr&+pkbH}{Ux8*y3l9RAg zZKua2x~{GIvMJ7nu%Ko{Usn<2eya zEXOPrM+|myXxKd#skm%gwTA`dJiss00*?1`Lp}$YJ!{Cc`>dJ6G57q(l}D%dbMpAx z*N@I*V3H=A*;gmYBWKPTvz60CVKcZGle3@37-ZaT93x7yVd=C;fOz;%HFi^~RK5ESl6^`cQ~*@6U4Reyte9k08eU0lrahFQd)Kzu`cs z2tK^P{}b?w(D+H#jGu&NQ~344mv6+H$@!6ZyfR){885*f0{)5Pr>3h)0pq2(iNA7- z=~b2S4a|TW{6wQ5{ePmisE6OKJ>kssb*K7Qq0XUD!7`$6oR(M#s9EA#hN#P0acx1)>ZMlYTn9h@>Z zx_;*HaCF_Q*rl;cqbuje`eK{E{%SNaJGy*s^m4HFUxm#ZP9~depKnc-DVN!d?Y&JI zyCC+174f0+bb0&@f8Stq$?SM^K8Ste+jV~e6)Gh>@$mkvcQ0e^oh{0*MW z&gdK15%8DY8}EPFs@dYX~QX#L!8 z$Nu5l(eFp*emi<6R4)dW{#;o4(#d2g)v>oV)z>i&J9_qRFt{{w{spmfVK_BAzYzcE zK?){=SaZ)HsM=g5;{tn!lnL^-jLP zTgM~tH`o{AsE{J{vt6nOC z-v`3^qlmxp(QonBLEaxmB0A)8{KL=}uatq0gBwRa4uX{S!r#DaAZA z61iUp8~P0q*4f>a<~NKFV)zkd{|Bc;O0V1yU3~hL9iI`)`j013d?GO`J_%^NYH9xB zTtY&|mU!Q_eXVUheeuqYu7SPrmhRoVySqHErL()QO}!yIU=ukjjHK{;oRP@WQscuD zt1;f)(;pwWLR;C9>gZb0)|o=1JL2f-c#yEN_=4gK;~iZsodd0HUa`gEJ39LN!b{KV zZEJ2d&bq&~wJn8Cz>kpjU)$5x2h{hxfv%3e{#M}lS$T4B(B*)?w;J^xm>387h@k{s z()!vu+gkdSI7<*{>+4AOwe>5VCW{c--?5t^Cdf1x^Y*uPbTO|Xp1YJNr0y%{9Fp{YG`b$9Vc? zKYkfJ&@TM+Gy0}BFAKXn`dXkC{cXKn&7FOomrS_u z&nsh}6CL{-A@RRWmc&VEo7dBe9yQ_F1Vs(0H}}#@8)LeMj1@*IHm<$kbs0up5QZK< zxeTR_BS+5|jxM-K_&F&2bdJH#(Z!7lCuJC({{la4YT~O?I z6#MfB88!KR#r~XPzbl2m2P=oFI>cuFJ8Fn}*Wqs-zdVMgF|I>K^qef^_cS96d;NXj zGj>R8jba9}z#@+Rk!v|+Z2CJhb^D)$1@*U&He<9|1 z2L6twlat~n5J%RKnH?%+u?^C5g$r3-40E)jELfxoOQ?kRY>0Ej1)62fYU?@-z*!j& z;pQAbExVid_ILO7_lASu`xM?^O^c*%tW2+n`_D)2O|M8-u81x6A3IRo8N1Z~#gwOD zI29MccoM_WrDw(#uXs8g+k4+m|E>M6`1krL|EK#aI*<4>Q~u{u{>;oZ?<%w{VOr`r$i>>Bp3sqm*2S9aWZ_~%16{_F1_?uag0u;Cg1 z+*CRpk8Sk}VqaR3_WvI*R)m$I$|J8H8Q$pM_JzSiEBvF;*d;gnH+>=YC0zU)F8s4n z{=55Qm*DbYAD0)WZuAT8jTWH4b;awR@hZ7DDJ{s>>Y%I81HiR6v}Xc?4SEK7XrEjE z3p(J2DUtgRk(+k<+OlDPUd5~NpI1TV{tWtA@kP1-^IO2uGi2%Sr$lb?_Z8Pv-B6M) z75e`t_>FqM1@ym1`hPYh;!hhqI25~FhCvL56&MUFWBW0Dd=|STV@2QfYbyMegF`3w_2fFf;a_pBnK$F^F(rd9hz#5ieoXFnzGB%I~3dAI2Jc_0Yj(zxbEo$_@U~ zL4O;3Lxq24?2)1P&bHd`43{0Oe0oROjek+~>Op_nQ$rhuVgvE28-F}}q&wQnny*Hz{G%bCjE3a59oJikH(lzw8GpY_#D`s4OA3#WNzQ%J$f~BJsZy zekM3oKW2WM1)!0p0g}hh(6eM{W+Zh>?ApVzt?8$wlUjwTl2JMdYXxapQuMstZM$1~ zt}U*!>px2$MU7{3fji?m6hx{kjcuI>fx^k=n$2LP3oB~@rd z9|x3HmFh!pJSyNvTI`ufi-=QOcK3uWzHD18VZ|$}@C2f&q^x8pUOE&nSsA||4nL1) z?HiDSNAG1orOmHOoBd-+Gu_tJ*4xoCNpDG7(F^*7-70`l+Vy`TJyNnGmaNCao#8b8`Gp$P z{HahoaKeSym6zQ2N$$CLDtX|-n@REWmf|N%ZZ5sDw5sx8{9t^@-%#xTz)KB@i0=@h zb8Z{awc>u-(Ik63nM|7{&t6$1O`6dqTg(T)1-c6(LmR|j-5?}w8$*uSE3%kO^tLqj zwb2|z#hl?cUl4H*+r2QtsO$3;6#(T!D`Nj7M644cR*XdiTXoidImEohN@qq&uiJ2= z)Wn!1>T%f1H=Imf!odKdQ*11Q@9jxrnJB-wjVN+Ybf-Xt{XasK@yQCm83Ora#m2+& z)|+pQ4SYM^(J{25vvT;p%A16%q;R!9FIQNZ-`&yeJQ6V!cJwv(_Zuf*@@QO5(LKWU z&x&j~EGw9U(gYjIEx3G5^tYtj`q7F}wv1MG;ekP0XEIE~M1(Cr%a)f!Qf04kUlO7$ ze{O7(FxoCuT$Y!Lj;^-;P!~O~tG~OwGjMV`tuWqX9%2grqR3F%zc!VQm%r*?TO8ox zhEJDi5oT6-IF`1KZDh{17DJki(YTgr4G5DPiz4Xg>u%X4Pq2_o$@P<|TYSVD{&NQ^ z{MoNy?X!Hi{b0QE>EU+FHvH35RsO?~4?ZmQ>j#nPr7u+Yr^PmLh4i#R>@-RbVK>yF zXxY5z;Z#iR3Wm~j|ozZ_yccSlgsQZTVgDykp7 zqR9%7&Ha$gJsU-H%h230(CuL%*?*T6QTTkm9QB6s(v9b-cmNpMUzU2Kqa}l}NB7~Y zrt8C3^T3$8(2?%wN^$v6FPdBAX=0!m%SjzZ*s|DpfA`(kCo6vx8z_(eT!+#PLTk>> z8X;LriFH4$_NW($T@t(WgV+F`z9>FE{z;#hy|Y9O&s{RxwH^#Buo(uedTjRE4B9_xjUb!6NcMd4qTkQ_!MaVXAc@SHU=2n=hh%Hua|c(vrUwzz+1WH2>6 z=zsmd;FTK=RsZ;~e{S)2)|dF_52h~sj=$$AXkpp1*Zpn;R25iTKBK~)Tk%?Y_`}Nf zl@N%J(FBuz?B-sv3rmL;{vKRUmur7|>hO(+Z1+%zHT~bJ(s;KvWjk7|#@@tNKF6DC1$S zEqjxqD^S`I(bMkT7}!TF*w{E4<`-x&W(H)Vm26xV8LS+J6=GxeY%`1ck_dU<$q@4H zfv%iXle{A&59%Z_@gECKUzr$9`DJxYb4UM56_%Z4hH<48nMRfBaUs5NvtMspU-v+7 z3!fk%4{3dmw4NT>F&tYh`mjUD-I|NsETUxLM!cCklnSSBaDXG0LXf79u3DtwlhX(<;w2;=b7#A~Pd4|dY`vM{#$U}_79$1r>m64^7_noaDN$a(c2vX23M1LqMjJSX z9&L*P`+nim==((x3}AjwafLr?a9wp8z8sqmrdM3q(NS6RuggoyH!d&PRVu3SmWUHG zu>7I($SsV=CLwIOOdY=^{=3QVJOotJDs~R<9PY%jYV30#RlZsoe<^{oTE7qc>Xe3>qzpq~hiA%IcwALzv*ir8PXE+IF7ti%M=z<#Q zVe0<^Vtf(d=6NZ9b20v=<0V5^Zn*WPo!C%QU0s>3tn5fvez@~!?3+J6x+1=!vNXDA zUiG??p~|85*k=FtVwY5wV^?r&Ggj_y#P{hNKEk@i=CU^)!0V4~@s8-Sxv#<^{^bY_ zV?||k?9!Wt(v`7f8t>>8*Bq{VaLAwc%B#B$USIOs)3L>sH&w1b7*CfitB(8URa7m< z6RPE9N8;C){OIY=l*Av1z1Lpp&%C!3H4K+jrt$bJwmN<=Jv58}_g-$gI=JEIuMXj* z#i6S8e3Djr%g~Cd>Y?RT2#x*E7h^&9w2I0bhdzT_mBR=9=e!SM`&N`}_|MT

4U3 z@q}wFqbWz03I~^y8)&@baoIUwltp_rm?2?+88OO3$+9-6)ch3`;49N2eiqB`q8H8g&%Rf>s4Crgc(;FTMQv=+(2?aOJJa|1XAk9lGP*13<)6!G5D@gzh`{#v$Um2uXc)(ie zpB}s9Fnp(f0e0^VrPGz^o&MUvT2Asx9`NU25&ZQHur=We;~@CjG%;n&&?f6k(Bt{Y zn};0^{u9`ngvT6vup_BBwsghe*NzVDT!DQ^(?2-G*G+fcuwlsmQX&`}r+kBepGV%?-! zM>x_X-v1lO<&MILpDIrIXBGRYd-3;y@5Ihc|9EIP4fRalA3L}5zUxXWhth{1#OS|k zS@rdQO=lfL)#=|K{?Sl;xbmhCZxOAj6Z%R<(VDF79PPc~!oxi; zp?clUQM!RA4RCvfJW%_hRC|IS$zyj(Pu`6UM@U;?WH80_IKhXhT^mzPx)sK`srf+ZN0a{Kl3Rp{^7IJ ze*&5Q&MS_c^GDKkoRLPom1A|C-8;f3<{@>Y=s~;}fmbR@KT~m`KLZ}ALg}h$`3n)* zrBeTY7^8kV4%w=Z#7Y&Wi@W>M=Bc0etW-b?$TPr?;~A294x|#b4{zW>%;TkrJVr8$ z11OpOaOq77Vj1@6SH{1d9zJ*rUe6wix1|psyjcYCm%<0u-SY7vkAuR6-VuWy21U%S zRV~ICCbEKs>oMN?e|QRZN?->&COw1c6>r40lpZOM50%^yKe%(ZKR;IF?@X0M7cc1A zQC1my2T@;a4_;0D)KF|q`a&GVu;umGmu1)aSu#M}FnKoE(f!@##m_PL7}MvkdIg;Q z7;*5qDL+|J>z`GTUhyxnNBuKix$)KbZhv;PEaEp8`|()Ohn<}76{h^&r{s;FLHw;+ z5g+~#VQ#yBEgoslpre;z0+ZHz(>wn@_Iy|Q(9PVTKKqrm7o2}V8Mhk_?^?U@{Eg-5 zov-~o?e`-JszAhie@S|yNasfBexI*AJ#aB&YL7Am_hhEx+u;wpU|Ysw%7EvF+k#{!JwF z)4T*_u27o=j2kUZbuc zjUfD}3N=+*U3nDmWkt)*s==^ay$t&@@p4`4a_RVwgm$>8Jcg)Ko#U$LBi1_;Ygexs z8BSP9Kx4BcffRd_sy^0o=ePbI9e8#G8{5+l9Zq-nvs1$PH-+=TF*wh!^2z4bodbRS z$)4_!8-TJ1=1^{^1np+juqn7ni+rC{Vv(}!RXkveeHw3YFuI>s9Q$%<<~5j#`iaRp&=rWSr7xKp=xRAGs_`4yHe>^e-3`O($!v75+IXzZ2_A#eQjpzj4qnE%xUQ`a3I1`4kb`t*fez@SlICzIJ@G zkkFZ*gj~-@0|m$$AI0N&*eQrXazub^U6~n~e?i*Mj0{$N7;8Ez()d^$+q33PkTsZn zY|pSrX>TqmoxEcKx01BKibjTpuw;+({;2FkwiIoa52t)`{$D7@eiXf^-B*F7iVE4Iq7(U(N_}U3>bJj>gL=HqEA)06X!*F>@==5+PJ7|2=!+3ks}t1= zIF@gqt8bhq^R53!a2B4-hmKiwAofn?$$WR7RO)#$ALt+7DRIw`e4foW6kQ~yQ3E+Y zFPi_AlSy@dFTx9m+@81DhZkw=L895GJyyL7nioedjO|(PUprXa9$SS+F*s3lZ$<1| z(N%@_ABb&z2`Nv+UXa;W0r>de_(Z(O{!bMYdP{N556>q36`uKBUbt{g!OX>XOnV^q z#Zzya`Uj`nJmn_;#^^yTy?EJWi;#8+zC8Yu;ojwivru-y9aA3&OJ$c~dwk5zb2op2 z2p{cbwzI{wjy&0A7bEQve0jj-%Q(sQ^1^v&Z{Z!MJ}~u*VT&WnEkv2O@a4IY`vKP! z#%_+@6hTX~?wIm`Kcbx?c9 z7@CkSPz7WEGS556LwmctZ~-zD-4T1>)GtoGE$rcJ9!blyD93Za#zPBbauoS_nAaTO z`D9mwdkYb|@u02kz@Z0U^r<=Pj5Z)Go0cM^)u7D6L!Ng4IP?I$DE#3&}KmA7ssOW zW#s44HT$%k&_94b@fb+YZin<0zz6cw7A}|N(?8O{e60_7-baw%M0_TB=|Nc@OwuZC z#J&g%gO23(Ma+K)`FZNc@-RQR$e;g*$j?(Yro(X8gm(NzT#n$Gym;`XJawW_dCBz0 zXh}wc9A&A4m!K?9R2WSki;%As`FIooeGu$O{V3`duZpznzF?WVQHI9>+^J2vyO(tjKB@!jD;se5c6d<6OV@~-;Jz@gGhjgTqpe-HWj(k$(AEPH4Eg)#Ugsdr?31L%J79x*SBQr4{3i5`S^Nf zHE?IJp-zmD4fQuR4SM{T>N1o~`pBj)MLO$*%4Vdm$&-ImR{m`Iicr^Hw8xhqRaXPu z3-o)b$y0!J!Oy~YC+cTjL;ZXqQFVK4U5ZTyJrl^!-$>%ig2kW{x&${rdc4q%{CwN5 zBr|``*pjlo8~OQC-+1YN4*B_--Ca_DU<-Ns`xnUnEb=cw{(7fhnf{(hugOZE_k@l? zHh*@%lJ1%r@QcXzZYCW$ZIb@rdgSNpV5_8$=Z$NuVmnWw9N(7ely)#C!ZP#O8ryjX z`S}9U3zB~UW2!$eqc+r9;;a#N!FGzkB;W3NOWPT>pNo*E2Ko7BO-k|ydYw0RW*Y}l zhA*;g1)eC3fgbTO(s%RB{q=`2MgezikmWX+bk}B?-j4JN zGh_^d%I9a8zh)NX_k!oW4jaQ<8)6P^IhPEtM}F?0dk?&CyS8hdgSLLV#;XEIM$lj#^Wf%hpvl&k4Nv{ zLVi9GtsZCoc@Qk0O;TT^{!whc2zk~ZKOYz#mHf_}=r&m~k$RZt{U2kDSDnqAXIAH* zXR`hWQI?PX9+CPB(9L77$GwI!eB@RoW!&|qgQ9%dI>NE5;B?P>?oH2oY%2L4-}+M# z%B?{;K9%?>aOjrR6T1dDBCcYYy(q(H0dJ49%tGXQ1ZB9&z8Cmd>zK^{2J&-R`!;D~ zbXzJyo&p#Vmz23K2|g_S?bhEV``SBF{a$i+GF6I0gL+H&huA)Rf|VQ|_T^Yc1kYg-F^%dIvg% z6HwiiOqF~ADwC*$Y@7^*m!AkLm<>ZIByb~lo z`zv3`9l~6T{O#-SXxVkGmu&66rpx1<(i7Eu@Vi~fq@rGOUowRqy1P1hus8}gTW_*2F|7kD^sX)m_rp^W)e zE3cuh{6uPf_~Th<(*7Ei*VEjxE7{k!yQ8=HniD0mpfzlMFzmK=cnxb#JiGGKRfb*u z4Acqb(EQF6Tn3JbYwalW+B?$i9`=g%bhhm+5+NM7_OaF4{Fu?2CTy1N?()!PvbU{& zptmbIc`Zur80hG1T>%HCzn3%6qQ9o2%^BxM7i788M~&W^CTyD?5N&Sh+}8)*;gaY= zah2?E-r+UWYG=bjdM9I=x@nHT3z_@pgyQzsgfP^!^`T+rMC08jUjLqC7mfx*;XODlin;oFaG9Uh;OBdi zN#>SzQ?1F}&3(J1IIE#6L8aYYt$nzUCU`|i(6+awt*4(fA)D+5MjpQQdO=ypgtp=# zS5ki32pOdXw1n-$mQ~?$6k6?T*vpd1$PFTMg1+^1F%dm)z-Wl3D^LREdoKMEuC%6T?0L= zCIvEFN$TOiFxKX-mbOmu9?2vQ5J4q9y={BKx-wYenZmf$3zNWD28_M~D69Zh)JO8t zT>~w_rQ0I*@5xW?;Eb2u&HVwZl5DTc&sDgThQDCpR2KeTjL|BS;1+a$vc=>Ik`SnM z>}_i`f&ojiGndK%IR=*FGNNh}8v3~6pmC5QFTPcsB%*wZB?Yh+s zRrN{sHs*vx3aj#M&zw5_RQ`Yo%`Cq05!6as{K#EVg>h>Y92}D)UZ#`G&P? z96|%`8BvKPWabaKv#bRrDC`_10+KW641d&x76gYM^oY6R=5~H9#VSmokc`>Qzz6$) z<8SRwA`pZ@^CH<$z9HFAQ?oXKBmCQ-Tgk40-CiHg)y1gUg|PxxS8S|qOtxVAc=v8Z z@0@P*V8qd)Yt~*-&MppqxrFB^$XO*GY!an+h!0s*p9kqv7)a#aa>I4i#wG|% zL9>Du1+5C&6r>cS6?7=*QqZlSM?s&00R?-#=FXn>W*+k!NXkp??&rwhxSOO%l{QS3 zU!AOi(Gb>bEU&Hy3n)>->n4m4<<(aTdd2$H2_ncrVD5x9F>zhh#?^9n&BlhyF?JzI ziY1f4syD7qT!{gK9g42&5jl<^%H9ECnib=G?wsZZGnUu2boKXks`_;IY82Adc8v}L z<#p-a<{r$0%j^JxJxdE0014c6T z7Wfitz=14j5LyF&kZdYnQ@1ge5r`oi1^l_#jMaoMruC_hcCvU~OO0FpoqoZScf<)^OO*zau7_l-6;<|}b z#3Z4fKvzt#B!LgYBqwv`ov@7jcmaYY`uUM1`hq(s(S^6AcVyHl;j5d)5TeHm1ve~x z81(V7wXMN@%OI||&r_GS#xhl(Sq zgBAzaExDMWNPi1&NU2WE(jph#CO@XoZLCo)rJKzO;ql)cYcK~@hHnbKZ>T8y$fH2j(yQ34!hdTdm zZsGjaYr(s);Y}7mQ3Q#-TtVv%G+$cOB50F&QmvM_9h|uBzE%o_QekSSNDSLyR6DQ| z*4dqQxX>HOh#wa2YTn&OD6O{bY3p?IVKil{xEod)rm+`Z$!yIn{(M?VX4OJCfadU@Zes=nlN6 z2!Zh)#NR7LI~WEM>*-)-UTLM6$)Qr*7{Cp6NK$oNTM*Ki*>t3=B4CXLD~Rk^#1Ya? zPdB5wzK&E!TPK$&BslHBQU@YjRFrBS=wx;@F0IO&%9bg!4uJNhN@Ukpmy?EhLw^^7 z&0P#0kwHRFNGixnm64SWKn|8TiVOlEYr;O1qpyQp&}oC$9S|!agBp+}C84FLxR1jL z%Szp?t>{z5G3`)XJbad*aHqS6FaAj}k5hCbOZP-=bFenD=~>sw6ateZ4?%|2bo6(C zzEm@whP1UI#%OCs)GTtAsHM469#bGrVRU3p=!QU>5$teUBS$L-MTI9G;;pqSwHc(C zbBd)zf463nb1tD}TxU>R7ayc<@ZZ)?VP&?Y$2r?%IomlG=Tb=Sg8LLZPNrg#3}3km zqA*;G@F)iaFM9}`7A+3-b_$pbnbjnlQ}CmCNipoZg29XUdWf-cNO}#$+9Rjhc|49& zR{JDHjE-jlh$b=5=LZl|_B8kN0a9Dno{nDY9ra*?I8UPGTeZd~$fZm=kiWU72P+a? z9Y6`t{k_fCqL#p?!IkRyfm9T4M;m=U1J^U1A0K0L2kNNd$Jl?}2Fii5`Dh&MrMW*r*EmO8sCU^=}BUURlfKvTg zYrA-jhg}S3Myw$^1VeB+$jV*ao^HAwEXfNAL9>0d8g*mPEr(v^8eu){*Jj7NyfRT8 zkxz9d$Gf1?!*bRzy1&QDNe>|QxU!fbKAx#z)H7FI_Jm=ihYf3Vq`-~t0r7&&)3v9i?;6S6m+o!ZW3WD0Nq(;FA-X88BOQ>A zRyIYXE36yNAE)SQa-Y2~G_mClX&T<$$V#eZ6*?vZ*^My?tQaZS`+e}w%+}R+4djWa zfGn=%n)(&N6q-fC>2&5z4VFw1n<=ospbpK(^dL!P5+2%%CHdf<@j}6MSX`F-gLF&l z$dG+xiY?>@_E~9pnz1Fa1Y?p%FQj*KmmEa`rf$eVG$+gPaQ4K5O_rIEOscm}JC-Fa zCdrZ)a?)j9ImQ>0tM1lrqm#N+VUPF4f-!zqn2YS1U#FxQS%X7xcU;?#MFpGF95n06 z!e~Z;@CaHgi-yO(dRTG8)P*xwS;;Ubq$0#pV^PA~5>^^QS{xK+p68mG;0-XI)YZ!? zR@be~s5R>}){N6xF}|mp`#biu;fYpHX$hYccD8xt)$5YgtE)3=$vEJ&2M_tL>F};x zTfH{1x_)hPP5G7O^>rXXa)GOEc+4Je?WXejWL*uGQ?Z)bgF>BnjO5{Y1)K!#GfoWlT;VLo3fOl>zRCvB2U*4f%NGkHs)YasfROXw#~IqdE|oeH>4ND@Trol zfnq6zck=r!#f=zIzF)@)2R zt;gZex@aWNkz|74_4LU~uhW}*QnILne$;Hjk8~r~-gs&WDe*R}uD@cvE;Oc^cOism zYr(`z+U;yh_3yx*9L`o4A?RZ(xmC4xUH#>W)mK!mtq11=vINo((v!Tq77q(HR%KJvH}J5L)}SEprjJ4YPGas%8+XAz|2%0+8JkNXcw-$eQmwn5Kb2+G+e#n)D$Q~ z92t$trIj7*gI6FFPXja5#}zR|VlqlLrHU#5`fD3jSCy|T$1<+2Sgx+B+IU4~O(JS6 zz~V^_m)TI8m?0c_btCjl7xfwvSaYnSN@iteBg|4qM3*F4i$u=XV0DX%r3cF(Lp4-; zBX;^+2{GgB2)GN*!ktbw)#LF4R(Sa1iNc#S8K%j?hpsN8HnA0SIGz=GT@V&VD$)P0 z?k-B&8|V{P(bWO9lw}gPJ@c5=EXAR*VD!nn_&D3Qs0C22>`Wn{}Zoyuko6S2a;Jwx5tW#LwCPkXWjsk@Nf(8z+J-IueHH@kGJOd??SX8+?o?ULmx2dJMx&hL3=y==nh0Xd&|*&6P`S zf>U~o<;tNw(nDBi!09Q+Z3h>Iv{XkrZVqROYwh6n1Z~>1C#7InpQnzXPw_NM#@4+K zE-SEd{{)d?k32a+)#GV9_R*S?NVu9|FTta1z~e646TA&jn>cYjnQ`(5c8~=Jfp~Sg zYdYK>TqoP9v1Oa*Y2iQ^?`i^UTgT;rg@ioM11BwVTYK=q>o3St^VKP}U!4*p0*T>^ zW6@&=0r`Fe$}Q*ni+nkg_?G}zp#<>?z^@tnQ9#qqa%7j!7W};$U*z4oAJEjd6|Yg) z`nKK@*0v+^R%DmYIr!U-{1I>4PJjjA6X-ASwop4-2TEeTr|63SuPFKvKp{kc z3`+ru61}STDrZQ*`TutXhJUp!Ff$^&#E$XiPqQon^Vy)WBBnRP-KzM-=@Qz#EFP)pr#A z2w=ao+CULqCQUVvfG$PZ>ivp-13(4WKmvGZLd0vJ;HHXP8bZM}P;l!twH@FlMJdA< z6@3ZdXNrCRz_;2^nPEm=I;A2&S}{c9P7^@{? z(}mdDdVs4HB?~`Plq~#G(U65&l66$bsL`fl7&ORz}Qxjie(NWw~|8D&aEL?TS=DcVW9GNp`yp|jd*o@^GqqM zBZXzsYF$WH9m%>x2&f|g>}eFEQPn6)I=U1M38F+1hzHKC6|DyB5Zf+#ucS~v`<@u>Nsi$)Qvl={qPH zCWjJg1mE(x6@OJ0O_W86klaL|N_17&TTNv8G0i~smIzNx1ln;|kqxE2iGZ|6ysI7s zctX&orva3UCd&mfgiJJ9CXgEP&}4Z)YRE#9GJyBuK#S5{Lkhnp6xOgGUQ(1D@UEi2 z0Qj{*A%7kr6Y*-orfS0aYi#|qkl!dqD;prQkY+1&({xWOxiMo&t1U;mj3v_as3$Nf znjY;AC{0f#x7F5#)KD;6DUDy@i&TObx-sG<2uLwfDHu98pakuLCT; z3aEB|{kHs@EvuLmBxnewrsXyN&UaI+$%?w{4@vuC5%zG+j^PKikG4a;>Cb8AL5oWr@qd!!umQp!}>a%`Z}HZ zI-UAD-TKUUIUfw~6Q&z^WD`{bqB;n0m!Jt-FUxB zBqTt#>jiDv1fYJZi4sr>>j;#>CK|bVBymIRe-P<**Jp+9#4ka2fzaLfvw-eI=w*WO z8*&fnPK0!e`&74|2z>`9|jiZ2mx-exes#D?y3z1SIbs^i7%p? z#i(E9QcDSZMHmc%O-H|bmWBG=WBGzD^w@fdzk*7Qz4VZB%8TiiNT^-{Z4)Tw!T%ULnkaX%&I;haK{I5_a=Oybm84bTecB*`t>fs*92|4AK)8`+KhJw zNj1E)K!oh5qy#n3i8v*aQ7US}u61-PP@T(AleXT(xzB6(V(t-=8B9Z-#vLjb^u`kO z0xo|lNwoxT30gz&k*3;=FXM8r5SE~Y8oyxgzJa?(r9fcl>>mwYw$b6PlCs-EeckpE zQdC{Gu|KFXaIaKHHH~0i>h$#9C8jE9!d_b!aaKnCBW`OWZmT11iS0!l>J9_1u?k7; z_@a9WZWpxaUV!HnwPi_*nU~&zJBQ?M4Z&r?V1p$pb1GQ~(nuasN!@xy+W~G;lyrVW zQM!v46@3ZdXNp<^iqVu(+SC&e5cKe4NcuIt5pPRK$d<76Eo@zVz!o;Cu4#*{{Am>B z;fXM2f>#8sA$V6)ZN~58@*PPEoCYOh#+w&$XO)P<@vH8fiv-OPz5;d0?Q__zBfZO4 zP?XezOiK`lmFd!CZ8(p1Wr1l{cRmOwjB;L%*XQ7rdt;tqi65j1c+1s^gR`ESW zZAL;^0SLRAz^q5jBD_m(UAF)r_$&oB+IrLy+&ATlY@vBTXuYuEO#r;@m@`Z0-TLru z;Ka@e?ly#X1KqhCcT-Yb?ezd(Q51jWLsMZzu#i0fdlkJCKuHKp2`Ta+a~I*8i$O<5 z3z3Cuc7#8H*kP!Pfd-!#uv}Fz6W8o+2YgfT>z4l-FoC{89m}r<{0WqT`1^o8TKDps z08Kl=n%#DkYt=gT-URrj!5PAu`t~-4_3d@)+w0UvnaF1W{@#xKm~FlUR@b3Cnh$ILYo1-(s5WS94eNr>L2|!|ymtd2ijRgBNl}%}ATPICPt96tCqaV~u zpmtnG4nC07x+q9060+(z!jm5~!GZpMMbWN&X5sH^($qFiiOfo5$l$h+!N7I@1ZCdD z7nZsZWiFQDwU+}_C|U)eT-CD27*HcGE7hT>wh&aV5lU-Wf4ib|-{cH=7l6uzLTO;l z4+pJowJL#`EbH%;`f(_?X!}=4f|9YuE z!TM(jc?s5kK+#(Pl;{MT`lY5){^tn&iBRZ)SA7W0JSI&w5WFI2Bf*=3Hjn_7WdlLA z5YR}VVr?KvKC3J4J7M&MMJV0NEYdVvJfm0w1L97T~i4j(p0o7AG&}y@x}6Q zD2#fx`mnTG9}2rZ6n1?m?D|mHfu~}bSMY_mp#sbiN^9x?8WoizgB5)U;3-9)26$G{ z=KxgLfoHl1^r!}ICwY2zI~k>OhL88j|-Y0(AGD< z1oSmY-5hr6X7+8B)SuwgP@CF(KTs89;t0^ECBtTd*91+x4xqFIy6_YPvQFx6tN~D3 z8utLDIiSyO0eDbR9+j+QH9iAWh0^#uP-R>CS7~XyH)yKSvi%U6qTn$>A($m-q5@!( zrtSsMR-33l_iO5-08c9VJpgUB=>?#SAy65`qXaZjMDv8#CYrE{sEI(yN*n^JB5EQ~ z5hVyzEkoA=_9 zi(e1`$6c-Qs<6hZ!Wyp%YYc|r>rv(&DIVC`ZMalsn!{?E!)lttYML!GkD|=$QcVz3 zJ%&qN#1951E`#dRlc2HhA?Xb%80a(^Tm#{N$#sE@wuYo^4N2J=k`fG7zd-S`q~(o#tZ+U4cm%%nxQ{H!F^5~y(NLsIHPQtCre0$08gWwuK3pxujbsk78A zR(9V2DJt*Qu;$jV=GL(0R$Jy>RI>&ejUa#-P55u`UWPlQRcs6ks5YJc%#_-MM74oh zdYDJ?MO`){AzDC^8_ds}iX{F30|Lv1%wj)9Kyn4D3}6|k76Y1ci-F4LBK-X+zL@vE z4WJ9<+o&{4gs*MO0W>(XezUxjb~}OcSVQnNO(jqsYY4utsRYVnO~~VRuqGdlkILhgkjE|LQMuU?aw#{?7kR14FDS}Uu1u7=aXY|H zMGpYnq9|3JVGWA`D6x$sRt-R6s(R_0#$JG16eSBUD>@5wm*9&UJ`1o)(Jp{~Mad(r z1Q}iiP_=C&yT8`d`RJERq;DFzT>P@4>@ju~id_Uyq39-nLyA5Opyn0?Xe&|VdJ#<% zrS!ImGpm

KwaQwil$H)+f1OMsUf&s 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 diff --git a/slsDetectorServers/mythen3DetectorServer/programfpga.h b/slsDetectorServers/mythen3DetectorServer/programfpga.h deleted file mode 120000 index 72c54d21d..000000000 --- a/slsDetectorServers/mythen3DetectorServer/programfpga.h +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServer/programfpga.h \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c deleted file mode 100644 index b31416c6a..000000000 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c +++ /dev/null @@ -1,1304 +0,0 @@ -//#ifdef SLS_DETECTOR_FUNCTION_LIST - - -#include "slsDetectorFunctionList.h" -#include "gitInfoMythen3.h" - - -#include "AD9257.h" // include "commonServerFunctions.h", which in turn includes "blackfin.h" -#include "programfpga.h" -#include "RegisterDefs.h" - -/* global variables */ -sls_detector_module *detectorModules=NULL; -int *detectorChips=NULL; -int *detectorChans=NULL; -dacs_t *detectorDacs=NULL; -dacs_t *detectorAdcs=NULL; - -enum detectorSettings thisSettings; -enum masterFlags masterMode = NO_MASTER; -int32_t clkPhase[2] = {0, 0}; -int vlimit = -1; - - - -/* basic tests */ - -void checkFirmwareCompatibility(int flag) { - - defineGPIOpins(); - resetFPGA(); - if (mapCSP0() == FAIL) { - cprintf(BG_RED, "Dangerous to continue. Goodbye!\n"); - exit(EXIT_FAILURE); - } - - // does check only if flag is 0 (by default), set by command line - if ((!flag) && ((checkType() == FAIL) || (testFpga() == FAIL) || (testBus() == FAIL))) { - cprintf(BG_RED, "Dangerous to continue. Goodbye!\n"); - exit(EXIT_FAILURE); - } - - uint32_t ipadd = getDetectorIP(); - uint64_t macadd = getDetectorMAC(); - int64_t fwversion = getDetectorId(DETECTOR_FIRMWARE_VERSION); - int64_t swversion = getDetectorId(DETECTOR_SOFTWARE_VERSION); - //int64_t sw_fw_apiversion = getDetectorId(SOFTWARE_FIRMWARE_API_VERSION); - cprintf(BLUE,"\n\n" - "********************************************************\n" - "****************** Mythen3 Server *********************\n" - "********************************************************\n\n" - - "Detector IP Addr:\t\t 0x%x\n" - "Detector MAC Addr:\t\t 0x%llx\n" - - "Firmware Version:\t\t 0x%llx\n" - "Software Version:\t\t 0x%llx\n" - //"F/w-S/w API Version:\t\t 0x%llx\n" - //"Required Firmware Version:\t 0x%x\n" - "\n" - "********************************************************\n", - hversion, hsnumber, - ipadd, macadd, - fwversion, swversion - //, sw_fw_apiversion, REQUIRED_FIRMWARE_VERSION - ); - - -/* - * printf("Testing firmware capability... "); - //cant read versions - if(!fwversion || !sw_fw_apiversion){ - cprintf(RED,"FATAL ERROR: Cant read versions from FPGA. Please update firmware\n"); - cprintf(RED,"Exiting Server. Goodbye!\n\n"); - exit(-1); - } - - //check for API compatibility - old server - if(sw_fw_apiversion > REQUIRED_FIRMWARE_VERSION){ - cprintf(RED,"FATAL ERROR: This software version is incompatible.\n" - "Please update it to be compatible with this firmware\n\n"); - cprintf(RED,"Exiting Server. Goodbye!\n\n"); - exit(-1); - } - - //check for firmware compatibility - old firmware - if( REQUIRED_FIRMWARE_VERSION > fwversion){ - cprintf(RED,"FATAL ERROR: This firmware version is incompatible.\n" - "Please update it to v%d to be compatible with this server\n\n", REQUIRED_FIRMWARE_VERSION); - cprintf(RED,"Exiting Server. Goodbye!\n\n"); - exit(-1); - } -*/ -} - - -int checkType() { - volatile u_int32_t type = ((bus_r(FPGA_VERSION_REG) & DETECTOR_TYPE_MSK) >> DETECTOR_TYPE_OFST); - if (type != JUNGFRAUCTB){ - cprintf(BG_RED,"This is not a Mythen 3 Server (read %d, expected %d)\n",type, JUNGFRAUCTB); - return FAIL; - } - - return OK; -} - - - -u_int32_t testFpga(void) { - printf("\nTesting FPGA...\n"); - - //fixed pattern - int ret = OK; - volatile u_int32_t val = bus_r(FIX_PATT_REG); - if (val == FIX_PATT_VAL) { - printf("Fixed pattern: successful match 0x%08x\n",val); - } else { - cprintf(RED,"Fixed pattern does not match! Read 0x%08x, expected 0x%08x\n", val, FIX_PATT_VAL); - ret = FAIL; - } - return ret; -} - - -int testBus() { - printf("\nTesting Bus...\n"); - - int ret = OK; - u_int32_t addr = SET_DELAY_LSB_REG; - int times = 1000 * 1000; - int i = 0; - - for (i = 0; i < times; ++i) { - bus_w(addr, i * 100); - if (i * 100 != bus_r(SET_DELAY_LSB_REG)) { - cprintf(RED,"ERROR: Mismatch! Wrote 0x%x, read 0x%x\n", i * 100, bus_r(SET_DELAY_LSB_REG)); - ret = FAIL; - } - } - - if (ret == OK) - printf("Successfully tested bus %d times\n", times); - return ret; -} - - - - -int detectorTest( enum digitalTestMode arg){ - switch(arg){ - case DETECTOR_FIRMWARE_TEST: return testFpga(); - case DETECTOR_BUS_TEST: return testBus(); - default: - cprintf(RED,"Warning: Test not implemented for this detector %d\n", (int)arg); - break; - } - return OK; -} - - - - - -/* Ids */ - -int64_t getDetectorId(enum idMode arg){ - int64_t retval = -1; - - switch(arg){ - case DETECTOR_SERIAL_NUMBER: - retval = getDetectorMAC(); - break; - case DETECTOR_FIRMWARE_VERSION: - retval = getFirmwareVersion(); - break; - //case SOFTWARE_FIRMWARE_API_VERSION: - //return GetFirmwareSoftwareAPIVersion(); - case DETECTOR_SOFTWARE_VERSION: - retval= GITREV; - retval= (retval <<32) | GITDATE; - break; - default: - break; - } - - return retval; -} - -u_int64_t getFirmwareVersion() { - return ((bus_r(FPGA_VERSION_REG) & BOARD_REVISION_MSK) >> BOARD_REVISION_OFST); -} - - - -u_int64_t getDetectorMAC() { - char output[255],mac[255]=""; - u_int64_t res=0; - FILE* sysFile = popen("ifconfig eth0 | grep HWaddr | cut -d \" \" -f 11", "r"); - fgets(output, sizeof(output), sysFile); - pclose(sysFile); - //getting rid of ":" - char * pch; - pch = strtok (output,":"); - while (pch != NULL){ - strcat(mac,pch); - pch = strtok (NULL, ":"); - } - sscanf(mac,"%llx",&res); - return res; -} - -u_int32_t getDetectorIP(){ - char temp[50]=""; - u_int32_t res=0; - //execute and get address - char output[255]; - FILE* sysFile = popen("ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2", "r"); - fgets(output, sizeof(output), sysFile); - pclose(sysFile); - - //converting IPaddress to hex. - char* pcword = strtok (output,"."); - while (pcword != NULL) { - sprintf(output,"%02x",atoi(pcword)); - strcat(temp,output); - pcword = strtok (NULL, "."); - } - strcpy(output,temp); - sscanf(output, "%x", &res); - //printf("ip:%x\n",res); - - return res; -} - - - - - - - - -/* initialization */ - -void initControlServer(){ - clkPhase[0] = 0; clkPhase[1] = 0; - setupDetector(); - printf("\n"); -} - - - -void initStopServer() { - - usleep(CTRL_SRVR_INIT_TIME_US); - if (mapCSP0() == FAIL) { - cprintf(BG_RED, "Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"); - exit(EXIT_FAILURE); - } -} - - - - - - -/* set up detector */ - -void allocateDetectorStructureMemory(){ - printf("This Server is for 1 Jungfrau module (500k)\n"); - - //Allocation of memory - if (detectorModules!=NULL) free(detectorModules); - if (detectorChans!=NULL) free(detectorChans); - if (detectorChips!=NULL) free(detectorChips); - if (detectorDacs!=NULL) free(detectorDacs); - if (detectorAdcs!=NULL) free(detectorAdcs); - detectorModules=malloc(sizeof(sls_detector_module)); - detectorChips=malloc(NCHIP*sizeof(int)); - detectorChans=malloc(NCHIP*NCHAN*sizeof(int)); - detectorDacs=malloc(NDAC*sizeof(dacs_t)); - detectorAdcs=malloc(NADC*sizeof(dacs_t)); -#ifdef VERBOSE - printf("modules from 0x%x to 0x%x\n",detectorModules, detectorModules+n); - printf("dacs from 0x%x to 0x%x\n",detectorDacs, detectorDacs+n*NDAC); - printf("adcs from 0x%x to 0x%x\n",detectorAdcs, detectorAdcs+n*NADC); -#endif - (detectorModules)->dacs=detectorDacs; - (detectorModules)->adcs=detectorAdcs; - (detectorModules)->ndac=NDAC; - (detectorModules)->nadc=NADC; - (detectorModules)->nchip=NCHIP; - (detectorModules)->nchan=NCHIP*NCHAN; - (detectorModules)->module=0; - (detectorModules)->gain=0; - (detectorModules)->offset=0; - (detectorModules)->reg=0; - thisSettings = UNINITIALIZED; - - // if trimval requested, should return -1 to acknowledge unknown - int ichan=0; - for (ichan=0; ichan<(detectorModules->nchan); ichan++) { - *((detectorModules->chanregs)+ichan) = -1; - } -} - - - -void setupDetector() { - - allocateDetectorStructureMemory(); - - resetPLL(); - resetCore(); - resetPeripheral(); - cleanFifos(); - - //initialize dac series - initDac(0); - initDac(8); - initDac(16); - - //set dacs - printf("Setting Default Dac values\n"); - { - int i = 0; - int retval[2]={-1,-1}; - const int defaultvals[NDAC] = DEFAULT_DAC_VALS; - for(i = 0; i < NDAC; ++i) { - setDAC((enum DACINDEX)i,defaultvals[i],0,0,retval); - if (retval[0] != defaultvals[i]) - cprintf(RED, "Warning: Setting dac %d failed, wrote %d, read %d\n",i ,defaultvals[i], retval[0]); - } - } - - /*setSamples(1); - bus_w(DAC_REG,0xffff); - setSpeed - cleanFifos(); /* todo might work without - resetCore(); /* todo might work without */ - - //Initialization of acquistion parameters - setTimer(FRAME_NUMBER, DEFAULT_NUM_FRAMES); - setTimer(CYCLES_NUMBER, DEFAULT_NUM_CYCLES); - setTimer(ACQUISITION_TIME, DEFAULT_EXPTIME); - setTimer(FRAME_PERIOD, DEFAULT_PERIOD); - setTimer(DELAY_AFTER_TRIGGER, DEFAULT_DELAY); -} - - - - - - - -/* firmware functions (resets) */ - -int powerChip (int on){ - - /* set all the required voltages */ - return 0; -} - - -void cleanFifos() { printf("\nClearing Acquisition Fifos - Not doing anything\n"); - /* printf("\nClearing Acquisition Fifos\n"); - bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_ACQ_FIFO_CLR_MSK); - bus_w(CONTROL_REG, bus_r(CONTROL_REG) & ~CONTROL_ACQ_FIFO_CLR_MSK);*/ -} - -void resetCore() {printf("\nResetting Core - Not doing anything\n"); - /*printf("\nResetting Core\n"); - bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_CORE_RST_MSK); - bus_w(CONTROL_REG, bus_r(CONTROL_REG) & ~CONTROL_CORE_RST_MSK);*/ -} - -void resetPeripheral() {printf("\nResetting Peripheral - Not doing anything\n"); - /* printf("\nResetting Peripheral\n"); - bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_PERIPHERAL_RST_MSK); - bus_w(CONTROL_REG, bus_r(CONTROL_REG) & ~CONTROL_PERIPHERAL_RST_MSK);*/ -} - -int getPhase(int i) { - if (i>=0 && i<4) - return clkPhase[i]; - else - return -1; -} - - -int configurePhase(int val, int i) { /** compare with old jungfrau software and add in */ - - u_int32_t l=0x0c; - u_int32_t h=0x0d; - u_int32_t vv; - int32_t phase=0, inv=0; - - u_int32_t tot; - u_int32_t odd=1;//0; - - if (i<0 || i>3) - return -1; - - if (val>65535 || val<-65535) - return clkPhase[i]; - - resetPLL(); - - setPllReconfigReg(PLL_MODE_REG, 1, 0); - printf("phase in %d\n",clkPhase[1]); - - if (val>0) { - inv=0; - phase=val&0xffff; - } else { - inv=0; - val=-1*val; - phase=(~val)&0xffff; - } - - - vv=phase | (i<<16);// | (inv<<21); - - setPllReconfigReg(PLL_PHASE_SHIFT_REG,vv,0); - - clkPhase[i]=val; - return clkPhase[i]; -} - - - -int configureFrequency(int val, enum CLKINDEX i) { /** compare with old jungfrau software and add in */ - - - u_int32_t l=0x0c; - u_int32_t h=0x0d; - u_int32_t vv; - int32_t phase=0, inv=0; - - u_int32_t tot; - u_int32_t odd=1;//0; - printf("Want to configure frequency of counter %d to %d\n",i,val); - // printf("PLL reconfig reset\N"); bus_w(PLL_CNTRL_REG,(1<3) { - printf("wrong counter number %d\n",i); - return -1; - } - - if (val<=0) { - - printf("get value %d %d \n",i,clkDivider[i]); - return clkDivider[i]; - } - if (i==adc_clk_c){ - if (val>40) - { - printf("Too high frequency %d MHz for these ADCs!\n", val); - return clkDivider[i]; - } - } - - tot= PLL_VCO_FREQ_MHZ/val; - l=tot/2; - h=l; - if (tot>2*l) { - h=l+1; - odd=1; - } - else - { - odd=0; - } - - printf("Counter %d: Low is %d, High is %d\n",i, l,h); - - - vv= (i<<18)| (odd<<17) | l | (h<<8); - - printf("Counter %d, val: %08x\n", i, vv); - setPllReconfigReg(PLL_C_COUNTER_REG, vv,0); - - - usleep(10000); - - resetPLL(); - - clkDivider[i]=PLL_VCO_FREQ_MHZ/(l+h); - - printf("Frequency of clock %d is %d\n", i, clkDivider[i]); - - return clkDivider[i]; -} - - - - - - - - -/* set parameters - nmod, dr, roi */ - -int setNMod(int nm, enum dimension dim){ - return NMOD; -} - - -int getNModBoard(enum dimension arg){ - return NMAXMOD; -} - - -int setDynamicRange(int dr){ - /* edit functionality */ - return 16; -} - - - - -/* parameters - readout */ - -int setSpeed(enum speedVariable arg, int val) { - int retval = -1; - - switch (arg) { - case DBIT_PHASE: - if (val==-1) - retval=getPhase(DBIT_CLK_C); - else - retval=configurePhase(val,DBIT_CLK_C); - break; - case DBIT_CLOCK: - retval=configureFrequency(val,DBIT_CLK_C); - if (configureFrequency(-1,SYNC_CLK_C)>retval){ - configureFrequency(retval,SYNC_CLK_C); - printf("--Configuring sync clk to %d MHz\n",val); - } else if (configureFrequency(-1,ADC_CLK_C)>retval && configureFrequency(-1,RUN_CLK_C)>retval) { - printf("++Configuring sync clk to %d MHz\n",val); - configureFrequency(retval,SYNC_CLK_C); - } - break; - default: - sprintf(mess,"Unknown speed parameter %d",arg); - break; - } - return retval; -} - - - - - - -/* parameters - timer */ - -int64_t setTimer(enum timerIndex ind, int64_t val) { - - int64_t retval = -1; - switch(ind){ - - case FRAME_NUMBER: - if(val >= 0) - printf("\nSetting #frames: %lld\n",(long long int)val); - retval = set64BitReg(val, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG); - printf("Getting #frames: %lld\n",(long long int)retval); - break; - - case ACQUISITION_TIME: - if(val >= 0){ - printf("\nSetting exptime: %lldns\n", (long long int)val); - val *= (1E-3 * CLK_RUN); /* ?? */ - } - retval = set64BitReg(val, SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG) / (1E-3 * CLK_RUN); - printf("Getting exptime: %lldns\n", (long long int)retval); - break; - - case FRAME_PERIOD: - if(val >= 0){ - printf("\nSetting period to %lldns\n",(long long int)val); - val *= (1E-3 * CLK_SYNC); /* ?? */ - } - retval = set64BitReg(val, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG )/ (1E-3 * CLK_SYNC); - printf("Getting period: %lldns\n", (long long int)retval); - break; - - case DELAY_AFTER_TRIGGER: - if(val >= 0){ - printf("\nSetting delay to %lldns\n", (long long int)val); - val *= (1E-3 * CLK_SYNC); /* ?? */ - } - retval = set64BitReg(val, SET_DELAY_LSB_REG, SET_DELAY_MSB_REG) / (1E-3 * CLK_SYNC); - printf("Getting delay: %lldns\n", (long long int)retval); - break; - - case CYCLES_NUMBER: - if(val >= 0) - printf("\nSetting #cycles to %lld\n", (long long int)val); - retval = set64BitReg(val, SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG); - printf("Getting #cycles: %lld\n", (long long int)retval); - break; - - case GATES_NUMBER: - if(val >= 0) - printf("\nSetting #gates to %lld\n", (long long int)val); - retval = set64BitReg(val, SET_GATES_LSB_REG, SET_GATES_MSB_REG); - printf("Getting #gates: %lld\n", (long long int)retval); - break; - - case PROBES_NUMBER: /* does not exist in firmware_funcs.c*/ - /*if(val >= 0) - printf("\nSetting #probes to %lld\n", (long long int)val); - retval = set64BitReg(val, SET_PROBES_LSB_REG, SET_PROBES_MSB_REG); - printf("Getting #probes: %lld\n", (long long int)retval); - */ - break; - - case SAMPLES_JCTB: - if(val >= 0) - printf("\nSetting #samples to %lld\n", (long long int)val); - retval = bus_w(NSAMPLES_REG, val); - printf("Getting #samples: %lld\n", (long long int)retval); - - break; - - default: - cprintf(RED,"Warning: Timer Index not implemented for this detector: %d\n", ind); - break; - } - - return retval; - -} - - - -int64_t getTimeLeft(enum timerIndex ind){ - int64_t retval = -1; - switch(ind){ - - case FRAME_NUMBER: - retval = get64BitReg(GET_FRAMES_LSB_REG, GET_FRAMES_MSB_REG); - printf("Getting number of frames left: %lld\n",(long long int)retval); - break; - - case FRAME_PERIOD: - retval = get64BitReg(GET_PERIOD_LSB_REG, GET_PERIOD_MSB_REG) / (1E-3 * CLK_SYNC); - printf("Getting period left: %lldns\n", (long long int)retval); - break; - - case DELAY_AFTER_TRIGGER: - retval = get64BitReg(GET_DELAY_LSB_REG, GET_DELAY_MSB_REG) / (1E-3 * CLK_SYNC); - printf("Getting delay left: %lldns\n", (long long int)retval); - break; - - /** acquisition time and period gives in time left in func.c, pls check with anna */ - - case CYCLES_NUMBER: - retval = get64BitReg(GET_CYCLES_LSB_REG, GET_CYCLES_MSB_REG); - printf("Getting number of cycles left: %lld\n", (long long int)retval); - break; - - case ACTUAL_TIME: - retval = get64BitReg(GET_ACTUAL_TIME_LSB_REG, GET_ACTUAL_TIME_MSB_REG) / (1E-9 * CLK_SYNC); - printf("Getting actual time (time from start): %lld\n", (long long int)retval); - break; - - case MEASUREMENT_TIME: - retval = get64BitReg(GET_MEASUREMENT_TIME_LSB_REG, GET_MEASUREMENT_TIME_MSB_REG) / (1E-9 * CLK_SYNC); - printf("Getting measurement time (timestamp/ start frame time): %lld\n", (long long int)retval); - break; - - case FRAMES_FROM_START: - retval = get64BitReg(FRAMES_FROM_START_LSB_REG, FRAMES_FROM_START_MSB_REG); - printf("Getting frames from start run control %lld\n", (long long int)retval); - break; - - case FRAMES_FROM_START_PG: /** ask anna, seems to be calling previous function (frames_from_start) */ - retval = get64BitReg(FRAMES_FROM_START_PG_LSB_REG, FRAMES_FROM_START_PG_MSB_REG); - printf("Getting frames from start run control %lld\n", (long long int)retval); - break; - - default: - cprintf(RED, "Warning: Remaining Timer index not implemented for this detector: %d\n", ind); - break; - } - - return retval; -} - - - - - - -/* parameters - channel, chip, module, settings */ - - -int setModule(sls_detector_module myMod){ - return thisSettings; -} - - -int getModule(sls_detector_module *myMod){ - return OK; -} - - - -enum detectorSettings setSettings(enum detectorSettings sett, int imod){ - return getSettings(); - -} - - -enum detectorSettings getSettings(){ - return thisSettings; -} - - - - - -/* parameters - dac, adc, hv */ - - - - - - -void initDac(int dacnum) { - printf("\nInitializing dac for %d to \n",dacnum); - - u_int32_t codata; - int csdx = dacnum / NDAC_PER_SET + DAC_SERIAL_CS_OUT_OFST; //,so can be DAC_SERIAL_CS_OUT_OFST or +1 - int dacchannel = 0xf; // all channels - int dacvalue = 0x6; // can be any random value (just writing to power up) - printf(" Write to Input Register\n" - " Chip select bit:%d\n" - " Dac Channel:0x%x\n" - " Dac Value:0x%x\n", - csdx, dacchannel, dacvalue); - - codata = LTC2620_DAC_CMD_WRITE + // command to write to input register - ((dacchannel << LTC2620_DAC_ADDR_OFST) & LTC2620_DAC_ADDR_MSK) + // all channels - ((dacvalue << LTC2620_DAC_DATA_OFST) & LTC2620_DAC_DATA_MSK); // any random value - serializeToSPI(SPI_REG, codata, (0x1 << csdx), LTC2620_DAC_NUMBITS, - DAC_SERIAL_CLK_OUT_MSK, DAC_SERIAL_DIGITAL_OUT_MSK, DAC_SERIAL_DIGITAL_OUT_OFST); -} - - - - - - - - - -int voltageToDac(int value){ - int vmin = 0; - int vmax = MAX_DACVOLTVAL; - int nsteps = MAX_DACVAL; - if ((value < vmin) || (value > vmax)) { - cprintf(RED,"Voltage value (to convert to dac value) is outside bounds: %d\n", value); - return -1; - } - return (int)(((value - vmin) / (vmax - vmin)) * (nsteps - 1) + 0.5); -} - -int dacToVoltage(unsigned int digital){ - int vmin = 0; - int vmax = MAX_DACVOLTVAL; - int nsteps = MAX_DACVAL; - int v = vmin + (vmax - vmin) * digital / (nsteps - 1); - if((v < 0) || (v > nsteps - 1)) { - cprintf(RED,"Voltage value (converted from dac value) is outside bounds: %d\n", v); - return -1; - } - return v; -} - -int powerToDac(int value, int chip) { - int nsteps = MAX_DACVAL; - int vchip = MAX_VCHIPVAL - (getDacRegister(V_CHIP)*1000)/(nsteps -1); - printf("Current V_Chip: %d mV\n",vchip); - - int vmax = vchip - MIN_VCHIP_OFSTVAL; - int vmin = MIN_VCHIP_VAL; - - // recalculating only for v_chip - if (chip) { - printf("vchip\n"); - vmax = MAX_VCHIPVAL; - vmin = MAX_VCHIPVAL - 1000; - } - else - printf("vpower\n"); - - int v = (int)(((vmax - value) * (nsteps - 1) / (vmax - vmin)) ); /***+0.5 removed is this correct? seems different from voltageToDac maybe get rid of 0.5*/ - - - if (v < 0) v = 0; - if (v > nsteps - 1) v = nsteps - 1; - if (value == -100) v = -100; - - return v; -} - -int dacToPower(int value, int chip) { - int retval1 = -1; - int nsteps = MAX_DACVAL; - int vchip = MAX_VCHIPVAL - (getDacRegister(V_CHIP)*1000)/(nsteps -1); - printf("Vchip id %d mV\n",vmax); - int vmax = vchip - MIN_VCHIP_OFSTVAL; - int vmin = MIN_VCHIP_VAL; - - // recalculating only for v_chip - if (chip) { - printf("vchip\n"); - vmax = MAX_VCHIPVAL; - vmin = MAX_VCHIPVAL - 1000; - } - else - printf("vpower\n"); - - retval1 = vmax - (value * (vmax - vmin)) / (nsteps - 1); - if (retval1 > vmax) retval1 = vmax; - if (retval1 < vmin) retval1 = vmin; - if (value < 0) retval1 = value; - return retval1; -} - - - -void setDAC(enum DACINDEX ind, int val, int imod, int mV, int retval[]){ - - int dacval = val; - - // dacs: if set and mv, convert to dac - if (ind < val > 0 && mV) { - val = voltageToDac(val); //gives -1 on error - } - - - if ( (val >= 0) || (val == -100)) { - - - u_int32_t ichip = 2 - ind / NDAC_PER_SET; - u_int32_t valw = 0; - int i; - - // start and chip select bar down ----------------- - SPIChipSelect (&valw, SPI_REG, (0x1 << csdx)); - - - // next dac -------------------------------------- - for (i = 0; i < ichip; ++i) { - printf("%d next DAC\n", i); - sendDataToSPI (&valw, SPI_REG, LTC2620_DAC_CMD_MSK, LTC2620_DAC_NUMBITS, - DAC_SERIAL_CLK_OUT_MSK, DAC_SERIAL_DIGITAL_OUT_MSK, DAC_SERIAL_DIGITAL_OUT_OFST); - } - - - // this dac ---------------------------------------- - u_int32_t codata; - int csdx = DAC_SERIAL_CS_OUT_OFST; - int dacchannel = ind % NDAC_PER_SET; - - printf("\nSetting of DAC %d : %d dac units (%d mV)\n",ind, dacval, val); - // command - if (val >= 0) { - printf(" Write to Input Register and Update\n"); - codata = LTC2620_DAC_CMD_SET; - - } else if (val == -100) { - printf(" POWER DOWN\n"); - codata = LTC2620_DAC_CMD_POWER_DOWN; - } - // address - printf(" Chip select bit:%d\n" - " Dac Channel:0x%x\n" - " Dac Value:0x%x\n", - csdx, dacchannel, val); - codata += ((dacchannel << LTC2620_DAC_ADDR_OFST) & LTC2620_DAC_ADDR_MSK) + - ((val << LTC2620_DAC_DATA_OFST) & LTC2620_DAC_DATA_MSK); - // to spi - serializeToSPI(SPI_REG, codata, (0x1 << csdx), LTC2620_DAC_NUMBITS, - DAC_SERIAL_CLK_OUT_MSK, DAC_SERIAL_DIGITAL_OUT_MSK, DAC_SERIAL_DIGITAL_OUT_OFST); - - - printf("--------done setting dac set %d \n",i); - - // next dac ----------------------------------------------------------- - for (i = ichip+1; i < (N_DAC / NDAC_PER_SET); ++i) { - printf("%d next DAC\n", i); - sendDataToSPI (&valw, SPI_REG, LTC2620_DAC_CMD_MSK, LTC2620_DAC_NUMBITS, - DAC_SERIAL_CLK_OUT_MSK, DAC_SERIAL_DIGITAL_OUT_MSK, DAC_SERIAL_DIGITAL_OUT_OFST); - } - - - //chip select bar up, clk down and stop -------------------------------- - SPIChipDeselect (&valw, SPI_REG, (0x1 << csdx), DAC_SERIAL_CLK_OUT_MSK); - - // writes to register - setDacRegister(ind, dacval); - } - - // reading dac value from register - printf("Getting DAC %d : ",ind); - retval[0] = getDacRegister(ind); printf("%d dac units ", retval[0]); - retval[1] = dacToVoltage(retval[0]);printf("(%d mV)\n", retval[1]); -} - - -int setPower(enum DACINDEX ind, int val) { - - // not implemented yet - if ((ind == V_D) || (ind == V_C)) - return -1; - - // vlimit software limit - else if (ind == V_LIMIT) { - if (val >= 0) - vlimit = val; - return vlimit; - } - - int pwrindex = -1; - int dacval = val; - int retval=-1, retval1=-1; - u_int32_t preg = 0; - int temp[2] = {-1,-1}; - - // get - if (val == -1) - dacval = -1; - - // vchip - else if (ind == V_CHIP) - dacval = powerToDac(val, 1); - - // power a, b, c , d, io - else { - dacval = powerToDac(val, 0); - - switch (ind) { - case V_IO: pwrindex = 0;break; - case V_A: pwrindex = 1; break; - case V_B: pwrindex = 2; break; - default:break; - } - - // shut down - preg = bus_r(POWER_ON_REG); - printf("power reg is %08x\n",bus_r(POWER_ON_REG)); - printf("Switching off power %d\n", ind); - bus_w(POWER_ON_REG,preg &(~(1 << (POWER_ENABLE_OFST + pwrindex)))); - setDac(ind,-100, 0, 1, temp); - printf("power reg is %08x\n",bus_r(POWER_ON_REG)); - retval=0; - } - - // actual setting - if (val != -100) { - printf("Setting power %d to %d mV (%d dac val)\n",ind, val, dacval); - retval = setDac(ind, dacval); - // setting power a, b, c, d, io - if (pwrindex >= 0 && dacval >= 0 ) { - preg = bus_r(POWER_ON_REG); - printf("power reg is %08x\n", bus_r(POWER_ON_REG)); - printf("Switching on power %d\n", pwrindex); - bus_w(POWER_ON_REG, preg | ((1 << (POWER_ENABLE_OFST + pwrindex)))); - printf("power reg is %08x\n",bus_r(POWER_ON_REG)); - } - } - - if (pwrindex >= 0) { - if (bus_r(POWER_ON_REG) & (1 << (POWER_ENABLE_OFST + pwrindex))) { - retval1 = dacToPower(retval, 0); - printf("Vdac id %d mV\n",retval1); - } else - retval1 = 0; - } else { - if (retval >= 0) { - retval1 = dacToPower(retval, 1); - /*printf("Vchip is %d mV\n",vmax); makes no sense.. should be printing retval1??? */ - } else - retval1=-1; - } - - return retval1; -} - -int getVLimit() { - return vlimit; -} - -void setDacRegister(int dacnum,int dacvalue) { - bus_w(DAC_NUM_REG, dacnum); - bus_w(DAC_VAL_REG, dacvalue); - bus_w(DAC_NUM_REG, dacnum | (1<<16));/** super strange writing dac num in weird ways */ - bus_w(DAC_NUM_REG, dacnum); - printf("Wrote dac register value %d address %d\n",bus_r(DAC_VAL_REG),bus_r(DAC_NUM_REG)) ; -} - -int getDacRegister(int dacnum) {/** super strange, reading out in some other register than written */ - bus_w(DAC_NUM_REG, dacnum); - printf("READ dac register value %d address %d\n",(int16_t)bus_r(DAC_VAL_OUT_REG),bus_r(DAC_NUM_REG)) ; - return (int16_t)bus_r(DAC_VAL_OUT_REG); -} - - - - - -/* parameters - timing, extsig */ - - -enum externalCommunicationMode setTiming( enum externalCommunicationMode arg){ - return AUTO_TIMING; -} - - - - -/* jungfrau specific - pll, flashing fpga */ - - - -void resetPLL() { - // reset PLL Reconfiguration and PLL - bus_w(PLL_CONTROL_REG, bus_r(PLL_CONTROL_REG) | PLL_CTRL_RECONFIG_RST_MSK | PLL_CTRL_RST_MSK); - usleep(100); - bus_w(PLL_CONTROL_REG, bus_r(PLL_CONTROL_REG) & ~PLL_CTRL_RECONFIG_RST_MSK & ~PLL_CTRL_RST_MSK); -} - - -u_int32_t setPllReconfigReg(u_int32_t reg, u_int32_t val) { - - // set parameter - bus_w(PLL_PARAM_REG, val); - - // set address - bus_w(PLL_CONTROL_REG, (reg << PLL_CTRL_ADDR_OFST) & PLL_CTRL_ADDR_MSK); - usleep(10*1000); - - //write parameter - bus_w(PLL_CONTROL_REG, bus_r(PLL_CONTROL_REG) | PLL_CTRL_WR_PARAMETER_MSK); - bus_w(PLL_CONTROL_REG, bus_r(PLL_CONTROL_REG) & ~PLL_CTRL_WR_PARAMETER_MSK); - usleep(10*1000); - - return val; -} - - - - -void configurePll() { - u_int32_t val; - int32_t phase=0, inv=0; - - printf(" phase in %d\n", clkPhase[1]); - if (clkPhase[1]>0) { - inv=0; - phase=clkPhase[1]; - } else { - inv=1; - phase=-1*clkPhase[1]; - } - printf(" phase out %d (0x%08x)\n", phase, phase); - - if (inv) { - val = ((phase << PLL_SHIFT_NUM_SHIFTS_OFST) & PLL_SHIFT_NUM_SHIFTS_MSK) + PLL_SHIFT_CNT_SLCT_C1_VAL + PLL_SHIFT_UP_DOWN_NEG_VAL; - printf(" phase word 0x%08x\n", val); - setPllReconfigReg(PLL_PHASE_SHIFT_REG, val); - } else { - val = ((phase << PLL_SHIFT_NUM_SHIFTS_OFST) & PLL_SHIFT_NUM_SHIFTS_MSK) + PLL_SHIFT_CNT_SLCT_C0_VAL + PLL_SHIFT_UP_DOWN_NEG_VAL; - printf(" phase word 0x%08x\n", val); - setPllReconfigReg(PLL_PHASE_SHIFT_REG, val); - - printf(" phase word 0x%08x\n", val); - val = ((phase << PLL_SHIFT_NUM_SHIFTS_OFST) & PLL_SHIFT_NUM_SHIFTS_MSK) + PLL_SHIFT_CNT_SLCT_C2_VAL; - setPllReconfigReg(PLL_PHASE_SHIFT_REG, val); - } - usleep(10000); -} - - - - -/* aquisition */ - -int startStateMachine(){ - printf("*******Starting State Machine*******\n"); - - cleanFifos(); - - //start state machine - bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_START_ACQ_MSK); - bus_w(CONTROL_REG, bus_r(CONTROL_REG) & ~CONTROL_START_ACQ_MSK); - - printf("Status Register: %08x\n",bus_r(STATUS_REG)); - return OK; -} - - -int stopStateMachine(){ - cprintf(BG_RED,"*******Stopping State Machine*******\n"); - - //stop state machine - bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_STOP_ACQ_MSK); - usleep(100); - bus_w(CONTROL_REG, bus_r(CONTROL_REG) & ~CONTROL_STOP_ACQ_MSK); - - printf("Status Register: %08x\n",bus_r(STATUS_REG)); - return OK; -} - - - - - -enum runStatus getRunStatus(){ -#ifdef VERBOSE - printf("Getting status\n"); -#endif - - enum runStatus s; - u_int32_t retval = bus_r(STATUS_REG); - printf("Status Register: %08x\n",retval); - - //running - if(((retval & RUN_BUSY_MSK) >> RUN_BUSY_OFST)) { - if ((retval & WAITING_FOR_TRIGGER_MSK) >> WAITING_FOR_TRIGGER_OFST) { - printf("-----------------------------------WAITING-----------------------------------\n"); - s=WAITING; - } - else{ - printf("-----------------------------------RUNNING-----------------------------------\n"); - s=RUNNING; - } - } - - //not running - else { - if ((retval & STOPPED_MSK) >> STOPPED_OFST) { - printf("-----------------------------------STOPPED--------------------------\n"); - s=STOPPED; - } else if ((retval & RUNMACHINE_BUSY_MSK) >> RUNMACHINE_BUSY_OFST) { - printf("-----------------------------------READ MACHINE BUSY--------------------------\n"); - s=TRANSMITTING; - } else if (!retval) { - printf("-----------------------------------IDLE--------------------------------------\n"); - s=IDLE; - } else { - printf("-----------------------------------Unknown status %08x--------------------------------------\n", retval); - s=ERROR; - } - } - - return s; -} - - - -void readFrame(int *ret, char *mess){ - - // wait for status to be done - while(runBusy()){ - usleep(500); - } - - // frames left to give status - int64_t retval = getTimeLeft(FRAME_NUMBER) + 1; - if ( retval > 0) { - *ret = (int)FAIL; - sprintf(mess,"no data and run stopped: %lld frames left\n",retval); - cprintf(RED,"%s\n",mess); - } else { - *ret = (int)FINISHED; - sprintf(mess,"acquisition successfully finished\n"); - printf("%s",mess); - } -} - - - -u_int32_t runBusy(void) { - u_int32_t s = ((bus_r(STATUS_REG) & RUN_BUSY_MSK) >> RUN_BUSY_OFST); -#ifdef VERBOSE - printf("Status Register: %08x\n", s); -#endif - return s; -} - - - - - - - - -/* common */ - -//jungfrau doesnt require chips and chans (save memory) -int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod){ - - int idac, iadc; - int ret=OK; - -#ifdef VERBOSE - printf("Copying module %x to module %x\n",srcMod,destMod); -#endif - - if (srcMod->module>=0) { -#ifdef VERBOSE - printf("Copying module number %d to module number %d\n",srcMod->module,destMod->module); -#endif - destMod->module=srcMod->module; - } - if (srcMod->serialnumber>=0){ - - destMod->serialnumber=srcMod->serialnumber; - } - if ((srcMod->nchip)>(destMod->nchip)) { - printf("Number of chip of source is larger than number of chips of destination\n"); - return FAIL; - } - if ((srcMod->nchan)>(destMod->nchan)) { - printf("Number of channels of source is larger than number of channels of destination\n"); - return FAIL; - } - if ((srcMod->ndac)>(destMod->ndac)) { - printf("Number of dacs of source is larger than number of dacs of destination\n"); - return FAIL; - } - if ((srcMod->nadc)>(destMod->nadc)) { - printf("Number of dacs of source is larger than number of dacs of destination\n"); - return FAIL; - } - -#ifdef VERBOSE - printf("DACs: src %d, dest %d\n",srcMod->ndac,destMod->ndac); - printf("ADCs: src %d, dest %d\n",srcMod->nadc,destMod->nadc); - printf("Chips: src %d, dest %d\n",srcMod->nchip,destMod->nchip); - printf("Chans: src %d, dest %d\n",srcMod->nchan,destMod->nchan); - -#endif - destMod->ndac=srcMod->ndac; - destMod->nadc=srcMod->nadc; - destMod->nchip=srcMod->nchip; - destMod->nchan=srcMod->nchan; - if (srcMod->reg>=0) - destMod->reg=srcMod->reg; -#ifdef VERBOSE - printf("Copying register %x (%x)\n",destMod->reg,srcMod->reg ); -#endif - if (srcMod->gain>=0) - destMod->gain=srcMod->gain; - if (srcMod->offset>=0) - destMod->offset=srcMod->offset; - - for (idac=0; idac<(srcMod->ndac); idac++) { - if (*((srcMod->dacs)+idac)>=0) - *((destMod->dacs)+idac)=*((srcMod->dacs)+idac); - } - for (iadc=0; iadc<(srcMod->nadc); iadc++) { - if (*((srcMod->adcs)+iadc)>=0) - *((destMod->adcs)+iadc)=*((srcMod->adcs)+iadc); - } - return ret; -} - - -int calculateDataBytes(){ - return DATA_BYTES; -} - -int getTotalNumberOfChannels(){return ((int)getNumberOfChannelsPerModule() * (int)getTotalNumberOfModules());} -int getTotalNumberOfChips(){return ((int)getNumberOfChipsPerModule() * (int)getTotalNumberOfModules());} -int getTotalNumberOfModules(){return NMOD;} -int getNumberOfChannelsPerModule(){return ((int)getNumberOfChannelsPerChip() * (int)getTotalNumberOfChips());} -int getNumberOfChipsPerModule(){return NCHIP;} -int getNumberOfDACsPerModule(){return NDAC;} -int getNumberOfADCsPerModule(){return NADC;} -int getNumberOfChannelsPerChip(){return NCHAN;} - - - -/* sync */ - -enum masterFlags setMaster(enum masterFlags arg){ - return NO_MASTER; -} - -enum synchronizationMode setSynchronization(enum synchronizationMode arg){ - return NO_SYNCHRONIZATION; -} - - - - - - -//#endif diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.h b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.h deleted file mode 120000 index 345b8c029..000000000 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.h +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServer/slsDetectorFunctionList.h \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer.c b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer.c deleted file mode 120000 index a7eb59acb..000000000 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer.c +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServer/slsDetectorServer.c \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h deleted file mode 100644 index e638f840e..000000000 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * mythen3Server_defs.h - * - * Created on: Jan 24, 2013 - * Author: l_maliakal_d, changed my Marie A. - */ - -#ifndef SLSDETECTORSERVER_DEFS_H_ -#define SLSDETECTORSERVER_DEFS_H_ - -#include "sls_detector_defs.h" -#include - -/** This is only an example file!!! */ - - - -#define GOODBYE (-200) -enum DACINDEX {vIpre, vIbias, Vrf, VrfSh, vIinSh, VdcSh, Vth2, VPL, Vth1, Vth3, Vtrim, casSh, cas, vIbiasSh, vIcin, VPH, NC, vIpreOut, V_D, V_CHIP, V_C, V_B, V_A, V_IO, V_LIM}; // Mythen 3.01 -enum PWRINDEX {PWR_IO, PWR_A, PWR_B, PWR_C, PWR_D, PWR_CHIP=-1, PWR_LIMIT=-1}; -enum CLKINDEX {RUN_CLK_C, ADC_CLK_C, SYNC_CLK_C, DBIT_CLK_C}; - -#define DEFAULT_DAC_VALS { 2150, /* vIpre */ \ - 1200, /* vIbias */ \ - 900, /* Vrf */ \ - 1050, /* VrfSh */ \ - 1400, /* vIinSh */ \ - 655, /* VdcSh */ \ - 850, /* Vth2 */ \ - 1400, /* VPL */ \ - 850, /* Vth1 */ \ - 850, /* Vth3 */ \ - 2294, /* Vtrim */ \ - 983, /* casSh */ \ - 1474, /* cas */ \ - 1200, /* vIbiasSh */ \ - 1600, /* vIcin */ \ - 1520, /* VPH */ \ - 0, /* NC */ \ - 1000 /* vIpreOut */ \ - 0 /* V_D */ \ - 0 /* V_CHIP */ \ - 0 /* V_C */ \ - 1335 /* V_B */ \ - 1335 /* V_A */ \ - 1350 /* V_IO */ \ - }; - -#define DEFAULT_DAC_NAMES { "vIpre", \ - "vIbias", \ - "Vrf", \ - "VrfSh", \ - "vIinSh", \ - "VdcSh", \ - "Vth2", \ - "VPL", \ - "Vth1", \ - "Vth3", \ - "Vtrim", \ - "casSh", \ - "cas", \ - "vIbiasSh", \ - "vIcin", \ - "VPH", \ - "NC", \ - "vIpreOut" \ - "v_d" \ - "v_chip" \ - "v_c" \ - "v_b" \ - "v_a" \ - "v_io" \ - }; - -/*Hardware Definitions */ -#define NMAXMOD (1) -#define NMOD (1) -#define NCHAN (32) -#define NCHIP (1) -#define NADC (0) -#define NDAC (24) -#define NDAC_PER_SET (8) - - -#define NPWR (5) -#define MAX_DACVOLTVAL (2500) //mV -#define MAX_DACVAL (4096) // dac val -#define MAX_VCHIPVAL (2700) //mV /** name ???? */ -#define MIN_VCHIP_OFSTVAL (200) //mV /** name ???? */ -#define MIN_VCHIP_VAL (600) //mV /** name ???? */ - - -/** Default Parameters */ -#define DEFAULT_NUM_FRAMES (1) -#define DEFAULT_NUM_CYCLES (1) -#define DEFAULT_EXPTIME (200*1000) //ns -#define DEFAULT_PERIOD (1*1000*1000) //ns -#define DEFAULT_DELAY (0) -#define DEFAULT_HIGH_VOLTAGE (0) -#define DEFAULT_TIMING_MODE (AUTO_TIMING) - - -/* Defines in the Firmware */ -#define FIX_PATT_VAL (0xACDC1980) - -/* LTC2620 DAC DEFINES */ -#define LTC2620_DAC_CMD_OFST (20) -#define LTC2620_DAC_CMD_MSK (0x0000000F << LTC2620_DAC_CMD_OFST) -#define LTC2620_DAC_ADDR_OFST (16) -#define LTC2620_DAC_ADDR_MSK (0x0000000F << LTC2620_DAC_ADDR_OFST) -#define LTC2620_DAC_DATA_OFST (4) -#define LTC2620_DAC_DATA_MSK (0x00000FFF << LTC2620_DAC_DATA_OFST) - -#define LTC2620_DAC_CMD_WRITE (0x00000000 << LTC2620_DAC_CMD_OFST) -#define LTC2620_DAC_CMD_SET (0x00000003 << LTC2620_DAC_CMD_OFST) -#define LTC2620_DAC_CMD_POWER_DOWN (0x00000004 << LTC2620_DAC_CMD_OFST) -#define LTC2620_DAC_NUMBITS (24) - -/** PLL Reconfiguration Registers */ -//https://www.altera.com/documentation/mcn1424769382940.html -#define PLL_MODE_REG (0x00) -#define PLL_STATUS_REG (0x01) -#define PLL_START_REG (0x02) -#define PLL_N_COUNTER_REG (0x03) -#define PLL_M_COUNTER_REG (0x04) -#define PLL_C_COUNTER_REG (0x05) -#define PLL_PHASE_SHIFT_REG (0x06) - -#define PLL_SHIFT_NUM_SHIFTS_OFST (0) -#define PLL_SHIFT_NUM_SHIFTS_MSK (0x0000FFFF << PLL_SHIFT_NUM_SHIFTS_OFST) - -#define PLL_SHIFT_CNT_SELECT_OFST (16) -#define PLL_SHIFT_CNT_SELECT_MSK (0x0000001F << PLL_SHIFT_CNT_SELECT_OFST) -#define PLL_SHIFT_CNT_SLCT_C0_VAL ((0x0 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C1_VAL ((0x1 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C2_VAL ((0x2 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C3_VAL ((0x3 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C4_VAL ((0x4 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C5_VAL ((0x5 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C6_VAL ((0x6 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C7_VAL ((0x7 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C8_VAL ((0x8 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C9_VAL ((0x9 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C10_VAL ((0x10 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C11_VAL ((0x11 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C12_VAL ((0x12 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C13_VAL ((0x13 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C14_VAL ((0x14 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C15_VAL ((0x15 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C16_VAL ((0x16 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) -#define PLL_SHIFT_CNT_SLCT_C17_VAL ((0x17 << PLL_SHIFT_CNT_SELECT_OFST) & PLL_SHIFT_CNT_SELECT_MSK) - -#define PLL_SHIFT_UP_DOWN_OFST (21) -#define PLL_SHIFT_UP_DOWN_MSK (0x00000001 << PLL_SHIFT_UP_DOWN_OFST) -#define PLL_SHIFT_UP_DOWN_NEG_VAL ((0x0 << PLL_SHIFT_UP_DOWN_OFST) & PLL_SHIFT_UP_DOWN_MSK) -#define PLL_SHIFT_UP_DOWN_POS_VAL ((0x1 << PLL_SHIFT_UP_DOWN_OFST) & PLL_SHIFT_UP_DOWN_MSK) - -#define PLL_K_COUNTER_REG (0x07) -#define PLL_BANDWIDTH_REG (0x08) -#define PLL_CHARGEPUMP_REG (0x09) -#define PLL_VCO_DIV_REG (0x1c) -#define PLL_MIF_REG (0x1f) - -#define PLL_VCO_FREQ_MHZ 400 - - -#endif /* SLSDETECTORSERVER_DEFS_H_ */ diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_funcs.c b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_funcs.c deleted file mode 120000 index a7532ccd4..000000000 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_funcs.c +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServer/slsDetectorServer_funcs.c \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_funcs.h b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_funcs.h deleted file mode 120000 index 7569daf47..000000000 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_funcs.h +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorServer/slsDetectorServer_funcs.h \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/sls_detector_defs.h b/slsDetectorServers/mythen3DetectorServer/sls_detector_defs.h deleted file mode 120000 index c5062e03f..000000000 --- a/slsDetectorServers/mythen3DetectorServer/sls_detector_defs.h +++ /dev/null @@ -1 +0,0 @@ -../commonFiles/sls_detector_defs.h \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/sls_detector_funcs.h b/slsDetectorServers/mythen3DetectorServer/sls_detector_funcs.h deleted file mode 120000 index 844b67129..000000000 --- a/slsDetectorServers/mythen3DetectorServer/sls_detector_funcs.h +++ /dev/null @@ -1 +0,0 @@ -../commonFiles/sls_detector_funcs.h \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/sls_receiver_defs.h b/slsDetectorServers/mythen3DetectorServer/sls_receiver_defs.h deleted file mode 120000 index 1de31caf5..000000000 --- a/slsDetectorServers/mythen3DetectorServer/sls_receiver_defs.h +++ /dev/null @@ -1 +0,0 @@ -../../slsReceiverSoftware/include/sls_receiver_defs.h \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/sls_receiver_funcs.h b/slsDetectorServers/mythen3DetectorServer/sls_receiver_funcs.h deleted file mode 120000 index c2ea4ded9..000000000 --- a/slsDetectorServers/mythen3DetectorServer/sls_receiver_funcs.h +++ /dev/null @@ -1 +0,0 @@ -../../slsReceiverSoftware/include/sls_receiver_funcs.h \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/updateGitVersion.sh b/slsDetectorServers/mythen3DetectorServer/updateGitVersion.sh deleted file mode 100755 index 0c25e7f1e..000000000 --- a/slsDetectorServers/mythen3DetectorServer/updateGitVersion.sh +++ /dev/null @@ -1,31 +0,0 @@ -SERVER=jungfrauDetectorServer -MAINDIR=slsDetectorsPackage -SPECDIR=slsDetectorSoftware/$SERVER -TMPFILE=gitInfoJungfrauTmp.h -INCLFILE=gitInfoJungfrau.h - - -#evaluate the variables -EVALFILE=../../evalVersionVariables.sh -source $EVALFILE - - -#get modified date -#RDATE1='git log --pretty=format:"%ci" -1' -RDATE1="find ../slsDetectorServer . -type f -exec stat --format '%Y :%y %n' '{}' \; | sort -nr | cut -d: -f2- | egrep -v 'gitInfo|bin|.git|updateGitVersion|.o' | head -n 1" -RDATE=`eval $RDATE1` -NEWDATE=$(sed "s/-//g" <<< $RDATE | awk '{print $1;}') -NEWDATE=${NEWDATE/#/0x} - - -#get old date from INCLFILE -OLDDATE=$(more $INCLFILE | grep '#define GITDATE' | awk '{print $3}') - - -#update INCLFILE if changes -if [ "$OLDDATE" != "$NEWDATE" ]; then - echo Path: ${MAINDIR}/${SPECDIR} $'\n'URL: ${GITREPO} $'\n'Repository Root: ${GITREPO} $'\n'Repsitory UUID: ${REPUID} $'\n'Revision: ${FOLDERREV} $'\n'Branch: ${BRANCH} $'\n'Last Changed Author: ${AUTH1}_${AUTH2} $'\n'Last Changed Rev: ${REV} $'\n'Last Changed Date: ${RDATE} > gitInfo.txt - cd ../../ - ./genVersionHeader.sh $SPECDIR/gitInfo.txt $SPECDIR/$TMPFILE $SPECDIR/$INCLFILE - cd $WD -fi \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/communication_funcs.c b/slsDetectorServers/slsDetectorServer/communication_funcs.c index a6ece1276..a82f9bd82 100755 --- a/slsDetectorServers/slsDetectorServer/communication_funcs.c +++ b/slsDetectorServers/slsDetectorServer/communication_funcs.c @@ -95,7 +95,7 @@ int bindSocket(unsigned short int port_number) { // success myport = port_number; ret = OK; - FILE_LOG(logINFO, (" %s socket bound: isock=%d port=%d fd=%d\n", + FILE_LOG(logDEBUG5, ("%s socket bound: isock=%d, port=%d, fd=%d\n", (isControlServer ? "Control":"Stop"), isock, port_number, socketDescriptor)); } @@ -356,25 +356,34 @@ int sendModule(int file_des, sls_detector_module *myMod) { int sendModuleGeneral(int file_des, sls_detector_module *myMod, int sendAll) { - int ts = 0; + int ts = 0, n = 0; int nChips = myMod->nchip; int nChans = myMod->nchan; int nAdcs = myMod->nadc; int nDacs = myMod->ndac; // send module structure - ts += sendData(file_des,&(myMod->serialnumber),sizeof(myMod->serialnumber),INT32); - ts += sendData(file_des,&(myMod->nchan),sizeof(myMod->nchan),INT32); - ts += sendData(file_des,&(myMod->nchip),sizeof(myMod->nchip),INT32); - ts += sendData(file_des,&(myMod->ndac),sizeof(myMod->ndac),INT32); - ts += sendData(file_des,&(myMod->nadc),sizeof(myMod->nadc),INT32); - ts += sendData(file_des,&(myMod->reg),sizeof(myMod->reg),INT32); - ts += sendData(file_des,&(myMod->gain), sizeof(myMod->gain),OTHER); - ts += sendData(file_des,&(myMod->offset), sizeof(myMod->offset),OTHER); + n = sendData(file_des,&(myMod->serialnumber),sizeof(myMod->serialnumber),INT32); + if (!n) return -1; ts += n; + n = sendData(file_des,&(myMod->nchan),sizeof(myMod->nchan),INT32); + if (!n) return -1; ts += n; + n = sendData(file_des,&(myMod->nchip),sizeof(myMod->nchip),INT32); + if (!n) return -1; ts += n; + n = sendData(file_des,&(myMod->ndac),sizeof(myMod->ndac),INT32); + if (!n) return -1; ts += n; + n = sendData(file_des,&(myMod->nadc),sizeof(myMod->nadc),INT32); + if (!n) return -1; ts += n; + n = sendData(file_des,&(myMod->reg),sizeof(myMod->reg),INT32); + if (!n) return -1; ts += n; + n = sendData(file_des,&(myMod->gain), sizeof(myMod->gain),OTHER); + if (!n) return -1; ts += n; + n = sendData(file_des,&(myMod->offset), sizeof(myMod->offset),OTHER); + if (!n) return -1; ts += n; FILE_LOG(logDEBUG5, ("module of size %d sent\n",ts)); // send dac - ts += sendData(file_des,myMod->dacs,sizeof(int)*nDacs,INT32); + n = sendData(file_des,myMod->dacs,sizeof(int)*nDacs,INT32); + if (!n) return -1; ts += n; FILE_LOG(logDEBUG5, ("dacs of size %d sent\n",ts)); { int idac; @@ -383,18 +392,21 @@ int sendModuleGeneral(int file_des, sls_detector_module *myMod, int sendAll) { } // send adc - ts += sendData(file_des,myMod->adcs,sizeof(int)*nAdcs,INT32); + n = sendData(file_des,myMod->adcs,sizeof(int)*nAdcs,INT32); + if (!n) return -1; ts += n; FILE_LOG(logDEBUG5, ("adcs of size %d sent\n", ts)); // some detectors dont require sending all trimbits etc. if(sendAll) { // chips - ts += sendData(file_des,myMod->chipregs,sizeof(int)*nChips,INT32); + n = sendData(file_des,myMod->chipregs,sizeof(int)*nChips,INT32); + if (!n) return -1; ts += n; FILE_LOG(logDEBUG5, ("chips of size %d sent\n", ts)); // channels - ts += sendData(file_des,myMod->chanregs,sizeof(int)*nChans,INT32); + n = sendData(file_des,myMod->chanregs,sizeof(int)*nChans,INT32); FILE_LOG(logDEBUG5, ("chans of size %d sent - %d\n", ts, myMod->nchan)); + if (!n) return -1; ts += n; } FILE_LOG(logDEBUG5, ("module of size %d sent register %x\n", ts, myMod->reg)); @@ -408,7 +420,7 @@ int receiveModule(int file_des, sls_detector_module* myMod) { } int receiveModuleGeneral(int file_des, sls_detector_module* myMod, int receiveAll) { - int ts = 0; + int ts = 0, n = 0; int *dacptr = myMod->dacs; int *adcptr = myMod->adcs; int *chipptr = myMod->chipregs, *chanptr = myMod->chanregs; @@ -416,14 +428,22 @@ int receiveModuleGeneral(int file_des, sls_detector_module* myMod, int receiveA int nChans, nchanold = myMod->nchan, nchandiff; int nDacs, ndold = myMod->ndac, ndacdiff; int nAdcs, naold = myMod->nadc, nadcdiff; - ts += receiveData(file_des,&(myMod->serialnumber),sizeof(myMod->serialnumber),INT32); - ts += receiveData(file_des,&(myMod->nchan),sizeof(myMod->nchan),INT32); - ts += receiveData(file_des,&(myMod->nchip),sizeof(myMod->nchip),INT32); - ts += receiveData(file_des,&(myMod->ndac),sizeof(myMod->ndac),INT32); - ts += receiveData(file_des,&(myMod->nadc),sizeof(myMod->nadc),INT32); - ts += receiveData(file_des,&(myMod->reg),sizeof(myMod->reg),INT32); - ts += receiveData(file_des,&(myMod->gain), sizeof(myMod->gain),OTHER); - ts += receiveData(file_des,&(myMod->offset), sizeof(myMod->offset),OTHER); + n = receiveData(file_des,&(myMod->serialnumber),sizeof(myMod->serialnumber),INT32); + if (!n) return -1; ts += n; + n = receiveData(file_des,&(myMod->nchan),sizeof(myMod->nchan),INT32); + if (!n) return -1; ts += n; + n = receiveData(file_des,&(myMod->nchip),sizeof(myMod->nchip),INT32); + if (!n) return -1; ts += n; + n = receiveData(file_des,&(myMod->ndac),sizeof(myMod->ndac),INT32); + if (!n) return -1; ts += n; + n = receiveData(file_des,&(myMod->nadc),sizeof(myMod->nadc),INT32); + if (!n) return -1; ts += n; + n = receiveData(file_des,&(myMod->reg),sizeof(myMod->reg),INT32); + if (!n) return -1; ts += n; + n = receiveData(file_des,&(myMod->gain), sizeof(myMod->gain),OTHER); + if (!n) return -1; ts += n; + n = receiveData(file_des,&(myMod->offset), sizeof(myMod->offset),OTHER); + if (!n) return -1; ts += n; myMod->dacs = dacptr; myMod->adcs = adcptr; @@ -473,7 +493,8 @@ int receiveModuleGeneral(int file_des, sls_detector_module* myMod, int receiveA else FILE_LOG(logDEBUG5, ("received %d adcs\n",nAdcs)); if (ndacdiff <= 0) { - ts += receiveData(file_des,myMod->dacs, sizeof(int)*nDacs,INT32); + n = receiveData(file_des,myMod->dacs, sizeof(int)*nDacs,INT32); + if (!n) return -1; ts += n; FILE_LOG(logDEBUG5, ("dacs received\n")); int id; for (id = 0; idndac = ndold; - ts += receiveData(file_des,myMod->dacs, sizeof(int)*ndold,INT32); - ts += receiveData(file_des,dacptr, sizeof(int)*ndacdiff,INT32); + n = receiveData(file_des,myMod->dacs, sizeof(int)*ndold,INT32); + if (!n) return -1; ts += n; + n = receiveData(file_des,dacptr, sizeof(int)*ndacdiff,INT32); + if (!n) return -1; ts += n; free(dacptr); return FAIL; } if (nadcdiff <= 0) { - ts += receiveData(file_des,myMod->adcs, sizeof(int)*nAdcs,INT32); + n = receiveData(file_des,myMod->adcs, sizeof(int)*nAdcs,INT32); + if (!n) return -1; ts += n; FILE_LOG(logDEBUG5, ("adcs received\n")); } else { adcptr = (int*)malloc(nadcdiff*sizeof(int)); myMod->nadc = naold; - ts += receiveData(file_des,myMod->adcs, sizeof(int)*naold,INT32); - ts += receiveData(file_des,adcptr, sizeof(int)*nadcdiff,INT32); + n = receiveData(file_des,myMod->adcs, sizeof(int)*naold,INT32); + if (!n) return -1; ts += n; + n = receiveData(file_des,adcptr, sizeof(int)*nadcdiff,INT32); + if (!n) return -1; ts += n; free(adcptr); return FAIL; } @@ -504,25 +530,31 @@ int receiveModuleGeneral(int file_des, sls_detector_module* myMod, int receiveA if(receiveAll){ if (nchipdiff <= 0) { - ts += receiveData(file_des,myMod->chipregs, sizeof(int)*nChips,INT32); + n = receiveData(file_des,myMod->chipregs, sizeof(int)*nChips,INT32); + if (!n) return -1; ts += n; FILE_LOG(logDEBUG5, ("chips received\n")); } else { chipptr = (int*)malloc(nchipdiff*sizeof(int)); myMod->nchip = nchipold; - ts += receiveData(file_des,myMod->chipregs, sizeof(int)*nchipold,INT32); - ts += receiveData(file_des,chipptr, sizeof(int)*nchipdiff,INT32); + n = receiveData(file_des,myMod->chipregs, sizeof(int)*nchipold,INT32); + if (!n) return -1; ts += n; + n = receiveData(file_des,chipptr, sizeof(int)*nchipdiff,INT32); + if (!n) return -1; ts += n; free(chipptr); return FAIL; } if (nchandiff <= 0) { - ts += receiveData(file_des,myMod->chanregs, sizeof(int)*nChans,INT32); + n = receiveData(file_des,myMod->chanregs, sizeof(int)*nChans,INT32); + if (!n) return -1; ts += n; FILE_LOG(logDEBUG5, ("chans received\n")); } else { chanptr = (int*)malloc(nchandiff*sizeof(int)); myMod->nchan = nchanold; - ts += receiveData(file_des,myMod->chanregs, sizeof(int)*nchanold,INT32); - ts += receiveData(file_des,chanptr, sizeof(int)*nchandiff,INT32); + n = receiveData(file_des,myMod->chanregs, sizeof(int)*nchanold,INT32); + if (!n) return -1; ts += n; + n = receiveData(file_des,chanptr, sizeof(int)*nchandiff,INT32); + if (!n) return -1; ts += n; free(chanptr); return FAIL; } @@ -546,7 +578,7 @@ int Server_VerifyLock() { } -void Server_SendResult(int fileDes, intType itype, int update, void* retval, int retvalSize) { +int Server_SendResult(int fileDes, intType itype, int update, void* retval, int retvalSize) { // update if different clients (ret can be ok or acquisition finished), not fail to not overwrite e message if (update && ret != FAIL && differentClients) @@ -554,7 +586,7 @@ void Server_SendResult(int fileDes, intType itype, int update, void* retval, int // send success of operation int ret1 = ret; - sendData(fileDes, &ret1,sizeof(ret1), INT32);/* if < 0, return , socket crash*/ + sendData(fileDes, &ret1,sizeof(ret1), INT32); if(ret == FAIL) { // send error message if (strlen(mess)) @@ -567,4 +599,6 @@ void Server_SendResult(int fileDes, intType itype, int update, void* retval, int } // send return value sendData(fileDes, retval, retvalSize, itype); + + return ret; } diff --git a/slsDetectorServers/slsDetectorServer/communication_funcs.h b/slsDetectorServers/slsDetectorServer/communication_funcs.h index 6b2068e20..0089fc16e 100755 --- a/slsDetectorServers/slsDetectorServer/communication_funcs.h +++ b/slsDetectorServers/slsDetectorServer/communication_funcs.h @@ -64,7 +64,8 @@ int Server_VerifyLock(); * @param update 1 if one must update if different clients, else 0 * @param retval pointer to result * @param retvalSize size of result + * @returns result of operation */ -void Server_SendResult(int fileDes, intType itype, int update, void* retval, int retvalSize); +int Server_SendResult(int fileDes, intType itype, int update, void* retval, int retvalSize); #endif diff --git a/slsDetectorServers/slsDetectorServer/logger.h b/slsDetectorServers/slsDetectorServer/logger.h index c89aafd30..85d0661e4 100644 --- a/slsDetectorServers/slsDetectorServer/logger.h +++ b/slsDetectorServers/slsDetectorServer/logger.h @@ -20,7 +20,7 @@ #endif typedef enum { -logERROR, logWARNING, logINFO, logINFOBLUE, +logERROR, logWARNING, logINFO, logINFOBLUE, logGREEN, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4, logDEBUG5 }TLogLevel; @@ -35,6 +35,7 @@ static inline void FILELOG_PrintLog(TLogLevel level, char* m) { case logERROR: cprintf(RED BOLD, "ERROR: %s", m); break; case logWARNING: cprintf(YELLOW BOLD, "WARNING: %s", m); break; case logINFOBLUE: cprintf(BLUE, "INFO: %s", m); break; + case logGREEN: cprintf(GREEN, "INFO: %s", m); break; case logINFO: cprintf(RESET, "INFO: %s", m); break; case logDEBUG: cprintf(MAGENTA, "DEBUG: %s", m); break; case logDEBUG1: cprintf(MAGENTA, "DEBUG1: %s", m); break; diff --git a/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h index d100b85f8..05861f3e0 100644 --- a/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h @@ -19,15 +19,12 @@ int getFirmwareCheckResult(char** mess); #endif void checkFirmwareCompatibility(); -#if defined(MYTHEN3D) || defined(JUNGFRAUD) +#ifdef JUNGFRAUD int checkType(); u_int32_t testFpga(void); int testBus(void); #endif -#ifdef MYTHEN3D -int moduleTest( enum digitalTestMode arg); -#endif #ifdef JUNGFRAUD int detectorTest( enum digitalTestMode arg); #endif @@ -40,7 +37,7 @@ u_int64_t getFirmwareAPIVersion(); u_int16_t getHardwareVersionNumber(); u_int16_t getHardwareSerialNumber(); #endif -#if !defined(MYTHEN3D) || !defined(EIGERD) +#ifdef EIGERD u_int32_t getDetectorNumber(); #endif u_int64_t getDetectorMAC(); @@ -73,17 +70,11 @@ uint32_t readRegister(uint32_t offset); // firmware functions (resets) -#if defined(MYTHEN3D) || defined(JUNGFRAUD) +#ifdef JUNGFRAUD int powerChip (int on); void cleanFifos(); void resetCore(); void resetPeripheral(); -#endif -#ifdef MYTHEN3D -int getPhase(int i); -int configurePhase(int val, enum CLKINDEX i); -int configureFrequency(int val, int i); -#elif JUNGFRAUD int autoCompDisable(int on); int adcPhase(int st); int getPhase(); @@ -97,7 +88,7 @@ int setROI(int n, ROI arg[], int *retvalsize, int *ret); #endif // parameters - readout -int setSpeed(enum speedVariable arg, int val); +enum speedVariable setSpeed(int val); #ifdef EIGERD enum readOutFlags setReadOutFlags(enum readOutFlags val); #endif @@ -129,35 +120,21 @@ int setThresholdEnergy(int ev); #endif // parameters - dac, adc, hv -#if defined(MYTHEN3D) || defined(JUNGFRAUD) +#ifdef JUNGFRAUD void serializeToSPI(u_int32_t addr, u_int32_t val, u_int32_t csmask, int numbitstosend, u_int32_t clkmask, u_int32_t digoutmask, int digofset); void initDac(int dacnum); int voltageToDac(int value); int dacToVoltage(unsigned int digital); #endif -#ifdef MYTHEN3D -int setPower(enum DACINDEX ind, int val); -int powerToDac(int value, int chip); -int dacToPower(int value, int chip); -#endif #ifdef JUNGFRAUD extern void setAdc(int addr, int val); // AD9257.h #endif void setDAC(enum DACINDEX ind, int val, int mV, int retval[]); -#ifdef MYTHEN3D -int getVLimit(); -void setDacRegister(int dacnum,int dacvalue); -int getDacRegister(int dacnum); -#endif -#ifndef MYTHEN3D int getADC(enum ADCINDEX ind); -#endif -#ifndef MYTHEN3D int setHighVoltage(int val); -#endif @@ -169,8 +146,10 @@ enum externalCommunicationMode getTiming(); #ifdef JUNGFRAUD long int calcChecksum(int sourceip, int destip); #endif -#ifndef MYTHEN3D +#ifdef GOTTHARDD int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport, uint32_t udpport2, int ival); +#else +int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport, uint32_t udpport2); #endif #if defined(JUNGFRAUD) || defined(EIGERD) int setDetectorPosition(int pos[]); @@ -187,7 +166,7 @@ int resetCounterBlock(int startACQ); int calibratePedestal(int frames); // jungfrau specific - pll, flashing firmware -#elif defined(JUNGFRAUD) || defined(MYTHEN3D) +#elif JUNGFRAUD void resetPLL(); u_int32_t setPllReconfigReg(u_int32_t reg, u_int32_t val); void configurePll(); diff --git a/slsDetectorServers/slsDetectorServer/slsDetectorServer.c b/slsDetectorServers/slsDetectorServer/slsDetectorServer.c index 9a4c56df3..ef85d11b5 100755 --- a/slsDetectorServers/slsDetectorServer/slsDetectorServer.c +++ b/slsDetectorServers/slsDetectorServer/slsDetectorServer.c @@ -33,6 +33,7 @@ int main(int argc, char *argv[]){ // subsequent read/write to socket gives error - must handle locally signal(SIGPIPE, SIG_IGN); + // circumvent the basic tests { int i; @@ -64,28 +65,20 @@ int main(int argc, char *argv[]){ #endif if (isControlServer) { portno = DEFAULT_PORTNO; - FILE_LOG(logINFOBLUE, - ("***************************************************\n" - "********* opening control server on port %d **********\n" - "********************************************************\n\n" - , portno)); + FILE_LOG(logINFO, ("Opening control server on port %d \n", portno)); #ifdef STOP_SERVER { int i; for (i = 0; i < argc; ++i) sprintf(cmd, "%s %s", cmd, argv[i]); sprintf(cmd,"%s -stopserver&", cmd); - FILE_LOG(logINFO, ("Command to start stop server:%s\n", cmd)); + FILE_LOG(logDEBUG5, ("Command to start stop server:%s\n", cmd)); system(cmd); } #endif } else { portno = DEFAULT_PORTNO + 1; - FILE_LOG(logINFOBLUE, - ("***************************************************\n" - "*********** opening stop server on port %d ***********\n" - "********************************************************\n\n" - , portno)); + FILE_LOG(logINFO,("Opening stop server on port %d \n", portno)); } init_detector(); @@ -100,7 +93,7 @@ int main(int argc, char *argv[]){ function_table(); if (isControlServer) { - FILE_LOG(logINFO, ("Control Server Ready...\n\n")); + FILE_LOG(logINFOBLUE, ("Control Server Ready...\n\n")); } else { FILE_LOG(logINFO, ("Stop Server Ready...\n\n")); } diff --git a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c index 6e020da88..c202dceac 100755 --- a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c @@ -14,8 +14,6 @@ const enum detectorType myDetectorType=GOTTHARD; const enum detectorType myDetectorType=EIGER; #elif JUNGFRAUD const enum detectorType myDetectorType=JUNGFRAU; -#elif MYTHEN3D -const enum detectorType myDetectorType=MYTHEN3; #else const enum detectorType myDetectorType=GENERIC; #endif @@ -40,7 +38,7 @@ int dataBytes = 10; #ifdef EIGERD uint32_t dhcpipad = 0; #endif -#ifdef GOTTHARD +#ifdef GOTTHARDD int digitalTestBit = 0; #endif @@ -110,7 +108,7 @@ int decode_function(int file_des) { } else { FILE_LOG(logDEBUG5, (" calling function fnum=%d, (%s)\n", fnum, getFunctionName((enum detFuncs)fnum))); - ret=(*flist[fnum])(file_des); + ret = (*flist[fnum])(file_des); if (ret == FAIL) { FILE_LOG(logDEBUG5, ("Error executing the function = %d (%s)\n", @@ -271,24 +269,37 @@ void functionNotImplemented() { void modeNotImplemented(char* modename, int mode) { ret = FAIL; sprintf(mess, "%s (%d) is not implemented for this detector\n", modename, mode); - FILE_LOG(logWARNING,(mess)); + FILE_LOG(logERROR,(mess)); } void validate(int arg, int retval, char* modename, int hex) { if (ret == OK && arg != -1 && retval != arg) { ret = FAIL; if (hex) - sprintf(mess, "Could not set %s. Set 0x%x, but got 0x%x\n", + sprintf(mess, "Could not %s. Set 0x%x, but read 0x%x\n", modename, arg, retval); else - sprintf(mess, "Could not set %s. Set %d, but got %d\n", + sprintf(mess, "Could not %s. Set %d, but read %d\n", + modename, arg, retval); + FILE_LOG(logERROR,(mess)); + } +} + +void validate64(int64_t arg, int64_t retval, char* modename, int hex) { + if (ret == OK && arg != -1 && retval != arg) { + ret = FAIL; + if (hex) + sprintf(mess, "Could not %s. Set 0x%llx, but read 0x%llx\n", + modename, arg, retval); + else + sprintf(mess, "Could not %s. Set %lld, but read %lld\n", modename, arg, retval); FILE_LOG(logERROR,(mess)); } } -int M_nofunc(int file_des){ +int M_nofunc(int file_des) { ret = FAIL; memset(mess, 0, sizeof(mess)); @@ -299,14 +310,12 @@ int M_nofunc(int file_des){ strcpy(mess,"Unrecognized Function. Please do not proceed.\n"); FILE_LOG(logERROR, (mess)); - - Server_SendResult(file_des, OTHER, 0, NULL, 0); - return ret; + return Server_SendResult(file_des, OTHER, 0, NULL, 0); } // Jungfrau program mode -int M_nofuncMode(int file_des){ +int M_nofuncMode(int file_des) { ret = FAIL; memset(mess, 0, sizeof(mess)); @@ -320,9 +329,7 @@ int M_nofuncMode(int file_des){ "Restart detector server in normal mode (without any arguments) to continue.\n", getFunctionName((enum detFuncs)fnum)); FILE_LOG(logERROR, (mess)); - - Server_SendResult(file_des, OTHER, 0, NULL, 0); - return ret; + return Server_SendResult(file_des, OTHER, 0, NULL, 0); } @@ -336,7 +343,6 @@ int exec_command(int file_des) { if (receiveData(file_des, cmd, MAX_STR_LENGTH, OTHER) < 0) return printSocketReadError(); - FILE_LOG(logINFO, ("Executing command (%s)\n", cmd)); // set @@ -359,10 +365,7 @@ int exec_command(int file_des) { pclose(sysFile); FILE_LOG(logINFO, ("Result of cmd (%s):\n%s\n", cmd, retval)); } - - Server_SendResult(file_des, OTHER, 0, retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, OTHER, 0, retval, sizeof(retval)); } @@ -372,10 +375,7 @@ int get_detector_type(int file_des) { ret = OK; enum detectorType retval = myDetectorType; FILE_LOG(logDEBUG5,("Returning detector type %d\n", retval)); - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -391,27 +391,24 @@ int set_external_signal_flag(int file_des) { if (receiveData(file_des, args, sizeof(args), INT32) < 0) return printSocketReadError(); + int signalindex = args[0]; + enum externalSignalFlag flag = args[1]; + FILE_LOG(logDEBUG5, ("Setting external signal %d to flag %d\n", signalindex, flag)); + #ifndef GOTTHARDD functionNotImplemented(); #else - int signalindex = args[0]; - enum externalSignalFlag flag = args[1]; - - FILE_LOG(logDEBUG5, ("Setting external signal %d to flag %d\n", signalindex, flag)); // set if ((flag != GET_EXTERNAL_SIGNAL_FLAG) && (Server_VerifyLock() != FAIL)) { setExtSignal(signalindex, flag); } // get retval = getExtSignal(signalindex); - validate((int)flag, (int)retval, "external signal flag", 1); + validate((int)flag, (int)retval, "set external signal flag", 1); FILE_LOG(logDEBUG5, ("External Signal Flag: %d\n", retval)); } #endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -425,7 +422,6 @@ int set_external_communication_mode(int file_des) { if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) return printSocketReadError(); - FILE_LOG(logDEBUG5, ("Setting external communication mode to %d\n", arg)); // set @@ -446,12 +442,9 @@ int set_external_communication_mode(int file_des) { } // get retval = getTiming(); - validate((int)arg, (int)retval, "timing mode", 0); + validate((int)arg, (int)retval, "set timing mode", 0); FILE_LOG(logDEBUG5, ("Timing Mode: %d\n",retval)); - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -465,7 +458,6 @@ int get_id(int file_des) { if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) return printSocketReadError(); - FILE_LOG(logDEBUG5, ("Getting Id %d\n", arg)); // get @@ -483,10 +475,7 @@ int get_id(int file_des) { modeNotImplemented("ID Index", (int)arg); break; } - - Server_SendResult(file_des, INT64, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT64, 1, &retval, sizeof(retval)); } @@ -501,19 +490,21 @@ int digital_test(int file_des) { if (receiveData(file_des, args, sizeof(args), INT32) < 0) return printSocketReadError(); + enum digitalTestMode mode = args[0]; +#ifdef GOTTHARDD + int ival = args[1]; + FILE_LOG(logDEBUG5, ("Digital test, mode = %d, ival:%d\n", mode, ival)); +#else + FILE_LOG(logDEBUG5, ("Digital test, mode = %d\n", mode)); +#endif #ifdef EIGERD functionNotImplemented(); #else - enum digitalTestMode mode = args[0]; - int ival = args[1]; - - FILE_LOG(logDEBUG5, ("Digital test, mode = %d\n", mode)); - - // set + // only set if (Server_VerifyLock() != FAIL) { switch (mode) { -#ifdef GOTTHARD: +#ifdef GOTTHARDD case DIGITAL_BIT_TEST: FILE_LOG(logDEBUG5, ("Setting digital test bit: %d\n", ival)); if (ival >= 0) @@ -532,10 +523,7 @@ int digital_test(int file_des) { } } #endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -551,7 +539,6 @@ int set_dac(int file_des) { if (receiveData(file_des, args, sizeof(args), INT32) < 0) return printSocketReadError(); - enum dacIndex ind = args[0]; int mV = args[1]; int val = args[2]; @@ -561,7 +548,7 @@ int set_dac(int file_des) { #ifdef JUNGFRAUD if ((ind != HV_NEW) && (ind >= NDAC_OLDBOARD)) { //for compatibility with old board modeNotImplemented("Dac Index", (int)ind); - }else + } else serverDacIndex = ind; #else switch (ind) { @@ -634,73 +621,6 @@ int set_dac(int file_des) { case HV_NEW: case IO_DELAY: break; -#elif MYTHEN3D - case M_vIpre: - serverDacIndex = vIpre; - break; - case M_vIbias: - serverDacIndex = vIbias; - break; - case PREAMP: - serverDacIndex = Vrf; - break; - case SHAPER1: - serverDacIndex = VrfSh; - break; - case M_vIinSh: - serverDacIndex = vIinSh; - break; - case M_VdcSh: - serverDacIndex = VdcSh; - break; - case M_Vth2: - serverDacIndex = Vth2; - break; - case M_VPL: - serverDacIndex = VPL; - break; - case THRESHOLD: - serverDacIndex = Vth1; - break; - case M_Vth3: - serverDacIndex = Vth3; - break; - case TRIMBIT_SIZE: - serverDacIndex = Vtrim; - break; - case M_casSh: - serverDacIndex = casSh; - break; - case M_cas: - serverDacIndex = cas; - break; - case M_vIbiasSh: - serverDacIndex = vIbiasSh; - break; - case M_vIcin: - serverDacIndex = vIcin; - break; - case CALIBRATION_PULSE: // !!! pulse height + 1400 DACu - serverDacIndex = VPH; - break; - case M_vIpreOut: - serverDacIndex = vIpreOut; - break; - case V_POWER_A: - serverDacIndex = V_A; - break; - case V_POWER_B: - serverDacIndex = V_B; - break; - case V_POWER_IO: - serverDacIndex = V_IO; - break; - case V_POWER_CHIP: - serverDacIndex = V_CHIP; - break; - case V_LIMIT: - serverDacIndex = V_LIM; - break; #endif default: modeNotImplemented("Dac Index", (int)ind); @@ -734,92 +654,27 @@ int set_dac(int file_des) { #ifdef EIGERD if ((retval[0] != SLAVE_HIGH_VOLTAGE_READ_VAL) && (retval[0] < 0)) { ret = FAIL; - if(retval[0] == -1) + if (retval[0] == -1) sprintf(mess, "Setting high voltage failed. Bad value %d. " "The range is from 0 to 200 V.\n",val); - else if(retval[0] == -2) + else if (retval[0] == -2) strcpy(mess, "Setting high voltage failed. " "Serial/i2c communication failed.\n"); - else if(retval[0] == -3) + else if (retval[0] == -3) strcpy(mess, "Getting high voltage failed. " "Serial/i2c communication failed.\n"); - FILE_LOG(logWARNING,(mess)); + FILE_LOG(logERROR,(mess)); } #endif break; - // power -#ifdef MYTHEN3D - case V_POWER_A: - case V_POWER_B: - case V_POWER_C: - case V_POWER_D: - case V_POWER_IO: - case V_POWER_CHIP: - case V_LIMIT: - FILE_LOG(logDEBUG5, ("Setting a power %d to %d\n",ind, val); - if (!mV) { - ret = FAIL; - strcpy(mess, "Power of index %d should be set in mV instead of DACu", - serverDacIndex); - FILE_LOG(logWARNING,(mess)); - val = -1; - } - - int lim = getVLimit(); - if (ind != V_LIMIT && lim != -1 && val > lim) { - ret = FAIL; - strcpy(mess, "Power of index %d is %d, should be less than %dmV\n", - serverDacIndex, val, lim); - FILE_LOG(logWARNING,(mess)); - val = -1; - } - - retval[1] = retval[0] = setPower(serverDacIndex,val); - validate(val, retval[1], "power", 0); - FILE_LOG(logDEBUG5, ("Power (%d): %d\n", serverDacIndex, retval[1])); - break; -#endif - // dacs default: -#ifdef MYTHEN3D - if( mV && val > MAX_DACVOLTVAL) { - ret = FAIL; - strcpy(mess, "Dac of index %d should be less than %dmV\n", - serverDacIndex, val, MAX_DACVOLTVAL); - FILE_LOG(logWARNING,(mess)); - val = -1; - } - else if( !mV && val >= MAX_DACVAL) { - ret = FAIL; - strcpy(mess, "Dac of index %d should be less than %d (dac value)\n", - serverDacIndex, val, MAX_DACVAL); - FILE_LOG(logWARNING,(mess)); - val = -1; - } - if (val >= 0) { - // conver to mV - int v = val; - if (!mV) - v = dacToVoltage(val); - - //checkvlimit compliant - int lim = getVLimit(); - if (lim!= -1 && v > lim) { - ret = FAIL; - strcpy(mess, "Dac of index %d should be less than %dmV (%d dac value)\n", - serverDacIndex, lim, voltageToDac(lim)); - FILE_LOG(logWARNING,(mess)); - val = -1; - } - } -#endif setDAC(serverDacIndex, val, mV, retval); #ifdef EIGERD - if(val != -1) { + if (val != -1) { //changing dac changes settings to undefined - switch(serverDacIndex){ + switch(serverDacIndex) { case VCMP_LL: case VCMP_LR: case VCMP_RL: @@ -827,7 +682,7 @@ int set_dac(int file_des) { case VRF: case VCP: setSettings(UNDEFINED); - FILE_LOG(logWARNING, ("Settings has been changed " + FILE_LOG(logERROR, ("Settings has been changed " "to undefined (changed specific dacs)\n")); break; default: @@ -838,7 +693,7 @@ int set_dac(int file_des) { //check if (ret == OK) { int temp = 0; - if(mV) + if (mV) temp = retval[1]; else temp = retval[0]; @@ -847,7 +702,7 @@ int set_dac(int file_des) { } else { ret = FAIL; sprintf(mess,"Setting dac %d : wrote %d but read %d\n", serverDacIndex, val, temp); - FILE_LOG(logWARNING,(mess)); + FILE_LOG(logERROR,(mess)); } } FILE_LOG(logDEBUG5, ("Dac (%d): %d dac units and %d mV\n", serverDacIndex, retval[0], retval[1])); @@ -855,10 +710,7 @@ int set_dac(int file_des) { } } } - - Server_SendResult(file_des, INT32, 1, retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, retval, sizeof(retval)); } @@ -874,14 +726,11 @@ int get_adc(int file_des) { if (receiveData(file_des, &ind, sizeof(ind), INT32) < 0) return printSocketReadError(); - -#ifdef MYTHEN3D - functionNotImplemented(); -#else enum ADCINDEX serverAdcIndex = 0; + // get switch (ind) { -#if defined(GOTTHARD) || defined(JUNGFRAUD) +#if defined(GOTTHARDD) || defined(JUNGFRAUD) case TEMPERATURE_FPGA: serverAdcIndex = TEMP_FPGA; break; @@ -925,11 +774,7 @@ int get_adc(int file_des) { retval = getADC(serverAdcIndex); FILE_LOG(logDEBUG5, ("ADC(%d): %d\n", retval)); } -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -937,42 +782,29 @@ int get_adc(int file_des) { int write_register(int file_des) { - int ret=OK,ret1=OK; - int n=0; - uint32_t retval=-1; - sprintf(mess,"write to register failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int args[2] = {-1, -1}; + uint32_t retval = -1; - // receive arguments - int arg[2]={-1,-1}; - n = receiveData(file_des,arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - int addr=arg[0]; - uint32_t val=arg[1]; + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + uint32_t addr = args[0]; + uint32_t val = args[1]; + FILE_LOG(logDEBUG5, ("Writing to register 0x%x, data 0x%x\n", addr, val)); - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { -#ifdef VERBOSE - printf("writing to register 0x%x data 0x%x\n", addr, val); -#endif - retval=writeRegister(addr,val); - if (retval!=val) { + // only set + if (Server_VerifyLock() != FAIL) { + retval = writeRegister(addr, val); + // validate + if (retval != val) { ret = FAIL; - sprintf(mess,"Writing to register 0x%x failed: wrote 0x%x but read 0x%x\n", addr, val, retval); - cprintf(RED, "Warning: %s", mess); + sprintf(mess,"Could not write to register 0x%x. Wrote 0x%x but read 0x%x\n", addr, val, retval); + FILE_LOG(logERROR,(mess)); } + FILE_LOG(logDEBUG5, ("Write register (0x%x): 0x%x\n", retval)); } -#ifdef VERBOSE - printf("Data set to 0x%x\n", retval); -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -980,148 +812,139 @@ int write_register(int file_des) { int read_register(int file_des) { - int ret=OK,ret1=OK; - int n=0; - uint32_t retval=-1; - sprintf(mess,"read register failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + uint32_t addr = -1; + uint32_t retval = -1; - // receive arguments - int arg=0; - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - int addr=arg; + if (receiveData(file_des, &addr, sizeof(addr), INT32) < 0) + return printSocketReadError(); - // execute action -#ifdef VERBOSE - printf("reading register 0x%x\n", addr); -#endif - retval=readRegister(addr); -#ifdef VERBOSE - printf("Returned value 0x%x\n", retval); -#endif + FILE_LOG(logDEBUG5, ("Reading from register 0x%x\n", addr)); - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); + // get + retval = readRegister(addr); + FILE_LOG(logDEBUG5, ("Read register (0x%x): 0x%x\n", retval)); - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } int set_module(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sls_detector_module myModule; - int retval=-1; -#ifdef EIGERD - int myIODelay=-1; - int myTau=-1; - int myEV=-1; -#endif - sprintf(mess,"set module failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int retval = -1; - -#ifdef MYTHEN3D - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Set Module) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); -#else - - - int *myDac=NULL; - int *myAdc=NULL; + sls_detector_module module; + int *myDac = NULL; + int *myAdc = NULL; int *myChip = NULL; int *myChan = NULL; +#ifdef EIGERD + int ioDelay = -1; + int tau = -1; + int eV = -1; +#endif - myDac=(int*)malloc(getNumberOfDACs()*sizeof(int)); - if (getNumberOfDACs() > 0 && myDac == NULL) { - ret = FAIL; - sprintf(mess,"could not allocate dacs\n"); - cprintf(RED, "Warning: %s", mess); - } - else { - myModule.dacs=myDac; - myAdc=(int*)malloc(getNumberOfADCs()*sizeof(int)); + // allocate to receive arguments + // infinite loop to break out when FAIL or a final OK + while(1) { + // allocate dacs + myDac = (int*)malloc(getNumberOfDACs() * sizeof(int)); + // error + if (getNumberOfDACs() > 0 && myDac == NULL) { + ret = FAIL; + sprintf(mess, "Could not allocate dacs\n"); + FILE_LOG(logERROR,(mess)); + break; + } + module.dacs = myDac; + + // allocate adcs + myAdc = (int*)malloc(getNumberOfADCs() * sizeof(int)); + // error if (getNumberOfADCs() > 0 && myAdc == NULL) { ret = FAIL; - sprintf(mess,"could not allocate adcs\n"); - cprintf(RED, "Warning: %s", mess); + sprintf(mess,"Could not allocate adcs\n"); + FILE_LOG(logERROR,(mess)); + break; } - else { - myModule.adcs=myAdc; - //no chips and chans allocated for jungfrau, too much memory -#ifdef JUNGFRAUD - myModule.chipregs=NULL; - myModule.chanregs=NULL; -#else - myChip=(int*)malloc(getNumberOfChips()*sizeof(int)); - if (getNumberOfChips() > 0 && myChip == NULL) { - ret = FAIL; - sprintf(mess,"could not allocate chips\n"); - cprintf(RED, "Warning: %s", mess); - } - else { - myModule.chipregs=myChip; - myChan=(int*)malloc(getTotalNumberOfChannels()*sizeof(int)); - if (getTotalNumberOfChannels() > 0 && myChan == NULL) { - ret = FAIL; - sprintf(mess,"could not allocate chans\n"); - cprintf(RED, "Warning: %s", mess); - } - else { - myModule.chanregs=myChan; -#endif - myModule.nchip=getNumberOfChips(); - myModule.nchan=getTotalNumberOfChannels(); - myModule.ndac=getNumberOfDACs(); - myModule.nadc=getNumberOfADCs(); + module.adcs=myAdc; - - // receive arguments -#ifdef VERBOSE - printf("Setting module\n"); -#endif - n=receiveModuleGeneral(file_des, &myModule, + // no need to allocate chips and chans for jungfrau, too much memory #ifdef JUNGFRAUD - 0 //0 is to receive partially (without trimbits etc.) + module.chipregs = NULL; + module.chanregs = NULL; #else - 1 -#endif - ); - if (n<0) return FAIL; -#ifdef VERBOSE - printf("module number register is %d, nchan %d, nchip %d, ndac %d, nadc %d, gain %f, offset %f\n", - myModule.reg, myModule.nchan, myModule.nchip, myModule.ndac, myModule.nadc, myModule.gain,myModule.offset); + // allocate chips + myChip = (int*)malloc(getNumberOfChips() * sizeof(int)); + if (getNumberOfChips() > 0 && myChip == NULL) { + ret = FAIL; + sprintf(mess,"Could not allocate chips\n"); + FILE_LOG(logERROR,(mess)); + break; + } + module.chipregs = myChip; + + // allocate chans + myChan = (int*)malloc(getTotalNumberOfChannels() * sizeof(int)); + if (getTotalNumberOfChannels() > 0 && myChan == NULL) { + ret = FAIL; + sprintf(mess,"Could not allocate chans\n"); + FILE_LOG(logERROR,(mess)); + break; + } + module.chanregs=myChan; #endif + module.nchip = getNumberOfChips(); + module.nchan = getTotalNumberOfChannels(); + module.ndac = getNumberOfDACs(); + module.nadc = getNumberOfADCs(); + + // receive arguments (0 to partially receive module without trimbits + if (receiveModuleGeneral(file_des, &module, (myDetectorType == JUNGFRAU) ? 0 : 1) < 0) { + if (myChip != NULL) free(myChip); + if (myChan != NULL) free(myChan); + if (myDac != NULL) free(myDac); + if (myAdc != NULL) free(myAdc); + return printSocketReadError(); + } + FILE_LOG(logDEBUG5, ("module register is %d, nchan %d, nchip %d, " + "ndac %d, nadc %d, gain %f, offset %f\n", + module.reg, module.nchan, module.nchip, + module.ndac, module.nadc, module.gain,module.offset)); + #ifdef EIGERD - n = receiveData(file_des,&myIODelay,sizeof(myIODelay),INT32); - if (n<0) return FAIL; - n = receiveData(file_des,&myTau,sizeof(myTau),INT32); - if (n<0) return FAIL; - n = receiveData(file_des,&myEV,sizeof(myEV),INT32); - if (n<0) return FAIL; -#ifdef VERBOSE - printf("IO Delay:%d\n",myIODelay); - printf("Tau:%d\n",myTau); - printf("eV:%d\n",myEV); -#endif -#endif -#ifndef JUNGFRAUD - } + int args[3] = {-1, -1}; + if (receiveData(file_des, args, sizeof(args), INT32) < 0) { + if (myChip != NULL) free(myChip); + if (myChan != NULL) free(myChan); + if (myDac != NULL) free(myDac); + if (myAdc != NULL) free(myAdc); + return printSocketReadError(); } + ioDelay = args[0]; + tau = args[1]; + eV = args[2]; + FILE_LOG(logDEBUG5, ("ioDelay: %d, tau: d, ev:%d\n", ioDelay, tau, eV)); #endif - } } - //check settings index - if (ret==OK) { -#if defined(JUNGFRAUD) || defined(EIGERD) - switch(myModule.reg){ - case GET_SETTINGS: - case UNINITIALIZED: + + // receive all arguments + if (ret == FAIL) { + int n = 0; + while (n > 0) + n = receiveData(file_des, mess, MAX_STR_LENGTH, OTHER); + } + + + // only set + else if (Server_VerifyLock() != FAIL) { + // check index + switch (module.reg) { #ifdef EIGERD case STANDARD: case HIGHGAIN: @@ -1135,73 +958,68 @@ int set_module(int file_des) { case FIXGAIN2: case FORCESWITCHG1: case FORCESWITCHG2: +#elif GOTTHARDD + case DYNAMICGAIN: + case HIGHGAIN: + case LOWGAIN: + case MEDIUMGAIN: + case VERYHIGHGAIN: #endif break; default: - ret = FAIL; - sprintf(mess,"Setting (%d) is not implemented for this detector\n", myModule.reg); - cprintf(RED, "Warning: %s", mess); + modeNotImplemented("Settings", (int)module.reg); break; } - } -#endif - - // execute action - if (ret==OK) { - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } -#ifdef EIGERD - //set dacs, trimbits and iodelay - ret=setModule(myModule, myIODelay); - //set threshhold - if (myEV >= 0) - setThresholdEnergy(myEV); - else { - //changes settings to undefined (loading a random trim file) - setSettings(UNDEFINED); - cprintf(RED,"Settings has been changed to undefined (random trim file)\n"); - } - //rate correction - //switch off rate correction: no value read from load calib/load settings) - if(myTau == -1){ - if(getRateCorrectionEnable()){ - setRateCorrection(0); - ret = FAIL; - strcat(mess,"Cannot set Rate correction. No default tau provided. Deactivating Rate Correction\n"); - cprintf(RED, "Warning: %s", mess); - } - } - //normal tau value (only if enabled) - else{ - setDefaultSettingsTau_in_nsec(myTau); - if (getRateCorrectionEnable()){ - int64_t retvalTau = setRateCorrection(myTau); - if(myTau != retvalTau){ - cprintf(RED,"%s",mess); - ret=FAIL; - } - } - } - retval = getSettings(); + // set +#ifndef EIGERD + retval = setModule(module); + validate(module.reg, retval, "set module (settings)", 0); + // eiger #else - retval=setModule(myModule); - if (retval != myModule.reg) + //set dacs, trimbits and iodelay + ret = setModule(module, ioDelay); + //set threshhold + if (eV >= 0) + setThresholdEnergy(eV); + else { + //changes settings to undefined (loading a random trim file) + setSettings(UNDEFINED); + FILE_LOG(logERROR, ("Settings has been changed to undefined " + "(random trim file)\n")); + } + //rate correction + //switch off rate correction: no value read from load calib/load settings) + if (tau == -1) { + if (getRateCorrectionEnable()) { + setRateCorrection(0); ret = FAIL; + sprintf(mess,"Cannot set module. Cannot set Rate correction. " + "No default tau provided. Deactivating Rate Correction\n"); + FILE_LOG(logERROR, (mess)); + } + } + //normal tau value (only if enabled) + else { + setDefaultSettingsTau_in_nsec(tau); + if (getRateCorrectionEnable()) { + int64_t retvalTau = setRateCorrection(tau); + if (tau != retvalTau) { + ret = FAIL; + sprintf(mess, "Cannot set module. Could not set rate correction\n"); + FILE_LOG(logERROR, (mess)); + } + } + } + retval = getSettings(); #endif - if(myChip != NULL) free(myChip); - if(myChan != NULL) free(myChan); - if(myDac != NULL) free(myDac); - if(myAdc != NULL) free(myAdc); + FILE_LOG(logDEBUG5, ("Settings: %d\n", retval)); } -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + if (myChip != NULL) free(myChip); + if (myChan != NULL) free(myChan); + if (myDac != NULL) free(myDac); + if (myAdc != NULL) free(myAdc); + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -1212,91 +1030,86 @@ int set_module(int file_des) { int get_module(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sls_detector_module myModule; - sprintf(mess,"get module failed\n"); - -#ifdef MYTHEN3D - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Get Module) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); -#else - - // execute action - int *myDac=NULL; - int *myAdc=NULL; + ret = OK; + memset(mess, 0, sizeof(mess)); + sls_detector_module module; + int *myDac = NULL; + int *myAdc = NULL; int *myChip = NULL; int *myChan = NULL; - myDac=(int*)malloc(getNumberOfDACs()*sizeof(int)); - if (getNumberOfDACs() > 0 && myDac == NULL) { - ret = FAIL; - sprintf(mess,"could not allocate dacs\n"); - cprintf(RED, "Warning: %s", mess); - } - else { - myModule.dacs=myDac; - myAdc=(int*)malloc(getNumberOfADCs()*sizeof(int)); + // allocate to send arguments + // infinite loop to break out when FAIL or a final OK + while(1) { + + // allocate dacs + myDac = (int*)malloc(getNumberOfDACs() * sizeof(int)); + // error + if (getNumberOfDACs() > 0 && myDac == NULL) { + ret = FAIL; + sprintf(mess, "Could not allocate dacs\n"); + FILE_LOG(logERROR,(mess)); + break; + } + module.dacs = myDac; + + // allocate adcs + myAdc = (int*)malloc(getNumberOfADCs() * sizeof(int)); + // error if (getNumberOfADCs() > 0 && myAdc == NULL) { ret = FAIL; - sprintf(mess,"could not allocate adcs\n"); - cprintf(RED, "Warning: %s", mess); + sprintf(mess,"Could not allocate adcs\n"); + FILE_LOG(logERROR,(mess)); + break; } - else { - myModule.adcs=myAdc; - //no chips and chans allocated for jungfrau, too much memory + module.adcs=myAdc; + + // no need to allocate chips and chans for jungfrau, too much memory #ifdef JUNGFRAUD - myModule.chipregs=NULL; - myModule.chanregs=NULL; + module.chipregs = NULL; + module.chanregs = NULL; #else - myChip=(int*)malloc(getNumberOfChips()*sizeof(int)); - if (getNumberOfChips() > 0 && myChip == NULL) { - ret = FAIL; - sprintf(mess,"could not allocate chips\n"); - cprintf(RED, "Warning: %s", mess); - } - else { - myModule.chipregs=myChip; - myChan=(int*)malloc(getTotalNumberOfChannels()*sizeof(int)); - if (getTotalNumberOfChannels() > 0 && myChan == NULL) { - ret = FAIL; - sprintf(mess,"could not allocate chans\n"); - cprintf(RED, "Warning: %s", mess); - } - else { - myModule.chanregs=myChan; -#endif - myModule.nchip=getNumberOfChips(); - myModule.nchan=getTotalNumberOfChannels(); - myModule.ndac=getNumberOfDACs(); - myModule.nadc=getNumberOfADCs(); - getModule(&myModule); -#ifdef VERBOSE - printf("Returning module of register %x\n", myModule.reg); -#endif -#ifndef JUNGFRAUD - } - } -#endif + // allocate chips + myChip = (int*)malloc(getNumberOfChips() * sizeof(int)); + if (getNumberOfChips() > 0 && myChip == NULL) { + ret = FAIL; + sprintf(mess,"Could not allocate chips\n"); + FILE_LOG(logERROR,(mess)); + break; } - } + module.chipregs = myChip; + + // allocate chans + myChan = (int*)malloc(getTotalNumberOfChannels() * sizeof(int)); + if (getTotalNumberOfChannels() > 0 && myChan == NULL) { + ret = FAIL; + sprintf(mess,"Could not allocate chans\n"); + FILE_LOG(logERROR,(mess)); + break; + } + module.chanregs=myChan; #endif + module.nchip = getNumberOfChips(); + module.nchan = getTotalNumberOfChannels(); + module.ndac = getNumberOfDACs(); + module.nadc = getNumberOfADCs(); + + // only get + FILE_LOG(logDEBUG5, ("Getting module\n")); + getModule(&module); + FILE_LOG(logDEBUG5, ("Getting module. Settings:%d\n", module.reg)); + } Server_SendResult(file_des, INT32, 1, NULL, 0); // send module, 0 is to receive partially (without trimbits etc) if (ret != FAIL) { - ret = sendModuleGeneral(file_des, &myModule, (myDetectorType == JUNGFRAU) ? 0 : 1); + ret = sendModuleGeneral(file_des, &module, (myDetectorType == JUNGFRAU) ? 0 : 1); } - if(myChip != NULL) free(myChip); - if(myChan != NULL) free(myChan); - if(myDac != NULL) free(myDac); - if(myAdc != NULL) free(myAdc); - + if (myChip != NULL) free(myChip); + if (myChan != NULL) free(myChan); + if (myDac != NULL) free(myDac); + if (myAdc != NULL) free(myAdc); return ret; } @@ -1306,100 +1119,63 @@ int get_module(int file_des) { int set_settings(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int arg=-1; - int retval=-1; - enum detectorSettings isett=-1; - sprintf(mess,"set settings failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + enum detectorSettings isett = GET_SETTINGS; + enum detectorSettings retval = GET_SETTINGS; -#ifdef MYTHEN3D - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Set Settings) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); -#else + if (receiveData(file_des, &isett, sizeof(isett), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Setting settings %d\n", isett)); - // receive arguments - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - isett=arg; + //set & get + if ((isett == GET_SETTINGS) || ((isett != GET_SETTINGS) && (Server_VerifyLock() != FAIL))) { - // execute action - if (differentClients && lockStatus && isett!=GET_SETTINGS) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - - switch(isett) { - case GET_SETTINGS: - case UNINITIALIZED: + // check index + switch(isett) { + case GET_SETTINGS: #ifdef JUNGFRAUD - case DYNAMICGAIN: - case DYNAMICHG0: - case FIXGAIN1: - case FIXGAIN2: - case FORCESWITCHG1: - case FORCESWITCHG2: - break; - default: - ret = FAIL; - sprintf(mess,"Setting (%d) is not implemented for this detector.\n" - "Options are dynamicgain, dynamichg0, fixgain1, fixgain2, " - "forceswitchg1 and forceswitchg2.\n", isett); - cprintf(RED, "Warning: %s", mess); - break; -// other detectors -// #elif GOTTHARDD, MOENCHD, PROPIXD -#else - break; - default: - ret = FAIL; -#ifdef EIGERD - sprintf(mess,"Cannot set settings via SET_SETTINGS, use SET_MODULE\n"); -#else - sprintf(mess,"Setting (%d) is not implemented for this detector\n", isett); + case DYNAMICGAIN: + case DYNAMICHG0: + case FIXGAIN1: + case FIXGAIN2: + case FORCESWITCHG1: + case FORCESWITCHG2: +#elif GOTTHARDD + case DYNAMICGAIN: + case HIGHGAIN: + case LOWGAIN: + case MEDIUMGAIN: + case VERYHIGHGAIN: #endif - cprintf(RED, "Warning: %s", mess); - break; -#endif - } - - if (ret != FAIL) { -#ifdef VERBOSE - printf("Changing settings to %d\n", isett); -#endif - retval=setSettings(isett); -#ifdef VERBOSE - printf("Settings changed to %d\n", isett); -#endif - if (retval == isett || isett < 0) { - ret=OK; - } else { - ret = FAIL; - sprintf(mess,"Changing settings : wrote %d but read %d\n", isett, retval); - cprintf(RED, "Warning: %s", mess); + break; + default: + if (myDetectorType == EIGER) { + ret = FAIL; + sprintf(mess, "Cannot set settings via SET_SETTINGS, use SET_MODULE\n"); + FILE_LOG(logERROR,(mess)); + } else + modeNotImplemented("Settings Index", (int)isett); + break; } - } - // set to default dacs, -//# also for #elif GOTTHARDD, MOENCHD, PROPIXD -#ifdef JUNGFRAUD - if (ret == OK && isett >= 0) { - ret = setDefaultDacs(); - if (ret == FAIL) { - strcpy(mess,"Could change settings, but could not set to default dacs\n"); - cprintf(RED, "Warning: %s", mess); + + // if index is okay, set & get + if (ret == OK) { + retval = setSettings(isett); + FILE_LOG(logDEBUG5, ("Settings: %d\n", retval)); + validate((int)isett, (int)retval, "set settings", 0); +#if defined(JUNGFRAUD) || defined (GOTTHARDD) + if (ret == OK && isett >= 0) { + ret = setDefaultDacs(); + if (ret == FAIL) { + strcpy(mess,"Could change settings, but could not set to default dacs\n"); + FILE_LOG(logERROR,(mess)); + } } +#endif } -#endif -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + } + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -1407,33 +1183,19 @@ int set_settings(int file_des) { int get_threshold_energy(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"get threshold energy failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int retval = -1; + FILE_LOG(logDEBUG5, ("Getting Threshold energy\n")); #ifndef EIGERD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Get Threshold Energy) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - - // execute action -#ifdef VERBOSE - printf("Getting threshold energy \n"); + // only get + retval = getThresholdEnergy(); + FILE_LOG(logDEBUG5, ("Threshold energy: %d eV\n", retval)); #endif - retval=getThresholdEnergy(); -#ifdef VERBOSE - printf("Threshold is %d eV\n", retval); -#endif -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -1442,51 +1204,39 @@ int get_threshold_energy(int file_des) { int start_acquisition(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sprintf(mess,"start acquisition failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); + FILE_LOG(logDEBUG5, ("Starting Acquisition\n")); + // only set + if (Server_VerifyLock() != FAIL) { + ret = startStateMachine(); + if (ret == FAIL) { + sprintf(mess, "Could not start acquisition\n"); + FILE_LOG(logERROR,(mess)); + } + FILE_LOG(logDEBUG5, ("Starting Acquisition ret: %d\n", ret)); } - else { - printf("Starting acquisition\n"); - ret=startStateMachine(); - if (ret==FAIL) - cprintf(RED, "Warning: %s", mess); - } - - Server_SendResult(file_des, INT32, 1, NULL, 0); - - return ret; + return Server_SendResult(file_des, INT32, 1, NULL, 0); } int stop_acquisition(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sprintf(mess,"stop acquisition failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); + FILE_LOG(logDEBUG5, ("Stopping Acquisition\n")); + // only set + if (Server_VerifyLock() != FAIL) { + ret = stopStateMachine(); + if (ret == FAIL) { + sprintf(mess, "Could not stop acquisition\n"); + FILE_LOG(logERROR,(mess)); + } + FILE_LOG(logDEBUG5, ("Stopping Acquisition ret: %d\n", ret)); } - else { - printf("Stopping acquisition\n"); - ret=stopStateMachine(); - if (ret==FAIL) - cprintf(RED, "Warning: %s", mess); - } - - Server_SendResult(file_des, INT32, 1, NULL, 0); - - return ret; + return Server_SendResult(file_des, INT32, 1, NULL, 0); } @@ -1494,36 +1244,24 @@ int stop_acquisition(int file_des) { int start_readout(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sprintf(mess,"start readout failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + FILE_LOG(logDEBUG5, ("Starting readout\n")); #ifdef JUNGFRAUD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Start Readout) is not implemented for this detector\n"); - cprintf(RED, "%s", mess); + functionNotImplemented(); #else - - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { - printf("Starting readout\n"); - ret=startReadOut(); - if (ret==FAIL) - cprintf(RED, "Warning: %s", mess); + // only set + if (Server_VerifyLock() != FAIL) { + ret = startReadOut(); + if (ret == FAIL) { + sprintf(mess, "Could not start readout\n"); + FILE_LOG(logERROR,(mess)); + } + FILE_LOG(logDEBUG5, ("Starting readout ret: %d\n", ret)); } #endif - - Server_SendResult(file_des, INT32, 1, NULL, 0); - - return ret; + return Server_SendResult(file_des, INT32, 1, NULL, 0); } @@ -1532,18 +1270,15 @@ int start_readout(int file_des) { int get_run_status(int file_des) { - int ret=OK,ret1=OK; - enum runStatus retval=ERROR; + ret = OK; + memset(mess, 0, sizeof(mess)); + enum runStatus retval = ERROR; - // execute action -#ifdef VERBOSE - printf("Getting status\n"); -#endif + FILE_LOG(logDEBUG5, ("Getting status\n")); + // only get retval = getRunStatus(); - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + FILE_LOG(logDEBUG5, ("Status: %d\n", retval)); + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -1551,55 +1286,44 @@ int get_run_status(int file_des) { int start_and_read_all(int file_des) { - ret = FAIL; -#ifdef VERBOSE - printf("Starting and reading all frames\n"); -#endif + ret = OK; + memset(mess, 0, sizeof(mess)); - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); + FILE_LOG(logDEBUG5, ("Starting Acquisition and read all frames\n")); + // start state machine + FILE_LOG(logDEBUG5, ("Stopping Acquisition\n")); + // only set + if (Server_VerifyLock() != FAIL) { + ret = startStateMachine(); + if (ret == FAIL) { + sprintf(mess, "Could not start acquisition\n"); + FILE_LOG(logERROR,(mess)); + } + FILE_LOG(logDEBUG5, ("Starting Acquisition ret: %d\n", ret)); - - Server_SendResult(file_des, INT32, 1 , NULL, 0); - - return ret; } - startStateMachine(); - read_all(file_des); - return ret; + + // lock or acquisition start error + if (ret == FAIL) + return Server_SendResult(file_des, INT32, 1 , NULL, 0); + + // read all (again validate lock, but should pass and not fail) + return read_all(file_des); } int read_all(int file_des) { - ret = FAIL; - int n=0; - sprintf(mess, "read all frame failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - - Server_SendResult(file_des, INT32, 1 , NULL, 0); - - return ret; + FILE_LOG(logDEBUG5, ("Reading all frames\n")); + // only set + if (Server_VerifyLock() != FAIL) { + readFrame(&ret, mess); } - - readFrame(&ret, mess); - if(ret == FAIL) - cprintf(RED,"%s\n",mess); - else - cprintf(GREEN,"%s",mess); - - Server_SendResult(file_des, INT32, 1 , NULL, 0); - - return ret; + return Server_SendResult(file_des, INT32, 1 , NULL, 0); } @@ -1608,92 +1332,81 @@ int read_all(int file_des) { int set_timer(int file_des) { - int ret=OK,ret1=OK; - int n=0; - enum timerIndex ind=0; - int64_t tns=-1; - int64_t retval=-1; - sprintf(mess,"set timer failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int64_t args[2] = {-1,-1}; + int64_t retval = -1; - // receive arguments - n = receiveData(file_des,&ind,sizeof(ind),INT32); - if (n < 0) return printSocketReadError(); - - n = receiveData(file_des,&tns,sizeof(tns),INT64); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus && tns!=-1) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { -#ifdef VERBOSE - printf("setting timer %d to %lld ns\n",ind,tns); -#endif + if (receiveData(file_des, args, sizeof(args), INT64) < 0) + return printSocketReadError(); + enum timerIndex ind = (int)args[0]; + int64_t tns = args[1]; #ifdef EIGERD - int64_t subexptime = 0; + int64_t subexptime = 0; #endif - switch(ind) { + FILE_LOG(logDEBUG5, ("Setting timer index %d to %lld ns\n", ind, tns)); + + // set & get + if ((tns == -1) || ((tns != -1) && (Server_VerifyLock() != FAIL))) { + + // check index + switch (ind) { + case FRAME_NUMBER: + case ACQUISITION_TIME: + case FRAME_PERIOD: + case CYCLES_NUMBER: +#ifdef JUNGFRAUD + case DELAY_AFTER_TRIGGER: +#endif + retval = setTimer(ind, tns); + break; #ifdef JUNGFRAUD case STORAGE_CELL_NUMBER: if (tns > MAX_STORAGE_CELL_VAL) { - ret=FAIL; + ret = FAIL; strcpy(mess,"Max Storage cell number should not exceed 15\n"); - cprintf(RED, "Warning: %s", mess); + FILE_LOG(logERROR,(mess)); break; } + retval = setTimer(ind,tns); + break; #endif #ifdef EIGERD case SUBFRAME_ACQUISITION_TIME: - if (tns > ((int64_t)MAX_SUBFRAME_EXPOSURE_VAL_IN_10NS*10) ){ - ret=FAIL; + if (tns > ((int64_t)MAX_SUBFRAME_EXPOSURE_VAL_IN_10NS*10) ) { + ret = FAIL; strcpy(mess,"Sub Frame exposure time should not exceed 5.368 seconds\n"); - cprintf(RED, "Warning: %s", mess); + FILE_LOG(logERROR,(mess)); break; } retval = setTimer(ind,tns); break; case SUBFRAME_DEADTIME: subexptime = setTimer(SUBFRAME_ACQUISITION_TIME, -1); - if ((tns + subexptime) > ((int64_t)MAX_SUBFRAME_EXPOSURE_VAL_IN_10NS*10) ){ - ret=FAIL; + if ((tns + subexptime) > ((int64_t)MAX_SUBFRAME_EXPOSURE_VAL_IN_10NS*10) ) { + ret = FAIL; sprintf(mess,"Sub Frame Period should not exceed 5.368 seconds. " - "So sub frame dead time should not exceed %lfu seconds (subexptime = %lf seconds)\n", - ((((int64_t)MAX_SUBFRAME_EXPOSURE_VAL_IN_10NS*10) - subexptime)/1E9), (subexptime/1E9)); - cprintf(RED, "Warning: %s", mess); + "So sub frame dead time should not exceed %lfu seconds " + "(subexptime = %lf seconds)\n", + ((((int64_t)MAX_SUBFRAME_EXPOSURE_VAL_IN_10NS*10) - subexptime)/1E9), + (subexptime/1E9)); + FILE_LOG(logERROR,(mess)); break; } retval = setTimer(ind,tns); break; #endif -#ifdef JUNGFRAUD - case DELAY_AFTER_TRIGGER: -#elif MYTHEN3D - case DELAY_AFTER_TRIGGER: - case GATES_NUMBER: - case PROBES_NUMBER: - case SAMPLES_JCTB: -#endif - case FRAME_NUMBER: - case ACQUISITION_TIME: - case FRAME_PERIOD: - case CYCLES_NUMBER: - retval = setTimer(ind,tns); - break; default: - ret = FAIL; - sprintf(mess,"Timer Index (%d) is not implemented for this detector\n", (int) ind); - cprintf(RED, "%s", mess); + modeNotImplemented("Timer index", (int)ind); break; } - + // validate + validate64(tns, retval, "set timer", 0); } - - Server_SendResult(file_des, INT64, 1, &retval, sizeof(retval)); - - return ret; + if (ret != FAIL) { + FILE_LOG(logDEBUG5, ("Timer index %d: %lld\n", ind, retval)); + } + return Server_SendResult(file_des, INT64, 1, &retval, sizeof(retval)); } @@ -1702,48 +1415,29 @@ int set_timer(int file_des) { - - int get_time_left(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int64_t retval=-1; - sprintf(mess,"get timer left failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + enum timerIndex ind = -1; + int64_t retval = -1; + if (receiveData(file_des, &ind, sizeof(ind), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Getting timer left index %d\n", ind)); - // receive arguments - enum timerIndex ind=0; - n = receiveData(file_des,&ind,sizeof(ind),INT32); - if (n < 0) return printSocketReadError(); - -#ifdef VERBOSE - printf("getting time left on timer %d \n",ind); -#endif - -#ifdef JUNGFRAUD - if (ind == DELAY_AFTER_TRIGGER) { - ret = FAIL; - sprintf(mess,"Timer Left Index (%d) is not implemented for this release.\n", (int)ind); - cprintf(RED, "%s", mess); - } else { -#endif - - switch(ind) { + // only get + // check index + switch(ind) { #ifdef EIGERD case MEASURED_PERIOD: case MEASURED_SUBPERIOD: #elif JUNGFRAUD case FRAMES_FROM_START: case FRAMES_FROM_START_PG: -#elif MYTHEN3D - case GATES_NUMBER: - case PROBES_NUMBER: - case SAMPLES_JCTB: -#endif -#ifndef EIGERD -#ifndef JUNGFRAUD +#elif GOTTHARDD case GATES_NUMBER: #endif +#if defined(GOTTHARDD) || defined(JUNGFRAUD) case FRAME_NUMBER: case ACQUISITION_TIME: case FRAME_PERIOD: @@ -1753,25 +1447,22 @@ int get_time_left(int file_des) { case ACTUAL_TIME: case MEASUREMENT_TIME: #endif - retval=getTimeLeft(ind); + retval = getTimeLeft(ind); + FILE_LOG(logDEBUG5, ("Timer left index %d: %lld\n", ind, retval)); break; - default: - ret = FAIL; - sprintf(mess,"Timer Left Index (%d) is not implemented for this detector\n", (int)ind); - cprintf(RED, "%s", mess); - break; - } -#ifdef VERBOSE - printf("Time left on timer %d is %lld\n",ind, retval); -#endif - #ifdef JUNGFRAUD - } // end of if (ind == DELAY_AFTER_TRIGGER) + case DELAY_AFTER_TRIGGER: + ret = FAIL; + sprintf(mess,"Timer Left Index (%d) is not implemented for this release.\n", (int)ind); + FILE_LOG(logERROR,(mess)); + break; #endif - Server_SendResult(file_des, INT64, 1, &retval, sizeof(retval)); - - return ret; + default: + modeNotImplemented("Timer left index", (int)ind); + break; + } + return Server_SendResult(file_des, INT64, 1, &retval, sizeof(retval)); } @@ -1780,76 +1471,63 @@ int get_time_left(int file_des) { int set_dynamic_range(int file_des) { - int retval[2]; - int ret=OK,ret1=OK; - int rateret=OK,rateret1=OK; - int n=0; - int dr=-1; - int retval=-1; - sprintf(mess,"set dynamic range failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int dr = -1; + int retval = -1; - // receive arguments - n = receiveData(file_des,&dr,sizeof(dr),INT32); - if (n < 0) return printSocketReadError(); + if (receiveData(file_des, &dr, sizeof(dr), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Setting dr to %d\n", dr)); - // execute action - if (differentClients && lockStatus && dr>=0) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { - switch(dr){ + // set & get + if ((dr == -1) || ((dr != -1) && (Server_VerifyLock() != FAIL))) { + +#ifdef EIGERD + int old_dr = setDynamicRange(-1); +#endif + // check dr + switch(dr) { case -1: case 16: #ifdef EIGERD case 4: case 8: case 32: #endif - break; + retval = setDynamicRange(dr); + FILE_LOG(logDEBUG5, ("Dynamic range: %d\n", retval)); + validate(dr, retval, "set dynamic range", 0); + if (dr >= 0) + dataBytes=calculateDataBytes(); + break; default: - ret = FAIL; - sprintf(mess,"Dynamic Range (%d) is not implemented for this detector\n", dr); - cprintf(RED, "Warning: %s", mess); + modeNotImplemented("Dynamic range", dr); + break; } - } - if(ret == OK){ + #ifdef EIGERD - int old_dr = setDynamicRange(-1); - retval=setDynamicRange(dr); - if (dr>=0 && retval!=dr) - ret=FAIL; - //look at rate correction only if dr change worked - if((ret==OK) && (dr!=32) && (dr!=16) && (dr!=-1) && (getRateCorrectionEnable())){ - setRateCorrection(0); - rateret = FAIL; - strcpy(mess,"Switching off Rate Correction. Must be in 32 or 16 bit mode\n"); - cprintf(RED,"%s",mess); - }else{ - //setting it if dr changed from 16 to 32 or vice versa with tau value as in rate table - if((dr!=-1) && (old_dr != dr) && getRateCorrectionEnable() && (dr == 16 || dr == 32)){ + if (dr != -1 && getRateCorrectionEnable()) { + // 4 or 8 bit, switch off rate corr (only if dr worked) + if ((dr != 32) && (dr != 16) && (ret == OK)) { + setRateCorrection(0); + ret = FAIL; + strcpy(mess,"Switching off Rate Correction. Must be in 32 or 16 bit mode\n"); + FILE_LOG(logERROR,(mess)); + } + + // 16, 32 (diff from old value), set new tau in rate table(-1), if it didnt work, give error + else if ((dr == 16 || dr == 32) && (old_dr != dr)) { setRateCorrection(-1); //tau_ns will not be -1 here - if(!getRateCorrectionEnable()){ + // it didnt work + if (!getRateCorrectionEnable()) { ret = FAIL; strcpy(mess,"Deactivating Rate Correction. Could not set it.\n"); - cprintf(RED,"%s",mess); + FILE_LOG(logERROR,(mess)); } } } - -#else - retval = setDynamicRange(dr); #endif - if (dr>=0) dataBytes=calculateDataBytes(); } - if ((ret == OK) && dr>=0 && retval!=dr) { - ret = FAIL; - cprintf(RED,"%s",mess); - } - - - Server_SendResult(file_des, INT32, 1, retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -1858,38 +1536,22 @@ int set_dynamic_range(int file_des) { int set_readout_flags(int file_des) { - int ret=OK,ret1=OK; - int n=0; - enum readOutFlags retval=-1; - sprintf(mess,"set readout flags failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + enum readOutFlags arg = GET_READOUT_FLAGS; + enum readOutFlags retval = GET_READOUT_FLAGS; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Setting readout flags to %d\n", arg)); #ifndef EIGERD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret=FAIL; - sprintf(mess,"Function (Set Read Out Flags) is not implemented for this detector\n"); - cprintf(RED, "%s",mess); + functionNotImplemented(); #else + // set & get + if ((arg == GET_READOUT_FLAGS) || ((arg != GET_READOUT_FLAGS) && (Server_VerifyLock() != FAIL))) { - // receive arguments - enum readOutFlags arg=-1; - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus && arg!=GET_READOUT_FLAGS) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { -#ifdef VERBOSE - printf("setting readout flags to %d\n",arg); -#endif switch(arg) { - case GET_READOUT_FLAGS: -#ifdef EIGERD case STORE_IN_RAM: case CONTINOUS_RO: case PARALLEL: @@ -1897,26 +1559,17 @@ int set_readout_flags(int file_des) { case SAFE: case SHOW_OVERFLOW: case NOOVERFLOW: -#endif - retval=setReadOutFlags(arg); + retval = setReadOutFlags(arg); + FILE_LOG(logDEBUG5, ("Read out flags: %d\n", retval)); + validate((int)arg, (int)retval, "set readout flag", 0); break; default: - ret = FAIL; - sprintf(mess,"Readout Flag Index (%d) is not implemented for this detector\n", (int)arg); - cprintf(RED, "Warning: %s", mess); + modeNotImplemented("Read out flag index", (int)arg); break; } - if (ret==OK && ((retval == -1) || ((arg!=-1) && ((retval&arg)!=arg)))){ - ret = FAIL; - sprintf(mess,"Could not change readout flag: should be 0x%x but is 0x%x\n", arg, retval); - cprintf(RED, "Warning: %s", mess); - } } #endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -1925,87 +1578,68 @@ int set_readout_flags(int file_des) { int set_roi(int file_des) { - int ret=OK,ret1=OK; - int n=0; - strcpy(mess,"set nroi failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int narg = -1; + ROI arg[MAX_ROIS]; + int nretval = -1; + ROI* retval = NULL; + + // receive number of ROIs + if (receiveData(file_des, &narg, sizeof(narg), INT32) < 0) + return printSocketReadError(); + // receive ROIs + { + int iloop = 0; + for (iloop = 0; iloop < narg; ++iloop) { + if (receiveData(file_des, &arg[iloop].xmin, sizeof(int), INT32) < 0) + return printSocketReadError(); + if (receiveData(file_des, &arg[iloop].xmax, sizeof(int), INT32) < 0) + return printSocketReadError(); + if (receiveData(file_des, &arg[iloop].ymin, sizeof(int), INT32) < 0) + return printSocketReadError(); + if (receiveData(file_des, &arg[iloop].ymax, sizeof(int), INT32) < 0) + return printSocketReadError(); + } + } + FILE_LOG(logDEBUG5, ("Set ROI (nroi:%d)\n", narg)); + { + int iloop = 0; + for (iloop = 0; iloop < narg; ++iloop) { + FILE_LOG(logDEBUG5, ("%d: %d\t%d\t%d\t%d\n", + arg[iloop].xmin, arg[iloop].xmax, arg[iloop].ymin, arg[iloop].ymax)); + } + } #ifndef GOTTHARDD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret=FAIL; - sprintf(mess,"Function (Set ROI) is not implemented for this detector\n"); - cprintf(RED, "%s",mess); + functionNotImplemented(); #else - - ROI* retval=0; - int retvalsize=0; - - // receive arguments - int nroi=-1; - ROI arg[MAX_ROIS]; - n = receiveData(file_des,&nroi,sizeof(nroi),INT32); - if (n < 0) return printSocketReadError(); - - { - int i; - if(nroi!=-1){ - for(i=0;i=0) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { -#ifdef VERBOSE - printf("setting speed variable %d to %d\n",arg,val); -#endif - switch (arg) { + // set & get + if ((val == -1) || ((val != -1) && (Server_VerifyLock() != FAIL))) { + // check index + switch(ind) { #ifdef JUNGFRAUD case ADC_PHASE: retval = adcPhase(val); - if ((val != 100000) && (retval!=val) && (val>=0)) { - ret=FAIL; - sprintf(mess,"could not change set adc phase: should be %d but is %d \n", val, retval); - cprintf(RED, "Warning: %s", mess); - } - break; -#endif -#ifdef EIGERD - case CLOCK_DIVIDER: -#elif JUNGFRAUD - case CLOCK_DIVIDER: -#elif MYTHEN3D - case DBIT_CLOCK: - case DBIT_PHASE: -#endif - retval=setSpeed(arg, val); - if ((retval!=val) && (val>=0)) { - ret=FAIL; - sprintf(mess,"could not change speed variable %d: should be %d but is %d \n",arg, val, retval); - cprintf(RED, "Warning: %s", mess); + FILE_LOG(logDEBUG5, ("ADc Phase: %d\n", retval)); + if (val != 100000) { + validate(val, retval, "set adc phase ", 0); } break; +#endif + case CLOCK_DIVIDER: + retval = setSpeed(val); + FILE_LOG(logDEBUG5, ("Clock: %d\n", retval)); + validate(val, retval, "set clock ", 0); + break; default: - ret = FAIL; - sprintf(mess,"Speed Index (%d) is not implemented for this detector\n",(int) arg); - cprintf(RED, "Warning: %s", mess); + modeNotImplemented("Speed index", (int)ind); break; } } - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -2083,9 +1691,9 @@ int set_speed(int file_des) { int exit_server(int file_des) { - ret = OK; cprintf(BG_RED,"Closing Server\n"); - Server_SendResult(file_des, INT32, 1, NULL, 0); + ret = OK; + Server_SendResult(file_des, INT32, 0, NULL, 0); return GOODBYE; } @@ -2093,41 +1701,34 @@ int exit_server(int file_des) { int lock_server(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int lock=0; - sprintf(mess,"lock server failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int lock = 0; - // receive arguments - n = receiveData(file_des,&lock,sizeof(lock),INT32); - if (n < 0) return printSocketReadError(); + if (receiveData(file_des, &lock, sizeof(lock), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Locking Server to %d\n", lock)); - // execute action - if (lock>=0) { - if (lockStatus==0 || strcmp(lastClientIP,thisClientIP)==0 || strcmp(lastClientIP,"none")==0) { - lockStatus=lock; - strcpy(lastClientIP,thisClientIP); + // set + if (lock >= 0) { + if (!lockStatus || // if it was unlocked, anyone can lock + (!strcmp(lastClientIP, thisClientIP)) || // if it was locked, need same ip + (!strcmp(lastClientIP,"none"))) { // if it was locked, must be by "none" + lockStatus = lock; + strcpy(lastClientIP, thisClientIP); } else { - ret = FAIL; - sprintf(mess,"Server already locked by %s\n", lastClientIP); - cprintf(RED, "Warning: %s", mess); + Server_LockedError(); } } - Server_SendResult(file_des, INT32, 1, &lockStatus, sizeof(lockStatus)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &lockStatus, sizeof(lockStatus)); } - int get_last_client_ip(int file_des) { - int ret=OK,ret1=OK; - - Server_SendResult(file_des, INT32, 1, lastClientIP, sizeof(lastClientIP)); - - return ret; + ret = OK; + return Server_SendResult(file_des, INT32, 1, lastClientIP, sizeof(lastClientIP)); } @@ -2136,42 +1737,34 @@ int get_last_client_ip(int file_des) { int set_port(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); - int n=0; - int p_number=-1; - sprintf(mess,"set port failed\n"); + int p_number = -1; - // receive argumets - n = receiveData(file_des,&p_number,sizeof(p_number),INT32); - if (n < 0) return printSocketReadError(); + if (receiveData(file_des, &p_number, sizeof(p_number), INT32) < 0) + return printSocketReadError(); - // execute action - int sd=-1; - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { + // set only + int sd = -1; + if ((Server_VerifyLock() != FAIL)) { + // port number too low if (p_number < 1024) { ret = FAIL; sprintf(mess,"%s port Number (%d) too low\n", (isControlServer ? "control":"stop"), p_number); - FILE_LOG(logWARNING, (mess)); + FILE_LOG(logERROR,(mess)); } else { FILE_LOG(logINFO, ("Setting %s port to %d\n", (isControlServer ? "control":"stop"), p_number)); - sd=bindSocket(p_number); + sd = bindSocket(p_number); } } Server_SendResult(file_des, INT32, 1, &p_number, sizeof(p_number)); - - if (ret!=FAIL) { + // delete old socket + if (ret != FAIL) { closeConnection(file_des); exitServer(sockfd); - sockfd=sd; + sockfd = sd; } - return ret; } @@ -2180,6 +1773,7 @@ int set_port(int file_des) { int update_client(int file_des) { ret = OK; + memset(mess, 0, sizeof(mess)); Server_SendResult(file_des, INT32, 0, NULL, 0); return send_update(file_des); } @@ -2188,72 +1782,71 @@ int update_client(int file_des) { int send_update(int file_des) { - int n=0; // if (n<0) should fail to stop talking to a closed client socket - int nm=0; + int n = 0; // if (n<0) should fail to stop talking to a closed client socket + int nm = 0; int64_t retval = 0; - enum detectorSettings t; n = sendData(file_des,lastClientIP,sizeof(lastClientIP),OTHER); if (n < 0) return printSocketReadError(); - nm=setDynamicRange(GET_FLAG); + nm = setDynamicRange(GET_FLAG); n = sendData(file_des,&nm,sizeof(nm),INT32); if (n < 0) return printSocketReadError(); - dataBytes=calculateDataBytes(); + dataBytes = calculateDataBytes(); n = sendData(file_des,&dataBytes,sizeof(dataBytes),INT32); if (n < 0) return printSocketReadError(); - t=setSettings(GET_SETTINGS); - n = sendData(file_des,&t,sizeof(t),INT32); + nm = (int)setSettings(GET_SETTINGS); + n = sendData(file_des,&nm,sizeof(nm),INT32); if (n < 0) return printSocketReadError(); #ifdef EIGERD - nm=getThresholdEnergy(GET_FLAG); + nm = getThresholdEnergy(GET_FLAG); n = sendData(file_des,&nm,sizeof(nm),INT32); if (n < 0) return printSocketReadError(); #endif - retval=setTimer(FRAME_NUMBER,GET_FLAG); + retval = setTimer(FRAME_NUMBER,GET_FLAG); n = sendData(file_des,&retval,sizeof(int64_t),INT64); if (n < 0) return printSocketReadError(); - retval=setTimer(ACQUISITION_TIME,GET_FLAG); + retval = setTimer(ACQUISITION_TIME,GET_FLAG); n = sendData(file_des,&retval,sizeof(int64_t),INT64); if (n < 0) return printSocketReadError(); #ifdef EIGERD - retval=setTimer(SUBFRAME_ACQUISITION_TIME,GET_FLAG); + retval = setTimer(SUBFRAME_ACQUISITION_TIME,GET_FLAG); n = sendData(file_des,&retval,sizeof(int64_t),INT64); if (n < 0) return printSocketReadError(); - retval=setTimer(SUBFRAME_DEADTIME,GET_FLAG); + retval = setTimer(SUBFRAME_DEADTIME,GET_FLAG); n = sendData(file_des,&retval,sizeof(int64_t),INT64); if (n < 0) return printSocketReadError(); #endif - retval=setTimer(FRAME_PERIOD,GET_FLAG); + retval = setTimer(FRAME_PERIOD,GET_FLAG); n = sendData(file_des,&retval,sizeof(int64_t),INT64); if (n < 0) return printSocketReadError(); #ifndef EIGERD - retval=setTimer(DELAY_AFTER_TRIGGER,GET_FLAG); + retval = setTimer(DELAY_AFTER_TRIGGER,GET_FLAG); n = sendData(file_des,&retval,sizeof(int64_t),INT64); if (n < 0) return printSocketReadError(); #endif #if !defined(EIGERD) && !defined(JUNGFRAUD) - retval=setTimer(GATES_NUMBER,GET_FLAG); + retval = setTimer(GATES_NUMBER,GET_FLAG); n = sendData(file_des,&retval,sizeof(int64_t),INT64); if (n < 0) return printSocketReadError(); #endif - retval=setTimer(CYCLES_NUMBER,GET_FLAG); + retval = setTimer(CYCLES_NUMBER,GET_FLAG); n = sendData(file_des,&retval,sizeof(int64_t),INT64); if (n < 0) return printSocketReadError(); - if (lockStatus==0) { + if (lockStatus == 0) { strcpy(lastClientIP,thisClientIP); } @@ -2266,141 +1859,145 @@ int send_update(int file_des) { int configure_mac(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int retval=-100; - sprintf(mess,"configure mac failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + char args[9][50]; + memset(args, 0, sizeof(args)); + char retvals[3][50]; + memset(retvals, 0, sizeof(retvals)); + int iretval = -1; - // receive arguments - char arg[6][50]; - memset(arg, 0, sizeof(arg)); - n = receiveData(file_des,arg,sizeof(arg),OTHER); -#if defined(JUNGFRAUD) || defined(EIGERD) - int pos[3]={0,0,0}; - n = receiveData(file_des,pos,sizeof(pos),INT32); + if (receiveData(file_des, args, sizeof(args), OTHER) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("\n Configuring UDP Destination\n")); +#ifdef GOTTHARDD + FILE_LOG(logDEBUG5, ("Digital Test Bit %d\t", digitalTestBit); #endif - if (n < 0) return printSocketReadError(); - - uint32_t ipad; - uint64_t imacadd; - uint64_t idetectormacadd; - uint32_t udpport; - uint32_t udpport2; - uint32_t detipad; - sscanf(arg[0], "%x", &ipad); + uint32_t dstIp = 0; + sscanf(args[0], "%x", &dstIp); + FILE_LOG(logDEBUG5, ("Dst Ip Addr: %d.%d.%d.%d = 0x%x \n", + (dstIp >> 24) & 0xff, (dstIp >> 16) & 0xff, (dstIp >> 8) & 0xff, (dstIp) & 0xff, + dstIp)); + uint64_t dstMac = 0; #ifdef VIRTUAL - sscanf(arg[1], "%lx", &imacadd); + sscanf(args[1], "%lx", &dstMac); #else - sscanf(arg[1], "%llx", &imacadd); + sscanf(args[1], "%llx", &dstMac); #endif - sscanf(arg[2], "%x", &udpport); -#ifdef VIRTUAL - sscanf(arg[3], "%lx", &idetectormacadd); -#else - sscanf(arg[3], "%llx", &idetectormacadd); -#endif - sscanf(arg[4], "%x", &detipad); - sscanf(arg[5], "%x", &udpport2); - - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { -#ifdef VERBOSE - int i; - //#ifdef GOTTHARD - //printf("\ndigital_test_bit in server %d\t",digitalTestBit); - //#endif - printf("\nipadd %x\t",ipad); - printf("destination ip is %d.%d.%d.%d = 0x%x \n",(ipad>>24)&0xff,(ipad>>16)&0xff,(ipad>>8)&0xff,(ipad)&0xff,ipad); - 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("udp port:0x%x\n",udpport); - printf("detector macad:%llx\n",idetectormacadd); - for (i=0;i<6;i++) - printf("detector mac adress %d is 0x%x \n",6-i,(unsigned int)(((idetectormacadd>>(8*i))&0xFF))); - printf("detipad %x\n",detipad); - printf("udp port2:0x%x\n",udpport2); - printf("\n"); - printf("Configuring MAC at port %x\n", udpport); - -#if defined(JUNGFRAUD) || defined(EIGERD) - printf("Position: [%d,%d,%d]\n", pos[0],pos[1],pos[2]); -#endif -#endif - if(getRunStatus() == RUNNING){ - ret = stopStateMachine(); + FILE_LOG(logDEBUG5, ("Dst Mac Addr: (0x) ")); + { + int iloop = 5; + for (iloop = 5; iloop >= 0; --iloop) { + FILE_LOG(logDEBUG5, ("%x", (unsigned int)(((dstMac >> (8 * iloop)) & 0xFF)))); + if (iloop > 0) { + FILE_LOG(logDEBUG5, (":")); + } } - if(ret==FAIL) { - sprintf(mess,"Could not stop detector acquisition to configure mac\n"); - cprintf(RED, "Warning: %s", mess); - } - else { -#ifdef EIGERD - // change mac to hardware mac, (for 1 gbe) change ip to hardware ip - if (idetectormacadd != getDetectorMAC()){ - printf("*************************************************\n"); - printf("WARNING: actual detector mac address %llx does not match " - "the one from client %llx\n", - (long long unsigned int)getDetectorMAC(), - (long long unsigned int)idetectormacadd); - idetectormacadd = getDetectorMAC(); - printf("WARNING: Matched detectormac to the hardware mac now\n"); - printf("*************************************************\n"); - } - - // always remember the ip sent from the client (could be for 10g(if not dhcp)) - if (detipad != getDetectorIP()) - dhcpipad = detipad; - - //only for 1Gbe - if(!enableTenGigabitEthernet(-1)){ - printf("*************************************************\n"); - printf("WARNING: Using DHCP IP for Configuring MAC\n"); - printf("*************************************************\n"); - detipad = getDetectorIP(); - } else - detipad = dhcpipad; + } + FILE_LOG(logDEBUG5, (" = %llx\n", dstMac)); + uint32_t dstPort = 0; + sscanf(args[2], "%x", &dstPort); + FILE_LOG(logDEBUG5, ("Dst Port: %x\n", dstPort)); + uint32_t dstPort2 = 0; + sscanf(args[5], "%x", &dstPort2); + FILE_LOG(logDEBUG5, ("Dst Port2: %x\n", dstPort2)); + uint64_t srcMac = 0; +#ifdef VIRTUAL + sscanf(args[3], "%lx", &srcMac); +#else + sscanf(args[3], "%llx", &srcMac); #endif - retval=configureMAC(ipad,imacadd,idetectormacadd,detipad,udpport,udpport2,0); //digitalTestBit); - if(retval==-1) { - ret = FAIL; - sprintf(mess,"Configure Mac failed\n"); - cprintf(RED, "Warning: %s", mess); - } - else { - printf("Configure MAC successful\n"); + FILE_LOG(logDEBUG5, ("Src Mac Addr: (0x) ")); + { + int iloop = 5; + for (iloop = 5; iloop >= 0; --iloop) { + FILE_LOG(logDEBUG5, ("%x", (unsigned int)(((srcMac >> (8 * iloop)) & 0xFF)))); + if (iloop > 0) { + FILE_LOG(logDEBUG5, (":")); + } + } + } + FILE_LOG(logDEBUG5, (" = %llx\n", srcMac)); + uint32_t srcIp = 0; + sscanf(args[4], "%x", &srcIp); + FILE_LOG(logDEBUG5, ("Src Ip Addr: %d.%d.%d.%d = 0x%x \n", + (srcIp >> 24) & 0xff, (srcIp >> 16) & 0xff, (srcIp >> 8) & 0xff, (srcIp) & 0xff, + srcIp)); #if defined(JUNGFRAUD) || defined(EIGERD) - ret = setDetectorPosition(pos); - if (ret == FAIL) { - sprintf(mess,"could not set detector position\n"); - cprintf(RED, "Warning: %s", mess); - } -#endif - } -#ifdef VERBOSE - printf("Configured MAC with retval %d\n", retval); + int pos[3] = {0, 0, 0}; + sscanf(args[6], "%x", &pos[0]); + sscanf(args[7], "%x", &pos[1]); + sscanf(args[8], "%x", &pos[2]); + FILE_LOG(logDEBUG5, ("Position: [%d, %d, %d]\n", pos[0], pos[1], pos[2])); #endif + + // set only + if ((Server_VerifyLock() != FAIL)) { + + // stop detector if it was running + if (getRunStatus() != IDLE) { + ret = FAIL; + sprintf(mess, "Cannot configure mac when detector is not idle\n"); + FILE_LOG(logERROR,(mess)); + } + + else { +#ifdef EIGERD + // change mac to hardware mac + if (srcMac != getDetectorMAC()) { + FILE_LOG(logERROR, ("actual detector mac address %llx does not match " + "the one from client %llx\n", + (long long unsigned int)getDetectorMAC(), + (long long unsigned int)srcMac)); + srcMac = getDetectorMAC(); + FILE_LOG(logERROR,("matched detectormac to the hardware mac now\n")); } - } + // always remember the ip sent from the client (could be for 10g(if not dhcp)) + if (srcIp != getDetectorIP()) + dhcpipad = srcIp; - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); + //only for 1Gbe, change ip to hardware ip + if (!enableTenGigabitEthernet(-1)) { + FILE_LOG(logERROR, ("using DHCP IP for Configuring MAC\n")); + srcIp = getDetectorIP(); + } + // 10 gbe (use ip given from client) + else + srcIp = dhcpipad; -#ifdef EIGERD - if (ret != FAIL) { - char arg[2][50]; - memset(arg, 0, sizeof(arg)); - sprintf(arg[0],"%llx",(long long unsigned int)idetectormacadd); - sprintf(arg[1],"%x",detipad); - n += sendData(file_des,arg,sizeof(arg),OTHER); - } #endif +#ifdef GOTTHARDD + iretval = configureMAC(dstIp, dstMac, srcMac, srcIp, dstPort, dstPort2, digitalTestBit); + FILE_LOG(logDEBUG5, ("Configure mac retval: %d\n", iretval)); + FILE_LOG(logINFO, ("Configure MAC successful: %d\n", iretval)); +#else + iretval = configureMAC(dstIp, dstMac, srcMac, srcIp, dstPort, dstPort2); + FILE_LOG(logDEBUG5, ("Configure mac retval: %d\n", iretval)); - return ret; + if (iretval == -1) { + ret = FAIL; + sprintf(mess,"Configure Mac failed\n"); + FILE_LOG(logERROR,(mess)); + } else { + FILE_LOG(logINFO, ("Configure MAC successful\n")); + ret = setDetectorPosition(pos); + if (ret == FAIL) { + sprintf(mess, "Could not set detector position\n"); + FILE_LOG(logERROR,(mess)); + } + } +#endif + // set retval vals + if (ret != FAIL) { + sprintf(retvals[0],"%x", iretval); + sprintf(retvals[1],"%llx", (long long unsigned int)srcMac); + sprintf(retvals[2],"%x", srcIp); + } + } + } + + return Server_SendResult(file_des, OTHER, 1, retvals, sizeof(retvals)); } @@ -2408,63 +2005,49 @@ int configure_mac(int file_des) { int load_image(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"Loading image failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int args[2] = {-1, -1}; + int retval = -1; + + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + enum imageType index = args[0]; + char* ImageVals = NULL; + if (args[1] > 0) { + ImageVals = (char*)malloc(args[1]); + if (receiveData(file_des, ImageVals, args[1], OTHER) < 0) { + free(ImageVals); + return printSocketReadError(); + } + } + FILE_LOG(logDEBUG5, ("Loading %s image (ind:%d)\n", (index == DARK_IMAGE) ? "dark" : + ((index == GAIN_IMAGE) ? "gain" : "unknown"), index)); #ifndef GOTTHARDD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Load Image) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - // receive arguments - enum imageType index=0; - char ImageVals[dataBytes] = {0}; - n = receiveData(file_des,&index,sizeof(index),INT32); - if (n < 0) return printSocketReadError(); - - n = receiveData(file_des,ImageVals,dataBytes,OTHER); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { + // set only + if (Server_VerifyLock() != FAIL) { switch (index) { case DARK_IMAGE : -#ifdef VERBOSE - printf("Loading Dark image\n"); -#endif case GAIN_IMAGE : -#ifdef VERBOSE - printf("Loading Gain image\n"); -#endif - retval=loadImage(index,ImageVals); - if (retval==-1) { + retval = loadImage(index, ImageVals); + FILE_LOG(logDEBUG5, ("Loading image retval: %d\n", retval)); + if (retval == -1) { ret = FAIL; - cprintf(RED, "Warning: %s", mess); + sprintf(mess, "Could not load image\n"); + FILE_LOG(logERROR,(mess)); } break; default: - ret = FAIL; - sprintf(mess,"Load Image Index (%d) is not implemented for this detector\n", (int)index); - cprintf(RED, "Warning: %s", mess); + modeNotImplemented("Image index", (int)index); break; } } #endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -2473,47 +2056,30 @@ int load_image(int file_des) { int read_counter_block(int file_des) { - int ret=OK,ret1=OK; - int n=0; - char CounterVals[dataBytes]; - memset(CounterVals, 0, dataBytes); - sprintf(mess,"Read counter block failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int startACQ = -1; + char retval[dataBytes]; + memset(retval, 0, dataBytes); + + if (receiveData(file_des, &startACQ, sizeof(startACQ), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Read counter block with start acq bit: %d\n", startACQ)); #ifndef GOTTHARDD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Read Counter Block) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - // receive arguments - int startACQ=-1; - n = receiveData(file_des,&startACQ,sizeof(startACQ),INT32); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { - ret=readCounterBlock(startACQ,CounterVals); - if (ret == FAIL) - cprintf(RED, "Warning: %s", mess); -#ifdef VERBOSE - int i; - for(i=0;i<6;i++) - printf("%d:%d\t",i,CounterVals[i]); -#endif + // only set + if (Server_VerifyLock() != FAIL) { + ret = readCounterBlock(startACQ, retval); + if (ret == FAIL) { + strcpy(mess, "Could not read counter block\n"); + FILE_LOG(logERROR,(mess)); + } } #endif - - Server_SendResult(file_des, OTHER, 1, CounterVals, dataBytes); - - return ret; + return Server_SendResult(file_des, OTHER, 1, retval, dataBytes); } @@ -2521,84 +2087,48 @@ int read_counter_block(int file_des) { int reset_counter_block(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sprintf(mess,"Reset counter block failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int startACQ = -1; + char retval[dataBytes]; + memset(retval, 0, dataBytes); + + if (receiveData(file_des, &startACQ, sizeof(startACQ), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Reset counter block with start acq bit: %d\n", startACQ)); #ifndef GOTTHARDD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Reset Counter Block) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - // receive arguments - int startACQ=-1; - n = receiveData(file_des,&startACQ,sizeof(startACQ),INT32); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { - ret=resetCounterBlock(startACQ); - if (ret == FAIL) - cprintf(RED, "Warning: %s", mess); + // only set + if (Server_VerifyLock() != FAIL) { + ret = resetCounterBlock(startACQ, retval); + if (ret == FAIL) { + strcpy(mess, "Could not reset counter block\n"); + FILE_LOG(logERROR, (mess)); + } } #endif - - Server_SendResult(file_des, INT32, 1, NULL, 0); - - return ret; + return Server_SendResult(file_des, INT32, 1, NULL, 0); } -int calibrate_pedestal(int file_des){ - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"calibrate pedestal failed\n"); +int calibrate_pedestal(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int frames = -1; + int retval = -1; + if (receiveData(file_des, &frames, sizeof(frames), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Calibrate pedestal, frames: %d\n", frames)); -#ifndef GOTTHARDD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Calibrate Pedestal) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); -#else - - // receive arguments - int frames=-1; - n = receiveData(file_des,&frames,sizeof(frames),INT32); - if (n < 0) return printSocketReadError(); - - - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { - ret=calibratePedestal(frames); - if (ret == FAIL) - cprintf(RED, "Warning: %s", mess); - } -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + functionNotImplemented(); + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -2609,432 +2139,177 @@ int calibrate_pedestal(int file_des){ int enable_ten_giga(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"Enabling/disabling 10GbE failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Enable/ Disable 10GbE : %d\n", arg)); - // execute action #ifndef EIGERD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Enable 10 GbE) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - - // receive arguments - int arg=-1; - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus && arg!=-1) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { -#ifdef VERBOSE - printf("Enabling/Disabling 10Gbe :%d \n",arg); -#endif - retval=enableTenGigabitEthernet(arg); - if((arg != -1) && (retval != arg)) { - ret=FAIL; - cprintf(RED, "Warning: %s", mess); - } + // set & get + if ((arg == -1) || ((arg != -1) && (Server_VerifyLock() != FAIL))) { + retval = enableTenGigabitEthernet(arg); + FILE_LOG(logDEBUG5, ("10GbE: %d\n", retval)); + validate(arg, retval, "enable/disable 10GbE", 0); } #endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } -int set_all_trimbits(int file_des){ - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"setting all trimbits failed\n"); +int set_all_trimbits(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Set all trmbits to %d\n", arg)); #ifndef EIGERD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Set All Trimbits) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - // receive arguments - int arg=-1; - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - - - // execute action - if (differentClients && lockStatus && arg!=-1) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); + // set + if (arg >= 0 && Server_VerifyLock() != FAIL) { + ret = setAllTrimbits(arg); + //changes settings to undefined + setSettings(UNDEFINED); + FILE_LOG(logERROR, ("Settings has been changed to undefined (change all trimbits)\n")); } - else { -#ifdef VERBOSE - printf("setting all trimbits to %d\n",arg); + // get + retval = getAllTrimbits(); + FILE_LOG(logDEBUG5, ("All trimbits: %d\n", retval)); + validate(arg, retval, "set all trimbits", 0); #endif - if(arg < -1){ - ret = FAIL; - strcpy(mess,"Cant set trimbits to this value\n"); - cprintf(RED, "Warning: %s", mess); - }else { - if(arg >= 0){ - ret = setAllTrimbits(arg); - //changes settings to undefined - setSettings(UNDEFINED); - cprintf(RED,"Settings has been changed to undefined (change all trimbits)\n"); - } - retval = getAllTrimbits(); - if (arg!=-1 && arg!=retval) { - ret=FAIL; - sprintf(mess,"Could not set all trimbits: should be %d but is %d\n", arg, retval); - cprintf(RED, "Warning: %s", mess); - } - } - } -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } + + int set_ctb_pattern(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sprintf(mess,"Could not set pattern\n"); - -#ifndef MYTHEN3D - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - - ret = FAIL; - sprintf(mess,"Function (Set CTB Pattern) is not implemented for this detector\n"); - cprintf(RED, "Error: %s", mess); - - Server_SendResult(file_des, INT32, 0, NULL, 0);// make sure client doesnt expect a retval if not jctb - - return ret; - -#else - - int retval=-1; - int mode = -1; - int addr = -1, level = -1, nl = -1, start = -1, stop = -1; - uint64_t word = -1,retval64 = -1, t = -1; - - n = receiveDataOnly(file_des, &mode, sizeof(mode)); - printf("pattern mode is %d\n",mode); - - switch (mode) { - - case 0: //sets word - n = receiveDataOnly(file_des,&addr,sizeof(addr)); - n = receiveDataOnly(file_des,&word,sizeof(word)); - ret=OK; - - printf("pattern addr is %d %llx\n",addr, word); - switch (addr) { - case -1: - retval64=writePatternIOControl(word); - break; - case -2: - retval64=writePatternClkControl(word); - break; - default: - retval64=writePatternWord(addr,word); - }; - - - //write word; - //@param addr address of the word, -1 is I/O control register, -2 is clk control register - //@param word 64bit word to be written, -1 gets - - Server_SendResult(file_des, INT32, 0, &retval64, sizeof(retval64)); - - break; - - case 1: //pattern loop - // printf("loop\n"); - n = receiveDataOnly(file_des,&level,sizeof(level)); - n = receiveDataOnly(file_des,&start,sizeof(start)); - n = receiveDataOnly(file_des,&stop,sizeof(stop)); - n = receiveDataOnly(file_des,&nl,sizeof(nl)); - - - - // printf("level %d start %x stop %x nl %d\n",level, start, stop, nl); - /** Sets the pattern or loop limits in the CTB - @param level -1 complete pattern, 0,1,2, loop level - @param start start address if >=0 - @param stop stop address if >=0 - @param n number of loops (if level >=0) - @returns OK/FAIL - */ - ret=setPatternLoop(level, &start, &stop, &nl); - - Server_SendResult(file_des, INT32, 0, retval, sizeof(retval)); -/* n += sendDataOnly(file_des,&start,sizeof(start)); - n += sendDataOnly(file_des,&stop,sizeof(stop)); - n += sendDataOnly(file_des,&nl,sizeof(nl)); - */ - break; - - - - case 2: //wait address - printf("wait\n"); - n = receiveDataOnly(file_des,&level,sizeof(level)); - n = receiveDataOnly(file_des,&addr,sizeof(addr)); - - - - /** Sets the wait address in the CTB - @param level 0,1,2, wait level - @param addr wait address, -1 gets - @returns actual value - */ - printf("wait addr %d %x\n",level, addr); - retval=setPatternWaitAddress(level,addr); - printf("ret: wait addr %d %x\n",level, retval); - ret=OK; - - Server_SendResult(file_des, INT32, 0, &retval, sizeof(retval)); - - break; - - - case 3: //wait time - printf("wait time\n"); - n = receiveDataOnly(file_des,&level,sizeof(level)); - n = receiveDataOnly(file_des,&t,sizeof(t)); - - - /** Sets the wait time in the CTB - @param level 0,1,2, wait level - @param t wait time, -1 gets - @returns actual value - */ - - ret=OK; - - retval64=setPatternWaitTime(level,t); - - Server_SendResult(file_des, INT32, 0, &retval64, sizeof(retval64)); - break; - - - - case 4: - n = receiveDataOnly(file_des,pat,sizeof(pat)); - for (addr=0; addr<1024; addr++) - writePatternWord(addr,word); - ret=OK; - retval=0; - - Server_SendResult(file_des, INT32, 0, &retval64, sizeof(retval64)); - - break; - - - - default: - ret=FAIL; - printf(mess); - sprintf(mess,"%s - wrong mode %d\n",mess, mode); - - Server_SendResult(file_des, INT32, 0, NULL, 0); - } - - - return ret; -#endif + ret = OK; + memset(mess, 0, sizeof(mess)); + functionNotImplemented(); + return Server_SendResult(file_des, INT32, 1, NULL, 0); } + int write_adc_register(int file_des) { - int ret=OK, ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"write to adc register failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int args[2] = {-1, -1}; + + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + int addr = args[0]; + int val = args[1]; + FILE_LOG(logDEBUG5, ("Writing 0x%x to ADC Register 0x%x\n", val, addr)); #ifndef JUNGFRAUD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Write ADC Register) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - - // receive arguments - int arg[2]={-1,-1}; - n = receiveData(file_des,arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - int addr=arg[0]; - int val=arg[1]; - - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { -#ifdef VERBOSE - printf("writing to register 0x%x data 0x%x\n", addr, val); + // only set + if (Server_VerifyLock() != FAIL) + setAdc(addr, val); #endif - setAdc(addr,val); -#ifdef VERBOSE - printf("Data set to 0x%x\n", retval); -#endif -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, NULL, 0); } int set_counter_bit(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"set counter bit failed \n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Set counter bit with value: %d\n", arg)); #ifndef EIGERD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - strcpy(mess,"Function (Set Counter Bit) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - // receive arguments - int arg=-1; - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus && arg!=-1) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); + // set + if (arg >= 0 && Server_VerifyLock() != FAIL) { + setCounterBit(arg); } - else { -#ifdef VERBOSE - printf("Getting/Setting/Resetting counter bit :%d \n",arg); + // get + retval = setCounterBit(-1); + FILE_LOG(logDEBUG5, ("Set counter bit retval: %d\n", retval)); + validate(arg, retval, "set counter bit", 0); #endif - retval=setCounterBit(arg); - if((arg != -1) && (retval != arg)) { - ret=FAIL; - cprintf(RED, "Warning: %s", mess); - } - } -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } + int pulse_pixel(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sprintf(mess,"pulse pixel failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int args[3] = {-1,-1,-1}; + + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Pulse pixel, n: %d, x: %d, y: %d\n", args[0], args[1], args[2])); #ifndef EIGERD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - strcpy(mess,"Function (Pulse Pixel) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - - // receive arguments - int arg[3]={-1,-1,-1}; - n = receiveData(file_des,arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { - ret=pulsePixel(arg[0],arg[1],arg[2]); - if (ret == FAIL) - cprintf(RED, "Warning: %s", mess); + // only set + if (Server_VerifyLock() != FAIL) { + ret = pulsePixel(args[0], args[1], args[2]); + if (ret == FAIL) { + strcpy(mess, "Could not pulse pixel\n"); + FILE_LOG(logERROR,(mess)); + } } #endif - - Server_SendResult(file_des, INT32, 1, NULL, 0); - - return ret; + return Server_SendResult(file_des, INT32, 1, NULL, 0); } int pulse_pixel_and_move(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sprintf(mess,"pulse pixel and move failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int args[3] = {-1,-1,-1}; + + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Pulse pixel and move, n: %d, x: %d, y: %d\n", + args[0], args[1], args[2])); #ifndef EIGERD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - strcpy(mess,"Function (Pulse Pixel and Move) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - - // receive arguments - int arg[3]={-1,-1,-1}; - n = receiveData(file_des,arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { - ret=pulsePixelNMove(arg[0],arg[1],arg[2]); - if (ret == FAIL) - cprintf(RED, "Warning: %s", mess); + // only set + if (Server_VerifyLock() != FAIL) { + ret = pulsePixelNMove(args[0], args[1], args[2]); + if (ret == FAIL) { + strcpy(mess, "Could not pulse pixel and move\n"); + FILE_LOG(logERROR,(mess)); + } } #endif - - Server_SendResult(file_des, INT32, 1, NULL, 0); - - return ret; + return Server_SendResult(file_des, INT32, 1, NULL, 0); } @@ -3043,40 +2318,27 @@ int pulse_pixel_and_move(int file_des) { int pulse_chip(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sprintf(mess,"pulse chip failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Pulse chip: %d\n", arg)); #ifndef EIGERD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - strcpy(mess,"Function (Pulse Chip) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - - // receive arguments - int arg = -1; - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { - ret=pulseChip(arg); - if (ret == FAIL) - cprintf(RED, "Warning: %s", mess); + // only set + if (Server_VerifyLock() != FAIL) { + ret = pulseChip(arg); + if (ret == FAIL) { + strcpy(mess, "Could not pulse chip\n"); + FILE_LOG(logERROR,(mess)); + } } #endif - - Server_SendResult(file_des, INT32, 1, NULL, 0); - - return ret; + return Server_SendResult(file_des, INT32, 1, NULL, 0); } @@ -3084,61 +2346,44 @@ int pulse_chip(int file_des) { int set_rate_correct(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sprintf(mess,"Set rate correct failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int64_t tau_ns = -1; + + if (receiveData(file_des, &tau_ns, sizeof(tau_ns), INT64) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Set rate correct with tau %lld\n", (long long int)tau_ns)); #ifndef EIGERD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret=FAIL; - sprintf(mess,"Function (Rate Correction) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else + // only set + if (Server_VerifyLock() != FAIL) { - // receive arguments - int64_t tau_ns=-1; - n = receiveData(file_des,&tau_ns,sizeof(tau_ns),INT64); - if (n < 0) return printSocketReadError(); + int dr = setDynamicRange(-1); - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { - printf("Setting rate correction to %lld ns\n",(long long int)tau_ns); - //set rate - //wrong bit mode - if((setDynamicRange(-1)!=32) && (setDynamicRange(-1)!=16) && (tau_ns!=0)){ - ret=FAIL; + // switching on in wrong bit mode + if ((tau_ns != 0) && (dr != 32) && (dr != 16)) { + ret = FAIL; strcpy(mess,"Rate correction Deactivated, must be in 32 or 16 bit mode\n"); - cprintf(RED, "Warning: %s", mess); + FILE_LOG(logERROR,(mess)); } - //16 or 32 bit mode - else{ - if(tau_ns < 0) + + // switching on in right mode + else { + if (tau_ns < 0) tau_ns = getDefaultSettingsTau_in_nsec(); - else if(tau_ns > 0){ + else if (tau_ns > 0) { //changing tau to a user defined value changes settings to undefined setSettings(UNDEFINED); - cprintf(RED,"Settings has been changed to undefined (tau changed)\n"); + FILE_LOG(logERROR, ("Settings has been changed to undefined (tau changed)\n")); } - int64_t retval = setRateCorrection(tau_ns); - if(tau_ns != retval){ - ret=FAIL; - cprintf(RED, "Warning: %s", mess); - } + validate64(tau_ns, retval, "set rate correction", 0); } } #endif - - Server_SendResult(file_des, INT32, 1, NULL, 0); - - return ret; + return Server_SendResult(file_des, INT32, 1, NULL, 0); } @@ -3146,30 +2391,18 @@ int set_rate_correct(int file_des) { int get_rate_correct(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int64_t retval=-1; - sprintf(mess,"Get Rate correct failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int64_t retval = -1; + FILE_LOG(logDEBUG5, ("Getting rate correction\n")); #ifndef EIGERD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret=FAIL; - sprintf(mess,"Function (Get Rate Correction) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - - - // execute action retval = getCurrentTau(); - printf("Getting rate correction %lld\n",(long long int)retval); - + FILE_LOG(logDEBUG5, ("Tau: %lld\n", (long long int)retval)); #endif - - Server_SendResult(file_des, INT64, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT64, 1, &retval, sizeof(retval)); } @@ -3177,84 +2410,60 @@ int get_rate_correct(int file_des) { int set_network_parameter(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"set network parameter failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int args[2] = {-1,-1}; + int retval = -1; -#if !defined(EIGERD) && !defined(JUNGFRAUD) - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret=FAIL; - sprintf(mess,"Function(Set Network Parmaeter) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + enum networkParameter mode = args[0]; + int value = args[1]; + enum NETWORKINDEX serverIndex = 0; + FILE_LOG(logDEBUG5, ("Set network parameter index %d to %d\n", mode, value)); + +#ifdef GOTTHARDD + functionNotImplemented(); #else - - enum NETWORKINDEX index; - - // receive arguments - enum networkParameter mode=0; - int value=-1; - n = receiveData(file_des,&mode,sizeof(mode),INT32); - if (n < 0) return printSocketReadError(); - - n = receiveData(file_des,&value,sizeof(value),INT32); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus && value >= 0) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { -#ifdef VERBOSE - printf("setting network parameter mode %d to %d\n",(int)mode,value); -#endif + // set & get + if ((value == -1) || ((value != -1) && (Server_VerifyLock() != FAIL))) { + // check index switch (mode) { - #ifdef EIGERD case FLOW_CONTROL_10G: - index = FLOWCTRL_10G; + serverIndex = FLOWCTRL_10G; break; case DETECTOR_TXN_DELAY_LEFT: - index = TXN_LEFT; + serverIndex = TXN_LEFT; break; case DETECTOR_TXN_DELAY_RIGHT: - index = TXN_RIGHT; + serverIndex = TXN_RIGHT; break; #endif case DETECTOR_TXN_DELAY_FRAME: - index = TXN_FRAME; + serverIndex = TXN_FRAME; #ifdef JUNGFRAUD if (value > MAX_TIMESLOT_VAL) { - ret=FAIL; - sprintf(mess,"Transmission delay %d should be in range: 0 - %d\n", value, MAX_TIMESLOT_VAL); - cprintf(RED, "Warning: %s", mess); + ret = FAIL; + sprintf(mess,"Transmission delay %d should be in range: 0 - %d\n", + value, MAX_TIMESLOT_VAL); + FILE_LOG(logERROR, (mess)); } #endif break; default: - ret=FAIL; - sprintf(mess,"Network Parameter Index (%d) is not implemented for this detector\n",(int) mode); - cprintf(RED, "Warning: %s", mess); + modeNotImplemented("Image index", (int)serverIndex); break; } - if (ret==OK) { - retval=setNetworkParameter(index, value); - if ((retval!=value) && (value>=0)) { - ret=FAIL; - sprintf(mess,"could not change network parameter mode %d: should be %d but is %d \n",index, value, retval); - cprintf(RED, "Warning: %s", mess); - } + // valid index + if (ret == OK) { + retval = setNetworkParameter(serverIndex, value); + FILE_LOG(logDEBUG5, ("Network Parameter index %d: %d\n", serverIndex, retval)); + validate(value, retval, "set network parameter", 0); } } #endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -3263,131 +2472,115 @@ int set_network_parameter(int file_des) { int program_fpga(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sprintf(mess,"program FPGA failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + FILE_LOG(logDEBUG5, ("Programming FPGA\n")); #ifndef JUNGFRAUD //to receive any arguments + int n = 0; while (n > 0) n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret=FAIL; - sprintf(mess,"Function (Program FPGA) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - if (!debugflag) { - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret=FAIL; - sprintf(mess,"FPGA cannot be programmed in this mode. " - "Restart on-board detector server with -update for update mode to continue.\n"); - cprintf(RED, "Warning: %s", mess); - } + // only set + if (Server_VerifyLock() != FAIL) { - else { - printf("Programming FPGA..."); - size_t filesize = 0; - size_t totalsize = 0; - size_t unitprogramsize = 0; - char* fpgasrc = NULL; - FILE* fp = NULL; - - // receive arguments - filesize - n = receiveData(file_des,&filesize,sizeof(filesize),INT32); - if (n < 0) return printSocketReadError(); - totalsize = filesize; -#ifdef VERY_VERBOSE - printf("\n\n Total size is:%d\n",totalsize); -#endif - - // execute action - if (differentClients && lockStatus) { + // not in programming mode + if (debugflag != PROGRAMMING_MODE) { + //to receive any arguments + int n = 1; + while (n > 0) + n = receiveData(file_des, mess, MAX_STR_LENGTH, OTHER); ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); + sprintf(mess,"FPGA cannot be programmed in this mode. " + "Restart on-board detector server with -update for programming mode.\n"); + FILE_LOG(logERROR,(mess)); } + else { - //opening file pointer to flash and telling FPGA to not touch flash - if(startWritingFPGAprogram(&fp) != OK) { - ret=FAIL; + FILE_LOG(logINFOBLUE, ("Programming FPGA...\n")); + + size_t filesize = 0; + size_t totalsize = 0; + size_t unitprogramsize = 0; + char* fpgasrc = NULL; + FILE* fp = NULL; + + // filesize + if (receiveData(file_des,&filesize,sizeof(filesize),INT32) < 0) + return printSocketReadError(); + totalsize = filesize; + FILE_LOG(logDEBUG5, ("Total program size is: %d\n", totalsize); + + // opening file pointer to flash and telling FPGA to not touch flash + if (startWritingFPGAprogram(&fp) != OK) { + ret = FAIL; sprintf(mess,"Could not write to flash. Error at startup.\n"); - cprintf(RED,"%s",mess); + FILE_LOG(logERROR,(mess)); } //---------------- first ret ---------------- - // ret could be swapped during sendData - ret1 = ret; - // send ok / fail - n = sendData(file_des,&ret1,sizeof(ret),INT32); - // send return argument - if (ret==FAIL) { - n += sendData(file_des,mess,sizeof(mess),OTHER); - } - //---------------- first ret ---------------- + Server_SendResult(file_des, INT32, 0, NULL, 0); - if(ret!=FAIL) { + if (ret != FAIL) { //erasing flash eraseFlash(); fpgasrc = (char*)malloc(MAX_FPGAPROGRAMSIZE); } //writing to flash part by part - while(ret != FAIL && filesize){ + while(ret != FAIL && filesize) { unitprogramsize = MAX_FPGAPROGRAMSIZE; //2mb - if(unitprogramsize > filesize) //less than 2mb + if (unitprogramsize > filesize) //less than 2mb unitprogramsize = filesize; -#ifdef VERY_VERBOSE - printf("unit size to receive is:%d\n",unitprogramsize); - printf("filesize:%d currentpointer:%d\n",filesize,currentPointer); -#endif + FILE_LOG(logDEBUG5, ("unit size to receive is:%d\n" + "filesize:%d currentpointer:%d\n", + unitprogramsize, filesize, currentPointer)); - //receive - n = receiveData(file_des,fpgasrc,unitprogramsize,OTHER); - if (n < 0) return printSocketReadError(); - if(!(unitprogramsize - filesize)){ - fpgasrc[unitprogramsize]='\0'; - filesize-=unitprogramsize; + //receive part of program + if (receiveData(file_des,fpgasrc,unitprogramsize,OTHER) < 0) + return printSocketReadError(); + + if (!(unitprogramsize - filesize)) { + fpgasrc[unitprogramsize] = '\0'; + filesize -= unitprogramsize; unitprogramsize++; - }else - filesize-=unitprogramsize; + } else + filesize -= unitprogramsize; - ret = writeFPGAProgram(fpgasrc,unitprogramsize,fp); + // write part to flash + ret = writeFPGAProgram(fpgasrc, unitprogramsize, fp); //---------------- middle rets ---------------- - // ret could be swapped during sendData - ret1 = ret; - // send ok / fail - n = sendData(file_des,&ret1,sizeof(ret),INT32); - // send return argument - if (ret==FAIL) { - n += sendData(file_des,mess,sizeof(mess),OTHER); + Server_SendResult(file_des, INT32, 0, NULL, 0); + + + + if (ret == FAIL) { cprintf(RED,"Failure: Breaking out of program receiving\n"); - } - //---------------- middle rets ---------------- - - if(ret != FAIL){ + } else { //print progress - printf("Writing to Flash:%d%%\r",(int) (((double)(totalsize-filesize)/totalsize)*100) ); + FILE_LOG(logINFO, ("Writing to Flash:%d%%\r", + (int) (((double)(totalsize-filesize)/totalsize)*100) )); fflush(stdout); } } - printf("\n"); + FILE_LOG(logINFO("\nDone copying program\n")); - //closing file pointer to flash and informing FPGA + // closing file pointer to flash and informing FPGA stopWritingFPGAprogram(fp); //free resources - if(fpgasrc != NULL) + if (fpgasrc != NULL) free(fpgasrc); - if(fp!=NULL) + if (fp != NULL) fclose(fp); -#ifdef VERY_VERBOSE - printf("Done with program receiving command\n"); -#endif + + FILE_LOG(logDEBUG5, ("Done with program receiving command\n")); if (isControlServer) { basictests(debugflag); @@ -3396,10 +2589,7 @@ int program_fpga(int file_des) { } } #endif - - Server_SendResult(file_des, INT32, 1, NULL, 0); - - return ret; + return Server_SendResult(file_des, INT32, 1, NULL, 0); } @@ -3407,177 +2597,106 @@ int program_fpga(int file_des) { int reset_fpga(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sprintf(mess,"Reset FPGA unsuccessful\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + FILE_LOG(logDEBUG5, ("Reset FPGA\n")); #ifndef JUNGFRAUD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Reset FPGA) is not implemented for this detector\n"); cprintf(RED, "%s", mess); + functionNotImplemented(); #else - - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { - if (isControlServer) { - basictests(debugflag); // mapping of control server at lease -#ifdef JUNGFRAUD - if (debugflag != PROGRAMMING_MODE) -#endif - initControlServer(); - } - else initStopServer(); //remapping of stop server + // only set + if (Server_VerifyLock() != FAIL) { + if (isControlServer) { + basictests(debugflag); // mapping of control server at least + if (debugflag != PROGRAMMING_MODE) + initControlServer(); + } + else initStopServer(); //remapping of stop server ret = FORCE_UPDATE; } #endif - - Server_SendResult(file_des, INT32, 1, NULL, 0); - - return ret; + return Server_SendResult(file_des, INT32, 1, NULL, 0); } int power_chip(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"power chip failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Powering chip to %d\n", arg)); #ifndef JUNGFRAUD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Power Chip) is not implemented for this detector\n"); - cprintf(RED, "%s", mess); + functionNotImplemented(); #else - - // receive arguments - int arg=-1; - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus && arg!=-1) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { -#ifdef VERBOSE - printf("Power chip to %d\n", arg); -#endif - retval=powerChip(arg); - -#ifdef VERBOSE - printf("Chip powered: %d\n",retval); -#endif - if (retval==arg || arg<0) { - ret=OK; - } else { - ret=FAIL; - if(setTemperatureEvent(-1) == 1) - sprintf(mess,"Powering chip failed due to over-temperature event. Clear event & power chip again. Wrote %d, read %d \n", arg, retval); - else - sprintf(mess,"Powering chip failed, wrote %d but read %d\n", arg, retval); - cprintf(RED, "Warning: %s", mess); + // set & get + if ((arg == -1) || ((arg != -1) && (Server_VerifyLock() != FAIL))) { + retval = powerChip(arg); + FILE_LOG(logDEBUG5, ("Power chip: %d\n", retval)); + validate(arg, retval, "power on/off chip", 0); + // narrow down error when powering on + if (ret == FAIL && arg > 0) { + if (setTemperatureEvent(-1) == 1) + sprintf(mess,"Powering chip failed due to over-temperature event. " + "Clear event & power chip again. Set %d, read %d \n", arg, retval); + FILE_LOG(logERROR, (mess)); } } #endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } int set_activate(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"Activate/Deactivate failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Setting activate mode to %d\n", arg)); #ifndef EIGERD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret=FAIL; - sprintf(mess,"Function (Set Activate) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + functionNotImplemented(); #else - - // receive arguments - int arg=-1; - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus && arg!=-1) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { -#ifdef VERBOSE - printf("Setting activate mode of detector to %d\n",arg); -#endif - retval=activate(arg); - if ((retval!=arg) && (arg!=-1)) { - ret=FAIL; - sprintf(mess,"Could not set activate mode to %d, is set to %d\n",arg, retval); - cprintf(RED, "Warning: %s", mess); - } + // set & get + if ((arg == -1) || ((arg != -1) && (Server_VerifyLock() != FAIL))) { + retval = activate(arg); + FILE_LOG(logDEBUG5, ("Activate: %d\n", retval)); + validate(arg, retval, "set activate", 0); } #endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } int prepare_acquisition(int file_des) { - int ret=OK,ret1=OK; - int n=0; - strcpy(mess,"prepare acquisition failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); -#if !defined(GOTTHARDD) && !defined(EIGERD) - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Prepare Acquisition) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); + FILE_LOG(logDEBUG5, ("Preparing Acquisition\n")); +#ifndef EIGERD + functionNotImplemented(); #else - - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { + // only set + if (Server_VerifyLock() != FAIL) { ret = prepareAcquisition(); - if (ret == FAIL) - cprintf(RED, "Warning: %s", mess); + if (ret == FAIL) { + strcpy(mess, "Could not prepare acquisition\n"); + FILE_LOG(logERROR, (mess)); + } } #endif - - Server_SendResult(file_des, INT32, 1 , NULL, 0); - - return ret; + return Server_SendResult(file_des, INT32, 1 , NULL, 0); } @@ -3585,130 +2704,86 @@ int prepare_acquisition(int file_des) { int threshold_temp(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"could not set/get threshold temperature\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Setting threshold temperature to %d\n", arg)); #ifndef JUNGFRAUD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Threshold Temp) is not implemented for this detector\n"); - cprintf(RED, "%s", mess); + functionNotImplemented(); #else - int arg=-1; - int val=-1; - - // receive arguments - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - - val=arg; - if (val > MAX_THRESHOLD_TEMP_VAL) { - ret=FAIL; - sprintf(mess,"Threshold Temp %d should be in range: 0 - %d\n", val, MAX_THRESHOLD_TEMP_VAL); - cprintf(RED, "Warning: %s", mess); - } - - - if (ret==OK) { -#ifdef VERBOSE - printf("Setting Threshold Temperature to %d\n", val); + // set & get + if ((arg == -1) || ((arg != -1) && (Server_VerifyLock() != FAIL))) { + if (arg > MAX_THRESHOLD_TEMP_VAL) { + ret = FAIL; + sprintf(mess,"Threshold Temp %d should be in range: 0 - %d\n", + arg, MAX_THRESHOLD_TEMP_VAL); + FILE_LOG(logERROR, (mess)); + } + // valid temp + else { + retval = setThresholdTemperature(arg); + FILE_LOG(logDEBUG5, ("Threshold temperature: %d\n", retval)); + validate(arg, retval, "set threshold temperature", 0); + } + } #endif - retval=setThresholdTemperature(val); - } -#ifdef VERBOSE - printf("Threshold temperature is %d\n", retval); -#endif -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } int temp_control(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"could not set/get temperature control\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Setting temperature control to %d\n", arg)); #ifndef JUNGFRAUD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Temperature control) is not implemented for this detector\n"); - cprintf(RED, "%s", mess); + functionNotImplemented(); #else - int arg=-1; - int val=-1; - - // receive arguments - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - val=arg; - - if (ret==OK) { -#ifdef VERBOSE - printf("Setting Temperature control to %d\n", val); + // set & get + if ((arg == -1) || ((arg != -1) && (Server_VerifyLock() != FAIL))) { + retval = setTemperatureControl(arg); + FILE_LOG(logDEBUG5, ("Temperature control: %d\n", retval)); + validate(arg, retval, "set temperature control", 0); + } #endif - retval=setTemperatureControl(val); - } -#ifdef VERBOSE - printf("Temperature control is %d\n", retval); -#endif -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } int temp_event(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"could not set/get temperature event\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Setting temperature event to %d\n", arg)); #ifndef JUNGFRAUD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Temperature Event) is not implemented for this detector\n"); - cprintf(RED, "%s", mess); + functionNotImplemented(); #else - int arg=-1; - int val=-1; - - // receive arguments - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - val=arg; - - if (ret==OK) { -#ifdef VERBOSE - printf("Setting Temperature Event to %d\n", val); + // set & get + if ((arg == -1) || ((arg != -1) && (Server_VerifyLock() != FAIL))) { + retval = setTemperatureEvent(arg); + FILE_LOG(logDEBUG5, ("Temperature event: %d\n", retval)); + validate(arg, retval, "set temperature event", 0); + } #endif - retval=setTemperatureEvent(val); - } -#ifdef VERBOSE - printf("Temperature Event is %d\n", retval); -#endif - -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -3716,60 +2791,26 @@ int temp_event(int file_des) { int auto_comp_disable(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"auto comp disable failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Setting Auto comp disable to %d\n", arg)); #ifndef JUNGFRAUD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Auto Comp Disable) is not implemented for this detector\n"); - cprintf(RED, "%s", mess); + functionNotImplemented(); #else - - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Auto Comp Disable) is not yet implemented for this detector\n"); - cprintf(RED, "%s", mess); - - // receive arguments - int arg=-1; - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus && arg!=-1) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { -#ifdef VERBOSE - printf("Auto Comp Disable to %d\n", arg); + // set & get + if ((arg == -1) || ((arg != -1) && (Server_VerifyLock() != FAIL))) { + retval = autoCompDisable(arg); + FILE_LOG(logDEBUG5, ("Auto comp disable: %d\n", retval)); + validate(arg, retval, "set auto comp disable", 0); + } #endif - retval=autoCompDisable(arg); - -#ifdef VERBOSE - printf("Auto comp disable set to: %d\n",retval); -#endif - if (retval==arg || arg<0) { - ret=OK; - } else { - ret=FAIL; - sprintf(mess,"Atuo Comp Disable failed, wrote %d but read %d\n", arg, retval); - cprintf(RED, "Warning: %s", mess); - } - } -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } @@ -3777,87 +2818,48 @@ int auto_comp_disable(int file_des) { int storage_cell_start(int file_des) { - int ret=OK,ret1=OK; - int n=0; - int retval=-1; - sprintf(mess,"storage cell start failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG5, ("Setting Storage cell start to %d\n", arg)); #ifndef JUNGFRAUD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Storage cell start) is not implemented for this detector\n"); - cprintf(RED, "%s", mess); + functionNotImplemented(); #else - - // receive arguments - int arg=-1; - n = receiveData(file_des,&arg,sizeof(arg),INT32); - if (n < 0) return printSocketReadError(); - - // execute action - if (differentClients && lockStatus && arg!=-1) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else if (arg > MAX_STORAGE_CELL_VAL) { - ret=FAIL; - strcpy(mess,"Max Storage cell number should not exceed 15\n"); - cprintf(RED, "Warning: %s", mess); - } else { -#ifdef VERBOSE - printf("Storage cell start to %d\n", arg); + // set & get + if ((arg == -1) || ((arg != -1) && (Server_VerifyLock() != FAIL))) { + if (arg > MAX_STORAGE_CELL_VAL) { + ret = FAIL; + strcpy(mess,"Max Storage cell number should not exceed 15\n"); + FILE_LOG(logERROR, (mess)); + } else { + retval = selectStoragecellStart(arg); + FILE_LOG(logDEBUG5, ("Storage cell start: %d\n", retval)); + validate(arg, retval, "set storage cell start", 0); + } #endif - retval=selectStoragecellStart(arg); - -#ifdef VERBOSE - printf("Storage cell start: %d\n",retval); -#endif - if (retval==arg || arg<0) { - ret=OK; - } else { - sprintf(mess,"Storage cell start select failed, wrote %d but read %d\n", arg, retval); - cprintf(RED, "Warning: %s", mess); - } - } -#endif - - Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); - - return ret; + return Server_SendResult(file_des, INT32, 1, &retval, sizeof(retval)); } int check_version(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sprintf(mess,"check version failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + int64_t arg = -1; -#if !defined(EIGERD) && !defined(JUNGFRAUD) && !defined(GOTTHARD) - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret=FAIL; - sprintf(mess,"Function (Check Version Compatibility) is not implemented for this detector\n"); - cprintf(RED, "Warning: %s", mess); -#else - - // receive arguments - int64_t arg=-1; - n = receiveData(file_des,&arg,sizeof(arg),INT64); - if (n < 0) return printSocketReadError(); - - // execute action + if (receiveData(file_des, &arg, sizeof(arg), INT64) < 0) + return printSocketReadError(); // check software- firmware compatibility and basic tests if (isControlServer) { -#ifdef VERBOSE - printf("Checking software-firmware compatibility and basic test result\n"); -#endif + FILE_LOG(logDEBUG5, ("Checking software-firmware compatibility and basic test result\n")); + // check if firmware check is done if (!isFirmwareCheckDone()) { usleep(3 * 1000 * 1000); @@ -3865,7 +2867,7 @@ int check_version(int file_des) { ret = FAIL; strcpy(mess,"Firmware Software Compatibility Check (Server Initialization) " "still not done done in server. Unexpected.\n"); - cprintf(RED, "Warning: %s", mess); + FILE_LOG(logERROR,(mess)); } } // check firmware check result @@ -3874,15 +2876,14 @@ int check_version(int file_des) { if (getFirmwareCheckResult(&firmware_message) == FAIL) { ret = FAIL; strcpy(mess, firmware_message); - cprintf(RED, "Warning: %s", mess); + FILE_LOG(logERROR,(mess)); } } } if (ret == OK) { -#ifdef VERBOSE - printf("Checking versioning compatibility with value %d\n",arg); -#endif + FILE_LOG(logDEBUG5, ("Checking versioning compatibility with value %d\n",arg)); + int64_t client_requiredVersion = arg; int64_t det_apiVersion = getDetectorId(CLIENT_SOFTWARE_API_VERSION); int64_t det_version = getDetectorId(DETECTOR_SOFTWARE_VERSION); @@ -3894,7 +2895,7 @@ int check_version(int file_des) { "Detector's SW API Version: (0x%llx). " "Incompatible, update client!\n", (long long int)client_requiredVersion, (long long int)det_apiVersion); - cprintf(RED, "Warning: %s", mess); + FILE_LOG(logERROR,(mess)); } // old software @@ -3904,48 +2905,33 @@ int check_version(int file_des) { "Client's detector SW API Version: (0x%llx). " "Incompatible, update detector software!\n", (long long int)det_version, (long long int)client_requiredVersion); - cprintf(RED, "Warning: %s", mess); + FILE_LOG(logERROR,(mess)); } } -#endif - - Server_SendResult(file_des, INT32, 1 , NULL, 0); - return ret; + return Server_SendResult(file_des, INT32, 1 , NULL, 0); } int software_trigger(int file_des) { - int ret=OK,ret1=OK; - int n=0; - sprintf(mess,"software trigger failed\n"); + ret = OK; + memset(mess, 0, sizeof(mess)); + FILE_LOG(logDEBUG5, ("Software Trigger\n")); #ifndef EIGERD - //to receive any arguments - while (n > 0) - n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); - ret = FAIL; - sprintf(mess,"Function (Software Trigger) is not implemented for this detector\n"); - cprintf(RED, "%s", mess); + functionNotImplemented(); #else - - // execute action - if (differentClients && lockStatus) { - ret = FAIL; - sprintf(mess,"Detector locked by %s\n",lastClientIP); - cprintf(RED, "Warning: %s", mess); - } - else { - printf("Software Trigger\n"); - ret=softwareTrigger(); - if (ret==FAIL) - cprintf(RED, "Warning: %s", mess); + // only set + if (Server_VerifyLock() != FAIL) { + ret = softwareTrigger(); + if (ret == FAIL) { + sprintf(mess, "Could not send software trigger\n"); + FILE_LOG(logERROR,(mess)); + } + FILE_LOG(logDEBUG5, ("Software trigger ret: %d\n", ret)); } #endif - - Server_SendResult(file_des, INT32, 1 , NULL, 0); - - return ret; + return Server_SendResult(file_des, INT32, 1 , NULL, 0); } diff --git a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.h index 0ac890f86..72829ec43 100755 --- a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.h @@ -1,6 +1,4 @@ -#ifndef SERVER_FUNCS_H -#define SERVER_FUNCS_H - +#pragma once #include "sls_detector_defs.h" #include @@ -14,6 +12,7 @@ void function_table(); void functionNotImplemented(); void modeNotImplemented(char* modename, int mode); void validate(int arg, int retval, char* modename, int hex); +void validate64(int64_t arg, int64_t retval, char* modename, int hex); int M_nofunc(int); int M_nofuncMode(int); @@ -79,4 +78,3 @@ int storage_cell_start(int); int check_version(int); int software_trigger(int); -#endif diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index d0a446944..bf92c04a2 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -2867,27 +2867,21 @@ int slsDetector::setDynamicRange(int n) { if (connectControl() == OK){ controlSocket->SendDataOnly(&fnum,sizeof(fnum)); controlSocket->SendDataOnly(&n,sizeof(n)); - //rate correction is switched off if not 32 bit mode - if(thisDetector->myDetectorType == EIGER){ - controlSocket->ReceiveDataOnly(&rateret,sizeof(rateret)); - if (rateret==FAIL) { - controlSocket->ReceiveDataOnly(mess,sizeof(mess)); - std::cout<< "Detector returned error: " << mess << std::endl; - if(strstr(mess,"Rate Correction")!=NULL){ - if(strstr(mess,"32")!=NULL) - setErrorMask((getErrorMask())|(RATE_CORRECTION_NOT_32or16BIT)); - else - setErrorMask((getErrorMask())|(COULD_NOT_SET_RATE_CORRECTION)); - } - } - } controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret==FAIL) { controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; - } else { - controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if(strstr(mess,"Rate Correction")!=NULL){ + // rate correction is switched off if not 32 bit mode + if(strstr(mess,"32")!=NULL) + setErrorMask((getErrorMask())|(RATE_CORRECTION_NOT_32or16BIT)); + else + setErrorMask((getErrorMask())|(COULD_NOT_SET_RATE_CORRECTION)); + } + else ret = OK; } + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectControl(); if (ret==FORCE_UPDATE) updateDetector(); @@ -4268,13 +4262,24 @@ int slsDetector::sendROI(int n,ROI roiLimits[]) { #ifdef VERBOSE std::cout << "Sending ROI of size " << arg << " to detector" << std::endl; #endif - controlSocket->SendDataOnly(roiLimits,arg*sizeof(ROI)); + for(int i = 0; i < n; ++i){ + controlSocket->SendDataOnly(&roiLimits[i].xmin, sizeof(int)); + controlSocket->SendDataOnly(&roiLimits[i].xmax, sizeof(int)); + controlSocket->SendDataOnly(&roiLimits[i].ymin, sizeof(int)); + controlSocket->SendDataOnly(&roiLimits[i].ymax, sizeof(int)); + } + //controlSocket->SendDataOnly(roiLimits,arg*sizeof(ROI)); } controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret!=FAIL){ controlSocket->ReceiveDataOnly(&retvalsize,sizeof(retvalsize)); - nrec = controlSocket->ReceiveDataOnly(retval,retvalsize*sizeof(ROI)); + nrec = 0; + nrec += controlSocket->ReceiveDataOnly(&retval[i].xmin, sizeof(int)); + nrec += controlSocket->ReceiveDataOnly(&retval[i].xmax, sizeof(int)); + nrec += controlSocket->ReceiveDataOnly(&retval[i].ymin, sizeof(int)); + nrec += controlSocket->ReceiveDataOnly(&retval[i].ymax, sizeof(int)); + //nrec = controlSocket->ReceiveDataOnly(retval,retvalsize*sizeof(ROI)); if(nrec!=(retvalsize*(int)sizeof(ROI))){ ret=FAIL; std::cout << " wrong size received: received " << nrec << diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index d7af5d8d2..d1ad6bace 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -290,9 +290,7 @@ int slsReceiverTCPIPInterface::M_nofunc(){ strcpy(mess,"Unrecognized Function. Please do not proceed.\n"); FILE_LOG(logERROR) << mess; - interface->Server_SendResult(false, ret, NULL, 0, mess); - - return ret; + return interface->Server_SendResult(false, ret, NULL, 0, mess); } @@ -329,21 +327,17 @@ int slsReceiverTCPIPInterface::exec_command() { } } - interface->Server_SendResult(false, ret, retval, MAX_STR_LENGTH, mess); - - return ret; + return interface->Server_SendResult(false, ret, retval, MAX_STR_LENGTH, mess); } int slsReceiverTCPIPInterface::exit_server() { - cprintf(RED,"Closing receiver server\n"); + cprintf(RED,"Closing server\n"); ret = OK; interface->Server_SendResult(false, ret, NULL, 0); - - ret = GOODBYE; - return ret; + return GOODBYE; } @@ -361,7 +355,7 @@ int slsReceiverTCPIPInterface::lock_receiver() { if (lock >= 0) { if (!lockStatus || // if it was unlocked, anyone can lock (!strcmp(mySock->lastClientIP,mySock->thisClientIP)) || // if it was locked, need same ip - (!strcmp(mySock->lastClientIP,"none"))) //if it was locked, must be by "none" + (!strcmp(mySock->lastClientIP,"none"))) // if it was locked, must be by "none" { lockStatus = lock; strcpy(mySock->lastClientIP,mySock->thisClientIP); @@ -369,18 +363,14 @@ int slsReceiverTCPIPInterface::lock_receiver() { interface->Server_LockedError(ret, mess); } - interface->Server_SendResult(true, ret, &lockStatus,sizeof(lockStatus), mess); - - return ret; + return interface->Server_SendResult(true, ret, &lockStatus,sizeof(lockStatus), mess); } int slsReceiverTCPIPInterface::get_last_client_ip() { ret = OK; - interface->Server_SendResult(true, ret,mySock->lastClientIP, sizeof(mySock->lastClientIP)); - - return ret; + return interface->Server_SendResult(true, ret,mySock->lastClientIP, sizeof(mySock->lastClientIP)); } @@ -560,9 +550,7 @@ int slsReceiverTCPIPInterface::get_id(){ ret = OK; int64_t retval = getReceiverVersion(); - interface->Server_SendResult(true, ret, &retval, sizeof(retval)); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval)); } @@ -622,9 +610,7 @@ int slsReceiverTCPIPInterface::set_detector_type(){ //get retval = myDetectorType; - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -679,7 +665,13 @@ int slsReceiverTCPIPInterface::set_roi() { int iloop = 0; for (iloop = 0; iloop < nroi; iloop++) { ROI temp; - if ( mySock->ReceiveDataOnly(&temp,sizeof(ROI)) < 0 ) + if ( mySock->ReceiveDataOnly(&temp.xmin,sizeof(int)) < 0 ) + return interface->Server_SocketCrash(); + if ( mySock->ReceiveDataOnly(&temp.xmax,sizeof(int)) < 0 ) + return interface->Server_SocketCrash(); + if ( mySock->ReceiveDataOnly(&temp.ymin,sizeof(int)) < 0 ) + return interface->Server_SocketCrash(); + if ( mySock->ReceiveDataOnly(&temp.ymax,sizeof(int)) < 0 ) return interface->Server_SocketCrash(); roiLimits.push_back(temp); } @@ -766,9 +758,7 @@ int slsReceiverTCPIPInterface::setup_udp(){ } } - interface->Server_SendResult(true, ret, retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, retval, sizeof(retval), mess); } @@ -865,9 +855,7 @@ int slsReceiverTCPIPInterface::set_timer() { FILE_LOG(logDEBUG1) << slsDetectorDefs::getTimerType((timerIndex)(index[0])) << ":" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -927,9 +915,7 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { FILE_LOG(logDEBUG1) << "dynamic range: " << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -966,9 +952,7 @@ int slsReceiverTCPIPInterface::set_streaming_frequency(){ } } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -984,9 +968,7 @@ int slsReceiverTCPIPInterface::get_status(){ if (ret == OK) retval = receiver->getStatus(); - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1017,11 +999,7 @@ int slsReceiverTCPIPInterface::start_receiver(){ } } - interface->Server_SendResult(true, ret, NULL, 0, mess); - - return ret; - - + return interface->Server_SendResult(true, ret, NULL, 0, mess); } @@ -1050,9 +1028,7 @@ int slsReceiverTCPIPInterface::stop_receiver(){ } } - interface->Server_SendResult(true, ret, NULL, 0, mess); - - return ret; + return interface->Server_SendResult(true, ret, NULL, 0, mess); } @@ -1162,9 +1138,7 @@ int slsReceiverTCPIPInterface::set_file_index() { FILE_LOG(logDEBUG1) << "file index:" << retval; } - interface->Server_SendResult(true, ret, &retval,sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval,sizeof(retval), mess); } @@ -1182,9 +1156,7 @@ int slsReceiverTCPIPInterface::get_frame_index(){ if (ret == OK) retval=receiver->getAcquisitionIndex(); - interface->Server_SendResult(true, ret, &retval,sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval,sizeof(retval), mess); } @@ -1199,9 +1171,7 @@ int slsReceiverTCPIPInterface::get_frames_caught(){ if (ret == OK) retval=receiver->getTotalFramesCaught(); - interface->Server_SendResult(true, ret, &retval,sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval,sizeof(retval), mess); } @@ -1221,9 +1191,7 @@ int slsReceiverTCPIPInterface::reset_frames_caught(){ } } - interface->Server_SendResult(true, ret, NULL, 0, mess); - - return ret; + return interface->Server_SendResult(true, ret, NULL, 0, mess); } @@ -1256,9 +1224,7 @@ int slsReceiverTCPIPInterface::enable_file_write(){ FILE_LOG(logDEBUG1) << "file write enable:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1293,9 +1259,7 @@ int slsReceiverTCPIPInterface::enable_overwrite() { FILE_LOG(logDEBUG1) << "file overwrite enable:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1331,9 +1295,7 @@ int slsReceiverTCPIPInterface::enable_tengiga() { FILE_LOG(logDEBUG1) << "10Gbe:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1371,9 +1333,7 @@ int slsReceiverTCPIPInterface::set_fifo_depth() { FILE_LOG(logDEBUG1) << "fifo depth:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1409,9 +1369,7 @@ int slsReceiverTCPIPInterface::set_activate() { FILE_LOG(logDEBUG1) << "Activate: " << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1444,9 +1402,7 @@ int slsReceiverTCPIPInterface::set_data_stream_enable(){ FILE_LOG(logDEBUG1) << "data streaming enable:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1479,9 +1435,7 @@ int slsReceiverTCPIPInterface::set_streaming_timer(){ FILE_LOG(logDEBUG1) << "Streaming timer:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1517,9 +1471,7 @@ int slsReceiverTCPIPInterface::set_flipped_data(){ FILE_LOG(logDEBUG1) << "Flipped Data:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1554,9 +1506,7 @@ int slsReceiverTCPIPInterface::set_file_format() { FILE_LOG(logDEBUG1) << "File Format: " << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1589,9 +1539,7 @@ int slsReceiverTCPIPInterface::set_detector_posid() { FILE_LOG(logDEBUG1) << "Position Id:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1628,9 +1576,7 @@ int slsReceiverTCPIPInterface::set_multi_detector_size() { FILE_LOG(logDEBUG1) << "Multi Detector Size:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1659,9 +1605,7 @@ int slsReceiverTCPIPInterface::set_streaming_port() { FILE_LOG(logDEBUG1) << "streaming port:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1727,9 +1671,7 @@ int slsReceiverTCPIPInterface::set_silent_mode() { FILE_LOG(logDEBUG1) << "silent mode:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1768,9 +1710,7 @@ int slsReceiverTCPIPInterface::enable_gap_pixels() { FILE_LOG(logDEBUG1) << "Gap Pixels Enable: " << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1801,9 +1741,7 @@ int slsReceiverTCPIPInterface::restream_stop(){ } } - interface->Server_SendResult(true, ret, NULL, 0, mess); - - return ret; + return interface->Server_SendResult(true, ret, NULL, 0, mess); } @@ -1871,9 +1809,7 @@ int slsReceiverTCPIPInterface::set_udp_socket_buffer_size() { FILE_LOG(logDEBUG1) << "UDP Socket Buffer Size:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1888,9 +1824,7 @@ int slsReceiverTCPIPInterface::get_real_udp_socket_buffer_size(){ if (ret == OK) retval = receiver->getActualUDPSocketBufferSize(); - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1924,9 +1858,7 @@ int slsReceiverTCPIPInterface::set_frames_per_file() { FILE_LOG(logDEBUG1) << "frames per file:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -1971,9 +1903,7 @@ int slsReceiverTCPIPInterface::check_version_compatibility() { } else FILE_LOG(logINFO) << "Compatibility with Client: Successful"; - interface->Server_SendResult(true, ret, NULL, 0, mess); - - return ret; + return interface->Server_SendResult(true, ret, NULL, 0, mess); } @@ -2007,9 +1937,7 @@ int slsReceiverTCPIPInterface::set_discard_policy() { FILE_LOG(logDEBUG1) << "frame discard policy:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -2045,9 +1973,7 @@ int slsReceiverTCPIPInterface::set_padding_enable() { FILE_LOG(logDEBUG1) << "Frame Padding Enable:" << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } @@ -2084,7 +2010,5 @@ int slsReceiverTCPIPInterface::set_deactivated_receiver_padding_enable() { FILE_LOG(logDEBUG1) << "Deactivated Padding Enable: " << retval; } - interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); - - return ret; + return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess); } diff --git a/slsSupportLib/include/ClientInterface.cpp b/slsSupportLib/include/ClientInterface.cpp index 78bd1bbbd..4d387da76 100644 --- a/slsSupportLib/include/ClientInterface.cpp +++ b/slsSupportLib/include/ClientInterface.cpp @@ -53,7 +53,7 @@ int ClientInterface::Client_Send(int fnum, } -void ClientInterface::Server_SendResult(bool update, int ret, +int ClientInterface::Server_SendResult(bool update, int ret, void* retval, int retvalSize, char* mess) { // update if different clients @@ -72,6 +72,8 @@ void ClientInterface::Server_SendResult(bool update, int ret, } // send return value mySocket->SendDataOnly(retval, retvalSize); + + return ret; } diff --git a/slsSupportLib/include/ClientInterface.h b/slsSupportLib/include/ClientInterface.h index 536c8c984..049de62aa 100644 --- a/slsSupportLib/include/ClientInterface.h +++ b/slsSupportLib/include/ClientInterface.h @@ -65,8 +65,9 @@ public: * @param retval pointer to result * @param retvalSize size of result * @param mess message + * @returns success of operation */ - void Server_SendResult(bool update, int ret, void* retval, int retvalSize, char* mess = 0); + int Server_SendResult(bool update, int ret, void* retval, int retvalSize, char* mess = 0); /** only Receiver * Server receives arguments and checks if base object is null (if checkbase is true) diff --git a/slsSupportLib/include/sls_detector_defs.h b/slsSupportLib/include/sls_detector_defs.h index 8649fd686..3d5bc07e4 100755 --- a/slsSupportLib/include/sls_detector_defs.h +++ b/slsSupportLib/include/sls_detector_defs.h @@ -82,9 +82,7 @@ public: EIGER, /**< eiger */ GOTTHARD, /**< gotthard */ JUNGFRAU, /**< jungfrau */ - JUNGFRAUCTB, /**< jungfrauCTBversion */ - MYTHEN3, /**< mythen 3 */ - MOENCH /**< moench */ + JUNGFRAUCTB /**< jungfrauCTBversion */ };