From 5f94b5c246e6db0217f26d9cc65ac5494c2fc958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20Andr=C3=A4?= <33870994+MarieAndrae@users.noreply.github.com> Date: Mon, 7 Oct 2019 12:13:25 +0200 Subject: [PATCH 1/3] Dac (#67) * dac WIP * dacs WIP * DACs are working with names * namechanges of vrfsh->vshaper, vrfshnpol->vshaperneg * pattern for MY3, configure MAC for MY3 --- .../mythen3DetectorServer/CMakeLists.txt | 1 + .../mythen3DetectorServer/Makefile | 4 +- .../mythen3DetectorServer/RegisterDefs.h | 146 +++++---- .../bin/mythen3DetectorServer_developer | Bin 97344 -> 114332 bytes .../slsDetectorFunctionList.c | 310 +++++++++++++++++- .../slsDetectorServer_defs.h | 73 +++-- .../slsDetectorServer/include/DAC6571.h | 1 - .../include/LTC2620_Driver.h | 43 +++ .../include/slsDetectorFunctionList.h | 8 +- .../slsDetectorServer/src/LTC2620_Driver.c | 90 +++++ .../src/slsDetectorServer_funcs.c | 53 ++- .../src/slsDetectorCommand.cpp | 83 +++-- slsSupportLib/include/sls_detector_defs.h | 2 - slsSupportLib/include/versionAPI.h | 2 +- 14 files changed, 665 insertions(+), 151 deletions(-) create mode 100755 slsDetectorServers/slsDetectorServer/include/LTC2620_Driver.h create mode 100755 slsDetectorServers/slsDetectorServer/src/LTC2620_Driver.c diff --git a/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt b/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt index dbfef1518..883f21614 100644 --- a/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt +++ b/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt @@ -7,6 +7,7 @@ add_executable(mythen3DetectorServer_virtual ../slsDetectorServer/src/communication_funcs_UDP.c ../slsDetectorServer/src/DAC6571.c ../slsDetectorServer/src/common.c + ../slsDetectorServer/src/LTC2620_Driver.c ) include_directories( diff --git a/slsDetectorServers/mythen3DetectorServer/Makefile b/slsDetectorServers/mythen3DetectorServer/Makefile index 8a18b66e9..70c908db0 100755 --- a/slsDetectorServers/mythen3DetectorServer/Makefile +++ b/slsDetectorServers/mythen3DetectorServer/Makefile @@ -5,14 +5,14 @@ support_lib = ../../slsSupportLib/include/ CROSS = nios2-buildroot-linux-gnu- CC = $(CROSS)gcc -CFLAGS += -Wall -DMYTHEN3D -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir)#-DVERBOSEI #-DVERBOSE +CFLAGS += -Wall -DMYTHEN3D -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir) -DDEBUG1 #-DVERBOSEI #-DVERBOSE LDLIBS += -lm PROGS = mythen3DetectorServer DESTDIR ?= bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c -SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)DAC6571.c $(main_src)common.c +SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)DAC6571.c $(main_src)common.c $(main_src)LTC2620_Driver.c OBJS = $(SRCS:.c=.o) diff --git a/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h b/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h index 711191582..e0d9f9e3e 100644 --- a/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h +++ b/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h @@ -2,14 +2,19 @@ #pragma once /* Definitions for FPGA*/ - +#define REG_OFFSET (4) #define BASE_CONTROL (0x0) -#define BASE_PATTERN_CONTROL (0x200 ) -#define BASE_PATTERN_RAM (0x10000 ) +#define BASE_PATTERN_CONTROL (0x200) +#define BASE_PATTERN_RAM (0x10000) + +#define BASE_UDP_RAM (0x1000) // fix it /* Basic detector FPGA registers --------------------------------------------------*/ +/* Module Control Board Serial Number Register */ +#define MCB_SERIAL_NO_REG (0x000 * REG_OFFSET + BASE_CONTROL) + /* FPGA Version register */ -#define FPGA_VERSION_REG (0x04 + BASE_CONTROL) +#define FPGA_VERSION_REG (0x001 * REG_OFFSET + BASE_CONTROL) #define FPGA_COMPILATION_DATE_OFST (0) #define FPGA_COMPILATION_DATE_MSK (0x00FFFFFF << FPGA_COMPILATION_DATE_OFST) @@ -17,64 +22,67 @@ #define DETECTOR_TYPE_MSK (0x000000FF << DETECTOR_TYPE_OFST) -/* Module Control Board Serial Number Register */ -#define MCB_SERIAL_NO_REG (0x00 + BASE_CONTROL) - /* API Version Register */ -#define API_VERSION_REG (0x08 + BASE_CONTROL) +#define API_VERSION_REG (0x002 * REG_OFFSET + BASE_CONTROL) + +#define API_VERSION_OFST (0) +#define API_VERSION_MSK (0x00FFFFFF << API_VERSION_OFST) +#define API_VERSION_DETECTOR_TYPE_OFST (24) //Not used in software +#define API_VERSION_DETECTOR_TYPE_MSK (0x000000FF << API_VERSION_DETECTOR_TYPE_OFST) //Not used in software /* Fix pattern register */ -#define FIX_PATT_REG (0x0C + BASE_CONTROL) +#define FIX_PATT_REG (0x003 * REG_OFFSET + BASE_CONTROL) #define FIX_PATT_VAL (0xACDC2019) /* Status register */ -#define STATUS_REG (0x10 + BASE_CONTROL) +#define STATUS_REG (0x004 * REG_OFFSET + BASE_CONTROL) #ifdef VIRTUAL // until firmware is ready ---------------------------------- #define RUN_BUSY_OFST (0) #define RUN_BUSY_MSK (0x00000001 << RUN_BUSY_OFST) #endif -/* Look at me register */ -#define LOOK_AT_ME_REG (0x14 + BASE_CONTROL) //Not used in firmware or software, good to play with +/* Look at me register, read only */ +#define LOOK_AT_ME_REG (0x005 * REG_OFFSET + BASE_CONTROL) //Not used in firmware or software, good to play with +#define DTA_OFFSET_REG (0x104 * REG_OFFSET + BASE_CONTROL) /* Pattern Control FPGA registers --------------------------------------------------*/ /* Pattern status Register*/ -#define PAT_STATUS_REG (0x00 + BASE_PATTERN_CONTROL) +#define PAT_STATUS_REG (0x000 * REG_OFFSET + BASE_PATTERN_CONTROL) /* Delay left 64bit Register */ -#define GET_DELAY_LSB_REG (0x08 + BASE_PATTERN_CONTROL) -#define GET_DELAY_MSB_REG (0x0C + BASE_PATTERN_CONTROL) +#define GET_DELAY_LSB_REG (0x0002 * REG_OFFSET + BASE_PATTERN_CONTROL) +#define GET_DELAY_MSB_REG (0x0003 * REG_OFFSET + BASE_PATTERN_CONTROL) /* Cycles left 64bit Register */ -#define GET_CYCLES_LSB_REG (0x10 + BASE_PATTERN_CONTROL) -#define GET_CYCLES_MSB_REG (0x14 + BASE_PATTERN_CONTROL) +#define GET_CYCLES_LSB_REG (0x0004 * REG_OFFSET + BASE_PATTERN_CONTROL) +#define GET_CYCLES_MSB_REG (0x0005 * REG_OFFSET + BASE_PATTERN_CONTROL) /* Frames left 64bit Register */ -#define GET_FRAMES_LSB_REG (0x18 + BASE_PATTERN_CONTROL) -#define GET_FRAMES_MSB_REG (0x1C + BASE_PATTERN_CONTROL) +#define GET_FRAMES_LSB_REG (0x0006 * REG_OFFSET + BASE_PATTERN_CONTROL) +#define GET_FRAMES_MSB_REG (0x0007 * REG_OFFSET + BASE_PATTERN_CONTROL) /* Period left 64bit Register */ -#define GET_PERIOD_LSB_REG (0x20 + BASE_PATTERN_CONTROL) -#define GET_PERIOD_MSB_REG (0x24 + BASE_PATTERN_CONTROL) +#define GET_PERIOD_LSB_REG (0x0008 * REG_OFFSET + BASE_PATTERN_CONTROL) +#define GET_PERIOD_MSB_REG (0x0009 * REG_OFFSET + BASE_PATTERN_CONTROL) /* Delay 64bit Write-register */ -#define SET_DELAY_LSB_REG (0x88 + BASE_PATTERN_CONTROL) -#define SET_DELAY_MSB_REG (0x8C + BASE_PATTERN_CONTROL) +#define SET_DELAY_LSB_REG (0x0102 * REG_OFFSET + BASE_PATTERN_CONTROL) +#define SET_DELAY_MSB_REG (0x0103 * REG_OFFSET + BASE_PATTERN_CONTROL) /* Cylces 64bit Write-register */ -#define SET_CYCLES_LSB_REG (0x90 + BASE_PATTERN_CONTROL) -#define SET_CYCLES_MSB_REG (0x94 + BASE_PATTERN_CONTROL) +#define SET_CYCLES_LSB_REG (0x0104 * REG_OFFSET + BASE_PATTERN_CONTROL) +#define SET_CYCLES_MSB_REG (0x0105 * REG_OFFSET + BASE_PATTERN_CONTROL) /* Frames 64bit Write-register */ -#define SET_FRAMES_LSB_REG (0x98 + BASE_PATTERN_CONTROL) -#define SET_FRAMES_MSB_REG (0x9C + BASE_PATTERN_CONTROL) +#define SET_FRAMES_LSB_REG (0x0106 * REG_OFFSET + BASE_PATTERN_CONTROL) +#define SET_FRAMES_MSB_REG (0x0107 * REG_OFFSET + BASE_PATTERN_CONTROL) /* Period 64bit Write-register */ -#define SET_PERIOD_LSB_REG (0xA0 + BASE_PATTERN_CONTROL) -#define SET_PERIOD_MSB_REG (0xA4 + BASE_PATTERN_CONTROL) +#define SET_PERIOD_LSB_REG (0x0108 * REG_OFFSET + BASE_PATTERN_CONTROL) +#define SET_PERIOD_MSB_REG (0x0109 * REG_OFFSET + BASE_PATTERN_CONTROL) /* Pattern Control FPGA registers --------------------------------------------------*/ @@ -85,76 +93,78 @@ // #define PATTERN_IO_CNTRL_MSB_REG (0x8C + BASE_CONTROL) /* Pattern Limit RW Register */ -#define PATTERN_LIMIT_REG (0x100 + BASE_PATTERN_CONTROL) +#define PATTERN_LIMIT_REG (0x1000 * REG_OFFSET + BASE_PATTERN_CONTROL) #define PATTERN_LIMIT_STRT_OFST (0) #define PATTERN_LIMIT_STRT_MSK (0x00001FFF << PATTERN_LIMIT_STRT_OFST) #define PATTERN_LIMIT_STP_OFST (16) #define PATTERN_LIMIT_STP_MSK (0x00001FFF << PATTERN_LIMIT_STP_OFST) +/* Pattern Wait Timer 0 64bit RW Register */ +#define PATTERN_WAIT_TIMER_0_LSB_REG (0x1100 * REG_OFFSET + BASE_PATTERN_CONTROL) +#define PATTERN_WAIT_TIMER_0_MSB_REG (0x1101 * REG_OFFSET + BASE_PATTERN_CONTROL) + /* Pattern Wait 0 RW Register*/ -#define PATTERN_WAIT_0_ADDR_REG (0x188 + BASE_PATTERN_CONTROL) +#define PATTERN_WAIT_0_ADDR_REG (0x1102 * REG_OFFSET + BASE_PATTERN_CONTROL) #define PATTERN_WAIT_0_ADDR_OFST (0) #define PATTERN_WAIT_0_ADDR_MSK (0x00001FFF << PATTERN_WAIT_0_ADDR_OFST) -/* Pattern Wait 1 RW Register*/ -#define PATTERN_WAIT_1_ADDR_REG (0x19C + BASE_PATTERN_CONTROL) - -#define PATTERN_WAIT_1_ADDR_OFST (0) -#define PATTERN_WAIT_1_ADDR_MSK (0x00001FFF << PATTERN_WAIT_1_ADDR_OFST) - -/* Pattern Wait 2 RW Register*/ -#define PATTERN_WAIT_2_ADDR_REG (0x1B0 + BASE_PATTERN_CONTROL) - -#define PATTERN_WAIT_2_ADDR_OFST (0) -#define PATTERN_WAIT_2_ADDR_MSK (0x00001FFF << PATTERN_WAIT_2_ADDR_OFST) - -/* Pattern Wait Timer 0 64bit RW Register */ -#define PATTERN_WAIT_TIMER_0_LSB_REG (0x180 + BASE_PATTERN_CONTROL) -#define PATTERN_WAIT_TIMER_0_MSB_REG (0x184 + BASE_PATTERN_CONTROL) - -/* Pattern Wait Timer 1 64bit RW Register */ -#define PATTERN_WAIT_TIMER_1_LSB_REG (0x194 + BASE_PATTERN_CONTROL) -#define PATTERN_WAIT_TIMER_1_MSB_REG (0x198 + BASE_PATTERN_CONTROL) - -/* Pattern Wait Timer 2 64bit RW Register */ -#define PATTERN_WAIT_TIMER_2_LSB_REG (0x1A8 + BASE_PATTERN_CONTROL) -#define PATTERN_WAIT_TIMER_2_MSB_REG (0x1AC + BASE_PATTERN_CONTROL) +/* Pattern Loop 0 Iteration RW Register */ +#define PATTERN_LOOP_0_ITERATION_REG (0x1103 * REG_OFFSET + BASE_PATTERN_CONTROL) // patnloop /* Pattern Loop 0 Address RW Register */ -#define PATTERN_LOOP_0_ADDR_REG (0x190 + BASE_PATTERN_CONTROL) +#define PATTERN_LOOP_0_ADDR_REG (0x1104 * REG_OFFSET + BASE_PATTERN_CONTROL) #define PATTERN_LOOP_0_ADDR_STRT_OFST (0) #define PATTERN_LOOP_0_ADDR_STRT_MSK (0x00001FFF << PATTERN_LOOP_0_ADDR_STRT_OFST) #define PATTERN_LOOP_0_ADDR_STP_OFST (16) #define PATTERN_LOOP_0_ADDR_STP_MSK (0x00001FFF << PATTERN_LOOP_0_ADDR_STP_OFST) + +/* Pattern Wait Timer 1 64bit RW Register */ +#define PATTERN_WAIT_TIMER_1_LSB_REG (0x1105 * REG_OFFSET + BASE_PATTERN_CONTROL) +#define PATTERN_WAIT_TIMER_1_MSB_REG (0x1106 * REG_OFFSET + BASE_PATTERN_CONTROL) + +/* Pattern Wait 1 RW Register*/ +#define PATTERN_WAIT_1_ADDR_REG (0x1107 * REG_OFFSET + BASE_PATTERN_CONTROL) + +#define PATTERN_WAIT_1_ADDR_OFST (0) +#define PATTERN_WAIT_1_ADDR_MSK (0x00001FFF << PATTERN_WAIT_1_ADDR_OFST) + +/* Pattern Loop 1 Iteration RW Register */ +#define PATTERN_LOOP_1_ITERATION_REG (0x1108 * REG_OFFSET + BASE_PATTERN_CONTROL) // patnloop + /* Pattern Loop 1 Address RW Register */ -#define PATTERN_LOOP_1_ADDR_REG (0x1A4 + BASE_PATTERN_CONTROL) +#define PATTERN_LOOP_1_ADDR_REG (0x1109 * REG_OFFSET + BASE_PATTERN_CONTROL) #define PATTERN_LOOP_1_ADDR_STRT_OFST (0) #define PATTERN_LOOP_1_ADDR_STRT_MSK (0x00001FFF << PATTERN_LOOP_1_ADDR_STRT_OFST) #define PATTERN_LOOP_1_ADDR_STP_OFST (16) #define PATTERN_LOOP_1_ADDR_STP_MSK (0x00001FFF << PATTERN_LOOP_1_ADDR_STP_OFST) + +/* Pattern Wait Timer 2 64bit RW Register */ +#define PATTERN_WAIT_TIMER_2_LSB_REG (0x110A * REG_OFFSET + BASE_PATTERN_CONTROL) +#define PATTERN_WAIT_TIMER_2_MSB_REG (0x110B * REG_OFFSET + BASE_PATTERN_CONTROL) + +/* Pattern Wait 2 RW Register*/ +#define PATTERN_WAIT_2_ADDR_REG (0x110C * REG_OFFSET + BASE_PATTERN_CONTROL) + +#define PATTERN_WAIT_2_ADDR_OFST (0) +#define PATTERN_WAIT_2_ADDR_MSK (0x00001FFF << PATTERN_WAIT_2_ADDR_OFST) + +/* Pattern Loop 2 Iteration RW Register */ +#define PATTERN_LOOP_2_ITERATION_REG (0x110D * REG_OFFSET + BASE_PATTERN_CONTROL) // patnloop + /* Pattern Loop 0 Address RW Register */ -#define PATTERN_LOOP_2_ADDR_REG (0x1B8 + BASE_PATTERN_CONTROL) +#define PATTERN_LOOP_2_ADDR_REG (0x110E * REG_OFFSET + BASE_PATTERN_CONTROL) #define PATTERN_LOOP_2_ADDR_STRT_OFST (0) #define PATTERN_LOOP_2_ADDR_STRT_MSK (0x00001FFF << PATTERN_LOOP_2_ADDR_STRT_OFST) #define PATTERN_LOOP_2_ADDR_STP_OFST (16) #define PATTERN_LOOP_2_ADDR_STP_MSK (0x00001FFF << PATTERN_LOOP_2_ADDR_STP_OFST) -/* Pattern Loop 0 Iteration RW Register */ -#define PATTERN_LOOP_0_ITERATION_REG (0x18C + BASE_PATTERN_CONTROL) // patnloop - -/* Pattern Loop 1 Iteration RW Register */ -#define PATTERN_LOOP_1_ITERATION_REG (0x1A0 + BASE_PATTERN_CONTROL) // patnloop - -/* Pattern Loop 2 Iteration RW Register */ -#define PATTERN_LOOP_2_ITERATION_REG (0x1B4 + BASE_PATTERN_CONTROL) // patnloop - /* Register of first word */ -#define PATTERN_STEP0_LSB_REG (0x0 + BASE_PATTERN_RAM) -#define PATTERN_STEP0_MSB_REG (0x4 + BASE_PATTERN_RAM) +#define PATTERN_STEP0_LSB_REG (0x0 * REG_OFFSET + BASE_PATTERN_RAM) +#define PATTERN_STEP0_MSB_REG (0x1 * REG_OFFSET + BASE_PATTERN_RAM) diff --git a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer index 2b09a7d16df6fa2db151f67d660f54bca227295a..e3df5e373b4d78188ba49e67b3c2326586eb33fa 100755 GIT binary patch literal 114332 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%0DO28TZKOTVc@Wzd1_l%^iJSAOKE+582FZ-rM|p; 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 diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c index a7a9366cd..ee13f8102 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c @@ -3,6 +3,7 @@ #include "clogger.h" #include "nios.h" #include "DAC6571.h" +#include "LTC2620_Driver.h" #include "common.h" #include "RegisterDefs.h" @@ -36,6 +37,7 @@ int32_t clkPhase[NUM_CLOCKS] = {0, 0, 0}; uint32_t clkDivider[NUM_CLOCKS] = {125, 20, 80}; int highvoltage = 0; +int dacValues[NDAC] = {0}; int detPos[2] = {0, 0}; int isFirmwareCheckDone() { @@ -74,7 +76,7 @@ void basictests() { return; } // does check only if flag is 0 (by default), set by command line - if ((!debugflag) && ((testFpga() == FAIL))) { + if ((!debugflag) && ((testFpga() == FAIL)|| (testBus() == FAIL))) { strcpy(firmware_message, "Could not pass basic tests of FPGA and bus. Dangerous to continue.\n"); FILE_LOG(logERROR, ("%s\n\n", firmware_message)); @@ -82,19 +84,98 @@ void basictests() { firmware_check_done = 1; return; } + uint16_t hversion = getHardwareVersionNumber(); + uint32_t ipadd = getDetectorIP(); + uint64_t macadd = getDetectorMAC(); + int64_t fwversion = getDetectorId(DETECTOR_FIRMWARE_VERSION); + int64_t swversion = getDetectorId(DETECTOR_SOFTWARE_VERSION); + int64_t sw_fw_apiversion = 0; + int64_t client_sw_apiversion = getDetectorId(CLIENT_SOFTWARE_API_VERSION); + uint32_t requiredFirmwareVersion = REQRD_FRMWRE_VRSN; + + if (fwversion >= MIN_REQRD_VRSN_T_RD_API) + sw_fw_apiversion = getDetectorId(SOFTWARE_FIRMWARE_API_VERSION); + FILE_LOG(logINFOBLUE, ("************ Mythen3 Server *********************\n" + "Hardware Version:\t\t 0x%x\n" + + "Detector IP Addr:\t\t 0x%x\n" + "Detector MAC Addr:\t\t 0x%llx\n\n" + + "Firmware Version:\t\t 0x%llx\n" + "Software Version:\t\t 0x%llx\n" + "F/w-S/w API Version:\t\t 0x%llx\n" + "Required Firmware Version:\t 0x%x\n" + "Client-Software API Version:\t 0x%llx\n" + "********************************************************\n", + hversion, + ipadd, + (long long unsigned int)macadd, + (long long int)fwversion, + (long long int)swversion, + (long long int)sw_fw_apiversion, + requiredFirmwareVersion, + (long long int)client_sw_apiversion + )); + + // return if flag is not zero, debug mode + if (debugflag) { + firmware_check_done = 1; + return; + } + + + //cant read versions + FILE_LOG(logINFO, ("Testing Firmware-software compatibility:\n")); + if(!fwversion || !sw_fw_apiversion){ + strcpy(firmware_message, + "Cant read versions from FPGA. Please update firmware.\n"); + FILE_LOG(logERROR, (firmware_message)); + firmware_compatibility = FAIL; + firmware_check_done = 1; + return; + } + + //check for API compatibility - old server + if(sw_fw_apiversion > requiredFirmwareVersion){ + sprintf(firmware_message, + "This detector software software version (0x%llx) is incompatible.\n" + "Please update detector software (min. 0x%llx) to be compatible with this firmware.\n", + (long long int)sw_fw_apiversion, + (long long int)requiredFirmwareVersion); + FILE_LOG(logERROR, (firmware_message)); + firmware_compatibility = FAIL; + firmware_check_done = 1; + return; + } + + //check for firmware compatibility - old firmware + if( requiredFirmwareVersion > fwversion) { + sprintf(firmware_message, + "This firmware version (0x%llx) is incompatible.\n" + "Please update firmware (min. 0x%llx) to be compatible with this server.\n", + (long long int)fwversion, + (long long int)requiredFirmwareVersion); + FILE_LOG(logERROR, (firmware_message)); + firmware_compatibility = FAIL; + firmware_check_done = 1; + return; + } + FILE_LOG(logINFO, ("Compatibility - success\n")); + firmware_check_done = 1; #endif } + int checkType() { #ifdef VIRTUAL return OK; #endif volatile u_int32_t type = ((bus_r(FPGA_VERSION_REG) & DETECTOR_TYPE_MSK) >> DETECTOR_TYPE_OFST); if (type != MYTHEN3){ - FILE_LOG(logERROR, ("This is not a Mythen3 Server (read %d, expected %d)\n", type, MYTHEN3)); - return FAIL; - } + FILE_LOG(logERROR, ("This is not a Mythen3 Server (read %d, expected %d)\n", type, MYTHEN3)); + return FAIL; + } return OK; } @@ -117,6 +198,34 @@ int testFpga() { return ret; } +int testBus() { +#ifdef VIRTUAL + return OK; +#endif + FILE_LOG(logINFO, ("Testing Bus:\n")); + + int ret = OK; + u_int32_t addr = DTA_OFFSET_REG; + int times = 1000 * 1000; + int i = 0; + + for (i = 0; i < times; ++i) { + bus_w(addr, i * 100); + if (i * 100 != bus_r(addr)) { + FILE_LOG(logERROR, ("Mismatch! Wrote 0x%x, read 0x%x\n", + i * 100, bus_r(addr))); + ret = FAIL; + } + } + + bus_w(addr, 0); + + if (ret == OK) { + FILE_LOG(logINFO, ("Successfully tested bus %d times\n", times)); + } + return ret; +} + /* Ids */ int64_t getDetectorId(enum idMode arg){ @@ -141,21 +250,28 @@ u_int64_t getFirmwareVersion() { #ifdef VIRTUAL return 0; #endif - return 0; + return ((bus_r(FPGA_VERSION_REG) & FPGA_COMPILATION_DATE_MSK) >> FPGA_COMPILATION_DATE_OFST); } u_int64_t getFirmwareAPIVersion() { #ifdef VIRTUAL return 0; #endif + return ((bus_r(API_VERSION_REG) & API_VERSION_MSK) >> API_VERSION_OFST); +} + +u_int16_t getHardwareVersionNumber() { +#ifdef VIRTUAL return 0; +#endif + return bus_r(MCB_SERIAL_NO_REG); } u_int32_t getDetectorNumber(){ #ifdef VIRTUAL return 0; #endif - return 0; + return bus_r(MCB_SERIAL_NO_REG); } @@ -236,8 +352,11 @@ void setupDetector() { #ifndef VIRTUAL // hv DAC6571_SetDefines(HV_HARD_MAX_VOLTAGE, HV_DRIVER_FILE_NAME); + //dac + LTC2620_D_SetDefines(DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC); #endif setHighVoltage(DEFAULT_HIGH_VOLTAGE); + setDefaultDacs(); // Initialization of acquistion parameters setTimer(FRAME_NUMBER, DEFAULT_NUM_FRAMES); @@ -246,9 +365,23 @@ void setupDetector() { setTimer(ACQUISITION_TIME, DEFAULT_EXPTIME); setTimer(FRAME_PERIOD, DEFAULT_PERIOD); setTimer(DELAY_AFTER_TRIGGER, DEFAULT_DELAY_AFTER_TRIGGER); - } +int setDefaultDacs() { + int ret = OK; + FILE_LOG(logINFOBLUE, ("Setting Default Dac values\n")); + { + int i = 0; + const int defaultvals[NDAC] = DEFAULT_DAC_VALS; + for(i = 0; i < NDAC; ++i) { + // if not already default, set it to default + if (dacValues[i] != defaultvals[i]) { + setDAC((enum DACINDEX)i,defaultvals[i],0); + } + } + } + return ret; +} /* set parameters - dr, roi */ @@ -351,7 +484,8 @@ int validateTimer(enum timerIndex ind, int64_t val, int64_t retval) { default: break; } - return OK; + return OK; + } @@ -379,6 +513,44 @@ int64_t getTimeLeft(enum timerIndex ind){ return retval; } + +/* parameters - dac, hv */ +void setDAC(enum DACINDEX ind, int val, int mV) { + if (val < 0) + return; + + FILE_LOG(logDEBUG1, ("Setting dac[%d]: %d %s \n", (int)ind, val, (mV ? "mV" : "dac units"))); + int dacval = val; +#ifdef VIRTUAL + if (!mV) { + dacValues[ind] = val; + } + // convert to dac units + else if (LTC2620_D_VoltageToDac(val, &dacval) == OK) { + dacValues[ind] = dacval; + } +#else + if (LTC2620_D_SetDACValue((int)ind, val, mV, &dacval) == OK) { + dacValues[ind] = dacval; + } +#endif +} + +int getDAC(enum DACINDEX ind, int mV) { + if (!mV) { + FILE_LOG(logDEBUG1, ("Getting DAC %d : %d dac\n",ind, dacValues[ind])); + return dacValues[ind]; + } + int voltage = -1; + LTC2620_D_DacToVoltage(dacValues[ind], &voltage); + FILE_LOG(logDEBUG1, ("Getting DAC %d : %d dac (%d mV)\n",ind, dacValues[ind], voltage)); + return voltage; +} + +int getMaxDacSteps() { + return LTC2620_D_GetMaxNumSteps(); +} + int setHighVoltage(int val){ // limit values if (val > HV_SOFT_MAX_VOLTAGE ) { @@ -401,10 +573,15 @@ int setHighVoltage(int val){ int configureMAC() { -#ifdef VIRTUAL - uint32_t dstip = udpDetails.dstip; - int dstport = udpDetails.dstport; + uint32_t srcip = udpDetails.srcip; + uint32_t dstip = udpDetails.dstip; + uint64_t srcmac = udpDetails.srcmac; + uint64_t dstmac = udpDetails.dstmac; + int srcport = udpDetails.srcport; + int dstport = udpDetails.dstport; + +#ifdef VIRTUAL char cDestIp[MAX_STR_LENGTH]; memset(cDestIp, 0, MAX_STR_LENGTH); sprintf(cDestIp, "%d.%d.%d.%d", (dstip>>24)&0xff,(dstip>>16)&0xff,(dstip>>8)&0xff,(dstip)&0xff); @@ -414,9 +591,108 @@ int configureMAC() { return FAIL; } #endif + FILE_LOG(logINFOBLUE, ("Configuring MAC\n")); + + FILE_LOG(logINFO, ("\tSource IP : %d.%d.%d.%d \t\t(0x%08x)\n", + (srcip>>24)&0xff,(srcip>>16)&0xff,(srcip>>8)&0xff,(srcip)&0xff, srcip)); + FILE_LOG(logINFO, ("\tSource MAC : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", + (unsigned int)((srcmac>>40)&0xFF), + (unsigned int)((srcmac>>32)&0xFF), + (unsigned int)((srcmac>>24)&0xFF), + (unsigned int)((srcmac>>16)&0xFF), + (unsigned int)((srcmac>>8)&0xFF), + (unsigned int)((srcmac>>0)&0xFF), + (long long unsigned int)srcmac)); + FILE_LOG(logINFO, ("\tSource Port : %d \t\t\t(0x%08x)\n", srcport, srcport)); + + FILE_LOG(logINFO, ("\tDest. IP : %d.%d.%d.%d \t\t(0x%08x)\n", + (dstip>>24)&0xff,(dstip>>16)&0xff,(dstip>>8)&0xff,(dstip)&0xff, dstip)); + FILE_LOG(logINFO, ("\tDest. MAC : %02x:%02x:%02x:%02x:%02x:%02x \t(0x%010llx)\n", + (unsigned int)((dstmac>>40)&0xFF), + (unsigned int)((dstmac>>32)&0xFF), + (unsigned int)((dstmac>>24)&0xFF), + (unsigned int)((dstmac>>16)&0xFF), + (unsigned int)((dstmac>>8)&0xFF), + (unsigned int)((dstmac>>0)&0xFF), + (long long unsigned int)dstmac)); + FILE_LOG(logINFO, ("\tDest. Port : %d \t\t\t(0x%08x)\n\n",dstport, dstport)); + + // start addr + uint32_t addr = BASE_UDP_RAM; + // calculate rxr endpoint offset + //addr += (iRxEntry * RXR_ENDPOINT_OFST);//TODO: is there round robin already implemented? + // get struct memory + udp_header *udp = (udp_header*) (Nios_getBaseAddress() + addr/(sizeof(u_int32_t))); + memset(udp, 0, sizeof(udp_header)); + + // mac addresses + // msb (32) + lsb (16) + udp->udp_destmac_msb = ((dstmac >> 16) & BIT32_MASK); + udp->udp_destmac_lsb = ((dstmac >> 0) & BIT16_MASK); + // msb (16) + lsb (32) + udp->udp_srcmac_msb = ((srcmac >> 32) & BIT16_MASK); + udp->udp_srcmac_lsb = ((srcmac >> 0) & BIT32_MASK); + + // ip addresses + udp->ip_srcip_msb = ((srcip >> 16) & BIT16_MASK); + udp->ip_srcip_lsb = ((srcip >> 0) & BIT16_MASK); + udp->ip_destip_msb = ((dstip >> 16) & BIT16_MASK); + udp->ip_destip_lsb = ((dstip >> 0) & BIT16_MASK); + + // source port + udp->udp_srcport = srcport; + udp->udp_destport = dstport; + + // other defines + udp->udp_ethertype = 0x800; + udp->ip_ver = 0x4; + udp->ip_ihl = 0x5; + udp->ip_flags = 0x2; //FIXME + udp->ip_ttl = 0x40; + udp->ip_protocol = 0x11; + // total length is redefined in firmware + + // calcChecksum(udp); + + //TODO? + //cleanFifos(); + //resetCore(); + //alignDeserializer(); return OK; } +void calcChecksum(udp_header* udp) { + int count = IP_HEADER_SIZE; + long int sum = 0; + + // start at ip_tos as the memory is not continous for ip header + uint16_t *addr = (uint16_t*) (&(udp->ip_tos)); + + sum += *addr++; + count -= 2; + + // ignore ethertype (from udp header) + addr++; + + // from identification to srcip_lsb + while( count > 2 ) { + sum += *addr++; + count -= 2; + } + + // ignore src udp port (from udp header) + addr++; + + if (count > 0) + sum += *addr; // Add left-over byte, if any + while (sum >> 16) + sum = (sum & 0xffff) + (sum >> 16);// Fold 32-bit sum to 16 bits + long int checksum = sum & 0xffff; + checksum += UDP_IP_HEADER_LENGTH_BYTES; + FILE_LOG(logINFO, ("\tIP checksum is 0x%lx\n",checksum)); + udp->ip_checksum = checksum; +} + /* pattern */ uint64_t readPatternWord(int addr) { @@ -427,9 +703,9 @@ uint64_t readPatternWord(int addr) { return -1; } - FILE_LOG(logINFORED, (" Reading (Executing) Pattern Word (addr:0x%x)\n", addr)); - uint32_t reg_lsb = PATTERN_STEP0_LSB_REG + addr; // the first word in RAM as base plus the offset of the word to write (addr) - uint32_t reg_msb = PATTERN_STEP0_MSB_REG + addr; + FILE_LOG(logINFORED, (" Reading Pattern Word (addr:0x%x)\n", addr)); + uint32_t reg_lsb = PATTERN_STEP0_LSB_REG + addr * REG_OFFSET * 2; // the first word in RAM as base plus the offset of the word to write (addr) + uint32_t reg_msb = PATTERN_STEP0_MSB_REG + addr * REG_OFFSET * 2; // read value uint64_t retval = get64BitReg(reg_lsb, reg_msb); @@ -451,8 +727,8 @@ uint64_t writePatternWord(int addr, uint64_t word) { } FILE_LOG(logINFO, ("Setting Pattern Word (addr:0x%x, word:0x%llx)\n", addr, (long long int) word)); - uint32_t reg_lsb = PATTERN_STEP0_LSB_REG + addr; // the first word in RAM as base plus the offset of the word to write (addr) - uint32_t reg_msb = PATTERN_STEP0_MSB_REG + addr; + uint32_t reg_lsb = PATTERN_STEP0_LSB_REG + addr * REG_OFFSET * 2; // the first word in RAM as base plus the offset of the word to write (addr) + uint32_t reg_msb = PATTERN_STEP0_MSB_REG + addr * REG_OFFSET * 2; // write word set64BitReg(word, reg_lsb, reg_msb); @@ -503,7 +779,7 @@ int setPatternWaitAddress(int level, int addr) { } // get - uint32_t regval = bus_r((reg & mask) >> offset); + uint32_t regval = ((bus_r(reg) & mask) >> offset); FILE_LOG(logDEBUG1, (" Wait Address retval (level:%d, addr:0x%x)\n", level, regval)); return regval; } diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h index 144a3f523..3ff59519f 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h @@ -1,6 +1,8 @@ #pragma once #include "sls_detector_defs.h" +#define REQRD_FRMWRE_VRSN 0x190000 +#define MIN_REQRD_VRSN_T_RD_API 0x190000 #define CTRL_SRVR_INIT_TIME_US (300 * 1000) @@ -11,6 +13,8 @@ #define HV_SOFT_MAX_VOLTAGE (200) #define HV_HARD_MAX_VOLTAGE (530) #define HV_DRIVER_FILE_NAME ("/etc/devlinks/hvdac") +#define DAC_DRIVER_FILE_NAME ("/etc/devlinks/dac") +#define DAC_MAX_MV (2048) /** Default Parameters */ #define DEFAULT_NUM_FRAMES (1) @@ -23,29 +27,58 @@ #define DEFAULT_TICK_CLK (20) // will be fixed later. Not configurable #define DEFAULT_SAMPLING_CLK (80) +/* Firmware Definitions */ +#define IP_HEADER_SIZE (20) + +/** Other Definitions */ +#define BIT16_MASK (0xFFFF) + /* Enums */ enum CLKINDEX {RUN_CLK, TICK_CLK, SAMPLING_CLK, NUM_CLOCKS}; -enum DACINDEX {VIBIASSH, VTRIM, VIPRE, VRFSHNPOL, VTH1, VIPREOUT, VRF, VTH2, CAS, CASSH, VPL, VDCSH, VICIN, VICINSH, VICBIAS, VPH, VTH3, VRFSH}; -#define DEFAULT_DAC_VALS {1200, /* vIbiasSh */ \ - 2300, /* vTrim */ \ - 2150, /* vIpre */ \ - 2300, /* VrfShNpol */ \ - 900, /* Vth1 */ \ - 1000, /* vIpreOut */ \ - 900, /* Vrf */ \ - 900, /* Vth2 */ \ - 1474, /* cas */ \ - 983, /* casSh */ \ - 900, /* VPL */ \ - 655, /* VdcSh */ \ - 1400, /* vIcin */ \ - 1400, /* vIcinSh */ \ - 1200, /* vIcbias */ \ - 960, /* VPH */ \ - 900, /* Vth3 */ \ - 1100 /* VrfSh */ \ +enum DACINDEX {CASSH, VTH2, VRFSH, VRFSHNPOL, VIPREOUT, VTH3, VTH1, VICIN, CAS, VRF, VPH, VIPRE, VIINSH, VPL, VTRIM, VDCSH}; +#define DEFAULT_DAC_VALS {1200, /* casSh */ \ + 2800, /* Vth2 */ \ + 1280, /* VrfSh */ \ + 2800, /* VrfShNpol */ \ + 1220, /* vIpreOut */ \ + 2800, /* Vth3 */ \ + 2800, /* Vth1 */ \ + 1708, /* vIcin */ \ + 1800, /* cas */ \ + 1100, /* Vrf */ \ + 1712, /* VPH */ \ + 2624, /* vIpre */ \ + 1708, /* vIinSh */ \ + 1100, /* VPL */ \ + 2800, /* vTrim */ \ + 800 /* VdcSh */ \ }; /* Defines in the Firmware */ -#define MAX_PATTERN_LENGTH (0x8192) // maximum number of words (64bit) +#define MAX_PATTERN_LENGTH (0x2000) // maximum number of words (64bit) + +/* Struct Definitions */ +typedef struct udp_header_struct { + uint32_t udp_destmac_msb; + uint16_t udp_srcmac_msb; + uint16_t udp_destmac_lsb; + uint32_t udp_srcmac_lsb; + uint8_t ip_tos; + uint8_t ip_ihl: 4, ip_ver: 4; + uint16_t udp_ethertype; + uint16_t ip_identification; + uint16_t ip_totallength; + uint8_t ip_protocol; + uint8_t ip_ttl; + uint16_t ip_fragmentoffset: 13, ip_flags: 3; + uint16_t ip_srcip_msb; + uint16_t ip_checksum; + uint16_t ip_destip_msb; + uint16_t ip_srcip_lsb; + uint16_t udp_srcport; + uint16_t ip_destip_lsb; + uint16_t udp_checksum; + uint16_t udp_destport; +} udp_header; +#define UDP_IP_HEADER_LENGTH_BYTES (28) \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/include/DAC6571.h b/slsDetectorServers/slsDetectorServer/include/DAC6571.h index 11a274688..6dc26e731 100755 --- a/slsDetectorServers/slsDetectorServer/include/DAC6571.h +++ b/slsDetectorServers/slsDetectorServer/include/DAC6571.h @@ -4,7 +4,6 @@ /** * Set Defines - * @param dofst digital output offset * @param hardMaxV maximum hardware limit * @param driverfname driver file name */ diff --git a/slsDetectorServers/slsDetectorServer/include/LTC2620_Driver.h b/slsDetectorServers/slsDetectorServer/include/LTC2620_Driver.h new file mode 100755 index 000000000..546432fe1 --- /dev/null +++ b/slsDetectorServers/slsDetectorServer/include/LTC2620_Driver.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +/** + * Set Defines + * @param hardMaxV maximum hardware limit + * @param driverfname driver file name + * @param numdacs number of dacs + */ +void LTC2620_D_SetDefines(int hardMaxV, char* driverfname, int numdacs); + + +/** + * Get max number of steps + */ +int LTC2620_D_GetMaxNumSteps(); + +/** + * Convert voltage to dac units + * @param voltage value in mv + * @param dacval pointer to value converted to dac units + * @returns FAIL when voltage outside limits, OK if conversion successful + */ +int LTC2620_D_VoltageToDac(int voltage, int* dacval); + +/** + * Convert dac units to voltage + * @param dacval dac units + * @param voltage pointer to value converted to mV + * @returns FAIL when voltage outside limits, OK if conversion successful + */ +int LTC2620_D_DacToVoltage(int dacval, int* voltage); + +/** + * Set value + * @param dacnum dac index + * @param val value to set + * @param mV 1 for mv, else 0 + * @param dacval pointer to dac value + * @return OK or FAIL + */ +int LTC2620_D_SetDACValue(int dacnum, int val, int mV, int *dacval); diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index 73b682cd6..16728c078 100755 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -51,8 +51,10 @@ int detectorTest(enum digitalTestMode arg); int64_t getDetectorId(enum idMode arg); u_int64_t getFirmwareVersion(); u_int64_t getFirmwareAPIVersion(); -#if defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || defined(MOENCHD) +#if defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(MYTHEN3D) u_int16_t getHardwareVersionNumber(); +#endif +#if defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || defined(MOENCHD) u_int16_t getHardwareSerialNumber(); #endif #ifdef JUNGFRAUD @@ -83,7 +85,7 @@ int allocateRAM(); void updateDataBytes(); #endif -#if defined(GOTTHARDD) || defined(JUNGFRAUD) +#if defined(GOTTHARDD) || defined(JUNGFRAUD) || defined(MYTHEN3D) int setDefaultDacs(); #endif @@ -210,7 +212,7 @@ extern int AD9257_GetVrefVoltage(int mV); // AD9257.h extern int AD9257_SetVrefVoltage(int val, int mV); // AD9257.h #endif -#if (!defined(MYTHEN3D)) && (!defined(GOTTHARD2D)) +#if (!defined(GOTTHARD2D)) void setDAC(enum DACINDEX ind, int val, int mV); int getDAC(enum DACINDEX ind, int mV); int getMaxDacSteps(); diff --git a/slsDetectorServers/slsDetectorServer/src/LTC2620_Driver.c b/slsDetectorServers/slsDetectorServer/src/LTC2620_Driver.c new file mode 100755 index 000000000..8a7ceb9c6 --- /dev/null +++ b/slsDetectorServers/slsDetectorServer/src/LTC2620_Driver.c @@ -0,0 +1,90 @@ +#include "LTC2620_Driver.h" +#include "clogger.h" +#include "common.h" +#include "sls_detector_defs.h" + +#include + +/* LTC2620 DAC DEFINES */ +#define LTC2620_D_PWR_DOWN_VAL (-100) +#define LTC2620_D_MAX_DAC_VAL (4095) // 12 bits +#define LTC2620_D_MAX_STEPS (LTC2620_D_MAX_DAC_VAL + 1) + + +// defines from the fpga +int LTC2620_D_HardMaxVoltage = 0; +char LTC2620_D_DriverFileName[MAX_STR_LENGTH]; +int LTC2620_D_NumDacs = 0; + +void LTC2620_D_SetDefines(int hardMaxV, char* driverfname, int numdacs) { + FILE_LOG(logINFOBLUE, ("Configuring DACs (LTC2620)\n")); + LTC2620_D_HardMaxVoltage = hardMaxV; + memset(LTC2620_D_DriverFileName, 0, MAX_STR_LENGTH); + strcpy(LTC2620_D_DriverFileName, driverfname); + LTC2620_D_NumDacs = numdacs; +} + +int LTC2620_D_GetMaxNumSteps() { + return LTC2620_D_MAX_STEPS; +} + +int LTC2620_D_VoltageToDac(int voltage, int* dacval) { + return ConvertToDifferentRange(0, LTC2620_D_HardMaxVoltage, 0, LTC2620_D_MAX_DAC_VAL, + voltage, dacval); +} + +int LTC2620_D_DacToVoltage(int dacval, int* voltage) { + return ConvertToDifferentRange( 0, LTC2620_D_MAX_DAC_VAL, 0, LTC2620_D_HardMaxVoltage, + dacval, voltage); +} + + +int LTC2620_D_SetDACValue (int dacnum, int val, int mV, int* dacval) { + FILE_LOG(logDEBUG1, ("dacnum:%d, val:%d, ismV:%d\n", dacnum, val, mV)); + // validate index + if (dacnum < 0 || dacnum >= LTC2620_D_NumDacs) { + FILE_LOG(logERROR, ("Dac index %d is out of bounds (0 to %d)\n", dacnum, LTC2620_D_NumDacs - 1)); + return FAIL; + } + + // get + if (val < 0 && val != LTC2620_D_PWR_DOWN_VAL) + return FAIL; + + // convert to dac or get mV value + *dacval = val; + int dacmV = val; + int ret = OK; + if (mV) { + ret = LTC2620_D_VoltageToDac(val, dacval); + } else if (val >= 0) { + // do not convert power down dac val + ret = LTC2620_D_DacToVoltage(val, &dacmV); + } + + // conversion out of bounds + if (ret == FAIL) { + FILE_LOG(logERROR, ("Setting Dac %d %s is out of bounds\n", dacnum, (mV ? "mV" : "dac units"))); + return FAIL; + } + + // set + if ( (*dacval >= 0) || (*dacval == LTC2620_D_PWR_DOWN_VAL)) { + FILE_LOG(logINFO, ("Setting DAC %d: %d dac (%d mV)\n",dacnum, *dacval, dacmV)); + + char fname[MAX_STR_LENGTH]; + sprintf(fname, "%s%d", LTC2620_D_DriverFileName, dacnum); + FILE_LOG(logDEBUG1, ("fname %s\n",fname)); + + //open file + FILE* fd=fopen(fname,"w"); + if (fd==NULL) { + FILE_LOG(logERROR, ("Could not open file %s for writing to set dac %d\n", fname, dacnum)); + return FAIL; + } + //convert to string, add 0 and write to file + fprintf(fd, "%d\n", *dacval); + fclose(fd); + } + return OK; +} diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 7c2666d51..98aa5e761 100755 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -847,6 +847,55 @@ int set_dac(int file_des) { #elif MYTHEN3D case HIGH_VOLTAGE: break; + case M_casSh: // in sls_detector_defs.h + serverDacIndex = CASSH; // in mythen3 slsDetectorServer_defs.h + break; + case M_Vth2: + serverDacIndex = VTH2; + break; + case SHAPER1: + serverDacIndex = VRFSH; + break; + case SHAPER2: + serverDacIndex = VRFSHNPOL; + break; + case M_vIpreOut: + serverDacIndex = VIPREOUT; + break; + case M_Vth3: + serverDacIndex = VTH3; + break; + case THRESHOLD: + serverDacIndex = VTH1; + break; + case M_vIcin: + serverDacIndex = VICIN; + break; + case M_cas: + serverDacIndex = CAS; + break; + case PREAMP: + serverDacIndex = VRF; + break; + case CALIBRATION_PULSE: + serverDacIndex = VPH; + break; + case M_vIpre: + serverDacIndex = VIPRE; + break; + case M_vIinSh: + serverDacIndex = VIINSH; + break; + case M_VPL: + serverDacIndex = VPL; + break; + case TRIMBIT_SIZE: + serverDacIndex = VTRIM; + break; + case M_VdcSh: + serverDacIndex = VDCSH; + break; + #endif default: @@ -1017,9 +1066,7 @@ int set_dac(int file_des) { #ifdef GOTTHARD2D default: break; -#elif MYTHEN3D - default: - break; + #else // dacs default: diff --git a/slsDetectorSoftware/src/slsDetectorCommand.cpp b/slsDetectorSoftware/src/slsDetectorCommand.cpp index a21982c2c..4ef4e569e 100755 --- a/slsDetectorSoftware/src/slsDetectorCommand.cpp +++ b/slsDetectorSoftware/src/slsDetectorCommand.cpp @@ -934,6 +934,13 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; + /*! \page settings + - vhaper1 [i] [mv] Sets/gets the voltage to define the feedback resistance of the first shaper. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ + descrToFuncMap[i].m_pFuncName = "vshaper"; + descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; + ++i; + /*! \page settings - vshaper2 [i] [mv] Sets/gets the voltage to define the feedback resistance of the second shaper. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ @@ -941,6 +948,13 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; + /*! \page settings + - vhaper1 [i] [mv] Sets/gets the voltage to define the feedback resistance of the first shaper. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ + descrToFuncMap[i].m_pFuncName = "vshaperneg"; + descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; + ++i; + /*! \page settings - vhighvoltage [i] Sets/gets the high voltage to the sensor in V. \c Returns \c (int ["mV"]). */ @@ -1214,51 +1228,51 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; - /* MYTHEN 3.01 + /* MYTHEN 3.0 all values are in DACu */ - descrToFuncMap[i].m_pFuncName = "vIpre"; + descrToFuncMap[i].m_pFuncName = "vipre"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; - descrToFuncMap[i].m_pFuncName = "VcdSh"; + descrToFuncMap[i].m_pFuncName = "vdcsh"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - Vth1 Sets/gets first detector threshold voltage for Mythen 3.01. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ - descrToFuncMap[i].m_pFuncName = "Vth1"; + descrToFuncMap[i].m_pFuncName = "vth1"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - Vth1 Sets/gets second detector threshold voltage for Mythen 3.01. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - Vth1 Sets/gets second detector threshold voltage for Mythen 3.0. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ - descrToFuncMap[i].m_pFuncName = "Vth2"; + descrToFuncMap[i].m_pFuncName = "vth2"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - Vth1 Sets/gets third detector threshold voltage for Mythen 3.01. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - Vth1 Sets/gets third detector threshold voltage for Mythen 3.0. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ - descrToFuncMap[i].m_pFuncName = "Vth3"; + descrToFuncMap[i].m_pFuncName = "vth3"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; - descrToFuncMap[i].m_pFuncName = "VPL"; //baseline for analog pulsing + descrToFuncMap[i].m_pFuncName = "vpl"; //baseline for analog pulsing descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; - descrToFuncMap[i].m_pFuncName = "Vtrim"; + descrToFuncMap[i].m_pFuncName = "vph"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; - descrToFuncMap[i].m_pFuncName = "vIbias"; + descrToFuncMap[i].m_pFuncName = "vtrim"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; - descrToFuncMap[i].m_pFuncName = "vIinSh"; + descrToFuncMap[i].m_pFuncName = "viinsh"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; @@ -1266,19 +1280,23 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; - descrToFuncMap[i].m_pFuncName = "casSh"; + descrToFuncMap[i].m_pFuncName = "cassh"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; - descrToFuncMap[i].m_pFuncName = "vIbiasSh"; + descrToFuncMap[i].m_pFuncName = "vicin"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; - descrToFuncMap[i].m_pFuncName = "vIcin"; + descrToFuncMap[i].m_pFuncName = "vipreout"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; - descrToFuncMap[i].m_pFuncName = "vIpreOut"; + descrToFuncMap[i].m_pFuncName = "vrfsh"; + descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; + ++i; + + descrToFuncMap[i].m_pFuncName = "vrfshnpol"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; @@ -3264,9 +3282,9 @@ std::string slsDetectorCommand::cmdDAC(int narg, const char * const args[], int dac = TRIMBIT_SIZE; else if (cmd == "vpreamp") dac = PREAMP; - else if (cmd == "vshaper1") + else if (cmd == "vshaper1" || cmd == "vshaper") dac = SHAPER1; - else if (cmd == "vshaper2") + else if (cmd == "vshaper2" || cmd == "vshaperneg") dac = SHAPER2; else if (cmd == "vhighvoltage") dac = HIGH_VOLTAGE; @@ -3349,35 +3367,32 @@ std::string slsDetectorCommand::cmdDAC(int narg, const char * const args[], int mode = 1; } else if (cmd == "v_limit") dac = V_LIMIT; - else if (cmd == "vIpre") + else if (cmd == "vipre") dac = M_vIpre; - else if (cmd == "vIbias") - dac = M_vIbias; - else if (cmd == "vIinSh") + else if (cmd == "viinsh") dac = M_vIinSh; - else if (cmd == "VcdSh") + else if (cmd == "vdcsh") dac = M_VdcSh; - else if (cmd == "Vth1") + else if (cmd == "vth1") dac = THRESHOLD; - else if (cmd == "Vth2") + else if (cmd == "vth2") dac = M_Vth2; - else if (cmd == "Vth3") + else if (cmd == "vth3") dac = M_Vth3; - else if (cmd == "VPL") + else if (cmd == "vpl") dac = M_VPL; - else if (cmd == "Vtrim") + else if (cmd == "vph") + dac = CALIBRATION_PULSE; + else if (cmd == "vtrim") dac = TRIMBIT_SIZE; - else if (cmd == "casSh") + else if (cmd == "cassh") dac = M_casSh; else if (cmd == "cas") dac = M_cas; - else if (cmd == "vIcin") + else if (cmd == "vicin") dac = M_vIcin; - else if (cmd == "vIbiasSh") - dac = M_vIbiasSh; - else if (cmd == "vIpreOut") + else if (cmd == "vipreout") dac = M_vIpreOut; - else return std::string("cannot decode dac ") + cmd; diff --git a/slsSupportLib/include/sls_detector_defs.h b/slsSupportLib/include/sls_detector_defs.h index ed1185992..b1b3b2174 100755 --- a/slsSupportLib/include/sls_detector_defs.h +++ b/slsSupportLib/include/sls_detector_defs.h @@ -428,7 +428,6 @@ format TEMPERATURE_FPGA2, /**< temperature sensor (fpga2 (eiger:febl) */ TEMPERATURE_FPGA3, /**< temperature sensor (fpga3 (eiger:febr) */ M_vIpre, /**< mythen 3 >*/ - M_vIbias, /**< mythen 3 >*/ M_vIinSh, /**< mythen 3 >*/ M_VdcSh, /**< mythen 3 >*/ M_Vth2, /**< mythen 3 >*/ @@ -436,7 +435,6 @@ format M_Vth3, /**< mythen 3 >*/ M_casSh, /**< mythen 3 >*/ M_cas, /**< mythen 3 >*/ - M_vIbiasSh, /**< mythen 3 >*/ M_vIcin, /**< mythen 3 >*/ M_vIpreOut, /**< mythen 3 >*/ V_POWER_A = 100, /**new chiptest board */ diff --git a/slsSupportLib/include/versionAPI.h b/slsSupportLib/include/versionAPI.h index 73c271437..5e6cb1414 100644 --- a/slsSupportLib/include/versionAPI.h +++ b/slsSupportLib/include/versionAPI.h @@ -7,6 +7,6 @@ #define APICTB 0x190930 #define APIGOTTHARD 0x190930 #define APIJUNGFRAU 0x190930 -#define APIMYTHEN3 0x190930 #define APIEIGER 0x190930 +#define APIMYTHEN3 0x191004 #define APIGOTTHARD2 0x191001 From 7a66dd08a3d16122fbf744875dbaf64ed66d3e00 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Mon, 7 Oct 2019 12:30:28 +0200 Subject: [PATCH 2/3] help for dacs mythen3 --- .../src/slsDetectorCommand.cpp | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/slsDetectorSoftware/src/slsDetectorCommand.cpp b/slsDetectorSoftware/src/slsDetectorCommand.cpp index 4ef4e569e..9a7f23f31 100755 --- a/slsDetectorSoftware/src/slsDetectorCommand.cpp +++ b/slsDetectorSoftware/src/slsDetectorCommand.cpp @@ -1228,13 +1228,16 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; - /* MYTHEN 3.0 - all values are in DACu */ - + /*! \page settings + - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ descrToFuncMap[i].m_pFuncName = "vipre"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; + /*! \page settings + - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ descrToFuncMap[i].m_pFuncName = "vdcsh"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; @@ -1260,42 +1263,72 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; - descrToFuncMap[i].m_pFuncName = "vpl"; //baseline for analog pulsing + /*! \page settings + - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ + descrToFuncMap[i].m_pFuncName = "vpl"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; + /*! \page settings + - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ descrToFuncMap[i].m_pFuncName = "vph"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; + /*! \page settings + - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ descrToFuncMap[i].m_pFuncName = "vtrim"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; + /*! \page settings + - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ descrToFuncMap[i].m_pFuncName = "viinsh"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; + /*! \page settings + - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ descrToFuncMap[i].m_pFuncName = "cas"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; + /*! \page settings + - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ descrToFuncMap[i].m_pFuncName = "cassh"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; + /*! \page settings + - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ descrToFuncMap[i].m_pFuncName = "vicin"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; + /*! \page settings + - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ descrToFuncMap[i].m_pFuncName = "vipreout"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; + /*! \page settings + - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ descrToFuncMap[i].m_pFuncName = "vrfsh"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; + /*! \page settings + - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + */ descrToFuncMap[i].m_pFuncName = "vrfshnpol"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; From 6cda61a612bdf79d65541bbff14a867f2c0aa0e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20Andr=C3=A4?= <33870994+MarieAndrae@users.noreply.github.com> Date: Mon, 7 Oct 2019 13:44:41 +0200 Subject: [PATCH 3/3] Update slsDetectorCommand.cpp help comments for the mythen3 dacs (not complete yet) --- .../src/slsDetectorCommand.cpp | 46 +++++++------------ 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/slsDetectorSoftware/src/slsDetectorCommand.cpp b/slsDetectorSoftware/src/slsDetectorCommand.cpp index 9a7f23f31..e9096aa61 100755 --- a/slsDetectorSoftware/src/slsDetectorCommand.cpp +++ b/slsDetectorSoftware/src/slsDetectorCommand.cpp @@ -935,7 +935,7 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { ++i; /*! \page settings - - vhaper1 [i] [mv] Sets/gets the voltage to define the feedback resistance of the first shaper. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - vhaper [i] [mv] Sets/gets the voltage to define the feedback resistance of the shaper. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "vshaper"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; @@ -949,7 +949,7 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { ++i; /*! \page settings - - vhaper1 [i] [mv] Sets/gets the voltage to define the feedback resistance of the first shaper. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - vhaperneg [i] [mv] Sets/gets the voltage to define the feedback resistance of the negative-polarity shaper. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "vshaperneg"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; @@ -1229,110 +1229,96 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { ++i; /*! \page settings - - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - vipre Sets/gets dac for the current in the preamplifier for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "vipre"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - vdcsh Sets/gets dac for the baseline of the shaper for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "vdcsh"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - Vth1 Sets/gets first detector threshold voltage for Mythen 3.01. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - vth1 Sets/gets first detector threshold voltage for Mythen 3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "vth1"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - Vth1 Sets/gets second detector threshold voltage for Mythen 3.0. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - vth2 Sets/gets second detector threshold voltage for Mythen 3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "vth2"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - Vth1 Sets/gets third detector threshold voltage for Mythen 3.0. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - vth3 Sets/gets third detector threshold voltage for Mythen 3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "vth3"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - vpl Sets/gets dac for the lower value of the analog pulse for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "vpl"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - vph Sets/gets dac for the higher value of the analog pulse for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "vph"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - vtrim Sets/gets dac for the voltage defining the trim bit size for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "vtrim"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - viinsh Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "viinsh"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - cas Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "cas"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - cassh Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "cassh"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - vicin Sets/gets dac for the bias of the comparator for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "vicin"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; /*! \page settings - - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) + - vipreout Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) */ descrToFuncMap[i].m_pFuncName = "vipreout"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; ++i; - /*! \page settings - - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) - */ - descrToFuncMap[i].m_pFuncName = "vrfsh"; - descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; - ++i; - - /*! \page settings - - vIpre Sets/gets dac for xxx for Mythen3. Normally in DAC units unless \c mv is specified at the end of the command line. \c Returns \c (int ["mV"]) - */ - descrToFuncMap[i].m_pFuncName = "vrfshnpol"; - descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdDAC; - ++i; - /* r/w timers */ /*! \page settings \section settingsadcs ADCs @@ -1957,7 +1943,7 @@ std::string slsDetectorCommand::executeLine(int narg, const char * const args[], if (action == READOUT_ACTION) return cmdAcquire(narg, args, action, detPos); - +xxx size_t s = std::string(args[0]).find(':'); std::string key = std::string(args[0]).substr(0, s); // truncate at :