From aab56ea943f339ef4fa4e8177558d3b35c1f3bd1 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 27 Oct 2017 15:39:55 +0200 Subject: [PATCH 01/10] updated jungfrau server binary --- serverBin/jungfrauDetectorServer | 1 - 1 file changed, 1 deletion(-) delete mode 120000 serverBin/jungfrauDetectorServer diff --git a/serverBin/jungfrauDetectorServer b/serverBin/jungfrauDetectorServer deleted file mode 120000 index 002832aec..000000000 --- a/serverBin/jungfrauDetectorServer +++ /dev/null @@ -1 +0,0 @@ -../slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServerv3.0.0.6 \ No newline at end of file From 18d5fd5a35e6438314cf8c72b4d058982eeb7dad Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Fri, 27 Oct 2017 16:08:52 +0200 Subject: [PATCH 02/10] update binaries --- .../{gotthardDetectorServerv3.0.0.5 => gotthardDetectorServer} | 0 serverBin/jungfrauDetectorServer | 1 + 2 files changed, 1 insertion(+) rename serverBin/{gotthardDetectorServerv3.0.0.5 => gotthardDetectorServer} (100%) create mode 120000 serverBin/jungfrauDetectorServer diff --git a/serverBin/gotthardDetectorServerv3.0.0.5 b/serverBin/gotthardDetectorServer similarity index 100% rename from serverBin/gotthardDetectorServerv3.0.0.5 rename to serverBin/gotthardDetectorServer diff --git a/serverBin/jungfrauDetectorServer b/serverBin/jungfrauDetectorServer new file mode 120000 index 000000000..aeb42a3f9 --- /dev/null +++ b/serverBin/jungfrauDetectorServer @@ -0,0 +1 @@ +../slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServerv3.0.0.6.1 \ No newline at end of file From ea0c436fc87044359b1d0b0c8c6e85f1a6288b82 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Wed, 15 Nov 2017 08:07:59 +0100 Subject: [PATCH 03/10] updated binaries --- serverBin/jungfrauDetectorServer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serverBin/jungfrauDetectorServer b/serverBin/jungfrauDetectorServer index aeb42a3f9..963568b79 120000 --- a/serverBin/jungfrauDetectorServer +++ b/serverBin/jungfrauDetectorServer @@ -1 +1 @@ -../slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServerv3.0.0.6.1 \ No newline at end of file +../slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServerv3.0.0.6.2 \ No newline at end of file From f340eef4bc1678f739b7657f0b3765250b82f2f5 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 16 Nov 2017 12:29:09 +0100 Subject: [PATCH 04/10] updated server hotfix binary --- serverBin/jungfrauDetectorServer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serverBin/jungfrauDetectorServer b/serverBin/jungfrauDetectorServer index 963568b79..386608ee5 120000 --- a/serverBin/jungfrauDetectorServer +++ b/serverBin/jungfrauDetectorServer @@ -1 +1 @@ -../slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServerv3.0.0.6.2 \ No newline at end of file +../slsDetectorSoftware/jungfrauDetectorServer/bin/jungfrauDetectorServerv3.0.0.6.3 \ No newline at end of file From 6438238b555f3f9508392eb9b6863b6ea972dc9f Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 19 Dec 2017 17:06:45 +0100 Subject: [PATCH 05/10] gotthard server bug fix, read temp --- .../gotthardDetectorServer/gitInfo.txt | 14 +++++++------- .../gotthardDetectorServer/gitInfoGotthard.h | 10 +++++----- .../gotthardDetectorServer/server_funcs.c | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/slsDetectorSoftware/gotthardDetectorServer/gitInfo.txt b/slsDetectorSoftware/gotthardDetectorServer/gitInfo.txt index 331da9c31..570d65f7d 100644 --- a/slsDetectorSoftware/gotthardDetectorServer/gitInfo.txt +++ b/slsDetectorSoftware/gotthardDetectorServer/gitInfo.txt @@ -1,9 +1,9 @@ Path: slsDetectorsPackage/slsDetectorSoftware/gotthardDetectorServer -URL: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git -Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git -Repsitory UUID: e4fa807b5d987714a047b9d2cac271c89f6c2fef -Revision: 208 -Branch: developer +URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git +Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git +Repsitory UUID: 735b8ea206bc3799535097dd27aa8fa92dec530c +Revision: 209 +Branch: 3.0 Last Changed Author: Dhanya_Maliakal -Last Changed Rev: 1487 -Last Changed Date: 2017-08-16 16:01:46.000000002 +0200 ./firmware_funcs.c +Last Changed Rev: 3148 +Last Changed Date: 2017-12-19 16:55:16.000000002 +0100 ./firmware_funcs.c diff --git a/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthard.h b/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthard.h index f5a2ab5e4..043705cb2 100644 --- a/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthard.h +++ b/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthard.h @@ -1,11 +1,11 @@ //#define SVNPATH "" -#define SVNURL "git@git.psi.ch:sls_detectors_software/sls_detector_software.git" +#define SVNURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git" //#define SVNREPPATH "" -#define SVNREPUUID "e4fa807b5d987714a047b9d2cac271c89f6c2fef" -//#define SVNREV 0x1487 +#define SVNREPUUID "735b8ea206bc3799535097dd27aa8fa92dec530c" +//#define SVNREV 0x3148 //#define SVNKIND "" //#define SVNSCHED "" #define SVNAUTH "Dhanya_Maliakal" -#define SVNREV 0x1487 -#define SVNDATE 0x20170816 +#define SVNREV 0x3148 +#define SVNDATE 0x20171219 // diff --git a/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c index 844b2d86f..b1a5181a9 100755 --- a/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c +++ b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c @@ -1052,7 +1052,7 @@ int get_adc(int file_des) { ret=FAIL; } ind=arg[0]; - imod=arg[1]; + imod=0;//arg[1]; #ifdef VERBOSE printf("Getting ADC %d of module %d\n", ind, imod); From a4dc00b252f34860190b26fb3967a613a94a4b0e Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 19 Dec 2017 17:08:28 +0100 Subject: [PATCH 06/10] gotthard server binary update --- serverBin/gotthardDetectorServer | 2 +- .../gotthardDetectorServerv3.0.0.5 | Bin 132024 -> 0 bytes 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100755 slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.5 diff --git a/serverBin/gotthardDetectorServer b/serverBin/gotthardDetectorServer index 98922ce43..ca005a699 120000 --- a/serverBin/gotthardDetectorServer +++ b/serverBin/gotthardDetectorServer @@ -1 +1 @@ -../slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.5 \ No newline at end of file +../slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.6 \ No newline at end of file diff --git a/slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.5 b/slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.5 deleted file mode 100755 index e802907cbf51e4d560a94227f348aa3e23bd752d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 132024 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 h3!Dt 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 From e39bee0113b47e79de0ee1902e0ca314e652c0a1 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 19 Dec 2017 17:33:27 +0100 Subject: [PATCH 07/10] gotthard server bug fix, temp fail --- .gitignore | 8 -------- .../gotthardDetectorServerv3.0.0.6 | Bin 0 -> 132056 bytes 2 files changed, 8 deletions(-) create mode 100755 slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.6 diff --git a/.gitignore b/.gitignore index 79784747f..28cdacd3c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,10 @@ .cproject .project bin/ -calibrationWizards/ -slsDetectorGui/ -slsDetectorSoftware/ -slsReceiverSoftware/ -slsDetectorCalibration/ -slsImageReconstruction/ .settings -JCTBGui/ *.aux *.log *.out *.toc build -tests docs/ diff --git a/slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.6 b/slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.6 new file mode 100755 index 0000000000000000000000000000000000000000..bd9ca2b26c97c8fa33b8505d41d6ee6f1a350c80 GIT binary patch literal 132056 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%0DJP%D}{ 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 SJ{jwGpZ%UjC8Uqv$Nmk$D;T~2 literal 0 HcmV?d00001 From bc8c7061502878c190f1f4b4b423d69686bdc493 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Tue, 19 Dec 2017 17:44:32 +0100 Subject: [PATCH 08/10] updated gotthard server binaries (3.0.0.6 was already used in 3.0.1) --- serverBin/gotthardDetectorServer | 2 +- ...3.0.0.6 => gotthardDetectorServerv3.0.0.7} | Bin 132056 -> 132056 bytes 2 files changed, 1 insertion(+), 1 deletion(-) rename slsDetectorSoftware/gotthardDetectorServer/{gotthardDetectorServerv3.0.0.6 => gotthardDetectorServerv3.0.0.7} (99%) diff --git a/serverBin/gotthardDetectorServer b/serverBin/gotthardDetectorServer index ca005a699..b88a50de5 120000 --- a/serverBin/gotthardDetectorServer +++ b/serverBin/gotthardDetectorServer @@ -1 +1 @@ -../slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.6 \ No newline at end of file +../slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.7 \ No newline at end of file diff --git a/slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.6 b/slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.7 similarity index 99% rename from slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.6 rename to slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv3.0.0.7 index bd9ca2b26c97c8fa33b8505d41d6ee6f1a350c80..74c484834730c69bfac30b5d6396cd0d2613aebe 100755 GIT binary patch delta 26 icmcc7&T*riV}cfw Date: Thu, 18 Jan 2018 09:25:06 +0100 Subject: [PATCH 09/10] first mythen3 server commit --- .../commonFiles/communication_funcs.c | 2 +- .../jctbDetectorServer/firmware_funcs.c | 20 +- .../jctbDetectorServer/server_funcs.c | 4 +- .../mythen3DetectorServer/AD9257.h | 141 + .../mythen3DetectorServer/Makefile | 28 + .../mythen3DetectorServer/RegisterDefs.h | 551 ++ .../mythen3DetectorServer/blackfin.h | 154 + .../commonServerFunctions.h | 60 + .../communication_funcs.c | 690 +++ .../communication_funcs.h | 51 + .../mythen3DetectorServer/programfpga.h | 178 + .../slsDetectorFunctionList.c | 1196 ++++ .../slsDetectorFunctionList.h | 245 + .../mythen3DetectorServer/slsDetectorServer.c | 120 + .../slsDetectorServer_defs.h | 93 + .../slsDetectorServer_funcs.c | 4996 +++++++++++++++++ .../slsDetectorServer_funcs.h | 93 + .../slsDetector_stopServer.c | 46 + .../mythen3DetectorServer/sls_detector_defs.h | 599 ++ .../sls_detector_funcs.h | 125 + .../include/sls_receiver_defs.h | 3 +- 21 files changed, 9381 insertions(+), 14 deletions(-) create mode 100755 slsDetectorSoftware/mythen3DetectorServer/AD9257.h create mode 100644 slsDetectorSoftware/mythen3DetectorServer/Makefile create mode 100644 slsDetectorSoftware/mythen3DetectorServer/RegisterDefs.h create mode 100755 slsDetectorSoftware/mythen3DetectorServer/blackfin.h create mode 100755 slsDetectorSoftware/mythen3DetectorServer/commonServerFunctions.h create mode 100755 slsDetectorSoftware/mythen3DetectorServer/communication_funcs.c create mode 100755 slsDetectorSoftware/mythen3DetectorServer/communication_funcs.h create mode 100755 slsDetectorSoftware/mythen3DetectorServer/programfpga.h create mode 100644 slsDetectorSoftware/mythen3DetectorServer/slsDetectorFunctionList.c create mode 100644 slsDetectorSoftware/mythen3DetectorServer/slsDetectorFunctionList.h create mode 100755 slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer.c create mode 100644 slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer_defs.h create mode 100755 slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer_funcs.c create mode 100755 slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer_funcs.h create mode 100755 slsDetectorSoftware/mythen3DetectorServer/slsDetector_stopServer.c create mode 100755 slsDetectorSoftware/mythen3DetectorServer/sls_detector_defs.h create mode 100644 slsDetectorSoftware/mythen3DetectorServer/sls_detector_funcs.h diff --git a/slsDetectorSoftware/commonFiles/communication_funcs.c b/slsDetectorSoftware/commonFiles/communication_funcs.c index caa58a8c4..1d30887dc 100755 --- a/slsDetectorSoftware/commonFiles/communication_funcs.c +++ b/slsDetectorSoftware/commonFiles/communication_funcs.c @@ -333,7 +333,7 @@ int receiveData(int file_des, void* buf,int length, intType itype){ #endif while(length > 0) { - nreceiving = (length>send_rec_max_size) ? send_rec_max_size:length; + nreceiving = (length>send_rec_max_size) ? send_rec_max_size:length; // (condition) ? if_true : if_false nreceived = read(file_des,(char*)buf+total_received,nreceiving); if(!nreceived){ if(!total_received) { diff --git a/slsDetectorSoftware/jctbDetectorServer/firmware_funcs.c b/slsDetectorSoftware/jctbDetectorServer/firmware_funcs.c index 05b88ed26..7487d054d 100755 --- a/slsDetectorSoftware/jctbDetectorServer/firmware_funcs.c +++ b/slsDetectorSoftware/jctbDetectorServer/firmware_funcs.c @@ -3717,21 +3717,21 @@ int setDac(int dacnum,int dacvalue){ csdx=2; else csdx=ichip+2; - //setting int reference - offw=DAC_REG; + //setting int reference + offw=DAC_REG; - valw=bus_r(offw)|0xff; + valw=bus_r(offw)|0xff; // alles auf 1 setzen (START) - bus_w(offw,(valw)); // start point - valw=((valw&(~(0x1< + +/* AD9257 ADC DEFINES */ +#define AD9257_ADC_NUMBITS (24) + +#define AD9257_DEV_IND_2_REG (0x04) +#define AD9257_CHAN_H_OFST (0) +#define AD9257_CHAN_H_MSK (0x00000001 << AD9257_CHAN_H_OFST) +#define AD9257_CHAN_G_OFST (1) +#define AD9257_CHAN_G_MSK (0x00000001 << AD9257_CHAN_G_OFST) +#define AD9257_CHAN_F_OFST (2) +#define AD9257_CHAN_F_MSK (0x00000001 << AD9257_CHAN_F_OFST) +#define AD9257_CHAN_E_OFST (3) +#define AD9257_CHAN_E_MSK (0x00000001 << AD9257_CHAN_E_OFST) + +#define AD9257_DEV_IND_1_REG (0x05) +#define AD9257_CHAN_D_OFST (0) +#define AD9257_CHAN_D_MSK (0x00000001 << AD9257_CHAN_D_OFST) +#define AD9257_CHAN_C_OFST (1) +#define AD9257_CHAN_C_MSK (0x00000001 << AD9257_CHAN_C_OFST) +#define AD9257_CHAN_B_OFST (2) +#define AD9257_CHAN_B_MSK (0x00000001 << AD9257_CHAN_B_OFST) +#define AD9257_CHAN_A_OFST (3) +#define AD9257_CHAN_A_MSK (0x00000001 << AD9257_CHAN_A_OFST) +#define AD9257_CLK_CH_DCO_OFST (4) +#define AD9257_CLK_CH_DCO_MSK (0x00000001 << AD9257_CLK_CH_DCO_OFST) +#define AD9257_CLK_CH_IFCO_OFST (5) +#define AD9257_CLK_CH_IFCO_MSK (0x00000001 << AD9257_CLK_CH_IFCO_OFST) + +#define AD9257_POWER_MODE_REG (0x08) +#define AD9257_POWER_INTERNAL_OFST (0) +#define AD9257_POWER_INTERNAL_MSK (0x00000003 << AD9257_POWER_INTERNAL_OFST) +#define AD9257_INT_RESET_VAL (0x3) +#define AD9257_INT_CHIP_RUN_VAL (0x0) +#define AD9257_POWER_EXTERNAL_OFST (5) +#define AD9257_POWER_EXTERNAL_MSK (0x00000001 << AD9257_POWER_EXTERNAL_OFST) +#define AD9257_EXT_FULL_POWER_VAL (0x0) +#define AD9257_EXT_STANDBY_VAL (0x1) + +#define AD9257_OUT_MODE_REG (0x14) +#define AD9257_OUT_FORMAT_OFST (0) +#define AD9257_OUT_FORMAT_MSK (0x00000001 << AD9257_OUT_FORMAT_OFST) +#define AD9257_OUT_BINARY_OFST_VAL (0) +#define AD9257_OUT_TWOS_COMPL_VAL (1) +#define AD9257_OUT_LVDS_OPT_OFST (6) +#define AD9257_OUT_LVDS_OPT_MSK (0x00000001 << AD9257_OUT_LVDS_OPT_OFST) +#define AD9257_OUT_LVDS_ANSI_VAL (0) +#define AD9257_OUT_LVDS_IEEE_VAL (1) + +#define AD9257_OUT_PHASE_REG (0x16) +#define AD9257_OUT_CLK_OFST (0) +#define AD9257_OUT_CLK_MSK (0x0000000F << AD9257_OUT_CLK_OFST) +#define AD9257_OUT_CLK_60_VAL (0x1) +#define AD9257_IN_CLK_OFST (4) +#define AD9257_IN_CLK_MSK (0x00000007 << AD9257_IN_CLK_OFST) +#define AD9257_IN_CLK_0_VAL (0x0) + +#define AD9257_VREF_REG (0x18) +#define AD9257_VREF_OFST (0) +#define AD9257_VREF_MSK (0x00000003 << AD9257_VREF_OFST) +#define AD9257_VREF_1_33_VAL (0x2) + +#define AD9257_TEST_MODE_REG (0x0D) +#define AD9257_OUT_TEST_OFST (0) +#define AD9257_OUT_TEST_MSK (0x0000000F << AD9257_OUT_TEST_OFST) +#define AD9257_NONE_VAL (0x0) +#define AD9257_MIXED_BIT_FREQ_VAL (0xC) +#define AD9257_TEST_RESET_SHORT_GEN (4) +#define AD9257_TEST_RESET_LONG_GEN (5) +#define AD9257_USER_IN_MODE_OFST (6) +#define AD9257_USER_IN_MODE_MSK (0x00000003 << AD9257_USER_IN_MODE_OFST) + + +void setAdc(int addr, int val) { + + u_int32_t codata; + codata = val + (addr << 8); + printf(" Setting ADC SPI Register. Wrote 0x%04x at 0x%04x\n", val, addr); + serializeToSPI(ADC_SPI_REG, codata, ADC_SERIAL_CS_OUT_MSK, AD9257_ADC_NUMBITS, + ADC_SERIAL_CLK_OUT_MSK, ADC_SERIAL_DATA_OUT_MSK, ADC_SERIAL_DATA_OUT_OFST); +} + +void prepareADC(){ + printf("\n\nPreparing ADC ... \n"); + + //power mode reset + printf("power mode reset:\n"); + setAdc(AD9257_POWER_MODE_REG, + (AD9257_INT_RESET_VAL << AD9257_POWER_INTERNAL_OFST) & AD9257_POWER_INTERNAL_MSK); + + //power mode chip run + printf("power mode chip run:\n"); + setAdc(AD9257_POWER_MODE_REG, + (AD9257_INT_CHIP_RUN_VAL << AD9257_POWER_INTERNAL_OFST) & AD9257_POWER_INTERNAL_MSK); + + //output clock phase + printf("output clock phase:\n"); + setAdc(AD9257_OUT_PHASE_REG, + (AD9257_OUT_CLK_60_VAL << AD9257_OUT_CLK_OFST) & AD9257_OUT_CLK_MSK); + + // lvds-iee reduced , binary offset + printf("lvds-iee reduced, binary offset:\n"); + setAdc(AD9257_OUT_MODE_REG, + (AD9257_OUT_LVDS_IEEE_VAL << AD9257_OUT_LVDS_OPT_OFST) & AD9257_OUT_LVDS_OPT_MSK); + + // all devices on chip to receive next command + printf("all devices on chip to receive next command:\n"); + setAdc(AD9257_DEV_IND_2_REG, + AD9257_CHAN_H_MSK | AD9257_CHAN_G_MSK | AD9257_CHAN_F_MSK | AD9257_CHAN_E_MSK); + setAdc(AD9257_DEV_IND_1_REG, + AD9257_CHAN_D_MSK | AD9257_CHAN_C_MSK | AD9257_CHAN_B_MSK | AD9257_CHAN_A_MSK | + AD9257_CLK_CH_DCO_MSK | AD9257_CLK_CH_IFCO_MSK); + + // vref 1.33 + printf("vref 1.33:\n"); + setAdc(AD9257_VREF_REG, + (AD9257_VREF_1_33_VAL << AD9257_VREF_OFST) & AD9257_VREF_MSK); + + // no test mode + printf("no test mode:\n"); + setAdc(AD9257_TEST_MODE_REG, + (AD9257_NONE_VAL << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK); + +#ifdef TESTADC + printf("***************************************** *******\n"); + printf("******* PUTTING ADC IN TEST MODE!!!!!!!!! *******\n"); + printf("***************************************** *******\n"); + // mixed bit frequency test mode + printf("mixed bit frequency test mode:\n"); + setAdc(AD9257_TEST_MODE_REG, + (AD9257_MIXED_BIT_FREQ_VAL << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK); +#endif +} + +#endif //AD9257_H diff --git a/slsDetectorSoftware/mythen3DetectorServer/Makefile b/slsDetectorSoftware/mythen3DetectorServer/Makefile new file mode 100644 index 000000000..7d4c38415 --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/Makefile @@ -0,0 +1,28 @@ +CROSS = bfin-uclinux- +CC = $(CROSS)gcc +#CC = gcc +CLAGS += -Wall -DVIRTUAL -DDACS_INT -DGENERICD # -DSLS_DETECTOR_FUNCTION_LIST +LDLIBS += -lm +INCS = -I. -I../../slsReceiverSoftware/include/ +PROGS = mythen3Server +#DESTDIR ?= bin +INSTMODE = 0777 + +SRC_CLNT = slsDetectorServer.c slsDetectorServer_funcs.c communication_funcs.c slsDetectorFunctionList.c +OBJS = $(SRC_CLNT:.c=.o) + + + +all: clean $(PROGS) + +boot: $(OBJS) + +$(PROGS): + echo $(OBJS) +# mkdir -p $(DESTDIR) + $(CC) $(SRC_CLNT) $(CLAGS) $(LDLIBS) $(INCS) -o $@ +# mv $(PROGS) $(DESTDIR) + + +clean: + rm -rf $(DESTDIR)/$(PROGS) *.o diff --git a/slsDetectorSoftware/mythen3DetectorServer/RegisterDefs.h b/slsDetectorSoftware/mythen3DetectorServer/RegisterDefs.h new file mode 100644 index 000000000..e475e8fcb --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/RegisterDefs.h @@ -0,0 +1,551 @@ +#ifndef REGISTERS_G_H +#define REGISTERS_G_H + + +#include "sls_detector_defs.h" + + +/* Definitions for FPGA*/ +#define CSP0 0x20200000 +#define MEM_SIZE 0x100000 + + + +/* values defined for FPGA */ +#define MCSNUM 0x0 +#define FIXED_PATT_VAL 0xacdc1980 + + +#define FPGA_INIT_PAT 0x60008 +#define FPGA_INIT_ADDR 0xb0000000 + +//#ifdef JUNGFRAU_DHANYA +#define POWER_ON_REG 0x5e<<11 +// Pwr_I2C_SDA <= PowerReg_s(1) when PowerReg_s(3)='1' else 'Z'; +// Pwr_I2C_SCL <= PowerReg_s(0) when PowerReg_s(2)='1' else 'Z'; + +#define PWR_I2C_SCL_BIT 0 +#define PWR_I2C_SDA_BIT 1 +#define PWR_I2C_SCL_EN_BIT 2 +#define PWR_I2C_SDA_EN_BIT 3 + +#define POWER_STATUS_REG 41<<11 + +#define ADCREG1 0x08 +#define ADCREG2 0x14//20 +#define ADCREG3 0x4 +#define ADCREG4 0x5 +#define ADCREG_VREFS 24 +#define DBIT_PIPELINE_REG 89<<11 //0x59 same PATTERN_N_LOOP2_REG +#define MEM_MACHINE_FIFOS_REG 79<<11 //from gotthard +#define CONFGAIN_REG 93<<11 //from gotthard +#define ADC_PIPELINE_REG 66<<11 //0x42 same as ADC_OFFSET_REG +//#endif + +//#define ADC_OFFSET_REG 93<<11 //same as DAQ_REG +#define ADC_INVERSION_REG 67<<11 + +#define DAC_REG 64<<11//0x17<<11// control the dacs +//ADC +#define ADC_WRITE_REG 65<<11//0x18<<11 +//#define ADC_SYNC_REG 66<<11//0x19<<11 +//#define HV_REG 67<<11//0x20<<11 + + + + +//#define MUTIME_REG 0x1a<<11 +//temperature +#define TEMP_IN_REG 0x1b<<11 +#define TEMP_OUT_REG 0x1c<<11 +//configure MAC +#define TSE_CONF_REG 0x1d<<11 +#define ENET_CONF_REG 0x1e<<11 +//#define WRTSE_SHAD_REG 0x1f<<11 +//HV + + +#define DUMMY_REG 68<<11//0x21<<11 +#define FPGA_VERSION_REG 0<<11 //0x22<<11 +#define PCB_REV_REG 0<<11 +#define FIX_PATT_REG 1<<11 //0x23<<11 +#define CONTROL_REG 79<<11//0x24<<11 +#define STATUS_REG 2<<11 //0x25<<11 +#define CONFIG_REG 77<<11//0x26<<11 +#define EXT_SIGNAL_REG 78<<11// 0x27<<11 +//#define FPGA_SVN_REG 0x29<<11 + + +#define CHIP_OF_INTRST_REG 0x2A<<11 + +//FIFO +#define LOOK_AT_ME_REG 3<<11 //0x28<<11 +#define SYSTEM_STATUS_REG 4<<11 + +#define FIFO_DATA_REG 6<<11 +#define FIFO_STATUS_REG 7<<11 + +// constant FifoDigitalInReg_c : integer := 60; +#define FIFO_DIGITAL_DATA_LSB_REG 60<<11 +#define FIFO_DIGITAL_DATA_MSB_REG 61<<11 + +#define FIFO_DATA_REG_OFF 0x50<<11 /////// +//to read back dac registers +//#define MOD_DACS1_REG 0x65<<11 +//#define MOD_DACS2_REG 0x66<<11 +//#define MOD_DACS3_REG 0x67<<11 + +//user entered + + + + + + +#define GET_ACTUAL_TIME_LSB_REG 16<<11 +#define GET_ACTUAL_TIME_MSB_REG 17<<11 + +#define GET_MEASUREMENT_TIME_LSB_REG 38<<11 +#define GET_MEASUREMENT_TIME_MSB_REG 39<<11 + + +#define SET_DELAY_LSB_REG 96<<11 //0x68<<11 +#define SET_DELAY_MSB_REG 97<<11 //0x69<<11 +#define GET_DELAY_LSB_REG 18<<11//0x6a<<11 +#define GET_DELAY_MSB_REG 19<<11//0x6b<<11 + +#define SET_CYCLES_LSB_REG 98<<11//0x6c<<11 +#define SET_CYCLES_MSB_REG 99<<11//0x6d<<11 +#define GET_CYCLES_LSB_REG 20<<11//0x6e<<11 +#define GET_CYCLES_MSB_REG 21<<11//0x6f<<11 + +#define SET_FRAMES_LSB_REG 100<<11//0x70<<11 +#define SET_FRAMES_MSB_REG 101<<11//0x71<<11 +#define GET_FRAMES_LSB_REG 22<<11//0x72<<11 +#define GET_FRAMES_MSB_REG 23<<11//0x73<<11 + +#define SET_PERIOD_LSB_REG 102<<11//0x74<<11 +#define SET_PERIOD_MSB_REG 103<<11//0x75<<11 +#define GET_PERIOD_LSB_REG 24<<11//0x76<<11 +#define GET_PERIOD_MSB_REG 25<<11//0x77<<11 + +//#define PATTERN_WAIT0_TIME_REG_LSB 114<<11 +//#define PATTERN_WAIT0_TIME_REG_MSB 115<<11 +#define SET_EXPTIME_LSB_REG 114<<11//0x78<<11 +#define SET_EXPTIME_MSB_REG 115<<11//0x79<<11 +#define GET_EXPTIME_LSB_REG 26<<11//0x7a<<11 +#define GET_EXPTIME_MSB_REG 27<<11//0x7b<<11 + +#define SET_GATES_LSB_REG 106<<11//0x7c<<11 +#define SET_GATES_MSB_REG 107<<11//0x7d<<11 +#define GET_GATES_LSB_REG 28<<11//0x7e<<11 +#define GET_GATES_MSB_REG 29<<11//0x7f<<11 + +#define DATA_IN_LSB_REG 30<<11 +#define DATA_IN_MSB_REG 31<<11 + +#define PATTERN_OUT_LSB_REG 32<<11 +#define PATTERN_OUT_MSB_REG 33<<11 + +#define FRAMES_FROM_START_LSB_REG 34<<11 +#define FRAMES_FROM_START_MSB_REG 35<<11 + +#define FRAMES_FROM_START_PG_LSB_REG 36<<11 +#define FRAMES_FROM_START_PG_MSB_REG 37<<11 + +#define SLOW_ADC_REG 43<<11 + + + +#define PLL_PARAM_REG 80<<11//0x37<<11 +#define PLL_PARAM_OUT_REG 5<<11 //0x38<<11 +#define PLL_CNTRL_REG 81<<11//0x34<<11 + + +#ifdef NEW_GBE_INTERFACE +#define GBE_PARAM_OUT_REG 40<<11 +#define GBE_PARAM_REG 69<<11 +#define GBE_CNTRL_REG 70<<11 +#else +#define RX_UDP_AREG 69<<11 //rx_udpip_AReg_c : integer:= 69; *\/ +#define UDPPORTS_AREG 70<<11// udpports_AReg_c : integer:= 70; *\/ +#define RX_UDPMACL_AREG 71<<11//rx_udpmacL_AReg_c : integer:= 71; *\/ +#define RX_UDPMACH_AREG 72<<11//rx_udpmacH_AReg_c : integer:= 72; *\/ +#define DETECTORMACL_AREG 73<<11//detectormacL_AReg_c : integer:= 73; *\/ +#define DETECTORMACH_AREG 74<<11//detectormacH_AReg_c : integer:= 74; *\/ +#define DETECTORIP_AREG 75<<11//detectorip_AReg_c : integer:= 75; *\/ +#define IPCHKSUM_AREG 76<<11//ipchksum_AReg_c : integer:= 76; *\/ */ +#endif + + +#define PATTERN_CNTRL_REG 82<<11 // address of patword +#define PATTERN_LIMITS_AREG 83<<11 // start/stop pattern + +#define PATTERN_LOOP0_AREG 84<<11 // start/stop of loop +#define PATTERN_N_LOOP0_REG 85<<11 // # loops + +#define PATTERN_LOOP1_AREG 86<<11 +#define PATTERN_N_LOOP1_REG 87<<11 + +#define PATTERN_LOOP2_AREG 88<<11 +#define PATTERN_N_LOOP2_REG 89<<11 + +#define PATTERN_WAIT0_AREG 90<<11 // address where to wait +#define PATTERN_WAIT1_AREG 91<<11 +#define PATTERN_WAIT2_AREG 92<<11 + + + +//#define DAQ_REG 93<<11 //unused +#define NSAMPLES_REG 93<<11 //unused + + +#define HV_REG 95<<11 + + + +#define PATTERN_IOCTRL_REG_LSB 108<<11 // if output or not +#define PATTERN_IOCTRL_REG_MSB 109<<11 + +#define PATTERN_IOCLKCTRL_REG_LSB 110<<11//unused +#define PATTERN_IOCLKCTRL_REG_MSB 111<<11//unused +#define PATTERN_IN_REG_LSB 112<<11 // write word +#define PATTERN_IN_REG_MSB 113<<11 +#define PATTERN_WAIT0_TIME_REG_LSB 114<<11 // how long to wait +#define PATTERN_WAIT0_TIME_REG_MSB 115<<11 +#define PATTERN_WAIT1_TIME_REG_LSB 116<<11 +#define PATTERN_WAIT1_TIME_REG_MSB 117<<11 +#define PATTERN_WAIT2_TIME_REG_LSB 118<<11 +#define PATTERN_WAIT2_TIME_REG_MSB 119<<11 + +//#define DAC_REG_OFF 120 +//#define DAC_0_1_VAL_REG 120<<11 +//#define DAC_2_3_VAL_REG 121<<11 +//#define DAC_4_5_VAL_REG 122<<11 +//#define DAC_6_7_VAL_REG 123<<11 +//#define DAC_8_9_VAL_REG 124<<11 +//#define DAC_10_11_VAL_REG 125<<11 +//#define DAC_12_13_VAL_REG 126<<11 +//#define DAC_14_15_VAL_REG 127<<11 +#define DAC_VAL_REG 121<<11 // value of the DAC +#define DAC_NUM_REG 122<<11 // Index of the DAC, only JCTB +#define DAC_VAL_OUT_REG 42<<11 +#define ADC_LATCH_DISABLE_REG 120<<11 + + + + + + + + +/* registers defined in FPGA */ +#define GAIN_REG 0 +//#define FLOW_CONTROL_REG 0x11<<11 +//#define FLOW_STATUS_REG 0x12<<11 +//#define FRAME_REG 0x13<<11 +#define MULTI_PURPOSE_REG 0 +//#define TIME_FROM_START_REG 0x16<<11 + + +#define ROI_REG 0 // 0x35<<11 +#define OVERSAMPLING_REG 0 // 0x36<<11 +#define MOENCH_CNTR_REG 0 // 0x31<<11 +#define MOENCH_CNTR_OUT_REG 0 // 0x33<<11 +#define MOENCH_CNTR_CONF_REG 0 // 0x32<<11 + + + +//image +#define DARK_IMAGE_REG 0 // 0x81<<11 +#define GAIN_IMAGE_REG 0 // 0x82<<11 + +//counter block memory +#define COUNTER_MEMORY_REG 0 // 0x85<<11 //gotthard + + +//not used +//#define MCB_DOUT_REG_OFF 0 // 0x200000 +//#define FIFO_CNTRL_REG_OFF 0 // 0x300000 +//#define FIFO_COUNTR_REG_OFF 0 // 0x400000 +//not used so far +//#define SPEED_REG 0 // 0x006000 +//#define SET_NBITS_REG 0 // 0x008000 +//not used +//#define GET_SHIFT_IN_REG 0 // 0x022000 + + + +#define SHIFTMOD 2 +#define SHIFTFIFO 9 + +/** for PCB_REV_REG */ +#define DETECTOR_TYPE_MASK 0xFF000000 +#define DETECTOR_TYPE_OFFSET 24 +#define BOARD_REVISION_MASK 0xFFFFFF +#define MOENCH03_MODULE_ID 2 +#define JUNGFRAU_MODULE_ID 1 +#define JUNGFRAU_CTB_ID 3 + + + + +/* for control register (16bit only)*/ +#define START_ACQ_BIT 0x0001 +#define STOP_ACQ_BIT 0x0002 +#define START_FIFOTEST_BIT 0x0004 // ????? +#define STOP_FIFOTEST_BIT 0x0008 // ?????? +#define START_READOUT_BIT 0x0010 +#define STOP_READOUT_BIT 0x0020 +#define START_EXPOSURE_BIT 0x0040 +#define STOP_EXPOSURE_BIT 0x0080 +#define START_TRAIN_BIT 0x0100 +#define STOP_TRAIN_BIT 0x0200 +#define FIFO_RESET_BIT 0x8000 +#define SYNC_RESET 0x0400 +#define GB10_RESET_BIT 0x0800 +#define MEM_RESET_BIT 0x1000 + +/* for status register */ +#define RUN_BUSY_BIT 0x00000001 +#define READOUT_BUSY_BIT 0x00000002 +#define FIFOTEST_BUSY_BIT 0x00000004 //???? +#define WAITING_FOR_TRIGGER_BIT 0x00000008 +#define DELAYBEFORE_BIT 0x00000010 +#define DELAYAFTER_BIT 0x00000020 +#define EXPOSING_BIT 0x00000040 +#define COUNT_ENABLE_BIT 0x00000080 +#define READSTATE_0_BIT 0x00000100 +#define READSTATE_1_BIT 0x00000200 +#define READSTATE_2_BIT 0x00000400 +#define LAM_BIT 0x00000400 // error! +#define SOME_FIFO_FULL_BIT 0x00000800 // error! + + + +#define RUNSTATE_0_BIT 0x00001000 +#define RUNSTATE_1_BIT 0x00002000 +#define RUNSTATE_2_BIT 0x00004000 +#define STOPPED_BIT 0x00008000 // stopped! +#define ALL_FIFO_EMPTY_BIT 0x00010000 // data ready +#define RUNMACHINE_BUSY_BIT 0x00020000 +#define READMACHINE_BUSY_BIT 0x00040000 +#define PLL_RECONFIG_BUSY 0x00100000 + + + +/* for fifo status register */ +#define FIFO_ENABLED_BIT 0x80000000 +#define FIFO_DISABLED_BIT 0x01000000 +#define FIFO_ERROR_BIT 0x08000000 +#define FIFO_EMPTY_BIT 0x04000000 +#define FIFO_DATA_READY_BIT 0x02000000 +#define FIFO_COUNTER_MASK 0x000001ff +#define FIFO_NM_MASK 0x00e00000 +#define FIFO_NM_OFF 21 +#define FIFO_NC_MASK 0x001ffe00 +#define FIFO_NC_OFF 9 + +/* for config register *///not really used yet +#define TOT_ENABLE_BIT 0x00000002 +#define TIMED_GATE_BIT 0x00000004 +#define CONT_RO_ENABLE_BIT 0x00080000 +#define GB10_NOT_CPU_BIT 0x00001000 +#define ADC_OUTPUT_DISABLE_BIT 0x00100 +#define DIGITAL_OUTPUT_ENABLE_BIT 0x00200 + + +/* for speed register */ +#define CLK_DIVIDER_MASK 0x000000ff +#define CLK_DIVIDER_OFFSET 0 +#define SET_LENGTH_MASK 0x00000f00 +#define SET_LENGTH_OFFSET 8 +#define WAIT_STATES_MASK 0x0000f000 +#define WAIT_STATES_OFFSET 12 +#define TOTCLK_DIVIDER_MASK 0xff000000 +#define TOTCLK_DIVIDER_OFFSET 24 +#define TOTCLK_DUTYCYCLE_MASK 0x00ff0000 +#define TOTCLK_DUTYCYCLE_OFFSET 16 + +/* for external signal register */ +#define SIGNAL_OFFSET 4 +#define SIGNAL_MASK 0xF +#define EXT_SIG_OFF 0x0 +#define EXT_GATE_IN_ACTIVEHIGH 0x1 +#define EXT_GATE_IN_ACTIVELOW 0x2 +#define EXT_TRIG_IN_RISING 0x3 +#define EXT_TRIG_IN_FALLING 0x4 +#define EXT_RO_TRIG_IN_RISING 0x5 +#define EXT_RO_TRIG_IN_FALLING 0x6 +#define EXT_GATE_OUT_ACTIVEHIGH 0x7 +#define EXT_GATE_OUT_ACTIVELOW 0x8 +#define EXT_TRIG_OUT_RISING 0x9 +#define EXT_TRIG_OUT_FALLING 0xA +#define EXT_RO_TRIG_OUT_RISING 0xB +#define EXT_RO_TRIG_OUT_FALLING 0xC + + + +/* for temperature register */ +#define T1_CLK_BIT 0x00000001 +#define T1_CS_BIT 0x00000002 +#define T2_CLK_BIT 0x00000004 +#define T2_CS_BIT 0x00000008 + + + +/* fifo control register */ +//#define FIFO_RESET_BIT 0x00000001 +//#define FIFO_DISABLE_TOGGLE_BIT 0x00000002 + + +//chip shiftin register meaning +#define OUTMUX_OFF 20 +#define OUTMUX_MASK 0x1f +#define PROBES_OFF 4 +#define PROBES_MASK 0x7f +#define OUTBUF_OFF 0 +#define OUTBUF_MASK 1 + + +/* multi purpose register */ +#define PHASE_STEP_BIT 0x00000001 +#define PHASE_STEP_OFFSET 0 +// #define xxx_BIT 0x00000002 +#define RESET_COUNTER_BIT 0x00000004 +#define RESET_COUNTER_OFFSET 2 +//#define xxx_BIT 0x00000008 +//#define xxx_BIT 0x00000010 +#define SW1_BIT 0x00000020 +#define SW1_OFFSET 5 +#define WRITE_BACK_BIT 0x00000040 +#define WRITE_BACK_OFFSET 6 +#define RESET_BIT 0x00000080 +#define RESET_OFFSET 7 +#define ENET_RESETN_BIT 0x00000800 +#define ENET_RESETN_OFFSET 11 +#define INT_RSTN_BIT 0x00002000 +#define INT_RSTN_OFFSET 13 +#define DIGITAL_TEST_BIT 0x00004000 +#define DIGITAL_TEST_OFFSET 14 +//#define CHANGE_AT_POWER_ON_BIT 0x00008000 +//#define CHANGE_AT_POWER_ON_OFFSET 15 + + +/* settings/conf gain register */ +#define GAIN_MASK 0x0000000f +#define GAIN_OFFSET 0 +#define SETTINGS_MASK 0x000000f0 +#define SETTINGS_OFFSET 4 + + +/* CHIP_OF_INTRST_REG */ +#define CHANNEL_MASK 0xffff0000 +#define CHANNEL_OFFSET 16 +#define ACTIVE_ADC_MASK 0x0000001f + + + +/**ADC SYNC CLEAN FIFO*/ +#define ADCSYNC_CLEAN_FIFO_BITS 0x300000 +#define CLEAN_FIFO_MASK 0x0fffff + + + + +enum {run_clk_c, adc_clk_c, sync_clk_c, dbit_clk_c}; + + + + +#define PLL_CNTR_ADDR_OFF 16 //PLL_CNTR_REG bits 21 downto 16 represent the counter address + +#define PLL_CNTR_RECONFIG_RESET_BIT 0 +#define PLL_CNTR_READ_BIT 1 +#define PLL_CNTR_WRITE_BIT 2 +#define PLL_CNTR_PLL_RESET_BIT 3 + + +#define PLL_CNTR_PHASE_EN_BIT 8 +#define PLL_CNTR_UPDN_BIT 9 +#define PLL_CNTR_CNTSEL_OFF 10 + + + + + +#define PLL_MODE_REG 0x0 +#define PLL_STATUS_REG 0x1 +#define PLL_START_REG 0x2 +#define PLL_N_COUNTER_REG 0x3 +#define PLL_M_COUNTER_REG 0x4 +#define PLL_C_COUNTER_REG 0x5 //which ccounter stands in param 22:18; 7:0 lowcount 15:8 highcount; 16 bypassenable; 17 oddivision +#define PLL_PHASE_SHIFT_REG 0x6 // which ccounter stands in param 16:20; 21 updown (1 up, 0 down) +#define PLL_K_COUNTER_REG 0x7 +#define PLL_BANDWIDTH_REG 0x8 +#define PLL_CHARGEPUMP_REG 0x9 +#define PLL_VCO_DIV_REG 0x1c +#define PLL_MIF_REG 0x1f + +#define PPL_M_CNT_PARAM_DEFAULT 0x4040 +#define PPL_N_CNT_PARAM_DEFAULT 0x20D0C +#define PPL_C0_CNT_PARAM_DEFAULT 0x20D0C +#define PPL_C1_CNT_PARAM_DEFAULT 0xA0A0 +#define PPL_C2_CNT_PARAM_DEFAULT 0x20D0C +#define PPL_C3_CNT_PARAM_DEFAULT 0x0808 +#define PPL_BW_PARAM_DEFAULT 0x2EE0 +#define PPL_VCO_PARAM_DEFAULT 0x1 + +#define NEW_PLL_RECONFIG + +#ifdef NEW_PLL_RECONFIG +#define PLL_VCO_FREQ_MHZ 400//480//800 +#else +#define PLL_VCO_FREQ_MHZ 480//800 +#endif + + + + + +/* + GBE parameter and control registers definitions +*/ + +#define GBE_CTRL_WSTROBE 0 +#define GBE_CTRL_VAR_OFFSET 16 +#define GBE_CTRL_VAR_MASK 0XF +#define GBE_CTRL_RAMADDR_OFFSET 24 +#define GBE_CTRL_RAMADDR_MASK 0X3F +#define GBE_CTRL_INTERFACE 23 + +#define RX_UDP_IP_ADDR 0 +#define RX_UDP_PORTS_ADDR 1 +#define RX_UDP_MAC_L_ADDR 2 +#define RX_UDP_MAC_H_ADDR 3 +#define IPCHECKSUM_ADDR 4 +#define GBE_DELAY_ADDR 5 +#define GBE_RESERVED1_ADDR 6 +#define GBE_RESERVED2_ADDR 7 +#define DETECTOR_MAC_L_ADDR 8 +#define DETECTOR_MAC_H_ADDR 9 +#define DETECTOR_IP_ADDR 10 + + + +/**------------------ +-- pattern registers definitions +--------------------------------------------- */ +#define IOSIGNALS_MASK 0xfffffffffffff +#define ADC_ENABLE_BIT 63 +#define APATTERN_MASK 0xffff +#define ASTART_OFFSET 0 +#define ASTOP_OFFSET 16 +#define PATTERN_CTRL_WRITE_BIT 0 +#define PATTERN_CTRL_READ_BIT 1 +#define PATTERN_CTRL_ADDR_OFFSET 16 +#define MAX_PATTERN_LENGTH 1024 + + +#endif + diff --git a/slsDetectorSoftware/mythen3DetectorServer/blackfin.h b/slsDetectorSoftware/mythen3DetectorServer/blackfin.h new file mode 100755 index 000000000..55b3a39b1 --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/blackfin.h @@ -0,0 +1,154 @@ +#ifndef BLACKFIN_H +#define BLACKFIN_H + +#include "ansi.h" + +#include +#include // open +#include // mmap + + +/* global variables */ +u_int32_t CSP0BASE = 0; +#define CSP0 0x20200000 +#define MEM_SIZE 0x100000 + + + +/** + * Write into a 16 bit register + * @param offset address offset + * @param data 16 bit data + */ +void bus_w16(u_int32_t offset, u_int16_t data) { + volatile u_int16_t *ptr1; + ptr1=(u_int16_t*)(CSP0BASE+offset*2); + *ptr1=data; +} + +/** + * Read from a 16 bit register + * @param offset address offset + * @retuns 16 bit data read + */ +u_int16_t bus_r16(u_int32_t offset){ + volatile u_int16_t *ptr1; + ptr1=(u_int16_t*)(CSP0BASE+offset*2); + return *ptr1; +} + +/** + * Write into a 32 bit register + * @param offset address offset + * @param data 32 bit data + */ +void bus_w(u_int32_t offset, u_int32_t data) { + volatile u_int32_t *ptr1; + ptr1=(u_int32_t*)(CSP0BASE+offset*2); + *ptr1=data; +} + +/** + * Read from a 32 bit register + * @param offset address offset + * @retuns 32 bit data read + */ +u_int32_t bus_r(u_int32_t offset) { + volatile u_int32_t *ptr1; + ptr1=(u_int32_t*)(CSP0BASE+offset*2); + return *ptr1; +} + +/** + * Read from a 64 bit register + * @param aLSB LSB offset address + * @param aMSB MSB offset address + * @returns 64 bit data read + */ +int64_t get64BitReg(int aLSB, int aMSB){ + int64_t v64; + u_int32_t vLSB,vMSB; + vLSB=bus_r(aLSB); + vMSB=bus_r(aMSB); + v64=vMSB; + v64=(v64<<32) | vLSB; + printf(" reg64(%x,%x) %x %x %llx\n", aLSB, aMSB, vLSB, vMSB, v64); + return v64; +} + +/** + * Write into a 64 bit register + * @param value 64 bit data + * @param aLSB LSB offset address + * @param aMSB MSB offset address + * @returns 64 bit data read + */ +int64_t set64BitReg(int64_t value, int aLSB, int aMSB){ + int64_t v64; + u_int32_t vLSB,vMSB; + if (value!=-1) { + vLSB=value&(0xffffffff); + bus_w(aLSB,vLSB); + v64=value>> 32; + vMSB=v64&(0xffffffff); + bus_w(aMSB,vMSB); + } + return get64BitReg(aLSB, aMSB); + +} + +/** + * Read from a 32 bit register (literal register value provided by client) + * @param offset address offset + * @retuns 32 bit data read + */ +u_int32_t readRegister(u_int32_t offset) { + return bus_r(offset << 11); +} + +/** + * Write into a 32 bit register (literal register value provided by client) + * @param offset address offset + * @param data 32 bit data + */ +u_int32_t writeRegister(u_int32_t offset, u_int32_t data) { + bus_w(offset << 11, data); + return readRegister(offset); +} + + +/** + * Map FPGA + */ +int mapCSP0(void) { + // if not mapped + if (!CSP0BASE) { + printf("Mapping memory\n"); +#ifdef VIRTUAL + CSP0BASE = malloc(MEM_SIZE); + printf("memory allocated\n"); +#else + int fd; + fd = open("/dev/mem", O_RDWR | O_SYNC, 0); + if (fd == -1) { + cprintf(BG_RED, "Error: Can't find /dev/mem\n"); + return FAIL; + } +#ifdef VERBOSE + printf("/dev/mem opened\n"); +#endif + CSP0BASE = (u_int32_t)mmap(0, MEM_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, CSP0); + if (CSP0BASE == (u_int32_t)MAP_FAILED) { + cprintf(BG_RED, "Error: Can't map memmory area\n"); + return FAIL; + } + printf("CSPOBASE mapped from %08x to %08x\n",CSP0BASE,CSP0BASE+MEM_SIZE); +#endif + printf("Status Register: %08x\n",bus_r(STATUS_REG)); + }else + printf("Memory already mapped before\n"); + return OK; +} + + +#endif //BLACKFIN_H diff --git a/slsDetectorSoftware/mythen3DetectorServer/commonServerFunctions.h b/slsDetectorSoftware/mythen3DetectorServer/commonServerFunctions.h new file mode 100755 index 000000000..4122fb7cf --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/commonServerFunctions.h @@ -0,0 +1,60 @@ +#ifndef COMMON_SERVER_FUNCTIONS_H +#define COMMON_SERVER_FUNCTIONS_H + +#ifndef GOTTHARDD //gotthard already had bus_w etc defined in its firmware_funcs.c (not yet made with common files) +#include "blackfin.h" +#endif + +/* global variables */ +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) { +#ifdef VERBOSE + if (numbitstosend == 16) + printf("Writing to SPI Register: 0x%04x\n",val); + else + printf("Writing to SPI Register: 0x%08x\n", val); +#endif + + u_int32_t valw; + + // start point + valw = 0xffffffff; // old board compatibility (not using specific bits) + bus_w (addr, valw); + + // chip sel bar down + valw &= ~csmask; /* todo with test: done a bit different, not with previous value */ + bus_w (addr, valw); + + { + int i = 0; + for (i = 0; i < numbitstosend; ++i) { + + // clk down + valw &= ~clkmask; + bus_w (addr, valw); + + // write data (i) + valw = ((valw & ~digoutmask) + // unset bit + (((val >> (numbitstosend - 1 - i)) & 0x1) << digofset)); // each bit from val starting from msb + bus_w (addr, valw); + + // clk up + valw |= clkmask ; + bus_w (addr, valw); + } + } + + // chip sel bar up + valw |= csmask; /* todo with test: not done for spi */ + bus_w (addr, valw); + + //clk down + valw &= ~clkmask; + bus_w (addr, valw); + + // stop point = start point of course + valw = 0xffffffff; // old board compatibility (not using specific bits) + bus_w (addr, valw); +} + + +#endif //COMMON_SERVER_FUNCTIONS_H diff --git a/slsDetectorSoftware/mythen3DetectorServer/communication_funcs.c b/slsDetectorSoftware/mythen3DetectorServer/communication_funcs.c new file mode 100755 index 000000000..caa58a8c4 --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/communication_funcs.c @@ -0,0 +1,690 @@ + + +#include "communication_funcs.h" +//#include +#include /* for TCP_NODELAY */ +#include +#include +#include +#include + +#include +char lastClientIP[INET_ADDRSTRLEN]; +char thisClientIP[INET_ADDRSTRLEN]; +int lockStatus; +int differentClients; + +//int socketDescriptor, file_des; +const int send_rec_max_size=SEND_REC_MAX_SIZE; +extern int errno; + + +char dummyClientIP[INET_ADDRSTRLEN]; + + +fd_set readset, tempset; +int isock=0, maxfd; + + +int myport=-1; + +//struct sockaddr_in address; +//#define VERBOSE + + +int bindSocket(unsigned short int port_number) { + int i; + + struct sockaddr_in addressS; + int socketDescriptor; + //int file_des; + + //file_des= -1; + + + + + + + + + + + if (myport==port_number) + return -10; + + + + + + socketDescriptor = socket(AF_INET, SOCK_STREAM,0); //tcp + + //socketDescriptor = socket(PF_INET, SOCK_STREAM, 0); + + + + if (socketDescriptor < 0) { + printf("Can not create socket\n"); + } else { + + i = 1; + setsockopt(socketDescriptor, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); + // setsockopt(socketDescriptor, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i)); + // TCP_CORK + + // Set some fields in the serverAddress structure. + addressS.sin_family = AF_INET; + addressS.sin_addr.s_addr = htonl(INADDR_ANY); + addressS.sin_port = htons(port_number); + + // memset(&address.sin_addr, 0, sizeof(address.sin_addr)); + + + if(bind(socketDescriptor,(struct sockaddr *) &addressS,sizeof(addressS))<0){ + + printf("Can not create socket\n"); + + socketDescriptor=-1; + } else { + if (listen(socketDescriptor, 5)==0) { + + if (isock==0) { + FD_ZERO(&readset); + } + + + FD_SET(socketDescriptor, &readset); + isock++; + maxfd = socketDescriptor; + printf ("%d port %d fd %d\n",isock, port_number,socketDescriptor); + myport=port_number; + } else + printf("error on listen"); + } + } + + + + //int getrlimit(int resource, struct rlimit *rlim); + + + + return socketDescriptor; + +} + + + + + +int getServerError(int socketDescriptor) +{ + if (socketDescriptor<0) return 1; + else return 0; +}; + + +int acceptConnection(int socketDescriptor) { + + + int j; + + + struct sockaddr_in addressC; + int file_des=-1; + struct timeval tv; + int result; + + + //socklen_t address_length; + socklen_t address_length=sizeof(struct sockaddr_in); + + if (socketDescriptor<0) + return -1; + + memcpy(&tempset, &readset, sizeof(tempset)); + tv.tv_sec = 10000000; + tv.tv_usec = 0; + result = select(maxfd + 1, &tempset, NULL, NULL, &tv); + + if (result == 0) { + printf("select() timed out!\n"); + } else if (result < 0 && errno != EINTR) { + printf("Error in select(): %s\n", strerror(errno)); + } else if (result > 0) { +#ifdef VERBOSE + printf("select returned!\n"); +#endif + for (j=0; j=0) + close(file_des); + FD_CLR(file_des, &readset); +} + +void exitServer(int socketDescriptor) { + if (socketDescriptor>=0) + close(socketDescriptor); +#ifdef VERY_VERBOSE + printf("Closing server\n"); +#endif + FD_CLR(socketDescriptor, &readset); + socketDescriptor=-1; + isock--; +} + + + + +void swapData(void* val,int length,intType itype){ + int i; + int16_t* c= (int16_t*)val; + int32_t* a= (int32_t*)val; + int64_t* b= (int64_t*)val; + for(i=0; length > 0; i++){ + switch(itype){ + case INT16: + c[i] = ((c[i] & 0x00FF) << 8) | ((c[i] & 0xFF00) >> 8); + length -= sizeof(int16_t); + break; + case INT32: + a[i]=((a[i] << 8) & 0xFF00FF00) | ((a[i] >> 8) & 0xFF00FF ); + a[i]=(a[i] << 16) | ((a[i] >> 16) & 0xFFFF); + length -= sizeof(int32_t); + break; + case INT64: + b[i] = ((b[i] << 8) & 0xFF00FF00FF00FF00ULL ) | ((b[i] >> 8) & 0x00FF00FF00FF00FFULL ); + b[i] = ((b[i] << 16) & 0xFFFF0000FFFF0000ULL ) | ((b[i] >> 16) & 0x0000FFFF0000FFFFULL ); + b[i] = (b[i] << 32) | ((b[i] >> 32) & 0xFFFFFFFFULL); + length -= sizeof(int64_t); + break; + default: + length = 0; + break; + } + } +} + +int sendData(int file_des, void* buf,int length, intType itype){ +#ifndef PCCOMPILE +#ifdef EIGERD + swapData(buf, length, itype); +#endif +#endif + return sendDataOnly(file_des, buf, length); +} + + +int receiveData(int file_des, void* buf,int length, intType itype){ + int ret = receiveDataOnly(file_des, buf, length); +#ifndef PCCOMPILE +#ifdef EIGERD + if (ret >= 0) swapData(buf, length, itype); +#endif +#endif + return ret; +} + + + int sendDataOnly(int file_des, void* buf,int length) { + int ret = write(file_des, buf, length); //value of -1 is other end socket crash as sigpipe is ignored + if (ret < 0) cprintf(BG_RED, "Error writing to socket. Possible socket crash\n"); + return ret; +} + + + int receiveDataOnly(int file_des, void* buf,int length) { + + int total_received=0; + int nreceiving; + int nreceived; + if (file_des<0) return -1; +#ifdef VERY_VERBOSE + printf("want to receive %d Bytes\n", length); +#endif + + while(length > 0) { + nreceiving = (length>send_rec_max_size) ? send_rec_max_size:length; + nreceived = read(file_des,(char*)buf+total_received,nreceiving); + if(!nreceived){ + if(!total_received) { + return -1; //to handle it + } + break; + } + length-=nreceived; + total_received+=nreceived; + } + + if (total_received>0) + strcpy(thisClientIP,dummyClientIP); + + if (strcmp(lastClientIP,thisClientIP)) + differentClients=1; + else + differentClients=0; + + return total_received; +} + + + + + + + + + + + + + + + +int sendChannel(int file_des, sls_detector_channel *myChan) { + int ts=0; + //sendDataOnly(file_des,myChan, sizeof(sls_detector_channel)); + ts+=sendData(file_des,&(myChan->chan),sizeof(myChan->chan),INT32); + ts+=sendData(file_des,&(myChan->chip),sizeof(myChan->chip),INT32); + ts+=sendData(file_des,&(myChan->module),sizeof(myChan->module),INT32); + ts+=sendData(file_des,&(myChan->reg),sizeof(myChan->reg),INT64); + return ts; +} + +int sendChip(int file_des, sls_detector_chip *myChip) { + int ts=0; + //ts+=sendDataOnly(file_des,myChip,sizeof(sls_detector_chip)); + ts+=sendData(file_des,&(myChip->chip),sizeof(myChip->chip),INT32); + ts+=sendData(file_des,&(myChip->module),sizeof(myChip->module),INT32); + ts+=sendData(file_des,&(myChip->nchan),sizeof(myChip->nchan),INT32); + ts+=sendData(file_des,&(myChip->reg),sizeof(myChip->reg),INT32); + ts+=sendData(file_des,(myChip->chanregs),sizeof(myChip->chanregs),INT32); + ts+=sendData(file_des,myChip->chanregs,myChip->nchan*sizeof(int),INT32); + return ts; +} + + +int sendModule(int file_des, sls_detector_module *myMod) { + return sendModuleGeneral(file_des, myMod, 1); +} + + +int sendModuleGeneral(int file_des, sls_detector_module *myMod, int sendAll) { + int ts=0; +#ifdef VERBOSE + int idac; +#endif + int nChips=myMod->nchip; + int nChans=myMod->nchan; + int nAdcs=myMod->nadc; + int nDacs=myMod->ndac; + //ts+= sendDataOnly(file_des,myMod,sizeof(sls_detector_module)); + ts+=sendData(file_des,&(myMod->module),sizeof(myMod->module),INT32); + 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->dacs,sizeof(myMod->ndac),OTHER); + if(sendAll){ + ts+=sendData(file_des,myMod->adcs,sizeof(myMod->nadc),OTHER); + }else{ + uint32_t k = 0; + ts+=sendData(file_des,&k,sizeof(k),OTHER); + } + + /*some detectors dont require sending all trimbits etc.*/ + if(sendAll){ + ts+=sendData(file_des,myMod->chipregs,sizeof(myMod->nchip),OTHER); + ts+=sendData(file_des,myMod->chanregs,sizeof(myMod->nchan),OTHER); + } + ts+=sendData(file_des,&(myMod->gain), sizeof(myMod->gain),OTHER); + ts+=sendData(file_des,&(myMod->offset), sizeof(myMod->offset),OTHER); + +#ifdef VERBOSE + printf("module %d of size %d sent\n",myMod->module, ts); +#endif + ts+= sendData(file_des,myMod->dacs,sizeof(dacs_t)*nDacs,INT32); +#ifdef VERBOSE + printf("dacs %d of size %d sent\n",myMod->module, ts); + for (idac=0; idac< nDacs; idac++) + printf("dac %d is %d\n",idac,(int)myMod->dacs[idac]); +#endif + if(sendAll) + ts+= sendData(file_des,myMod->adcs,sizeof(dacs_t)*nAdcs,INT32); + else { + uint32_t k = 0; + ts+= sendData(file_des,&k,sizeof(k),INT32); + } + +#ifdef VERBOSE + printf("adcs %d of size %d sent\n",myMod->module, ts); +#endif + + /*some detectors dont require sending all trimbits etc.*/ + if(sendAll){ + ts+=sendData(file_des,myMod->chipregs,sizeof(int)*nChips,INT32); +#ifdef VERBOSE + printf("chips %d of size %d sent\n",myMod->module, ts); +#endif + ts+=sendData(file_des,myMod->chanregs,sizeof(int)*nChans,INT32); +#ifdef VERBOSE + printf("chans %d of size %d sent - %d\n",myMod->module, ts, myMod->nchan); +#endif + } + +#ifdef VERBOSE + printf("module %d of size %d sent register %x\n",myMod->module, ts, myMod->reg); +#endif + return ts; +} + +int receiveChannel(int file_des, sls_detector_channel *myChan) { + int ts=0; + //receiveDataOnly(file_des,myChan,sizeof(sls_detector_channel)); + ts+=receiveData(file_des,&(myChan->chan),sizeof(myChan->chan),INT32); + ts+=receiveData(file_des,&(myChan->chip),sizeof(myChan->chip),INT32); + ts+=receiveData(file_des,&(myChan->module),sizeof(myChan->module),INT32); + ts+=receiveData(file_des,&(myChan->reg),sizeof(myChan->reg),INT32); + return ts; +} + +int receiveChip(int file_des, sls_detector_chip* myChip) { + + int *ptr=myChip->chanregs; + int ts=0; + int nChans, nchanold=myChip->nchan, chdiff; + + //ts+= receiveDataOnly(file_des,myChip,sizeof(sls_detector_chip)); + ts+=receiveData(file_des,&(myChip->chip),sizeof(myChip->chip),INT32); + ts+=receiveData(file_des,&(myChip->module),sizeof(myChip->module),INT32); + ts+=receiveData(file_des,&(myChip->nchan),sizeof(myChip->nchan),INT32); + ts+=receiveData(file_des,&(myChip->reg),sizeof(myChip->reg),INT32); + ts+=receiveData(file_des,(myChip->chanregs),sizeof(myChip->chanregs),INT32); + + myChip->chanregs=ptr; + nChans=myChip->nchan; + chdiff=nChans-nchanold; + if (nchanold!=nChans) { + printf("wrong number of channels received!\n"); + } + + +#ifdef VERBOSE + printf("chip structure received\n"); + printf("now receiving %d channels\n", nChans); +#endif + + if (chdiff<=0) + ts+=receiveData(file_des,myChip->chanregs, sizeof(int)*nChans,INT32); + else { + ptr=(int*)malloc(chdiff*sizeof(int)); + myChip->nchan=nchanold; + ts+=receiveData(file_des,myChip->chanregs, sizeof(int)*nchanold,INT32); + ts+=receiveData(file_des,ptr, sizeof(int)*chdiff,INT32); + free(ptr); + return FAIL; + } + +#ifdef VERBOSE + printf("chip's channels received\n"); +#endif + return ts; +} + + +int receiveModule(int file_des, sls_detector_module* myMod) { + return receiveModuleGeneral(file_des,myMod,1); +} + +int receiveModuleGeneral(int file_des, sls_detector_module* myMod, int receiveAll) { + int ts=0; + dacs_t *dacptr=myMod->dacs; + dacs_t *adcptr=myMod->adcs; + int *chipptr=myMod->chipregs, *chanptr=myMod->chanregs; + int nChips, nchipold=myMod->nchip, nchipdiff; + int nChans, nchanold=myMod->nchan, nchandiff; + int nDacs, ndold=myMod->ndac, ndacdiff; + int nAdcs, naold=myMod->nadc, nadcdiff; +#ifdef VERBOSE + int id=0; +#endif + // ts+= receiveDataOnly(file_des,myMod,sizeof(sls_detector_module)); + ts+=receiveData(file_des,&(myMod->module),sizeof(myMod->module),INT32); + 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->dacs,sizeof(myMod->ndac),INT32); + if(receiveAll){ // temporary fix + ts+=receiveData(file_des,myMod->adcs,sizeof(myMod->nadc),INT32); + }else { + uint32_t k;ts+=receiveData(file_des,&k,sizeof(k),INT32);//nadc is 0 + } + + /*some detectors dont require sending all trimbits etc.*/ + if(receiveAll){ + ts+=receiveData(file_des,myMod->chipregs,sizeof(myMod->nchip),INT32); + ts+=receiveData(file_des,myMod->chanregs,sizeof(myMod->nchan),INT32); + } + ts+=receiveData(file_des,&(myMod->gain), sizeof(myMod->gain),OTHER); + ts+=receiveData(file_des,&(myMod->offset), sizeof(myMod->offset),OTHER); + + myMod->dacs=dacptr; + myMod->adcs=adcptr; + myMod->chipregs=chipptr; + myMod->chanregs=chanptr; + +#ifdef EIGERD + //feature to exclude sending of trimbtis, nchips=0,nchans=0 in that case + if(myMod->nchip == 0 && myMod->nchan == 0) { + receiveAll=0; + nchipold=0; + nchanold=0; + } +#endif + + + nChips=myMod->nchip; + nchipdiff=nChips-nchipold; + if (nchipold!=nChips) { + printf("received wrong number of chips\n"); + } +#ifdef VERBOSE + else + printf("received %d chips\n",nChips); +#endif + + nChans=myMod->nchan; + nchandiff=nChans-nchanold; + if (nchanold!=nChans) { + printf("received wrong number of channels\n"); + } +#ifdef VERBOSE + else + printf("received %d chans\n",nChans); +#endif + + + nDacs=myMod->ndac; + ndacdiff=nDacs-ndold; + if (ndold!=nDacs) { + printf("received wrong number of dacs\n"); + } +#ifdef VERBOSE + else + printf("received %d dacs\n",nDacs); +#endif + + nAdcs=myMod->nadc; + nadcdiff=nAdcs-naold; + if (naold!=nAdcs) { + printf("received wrong number of adcs\n"); + } +#ifdef VERBOSE + else + printf("received %d adcs\n",nAdcs); +#endif + if (ndacdiff<=0) { + ts+=receiveData(file_des,myMod->dacs, sizeof(dacs_t)*nDacs,INT32); +#ifdef VERBOSE + printf("dacs received\n"); + int id; + for (id=0; iddacs[id]); + + +#endif + } else { + dacptr=(dacs_t*)malloc(ndacdiff*sizeof(dacs_t)); + myMod->ndac=ndold; + ts+=receiveData(file_des,myMod->dacs, sizeof(dacs_t)*ndold,INT32); + ts+=receiveData(file_des,dacptr, sizeof(dacs_t)*ndacdiff,INT32); + free(dacptr); + return FAIL; + } + + if (nadcdiff<=0) { + ts+=receiveData(file_des,myMod->adcs, sizeof(dacs_t)*nAdcs,INT32); +#ifdef VERBOSE + printf("adcs received\n"); +#endif + } else { + adcptr=(dacs_t*)malloc(nadcdiff*sizeof(dacs_t)); + myMod->nadc=naold; + ts+=receiveData(file_des,myMod->adcs, sizeof(dacs_t)*naold,INT32); + ts+=receiveData(file_des,adcptr, sizeof(dacs_t)*nadcdiff,INT32); + free(adcptr); + return FAIL; + } + + + /*some detectors dont require sending all trimbits etc.*/ + if(receiveAll){ + + if (nchipdiff<=0) { + ts+=receiveData(file_des,myMod->chipregs, sizeof(int)*nChips,INT32); +#ifdef VERBOSE + printf("chips received\n"); +#endif + } 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); + free(chipptr); + return FAIL; + } + + if (nchandiff<=0) { + ts+=receiveData(file_des,myMod->chanregs, sizeof(int)*nChans,INT32); +#ifdef VERBOSE + printf("chans received\n"); +#endif + } 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); + free(chanptr); + return FAIL; + } + } +#ifdef VERBOSE + printf("received module %d of size %d register %x\n",myMod->module,ts,myMod->reg); +#endif + + return ts; +} diff --git a/slsDetectorSoftware/mythen3DetectorServer/communication_funcs.h b/slsDetectorSoftware/mythen3DetectorServer/communication_funcs.h new file mode 100755 index 000000000..e4e3fac27 --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/communication_funcs.h @@ -0,0 +1,51 @@ +#ifndef COMMUNICATION_FUNCS_H +#define COMMUNICATION_FUNCS_H + +#define SEND_REC_MAX_SIZE 4096 +#define DEFAULT_PORTNO 1952 +#include +#include + + +#include +#include +#include +#include + +#include "sls_detector_defs.h" + + + +typedef enum{ + INT16, + INT32, + INT64, + OTHER +}intType; + + + + +int bindSocket(unsigned short int port_number); +int acceptConnection(int socketDescriptor); +void closeConnection(int file_Des); +void exitServer(int socketDescriptor); + +void swapData(void* val,int length,intType itype); +int sendData(int file_des, void* buf,int length, intType itype); +int receiveData(int file_des, void* buf,int length, intType itype); +int sendDataOnly(int file_des, void* buf,int length); +int receiveDataOnly(int file_des, void* buf,int length); + + +int getServerError(int socketDescriptor); +int sendChannel(int file_des, sls_detector_channel *myChan); +int sendChip(int file_des, sls_detector_chip *myChip); +int sendModule(int file_des, sls_detector_module *myMod); +int sendModuleGeneral(int file_des, sls_detector_module *myMod, int sendAll); +int receiveChannel(int file_des, sls_detector_channel *myChan); +int receiveChip(int file_des, sls_detector_chip* myChip); +int receiveModule(int file_des, sls_detector_module* myMod); +int receiveModuleGeneral(int file_des, sls_detector_module* myMod, int receiveAll); + +#endif diff --git a/slsDetectorSoftware/mythen3DetectorServer/programfpga.h b/slsDetectorSoftware/mythen3DetectorServer/programfpga.h new file mode 100755 index 000000000..db7b1cfb8 --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/programfpga.h @@ -0,0 +1,178 @@ +#ifndef PROGRAM_FPGA_H +#define PROGRAM_FPGA_H + +#include "ansi.h" + +#include +#include // usleep +#include + + +/* global variables */ +#define CTRL_SRVR_INIT_TIME_US (300 * 1000) +int gpioDefined=0; +char mtdvalue[10]; + + + +/** + * Define GPIO pins if not defined + */ +void defineGPIOpins(){ + if (!gpioDefined) { + //define the gpio pins + system("echo 7 > /sys/class/gpio/export"); + system("echo 9 > /sys/class/gpio/export"); + //define their direction + system("echo in > /sys/class/gpio/gpio7/direction"); + system("echo out > /sys/class/gpio/gpio9/direction"); + printf("gpio pins defined\n"); + gpioDefined = 1; + }else printf("gpio pins already defined earlier\n"); +} + +/** + * Notify FPGA to not touch flash + */ +void FPGAdontTouchFlash(){ + //tell FPGA to not touch flash + system("echo 0 > /sys/class/gpio/gpio9/value"); + //usleep(100*1000); +} + + +/** + * Notify FPGA to program from flash + */ +void FPGATouchFlash(){ + //tell FPGA to touch flash to program itself + system("echo 1 > /sys/class/gpio/gpio9/value"); +} + +/** + * Reset FPGA + */ +void resetFPGA(){ + cprintf(BLUE,"\n*** Reseting FPGA ***\n"); + FPGAdontTouchFlash(); + FPGATouchFlash(); + usleep(CTRL_SRVR_INIT_TIME_US); +} + +/** + * Erasing flash + */ +void eraseFlash(){ +#ifdef VERY_VERBOSE + printf("\nErasing Flash\n"); +#endif + char command[255]; + sprintf(command,"flash_eraseall %s",mtdvalue); + system(command); + printf("flash erased\n"); +} + +/** + * Open the drive to copy program and + * notify FPGA not to touch the program + * @param filefp pointer to flash + * @return 0 for success, 1 for fail (cannot open file for writing program) + */ +int startWritingFPGAprogram(FILE** filefp){ +#ifdef VERY_VERBOSE + printf("\nStart Writing of FPGA program\n"); +#endif + + //getting the drive + char output[255]; + FILE* fp = popen("awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd", "r"); + fgets(output, sizeof(output), fp); + pclose(fp); + strcpy(mtdvalue,"/dev/"); + char* pch = strtok(output,":"); + if(pch == NULL){ + cprintf(RED,"Could not get mtd value\n"); + return FAIL; + } + strcat(mtdvalue,pch); + printf ("\nFlash drive found: %s\n",mtdvalue); + + FPGAdontTouchFlash(); + + //writing the program to flash + *filefp = fopen(mtdvalue, "w"); + if(*filefp == NULL){ + cprintf(RED,"Unable to open %s in write mode\n",mtdvalue); + return 1; + } + printf("flash ready for writing\n"); + + return 0; +} + +/** + * When done writing the program, close file pointer and + * notify FPGA to pick up the program from flash + * @param filefp pointer to flash + */ +void stopWritingFPGAprogram(FILE* filefp){ +#ifdef VERY_VERBOSE + printf("\nStopping of writing FPGA program\n"); +#endif + + int wait = 0; + if(filefp!= NULL){ + fclose(filefp); + wait = 1; + } + + //touch and program + FPGATouchFlash(); + + if(wait){ +#ifdef VERY_VERBOSE + printf("Waiting for FPGA to program from flash\n"); +#endif + //waiting for success or done + char output[255]; + int res=0; + while(res == 0){ + FILE* sysFile = popen("cat /sys/class/gpio/gpio7/value", "r"); + fgets(output, sizeof(output), sysFile); + pclose(sysFile); + sscanf(output,"%d",&res); +#ifdef VERY_VERBOSE + printf("gpi07 returned %d\n",res); +#endif + } + } + printf("FPGA has picked up the program from flash\n\n"); +} + + +/** + * Write FPGA Program to flash + * @param fpgasrc source program + * @param fsize size of program + * @param filefp pointer to flash + * @return 0 for success, 1 for fail (cannot write) + */ +int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp){ +#ifdef VERY_VERBOSE + printf("\nWriting of FPGA Program\n"); + cprintf(BLUE,"address of fpgasrc:%p\n",(void *)fpgasrc); + cprintf(BLUE,"fsize:%d\n",fsize); + cprintf(BLUE,"pointer:%p\n",(void*)filefp); +#endif + + if(fwrite((void*)fpgasrc , sizeof(char) , fsize , filefp )!= fsize){ + cprintf(RED,"Could not write FPGA source to flash\n"); + return 1; + } +#ifdef VERY_VERBOSE + cprintf(BLUE, "program written to flash\n"); +#endif + return 0; +} + +#endif //PROGRAM_FPGA_H diff --git a/slsDetectorSoftware/mythen3DetectorServer/slsDetectorFunctionList.c b/slsDetectorSoftware/mythen3DetectorServer/slsDetectorFunctionList.c new file mode 100644 index 000000000..df40eabff --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/slsDetectorFunctionList.c @@ -0,0 +1,1196 @@ +#ifdef SLS_DETECTOR_FUNCTION_LIST + +#include "slsDetectorFunctionList.h" +#include "slsDetectorServer_defs.h" + +#include +#include + + +const int nChans=NCHAN; +const int nChips=NCHIP; +const int nDacs=NDAC; +const int nAdcs=NADC; +const int allSelected=-2; +const int noneSelected=-1; + +sls_detector_module *detectorModules=NULL; +int *detectorChips=NULL; +int *detectorChans=NULL; +dacs_t *detectorDacs=NULL; +dacs_t *detectorAdcs=NULL; + +int nModY = NMAXMOD; +int nModX = NMAXMOD; +int dynamicRange= DYNAMIC_RANGE; +int dataBytes = NMAXMOD*NCHIP*NCHAN*2; +int masterMode = NO_MASTER; +int syncMode = NO_SYNCHRONIZATION; +int timingMode = AUTO_TIMING; + + + +enum detectorSettings thisSettings; +int sChan, sChip, sMod, sDac, sAdc; +int nModBoard; +extern int dataBytes; + + +int initializeDetectorStructure(){ + + int imod; + int n=getNModBoard(X)*getNModBoard(Y); +#ifdef VERBOSE + printf("Board is for %d modules\n",n); +#endif + detectorModules=malloc(n*sizeof(sls_detector_module)); + detectorChips=malloc(n*NCHIP*sizeof(int)); + detectorChans=malloc(n*NCHIP*NCHAN*sizeof(int)); + detectorDacs=malloc(n*NDAC*sizeof(int)); + detectorAdcs=malloc(n*NADC*sizeof(int)); +#ifdef VERBOSE + printf("modules from 0x%x to 0x%x\n",(unsigned int)(detectorModules), (unsigned int)(detectorModules+n)); + printf("chips from 0x%x to 0x%x\n",(unsigned int)(detectorChips), (unsigned int)(detectorChips+n*NCHIP)); + printf("chans from 0x%x to 0x%x\n",(unsigned int)(detectorChans), (unsigned int)(detectorChans+n*NCHIP*NCHAN)); + printf("dacs from 0x%x to 0x%x\n",(unsigned int)(detectorDacs), (unsigned int)(detectorDacs+n*NDAC)); + printf("adcs from 0x%x to 0x%x\n",(unsigned int)(detectorAdcs), (unsigned int)(detectorAdcs+n*NADC)); +#endif + for (imod=0; imoddacs=detectorDacs+imod*NDAC; + (detectorModules+imod)->adcs=detectorAdcs+imod*NADC; + (detectorModules+imod)->chipregs=detectorChips+imod*NCHIP; + (detectorModules+imod)->chanregs=detectorChans+imod*NCHIP*NCHAN; + (detectorModules+imod)->ndac=NDAC; + (detectorModules+imod)->nadc=NADC; + (detectorModules+imod)->nchip=NCHIP; + (detectorModules+imod)->nchan=NCHIP*NCHAN; + (detectorModules+imod)->module=imod; + (detectorModules+imod)->gain=0; + (detectorModules+imod)->offset=0; + (detectorModules+imod)->reg=0; + /* initialize registers, dacs, retrieve sn, adc values etc */ + } + thisSettings=UNINITIALIZED; + sChan=noneSelected; + sChip=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + + return OK; +} + + + + + + +int setupDetector(){ + //testFpga(); + //testRAM(); + + //setSettings(GET_SETTINGS,-1); + //setFrames(1); + //setTrains(1); + //setExposureTime(1e6); + //setPeriod(1e9); + //setDelay(0); + //setGates(0); + + //setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + //setMaster(GET_MASTER); + //setSynchronization(GET_SYNCHRONIZATION_MODE); + return OK; +} + + + + +int setNMod(int nm, enum dimension dim){ + return 1; +} + + + +int getNModBoard(enum dimension arg){ + return 1; +} + + + + + + + + +int64_t getModuleId(enum idMode arg, int imod){ + //DETECTOR_SERIAL_NUMBER + //DETECTOR_FIRMWARE_VERSION + return 0; +} + + + + +int64_t getDetectorId(enum idMode arg){ + //DETECTOR_SOFTWARE_VERSION defined in slsDetector_defs.h? + return 0; +} + + + + + +int moduleTest( enum digitalTestMode arg, int imod){ + //template testShiftIn from mcb_funcs.c + + //CHIP_TEST + //testShiftIn + //testShiftOut + //testShiftStSel + //testDataInOutMux + //testExtPulseMux + //testOutMux + //testFpgaMux + + return OK; +} + + + + + +int detectorTest( enum digitalTestMode arg){ + //templates from firmware_funcs.c + + //DETECTOR_FIRMWARE_TEST:testFpga() + //DETECTOR_MEMORY_TEST:testRAM() + //DETECTOR_BUS_TEST:testBus() + //DETECTOR_SOFTWARE_TEST:testFpga() + return OK; +} + + + +int 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)); + 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)) ; + return getDacRegister(dacnum); +} + + + +int getDacRegister(int dacnum) { + + 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); +} + + + +int nextDac(){ + return dacSPI(0xf<=0) { + cmd=0x3; + } + else if (dacvalue==-100) { + cmd=0x4; + } + codata=cmd< conversion done in slsDetectorServer_funcs.c-> set_dac() + + //if normal dac: + + int dacval = val; // in DAC + u_int32_t offw; + u_int32_t ichip; // DAC-chip (3 chips with each 8 DACs) + u_int16_t valw; + int i,ddx,csdx,cdx; // ddx=data, cdx=clk, csdx=chipselect + + //select dac-chip: + if (myDetectorType==JUNGFRAUCTB) + ichip=2-ind/8; + printf("This is a CTB\n"); + else + ichip=ind/8; + printf("This is not a CTB\n"); + + // if(val>0 && mV){ // convert to DACu, if val is given in mV + // dacval = val * 4095 / 2500; // convert to DAC + if(dacval<0 || dacval>4095){ + dacval = -1; + printf("The DAC is out of range! Error!"); + return -1; + } + // } + + else if(dacval>=0 && dacval<=4095){ + printf("Setting of DAC %d to %d DACunits",ind,dacval); + ddx=0; // data is first bit in DAC_REG + cdx=1; // clk is 2nd bit in DAC_REG + if (myDetectorType==JUNGFRAUCTB) + csdx=2; + else + csdx=ichip+2; + + //setting int reference + offw=DAC_REG; + valw=bus_r(offw)|0xff; // alles (ddx,cdx,csdx) auf 1 setzen (for START) + bus_w(offw,(valw)); // start point + //chip select down: + valw=((valw&(~(0x1<=0) { + printf("vpower\n"); + dacval=((vmax-val)*4095)/(vmax-vmin); + if (dacval<0) + dacval=0; + if (dacval>4095) + dacval=-100; + if (val==-100) + dacval=-100; + + + } else if (dacindex>=0) { + printf("vchip\n"); + dacval=((2700-val)*4095)/1000; + if (dacval<0) + dacval=0; + if (dacval>4095) + dacval=4095; + + } else { + vLimit=val; + printf("vlimit %d\n",vLimit ); + } + + } + + if (pwrindex>=0 && val!=-1) { + preg=bus_r(POWER_ON_REG); + printf("power reg is %08x\n",bus_r(POWER_ON_REG)); + printf("Switching off power %d\n", pwrindex); + bus_w(POWER_ON_REG,preg&(~(1<<(16+pwrindex)))); + setDAC(dacindex,-100); + printf("power reg is %08x\n",bus_r(POWER_ON_REG)); + retval=0; + } + + if (dacindex>0 && dacval!=-100) { + + printf("Setting power %d to %d mV\n",ind,val); + printf("Setting DAC %d to value %d\n",dacindex,dacval); + retval=setDac(dacindex,dacval); + 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<<(16+pwrindex)))); + printf("power reg is %08x\n",bus_r(POWER_ON_REG)); + } + } + + if (pwrindex>=0) { + if (bus_r(POWER_ON_REG)&(1<<(16+pwrindex))){ + vmax=2700-(getDacRegister(19)*1000)/4095-200; + printf("Vchip id %d mV\n",vmax+200); + retval1=vmax-(retval*(vmax-vmin))/4095; + printf("Vdac id %d mV\n",retval1); + if (retval1>vmax) + retval1=vmax; + if (retval1=0) { + if (retval>=0) { + retval1=2700-(retval*1000)/4095; + printf("Vchip is %d mV\n",vmax); + } else + retval1=-1; + } else { + printf("Get vlimit %d\n",vLimit); + retval=vLimit; + retval1=vLimit; + } + + return retval1; +} + + + +double getADC(enum dacIndex ind, int imod){ + //get adc value + return 0; +} + + + + +int setChannel(sls_detector_channel myChan){ + //template initChannelByNumber() from mcb_funcs.c + + return myChan.reg; +} + + +int getChannel(sls_detector_channel *myChan){ + //template getChannelbyNumber() from mcb_funcs.c + return FAIL; +} + + + +int setChip(sls_detector_chip myChip){ + //template initChipbyNumber() from mcb_funcs.c + return myChip.reg; +} + + +int getChip(sls_detector_chip *myChip){ + //template getChipbyNumber() from mcb_funcs.c + return FAIL; +} + +int setModule(sls_detector_module myChan){ + //template initModulebyNumber() from mcb_funcs.c + return OK; +} + +int getModule(sls_detector_module *myChan){ + //template getModulebyNumber() from mcb_funcs.c + return FAIL; +} + +int getThresholdEnergy(int imod){ + //template getThresholdEnergy() from mcb_funcs.c + //depending on settings + return FAIL; +} + + +int setThresholdEnergy(int thr, int imod){ + //template getThresholdEnergy() from mcb_funcs.c + //depending on settings + return FAIL; +} + + + +enum detectorSettings setSettings(enum detectorSettings sett, int imod){ + //template setSettings() from mcb_funcs.c + //reads the dac registers from fpga to confirm which settings, if weird, undefined + + return OK; +} + +int startStateMachine(){ + //template startStateMachine() from firmware_funcs.c + /* + fifoReset(); + now_ptr=(char*)ram_values; + //send start acquisition to fpga + */ + return FAIL; +} + + +int stopStateMachine(){ + //template stopStateMachine() from firmware_funcs.c + // send stop to fpga + //if status = busy after 500us, return FAIL + return FAIL; +} + + +int startReadOut(){ + //template startReadOut() from firmware_funcs.c + //send fpga start readout + return FAIL; +} + + +enum runStatus getRunStatus(){ + //template runState() from firmware_funcs.c + //get status from fpga + return ERROR; +} + + +char *readFrame(int *ret, char *mess){ + //template fifo_read_event() from firmware_funcs.c + //checks if state machine running and if fifo has data(look_at_me_reg) and accordingly reads frame + // memcpy(now_ptr, values, dataBytes); + //returns ptr to values + return NULL; +} + + +int64_t setTimer(enum timerIndex ind, int64_t val){ + //template setDelay() from firmware_funcs.c + //writes to reg + //FRAME_NUMBER --> defined in sls_receiver_defs.h + //ACQUISITION_TIME + //FRAME_PERIOD -> how many frames per trigger + //DELAY_AFTER_TRIGGER + //GATES_NUMBER + //PROBES_NUMBER = # counters + //CYCLES_NUMBER -> how many triggers + + int64_t retval = -1; // return value to check + + switch(ind){ // only change the timer corresponding to 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: // defined in sls_receiver_defs.h + if(val>=0){ + printf("\n Setting the exposure time: %lld ns \n",(long long int)val); + val *= (1E-3 * CLK_RUN); // convert from ns to clk-cycles + // CLK_RUN is defined in slsDetectorServer_defs.h + } + retval = set64BitReg(val,SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG )/(1E-3 * CLK_RUN); // set the register to val and read back, convert back to ns + // SET_EXPTIME_LSB_REG are defined in RegisterDefs.h + printf("Getting the exposure time: %lld ns \n", (long long int)retval); + break; + + case FRAME_PERIOD: // how many frames per trigger + 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); + // CLK_SYN is defined in slsDetectorServer_defs.h + 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 PROBES_NUMBER: + + case CYCLES_NUMBER: // how many triggers + 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; + + default: + cprintf(RED,"Warning: Timer Index not implemented for this detector: %d\n", ind); + break; + } + return retval; +} + + +int64_t getTimeLeft(enum timerIndex ind){ + //template getDelay() from firmware_funcs.c + //reads from reg + //FRAME_NUMBER + //ACQUISITION_TIME + //FRAME_PERIOD + //DELAY_AFTER_TRIGGER + //GATES_NUMBER + //PROBES_NUMBER + //CYCLES_NUMBER + return -1; +} + + +int setDynamicRange(int dr){ + //template setDynamicRange() from firmware_funcs.c + return 0; +} + + +enum readOutFlags setReadOutFlags(enum readOutFlags val){ + //template setStoreInRAM from firmware_funcs.c + return -1; +} + + + + +int setROI(int n, ROI arg[], int *retvalsize, int *ret){ + return FAIL; +} + + + +int setSpeed(enum speedVariable arg, int val){ + //template setClockDivider() from firmware_funcs.c + //CLOCK_DIVIDER + //WAIT_STATES + //SET_SIGNAL_LENGTH + //TOT_CLOCK_DIVIDER + //TOT_DUTY_CYCLE + + //returns eg getClockDivider from firmware_funcs.c + return 0; +} + + + +int executeTrimming(enum trimMode mode, int par1, int par2, int imod){ + // template trim_with_noise from trimming_funcs.c + return FAIL; +} + + + + +int configureMAC(int ipad, long long int imacadd, long long int iservermacadd, int dtb){ + //detector specific. + return FAIL; +} + + +int loadImage(enum imageType index, char *imageVals){ + //detector specific. + return FAIL; +} + + +int readCounterBlock(int startACQ, char *counterVals){ + //detector specific. + return FAIL; +} + +int resetCounterBlock(int startACQ){ + //detector specific. + return FAIL; +} + +int startReceiver(int d){ + + return 0; +} + +int calibratePedestal(int frames){ + + return 0; +} + +int calculateDataBytes(){ + return 0; +} + +int getTotalNumberOfChannels(){return 0;} +int getTotalNumberOfChips(){return 0;} +int getTotalNumberOfModules(){return 0;} +int getNumberOfChannelsPerChip(){return 0;} +int getNumberOfChannelsPerModule(){return 0;} +int getNumberOfChipsPerModule(){return 0;} +int getNumberOfDACsPerModule(){return 0;} +int getNumberOfADCsPerModule(){return 0;} + + + + + + + +enum externalSignalFlag getExtSignal(int signalindex){ + //template getExtSignal from firmware_funcs.c + //return signals[signalindex]; + return -1; +} + + + + + +enum externalSignalFlag setExtSignal(int signalindex, enum externalSignalFlag flag){ + //template setExtSignal from firmware_funcs.c + + //in short..sets signals array, checks if agrees with timing mode, writes to fpga reg, calls synchronization and then settiming + /* + if (signalindex>=0 && signalindex<4) { + signals[signalindex]=flag; +#ifdef VERBOSE + printf("settings signal variable number %d to value %04x\n", signalindex, signals[signalindex]); +#endif + // if output signal, set it! + switch (flag) { + case GATE_IN_ACTIVE_HIGH: + case GATE_IN_ACTIVE_LOW: + if (timingMode==GATE_FIX_NUMBER || timingMode==GATE_WITH_START_TRIGGER)//timingMode = AUTO_TIMING by default and is set in setTiming() + setFPGASignal(signalindex,flag); //not implemented here, checks if flag within limits and writes to fpga reg + else + setFPGASignal(signalindex,SIGNAL_OFF); + break; + case TRIGGER_IN_RISING_EDGE: + case TRIGGER_IN_FALLING_EDGE: + if (timingMode==TRIGGER_EXPOSURE || timingMode==GATE_WITH_START_TRIGGER) + setFPGASignal(signalindex,flag); + else + setFPGASignal(signalindex,SIGNAL_OFF); + break; + case RO_TRIGGER_IN_RISING_EDGE: + case RO_TRIGGER_IN_FALLING_EDGE: + if (timingMode==BURST_TRIGGER) + setFPGASignal(signalindex,flag); + else + setFPGASignal(signalindex,SIGNAL_OFF); + break; + case MASTER_SLAVE_SYNCHRONIZATION: + setSynchronization(syncMode);//syncmode = NO_SYNCHRONIZATION by default and set with this function + break; + default: + setFPGASignal(signalindex,mode); + } + + setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + } + */ + return getExtSignal(signalindex); +} + + + + + + +enum externalCommunicationMode setTiming( enum externalCommunicationMode arg){ + //template setTiming from firmware_funcs.c + //template getFPGASignal from firmware_funcs.c + + + //getFPGASignal(signalindex) used later on in this fucntion + //gets flag from fpga reg, checks if flag within limits, + //if( flag=SIGNAL_OFF and signals[signalindex]==MASTER_SLAVE_SYNCHRONIZATION), return -1, (ensures masterslaveflag !=off now) + //else return flag + + int ret=GET_EXTERNAL_COMMUNICATION_MODE; + //sets timingmode variable + //ensures that the signals are in acceptance with timing mode and according sets the timing mode + /* + int g=-1, t=-1, rot=-1; + + int i; + + switch (ti) { + case AUTO_TIMING: + timingMode=ti; + // disable all gates/triggers in except if used for master/slave synchronization + for (i=0; i<4; i++) { + if (getFPGASignal(i)>0 && getFPGASignal(i)=0 && t>=0 && rot<0) { + ret=GATE_WITH_START_TRIGGER; + } else if (g<0 && t>=0 && rot<0) { + ret=TRIGGER_EXPOSURE; + } else if (g>=0 && t<0 && rot<0) { + ret=GATE_FIX_NUMBER; + } else if (g<0 && t<0 && rot>0) { + ret=TRIGGER_READOUT; + } else if (g<0 && t<0 && rot<0) { + ret=AUTO_TIMING; + } + + */ + return ret; +} + + + +enum masterFlags setMaster(enum masterFlags arg){ + //template setMaster from firmware_funcs.c + /* + int i; + switch(f) { + case NO_MASTER: + // switch of gates or triggers + masterMode=NO_MASTER; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + setFPGASignal(i,SIGNAL_OFF); + } + } + break; + case IS_MASTER: + // configure gate or trigger out + masterMode=IS_MASTER; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + switch (syncMode) { + case NO_SYNCHRONIZATION: + setFPGASignal(i,SIGNAL_OFF); + break; + case MASTER_GATES: + setFPGASignal(i,GATE_OUT_ACTIVE_HIGH); + break; + case MASTER_TRIGGERS: + setFPGASignal(i,TRIGGER_OUT_RISING_EDGE); + break; + case SLAVE_STARTS_WHEN_MASTER_STOPS: + setFPGASignal(i,RO_TRIGGER_OUT_RISING_EDGE); + break; + default: + ; + } + } + } + break; + case IS_SLAVE: + // configure gate or trigger in + masterMode=IS_SLAVE; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + switch (syncMode) { + case NO_SYNCHRONIZATION: + setFPGASignal(i,SIGNAL_OFF); + break; + case MASTER_GATES: + setFPGASignal(i,GATE_IN_ACTIVE_HIGH); + break; + case MASTER_TRIGGERS: + setFPGASignal(i,TRIGGER_IN_RISING_EDGE); + break; + case SLAVE_STARTS_WHEN_MASTER_STOPS: + setFPGASignal(i,TRIGGER_IN_RISING_EDGE); + break; + default: + ; + } + } + } + break; + default: + //do nothing + ; + } + + switch(masterMode) { + case NO_MASTER: + return NO_MASTER; + + + case IS_MASTER: + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + switch (syncMode) { + case NO_SYNCHRONIZATION: + return IS_MASTER; + case MASTER_GATES: + if (getFPGASignal(i)==GATE_OUT_ACTIVE_HIGH) + return IS_MASTER; + else + return NO_MASTER; + case MASTER_TRIGGERS: + if (getFPGASignal(i)==TRIGGER_OUT_RISING_EDGE) + return IS_MASTER; + else + return NO_MASTER; + case SLAVE_STARTS_WHEN_MASTER_STOPS: + if (getFPGASignal(i)==RO_TRIGGER_OUT_RISING_EDGE) + return IS_MASTER; + else + return NO_MASTER; + default: + return NO_MASTER; + } + + } + } + + case IS_SLAVE: + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + switch (syncMode) { + case NO_SYNCHRONIZATION: + return IS_SLAVE; + case MASTER_GATES: + if (getFPGASignal(i)==GATE_IN_ACTIVE_HIGH) + return IS_SLAVE; + else + return NO_MASTER; + case MASTER_TRIGGERS: + case SLAVE_STARTS_WHEN_MASTER_STOPS: + if (getFPGASignal(i)==TRIGGER_IN_RISING_EDGE) + return IS_SLAVE; + else + return NO_MASTER; + default: + return NO_MASTER; + } + + } + } + + } + */ + + return NO_MASTER; +} + + + +enum synchronizationMode setSynchronization(enum synchronizationMode arg){ + /* + int i; + + switch(s) { + case NO_SYNCHRONIZATION: + syncMode=NO_SYNCHRONIZATION; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + setFPGASignal(i,SIGNAL_OFF); + } + } + break; + // disable external signals? + case MASTER_GATES: + // configure gate in or out + syncMode=MASTER_GATES; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + if (masterMode==IS_MASTER) + setFPGASignal(i,GATE_OUT_ACTIVE_HIGH); + else if (masterMode==IS_SLAVE) + setFPGASignal(i,GATE_IN_ACTIVE_HIGH); + } + } + + break; + case MASTER_TRIGGERS: + // configure trigger in or out + syncMode=MASTER_TRIGGERS; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + if (masterMode==IS_MASTER) + setFPGASignal(i,TRIGGER_OUT_RISING_EDGE); + else if (masterMode==IS_SLAVE) + setFPGASignal(i,TRIGGER_IN_RISING_EDGE); + } + } + break; + + + case SLAVE_STARTS_WHEN_MASTER_STOPS: + // configure trigger in or out + syncMode=SLAVE_STARTS_WHEN_MASTER_STOPS; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + if (masterMode==IS_MASTER) + setFPGASignal(i,RO_TRIGGER_OUT_RISING_EDGE); + else if (masterMode==IS_SLAVE) + setFPGASignal(i,TRIGGER_IN_RISING_EDGE); + } + } + break; + + + default: + //do nothing + ; + } + + switch (syncMode) { + + case NO_SYNCHRONIZATION: + return NO_SYNCHRONIZATION; + + case MASTER_GATES: + + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + if (masterMode==IS_MASTER && getFPGASignal(i)==GATE_OUT_ACTIVE_HIGH) + return MASTER_GATES; + else if (masterMode==IS_SLAVE && getFPGASignal(i)==GATE_IN_ACTIVE_HIGH) + return MASTER_GATES; + } + } + return NO_SYNCHRONIZATION; + + case MASTER_TRIGGERS: + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + if (masterMode==IS_MASTER && getFPGASignal(i)==TRIGGER_OUT_RISING_EDGE) + return MASTER_TRIGGERS; + else if (masterMode==IS_SLAVE && getFPGASignal(i)==TRIGGER_IN_RISING_EDGE) + return MASTER_TRIGGERS; + } + } + return NO_SYNCHRONIZATION; + + case SLAVE_STARTS_WHEN_MASTER_STOPS: + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + if (masterMode==IS_MASTER && getFPGASignal(i)==RO_TRIGGER_OUT_RISING_EDGE) + return SLAVE_STARTS_WHEN_MASTER_STOPS; + else if (masterMode==IS_SLAVE && getFPGASignal(i)==TRIGGER_IN_RISING_EDGE) + return SLAVE_STARTS_WHEN_MASTER_STOPS; + } + } + return NO_SYNCHRONIZATION; + + default: + return NO_SYNCHRONIZATION; + + } + + + */ + return NO_SYNCHRONIZATION; +} + + + +#endif diff --git a/slsDetectorSoftware/mythen3DetectorServer/slsDetectorFunctionList.h b/slsDetectorSoftware/mythen3DetectorServer/slsDetectorFunctionList.h new file mode 100644 index 000000000..4da4a3d8b --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/slsDetectorFunctionList.h @@ -0,0 +1,245 @@ +#ifdef SLS_DETECTOR_FUNCTION_LIST +#ifndef SLS_DETECTOR_FUNCTION_LIST_H +#define SLS_DETECTOR_FUNCTION_LIST_H + +#include "sls_receiver_defs.h" +#include "slsDetectorServer_defs.h" // DAC_INDEX, ADC_INDEX, also include RegisterDefs.h + +#include +#include // FILE + + +/**************************************************** +This functions are used by the slsDetectroServer_funcs interface. +Here are the definitions, but the actual implementation should be done for each single detector. + +****************************************************/ + + +// basic tests +void checkFirmwareCompatibility(int flag); +#ifdef JUNGFRAUD +int checkType(); +u_int32_t testFpga(void); +int testBus(void); +#endif + +#if defined(MYTHEND) || defined(JUNGFRAUD) +int moduleTest( enum digitalTestMode arg, int imod); +int detectorTest( enum digitalTestMode arg); +#endif + +// Ids +int64_t getDetectorId(enum idMode arg); +u_int64_t getFirmwareVersion(); +#ifdef MYTHEND +int64_t getModuleId(enum idMode arg, int imod); +#elif JUNGFRAUD +u_int16_t getHardwareVersionNumber(); +u_int16_t getHardwareSerialNumber(); +#endif +u_int32_t getDetectorNumber(); +u_int64_t getDetectorMAC(); +u_int32_t getDetectorIP(); + + +// initialization +void initControlServer(); +void initStopServer(); +#ifdef EIGERD +void getModuleConfiguration(); +#endif + +// set up detector +void allocateDetectorStructureMemory(); +void setupDetector(); + + +// advanced read/write reg +#ifndef EIGERD +extern u_int32_t writeRegister(u_int32_t offset, u_int32_t data); // blackfin.h +extern u_int32_t readRegister(u_int32_t offset); // blackfin.h +#else +uint32_t writeRegister(uint32_t offset, uint32_t data); +uint32_t readRegister(uint32_t offset); +#endif + + +// firmware functions (resets) +#ifdef JUNGFRAUD +int powerChip (int on); +void cleanFifos(); +void resetCore(); +void resetPeripheral(); +int adcPhase(int st); +int getPhase(); +#endif + +// parameters - nmod, dr, roi +int setNMod(int nm, enum dimension dim); // mythen specific, but for detector compatibility as a get +int getNModBoard(enum dimension arg); // mythen specific, but for detector compatibility as a get +int setDynamicRange(int dr); +#ifdef GOTTHARD +int setROI(int n, ROI arg[], int *retvalsize, int *ret); +#endif + +// parameters - readout +int setSpeed(enum speedVariable arg, int val); +#if defined(EIGERD) || defined(MYTHEND) +enum readOutFlags setReadOutFlags(enum readOutFlags val); +#endif +#ifdef MYTHEND +int executeTrimming(enum trimMode mode, int par1, int par2, int imod); +#endif + +// parameters - timer +int64_t setTimer(enum timerIndex ind, int64_t val); +#ifndef EIGERD +int64_t getTimeLeft(enum timerIndex ind); +#endif + + +// parameters - channel, chip, module, settings +#ifdef MYTHEND +int setChannel(sls_detector_channel myChan); +int getChannel(sls_detector_channel *myChan); +int setChip(sls_detector_chip myChip); +int getChip(sls_detector_chip *myChip); +#endif +#ifdef EIGERD +int setModule(sls_detector_module myMod, int delay); +#else +int setModule(sls_detector_module myMod); +#endif +int getModule(sls_detector_module *myMod); +enum detectorSettings setSettings(enum detectorSettings sett, int imod); +enum detectorSettings getSettings(); + + +// parameters - threshold +#if defined(MYTHEND) || defined(EIGERD) +int getThresholdEnergy(int imod); +int setThresholdEnergy(int ev, int imod); +#endif + +// parameters - dac, adc, hv +#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); +extern void setAdc(int addr, int val); // AD9257.h +int voltageToDac(int value); +int dacToVoltage(unsigned int digital); +#endif +void setDAC(enum DACINDEX ind, int val, int imod, int mV, int retval[]); +int getADC(enum ADCINDEX ind, int imod); +#ifndef MYTHEND +int setHighVoltage(int val); +#endif + + + +// parameters - timing, extsig +#ifdef MYTHEND +enum externalSignalFlag getExtSignal(int signalindex); +enum externalSignalFlag setExtSignal(int signalindex, enum externalSignalFlag flag); +#endif +enum externalCommunicationMode setTiming( enum externalCommunicationMode arg); + +// configure mac +#ifdef JUNGFRAUD +long int calcChecksum(int sourceip, int destip); +#endif +#ifndef MYTHEND +int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport, uint32_t udpport2, int ival); +#endif +#if defined(JUNGFRAUD) || defined(EIGERD) +int setDetectorPosition(int pos[]); +#endif + + +// very detector specific + +// gotthard specific - image, pedestal +#ifdef GOTTHARDD +int loadImage(enum imageType index, char *imageVals); +int readCounterBlock(int startACQ, char *counterVals); +int resetCounterBlock(int startACQ); +int calibratePedestal(int frames); + +// jungfrau specific - pll, flashing firmware +#elif JUNGFRAUD +void resetPLL(); +u_int32_t setPllReconfigReg(u_int32_t reg, u_int32_t val); +void configurePll(); +extern void eraseFlash(); // programfpga.h +extern int startWritingFPGAprogram(FILE** filefp); // programfpga.h +extern void stopWritingFPGAprogram(FILE* filefp); // programfpga.h +extern int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp); // programfpga.h + +// eiger specific - iodelay, 10g, pulse, rate, temp, activate, delay nw parameter +#elif EIGERD +int setIODelay(int val, int imod); +int enableTenGigabitEthernet(int val); +int setCounterBit(int val); +int pulsePixel(int n, int x, int y); +int pulsePixelNMove(int n, int x, int y); +int pulseChip(int n); +int64_t setRateCorrection(int64_t custom_tau_in_nsec); +int getRateCorrectionEnable(); +int getDefaultSettingsTau_in_nsec(); +void setDefaultSettingsTau_in_nsec(int t); +int64_t getCurrentTau(); +void setExternalGating(int enable[]); +int setAllTrimbits(int val); +int getAllTrimbits(); +int getBebFPGATemp(); +int activate(int enable); +int setNetworkParameter(enum NETWORKINDEX mode, int value); +#endif + + + + +// aquisition +#if defined(EIGERD) || defined(GOTTHARD) +int prepareAcquisition(); +#endif +int startStateMachine(); +#ifdef VIRTUAL +void* start_timer(void* arg); +#endif +int stopStateMachine(); +#ifndef JUNGFRAUD +int startReadOut(); +#endif +enum runStatus getRunStatus(); +void readFrame(int *ret, char *mess); +#ifdef JUNGFRAUD +u_int32_t runBusy(void); +#endif + + +//common +int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod); +int calculateDataBytes(); +int getTotalNumberOfChannels(); +int getTotalNumberOfChips(); +int getTotalNumberOfModules(); +int getNumberOfChannelsPerModule(); +int getNumberOfChipsPerModule(); +int getNumberOfDACsPerModule(); +int getNumberOfADCsPerModule(); +#ifdef EIGERD +int getNumberOfGainsPerModule(); +int getNumberOfOffsetsPerModule(); +#endif +int getNumberOfChannelsPerChip(); + +// sync +enum masterFlags setMaster(enum masterFlags arg); +enum synchronizationMode setSynchronization(enum synchronizationMode arg); + + + +#endif +#endif diff --git a/slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer.c b/slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer.c new file mode 100755 index 000000000..fcbebfceb --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer.c @@ -0,0 +1,120 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ + +#include "sls_detector_defs.h" +#include "slsDetectorServer_defs.h" + +#include "communication_funcs.h" +#include "slsDetectorServer_funcs.h" + +#include +#include +#include +#include + + +extern int sockfd; + + +void error(char *msg){ + perror(msg); +} + +int main(int argc, char *argv[]){ + int portno, b; + int retval=OK; + int sd, fd; + int debugflag = 0; + + // if socket crash, ignores SISPIPE, prevents global signal handler + // subsequent read/write to socket gives error - must handle locally + signal(SIGPIPE, SIG_IGN); + + // circumvent the basic tests + if(argc > 1) { + if(!strcasecmp(argv[1],"-debug")){ + debugflag = 1; + argc=1; + } + } + + +#ifdef STOP_SERVER + char cmd[100]; +#endif + if (argc==1) { + portno = DEFAULT_PORTNO; + cprintf(BLUE, + "********************************************************\n" + "********* opening control server on port %d **********\n" + "********************************************************\n\n" + , portno); + b=1; + basictests(debugflag); +#ifdef STOP_SERVER + sprintf(cmd,"%s %d &",argv[0],DEFAULT_PORTNO+1); + //cprintf(BLUE,"cmd:%s\n", cmd); + system(cmd); +#endif + } else { + portno = DEFAULT_PORTNO+1; + if ( sscanf(argv[1],"%d",&portno) == 0) { + printf("could not open stop server: unknown port\n"); + return 1; + } + cprintf(BLUE, + "********************************************************\n" + "*********** opening stop server on port %d ***********\n" + "********************************************************\n\n" + , portno); + b=0; + } + + init_detector(b); //defined in slsDetectorServer_funcs + + sd=bindSocket(portno); //defined in communication_funcs + sockfd=sd; + if (getServerError(sd)) { //defined in communication_funcs + printf("server error!\n"); + return -1; + } + + /* assign function table */ + function_table(); //defined in slsDetectorServer_funcs +#ifdef VERBOSE + printf("function table assigned \n"); +#endif + + + printf("\nReady...\n\n"); + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Waiting for client call\n"); +#endif + fd=acceptConnection(sockfd); //defined in communication_funcs +#ifdef VERY_VERBOSE + printf("Connection accepted\n"); +#endif + if (fd>0) { + retval=decode_function(fd); //defined in slsDetectorServer_funcs +#ifdef VERY_VERBOSE + printf("function executed\n"); +#endif + closeConnection(fd); //defined in communication_funcs +#ifdef VERY_VERBOSE + printf("connection closed\n"); +#endif + } + } + + exitServer(sockfd); //defined in communication_funcs + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer_defs.h b/slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer_defs.h new file mode 100644 index 000000000..d8b9e82bf --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer_defs.h @@ -0,0 +1,93 @@ +/* + * slsDetectorServer_defs.h + * + * Created on: Jan 24, 2013 + * Author: l_maliakal_d + */ + +#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}; // Mythen 3.01 +#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 */ \ + }; + +/*Hardware Definitions +#define NMAXMOD (1) +#define NMOD (1) +#define NCHAN (256 * 256) +#define NCHIP (4) +#define NADC (0) +#define NDAC (16) +#define NGAIN (0) +#define NOFFSET (0) +*/ + +/** Default Parameters */ +#define DEFAULT_EXPTIME (10*1000) //ns + +/* Hardware Definitions */ +#define NMAXMOD (1) +#define NMOD (1) +#define NCHAN (256 * 256) +#define NCHIP (8) +#define NADC (0) +#define NDAC (8) +#define NDAC_OLDBOARD (16) +#define DYNAMIC_RANGE (16) +#define NUM_BITS_PER_PIXEL (DYNAMIC_RANGE / 8) +#define DATA_BYTES (NCHIP * NCHAN * NUM_BITS_PER_PIXEL) +#define IP_PACKETSIZE (0x2052) +#define CLK_RUN (40) /* MHz */ +#define CLK_SYNC (20) /* MHz */ + + +// Hardware definitions + +#define NCHAN 36 +#define NCHIP 1 +#define NADC 9 // + +/* #ifdef CTB */ +/* #define NDAC 24 */ +/* #define NPWR 5 */ +/* #else */ +/* #define NDAC 16 */ +/* #define NPWR 0 */ +/* #endif */ +#define DAC_CMD_OFF 20 + +#define NMAXMODX 1 +#define NMAXMODY 1 +#define NMAXMOD (NMAXMODX*NMAXMODY) + +#define NCHANS (NCHAN*NCHIP*NMAXMOD) +#define NDACS (NDAC*NMAXMOD) + +#endif /* SLSDETECTORSERVER_DEFS_H_ */ diff --git a/slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer_funcs.c b/slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer_funcs.c new file mode 100755 index 000000000..a38c95598 --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer_funcs.c @@ -0,0 +1,4996 @@ + +#include "sls_detector_defs.h" +#include "slsDetectorServer_funcs.h" +#include "slsDetectorFunctionList.h" +#include "communication_funcs.h" +#include "slsDetectorServer_defs.h" + +#include +#include +#include + + +// Global variables +extern int lockStatus; +extern char lastClientIP[INET_ADDRSTRLEN]; +extern char thisClientIP[INET_ADDRSTRLEN]; +extern int differentClients; + +//defined in the detector specific Makefile +#ifdef MYTHEND +const enum detectorType myDetectorType=MYTHEN; +#elif GOTTHARDD +const enum detectorType myDetectorType=GOTTHARD; +#elif EIGERD +const enum detectorType myDetectorType=EIGER; +#elif PICASSOD +const enum detectorType myDetectorType=PICASSO; +#elif MOENCHD +const enum detectorType myDetectorType=MOENCH; +#elif JUNGFRAUD +const enum detectorType myDetectorType=JUNGFRAU; +#elif MYTHEN3D +const enum detectorType myDetectorType=MYTHEN3D; +#else +const enum detectorType myDetectorType=GENERIC; +#endif + +int sockfd; // (updated in slsDetectorServer) as extern +int (*flist[NUM_DET_FUNCTIONS])(int); +char mess[MAX_STR_LENGTH]; +int dataBytes = 10; +int isControlServer = 0; +int debugflag = 0; + +int N_DAC=24; +int N_PWR=5; + +int vPowerLimit = 1400; // mV + +/* initialization functions */ + +int printSocketReadError() { + cprintf(BG_RED, "Error reading from socket. Possible socket crash\n"); + return FAIL; +} + +void basictests(int flag) { + debugflag = flag; +#ifdef SLS_DETECTOR_FUNCTION_LIST + checkFirmwareCompatibility(debugflag); +#endif +} + + +void init_detector(int controlserver) { +#ifdef VIRTUAL + printf("This is a VIRTUAL detector\n"); +#endif + +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (controlserver) { + isControlServer = 1; + initControlServer(); + } + else initStopServer(); +#endif + strcpy(mess,"dummy message"); + strcpy(lastClientIP,"none"); + strcpy(thisClientIP,"none1"); + lockStatus=0; +} + + +int decode_function(int file_des) { + int fnum,n; + int ret=FAIL; +#ifdef VERBOSE + printf( "\nreceive data\n"); +#endif + n = receiveData(file_des,&fnum,sizeof(fnum),INT32); + if (n <= 0) { +#ifdef VERBOSE + printf("ERROR reading from socket %d, %d %d (%s)\n", n, fnum, file_des, getFunctionName((enum detFuncs)fnum)); +#endif + return FAIL; + } +#ifdef VERBOSE + else + printf("size of data received %d\n",n); +#endif + +#ifdef VERBOSE + printf(" calling function fnum=%d, (%s) located at 0x%x\n", fnum, getFunctionName((enum detFuncs)fnum), (unsigned int)flist[fnum]); +#endif + if (fnum<0 || fnum>=NUM_DET_FUNCTIONS) { + cprintf(BG_RED,"Unknown function enum %d\n", fnum); + ret=(M_nofunc)(file_des); + }else + ret=(*flist[fnum])(file_des); + if (ret == FAIL) + cprintf(RED, "Error executing the function = %d (%s)\n", fnum, getFunctionName((enum detFuncs)fnum)); + return ret; +} + + +const char* getFunctionName(enum detFuncs func) { + switch (func) { + case F_EXEC_COMMAND: return "F_EXEC_COMMAND"; + case F_GET_ERROR: return "F_GET_ERROR"; + case F_GET_DETECTOR_TYPE: return "F_GET_DETECTOR_TYPE"; + case F_SET_NUMBER_OF_MODULES: return "F_SET_NUMBER_OF_MODULES"; + case F_GET_MAX_NUMBER_OF_MODULES: return "F_GET_MAX_NUMBER_OF_MODULES"; + case F_SET_EXTERNAL_SIGNAL_FLAG: return "F_SET_EXTERNAL_SIGNAL_FLAG"; + case F_SET_EXTERNAL_COMMUNICATION_MODE: return "F_SET_EXTERNAL_COMMUNICATION_MODE"; + case F_GET_ID: return "F_GET_ID"; + case F_DIGITAL_TEST: return "F_DIGITAL_TEST"; + case F_ANALOG_TEST: return "F_ANALOG_TEST"; + case F_ENABLE_ANALOG_OUT: return "F_ENABLE_ANALOG_OUT"; + case F_CALIBRATION_PULSE: return "F_CALIBRATION_PULSE"; + case F_SET_DAC: return "F_SET_DAC"; + case F_GET_ADC: return "F_GET_ADC"; + case F_WRITE_REGISTER: return "F_WRITE_REGISTER"; + case F_READ_REGISTER: return "F_READ_REGISTER"; + case F_WRITE_MEMORY: return "F_WRITE_MEMORY"; + case F_READ_MEMORY: return "F_READ_MEMORY"; + case F_SET_CHANNEL: return "F_SET_CHANNEL"; + case F_GET_CHANNEL: return "F_GET_CHANNEL"; + case F_SET_ALL_CHANNELS: return "F_SET_ALL_CHANNELS"; + case F_SET_CHIP: return "F_SET_CHIP"; + case F_GET_CHIP: return "F_GET_CHIP"; + case F_SET_ALL_CHIPS: return "F_SET_ALL_CHIPS"; + case F_SET_MODULE: return "F_SET_MODULE"; + case F_GET_MODULE: return "F_GET_MODULE"; + case F_SET_ALL_MODULES: return "F_SET_ALL_MODULES"; + case F_SET_SETTINGS: return "F_SET_SETTINGS"; + case F_GET_THRESHOLD_ENERGY: return "F_GET_THRESHOLD_ENERGY"; + case F_SET_THRESHOLD_ENERGY: return "F_SET_THRESHOLD_ENERGY"; + case F_START_ACQUISITION: return "F_START_ACQUISITION"; + case F_STOP_ACQUISITION: return "F_STOP_ACQUISITION"; + case F_START_READOUT: return "F_START_READOUT"; + case F_GET_RUN_STATUS: return "F_GET_RUN_STATUS"; + case F_START_AND_READ_ALL: return "F_START_AND_READ_ALL"; + case F_READ_FRAME: return "F_READ_FRAME"; + case F_READ_ALL: return "F_READ_ALL"; + case F_SET_TIMER: return "F_SET_TIMER"; + case F_GET_TIME_LEFT: return "F_GET_TIME_LEFT"; + case F_SET_DYNAMIC_RANGE: return "F_SET_DYNAMIC_RANGE"; + case F_SET_READOUT_FLAGS: return "F_SET_READOUT_FLAGS"; + case F_SET_ROI: return "F_SET_ROI"; + case F_SET_SPEED: return "F_SET_SPEED"; + case F_EXECUTE_TRIMMING: return "F_EXECUTE_TRIMMING"; + case F_EXIT_SERVER: return "F_EXIT_SERVER"; + case F_LOCK_SERVER: return "F_LOCK_SERVER"; + case F_GET_LAST_CLIENT_IP: return "F_GET_LAST_CLIENT_IP"; + case F_SET_PORT: return "F_SET_PORT"; + case F_UPDATE_CLIENT: return "F_UPDATE_CLIENT"; + case F_CONFIGURE_MAC: return "F_CONFIGURE_MAC"; + case F_LOAD_IMAGE: return "F_LOAD_IMAGE"; + case F_SET_MASTER: return "F_SET_MASTER"; + case F_SET_SYNCHRONIZATION_MODE: return "F_SET_SYNCHRONIZATION_MODE"; + case F_READ_COUNTER_BLOCK: return "F_READ_COUNTER_BLOCK"; + case F_RESET_COUNTER_BLOCK: return "F_RESET_COUNTER_BLOCK"; + case F_CALIBRATE_PEDESTAL: return "F_CALIBRATE_PEDESTAL"; + case F_ENABLE_TEN_GIGA: return "F_ENABLE_TEN_GIGA"; + case F_SET_ALL_TRIMBITS: return "F_SET_ALL_TRIMBITS"; + case F_SET_CTB_PATTERN: return "F_SET_CTB_PATTERN"; + case F_WRITE_ADC_REG: return "F_WRITE_ADC_REG"; + case F_SET_COUNTER_BIT: return "F_SET_COUNTER_BIT"; + case F_PULSE_PIXEL: return "F_PULSE_PIXEL"; + case F_PULSE_PIXEL_AND_MOVE: return "F_PULSE_PIXEL_AND_MOVE"; + case F_PULSE_CHIP: return "F_PULSE_CHIP"; + case F_SET_RATE_CORRECT: return "F_SET_RATE_CORRECT"; + case F_GET_RATE_CORRECT: return "F_GET_RATE_CORRECT"; + case F_SET_NETWORK_PARAMETER: return "F_SET_NETWORK_PARAMETER"; + case F_PROGRAM_FPGA: return "F_PROGRAM_FPGA"; + case F_RESET_FPGA: return "F_RESET_FPGA"; + case F_POWER_CHIP: return "F_POWER_CHIP"; + case F_ACTIVATE: return "F_ACTIVATE"; + case F_PREPARE_ACQUISITION: return "F_PREPARE_ACQUISITION"; + case F_CLEANUP_ACQUISITION: return "F_CLEANUP_ACQUISITION"; + default: return "Unknown Function"; + } +} + +void function_table() { + flist[F_EXEC_COMMAND] = &exec_command; + flist[F_GET_ERROR] = &get_error; + flist[F_GET_DETECTOR_TYPE] = &get_detector_type; + flist[F_SET_NUMBER_OF_MODULES] = &set_number_of_modules; + flist[F_GET_MAX_NUMBER_OF_MODULES] = &get_max_number_of_modules; + flist[F_SET_EXTERNAL_SIGNAL_FLAG] = &set_external_signal_flag; + flist[F_SET_EXTERNAL_COMMUNICATION_MODE] = &set_external_communication_mode; + flist[F_GET_ID] = &get_id; + flist[F_DIGITAL_TEST] = &digital_test; + flist[F_ANALOG_TEST] = &analog_test; + flist[F_ENABLE_ANALOG_OUT] = &enable_analog_out; + flist[F_CALIBRATION_PULSE] = &calibration_pulse; + flist[F_SET_DAC] = &set_dac; + flist[F_GET_ADC] = &get_adc; + flist[F_WRITE_REGISTER] = &write_register; + flist[F_READ_REGISTER] = &read_register; + flist[F_WRITE_MEMORY] = &write_memory; + flist[F_READ_MEMORY] = &read_memory; + flist[F_SET_CHANNEL] = &set_channel; + flist[F_GET_CHANNEL] = &get_channel; + flist[F_SET_ALL_CHANNELS] = &set_all_channels; + flist[F_SET_CHIP] = &set_chip; + flist[F_GET_CHIP] = &get_chip; + flist[F_SET_ALL_CHIPS] = &set_all_chips; + flist[F_SET_MODULE] = &set_module; + flist[F_GET_MODULE] = &get_module; + flist[F_SET_ALL_MODULES] = &set_all_modules; + flist[F_SET_SETTINGS] = &set_settings; + flist[F_GET_THRESHOLD_ENERGY] = &get_threshold_energy; + flist[F_SET_THRESHOLD_ENERGY] = &set_threshold_energy; + flist[F_START_ACQUISITION] = &start_acquisition; + flist[F_STOP_ACQUISITION] = &stop_acquisition; + flist[F_START_READOUT] = &start_readout; + flist[F_GET_RUN_STATUS] = &get_run_status; + flist[F_START_AND_READ_ALL] = &start_and_read_all; + flist[F_READ_FRAME] = &read_frame; + flist[F_READ_ALL] = &read_all; + flist[F_SET_TIMER] = &set_timer; + flist[F_GET_TIME_LEFT] = &get_time_left; + flist[F_SET_DYNAMIC_RANGE] = &set_dynamic_range; + flist[F_SET_READOUT_FLAGS] = &set_readout_flags; + flist[F_SET_ROI] = &set_roi; + flist[F_SET_SPEED] = &set_speed; + flist[F_EXECUTE_TRIMMING] = &execute_trimming; + flist[F_EXIT_SERVER] = &exit_server; + flist[F_LOCK_SERVER] = &lock_server; + flist[F_GET_LAST_CLIENT_IP] = &get_last_client_ip; + flist[F_SET_PORT] = &set_port; + flist[F_UPDATE_CLIENT] = &update_client; + flist[F_CONFIGURE_MAC] = &configure_mac; + flist[F_LOAD_IMAGE] = &load_image; + flist[F_SET_MASTER] = &set_master; + flist[F_SET_SYNCHRONIZATION_MODE] = &set_synchronization; + flist[F_READ_COUNTER_BLOCK] = &read_counter_block; + flist[F_RESET_COUNTER_BLOCK] = &reset_counter_block; + flist[F_CALIBRATE_PEDESTAL] = &calibrate_pedestal; + flist[F_ENABLE_TEN_GIGA] = &enable_ten_giga; + flist[F_SET_ALL_TRIMBITS] = &set_all_trimbits; + flist[F_SET_CTB_PATTERN] = &set_ctb_pattern; + flist[F_WRITE_ADC_REG] = &write_adc_register; + flist[F_SET_COUNTER_BIT] = &set_counter_bit; + flist[F_PULSE_PIXEL] = &pulse_pixel; + flist[F_PULSE_PIXEL_AND_MOVE] = &pulse_pixel_and_move; + flist[F_PULSE_CHIP] = &pulse_chip; + flist[F_SET_RATE_CORRECT] = &set_rate_correct; + flist[F_GET_RATE_CORRECT] = &get_rate_correct; + flist[F_SET_NETWORK_PARAMETER] = &set_network_parameter; + flist[F_PROGRAM_FPGA] = &program_fpga; + flist[F_RESET_FPGA] = &reset_fpga; + flist[F_POWER_CHIP] = &power_chip; + flist[F_ACTIVATE] = &set_activate; + flist[F_PREPARE_ACQUISITION] = &prepare_acquisition; + flist[F_CLEANUP_ACQUISITION] = &cleanup_acquisition; + + // check + if (NUM_DET_FUNCTIONS >= TOO_MANY_FUNCTIONS_DEFINED) { + cprintf(BG_RED,"The last detector function enum has reached its limit\nGoodbye!\n"); + exit(EXIT_FAILURE); + } + +#ifdef VERYVERBOSE + { + int i=0; + for (i = 0; i < NUM_DET_FUNCTIONS ; i++) { + printf("function fnum=%d, (%s) located at 0x%x\n", i, getFunctionName((enum detFuncs)i), (unsigned int)flist[i]); + } + } +#endif +} + + +int M_nofunc(int file_des){ + int ret=FAIL,ret1=FAIL; + int n=0; + + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + + sprintf(mess,"Unrecognized Function. Please do not proceed.\n"); + cprintf(BG_RED,"Error: %s",mess); + n = sendData(file_des,&ret1,sizeof(ret1),INT32); + n = sendData(file_des,mess,sizeof(mess),OTHER); + + // return ok / fail + return ret; +} + + + + + + +/* functions called by client */ + + + +int exec_command(int file_des) { + int ret=OK,ret1=OK; + int n=0; + char cmd[MAX_STR_LENGTH]=""; + int sysret=0; + + // receive arguments + n = receiveData(file_des,cmd,MAX_STR_LENGTH,OTHER); + if (n < 0) return printSocketReadError(); + + // execute action if the arguments correctly arrived +#ifdef VERBOSE + printf("executing command %s\n", cmd); +#endif + if (differentClients && lockStatus) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } else { + sysret=system(cmd); + //should be replaced by popen + if (sysret==0) { + sprintf(mess,"Succeeded\n"); + } else { + ret = FAIL; + sprintf(mess,"Executing Command failed\n"); + cprintf(RED, "Warning: %s", mess); + } + } + + ret1=ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + n = sendData(file_des,mess,MAX_STR_LENGTH,OTHER); + + // return ok / fail + return ret; +} + + + +int get_error(int file_des) { + int ret=FAIL,ret1=FAIL; + int n=0; + sprintf(mess,"Function (Get Error) is not implemented for this detector\n"); + cprintf(RED, "Error: %s", mess); + + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + + n = sendData(file_des,&ret1,sizeof(ret),INT32); + n = sendData(file_des,mess,MAX_STR_LENGTH,OTHER); + + // return ok / fail + return ret; +} + + + +int get_detector_type(int file_des) { + int ret=OK,ret1=OK; + int n=0; + enum detectorType retval=-1; + + // execute action + retval=myDetectorType; +#ifdef VERBOSE + printf("Returning detector type %d\n",retval); +#endif + + if (differentClients) + ret=FORCE_UPDATE; + + // send ok / fail + n += sendData(file_des,&ret1,sizeof(ret),INT32); + // send return argument + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; + + +} + + + + +int set_number_of_modules(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int retval=0; + int arg[2]={-1,-1}; + sprintf(mess,"set number of modules failed\n"); + + // receive arguments + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + enum dimension dim=arg[0]; + int nm=arg[1]; + + // execute action +#ifdef VERBOSE + printf("Setting the number of modules in dimension %d to %d\n",dim,nm ); +#endif + if (lockStatus && differentClients && nm!=GET_FLAG) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + retval=setNMod(nm, dim); + dataBytes=calculateDataBytes(); + } +#endif + + if (retval==nm || nm==GET_FLAG) { + ret=OK; + if (differentClients) + ret=FORCE_UPDATE; + } else + ret=FAIL; + + // 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,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; +} + + + + +int get_max_number_of_modules(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int retval=-1; + enum dimension arg=0; + sprintf(mess,"get max number of modules failed\n"); + + // receive arguments + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + + // execute action +#ifdef VERBOSE + printf("Getting the max number of modules in dimension %d \n",arg); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=getNModBoard(arg); +#endif +#ifdef VERBOSE + printf("Max number of module in dimension %d is %d\n",arg,retval ); +#endif + if (differentClients && ret==OK) { + ret=FORCE_UPDATE; + } + + // 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,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; +} + + + + +int set_external_signal_flag(int file_des) { + int ret=OK,ret1=OK; + int n=0; + enum externalSignalFlag retval=GET_EXTERNAL_SIGNAL_FLAG; + sprintf(mess,"set external signal flag failed\n"); + +#ifndef MYTHEND + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret = FAIL; + sprintf(mess,"Function (Set External Signal Flag) is not implemented for this detector\n"); + cprintf(RED, "%s", mess); +#else + + // receive arguments + int arg[2]={-1,-1}; + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + + int signalindex=arg[0]; + enum externalSignalFlag flag=arg[1]; + + // execute action + if (lockStatus && differentClients && flag!=GET_EXTERNAL_SIGNAL_FLAG) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } + +#ifdef SLS_DETECTOR_FUNCTION_LIST + else{ +#ifdef VERBOSE + printf("Setting external signal %d to flag %d\n",signalindex,flag); +#endif + switch (flag) { + case GET_EXTERNAL_SIGNAL_FLAG: + retval=getExtSignal(signalindex); + break; + default: + retval=setExtSignal(signalindex,flag); + if (retval!=flag) { + ret=FAIL; + sprintf(mess,"External signal %d flag should be 0x%04x but is 0x%04x\n", signalindex, flag, retval); + cprintf(RED, "%s", mess); + } + break; + } +#ifdef VERBOSE + printf("Set to flag %d\n",retval); +#endif + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; + +} + + +int set_external_communication_mode(int file_des) { + int ret=OK,ret1=OK; + int n=0; + enum externalCommunicationMode arg=GET_EXTERNAL_COMMUNICATION_MODE; + enum externalCommunicationMode retval=GET_EXTERNAL_COMMUNICATION_MODE; + sprintf(mess,"set external communication mode failed\n"); + + // receive arguments + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + + // execute action +#ifdef VERBOSE + printf("Setting external communication mode to %d\n", arg); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + switch(arg){ +#ifdef EIGERD + case GET_EXTERNAL_COMMUNICATION_MODE: + case AUTO_TIMING: + case TRIGGER_EXPOSURE: + case GATE_FIX_NUMBER: + case BURST_TRIGGER: +#elif JUNGFRAUD + case GET_EXTERNAL_COMMUNICATION_MODE: + case AUTO_TIMING: + case TRIGGER_EXPOSURE: +#endif + retval=setTiming(arg); + break; + default: + ret = FAIL; + sprintf(mess,"Timing mode (%d) is not implemented for this detector\n",(int)arg); + cprintf(RED, "Warning: %s", mess); + break; + } +#ifdef VERBOSE + if(ret==OK) + printf("retval:%d\n",retval); +#endif + if (ret==OK && differentClients==1) + ret=FORCE_UPDATE; + +#endif + + // 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,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; +} + + + + +int get_id(int file_des) { + int ret=OK,ret1=OK; + int n=0; + enum idMode arg=0; + int imod=-1; + int64_t retval=-1; + sprintf(mess,"get id failed\n"); + + // receive arguments + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + + if (arg == MODULE_FIRMWARE_VERSION) { + n = receiveData(file_des,&imod,sizeof(imod),INT32); + if (n < 0) return printSocketReadError(); + } + + // execute action +#ifdef VERBOSE + printf("Getting id %d\n", arg); +#endif + +#ifdef SLS_DETECTOR_FUNCTION_LIST + switch (arg) { +#ifdef MYTHEND + case MODULE_SERIAL_NUMBER: + case MODULE_FIRMWARE_VERSION: +#ifdef VERBOSE + printf("of module %d\n", imod); +#endif + + if (imod>=0 && imod 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret = FAIL; + sprintf(mess,"Function (Digital Test) is not implemented for this detector\n"); + cprintf(RED, "%s", mess); +#else + + enum digitalTestMode arg=0; + int imod=-1; + int ival=-1; + + // receive arguments + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + + if (arg == CHIP_TEST) { + n = receiveData(file_des,&imod,sizeof(imod),INT32); + if (n < 0) return printSocketReadError(); + } + + if (arg == DIGITAL_BIT_TEST) { + n = receiveData(file_des,&ival,sizeof(ival),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 { +#ifdef VERBOSE + printf("Digital test mode %d\n",arg ); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + switch (arg) { + +#ifdef GOTTHARD + case DIGITAL_BIT_TEST: + retval=0; + break; + +#elif MYTHEND + case CHIP_TEST: +#ifdef VERBOSE + printf("of module %d\n", imod); +#endif + if (imod>=0 && imod 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + + n = sendData(file_des,&ret1,sizeof(ret),INT32); + n = sendData(file_des,mess,MAX_STR_LENGTH,OTHER); + + // return ok / fail + return ret; +} + + + +int enable_analog_out(int file_des) { + int ret=FAIL,ret1=FAIL; + int n=0; + sprintf(mess,"Function (Enable Analog Out) is not implemented for this detector\n"); + cprintf(RED, "Error: %s", mess); + + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + + n = sendData(file_des,&ret1,sizeof(ret),INT32); + n = sendData(file_des,mess,MAX_STR_LENGTH,OTHER); + + // return ok / fail + return ret; +} + + + +int calibration_pulse(int file_des) { + int ret=FAIL,ret1=FAIL; + int n=0; + sprintf(mess,"Function (Calibration Pulse) is not implemented for this detector\n"); + cprintf(RED, "Error: %s", mess); + + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + + n = sendData(file_des,&ret1,sizeof(ret),INT32); + n = sendData(file_des,mess,MAX_STR_LENGTH,OTHER); + + // return ok / fail + return ret; +} + + + + +int set_dac(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int arg[3]={-1,-1,-1}; + int val=-1; + enum dacIndex ind=0; + int imod=-1; + double retval[2]={-1,-1}; + int mV=0; + sprintf(mess,"set DAC failed\n"); + + // receive arguments + n = receiveData(file_des,arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + + ind=arg[0]; + imod=arg[1]; + mV=arg[2]; + + if (mV) + printf("DAC will be set in mV %d!\n",mV); + else + printf("DAC will be set in DACu! %d\n", mV); + + n = receiveData(file_des,&val,sizeof(val),INT32); + if (n < 0) return printSocketReadError(); + + // checks +#ifdef MYTHEND +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (imod>=getTotalNumberOfModules()) { + ret = FAIL; + sprintf(mess,"Module number %d out of range\n",imod); + cprintf(RED, "Warning: %s", mess); + } +#endif +#endif + // check if dac exists for this detector + enum DACINDEX idac=0; +#ifdef JUNGFRAUD + if ((ind != HV_NEW) && (ind >= NDAC_OLDBOARD)) { //for compatibility with old board + ret = FAIL; + sprintf(mess,"Dac Index (%d) is not implemented for this detector\n",(int)ind); + cprintf(RED, "Warning: %s", mess); + }else + idac = ind; +#else + switch (ind) { +#ifdef MYTHEND + case TRIMBIT_SIZE: //ind = VTRIM; + case THRESHOLD: + case SHAPER1: + case SHAPER2: + case CALIBRATION_PULSE: + case PREAMP: + break; +#elif GOTTHARDD + case G_VREF_DS : + break; + case G_VCASCN_PB: + break; + case G_VCASCP_PB: + break; + case G_VOUT_CM: + break; + case G_VCASC_OUT: + break; + case G_VIN_CM: + break; + case G_VREF_COMP: + break; + case G_IB_TESTC: + break; + case HV_POT: + break; +#elif EIGERD + case TRIMBIT_SIZE: + idac = VTR; + break; + case THRESHOLD: + idac = VTHRESHOLD; + break; + case E_SvP: + idac = SVP; + break; + case E_SvN: + idac = SVN; + break; + case E_Vtr: + idac = VTR; + break; + case E_Vrf: + idac = VRF; + break; + case E_Vrs: + idac = VRS; + break; + case E_Vtgstv: + idac = VTGSTV; + break; + case E_Vcmp_ll: + idac = VCMP_LL; + break; + case E_Vcmp_lr: + idac = VCMP_LR; + break; + case E_cal: + idac = CAL; + break; + case E_Vcmp_rl: + idac = VCMP_RL; + break; + case E_Vcmp_rr: + idac = VCMP_RR; + break; + case E_rxb_rb: + idac = RXB_RB; + break; + case E_rxb_lb: + idac = RXB_LB; + break; + case E_Vcp: + idac = VCP; + break; + case E_Vcn: + idac = VCN; + break; + case E_Vis: + idac = VIS; + break; + case HV_NEW: + break; + case IO_DELAY: + break; + /* +#elif JUNGFRAUD + case V_DAC0: + idac = VB_COMP; + break; + case V_DAC1: + idac = VDD_PROT; + break; + case V_DAC2: + idac = VIN_COM; + break; + case V_DAC3: + idac = VREF_PRECH; + break; + case V_DAC4: + idac = VB_PIXBUF; + break; + case V_DAC5: + idac = VB_DS; + break; + case V_DAC6: + idac = VREF_DS; + break; + case V_DAC7: + idac = VREF_COMP; + break; + case HV_POT: + break; + */ +#elif MYTHEN3D + case M_vIpre: + idac = vIpre; + break; + case M_Vrf: + idac = Vrf; + break; + case M_VrfSh: + idac = VrfSh; + break; + case M_Vth1: + idac = Vth1; + break; + case M_Vth2: + idac = Vth2; + break; + case M_Vth3: + idac = Vth3; + break; + case M_VPL: + idac = VPL; + break; + case M_VPH: + idac = VPH; + break; + case M_Vtrim: + idac = Vtrim; + break; + 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: + break; +#endif + default: + ret = FAIL; + sprintf(mess,"Dac Index (%d) is not implemented for this detector\n",(int)ind); + cprintf(RED, "Warning: %s", mess); + break; + } +#endif + + // execute action +#ifdef VERBOSE + printf("Setting DAC %d of module %d to %d \n", idac, imod, val); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + double temp; + if (ret==OK) { + if (differentClients && lockStatus && val!=-1) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } + else { +#ifdef EIGERD + //iodelay + if(ind == IO_DELAY) + retval[0] = setIODelay(val,imod); + //high voltage + else +#endif +// if((ind == HV_POT) || (ind == HV_NEW)) { +// retval[0] = setHighVoltage(val); +// #ifdef EIGERD +// if ((retval[0] != SLAVE_HIGH_VOLTAGE_READ_VAL) && (retval[0] < 0)) { +// ret = FAIL; +// 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) +// strcpy(mess, "Setting high voltage failed. Serial/i2c communication failed.\n"); +// else if(retval[0] == -3) +// strcpy(mess, "Getting high voltage failed. Serial/i2c communication failed.\n"); +// cprintf(RED, "Warning: %s", mess); +// } +// #endif +// } + if(ind == V_POWER_A || ind == V_POWER_B || ind == V_POWER_IO){ + if(mV){ + + if( val >=0 && val <=vPowerLimit){ + retval[1] = setPower(ind,val); // in mV + } + else{ + printf("********power %d exceeds voltage limits", ind); + } + } + else{ + printf("********power %d should be set in mV instead od DACu", ind); + } + } + else if(ind == V_LIMIT){ + if(mV){ // without safetycheck + retval[1] = setPower(ind, val); + } + else{ + printf("********power %d should be set in mV instead od DACu", ind); + } + } + //dac: + else{ + if(mV && (val>0 && val<2500)){ // val given in mV, check taht val is not out of range + retval[1] = setDAC(idac,val,imod,mV); + retval[0] = retval[1]*4095./2500.; // convert to DACu (for later printout) + } + else if(!mV && (val>0 && val<4095)){ // val given in DACu + retval[0] = setDAC(idac,val,imod,mV); + retval[1] = retval[0] *2500/4095; // convert to mV + } + +#ifdef EIGERD + if(val != -1) { + //changing dac changes settings to undefined + switch(idac){ + case VCMP_LL: + case VCMP_LR: + case VCMP_RL: + case VCMP_RR: + case VRF: + case VCP: + setSettings(UNDEFINED,-1); + cprintf(RED,"Settings has been changed to undefined (changed specific dacs)\n"); + break; + default: + break; + } + } +#endif + //check + if(retval[0]==-1 || retval[1] == -1){// something in setDAC failed (should never occur) + ret = FAIL; + sprintf(mess,"Setting dac %d of module %d: wrote %d but read %d\n", idac, imod, val, temp); + cprintf(RED, "Warning: %s", mess); + } + if(mV) + temp = retval[1]; + else + temp = retval[0]; + if ((abs(temp-val)<=5) || val==-1) { // ??? + ret=OK; + } + else { + ret = FAIL; + sprintf(mess,"Setting dac %d of module %d: wrote %d but read %d\n", idac, imod, val, temp); + cprintf(RED, "Warning: %s", mess); + } + } // end else dac + } // end else "detector not locked" + } // end if ret==OK +#endif +#ifdef VERBOSE + printf("DAC set to %d in dac units and %d mV\n", retval[0],retval[1]); +#endif + + if(ret == OK && differentClients) + ret=FORCE_UPDATE; + + // 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,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; +} + + + + + + +int get_adc(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int arg[2]={-1,-1}; + int retval=-1; + enum dacIndex ind=0; + int imod=-1; + sprintf(mess,"get ADC failed\n"); + + // receive arguments + n = receiveData(file_des,arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + ind=arg[0]; + imod=arg[1]; + +#ifdef MYTHEND +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (imod>=getTotalNumberOfModules() || imod<0) { + ret = FAIL; + sprintf(mess,"Module number %d out of range\n",imod); + cprintf(RED, "Warning: %s", mess); + } +#endif +#endif + + enum ADCINDEX iadc=0; + switch (ind) { +#ifdef EIGERD + case TEMPERATURE_FPGAEXT: + iadc = TEMP_FPGAEXT; + break; + case TEMPERATURE_10GE: + iadc = TEMP_10GE; + break; + case TEMPERATURE_DCDC: + iadc = TEMP_DCDC; + break; + case TEMPERATURE_SODL: + iadc = TEMP_SODL; + break; + case TEMPERATURE_SODR: + iadc = TEMP_SODR; + break; + case TEMPERATURE_FPGA: + iadc = TEMP_FPGA; + break; + case TEMPERATURE_FPGA2: + iadc = TEMP_FPGAFEBL; + break; + case TEMPERATURE_FPGA3: + iadc = TEMP_FPGAFEBR; + break; +#endif +#if defined(GOTTHARD) || defined(JUNGFRAUD) + case TEMPERATURE_FPGA: + iadc = TEMP_FPGA; + break; + case TEMPERATURE_ADC: + iadc = TEMP_ADC; + break; +#endif + default: + ret = FAIL; + sprintf(mess,"Dac Index (%d) is not implemented for this detector\n",(int)ind); + cprintf(RED, "Warning: %s", mess); + break; + } + +#ifdef VERBOSE + printf("Getting ADC %d of module %d\n", iadc, imod); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) + retval=getADC(iadc,imod); +#endif +#ifdef VERBOSE + printf("ADC is %f\n", retval); +#endif + + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + + // 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,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; +} + + + + + +int write_register(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int retval=-1; + sprintf(mess,"write to register failed\n"); + + // 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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { +#ifdef VERBOSE + printf("writing to register 0x%x data 0x%x\n", addr, val); +#endif + retval=writeRegister(addr,val); + 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); + } + } +#endif +#ifdef VERBOSE + printf("Data set to 0x%x\n", retval); +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + + // 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,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; + +} + + + + + +int read_register(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int retval=-1; + sprintf(mess,"read register failed\n"); + + // receive arguments + int arg=0; + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + int addr=arg; + + // execute action +#ifdef VERBOSE + printf("reading register 0x%x\n", addr); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=readRegister(addr); +#endif +#ifdef VERBOSE + printf("Returned value 0x%x\n", retval); +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + + // 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,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; +} + + + + +int write_memory(int file_des) { + int ret=FAIL,ret1=FAIL; + int n=0; + sprintf(mess,"Function (Write Memory) is not implemented for this detector\n"); + cprintf(RED, "Error: %s", mess); + + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + + n = sendData(file_des,&ret1,sizeof(ret),INT32); + n = sendData(file_des,mess,MAX_STR_LENGTH,OTHER); + + // return ok / fail + return ret; +} + + +int read_memory(int file_des) { + int ret=FAIL,ret1=FAIL; + int n=0; + sprintf(mess,"Function (Read Memory) is not implemented for this detector\n"); + cprintf(RED, "Error: %s", mess); + + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + + n = sendData(file_des,&ret1,sizeof(ret),INT32); + n = sendData(file_des,mess,MAX_STR_LENGTH,OTHER); + + // return ok / fail + return ret; +} + + + +int set_channel(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int retval=-1; + sprintf(mess,"set channel failed\n"); + +#ifndef MYTHEND + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret = FAIL; + sprintf(mess,"Function (Set Channel) is not implemented for this detector\n"); + cprintf(RED, "Warning: %s", mess); +#else + + // receive arguments + sls_detector_channel myChan; + n=receiveChannel(file_des, &myChan); + if (n < 0) return printSocketReadError(); + + // execute action +#ifdef VERBOSE + printf("Setting channel\n"); + printf("channel number is %d, chip number is %d, module number is %d, register is %lld\n", myChan.chan,myChan.chip, myChan.module, myChan.reg); +#endif + if (differentClients && lockStatus) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else if (myChan.chan>=getNumberOfChannelsPerChip()) { + ret = FAIL; + sprintf(mess,"channel number %d too large!\n",myChan.chan); + cprintf(RED, "Warning: %s", mess); + } + else if (myChan.chip>=getNumberOfChipsPerModule()) { + ret = FAIL; + sprintf(mess,"chip number %d too large!\n",myChan.chip); + cprintf(RED, "Warning: %s", mess); + } + else if (myChan.module>=getTotalNumberOfModules()) { + ret = FAIL; + sprintf(mess,"module number %d too large!\n",myChan.module); + cprintf(RED, "Warning: %s", mess); + } + else + retval=setChannel(myChan); +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; +} + + + + +int get_channel(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sls_detector_channel retval; + sprintf(mess,"get channel failed\n"); + +#ifndef MYTHEND + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret = FAIL; + sprintf(mess,"Function (Get Channel) is not implemented for this detector\n"); + cprintf(RED, "Warning: %s", mess); +#else + + // receive arguments + int arg[3]={-1,-1,-1}; + n = receiveData(file_des,arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + + // execute action + int ichan=arg[0]; + int ichip=arg[1]; + int imod=arg[2]; +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ichan>=getNumberOfChannelsPerChip()) { + ret=FAIL; + sprintf(mess, "channel number %d too large!\n",myChan.chan); + cprintf(RED, "Warning: %s", mess); + } else + retval.chan=ichan; + if (ichip>=getNumberOfChipsPerModule()) { + ret=FAIL; + sprintf(mess, "chip number %d too large!\n",myChan.chip); + cprintf(RED, "Warning: %s", mess); + } else + retval.chip=ichip; + + if (imod>=getTotalNumberOfModules()) { + ret=FAIL; + sprintf(mess, "module number %d too large!\n",myChan.module); + cprintf(RED, "Warning: %s", mess); + } else { + retval.module=imod; + ret=getChannel(&retval); +#ifdef VERBOSE + printf("Returning channel %d %d %d, 0x%llx\n", retval.chan, retval.chip, retval.mod, (retval.reg)); +#endif + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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) { + ret=sendChannel(file_des, &retval); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; +} + + + +int set_all_channels(int file_des) { + int ret=FAIL,ret1=FAIL; + int n=0; + sprintf(mess,"Function (Set All Channels) is not implemented for this detector\n"); + cprintf(RED, "Error: %s", mess); + + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + + n = sendData(file_des,&ret1,sizeof(ret),INT32); + n = sendData(file_des,mess,MAX_STR_LENGTH,OTHER); + + // return ok / fail + return ret; +} + + + + + +int set_chip(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int retval=-1; + sprintf(mess,"set chip failed\n"); + +#ifndef MYTHEND + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret = FAIL; + sprintf(mess,"Function (Set Channel) is not implemented for this detector\n"); + cprintf(RED, "Warning: %s", mess); +#else + sls_detector_chip myChip; + +#ifdef SLS_DETECTOR_FUNCTION_LIST + myChip.nchan=getNumberOfChannelsPerChip(); + int *ch(int*)malloc((myChip.nchan)*sizeof(int)); + myChip.chanregs=ch; + + // receive arguments + n=receiveChip(file_des, &myChip); +#ifdef VERBOSE + printf("Chip received\n"); +#endif + if(n < 0) return FAIL; + + // execute action + if (differentClients==1 && lockStatus==1) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } + else{ +#ifdef VERBOSE + printf("Setting chip\n"); + printf("chip number is %d, module number is %d, register is %d, nchan %d\n",myChip.chip, myChip.module, myChip.reg, myChip.nchan); +#endif + if (myChip.chip>=getNumberOfChipsPerModule()) { + ret = FAIL; + sprintf(mess,"chip number %d too large!\n",myChan.chip); + cprintf(RED, "Warning: %s", mess); + } + else if (myChip.module>=getTotalNumberOfModules()) { + ret = FAIL; + sprintf(mess,"module number %d too large!\n",myChan.module); + cprintf(RED, "Warning: %s", mess); + } + else + retval=setChip(myChip); + } + free(ch); +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; +} + + + + +int get_chip(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sls_detector_chip retval; + sprintf(mess,"get chip failed\n"); + +#ifndef MYTHEND + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret = FAIL; + sprintf(mess,"Function (Set Channel) is not implemented for this detector\n"); + cprintf(RED, "Warning: %s", mess); +#else + + // receive arguments + int arg[2]={-1,-1}; + n = receiveData(file_des,arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + +#ifdef SLS_DETECTOR_FUNCTION_LIST + int ichip=arg[0]; + int imod=arg[1]; + + // execute action + if (ichip>=getNumberOfChipsPerModule()) { + ret = FAIL; + sprintf(mess,"channel number %d too large!\n",myChan.chan); + cprintf(RED, "Warning: %s", mess); + } else + retval.chip=ichip; + + if (imod>=getTotalNumberOfModules()) { + ret = FAIL; + sprintf(mess,"module number %d too large!\n",imod); + cprintf(RED, "Warning: %s", mess); + } else + retval.module=imod; + + if (ret==OK) + ret=getChip(&retval); +#endif +#ifdef VERBOSE + printf("Returning chip %d %d\n", ichip, imod); +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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) { + ret=sendChip(file_des, &retval); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; +} + + + + +int set_all_chips(int file_des) { + int ret=FAIL,ret1=FAIL; + int n=0; + sprintf(mess,"Function (Set All Chips) is not implemented for this detector\n"); + cprintf(RED, "Error: %s", mess); + + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + + n = sendData(file_des,&ret1,sizeof(ret),INT32); + n = sendData(file_des,mess,MAX_STR_LENGTH,OTHER); + + // return ok / fail + return ret; +} + + + + + +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"); + +#ifdef SLS_DETECTOR_FUNCTION_LIST + int *myDac=NULL; + int *myAdc=NULL; + int *myChip = NULL; + int *myChan = NULL; + + myDac=(int*)malloc(getNumberOfDACsPerModule()*sizeof(int)); + if (getNumberOfDACsPerModule() > 0 && myDac == NULL) { + ret = FAIL; + sprintf(mess,"could not allocate dacs\n"); + cprintf(RED, "Warning: %s", mess); + } + else { + myModule.dacs=myDac; + myAdc=(int*)malloc(getNumberOfADCsPerModule()*sizeof(int)); + if (getNumberOfADCsPerModule() > 0 && myAdc == NULL) { + ret = FAIL; + sprintf(mess,"could not allocate adcs\n"); + cprintf(RED, "Warning: %s", mess); + } + 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(getNumberOfChipsPerModule()*sizeof(int)); + if (getNumberOfChipsPerModule() > 0 && myChip == NULL) { + ret = FAIL; + sprintf(mess,"could not allocate chips\n"); + cprintf(RED, "Warning: %s", mess); + } + else { + myModule.chipregs=myChip; + myChan=(int*)malloc(getNumberOfChannelsPerModule()*sizeof(int)); + if (getNumberOfChannelsPerModule() > 0 && myChan == NULL) { + ret = FAIL; + sprintf(mess,"could not allocate chans\n"); + cprintf(RED, "Warning: %s", mess); + } + else { + myModule.chanregs=myChan; +#endif + myModule.nchip=getNumberOfChipsPerModule(); + myModule.nchan=getNumberOfChannelsPerModule(); + myModule.ndac=getNumberOfDACsPerModule(); + myModule.nadc=getNumberOfADCsPerModule(); + + + // receive arguments +#ifdef VERBOSE + printf("Setting module\n"); +#endif + n=receiveModuleGeneral(file_des, &myModule, +#ifdef JUNGFRAUD + 0 //0 is to receive partially (without trimbits etc.) +#else + 1 +#endif + ); + if (n<0) return FAIL; +#ifdef VERBOSE + printf("module number is %d,register is %d, nchan %d, nchip %d, ndac %d, nadc %d, gain %f, offset %f\n", + myModule.module, myModule.reg, myModule.nchan, myModule.nchip, myModule.ndac, myModule.nadc, myModule.gain,myModule.offset); +#endif +#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 + } + } +#endif + } + } + + //check settings index + if (ret==OK) { +#ifdef MYTHEND + if (myModule.module>=getNModBoard()) { + ret = FAIL; + sprintf(mess,"Module Number to Set Module (%d) is too large\n", myModule.module); + cprintf(RED, "Warning: %s", mess); + } + if (myModule.module<0) + myModule.module=ALLMOD; +#endif +#if defined(JUNGFRAUD) || defined(EIGERD) + switch(myModule.reg){ + case GET_SETTINGS: + case UNINITIALIZED: +#ifdef EIGERD + case STANDARD: + case HIGHGAIN: + case LOWGAIN: + case VERYHIGHGAIN: + case VERYLOWGAIN: +#elif JUNGFRAUD + case DYNAMICGAIN: + case DYNAMICHG0: + case FIXGAIN1: + case FIXGAIN2: + case FORCESWITCHG1: + case FORCESWITCHG2: +#endif + break; + default: + ret = FAIL; + sprintf(mess,"Setting (%d) is not implemented for this detector\n", myModule.reg); + cprintf(RED, "Warning: %s", mess); + 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,-1); + else { + //changes settings to undefined (loading a random trim file) + setSettings(UNDEFINED,-1); + 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(); +#else + retval=setModule(myModule); + if (retval != myModule.reg) + ret = FAIL; +#endif + if(myChip != NULL) free(myChip); + if(myChan != NULL) free(myChan); + if(myDac != NULL) free(myDac); + if(myAdc != NULL) free(myAdc); + } + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // return ok / fail + return ret; +} + + + + + + + + +int get_module(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int arg=-1; + int imod=-1; + sls_detector_module myModule; + sprintf(mess,"get module failed\n"); + + // receive arguments + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + imod=arg; + + // execute action +#ifdef SLS_DETECTOR_FUNCTION_LIST + int *myDac=NULL; + int *myAdc=NULL; + int *myChip = NULL; + int *myChan = NULL; + + if (imod<0 || imod>getTotalNumberOfModules()) { + ret = FAIL; + sprintf(mess,"Module Index (%d) is out of range\n", imod); + cprintf(RED, "Warning: %s", mess); + } + else { + myDac=(int*)malloc(getNumberOfDACsPerModule()*sizeof(int)); + if (getNumberOfDACsPerModule() > 0 && myDac == NULL) { + ret = FAIL; + sprintf(mess,"could not allocate dacs\n"); + cprintf(RED, "Warning: %s", mess); + } + else { + myModule.dacs=myDac; + myAdc=(int*)malloc(getNumberOfADCsPerModule()*sizeof(int)); + if (getNumberOfADCsPerModule() > 0 && myAdc == NULL) { + ret = FAIL; + sprintf(mess,"could not allocate adcs\n"); + cprintf(RED, "Warning: %s", mess); + } + 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(getNumberOfChipsPerModule()*sizeof(int)); + if (getNumberOfChipsPerModule() > 0 && myChip == NULL) { + ret = FAIL; + sprintf(mess,"could not allocate chips\n"); + cprintf(RED, "Warning: %s", mess); + } + else { + myModule.chipregs=myChip; + myChan=(int*)malloc(getNumberOfChannelsPerModule()*sizeof(int)); + if (getNumberOfChannelsPerModule() > 0 && myChan == NULL) { + ret = FAIL; + sprintf(mess,"could not allocate chans\n"); + cprintf(RED, "Warning: %s", mess); + } + else { + myModule.chanregs=myChan; +#endif + myModule.nchip=getNumberOfChipsPerModule(); + myModule.nchan=getNumberOfChannelsPerModule(); + myModule.ndac=getNumberOfDACsPerModule(); + myModule.nadc=getNumberOfADCsPerModule(); + myModule.module=imod; + getModule(&myModule); +#ifdef VERBOSE + printf("Returning module %d of register %x\n", imod, myModule.reg); +#endif +#ifndef JUNGFRAUD + } + } +#endif + } + } + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + + // 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) { + ret=sendModuleGeneral(file_des, &myModule, +#ifdef JUNGFRAUD + 0 //0 is to receive partially (without trimbits etc.) +#else + 1 +#endif + ); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + +#ifdef SLS_DETECTOR_FUNCTION_LIST + if(myChip != NULL) free(myChip); + if(myChan != NULL) free(myChan); + if(myDac != NULL) free(myDac); + if(myAdc != NULL) free(myAdc); +#endif + + // return ok / fail + return ret; + +} + + + +int set_all_modules(int file_des) { + int ret=FAIL,ret1=FAIL; + int n=0; + sprintf(mess,"Function (Set All Modules) is not implemented for this detector\n"); + cprintf(RED, "Error: %s", mess); + + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + + n = sendData(file_des,&ret1,sizeof(ret),INT32); + n = sendData(file_des,mess,MAX_STR_LENGTH,OTHER); + + // return ok / fail + return ret; +} + + + + +int set_settings(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int arg[2]={-1,-1}; + int retval=-1; + int imod=-1; + enum detectorSettings isett=-1; + sprintf(mess,"set settings failed\n"); + + // receive arguments + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + imod=arg[1]; + isett=arg[0]; + + // execute action + if (differentClients && lockStatus && isett!=GET_SETTINGS) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else if (imod>=getTotalNumberOfModules()) { + ret = FAIL; + sprintf(mess,"Module number %d out of range\n",imod); + cprintf(RED, "Warning: %s", mess); + } + else { +#ifdef VERBOSE + printf("Changing settings of module %d to %d\n", imod, isett); +#endif + retval=setSettings(isett, imod); +#ifdef VERBOSE + printf("Settings changed to %d\n", isett); +#endif + if (retval==isett || isett<0) { + ret=OK; + } else { + ret = FAIL; + sprintf(mess,"Changing settings of module %d: wrote %d but read %d\n", imod, isett, retval); + cprintf(RED, "Warning: %s", mess); + } + } +#endif + + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + + +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"); + +#if !defined(MYTHEND) && !defined(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); +#else + + // receive arguments + int imod=-1; + n = receiveData(file_des,&imod,sizeof(imod),INT32); + if (n < 0) return printSocketReadError(); + + // execute action +#ifdef VERBOSE + printf("Getting threshold energy of module %d\n", imod); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (imod>=getTotalNumberOfModules()) { + ret=FAIL; + sprintf(mess,"Module number %d out of range\n",imod); + } + else { + retval=getThresholdEnergy(imod); +#ifdef VERBOSE + printf("Threshold is %d eV\n", retval); +#endif + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + +int set_threshold_energy(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int retval=-1; + sprintf(mess,"set thhreshold energy failed\n"); + +#ifndef MYTHEND + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret = FAIL; +#ifdef EIGERD + sprintf(mess,"Function (Set Threshold Energy) is only implemented via Set Settings for this detector\n"); +#else + sprintf(mess,"Function (Set Threshold Energy) is not implemented for this detector\n"); +#endif + cprintf(RED, "Warning: %s", mess); +#else + + // receive arguments + int arg[3]={-1,-1,-1}; + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + + // execute action + int ethr=arg[0]; + int imod=arg[1]; + enum detectorSettings isett=arg[2]; + if (differentClients && lockStatus) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else if (imod>=getTotalNumberOfModules()) { + ret=FAIL; + sprintf(mess,"Module number %d out of range\n",imod); + } + else { + printf("Setting threshold energy of module %d to %d eV with settings %d\n", imod, ethr, isett); + retval=setThresholdEnergy(ethr, imod); +#ifdef VERBOSE + printf("Threshold set to %d eV\n", retval); +#endif + if (retval!=ethr) { + ret=FAIL; + sprintf(mess,"Setting threshold of module %d: wrote %d but read %d\n", imod, ethr, retval); + cprintf(RED, "Warning: %s", mess); + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + + +int start_acquisition(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sprintf(mess,"start acquisition failed\n"); + + // execute action + if (differentClients && lockStatus) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + printf("Starting acquisition\n"); + ret=startStateMachine(); + if (ret==FAIL) + cprintf(RED, "Warning: %s", mess); + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + + // 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); + } + + // return ok / fail + return ret; +} + + + +int stop_acquisition(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sprintf(mess,"stop acquisition failed\n"); + + // execute action + if (differentClients && lockStatus) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + printf("Stopping acquisition\n"); + ret=stopStateMachine(); + if (ret==FAIL) + cprintf(RED, "Warning: %s", mess); + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + + // 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); + } + + // return ok / fail + return ret; +} + + + + + +int start_readout(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sprintf(mess,"start readout failed\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); +#else + + // execute action + if (differentClients && lockStatus) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + printf("Starting readout\n"); + ret=startReadOut(); + if (ret==FAIL) + cprintf(RED, "Warning: %s", mess); + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } + + // return ok / fail + return ret; +} + + + + + + +int get_run_status(int file_des) { + int ret=OK,ret1=OK; + enum runStatus s=ERROR; + + // execute action +#ifdef VERBOSE + printf("Getting status\n"); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + s= getRunStatus(); +#endif + if (differentClients) + ret=FORCE_UPDATE; + + // send ok / fail + sendData(file_des,&ret1,sizeof(ret),INT32); + // send return argument + sendData(file_des,&s,sizeof(s),INT32); + + // return ok / fail + return ret; +} + + + + + +int start_and_read_all(int file_des) { + int dataret1=FAIL, dataret=FAIL; +#ifdef VERBOSE + printf("Starting and reading all frames\n"); +#endif + + // execute action + if (differentClients && lockStatus) { + dataret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + // ret could be swapped during sendData + dataret1 = dataret; + // send fail + sendData(file_des,&dataret1,sizeof(dataret),INT32); + // send return argument + sendData(file_des,mess,sizeof(mess),OTHER); + // return fail + return dataret; + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + startStateMachine(); + read_all(file_des); +#endif + return OK; +} + + + + +int read_frame(int file_des) { + int dataret1=FAIL, dataret=FAIL; + int n=0; + sprintf(mess, "read frame failed\n"); + + // execute action + if (differentClients && lockStatus) { + dataret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + // ret could be swapped during sendData + dataret1 = dataret; + // send fail + sendData(file_des,&dataret1,sizeof(dataret),INT32); + // send return argument + sendData(file_des,mess,sizeof(mess),OTHER); + // return fail + return dataret; + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + readFrame(&dataret, mess); +#endif + if(dataret == FAIL) + cprintf(RED,"%s\n",mess); + else + cprintf(GREEN,"%s",mess); + + if (differentClients) + dataret=FORCE_UPDATE; + + //dataret could be swapped during sendData + dataret1 = dataret; + // send finished / fail + n=sendData(file_des,&dataret1,sizeof(dataret1),INT32); + if (n<0) return FAIL; // if called from read_all, should fail to stop talking to a closed client socket + // send return argument + n=sendData(file_des,mess,sizeof(mess),OTHER); + if (n<0) return FAIL; // if called from read_all, should fail to stop talking to a closed client socket + // return finished / fail + return dataret; +} + + + + +int read_all(int file_des) { +#ifdef SLS_DETECTOR_FUNCTION_LIST + while(read_frame(file_des)==OK) { +#ifdef VERBOSE + printf("frame read\n"); +#endif + ; + } +#endif +#ifdef VERBOSE + printf("Frames finished or failed\n"); +#endif + return OK; +} + + + + +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"); + + // 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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { +#ifdef VERBOSE + printf("setting timer %d to %lld ns\n",ind,tns); +#endif + switch(ind) { +#ifdef EIGERD + case SUBFRAME_ACQUISITION_TIME: + 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"); + break; + } +#endif +#ifdef MYTHEN + case PROBES_NUMBER: + case GATES_NUMBER: + case DELAY_AFTER_TRIGGER: +#elif JUNGFRAUD + case DELAY_AFTER_TRIGGER: +#endif + case FRAME_NUMBER: + case ACQUISITION_TIME: // for all detectors + 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); + break; + } +#if defined(MYTHEND) || defined(GOTTHARD) + if (ret == OK && ind==FRAME_NUMBER) { + ret=allocateRAM(); + if (ret!=OK) { + ret = FAIL; + sprintf(mess,"Could not allocate RAM for %lld frames\n", tns); + cprintf(RED, "%s", mess); + } + } +#endif + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT64); + + // return ok / fail + return ret; +} + + + + + + + + + +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"); + + + +#ifdef EIGERD + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret = FAIL; + sprintf(mess,"Function (Get Timer Left) is not implemented for this detector\n"); + cprintf(RED, "%s", mess); +#else + + // 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 SLS_DETECTOR_FUNCTION_LIST + switch(ind) { +#ifdef MYTHEND + case PROBES_NUMBER: +#endif + case FRAME_NUMBER: + case ACQUISITION_TIME: + case FRAME_PERIOD: + case DELAY_AFTER_TRIGGER: +#ifndef JUNGFRAUD + case GATES_NUMBER: +#endif + case CYCLES_NUMBER: + case PROGRESS: + case ACTUAL_TIME: + case MEASUREMENT_TIME: +#ifdef JUNGFRAUD + case FRAMES_FROM_START: + case FRAMES_FROM_START_PG: +#endif + retval=getTimeLeft(ind); + 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 +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT64); + + // return ok / fail + return ret; +} + + + + + + +int set_dynamic_range(int file_des) { + 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"); + + // receive arguments + n = receiveData(file_des,&dr,sizeof(dr),INT32); + if (n < 0) return printSocketReadError(); + + // execute action + if (differentClients && lockStatus && dr>=0) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + switch(dr){ + case -1: + case 16: +#ifdef EIGERD + case 4: case 8: case 32: +#endif + break; + default: + ret = FAIL; + sprintf(mess,"Dynamic Range (%d) is not implemented for this detector\n", dr); + cprintf(RED, "Warning: %s", mess); + } + } + 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)){ + setRateCorrection(-1); //tau_ns will not be -1 here + if(!getRateCorrectionEnable()){ + ret = FAIL; + strcpy(mess,"Deactivating Rate Correction. Could not set it.\n"); + cprintf(RED,"%s",mess); + } + } + } + +#else + retval = setDynamicRange(dr); +#endif + if (dr>=0) dataBytes=calculateDataBytes(); + } +#endif + if ((ret == OK) && dr>=0 && retval!=dr) { + ret = FAIL; + cprintf(RED,"%s",mess); + } + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + + //rate correction ret + // ret could be swapped during sendData + rateret1 = rateret; + // send ok / fail + n = sendData(file_des,&rateret1,sizeof(rateret1),INT32); + // send return argument + if (ret==FAIL) { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + + + +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"); + +#if !defined(MYTHEND) && !defined(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); +#else + + // 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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { +#ifdef VERBOSE + printf("setting readout flags to %d\n",arg); +#endif + switch(arg) { + case GET_READOUT_FLAGS: +#ifdef MYTHEND + case TOT_MODE: + case NORMAL_READOUT: + case STORE_IN_RAM: + case CONTINOUS_RO: +#elif EIGERD + case STORE_IN_RAM: + case CONTINOUS_RO: + case PARALLEL: + case NONPARALLEL: + case SAFE: +#endif + retval=setReadOutFlags(arg); + break; + default: + ret = FAIL; + sprintf(mess,"Readout Flag Index (%d) is not implemented for this detector\n", (int)arg); + cprintf(RED, "Warning: %s", mess); + break; + } +#endif + 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); + } + + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + } +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + + + +int set_roi(int file_des) { + int ret=OK,ret1=OK; + int n=0; + strcpy(mess,"set nroi failed\n"); + +#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); +#else + + ROI* retval=0; + int retvalsize=0,retvalsize1=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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { +#ifdef VERBOSE + printf("setting speed variable %d to %d\n",arg,val); +#endif + switch (arg) { +#ifdef JUNGFRAUD + case ADC_PHASE: + adcPhase(val); + break; +#endif +#ifdef MYTHEND + case CLOCK_DIVIDER: + case WAIT_STATES: + case SET_SIGNAL_LENGTH: + case TOT_CLOCK_DIVIDER: + case TOT_DUTY_CYCLE: +#elif EIGERD + case CLOCK_DIVIDER: +#elif JUNGFRAUD + case CLOCK_DIVIDER: +#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); + } + break; + default: + ret = FAIL; + sprintf(mess,"Speed Index (%d) is not implemented for this detector\n",(int) arg); + cprintf(RED, "Warning: %s", mess); + break; + } + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + + +int execute_trimming(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sprintf(mess,"execute trimming failed\n"); + +#ifndef MYTHEND + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret = FAIL; + sprintf(mess,"Function (Execute Trimming) is not implemented for this detector\n"); + cprintf(RED, "Warning: %s", mess); +#else + + int retval=-1; + + // receive arguments + enum trimMode mode=0; + int arg[3]={-1,-1,-1}; + n = receiveData(file_des,&mode,sizeof(mode),INT32); + if (n < 0) return printSocketReadError(); + + n = receiveData(file_des,arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + + // execute action + int imod, par1,par2; + imod=arg[0]; + par1=arg[1]; + par2=arg[2]; + if (differentClients && lockStatus) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else if (imod>=getTotalNumberOfModules()) { + ret = FAIL; + sprintf(mess,"Module Number (%d) is out of range\n"); + cprintf(RED, "Warning: %s", mess); + } + else { +#ifdef VERBOSE + printf("trimming module %d mode %d, parameters %d %d \n",imod,mode, par1, par2); +#endif + switch(mode) { + case NOISE_TRIMMING: + case BEAM_TRIMMING: + case IMPROVE_TRIMMING: + case FIXEDSETTINGS_TRIMMING: + retval=executeTrimming(mode, par1, par2, imod); + if ((ret!=OK) && (retval>0)) { + ret=FAIL; + sprintf(mess,"Could not trim %d channels\n", retval); + cprintf(RED, "Warning: %s", mess); + } + break; + default: + ret = FAIL; + sprintf(mess,"Trimming Mode (%d) is not implemented for this detector\n", (int) mode); + cprintf(RED, "Warning: %s", mess); + break; + } + + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } + + // return ok / fail + return ret; +} + + + + + +int exit_server(int file_des) { + int ret=FAIL; + sprintf(mess,"Closing Server\n"); + cprintf(BG_RED,"Error: %s",mess); + // send ok / fail + sendData(file_des,&ret,sizeof(ret),INT32); + // send return argument + sendData(file_des,mess,sizeof(mess),OTHER); + return GOODBYE; +} + + + + +int lock_server(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int lock=0; + sprintf(mess,"lock server failed\n"); + + // receive arguments + n = receiveData(file_des,&lock,sizeof(lock),INT32); + if (n < 0) return printSocketReadError(); + + // execute action + if (lock>=0) { + if (lockStatus==0 || strcmp(lastClientIP,thisClientIP)==0 || strcmp(lastClientIP,"none")==0) { + lockStatus=lock; + strcpy(lastClientIP,thisClientIP); + } else { + ret = FAIL; + sprintf(mess,"Server already locked by %s\n", lastClientIP); + cprintf(RED, "Warning: %s", mess); + } + } + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + + // 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); + } else + n += sendData(file_des,&lockStatus,sizeof(lockStatus),INT32); + + // return ok / fail + return ret; +} + + + + + +int get_last_client_ip(int file_des) { + int ret=OK,ret1=OK; + if (differentClients) + ret=FORCE_UPDATE; + // send ok / fail + sendData(file_des,&ret1,sizeof(ret),INT32); + // send return argument + sendData(file_des,lastClientIP,sizeof(lastClientIP),OTHER); + // return ok / fail + return ret; +} + + + + +int set_port(int file_des) { + int ret=OK,ret1=OK; + int n=0; + enum portType p_type=0; + int p_number=-1; + sprintf(mess,"set port failed\n"); + + // receive arguments + n = receiveData(file_des,&p_type,sizeof(p_type),INT32); + if (n < 0) return printSocketReadError(); + + n = receiveData(file_des,&p_number,sizeof(p_number),INT32); + if (n < 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 { + if (p_number<1024) { + ret = FAIL; + sprintf(mess,"Port Number (%d) too low\n", p_number); + cprintf(RED, "Warning: %s", mess); + } + printf("set port %d to %d\n",p_type, p_number); + sd=bindSocket(p_number); + if (sd<0) { + ret = FAIL; + sprintf(mess,"Could not bind port %d\n", p_number); + cprintf(RED, "Warning: %s", mess); + if (sd==-10) { + ret = FAIL; + sprintf(mess,"Port %d already set\n", p_number); + cprintf(RED, "Warning: %s", mess); + } + } + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + } + + // 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); + } else { + n = sendData(file_des,&p_number,sizeof(p_number),INT32); + closeConnection(file_des); + exitServer(sockfd); + sockfd=sd; + } + + // return ok / fail + return ret; +} + + + + +int update_client(int file_des) { + int ret=OK; + sendData(file_des,&ret,sizeof(ret),INT32); + return send_update(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; + int64_t retval = 0; + enum detectorSettings t; + + n = sendData(file_des,lastClientIP,sizeof(lastClientIP),OTHER); + if (n < 0) return printSocketReadError(); + + +#ifdef SLS_DETECTOR_FUNCTION_LIST + nm=setNMod(GET_FLAG,X); +#endif + n = sendData(file_des,&nm,sizeof(nm),INT32); + if (n < 0) return printSocketReadError(); + + +#ifdef SLS_DETECTOR_FUNCTION_LIST + nm=setNMod(GET_FLAG,Y); +#endif + n = sendData(file_des,&nm,sizeof(nm),INT32); + if (n < 0) return printSocketReadError(); + + +#ifdef SLS_DETECTOR_FUNCTION_LIST + nm=setDynamicRange(GET_FLAG); +#endif + n = sendData(file_des,&nm,sizeof(nm),INT32); + if (n < 0) return printSocketReadError(); + + +#ifdef SLS_DETECTOR_FUNCTION_LIST + dataBytes=calculateDataBytes(); +#endif + n = sendData(file_des,&dataBytes,sizeof(dataBytes),INT32); + if (n < 0) return printSocketReadError(); + + +#ifdef SLS_DETECTOR_FUNCTION_LIST + t=setSettings(GET_SETTINGS, GET_FLAG); +#endif + n = sendData(file_des,&t,sizeof(t),INT32); + if (n < 0) return printSocketReadError(); + + +#if defined(MYTHEND) || defined(EIGERD) +#ifdef SLS_DETECTOR_FUNCTION_LIST + nm=getThresholdEnergy(GET_FLAG); +#endif + n = sendData(file_des,&nm,sizeof(nm),INT32); + if (n < 0) return printSocketReadError(); +#endif + + +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(FRAME_NUMBER,GET_FLAG); +#endif + n = sendData(file_des,&retval,sizeof(int64_t),INT64); + if (n < 0) return printSocketReadError(); + + +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(ACQUISITION_TIME,GET_FLAG); +#endif + n = sendData(file_des,&retval,sizeof(int64_t),INT64); + if (n < 0) return printSocketReadError(); + + +#ifdef EIGERD +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(SUBFRAME_ACQUISITION_TIME,GET_FLAG); +#endif + n = sendData(file_des,&retval,sizeof(int64_t),INT64); + if (n < 0) return printSocketReadError(); +#endif + + +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(FRAME_PERIOD,GET_FLAG); +#endif + n = sendData(file_des,&retval,sizeof(int64_t),INT64); + if (n < 0) return printSocketReadError(); + + +#ifndef EIGERD +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(DELAY_AFTER_TRIGGER,GET_FLAG); +#endif + n = sendData(file_des,&retval,sizeof(int64_t),INT64); + if (n < 0) return printSocketReadError(); +#endif + + +#if !defined(EIGERD) && !defined(JUNGFRAUD) +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(GATES_NUMBER,GET_FLAG); +#endif + n = sendData(file_des,&retval,sizeof(int64_t),INT64); + if (n < 0) return printSocketReadError(); +#endif + + +#ifdef MYTHEND +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(PROBES_NUMBER,GET_FLAG); +#endif + n = sendData(file_des,&retval,sizeof(int64_t),INT64); + if (n < 0) return printSocketReadError(); +#endif + + +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(CYCLES_NUMBER,GET_FLAG); +#endif + n = sendData(file_des,&retval,sizeof(int64_t),INT64); + if (n < 0) return printSocketReadError(); + + + if (lockStatus==0) { + strcpy(lastClientIP,thisClientIP); + } + + return OK; +} + + + + + + +int configure_mac(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int retval=-100; + sprintf(mess,"configure mac failed\n"); + +#ifdef MYTHEND + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret = FAIL; + strcpy(mess,"Function (Configure MAC) is not implemented for this detector\n"); + cprintf(RED, "Warning: %s", mess); +#else + + // 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); +#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); +#ifdef VIRTUAL + sscanf(arg[1], "%lx", &imacadd); +#else + sscanf(arg[1], "%llx", &imacadd); +#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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + 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 of module %d at port %x\n", imod, 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(); + } + if(ret==FAIL) { + sprintf(mess,"Could not stop detector acquisition to configure mac\n"); + cprintf(RED, "Warning: %s", mess); + } + else { + 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"); +#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); +#endif + } + + } +#endif + if (differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + + +int load_image(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int retval=-1; + sprintf(mess,"Loading image failed\n"); + +#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); +#else + + // receive arguments + enum imageType index=0; + char ImageVals[dataBytes]; + memset(ImageVals,0,dataBytes); + 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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + 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) { + ret = FAIL; + cprintf(RED, "Warning: %s", 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); + break; + } + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + + +int set_master(int file_des) { + int ret=OK,ret1=OK; + int n=0; + enum masterFlags arg=GET_MASTER; + enum masterFlags retval=GET_MASTER; + sprintf(mess,"set master failed\n"); + + // receive arguments + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + + // execute action + if (differentClients && lockStatus && ((int)arg!=(int)GET_MASTER)) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + retval=setMaster(arg); + if (retval==GET_MASTER) + ret=FAIL; + + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + } +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + + + + +int set_synchronization(int file_des) { + int ret=OK,ret1=OK; + int n=0; + enum synchronizationMode arg=GET_SYNCHRONIZATION_MODE; + enum synchronizationMode retval=GET_SYNCHRONIZATION_MODE; + sprintf(mess,"synchronization mode failed\n"); + + // receive arguments + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) return printSocketReadError(); + + // execute action + if (differentClients && lockStatus && ((int)arg!=(int)GET_SYNCHRONIZATION_MODE)) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + retval=setSynchronization(arg); + if (retval==GET_SYNCHRONIZATION_MODE) + ret=FAIL; + + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + } +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + + +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"); + +#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); +#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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + 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 + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } else + n += sendData(file_des,CounterVals,dataBytes,OTHER); + + // return ok / fail + return ret; +} + + + + + +int reset_counter_block(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sprintf(mess,"Reset counter block failed\n"); + +#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); +#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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + ret=resetCounterBlock(startACQ); + if (ret == FAIL) + cprintf(RED, "Warning: %s", mess); + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + + // 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); + } + + // return ok / fail + return ret; +} + + + + + +int calibrate_pedestal(int file_des){ + int ret=OK,ret1=OK; + int n=0; + int retval=-1; + sprintf(mess,"calibrate pedestal failed\n"); + + +#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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + ret=calibratePedestal(frames); + if (ret == FAIL) + cprintf(RED, "Warning: %s", mess); + } +#endif + if(ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + + + + + +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"); + + // 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); +#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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + 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); + } + else if (differentClients) + ret=FORCE_UPDATE; + } +#endif +#endif + + // 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); + } + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + +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"); + +#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); +#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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { +#ifdef VERBOSE + printf("setting all trimbits to %d\n",arg); +#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,-1); + 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 + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + +int set_ctb_pattern(int file_des) { + int ret=FAIL,ret1=FAIL; + int n=0; + sprintf(mess,"Function (Set CTB Pattern) is not implemented for this detector\n"); + cprintf(RED, "Error: %s", mess); + + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + + n = sendData(file_des,&ret1,sizeof(ret),INT32); + n = sendData(file_des,mess,MAX_STR_LENGTH,OTHER); + + // return ok / fail + return ret; +} + + + +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"); + +#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); +#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); +#endif + setAdc(addr,val); +#ifdef VERBOSE + printf("Data set to 0x%x\n", retval); +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + } +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + +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"); + +#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); +#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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { +#ifdef VERBOSE + printf("Getting/Setting/Resetting counter bit :%d \n",arg); +#endif + retval=setCounterBit(arg); + if((arg != -1) && (retval != arg)) { + ret=FAIL; + cprintf(RED, "Warning: %s", mess); + } + if (ret==OK && differentClients) + ret=FORCE_UPDATE; + } +#endif +#endif + + // 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); + } + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + +int pulse_pixel(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sprintf(mess,"pulse pixel failed\n"); + +#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); +#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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + ret=pulsePixel(arg[0],arg[1],arg[2]); + if (ret == FAIL) + cprintf(RED, "Warning: %s", mess); + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } + + // return ok / fail + return ret; +} + + + + +int pulse_pixel_and_move(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sprintf(mess,"pulse pixel and move failed\n"); + +#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); +#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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + ret=pulsePixelNMove(arg[0],arg[1],arg[2]); + if (ret == FAIL) + cprintf(RED, "Warning: %s", mess); + } +#endif + if(ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } + + // return ok / fail + return ret; +} + + + + + + +int pulse_chip(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sprintf(mess,"pulse chip failed\n"); + +#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); +#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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + ret=pulseChip(arg); + if (ret == FAIL) + cprintf(RED, "Warning: %s", mess); + } +#endif + if(ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } + + // return ok / fail + return ret; +} + + + + + +int set_rate_correct(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sprintf(mess,"Set rate correct failed\n"); + +#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); +#else + + // receive arguments + int64_t tau_ns=-1; + n = receiveData(file_des,&tau_ns,sizeof(tau_ns),INT64); + 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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + 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; + strcpy(mess,"Rate correction Deactivated, must be in 32 or 16 bit mode\n"); + cprintf(RED, "Warning: %s", mess); + } + //16 or 32 bit mode + else{ + if(tau_ns < 0) + tau_ns = getDefaultSettingsTau_in_nsec(); + else if(tau_ns > 0){ + //changing tau to a user defined value changes settings to undefined + setSettings(UNDEFINED,-1); + cprintf(RED,"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); + } + } + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } + + // return ok / fail + return ret; +} + + + + + +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"); + +#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); +#else + +#ifdef SLS_DETECTOR_FUNCTION_LIST + + // execute action + retval = getCurrentTau(); + printf("Getting rate correction %lld\n",(long long int)retval); + +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT64); + + // return ok / fail + return ret; +} + + + + + +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"); + +#ifndef EIGERD + //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); +#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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { +#ifdef VERBOSE + printf("setting network parameter mode %d to %d\n",(int)mode,value); +#endif + switch (mode) { + case DETECTOR_TXN_DELAY_LEFT: + index = TXN_LEFT; + break; + case DETECTOR_TXN_DELAY_RIGHT: + index = TXN_RIGHT; + break; + case DETECTOR_TXN_DELAY_FRAME: + index = TXN_FRAME; + break; + case FLOW_CONTROL_10G: + index = FLOWCTRL_10G; + break; + default: + ret=FAIL; + sprintf(mess,"Network Parameter Index (%d) is not implemented for this detector\n",(int) mode); + cprintf(RED, "Warning: %s", mess); + 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); + } + } + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + + + +int program_fpga(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sprintf(mess,"program FPGA failed\n"); + + +#ifndef JUNGFRAUD + //to receive any arguments + 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); +#else + + 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) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + //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); + } + + //---------------- 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 ---------------- + + if(ret!=FAIL) { + //erasing flash + eraseFlash(); + fpgasrc = (char*)malloc(MAX_FPGAPROGRAMSIZE); + } + + //writing to flash part by part + while(ret != FAIL && filesize){ + + unitprogramsize = MAX_FPGAPROGRAMSIZE; //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 + + //receive + n = receiveData(file_des,fpgasrc,unitprogramsize,OTHER); + if (n < 0) return printSocketReadError(); + + if(!(unitprogramsize - filesize)){ + fpgasrc[unitprogramsize]='\0'; + filesize-=unitprogramsize; + unitprogramsize++; + }else + filesize-=unitprogramsize; + + 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); + cprintf(RED,"Failure: Breaking out of program receiving\n"); + } + //---------------- middle rets ---------------- + + if(ret != FAIL){ + //print progress + printf("Writing to Flash:%d%%\r",(int) (((double)(totalsize-filesize)/totalsize)*100) ); + fflush(stdout); + } + } + + printf("\n"); + + //closing file pointer to flash and informing FPGA + stopWritingFPGAprogram(fp); + + //free resources + if(fpgasrc != NULL) + free(fpgasrc); + if(fp!=NULL) + fclose(fp); +#ifdef VERY_VERBOSE + printf("Done with program receiving command\n"); +#endif + if (isControlServer) + basictests(debugflag); + init_detector(isControlServer); + } +#endif + if (ret==OK) + ret=FORCE_UPDATE; +#endif + + // 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); + } + + // return ok / fail + return ret; +} + + + + + +int reset_fpga(int file_des) { + int ret=OK,ret1=OK; + int n=0; + sprintf(mess,"Reset FPGA unsuccessful\n"); + +#ifndef 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); +#else + + // execute action + if (differentClients && lockStatus) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + if (isControlServer) + basictests(debugflag); + init_detector(isControlServer); + ret = FORCE_UPDATE; + } +#endif +#endif + + // 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); + } + + // return ok / fail + return ret; +} + + + +int power_chip(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int retval=-1; + sprintf(mess,"power chip failed\n"); + +#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); +#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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + 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; + sprintf(mess,"Powering chip failed, wrote %d but read %d\n", arg, retval); + cprintf(RED, "Warning: %s", mess); + } + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + +int set_activate(int file_des) { + int ret=OK,ret1=OK; + int n=0; + int retval=-1; + sprintf(mess,"Activate/Deactivate failed\n"); + +#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); +#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); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + 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); + } + } +#endif + if (ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + // return ok / fail + return ret; +} + + + + +int prepare_acquisition(int file_des) { + int ret=OK,ret1=OK; + int n=0; + strcpy(mess,"prepare acquisition failed\n"); + +#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); +#else + + // execute action + if (differentClients && lockStatus) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else { + ret = prepareAcquisition(); + if (ret == FAIL) + cprintf(RED, "Warning: %s", mess); + } +#endif + if(ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } + + // return ok / fail + return ret; +} + + +int cleanup_acquisition(int file_des) { + int ret=OK,ret1=OK; + int n=0; + strcpy(mess,"prepare acquisition failed\n"); + +#ifndef GOTTHARDD + //to receive any arguments + while (n > 0) + n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER); + ret = FAIL; + sprintf(mess,"Function (Cleanup Acquisition) is not implemented for this detector\n"); + cprintf(RED, "Warning: %s", mess); +#else + + // execute action + if (differentClients && lockStatus) { + ret = FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED, "Warning: %s", mess); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + else {//to be implemented when used here + ret = FAIL; + sprintf(mess,"Function (Cleanup Acquisition) is not implemented for this detector\n"); + cprintf(RED, "Warning: %s", mess); + } +#endif + if(ret==OK && differentClients) + ret=FORCE_UPDATE; +#endif + + // 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); + } + + // return ok / fail + return ret; +} + + diff --git a/slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer_funcs.h b/slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer_funcs.h new file mode 100755 index 000000000..e98feb57f --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/slsDetectorServer_funcs.h @@ -0,0 +1,93 @@ +#ifndef SERVER_FUNCS_H +#define SERVER_FUNCS_H + +#include "sls_receiver_defs.h" +#include + +// initialization functions +int printSocketReadError(); +void basictests(int); +void init_detector(int); +int decode_function(int); +const char* getFunctionName(enum detFuncs func); +void function_table(); +int M_nofunc(int); + +// functions called by client +int exec_command(int); +int get_error(int); +int get_detector_type(int); +int set_number_of_modules(int); +int get_max_number_of_modules(int); +int set_external_signal_flag(int); +int set_external_communication_mode(int); +int get_id(int); +int digital_test(int); +int analog_test(int); +int enable_analog_out(int); +int calibration_pulse(int); +int set_dac(int); +int get_adc(int); +int write_register(int); +int read_register(int); +int write_memory(int); +int read_memory(int); +int set_channel(int); +int get_channel(int); +int set_all_channels(int); +int set_chip(int); +int get_chip(int); +int set_all_chips(int); +int set_module(int); +int get_module(int); +int set_all_modules(int); +int set_settings(int); +int get_threshold_energy(int); +int set_threshold_energy(int); +int start_acquisition(int); +int stop_acquisition(int); +int start_readout(int); +int get_run_status(int); +int start_and_read_all(int); +int read_frame(int); +int read_all(int); +int set_timer(int); +int get_time_left(int); +int set_dynamic_range(int); +int set_readout_flags(int); +int set_roi(int); +int set_speed(int); +int execute_trimming(int); +int exit_server(int); +int lock_server(int); +int get_last_client_ip(int); +int set_port(int); +int update_client(int); +int send_update(int); +int configure_mac(int); +int load_image(int); +int set_master(int); +int set_synchronization(int); +int read_counter_block(int); +int reset_counter_block(int); +int calibrate_pedestal(int); +int enable_ten_giga(int); +int set_all_trimbits(int); +int set_ctb_pattern(int); +int write_adc_register(int); +int set_counter_bit(int); +int pulse_pixel(int); +int pulse_pixel_and_move(int); +int pulse_chip(int); +int set_rate_correct(int); +int get_rate_correct(int); +int set_network_parameter(int); +int program_fpga(int); +int reset_fpga(int); +int power_chip(int); +int set_activate(int); +int prepare_acquisition(int); +int cleanup_acquisition(int); + + +#endif diff --git a/slsDetectorSoftware/mythen3DetectorServer/slsDetector_stopServer.c b/slsDetectorSoftware/mythen3DetectorServer/slsDetector_stopServer.c new file mode 100755 index 000000000..1772ce2b6 --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/slsDetector_stopServer.c @@ -0,0 +1,46 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ +#include "communication_funcs.h" + +#include "slsDetectorFunctionList.h"/*#include "slsDetector_firmware.h" for the time being*/ +#include "slsDetectorServer_defs.h" + +#include +#include + +int sockfd; + +int main(int argc, char *argv[]) +{ + int portno; + int retval=0; + int sd,fd; + + portno = DEFAULT_PORTNO; + + + sd=bindSocket(portno); //defined in communication_funcs + if (getServerError(sd)) //defined in communication_funcs + return -1; + + + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Stop server: waiting for client call\n"); +#endif + fd=acceptConnection(sd); //defined in communication_funcs + retval=stopStateMachine();//defined in slsDetectorFirmare_funcs + closeConnection(fd); //defined in communication_funcs + } + + exitServer(sd); //defined in communication_funcs + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/mythen3DetectorServer/sls_detector_defs.h b/slsDetectorSoftware/mythen3DetectorServer/sls_detector_defs.h new file mode 100755 index 000000000..a8dca1ea5 --- /dev/null +++ b/slsDetectorSoftware/mythen3DetectorServer/sls_detector_defs.h @@ -0,0 +1,599 @@ +#ifndef SLS_DETECTOR_DEFS_H +#define SLS_DETECTOR_DEFS_H + + +#ifdef __CINT__ +#define MYROOT +#define __cplusplus +#endif + +//#include +#include "sls_receiver_defs.h" + +/** default maximum string length */ +#define MAX_SCAN_STEPS 2000 +/** maxmimum number of modules per controller*/ +#define MAXMODS 24 +/** maxmimum number of detectors ina multidetector structure*/ +#define MAXDET 100 +/** header length for data :gotthard*/ +#define HEADERLENGTH 12 + +/** maximum rois */ +#define MAX_ROIS 100 + +/** maximum unit size of program sent to detector */ +#define MAX_FPGAPROGRAMSIZE (2 * 1024 *1024) + + + +#define MAX_SCAN_LEVELS 2 + +typedef char mystring[MAX_STR_LENGTH]; +typedef double mysteps[MAX_SCAN_STEPS]; + + + +#ifndef DACS_FLOAT +typedef int dacs_t; +#else +typedef float dacs_t; +#endif + +#define DEFAULT_DET_MAC "00:aa:bb:cc:dd:ee" +#define DEFAULT_DET_IP "129.129.202.46" + + +/** + \file sls_detector_defs.h +This file contains all the basic definitions common to the slsDetector class +and to the server programs running on the detector + + + * @author Anna Bergamaschi + * @version 0.1alpha (any string) + * @see slsDetector + +$Revision: 824 $ + +*/ + + +/** get flag form most functions */ +#define GET_FLAG -1 + + +#ifdef __cplusplus + +/** @short class containing all the structures, constants and enum definitions */ +class slsDetectorDefs: public virtual slsReceiverDefs{ + public: + + slsDetectorDefs(){}; + +#endif + + + enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript, enCalLog, angCalLog, MAX_ACTIONS}; + + + +/** + @short structure for a detector channel + + should not be used by unexperienced users + + \see ::channelRegisterBit +*/ + typedef struct { + int chan; /**< is the channel number */ + int chip; /**< is the chip number */ + int module; /**< is the module number */ + int64_t reg; /**< is the is the channel register (e.g. trimbits, calibration enable, comparator enable...) */ + } sls_detector_channel; + + /** + @short structure for a detector chip + + should not be used by unexperienced users + \see ::chipRegisterBit ::channelRegisterBit +*/ + typedef struct { + int chip; /**< is the chip number */ + int module; /**< is the module number */ + int nchan; /**< is the number of channels in the chip */ + int reg; /***/ + M_Vrf, /**< mythen 3 >*/ + M_VrfSh, /**< mythen 3 >*/ + M_Vth1, /**< mythen 3 >*/ + M_Vth2, /**< mythen 3 >*/ + M_Vth3, /**< mythen 3 >*/ + M_Vtrim, /**< mythen 3 >*/ + M_VPL, /**< mythen 3 >*/ + M_VPH, /**< mythen 3 >*/ + V_POWER_A = 100, /**new chiptest board */ + V_POWER_B = 101, /**new chiptest board */ + V_POWER_C = 102, /**new chiptest board */ + V_POWER_D = 103, /**new chiptest board */ + V_POWER_IO =104, /**new chiptest board */ + V_POWER_CHIP=105 ,/**new chiptest board */ + I_POWER_A=106 , /**new chiptest board */ + I_POWER_B=107 , /**new chiptest board */ + I_POWER_C=108 , /**new chiptest board */ + I_POWER_D=109 , /**new chiptest board */ + I_POWER_IO=110 , /**new chiptest board */ + V_LIMIT=111 /**new chiptest board */ +}; + +/** + detector settings indexes +*/ +enum detectorSettings{ + GET_SETTINGS=-1, /**< return current detector settings */ + STANDARD, /**< standard settings */ + FAST, /**< fast settings */ + HIGHGAIN, /**< highgain settings */ + DYNAMICGAIN, /**< dynamic gain settings */ + LOWGAIN, /**< low gain settings */ + MEDIUMGAIN, /**< medium gain settings */ + VERYHIGHGAIN, /**< very high gain settings */ + LOWNOISE, /**< low noise settings */ + DYNAMICHG0, /**< dynamic high gain 0 */ + FIXGAIN1, /**< fix gain 1 */ + FIXGAIN2, /**< fix gain 2 */ + FORCESWITCHG1, /**< force switch gain 1 */ + FORCESWITCHG2, /**< force switch gain 2 */ + VERYLOWGAIN, /**< very low gain settings */ + UNDEFINED=200, /**< undefined or custom settings */ + UNINITIALIZED /**< uninitialiazed (status at startup) */ +}; +/** + meaning of the channel register bits + \see ::sls_detector_channel +*/ +enum channelRegisterBit { + TRIMBIT_OFF=0, /**< offset of trimbit value in the channel register */ + COMPARATOR_ENABLE=0x100, /**< mask of the comparator enable bit */ + ANALOG_SIGNAL_ENABLE=0x200, /**< mask of the analogue output enable bit */ + CALIBRATION_ENABLE=0x300, /**< mask of the calibration input enable bit */ +}; + +#define TRIMBITMASK 0x3f +/** + meaning of the chip register bits + \see ::sls_detector_chip +*/ +enum chipRegisterBit { + ENABLE_ANALOG_OUTPUT=0x1, /**< mask of the analogue output enable bit */ + CHIP_OUTPUT_WIDTH=0x2 /**< mask of the chip output width */ +}; +/** + meaning of the module register bits +*/ +enum moduleRegisterBit { + MY_MODULE_REGISTER_BIT, /**< possible module register bit meaning */ + MODULE_OUTPUT_WIDTH /**< possibly module dynamic range */ +}; + + +/** + important speed parameters +*/ +enum speedVariable { + CLOCK_DIVIDER, /**< readout clock divider */ + WAIT_STATES, /**< wait states for bus read */ + TOT_CLOCK_DIVIDER, /**< wait states for bus read */ + TOT_DUTY_CYCLE, /**< wait states for bus read */ + SET_SIGNAL_LENGTH, /**< set/clear signal length */ + PHASE_SHIFT, /**< adds phase shift */ + OVERSAMPLING, /**< oversampling for analog detectors */ + ADC_CLOCK, /**< adc clock divider */ + ADC_PHASE, /**< adc clock phase */ + ADC_PIPELINE, /**< adc pipeline */ + DBIT_CLOCK, /**< adc clock divider */ + DBIT_PHASE, /**< adc clock phase */ + DBIT_PIPELINE /**< adc pipeline */ +}; + + +/** + readout flags +*/ +enum readOutFlags { + GET_READOUT_FLAGS=-1, /**< return readout flags */ + NORMAL_READOUT=0, /**< no flag */ + STORE_IN_RAM=0x1, /**< data are stored in ram and sent only after end of acquisition for faster frame rate */ + READ_HITS=0x2, /**< return only the number of the channel which counted ate least one */ + ZERO_COMPRESSION=0x4,/**< returned data are 0-compressed */ + PUMP_PROBE_MODE=0x8,/** Date: Fri, 19 Jan 2018 16:05:15 +0100 Subject: [PATCH 10/10] eiger manual --- manual/manual-client/Eiger_short.tex | 312 ++++++++++++++------------- 1 file changed, 165 insertions(+), 147 deletions(-) diff --git a/manual/manual-client/Eiger_short.tex b/manual/manual-client/Eiger_short.tex index ee13cc1d7..d133b7730 100644 --- a/manual/manual-client/Eiger_short.tex +++ b/manual/manual-client/Eiger_short.tex @@ -71,9 +71,6 @@ Here is an explanation of the LED color scheme of the bchip100: \end{itemize} You can also Check temperatures and water flow in a browser (from the same subnet where the 9M is: http://bchip100/status.cgi - - - \subsection{Mandatory setup - Receiver} The receiver is a process run on a PC closely connected to the detector. Open one receiver for every half module board (remember, a module has two receivers!!!) . Go to {\tt{slsDetectorsPackage/bin/}}, \textbf{slsReceiver} should be started on the machine expected to receive the data from the detector. @@ -85,9 +82,17 @@ The receiver is a process run on a PC closely connected to the detector. Open on where xxxx, yyyy are the tcp port numbers. Use 1955 and 1956 for example. Note that in older version of the software {\tt{--mode 1}} was used only for the ``bottom'' half module. Now, the receiver for the bottom is open without arguments anymore, but still in the configuration file one needs to write {\tt{n:flippeddatax 1}}, where {\tt{n}} indicated the half module number, 1 if it is a module. \\ Open as many receiver as half module boards. A single module has two half module boards. +From the software version 3.0.1, one can decide weather start a zmq callback from the receiver to the client (for example to visualize data in the slsDetectorGui or another gui). If the zmq steam is not required (cased of the command line for example, one can switch off the streaming with {\tt{./sls\_detector\_put rx\_datastream 0}}, enable it with {\tt{./sls\_detector\_put rx\_datastream 1}}. In the case of inizialising the stream to use the slsDetectorGui, nothing needs to be taken care of by the user. If instead you want to stream the streaming on different channels, the zmq port of the client can be set stealing from the slsDetectorGui stream having {\tt{./sls\_detector\_put n:zmqport 300y}}, where n is each half module independently, matching the receiver stream {\tt{./sls\_detector\_put n:rx\_zmqport 300y}}. + + +There is an example code that can be compiled in {\tt{manual/manual-api/mainReceiver.cpp}} and gives the executable {\tt{./detReceiver}}, use it with two or more receivers to open all receivers in one single terminal: {\tt{./detReceiver startTCPPort numReceivers withCallback}}, where startTCPPort assumes the other ports are consecutively increased. + + + + \subsection{Mandatory setup - Client} -\underline{In the case of cSAXS, the detector software is installed on the x12sa-ed-1 machine:}\\ +\underline{In the case of cSAXS, the detector software is installed on:}\\ \underline{/sls/X12SA/data/x12saop/EigerPackage/slsDetectorsPackage} The command line interface consists in these main functions: @@ -97,7 +102,7 @@ The command line interface consists in these main functions: \item[sls\_detector\_get] to retrieve detector parameters \end{description} -First, your detector should always be configured for each PC that you might want to use for controlling the detector. All the examples given here show the command {\tt{0-}}, which could be omitted for the EIGER system $0$. In the case more EIGER systems are controlled at once, the call of {\tt{1-}},.. becomes compulsory. +First, your detector should always be configured for each PC that you might want to use for controlling the detector. All the examples given here show the command {\tt{0-}}, which could be omitted for the EIGER system $0$. In the case more EIGER systems are controlled at once, the call of {\tt{1-}},.. becomes compulsory. To make sure the shared memory is cleaned, before starting, one should do: \begin{verbatim} @@ -120,6 +125,7 @@ hostname beb059+beb058+ #1Gb detector hostname for controls 1:rx_udpport2 50014 #udp port second quadrant, second halfmodule rx_hostname x12sa-vcons #1Gb receiver pc hostname outdir /sls/X12SA/data/x12saop/Data10/Eiger0.5M +threaded 1 \end{verbatim} In the config file, if client, receiver and detector commands are on 1Gb, but detector data to receiver are sent using \textbf{10GbE} the following lines are mandatory (see slsDetectorsPackage/examples/eiger\_10Gb.config): @@ -139,8 +145,17 @@ hostname beb059+beb058+ #1Gb detector hostname for controls 1:detectorip 10.0.40.101 #second half module 10 Gb IP rx_hostname x12sa-vcons #1Gb receiver pc hostname outdir /sls/X12SA/data/x12saop/Data10/Eiger0.5M +threaded 1 \end{verbatim} + +In the case you are developing your own receiver, then you need to remove the 1Gb receiver hostname {\tt{rx\_hostname}} and substitute it with the mac address of the device: +\begin{verbatim} +configuremac 0 +rx_udpmac xx:xx:... +\end{verbatim} + + One can configure all the detector settings in a parameter file {\tt{setup.det}}, which is loaded by doing: \begin{verbatim} sls_detector_put 0-parameters setup.det @@ -186,7 +201,7 @@ The first line requires to specify how many ({\tt{N}}) and at which energies in NORMALLY, in this new calibration scheme, only {\tt{settings standard}} will be provided to you, unless specific cases to be discussed. The threshold at 6000 eV , for example would be set as:{\tt{sls\_detector\_put 0-threshold 6000}}. -We have added a special command, {\tt{thresholdnotb}}, which allows to scan the threshold energy without reloading the trimbits at every stage. One cain either keep the trimbits at a specific value (es.32 if the range of energies to scan is large) or use the trimbits from a specific energy (like a central energy). +We have added a special command, {\tt{thresholdnotb}}, which allows to scan the threshold energy without reloading the trimbits at every stage. One can either keep the trimbits at a specific value (es.32 if the range of energies to scan is large) or use the trimbits from a specific energy (like a central energy). \begin{verbatim} sls_detector_put 0-thresholdnotb energy_in_eV \end{verbatim} @@ -440,150 +455,10 @@ If \textbf{dr} is 32 and \textbf{clkdivider} is not 2, whatever the detector get \item If the variable \textbf{frames} is greater than what the memory can store (table~\ref{timgs}) and the frame rate exceed the continuos streaming (table~\ref{tcont}), limits on the maximum number of images need to be implemented if the period is lower than the one listed in table~\ref{tcont}. Check table~\ref{tframes} to see the different cases. \item Running at a speed that does not support the frame rate you are asking: see table~\ref{tframes} to check if the frame rate (\textbf{period}) you are asking is compatible with the \textbf{clkdivider} you are asking. \item Running at a redout time that does not support the frame rate you are asking. Check table~\ref{tframes} to check if the frame rate (\textbf{period}) you are asking is compatible with the \textbf{flags} you are asking. -\item The minimum allowed value for \textbf{epttime} should be 10~$\mu$s. +\item The minimum allowed value for \textbf{exptime} should be 10~$\mu$s. \item By default the {\textbf{subexptime}} is set to 2.621440~ms. Values smaller than 500~$\mu$s do not make sense. The maximum value is 5.2~s. This limits should be checked. \end{enumerate} -\section{Client checks - command line} - -Guide on returned strings: -\begin{enumerate} -\item \begin{verbatim} -sls_detector_get free -\end{verbatim} -Returns a list of shared memories cleaned (variable number depending on detector): -\begin{verbatim} -Shared memory 273612805 deleted -Shared memory 276922374 deleted -Shared memory 270270468 deleted -free freed -\end{verbatim} -Note that occasionally if there is a shared memory of a different size (from an older software version), it will return also a line like this: -\begin{verbatim} -*** shmget error (server) ***-1 -\end{verbatim} -This needs to be cleaned with {\tt{ipcs -m}} and then {\tt{ipcrm -M xxx}}, where xxx are the keys with nattch 0. -\item \begin{verbatim}sls_detector_get settings -settings standard -\end{verbatim} -{\tt{standard}} is only if correct. {\tt{undefined}} or anything else is wrong. - -\item \begin{verbatim} -sls_detector_get threshold -threshold xxxx -\end{verbatim} -Returns a string (xxxx) that can be interpreted as the threshold in eV. If it fails to set it, returns the last threshold it was set (which the detector still has). If settings are not defined or different trimbits are chosen, it will return "undefined". - -\item \begin{verbatim} -sls_detector_get fname -fname string -\end{verbatim} - -\item \begin{verbatim} -sls_detector_get exptime -exptime number -\end{verbatim} -where {\tt{number}} is a string to be interpreted as a float in (s). - -\item \begin{verbatim} -sls_detector_get period -period number -\end{verbatim} -where {\tt{nuymber}} is a string to be interpreted as a float in (s). - -\item \begin{verbatim} -sls_detector_get frames -frames number -\end{verbatim} -where {\tt{number}} is a string to be interpreted as an integer. - -\item \begin{verbatim} -sls_detector_get cycles -cycles number -\end{verbatim} -where {\tt{number}} is a string to be interpreted as an integer. - -\item \begin{verbatim} -sls_detector_get status -status string -\end{verbatim} -where {\tt{string}} can be {\tt{idle}} or {\tt{running}}. - -\item \begin{verbatim} -sls_detector_get index -status number -\end{verbatim} -where {\tt{number}} is a string to be interpreted as an integer. - -\item \begin{verbatim} -sls_detector_get dr -dr number -\end{verbatim} -where {\tt{number}} is a string that should be interpreted as an integer (4/8/16/32). - -\item \begin{verbatim} -sls_detector_get clkdivider -clkdivider number -\end{verbatim} -where {\tt{number}} is a string that should be interpreted as an integer (0/1/2/3). - -\item \begin{verbatim} -sls_detector_get flags -flags string1 string2 -\end{verbatim} -where {\tt{string1}} is a string should be always {\tt{continous}} and {\tt{string2}} can be either {\tt{nonparallel}} or {\tt{parallel}}. - -\item \begin{verbatim} -sls_detector_get timing -timing string -\end{verbatim} -where {\tt{string}} is a string which can be {\tt{auto/trigger/burst\_trigger/gating}}. - -\item \begin{verbatim} -sls_detector_get enablefwrite -enablefwrite number -\end{verbatim} -where {\tt{number}} is a string which should be interpreted as an integer "0" or "1". - -\item \begin{verbatim} -sls_detector_get framescaught -framescaught number -\end{verbatim} -where {\tt{number}} is a string which should be interpreted as an integer of the complete frames got by the receiver. - -\item \begin{verbatim} -sls_detector_get frameindex -frameindex number -\end{verbatim} -where {\tt{number}} is a string which should be interpreted as an integer of the last frame number read from firmware. It comes from the receiver, though and reset after every acquisition series. - -\item \begin{verbatim} -sls_detector_get subexptime -subexptime number -\end{verbatim} -where {\tt{number}} is a string that should be interpreted as a float in s. The default value is 0.002621440. - -\item \begin{verbatim} -sls_detector_get ratecorr -ratecorr number -\end{verbatim} -where {\tt{number}} is a string that should be interpreted as a float in s. 0.000000 means correction off. Values above zero are the value of $\tau$ in ns. - -\item \begin{verbatim} -sls_detector_get vhighvoltage -vhighvoltage number -\end{verbatim} -where {\tt{number}} is a string that should be interpreted as an int and for proper Eiger setting is approximately 150~V if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:vhighvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned. - -\item \begin{verbatim} -sls_detector_get busy -busy number -\end{verbatim} -where {\tt{number}} is a string that should be interpreted as an int for 0/1 meaning no/yes. This command tells if the sharedmemory has in memory that an acquisition has been started or not. It should allows to use the non blocking acquire, regardless of any delay to the detector getting into 'running' mode. - - -\end{enumerate} - \section{1Gb/s, 10Gb/s links} \subsection{Checking the 1Gb/s, 10Gb/s physical links}\label{led} @@ -1009,5 +884,148 @@ Scroll up in the terminal till you find:\\ + +\section{Client checks - command line} + +Guide on returned strings: +\begin{enumerate} +\item \begin{verbatim} +sls_detector_get free +\end{verbatim} +Returns a list of shared memories cleaned (variable number depending on detector): +\begin{verbatim} +Shared memory 273612805 deleted +Shared memory 276922374 deleted +Shared memory 270270468 deleted +free freed +\end{verbatim} +Note that occasionally if there is a shared memory of a different size (from an older software version), it will return also a line like this: +\begin{verbatim} +*** shmget error (server) ***-1 +\end{verbatim} +This needs to be cleaned with {\tt{ipcs -m}} and then {\tt{ipcrm -M xxx}}, where xxx are the keys with nattch 0. +\item \begin{verbatim}sls_detector_get settings +settings standard +\end{verbatim} +{\tt{standard}} is only if correct. {\tt{undefined}} or anything else is wrong. + +\item \begin{verbatim} +sls_detector_get threshold +threshold xxxx +\end{verbatim} +Returns a string (xxxx) that can be interpreted as the threshold in eV. If it fails to set it, returns the last threshold it was set (which the detector still has). If settings are not defined or different trimbits are chosen, it will return "undefined". + +\item \begin{verbatim} +sls_detector_get fname +fname string +\end{verbatim} + +\item \begin{verbatim} +sls_detector_get exptime +exptime number +\end{verbatim} +where {\tt{number}} is a string to be interpreted as a float in (s). + +\item \begin{verbatim} +sls_detector_get period +period number +\end{verbatim} +where {\tt{nuymber}} is a string to be interpreted as a float in (s). + +\item \begin{verbatim} +sls_detector_get frames +frames number +\end{verbatim} +where {\tt{number}} is a string to be interpreted as an integer. + +\item \begin{verbatim} +sls_detector_get cycles +cycles number +\end{verbatim} +where {\tt{number}} is a string to be interpreted as an integer. + +\item \begin{verbatim} +sls_detector_get status +status string +\end{verbatim} +where {\tt{string}} can be {\tt{idle}} or {\tt{running}}. + +\item \begin{verbatim} +sls_detector_get index +status number +\end{verbatim} +where {\tt{number}} is a string to be interpreted as an integer. + +\item \begin{verbatim} +sls_detector_get dr +dr number +\end{verbatim} +where {\tt{number}} is a string that should be interpreted as an integer (4/8/16/32). + +\item \begin{verbatim} +sls_detector_get clkdivider +clkdivider number +\end{verbatim} +where {\tt{number}} is a string that should be interpreted as an integer (0/1/2/3). + +\item \begin{verbatim} +sls_detector_get flags +flags string1 string2 +\end{verbatim} +where {\tt{string1}} is a string should be always {\tt{continous}} and {\tt{string2}} can be either {\tt{nonparallel}} or {\tt{parallel}}. + +\item \begin{verbatim} +sls_detector_get timing +timing string +\end{verbatim} +where {\tt{string}} is a string which can be {\tt{auto/trigger/burst\_trigger/gating}}. + +\item \begin{verbatim} +sls_detector_get enablefwrite +enablefwrite number +\end{verbatim} +where {\tt{number}} is a string which should be interpreted as an integer "0" or "1". + +\item \begin{verbatim} +sls_detector_get framescaught +framescaught number +\end{verbatim} +where {\tt{number}} is a string which should be interpreted as an integer of the complete frames got by the receiver. + +\item \begin{verbatim} +sls_detector_get frameindex +frameindex number +\end{verbatim} +where {\tt{number}} is a string which should be interpreted as an integer of the last frame number read from firmware. It comes from the receiver, though and reset after every acquisition series. + +\item \begin{verbatim} +sls_detector_get subexptime +subexptime number +\end{verbatim} +where {\tt{number}} is a string that should be interpreted as a float in s. The default value is 0.002621440. + +\item \begin{verbatim} +sls_detector_get ratecorr +ratecorr number +\end{verbatim} +where {\tt{number}} is a string that should be interpreted as a float in s. 0.000000 means correction off. Values above zero are the value of $\tau$ in ns. + +\item \begin{verbatim} +sls_detector_get vhighvoltage +vhighvoltage number +\end{verbatim} +where {\tt{number}} is a string that should be interpreted as an int and for proper Eiger setting is approximately 150~V if it is correctly set. If two master modules are presents (multi systems), the average is returned (still to be tested). If one asks for the individual $n$ half module bias voltage through {\tt{sls\_detector\_get n:vhighvoltage}}, if the $n$ module is a master, the actual voltage will be returned. If it is a slave, -999 will be returned. + +\item \begin{verbatim} +sls_detector_get busy +busy number +\end{verbatim} +where {\tt{number}} is a string that should be interpreted as an int for 0/1 meaning no/yes. This command tells if the sharedmemory has in memory that an acquisition has been started or not. It should allows to use the non blocking acquire, regardless of any delay to the detector getting into 'running' mode. + + +\end{enumerate} + + + \end{document}